<commit_before>use event_imp::{Ready, ready_as_usize, ready_from_usize};

use std::ops;
use std::fmt;

/// Unix specific extensions to `Ready`
///
/// Provides additional readiness event kinds that are available on unix
/// platforms. Unix platforms are able to provide readiness events for
/// additional socket events, such as HUP and error.
///
/// HUP events occur when the remote end of a socket hangs up. In the TCP case,
/// this occurs when the remote end of a TCP socket shuts down writes.
///
/// Error events occur when the socket enters an error state. In this case, the
/// socket will also receive a readable or writable event. Reading or writing to
/// the socket will result in an error.
///
/// Conversion traits are implemented between `Ready` and `UnixReady`. See the
/// examples.
///
/// For high level documentation on polling and readiness, see [`Poll`].
///
/// # Examples
///
/// Most of the time, all that is needed is using bit operations
///
/// ```
/// use mio::Ready;
/// use mio::unix::UnixReady;
///
/// let ready = Ready::readable() | UnixReady::hup();
///
/// assert!(ready.is_readable());
/// assert!(UnixReady::from(ready).is_hup());
/// ```
///
/// Basic conversion between ready types.
///
/// ```
/// use mio::Ready;
/// use mio::unix::UnixReady;
///
/// // Start with a portable ready
/// let ready = Ready::readable();
///
/// // Convert to a unix ready, adding HUP
/// let mut unix_ready = UnixReady::from(ready) | UnixReady::hup();
///
/// unix_ready.insert(UnixReady::error());
///
/// // `unix_ready` maintains readable interest
/// assert!(unix_ready.is_readable());
/// assert!(unix_ready.is_hup());
/// assert!(unix_ready.is_error());
///
/// // Convert back to `Ready`
/// let ready = Ready::from(unix_ready);
///
/// // Readable is maintained
/// assert!(ready.is_readable());
/// ```
///
/// Registering readable and error interest on a socket
///
/// ```
/// # use std::error::Error;
/// # fn try_main() -> Result<(), Box<Error>> {
/// use mio::{Ready, Poll, PollOpt, Token};
/// use mio::net::TcpStream;
/// use mio::unix::UnixReady;
///
/// let addr = "216.58.193.68:80".parse()?;
/// let socket = TcpStream::connect(&addr)?;
///
/// let poll = Poll::new()?;
///
/// poll.register(&socket,
///               Token(0),
///               Ready::readable() | UnixReady::error(),
///               PollOpt::edge())?;
/// #     Ok(())
/// # }
/// #
/// # fn main() {
/// #     try_main().unwrap();
/// # }
/// ```
///
/// [`Poll`]: ../struct.Poll.html
/// [readiness]: struct.Poll.html#readiness-operations
#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord)]
pub struct UnixReady(Ready);

const ERROR: usize = 0b00_0100;
const HUP: usize   = 0b00_1000;

#[cfg(any(target_os = "dragonfly",
    target_os = "freebsd", target_os = "ios", target_os = "macos"))]
const AIO: usize   = 0b01_0000;

#[cfg(not(any(target_os = "dragonfly",
    target_os = "freebsd", target_os = "ios", target_os = "macos")))]
const AIO: usize   = 0b00_0000;

#[cfg(any(target_os = "freebsd"))]
const LIO: usize   = 0b10_0000;

#[cfg(not(any(target_os = "freebsd")))]
const LIO: usize   = 0b00_0000;

#[cfg(any(target_os = "linux", target_os = "android", target_os = "solaris"))]
const PRI: usize = 0b100_0000;

#[cfg(not(any(target_os = "linux", target_os = "android", target_os = "solaris")))]
const PRI: usize = 0;

// Export to support `Ready::all`
pub const READY_ALL: usize = ERROR | HUP | AIO | LIO | PRI;

impl UnixReady {
    /// Returns a `Ready` representing AIO completion readiness
    ///
    /// See [`Poll`] for more documentation on polling.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::unix::UnixReady;
    ///
    /// let ready = UnixReady::aio();
    ///
    /// assert!(ready.is_aio());
    /// ```
    ///
    /// [`Poll`]: ../struct.Poll.html
    #[inline]
    #[cfg(any(target_os = "dragonfly",
        target_os = "freebsd", target_os = "ios", target_os = "macos"))]
    pub fn aio() -> UnixReady {
        UnixReady(ready_from_usize(AIO))
    }

    #[cfg(not(any(target_os = "dragonfly",
        target_os = "freebsd", target_os = "ios", target_os = "macos")))]
    #[deprecated(since = "0.6.12", note = "this function is now platform specific")]
    #[doc(hidden)]
    pub fn aio() -> UnixReady {
        UnixReady(Ready::empty())
    }

    /// Returns a `Ready` representing error readiness.
    ///
    /// **Note that only readable and writable readiness is guaranteed to be
    /// supported on all platforms**. This means that `error` readiness
    /// should be treated as a hint. For more details, see [readiness] in the
    /// poll documentation.
    ///
    /// See [`Poll`] for more documentation on polling.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::unix::UnixReady;
    ///
    /// let ready = UnixReady::error();
    ///
    /// assert!(ready.is_error());
    /// ```
    ///
    /// [`Poll`]: ../struct.Poll.html
    /// [readiness]: ../struct.Poll.html#readiness-operations
    #[inline]
    pub fn error() -> UnixReady {
        UnixReady(ready_from_usize(ERROR))
    }

    /// Returns a `Ready` representing HUP readiness.
    ///
    /// A HUP (or hang-up) signifies that a stream socket **peer** closed the
    /// connection, or shut down the writing half of the connection.
    ///
    /// **Note that only readable and writable readiness is guaranteed to be
    /// supported on all platforms**. This means that `hup` readiness
    /// should be treated as a hint. For more details, see [readiness] in the
    /// poll documentation.
    ///
    /// See [`Poll`] for more documentation on polling.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::unix::UnixReady;
    ///
    /// let ready = UnixReady::hup();
    ///
    /// assert!(ready.is_hup());
    /// ```
    ///
    /// [`Poll`]: ../struct.Poll.html
    /// [readiness]: ../struct.Poll.html#readiness-operations
    #[inline]
    pub fn hup() -> UnixReady {
        UnixReady(ready_from_usize(HUP))
    }

    /// Returns a `Ready` representing LIO completion readiness
    ///
    /// See [`Poll`] for more documentation on polling.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::unix::UnixReady;
    ///
    /// let ready = UnixReady::lio();
    ///
    /// assert!(ready.is_lio());
    /// ```
    ///
    /// [`Poll`]: struct.Poll.html
    #[inline]
    #[cfg(any(target_os = "freebsd"))]
    pub fn lio() -> UnixReady {
        UnixReady(ready_from_usize(LIO))
    }

    /// Returns a `Ready` representing priority (`EPOLLPRI`) readiness
    ///
    /// See [`Poll`] for more documentation on polling.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::unix::UnixReady;
    ///
    /// let ready = UnixReady::priority();
    ///
    /// assert!(ready.is_priority());
    /// ```
    ///
    /// [`Poll`]: struct.Poll.html
    #[inline]
    #[cfg(any(target_os = "linux",
        target_os = "android", target_os = "solaris"))]
    pub fn priority() -> UnixReady {
        UnixReady(ready_from_usize(PRI))
    }

    /// Returns true if `Ready` contains AIO readiness
    ///
    /// See [`Poll`] for more documentation on polling.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::unix::UnixReady;
    ///
    /// let ready = UnixReady::aio();
    ///
    /// assert!(ready.is_aio());
    /// ```
    ///
    /// [`Poll`]: ../struct.Poll.html
    #[inline]
    #[cfg(any(target_os = "dragonfly",
        target_os = "freebsd", target_os = "ios", target_os = "macos"))]
    pub fn is_aio(&self) -> bool {
        self.contains(ready_from_usize(AIO))
    }

    #[deprecated(since = "0.6.12", note = "this function is now platform specific")]
    #[cfg(feature = "with-deprecated")]
    #[cfg(not(any(target_os = "dragonfly",
        target_os = "freebsd", target_os = "ios", target_os = "macos")))]
    #[doc(hidden)]
    pub fn is_aio(&self) -> bool {
        false
    }

    /// Returns true if the value includes error readiness
    ///
    /// **Note that only readable and writable readiness is guaranteed to be
    /// supported on all platforms**. This means that `error` readiness should
    /// be treated as a hint. For more details, see [readiness] in the poll
    /// documentation.
    ///
    /// See [`Poll`] for more documentation on polling.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::unix::UnixReady;
    ///
    /// let ready = UnixReady::error();
    ///
    /// assert!(ready.is_error());
    /// ```
    ///
    /// [`Poll`]: ../struct.Poll.html
    /// [readiness]: ../struct.Poll.html#readiness-operations
    #[inline]
    pub fn is_error(&self) -> bool {
        self.contains(ready_from_usize(ERROR))
    }

    /// Returns true if the value includes HUP readiness
    ///
    /// A HUP (or hang-up) signifies that a stream socket **peer** closed the
    /// connection, or shut down the writing half of the connection.
    ///
    /// **Note that only readable and writable readiness is guaranteed to be
    /// supported on all platforms**. This means that `hup` readiness
    /// should be treated as a hint. For more details, see [readiness] in the
    /// poll documentation.
    ///
    /// See [`Poll`] for more documentation on polling.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::unix::UnixReady;
    ///
    /// let ready = UnixReady::hup();
    ///
    /// assert!(ready.is_hup());
    /// ```
    ///
    /// [`Poll`]: ../struct.Poll.html
    /// [readiness]: ../struct.Poll.html#readiness-operations
    #[inline]
    pub fn is_hup(&self) -> bool {
        self.contains(ready_from_usize(HUP))
    }

    /// Returns true if `Ready` contains LIO readiness
    ///
    /// See [`Poll`] for more documentation on polling.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::unix::UnixReady;
    ///
    /// let ready = UnixReady::lio();
    ///
    /// assert!(ready.is_lio());
    /// ```
    #[inline]
    #[cfg(any(target_os = "freebsd"))]
    pub fn is_lio(&self) -> bool {
        self.contains(ready_from_usize(LIO))
    }

    /// Returns true if `Ready` contains priority (`EPOLLPRI`) readiness
    ///
    /// See [`Poll`] for more documentation on polling.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::unix::UnixReady;
    ///
    /// let ready = UnixReady::priority();
    ///
    /// assert!(ready.is_priority());
    /// ```
    ///
    /// [`Poll`]: struct.Poll.html
    #[inline]
    #[cfg(any(target_os = "linux",
        target_os = "android", target_os = "solaris"))]
    pub fn is_priority(&self) -> bool {
        self.contains(ready_from_usize(PRI))
    }
}

impl From<Ready> for UnixReady {
    fn from(src: Ready) -> UnixReady {
        UnixReady(src)
    }
}

impl From<UnixReady> for Ready {
    fn from(src: UnixReady) -> Ready {
        src.0
    }
}

impl ops::Deref for UnixReady {
    type Target = Ready;

    fn deref(&self) -> &Ready {
        &self.0
    }
}

impl ops::DerefMut for UnixReady {
    fn deref_mut(&mut self) -> &mut Ready {
        &mut self.0
    }
}

impl ops::BitOr for UnixReady {
    type Output = UnixReady;

    #[inline]
    fn bitor(self, other: UnixReady) -> UnixReady {
        (self.0 | other.0).into()
    }
}

impl ops::BitXor for UnixReady {
    type Output = UnixReady;

    #[inline]
    fn bitxor(self, other: UnixReady) -> UnixReady {
        (self.0 ^ other.0).into()
    }
}

impl ops::BitAnd for UnixReady {
    type Output = UnixReady;

    #[inline]
    fn bitand(self, other: UnixReady) -> UnixReady {
        (self.0 & other.0).into()
    }
}

impl ops::Sub for UnixReady {
    type Output = UnixReady;

    #[inline]
    fn sub(self, other: UnixReady) -> UnixReady {
        ready_from_usize(ready_as_usize(self.0) & !ready_as_usize(other.0)).into()
    }
}

#[deprecated(since = "0.6.10", note = "removed")]
#[cfg(feature = "with-deprecated")]
#[doc(hidden)]
impl ops::Not for UnixReady {
    type Output = UnixReady;

    #[inline]
    fn not(self) -> UnixReady {
        (!self.0).into()
    }
}

impl fmt::Debug for UnixReady {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let mut one = false;
        let flags = [
            (UnixReady(Ready::readable()), "Readable"),
            (UnixReady(Ready::writable()), "Writable"),
            (UnixReady::error(), "Error"),
            (UnixReady::hup(), "Hup"),
            #[allow(deprecated)]
            (UnixReady::aio(), "Aio"),
            #[cfg(any(target_os = "linux",
                target_os = "android", target_os = "solaris"))]
            (UnixReady::priority(), "Priority"),
        ];

        for &(flag, msg) in &flags {
            if self.contains(flag) {
                if one { write!(fmt, " | ")? }
                write!(fmt, "{}", msg)?;

                one = true
            }
        }

        if !one {
            fmt.write_str("(empty)")?;
        }

        Ok(())
    }
}
<commit_msg>unix: add a simple test to check the flags<commit_after>use event_imp::{Ready, ready_as_usize, ready_from_usize};

use std::ops;
use std::fmt;

/// Unix specific extensions to `Ready`
///
/// Provides additional readiness event kinds that are available on unix
/// platforms. Unix platforms are able to provide readiness events for
/// additional socket events, such as HUP and error.
///
/// HUP events occur when the remote end of a socket hangs up. In the TCP case,
/// this occurs when the remote end of a TCP socket shuts down writes.
///
/// Error events occur when the socket enters an error state. In this case, the
/// socket will also receive a readable or writable event. Reading or writing to
/// the socket will result in an error.
///
/// Conversion traits are implemented between `Ready` and `UnixReady`. See the
/// examples.
///
/// For high level documentation on polling and readiness, see [`Poll`].
///
/// # Examples
///
/// Most of the time, all that is needed is using bit operations
///
/// ```
/// use mio::Ready;
/// use mio::unix::UnixReady;
///
/// let ready = Ready::readable() | UnixReady::hup();
///
/// assert!(ready.is_readable());
/// assert!(UnixReady::from(ready).is_hup());
/// ```
///
/// Basic conversion between ready types.
///
/// ```
/// use mio::Ready;
/// use mio::unix::UnixReady;
///
/// // Start with a portable ready
/// let ready = Ready::readable();
///
/// // Convert to a unix ready, adding HUP
/// let mut unix_ready = UnixReady::from(ready) | UnixReady::hup();
///
/// unix_ready.insert(UnixReady::error());
///
/// // `unix_ready` maintains readable interest
/// assert!(unix_ready.is_readable());
/// assert!(unix_ready.is_hup());
/// assert!(unix_ready.is_error());
///
/// // Convert back to `Ready`
/// let ready = Ready::from(unix_ready);
///
/// // Readable is maintained
/// assert!(ready.is_readable());
/// ```
///
/// Registering readable and error interest on a socket
///
/// ```
/// # use std::error::Error;
/// # fn try_main() -> Result<(), Box<Error>> {
/// use mio::{Ready, Poll, PollOpt, Token};
/// use mio::net::TcpStream;
/// use mio::unix::UnixReady;
///
/// let addr = "216.58.193.68:80".parse()?;
/// let socket = TcpStream::connect(&addr)?;
///
/// let poll = Poll::new()?;
///
/// poll.register(&socket,
///               Token(0),
///               Ready::readable() | UnixReady::error(),
///               PollOpt::edge())?;
/// #     Ok(())
/// # }
/// #
/// # fn main() {
/// #     try_main().unwrap();
/// # }
/// ```
///
/// [`Poll`]: ../struct.Poll.html
/// [readiness]: struct.Poll.html#readiness-operations
#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord)]
pub struct UnixReady(Ready);

const ERROR: usize = 0b00_0100;
const HUP: usize   = 0b00_1000;

#[cfg(any(target_os = "dragonfly",
    target_os = "freebsd", target_os = "ios", target_os = "macos"))]
const AIO: usize   = 0b01_0000;

#[cfg(not(any(target_os = "dragonfly",
    target_os = "freebsd", target_os = "ios", target_os = "macos")))]
const AIO: usize   = 0b00_0000;

#[cfg(any(target_os = "freebsd"))]
const LIO: usize   = 0b10_0000;

#[cfg(not(any(target_os = "freebsd")))]
const LIO: usize   = 0b00_0000;

#[cfg(any(target_os = "linux", target_os = "android", target_os = "solaris"))]
const PRI: usize = 0b100_0000;

#[cfg(not(any(target_os = "linux", target_os = "android", target_os = "solaris")))]
const PRI: usize = 0;

// Export to support `Ready::all`
pub const READY_ALL: usize = ERROR | HUP | AIO | LIO | PRI;

#[test]
fn test_ready_all() {
    let readable = Ready::readable().as_usize();
    let writable = Ready::writable().as_usize();

    assert_eq!(
        READY_ALL | readable | writable,
        ERROR + HUP + AIO + LIO + PRI + readable + writable
    );

    // Issue #896.
    #[cfg(any(target_os = "linux", target_os = "android", target_os = "solaris"))]
    assert!(!Ready::from(UnixReady::priority()).is_writable());
}

impl UnixReady {
    /// Returns a `Ready` representing AIO completion readiness
    ///
    /// See [`Poll`] for more documentation on polling.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::unix::UnixReady;
    ///
    /// let ready = UnixReady::aio();
    ///
    /// assert!(ready.is_aio());
    /// ```
    ///
    /// [`Poll`]: ../struct.Poll.html
    #[inline]
    #[cfg(any(target_os = "dragonfly",
        target_os = "freebsd", target_os = "ios", target_os = "macos"))]
    pub fn aio() -> UnixReady {
        UnixReady(ready_from_usize(AIO))
    }

    #[cfg(not(any(target_os = "dragonfly",
        target_os = "freebsd", target_os = "ios", target_os = "macos")))]
    #[deprecated(since = "0.6.12", note = "this function is now platform specific")]
    #[doc(hidden)]
    pub fn aio() -> UnixReady {
        UnixReady(Ready::empty())
    }

    /// Returns a `Ready` representing error readiness.
    ///
    /// **Note that only readable and writable readiness is guaranteed to be
    /// supported on all platforms**. This means that `error` readiness
    /// should be treated as a hint. For more details, see [readiness] in the
    /// poll documentation.
    ///
    /// See [`Poll`] for more documentation on polling.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::unix::UnixReady;
    ///
    /// let ready = UnixReady::error();
    ///
    /// assert!(ready.is_error());
    /// ```
    ///
    /// [`Poll`]: ../struct.Poll.html
    /// [readiness]: ../struct.Poll.html#readiness-operations
    #[inline]
    pub fn error() -> UnixReady {
        UnixReady(ready_from_usize(ERROR))
    }

    /// Returns a `Ready` representing HUP readiness.
    ///
    /// A HUP (or hang-up) signifies that a stream socket **peer** closed the
    /// connection, or shut down the writing half of the connection.
    ///
    /// **Note that only readable and writable readiness is guaranteed to be
    /// supported on all platforms**. This means that `hup` readiness
    /// should be treated as a hint. For more details, see [readiness] in the
    /// poll documentation.
    ///
    /// See [`Poll`] for more documentation on polling.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::unix::UnixReady;
    ///
    /// let ready = UnixReady::hup();
    ///
    /// assert!(ready.is_hup());
    /// ```
    ///
    /// [`Poll`]: ../struct.Poll.html
    /// [readiness]: ../struct.Poll.html#readiness-operations
    #[inline]
    pub fn hup() -> UnixReady {
        UnixReady(ready_from_usize(HUP))
    }

    /// Returns a `Ready` representing LIO completion readiness
    ///
    /// See [`Poll`] for more documentation on polling.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::unix::UnixReady;
    ///
    /// let ready = UnixReady::lio();
    ///
    /// assert!(ready.is_lio());
    /// ```
    ///
    /// [`Poll`]: struct.Poll.html
    #[inline]
    #[cfg(any(target_os = "freebsd"))]
    pub fn lio() -> UnixReady {
        UnixReady(ready_from_usize(LIO))
    }

    /// Returns a `Ready` representing priority (`EPOLLPRI`) readiness
    ///
    /// See [`Poll`] for more documentation on polling.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::unix::UnixReady;
    ///
    /// let ready = UnixReady::priority();
    ///
    /// assert!(ready.is_priority());
    /// ```
    ///
    /// [`Poll`]: struct.Poll.html
    #[inline]
    #[cfg(any(target_os = "linux",
        target_os = "android", target_os = "solaris"))]
    pub fn priority() -> UnixReady {
        UnixReady(ready_from_usize(PRI))
    }

    /// Returns true if `Ready` contains AIO readiness
    ///
    /// See [`Poll`] for more documentation on polling.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::unix::UnixReady;
    ///
    /// let ready = UnixReady::aio();
    ///
    /// assert!(ready.is_aio());
    /// ```
    ///
    /// [`Poll`]: ../struct.Poll.html
    #[inline]
    #[cfg(any(target_os = "dragonfly",
        target_os = "freebsd", target_os = "ios", target_os = "macos"))]
    pub fn is_aio(&self) -> bool {
        self.contains(ready_from_usize(AIO))
    }

    #[deprecated(since = "0.6.12", note = "this function is now platform specific")]
    #[cfg(feature = "with-deprecated")]
    #[cfg(not(any(target_os = "dragonfly",
        target_os = "freebsd", target_os = "ios", target_os = "macos")))]
    #[doc(hidden)]
    pub fn is_aio(&self) -> bool {
        false
    }

    /// Returns true if the value includes error readiness
    ///
    /// **Note that only readable and writable readiness is guaranteed to be
    /// supported on all platforms**. This means that `error` readiness should
    /// be treated as a hint. For more details, see [readiness] in the poll
    /// documentation.
    ///
    /// See [`Poll`] for more documentation on polling.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::unix::UnixReady;
    ///
    /// let ready = UnixReady::error();
    ///
    /// assert!(ready.is_error());
    /// ```
    ///
    /// [`Poll`]: ../struct.Poll.html
    /// [readiness]: ../struct.Poll.html#readiness-operations
    #[inline]
    pub fn is_error(&self) -> bool {
        self.contains(ready_from_usize(ERROR))
    }

    /// Returns true if the value includes HUP readiness
    ///
    /// A HUP (or hang-up) signifies that a stream socket **peer** closed the
    /// connection, or shut down the writing half of the connection.
    ///
    /// **Note that only readable and writable readiness is guaranteed to be
    /// supported on all platforms**. This means that `hup` readiness
    /// should be treated as a hint. For more details, see [readiness] in the
    /// poll documentation.
    ///
    /// See [`Poll`] for more documentation on polling.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::unix::UnixReady;
    ///
    /// let ready = UnixReady::hup();
    ///
    /// assert!(ready.is_hup());
    /// ```
    ///
    /// [`Poll`]: ../struct.Poll.html
    /// [readiness]: ../struct.Poll.html#readiness-operations
    #[inline]
    pub fn is_hup(&self) -> bool {
        self.contains(ready_from_usize(HUP))
    }

    /// Returns true if `Ready` contains LIO readiness
    ///
    /// See [`Poll`] for more documentation on polling.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::unix::UnixReady;
    ///
    /// let ready = UnixReady::lio();
    ///
    /// assert!(ready.is_lio());
    /// ```
    #[inline]
    #[cfg(any(target_os = "freebsd"))]
    pub fn is_lio(&self) -> bool {
        self.contains(ready_from_usize(LIO))
    }

    /// Returns true if `Ready` contains priority (`EPOLLPRI`) readiness
    ///
    /// See [`Poll`] for more documentation on polling.
    ///
    /// # Examples
    ///
    /// ```
    /// use mio::unix::UnixReady;
    ///
    /// let ready = UnixReady::priority();
    ///
    /// assert!(ready.is_priority());
    /// ```
    ///
    /// [`Poll`]: struct.Poll.html
    #[inline]
    #[cfg(any(target_os = "linux",
        target_os = "android", target_os = "solaris"))]
    pub fn is_priority(&self) -> bool {
        self.contains(ready_from_usize(PRI))
    }
}

impl From<Ready> for UnixReady {
    fn from(src: Ready) -> UnixReady {
        UnixReady(src)
    }
}

impl From<UnixReady> for Ready {
    fn from(src: UnixReady) -> Ready {
        src.0
    }
}

impl ops::Deref for UnixReady {
    type Target = Ready;

    fn deref(&self) -> &Ready {
        &self.0
    }
}

impl ops::DerefMut for UnixReady {
    fn deref_mut(&mut self) -> &mut Ready {
        &mut self.0
    }
}

impl ops::BitOr for UnixReady {
    type Output = UnixReady;

    #[inline]
    fn bitor(self, other: UnixReady) -> UnixReady {
        (self.0 | other.0).into()
    }
}

impl ops::BitXor for UnixReady {
    type Output = UnixReady;

    #[inline]
    fn bitxor(self, other: UnixReady) -> UnixReady {
        (self.0 ^ other.0).into()
    }
}

impl ops::BitAnd for UnixReady {
    type Output = UnixReady;

    #[inline]
    fn bitand(self, other: UnixReady) -> UnixReady {
        (self.0 & other.0).into()
    }
}

impl ops::Sub for UnixReady {
    type Output = UnixReady;

    #[inline]
    fn sub(self, other: UnixReady) -> UnixReady {
        ready_from_usize(ready_as_usize(self.0) & !ready_as_usize(other.0)).into()
    }
}

#[deprecated(since = "0.6.10", note = "removed")]
#[cfg(feature = "with-deprecated")]
#[doc(hidden)]
impl ops::Not for UnixReady {
    type Output = UnixReady;

    #[inline]
    fn not(self) -> UnixReady {
        (!self.0).into()
    }
}

impl fmt::Debug for UnixReady {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let mut one = false;
        let flags = [
            (UnixReady(Ready::readable()), "Readable"),
            (UnixReady(Ready::writable()), "Writable"),
            (UnixReady::error(), "Error"),
            (UnixReady::hup(), "Hup"),
            #[allow(deprecated)]
            (UnixReady::aio(), "Aio"),
            #[cfg(any(target_os = "linux",
                target_os = "android", target_os = "solaris"))]
            (UnixReady::priority(), "Priority"),
        ];

        for &(flag, msg) in &flags {
            if self.contains(flag) {
                if one { write!(fmt, " | ")? }
                write!(fmt, "{}", msg)?;

                one = true
            }
        }

        if !one {
            fmt.write_str("(empty)")?;
        }

        Ok(())
    }
}
<|endoftext|>


<commit_before>trait IntConsts {
    static pure fn zero() -> self;
    static pure fn one() -> self;
}

trait FloatConsts: IntConsts {
    static pure fn pi() -> self;
    static pure fn frac_pi_2() -> self;
    static pure fn frac_pi_4() -> self;
    static pure fn frac_1_pi() -> self;
    static pure fn frac_2_pi() -> self;
    static pure fn frac_2_sqrtpi() -> self;
    static pure fn sqrt2() -> self;
    static pure fn frac_1_sqrt2() -> self;
    static pure fn e() -> self;
    static pure fn log2_e() -> self;
    static pure fn log10_e() -> self;
    static pure fn ln_2() -> self;
    static pure fn ln_10() -> self;
}

pub impl u8: IntConsts {
    #[inline(always)] static pure fn zero() -> u8 { 0u8 }
    #[inline(always)] static pure fn one()  -> u8 { 1u8 }
}

pub impl u16: IntConsts {
    #[inline(always)] static pure fn zero() -> u16 { 0u16 }
    #[inline(always)] static pure fn one()  -> u16 { 1u16 }
}

pub impl u32: IntConsts {
    #[inline(always)] static pure fn zero() -> u32 { 0u32 }
    #[inline(always)] static pure fn one()  -> u32 { 1u32 }
}

pub impl u64: IntConsts {
    #[inline(always)] static pure fn zero() -> u64 { 0u64 }
    #[inline(always)] static pure fn one()  -> u64 { 1u64 }
}

pub impl uint: IntConsts {
    #[inline(always)] static pure fn zero() -> uint { 0u }
    #[inline(always)] static pure fn one()  -> uint { 1u }
}

pub impl i8: IntConsts {
    #[inline(always)] static pure fn zero() -> i8 { 0i8 }
    #[inline(always)] static pure fn one()  -> i8 { 1i8 }
}

pub impl i16: IntConsts {
    #[inline(always)] static pure fn zero() -> i16 { 0i16 }
    #[inline(always)] static pure fn one()  -> i16 { 1i16 }
}

pub impl i32: IntConsts {
    #[inline(always)] static pure fn zero() -> i32 { 0i32 }
    #[inline(always)] static pure fn one()  -> i32 { 1i32 }
}

pub impl i64: IntConsts {
    #[inline(always)] static pure fn zero() -> i64 { 0i64 }
    #[inline(always)] static pure fn one()  -> i64 { 1i64 }
}

pub impl int: IntConsts {
    #[inline(always)] static pure fn zero() -> int { 0 }
    #[inline(always)] static pure fn one()  -> int { 1 }
}

pub impl f32: FloatConsts {
    #[inline(always)] static pure fn zero() -> f32 { 0f32 }
    #[inline(always)] static pure fn one()  -> f32 { 1f32 }

    #[inline(always)] static pure fn pi()               -> f32 { 3.14159265358979323846264338327950288_f32  }
    #[inline(always)] static pure fn frac_pi_2()        -> f32 { 1.57079632679489661923132169163975144_f32  }
    #[inline(always)] static pure fn frac_pi_4()        -> f32 { 0.785398163397448309615660845819875721_f32 }
    #[inline(always)] static pure fn frac_1_pi()        -> f32 { 0.318309886183790671537767526745028724_f32 }
    #[inline(always)] static pure fn frac_2_pi()        -> f32 { 0.636619772367581343075535053490057448_f32 }
    #[inline(always)] static pure fn frac_2_sqrtpi()    -> f32 { 1.12837916709551257389615890312154517_f32  }
    #[inline(always)] static pure fn sqrt2()            -> f32 { 1.41421356237309504880168872420969808_f32  }
    #[inline(always)] static pure fn frac_1_sqrt2()     -> f32 { 0.707106781186547524400844362104849039_f32 }
    #[inline(always)] static pure fn e()                -> f32 { 2.71828182845904523536028747135266250_f32  }
    #[inline(always)] static pure fn log2_e()           -> f32 { 1.44269504088896340735992468100189214_f32  }
    #[inline(always)] static pure fn log10_e()          -> f32 { 0.434294481903251827651128918916605082_f32 }
    #[inline(always)] static pure fn ln_2()             -> f32 { 0.693147180559945309417232121458176568_f32 }
    #[inline(always)] static pure fn ln_10()            -> f32 { 2.30258509299404568401799145468436421_f32  }
}

pub impl f64: FloatConsts {
    #[inline(always)] static pure fn zero() -> f64 { 0f64 }
    #[inline(always)] static pure fn one()  -> f64 { 1f64 }

    #[inline(always)] static pure fn pi()               -> f64 { 3.14159265358979323846264338327950288_f64  }
    #[inline(always)] static pure fn frac_pi_2()        -> f64 { 1.57079632679489661923132169163975144_f64  }
    #[inline(always)] static pure fn frac_pi_4()        -> f64 { 0.785398163397448309615660845819875721_f64 }
    #[inline(always)] static pure fn frac_1_pi()        -> f64 { 0.318309886183790671537767526745028724_f64 }
    #[inline(always)] static pure fn frac_2_pi()        -> f64 { 0.636619772367581343075535053490057448_f64 }
    #[inline(always)] static pure fn frac_2_sqrtpi()    -> f64 { 1.12837916709551257389615890312154517_f64  }
    #[inline(always)] static pure fn sqrt2()            -> f64 { 1.41421356237309504880168872420969808_f64  }
    #[inline(always)] static pure fn frac_1_sqrt2()     -> f64 { 0.707106781186547524400844362104849039_f64 }
    #[inline(always)] static pure fn e()                -> f64 { 2.71828182845904523536028747135266250_f64  }
    #[inline(always)] static pure fn log2_e()           -> f64 { 1.44269504088896340735992468100189214_f64  }
    #[inline(always)] static pure fn log10_e()          -> f64 { 0.434294481903251827651128918916605082_f64 }
    #[inline(always)] static pure fn ln_2()             -> f64 { 0.693147180559945309417232121458176568_f64 }
    #[inline(always)] static pure fn ln_10()            -> f64 { 2.30258509299404568401799145468436421_f64  }
}

pub impl float: FloatConsts {
    #[inline(always)] static pure fn zero() -> float { 0f }
    #[inline(always)] static pure fn one()  -> float { 1f }

    #[inline(always)] static pure fn pi()               -> float { 3.14159265358979323846264338327950288  }
    #[inline(always)] static pure fn frac_pi_2()        -> float { 1.57079632679489661923132169163975144  }
    #[inline(always)] static pure fn frac_pi_4()        -> float { 0.785398163397448309615660845819875721 }
    #[inline(always)] static pure fn frac_1_pi()        -> float { 0.318309886183790671537767526745028724 }
    #[inline(always)] static pure fn frac_2_pi()        -> float { 0.636619772367581343075535053490057448 }
    #[inline(always)] static pure fn frac_2_sqrtpi()    -> float { 1.12837916709551257389615890312154517  }
    #[inline(always)] static pure fn sqrt2()            -> float { 1.41421356237309504880168872420969808  }
    #[inline(always)] static pure fn frac_1_sqrt2()     -> float { 0.707106781186547524400844362104849039 }
    #[inline(always)] static pure fn e()                -> float { 2.71828182845904523536028747135266250  }
    #[inline(always)] static pure fn log2_e()           -> float { 1.44269504088896340735992468100189214  }
    #[inline(always)] static pure fn log10_e()          -> float { 0.434294481903251827651128918916605082 }
    #[inline(always)] static pure fn ln_2()             -> float { 0.693147180559945309417232121458176568 }
    #[inline(always)] static pure fn ln_10()            -> float { 2.30258509299404568401799145468436421  }
}<commit_msg>Add TypeConsts trait<commit_after>trait TypeConsts {
    static pure fn nil()   -> self;
    static pure fn ident() -> self;
}

trait IntConsts: TypeConsts {
    static pure fn zero() -> self;
    static pure fn one()  -> self;
}

trait FloatConsts: TypeConsts, IntConsts {
    static pure fn pi()             -> self;
    static pure fn frac_pi_2()      -> self;
    static pure fn frac_pi_4()      -> self;
    static pure fn frac_1_pi()      -> self;
    static pure fn frac_2_pi()      -> self;
    static pure fn frac_2_sqrtpi()  -> self;
    static pure fn sqrt2()          -> self;
    static pure fn frac_1_sqrt2()   -> self;
    static pure fn e()              -> self;
    static pure fn log2_e()         -> self;
    static pure fn log10_e()        -> self;
    static pure fn ln_2()           -> self;
    static pure fn ln_10()          -> self;
}

pub impl bool: TypeConsts {
    #[inline(always)] static pure fn nil()   -> bool { false }
    #[inline(always)] static pure fn ident() -> bool { true  }
}

pub impl u8: IntConsts {
    #[inline(always)] static pure fn nil()   -> u8 { 0u8 }
    #[inline(always)] static pure fn ident() -> u8 { 1u8 }
    #[inline(always)] static pure fn zero()  -> u8 { 0u8 }
    #[inline(always)] static pure fn one()   -> u8 { 1u8 }
}

pub impl u16: IntConsts {
    #[inline(always)] static pure fn nil()   -> u16 { 0u16 }
    #[inline(always)] static pure fn ident() -> u16 { 1u16 }
    #[inline(always)] static pure fn zero()  -> u16 { 0u16 }
    #[inline(always)] static pure fn one()   -> u16 { 1u16 }
}

pub impl u32: IntConsts {
    #[inline(always)] static pure fn nil()   -> u32 { 0u32 }
    #[inline(always)] static pure fn ident() -> u32 { 1u32 }
    #[inline(always)] static pure fn zero()  -> u32 { 0u32 }
    #[inline(always)] static pure fn one()   -> u32 { 1u32 }
}

pub impl u64: IntConsts {
    #[inline(always)] static pure fn nil()   -> u32 { 0u32 }
    #[inline(always)] static pure fn ident() -> u32 { 1u32 }
    #[inline(always)] static pure fn zero()  -> u64 { 0u64 }
    #[inline(always)] static pure fn one()   -> u64 { 1u64 }
}

pub impl uint: IntConsts {
    #[inline(always)] static pure fn nil()   -> uint { 0u }
    #[inline(always)] static pure fn ident() -> uint { 1u }
    #[inline(always)] static pure fn zero()  -> uint { 0u }
    #[inline(always)] static pure fn one()   -> uint { 1u }
}

pub impl i8: IntConsts {
    #[inline(always)] static pure fn nil()   -> i8 { 0i8 }
    #[inline(always)] static pure fn ident() -> i8 { 1i8 }
    #[inline(always)] static pure fn zero()  -> i8 { 0i8 }
    #[inline(always)] static pure fn one()   -> i8 { 1i8 }
}

pub impl i16: IntConsts {
    #[inline(always)] static pure fn nil()   -> i16 { 0i16 }
    #[inline(always)] static pure fn ident() -> i16 { 1i16 }
    #[inline(always)] static pure fn zero()  -> i16 { 0i16 }
    #[inline(always)] static pure fn one()   -> i16 { 1i16 }
}

pub impl i32: IntConsts {
    #[inline(always)] static pure fn nil()   -> i32 { 0i32 }
    #[inline(always)] static pure fn ident() -> i32 { 1i32 }
    #[inline(always)] static pure fn zero()  -> i32 { 0i32 }
    #[inline(always)] static pure fn one()   -> i32 { 1i32 }
}

pub impl i64: IntConsts {
    #[inline(always)] static pure fn nil()   -> i64 { 0i64 }
    #[inline(always)] static pure fn ident() -> i64 { 1i64 }
    #[inline(always)] static pure fn zero()  -> i64 { 0i64 }
    #[inline(always)] static pure fn one()   -> i64 { 1i64 }
}

pub impl int: IntConsts {
    #[inline(always)] static pure fn nil()   -> int { 0 }
    #[inline(always)] static pure fn ident() -> int { 1 }
    #[inline(always)] static pure fn zero()  -> int { 0 }
    #[inline(always)] static pure fn one()   -> int { 1 }
}

pub impl f32: FloatConsts {
    #[inline(always)] static pure fn nil()              -> f32 { 0f32 }
    #[inline(always)] static pure fn ident()            -> f32 { 1f32 }
    #[inline(always)] static pure fn zero()             -> f32 { 0f32 }
    #[inline(always)] static pure fn one()              -> f32 { 1f32 }
    #[inline(always)] static pure fn pi()               -> f32 { 3.14159265358979323846264338327950288_f32  }
    #[inline(always)] static pure fn frac_pi_2()        -> f32 { 1.57079632679489661923132169163975144_f32  }
    #[inline(always)] static pure fn frac_pi_4()        -> f32 { 0.785398163397448309615660845819875721_f32 }
    #[inline(always)] static pure fn frac_1_pi()        -> f32 { 0.318309886183790671537767526745028724_f32 }
    #[inline(always)] static pure fn frac_2_pi()        -> f32 { 0.636619772367581343075535053490057448_f32 }
    #[inline(always)] static pure fn frac_2_sqrtpi()    -> f32 { 1.12837916709551257389615890312154517_f32  }
    #[inline(always)] static pure fn sqrt2()            -> f32 { 1.41421356237309504880168872420969808_f32  }
    #[inline(always)] static pure fn frac_1_sqrt2()     -> f32 { 0.707106781186547524400844362104849039_f32 }
    #[inline(always)] static pure fn e()                -> f32 { 2.71828182845904523536028747135266250_f32  }
    #[inline(always)] static pure fn log2_e()           -> f32 { 1.44269504088896340735992468100189214_f32  }
    #[inline(always)] static pure fn log10_e()          -> f32 { 0.434294481903251827651128918916605082_f32 }
    #[inline(always)] static pure fn ln_2()             -> f32 { 0.693147180559945309417232121458176568_f32 }
    #[inline(always)] static pure fn ln_10()            -> f32 { 2.30258509299404568401799145468436421_f32  }
}

pub impl f64: FloatConsts {
    #[inline(always)] static pure fn nil()              -> f64 { 0f64 }
    #[inline(always)] static pure fn ident()            -> f64 { 1f64 }
    #[inline(always)] static pure fn zero()             -> f64 { 0f64 }
    #[inline(always)] static pure fn one()              -> f64 { 1f64 }
    #[inline(always)] static pure fn pi()               -> f64 { 3.14159265358979323846264338327950288_f64  }
    #[inline(always)] static pure fn frac_pi_2()        -> f64 { 1.57079632679489661923132169163975144_f64  }
    #[inline(always)] static pure fn frac_pi_4()        -> f64 { 0.785398163397448309615660845819875721_f64 }
    #[inline(always)] static pure fn frac_1_pi()        -> f64 { 0.318309886183790671537767526745028724_f64 }
    #[inline(always)] static pure fn frac_2_pi()        -> f64 { 0.636619772367581343075535053490057448_f64 }
    #[inline(always)] static pure fn frac_2_sqrtpi()    -> f64 { 1.12837916709551257389615890312154517_f64  }
    #[inline(always)] static pure fn sqrt2()            -> f64 { 1.41421356237309504880168872420969808_f64  }
    #[inline(always)] static pure fn frac_1_sqrt2()     -> f64 { 0.707106781186547524400844362104849039_f64 }
    #[inline(always)] static pure fn e()                -> f64 { 2.71828182845904523536028747135266250_f64  }
    #[inline(always)] static pure fn log2_e()           -> f64 { 1.44269504088896340735992468100189214_f64  }
    #[inline(always)] static pure fn log10_e()          -> f64 { 0.434294481903251827651128918916605082_f64 }
    #[inline(always)] static pure fn ln_2()             -> f64 { 0.693147180559945309417232121458176568_f64 }
    #[inline(always)] static pure fn ln_10()            -> f64 { 2.30258509299404568401799145468436421_f64  }
}

pub impl float: FloatConsts {
    #[inline(always)] static pure fn nil()              -> float { 0f }
    #[inline(always)] static pure fn ident()            -> float { 1f }
    #[inline(always)] static pure fn zero()             -> float { 0f }
    #[inline(always)] static pure fn one()              -> float { 1f }
    #[inline(always)] static pure fn pi()               -> float { 3.14159265358979323846264338327950288  }
    #[inline(always)] static pure fn frac_pi_2()        -> float { 1.57079632679489661923132169163975144  }
    #[inline(always)] static pure fn frac_pi_4()        -> float { 0.785398163397448309615660845819875721 }
    #[inline(always)] static pure fn frac_1_pi()        -> float { 0.318309886183790671537767526745028724 }
    #[inline(always)] static pure fn frac_2_pi()        -> float { 0.636619772367581343075535053490057448 }
    #[inline(always)] static pure fn frac_2_sqrtpi()    -> float { 1.12837916709551257389615890312154517  }
    #[inline(always)] static pure fn sqrt2()            -> float { 1.41421356237309504880168872420969808  }
    #[inline(always)] static pure fn frac_1_sqrt2()     -> float { 0.707106781186547524400844362104849039 }
    #[inline(always)] static pure fn e()                -> float { 2.71828182845904523536028747135266250  }
    #[inline(always)] static pure fn log2_e()           -> float { 1.44269504088896340735992468100189214  }
    #[inline(always)] static pure fn log10_e()          -> float { 0.434294481903251827651128918916605082 }
    #[inline(always)] static pure fn ln_2()             -> float { 0.693147180559945309417232121458176568 }
    #[inline(always)] static pure fn ln_10()            -> float { 2.30258509299404568401799145468436421  }
}<|endoftext|>


<commit_before>use tableau::tables::Table;

pub fn pivot_around(enter_var_index: usize, leave_var_index: usize, table: &mut Table) {
    let row_len = table.get_rows()[leave_var_index].len();
    let pivot_value = table.get_rows()[leave_var_index][enter_var_index];
    // Make all cells in pivot cell's column value 0.0
    for row_index in 0..table.get_rows().len() {
        if row_index != leave_var_index {
            let value_corres_pivot_column = table.get_rows()[row_index][enter_var_index];
            for i in 0..row_len {
                // value in line of pivot corresponding column of current cell *
                // value in current line corresponding pivot cell column
                let numerator = table.get_rows()[leave_var_index][i] *
                                value_corres_pivot_column;
                table.sub_cell(row_index, i, numerator / pivot_value);
            }
        }
    }
    // Make pivot cell value 1.0
    if pivot_value != 1.0 {
        for i in 0..row_len {
            table.div_cell(leave_var_index, i, pivot_value);
        }
    }
}
<commit_msg>Update pivot fuction comments.<commit_after>use tableau::tables::Table;

pub fn pivot_around(enter_var_index: usize, leave_var_index: usize, table: &mut Table) {
    let row_len = table.get_rows()[leave_var_index].len();
    let pivot_value = table.get_rows()[leave_var_index][enter_var_index];
    // Add multiples of pivot row to other rows to make their pivot column
    // entry 0.0.
    for row_index in 0..table.get_rows().len() {
        if row_index != leave_var_index {
            let value_corres_pivot_column = table.get_rows()[row_index][enter_var_index];
            for i in 0..row_len {
                // value in line of pivot corresponding column of current cell *
                // value in current line corresponding pivot cell column
                let numerator = table.get_rows()[leave_var_index][i] *
                                value_corres_pivot_column;
                table.sub_cell(row_index, i, numerator / pivot_value);
            }
        }
    }
    // Scale pivot row such that the pivot cell becomes 1.0.
    if pivot_value != 1.0 {
        for i in 0..row_len {
            table.div_cell(leave_var_index, i, pivot_value);
        }
    }
}
<|endoftext|>


<commit_before>use std::ops::{Add, Mul, Sub, Neg};
use variables::{LpExpression, LpConstraint, Constraint, LpContinuous, LpInteger, LpBinary};
use variables::LpExpression::*;
use std::rc::Rc;

/// Operations trait for any type implementing Into<LpExpressions> trait
pub trait LpOperations<T> where T: Into<LpExpression> {
    /// Less or equal binary syntax for LpExpression
    fn le(&self, lhs_expr: T) -> LpConstraint;
    /// Greater or equal binary syntax for LpExpression
    fn ge(&self, lhs_expr: T) -> LpConstraint;
    /// Equality binary syntax for LpExpression
    fn equal(&self, lhs_expr: T) -> LpConstraint;
}

/// Macro implementing Into<LpExpression> for types
macro_rules! to_into_expr {
    ($type_to:ty) => {
        impl Into<LpExpression> for $type_to {
            fn into(self) -> LpExpression {
                LitVal(self as f32)
            }
        }
    };
    ($type_to:ty, $wrapper: ident) => {
        impl Into<LpExpression> for $type_to {
            fn into(self) -> LpExpression {
                $wrapper(self)
            }
        }
        impl<'a> Into<LpExpression> for &'a $type_to {
            fn into(self) -> LpExpression {
                $wrapper(self.clone())
            }
        }
    };
}
to_into_expr!(f32);
to_into_expr!(i32);
to_into_expr!(LpBinary, ConsBin);
to_into_expr!(LpInteger, ConsInt);
to_into_expr!(LpContinuous, ConsCont);

/// Macro implementing binary operations for Into<LpExpression> or &Into<LpExpression>
macro_rules! operations_for_expr {
    ($trait_name: ident, $f_name: ident, $expr_type: ident) => {
        impl<T> $trait_name<T> for LpExpression where T: Into<LpExpression> + Clone {
            type Output = LpExpression;
            fn $f_name(self, _rhs: T) -> LpExpression {
                $expr_type(Rc::new(self.clone()), Rc::new(_rhs.into()))
            }
        }
        impl<'a, T> $trait_name<T> for &'a LpExpression where T: Into<LpExpression> + Clone {
            type Output = LpExpression;
            fn $f_name(self, _rhs: T) -> LpExpression {
                $expr_type(Rc::new(self.clone()), Rc::new(_rhs.into()))
            }
        }
    };
}

operations_for_expr!(Add, add, AddExpr);
operations_for_expr!(Sub, sub, SubExpr);
operations_for_expr!(Mul, mul, MulExpr);

/// Macro implementing a binary operation with a LpVars and a Into<Expression>
macro_rules! lpvars_operation_for_intoexpr {
    ($trait_name: ident, $f_name: ident, $lp_type: ident, $expr_type: ident, $cons_type: ident) => {
        impl<T> $trait_name<T> for $lp_type where T: Into<LpExpression> + Clone {
            type Output = LpExpression;
            fn $f_name(self, _rhs: T) -> LpExpression {
                $expr_type(Rc::new($cons_type(self.clone())), Rc::new(_rhs.into())).normalize()
            }
        }
        impl<'a, T> $trait_name<T> for &'a $lp_type where T: Into<LpExpression> + Clone {
            type Output = LpExpression;
            fn $f_name(self, _rhs: T) -> LpExpression {
                $expr_type(Rc::new($cons_type(self.clone())), Rc::new(_rhs.into())).normalize()
            }
        }
    };
}
lpvars_operation_for_intoexpr!(Mul, mul, LpInteger, MulExpr, ConsInt);
lpvars_operation_for_intoexpr!(Add, add, LpInteger, AddExpr, ConsInt);
lpvars_operation_for_intoexpr!(Sub, sub, LpInteger, SubExpr, ConsInt);

/// Macro implementing binary operations for a numeric type
macro_rules! numeric_operation_for_expr {
    ($num_type: ty, $trait_name: ident, $f_name: ident, $type_expr: ident) => {
        impl $trait_name<LpExpression> for $num_type {
            type Output = LpExpression;
            fn $f_name(self, _rhs: LpExpression) -> LpExpression {
                $type_expr(Rc::new(LitVal(self as f32)), Rc::new(_rhs))
            }
        }
        impl<'a> $trait_name<&'a LpExpression> for $num_type {
            type Output = LpExpression;
            fn $f_name(self, _rhs: &'a LpExpression) -> LpExpression {
                $type_expr(Rc::new(LitVal(self as f32)), Rc::new(_rhs.clone()))
            }
        }
    };
}
/// Macro implementing add, mul and sub for a specific numeric type
macro_rules! numeric_all_ops_for_expr {
    ($num_type: ty) => {
        numeric_operation_for_expr!($num_type, Add, add, AddExpr);
        numeric_operation_for_expr!($num_type, Mul, mul, MulExpr);
        numeric_operation_for_expr!($num_type, Sub, sub, SubExpr);
    }
}
numeric_all_ops_for_expr!(f32);
numeric_all_ops_for_expr!(i32);

/// &LpExpression to LpExpression
impl<'a> Into<LpExpression> for &'a LpExpression {
    fn into(self) -> LpExpression {
        self.clone()
    }
}

/// Implementing LpOperations trait for any Into<LpExpression>
impl<T: Into<LpExpression> + Clone, U> LpOperations<T> for U where U: Into<LpExpression> + Clone {
    fn le(&self, lhs_expr: T) -> LpConstraint {
        LpConstraint(self.clone().into(), Constraint::LessOrEqual, lhs_expr.clone().into()).generalize()
    }
    fn ge(&self, lhs_expr: T) -> LpConstraint {
        LpConstraint(self.clone().into(), Constraint::GreaterOrEqual, lhs_expr.clone().into()).generalize()
    }
    fn equal( &self, lhs_expr: T) -> LpConstraint {
        LpConstraint(self.clone().into(), Constraint::Equal, lhs_expr.clone().into()).generalize()
    }
}

impl<'a> Neg for &'a LpExpression {
    type Output = LpExpression;
    fn neg(self) -> LpExpression {
        MulExpr(Rc::new(LitVal(-1.0)), Rc::new(self.clone()))
    }
}

/// Macro implementing binary operations for a numeric type
macro_rules! numeric_operation_for_lpvars {
    ($num_type: ty, $trait_name: ident, $f_name: ident, $type_expr: ident, $lp_type: ty, $cons_expr: ident) => {
        impl $trait_name<$lp_type> for $num_type {
            type Output = LpExpression;
            fn $f_name(self, _rhs: $lp_type) -> LpExpression {
                $type_expr(Rc::new(LitVal(self as f32)), Rc::new($cons_expr(_rhs)))
            }
        }
        impl<'a> $trait_name<&'a $lp_type> for $num_type {
            type Output = LpExpression;
            fn $f_name(self, _rhs: &'a $lp_type) -> LpExpression {
                $type_expr(Rc::new(LitVal(self as f32)), Rc::new($cons_expr(_rhs.clone())))
            }
        }
    };
}

/// Macro implementing add, mul and sub for a specific numeric type
macro_rules! numeric_all_ops_for_lpvars{
    ($num_type: ty) => {
        numeric_operation_for_lpvars!($num_type, Add, add, AddExpr, LpInteger, ConsInt);
        numeric_operation_for_lpvars!($num_type, Add, add, AddExpr, LpBinary, ConsBin);
        numeric_operation_for_lpvars!($num_type, Add, add, AddExpr, LpContinuous, ConsCont);
        numeric_operation_for_lpvars!($num_type, Mul, mul, MulExpr, LpInteger, ConsInt);
        numeric_operation_for_lpvars!($num_type, Mul, mul, MulExpr, LpBinary, ConsBin);
        numeric_operation_for_lpvars!($num_type, Mul, mul, MulExpr, LpContinuous, ConsCont);
    }
}
numeric_all_ops_for_lpvars!(i32);
numeric_all_ops_for_lpvars!(f32);

<commit_msg>Add negation for Lp{Integer, Binary, Continuous}<commit_after>use std::ops::{Add, Mul, Sub, Neg};
use variables::{LpExpression, LpConstraint, Constraint, LpContinuous, LpInteger, LpBinary};
use variables::LpExpression::*;
use std::rc::Rc;

/// Operations trait for any type implementing Into<LpExpressions> trait
pub trait LpOperations<T> where T: Into<LpExpression> {
    /// Less or equal binary syntax for LpExpression
    fn le(&self, lhs_expr: T) -> LpConstraint;
    /// Greater or equal binary syntax for LpExpression
    fn ge(&self, lhs_expr: T) -> LpConstraint;
    /// Equality binary syntax for LpExpression
    fn equal(&self, lhs_expr: T) -> LpConstraint;
}

/// Macro implementing Into<LpExpression> for types
macro_rules! to_into_expr {
    ($type_to:ty) => {
        impl Into<LpExpression> for $type_to {
            fn into(self) -> LpExpression {
                LitVal(self as f32)
            }
        }
    };
    ($type_to:ty, $wrapper: ident) => {
        impl Into<LpExpression> for $type_to {
            fn into(self) -> LpExpression {
                $wrapper(self)
            }
        }
        impl<'a> Into<LpExpression> for &'a $type_to {
            fn into(self) -> LpExpression {
                $wrapper(self.clone())
            }
        }
    };
}
to_into_expr!(f32);
to_into_expr!(i32);
to_into_expr!(LpBinary, ConsBin);
to_into_expr!(LpInteger, ConsInt);
to_into_expr!(LpContinuous, ConsCont);

/// Macro implementing binary operations for Into<LpExpression> or &Into<LpExpression>
macro_rules! operations_for_expr {
    ($trait_name: ident, $f_name: ident, $expr_type: ident) => {
        impl<T> $trait_name<T> for LpExpression where T: Into<LpExpression> + Clone {
            type Output = LpExpression;
            fn $f_name(self, _rhs: T) -> LpExpression {
                $expr_type(Rc::new(self.clone()), Rc::new(_rhs.into()))
            }
        }
        impl<'a, T> $trait_name<T> for &'a LpExpression where T: Into<LpExpression> + Clone {
            type Output = LpExpression;
            fn $f_name(self, _rhs: T) -> LpExpression {
                $expr_type(Rc::new(self.clone()), Rc::new(_rhs.into()))
            }
        }
    };
}

operations_for_expr!(Add, add, AddExpr);
operations_for_expr!(Sub, sub, SubExpr);
operations_for_expr!(Mul, mul, MulExpr);

/// Macro implementing a binary operation with a LpVars and a Into<Expression>
macro_rules! lpvars_operation_for_intoexpr {
    ($trait_name: ident, $f_name: ident, $lp_type: ident, $expr_type: ident, $cons_type: ident) => {
        impl<T> $trait_name<T> for $lp_type where T: Into<LpExpression> + Clone {
            type Output = LpExpression;
            fn $f_name(self, _rhs: T) -> LpExpression {
                $expr_type(Rc::new($cons_type(self.clone())), Rc::new(_rhs.into())).normalize()
            }
        }
        impl<'a, T> $trait_name<T> for &'a $lp_type where T: Into<LpExpression> + Clone {
            type Output = LpExpression;
            fn $f_name(self, _rhs: T) -> LpExpression {
                $expr_type(Rc::new($cons_type(self.clone())), Rc::new(_rhs.into())).normalize()
            }
        }
    };
}
lpvars_operation_for_intoexpr!(Mul, mul, LpInteger, MulExpr, ConsInt);
lpvars_operation_for_intoexpr!(Add, add, LpInteger, AddExpr, ConsInt);
lpvars_operation_for_intoexpr!(Sub, sub, LpInteger, SubExpr, ConsInt);

/// Macro implementing binary operations for a numeric type
macro_rules! numeric_operation_for_expr {
    ($num_type: ty, $trait_name: ident, $f_name: ident, $type_expr: ident) => {
        impl $trait_name<LpExpression> for $num_type {
            type Output = LpExpression;
            fn $f_name(self, _rhs: LpExpression) -> LpExpression {
                $type_expr(Rc::new(LitVal(self as f32)), Rc::new(_rhs))
            }
        }
        impl<'a> $trait_name<&'a LpExpression> for $num_type {
            type Output = LpExpression;
            fn $f_name(self, _rhs: &'a LpExpression) -> LpExpression {
                $type_expr(Rc::new(LitVal(self as f32)), Rc::new(_rhs.clone()))
            }
        }
    };
}
/// Macro implementing add, mul and sub for a specific numeric type
macro_rules! numeric_all_ops_for_expr {
    ($num_type: ty) => {
        numeric_operation_for_expr!($num_type, Add, add, AddExpr);
        numeric_operation_for_expr!($num_type, Mul, mul, MulExpr);
        numeric_operation_for_expr!($num_type, Sub, sub, SubExpr);
    }
}
numeric_all_ops_for_expr!(f32);
numeric_all_ops_for_expr!(i32);

/// &LpExpression to LpExpression
impl<'a> Into<LpExpression> for &'a LpExpression {
    fn into(self) -> LpExpression {
        self.clone()
    }
}

/// Implementing LpOperations trait for any Into<LpExpression>
impl<T: Into<LpExpression> + Clone, U> LpOperations<T> for U where U: Into<LpExpression> + Clone {
    fn le(&self, lhs_expr: T) -> LpConstraint {
        LpConstraint(self.clone().into(), Constraint::LessOrEqual, lhs_expr.clone().into()).generalize()
    }
    fn ge(&self, lhs_expr: T) -> LpConstraint {
        LpConstraint(self.clone().into(), Constraint::GreaterOrEqual, lhs_expr.clone().into()).generalize()
    }
    fn equal( &self, lhs_expr: T) -> LpConstraint {
        LpConstraint(self.clone().into(), Constraint::Equal, lhs_expr.clone().into()).generalize()
    }
}

impl<'a> Neg for &'a LpExpression {
    type Output = LpExpression;
    fn neg(self) -> LpExpression {
        MulExpr(Rc::new(LitVal(-1.0)), Rc::new(self.clone()))
    }
}
macro_rules! neg_operation_for_lpvars {
    ($lp_var_type: ty, $constr_expr: ident) => {
        impl<'a> Neg for &'a $lp_var_type {
            type Output = LpExpression;
            fn neg(self) -> LpExpression {
                MulExpr(Rc::new(LitVal(-1.0)), Rc::new($constr_expr(self.clone())))
            }
        }
    }
}
neg_operation_for_lpvars!(LpInteger, ConsInt);
neg_operation_for_lpvars!(LpContinuous, ConsCont);
neg_operation_for_lpvars!(LpBinary, ConsBin);

/// Macro implementing binary operations for a numeric type
macro_rules! numeric_operation_for_lpvars {
    ($num_type: ty, $trait_name: ident, $f_name: ident, $type_expr: ident, $lp_type: ty, $cons_expr: ident) => {
        impl $trait_name<$lp_type> for $num_type {
            type Output = LpExpression;
            fn $f_name(self, _rhs: $lp_type) -> LpExpression {
                $type_expr(Rc::new(LitVal(self as f32)), Rc::new($cons_expr(_rhs)))
            }
        }
        impl<'a> $trait_name<&'a $lp_type> for $num_type {
            type Output = LpExpression;
            fn $f_name(self, _rhs: &'a $lp_type) -> LpExpression {
                $type_expr(Rc::new(LitVal(self as f32)), Rc::new($cons_expr(_rhs.clone())))
            }
        }
    };
}

/// Macro implementing add, mul and sub for a specific numeric type
macro_rules! numeric_all_ops_for_lpvars{
    ($num_type: ty) => {
        numeric_operation_for_lpvars!($num_type, Add, add, AddExpr, LpInteger, ConsInt);
        numeric_operation_for_lpvars!($num_type, Add, add, AddExpr, LpBinary, ConsBin);
        numeric_operation_for_lpvars!($num_type, Add, add, AddExpr, LpContinuous, ConsCont);
        numeric_operation_for_lpvars!($num_type, Mul, mul, MulExpr, LpInteger, ConsInt);
        numeric_operation_for_lpvars!($num_type, Mul, mul, MulExpr, LpBinary, ConsBin);
        numeric_operation_for_lpvars!($num_type, Mul, mul, MulExpr, LpContinuous, ConsCont);
    }
}
numeric_all_ops_for_lpvars!(i32);
numeric_all_ops_for_lpvars!(f32);
<|endoftext|>


<commit_before>pub mod Home {
    use chrono::{NaiveDate};

    pub struct NewsItem {
        pub title: String,
        pub date: NaiveDate,
    }

    fn changeFuncName() -> [NewsItem; 1] {
        let aNewsItems: [NewsItem; 1] = [
            NewsItem{
                title: String::from(
                    "Ethereum bounty contractshave now been added for anyone that would like to try to push the boundaries of human knowledge. The first contract is a competition for the correct solution to a³+b³+c³ = 33. Tweet me if you need assistance using these contracts!"),
                date: NaiveDate::from_ymd(2019, 1, 22)
            }
        ];
        aNewsItems
    }

}<commit_msg>snake_case home<commit_after>pub mod home {
    use chrono::{NaiveDate};

    pub struct NewsItem {
        pub title: String,
        pub date: NaiveDate,
    }

    fn changeFuncName() -> [NewsItem; 1] {
        let aNewsItems: [NewsItem; 1] = [
            NewsItem{
                title: String::from(
                    "Ethereum bounty contractshave now been added for anyone that would like to try to push the boundaries of human knowledge. The first contract is a competition for the correct solution to a³+b³+c³ = 33. Tweet me if you need assistance using these contracts!"),
                date: NaiveDate::from_ymd(2019, 1, 22)
            }
        ];
        aNewsItems
    }

}<|endoftext|>


<commit_before>#![doc(html_root_url="http://sfackler.github.io/rust-phf/doc/v0.7.14")]
extern crate phf;
extern crate phf_generator;

#[cfg(test)]
mod test;

use phf::PhfHash;
use std::collections::HashSet;
use std::hash::Hash;

/// A builder for the `phf::Map` type.
pub struct Map<K, V> {
    keys: Vec<K>,
    values: Vec<V>,
}

impl<K: Hash + PhfHash + Eq, V> Map<K, V> {
    /// Creates a new `phf::Map` builder.
    pub fn new() -> Map<K, V> {
        Map {
            keys: vec![],
            values: vec![],
        }
    }

    /// Adds an entry to the builder.
    pub fn entry(&mut self, key: K, value: V) -> &mut Map<K, V> {
        self.keys.push(key);
        self.values.push(value);
        self
    }

    /// Constructs a `phf::Map`.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate keys.
    pub fn build(self) -> phf::Map<K, V> {
        {
            let mut set = HashSet::new();
            for key in &self.keys {
                if !set.insert(key) {
                    panic!("duplicate key");
                }
            }
        }

        let state = phf_generator::generate_hash(&self.keys);

        let mut entries = self.keys
                              .into_iter()
                              .zip(self.values)
                              .map(Option::Some)
                              .collect::<Vec<_>>();
        let entries = state.map
                           .iter()
                           .map(|&i| entries[i].take().unwrap())
                           .collect();

        phf::Map {
            key: state.key,
            disps: phf::Slice::Dynamic(state.disps),
            entries: phf::Slice::Dynamic(entries),
        }
    }
}

/// A builder for the `phf::Set` type.
pub struct Set<T> {
    map: Map<T, ()>,
}

impl<T: Hash + PhfHash + Eq> Set<T> {
    /// Constructs a new `phf::Set` builder.
    pub fn new() -> Set<T> {
        Set { map: Map::new() }
    }

    /// Adds an entry to the builder.
    pub fn entry(&mut self, entry: T) -> &mut Set<T> {
        self.map.entry(entry, ());
        self
    }

    /// Constructs a `phf::Set`.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate entries.
    pub fn build(self) -> phf::Set<T> {
        phf::Set {
            map: self.map.build()
        }
    }
}

/// A builder for the `phf::OrderedMap` type.
pub struct OrderedMap<K, V> {
    keys: Vec<K>,
    values: Vec<V>,
}

impl<K: Hash + PhfHash + Eq, V> OrderedMap<K, V> {
    /// Constructs a enw `phf::OrderedMap` builder.
    pub fn new() -> OrderedMap<K, V> {
        OrderedMap {
            keys: vec![],
            values: vec![],
        }
    }

    /// Adds an entry to the builder.
    pub fn entry(&mut self, key: K, value: V) -> &mut OrderedMap<K, V> {
        self.keys.push(key);
        self.values.push(value);
        self
    }

    /// Constructs a `phf::OrderedMap`.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate keys.
    pub fn build(self) -> phf::OrderedMap<K, V> {
        {
            let mut set = HashSet::new();
            for key in &self.keys {
                if !set.insert(key) {
                    panic!("duplicate key");
                }
            }
        }

        let state = phf_generator::generate_hash(&self.keys);

        let entries = self.keys.into_iter().zip(self.values).collect();

        phf::OrderedMap {
            key: state.key,
            disps: phf::Slice::Dynamic(state.disps),
            idxs: phf::Slice::Dynamic(state.map),
            entries: phf::Slice::Dynamic(entries),
        }
    }
}

/// A builder for the `phf::OrderedSet` type.
pub struct OrderedSet<T> {
    map: OrderedMap<T, ()>,
}

impl<T: Hash + PhfHash + Eq> OrderedSet<T> {
    /// Constructs a new `phf::OrderedSet` builder.
    pub fn new() -> OrderedSet<T> {
        OrderedSet { map: OrderedMap::new() }
    }

    /// Adds an entry to the builder.
    pub fn entry(&mut self, entry: T) -> &mut OrderedSet<T> {
        self.map.entry(entry, ());
        self
    }

    /// Constructs a `phf::OrderedSet`.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate entries.
    pub fn build(self) -> phf::OrderedSet<T> {
        phf::OrderedSet {
            map: self.map.build(),
        }
    }
}
<commit_msg>Remove unnecessary qualifier<commit_after>#![doc(html_root_url="http://sfackler.github.io/rust-phf/doc/v0.7.14")]
extern crate phf;
extern crate phf_generator;

#[cfg(test)]
mod test;

use phf::PhfHash;
use std::collections::HashSet;
use std::hash::Hash;

/// A builder for the `phf::Map` type.
pub struct Map<K, V> {
    keys: Vec<K>,
    values: Vec<V>,
}

impl<K: Hash + PhfHash + Eq, V> Map<K, V> {
    /// Creates a new `phf::Map` builder.
    pub fn new() -> Map<K, V> {
        Map {
            keys: vec![],
            values: vec![],
        }
    }

    /// Adds an entry to the builder.
    pub fn entry(&mut self, key: K, value: V) -> &mut Map<K, V> {
        self.keys.push(key);
        self.values.push(value);
        self
    }

    /// Constructs a `phf::Map`.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate keys.
    pub fn build(self) -> phf::Map<K, V> {
        {
            let mut set = HashSet::new();
            for key in &self.keys {
                if !set.insert(key) {
                    panic!("duplicate key");
                }
            }
        }

        let state = phf_generator::generate_hash(&self.keys);

        let mut entries = self.keys
                              .into_iter()
                              .zip(self.values)
                              .map(Some)
                              .collect::<Vec<_>>();
        let entries = state.map
                           .iter()
                           .map(|&i| entries[i].take().unwrap())
                           .collect();

        phf::Map {
            key: state.key,
            disps: phf::Slice::Dynamic(state.disps),
            entries: phf::Slice::Dynamic(entries),
        }
    }
}

/// A builder for the `phf::Set` type.
pub struct Set<T> {
    map: Map<T, ()>,
}

impl<T: Hash + PhfHash + Eq> Set<T> {
    /// Constructs a new `phf::Set` builder.
    pub fn new() -> Set<T> {
        Set { map: Map::new() }
    }

    /// Adds an entry to the builder.
    pub fn entry(&mut self, entry: T) -> &mut Set<T> {
        self.map.entry(entry, ());
        self
    }

    /// Constructs a `phf::Set`.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate entries.
    pub fn build(self) -> phf::Set<T> {
        phf::Set {
            map: self.map.build()
        }
    }
}

/// A builder for the `phf::OrderedMap` type.
pub struct OrderedMap<K, V> {
    keys: Vec<K>,
    values: Vec<V>,
}

impl<K: Hash + PhfHash + Eq, V> OrderedMap<K, V> {
    /// Constructs a enw `phf::OrderedMap` builder.
    pub fn new() -> OrderedMap<K, V> {
        OrderedMap {
            keys: vec![],
            values: vec![],
        }
    }

    /// Adds an entry to the builder.
    pub fn entry(&mut self, key: K, value: V) -> &mut OrderedMap<K, V> {
        self.keys.push(key);
        self.values.push(value);
        self
    }

    /// Constructs a `phf::OrderedMap`.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate keys.
    pub fn build(self) -> phf::OrderedMap<K, V> {
        {
            let mut set = HashSet::new();
            for key in &self.keys {
                if !set.insert(key) {
                    panic!("duplicate key");
                }
            }
        }

        let state = phf_generator::generate_hash(&self.keys);

        let entries = self.keys.into_iter().zip(self.values).collect();

        phf::OrderedMap {
            key: state.key,
            disps: phf::Slice::Dynamic(state.disps),
            idxs: phf::Slice::Dynamic(state.map),
            entries: phf::Slice::Dynamic(entries),
        }
    }
}

/// A builder for the `phf::OrderedSet` type.
pub struct OrderedSet<T> {
    map: OrderedMap<T, ()>,
}

impl<T: Hash + PhfHash + Eq> OrderedSet<T> {
    /// Constructs a new `phf::OrderedSet` builder.
    pub fn new() -> OrderedSet<T> {
        OrderedSet { map: OrderedMap::new() }
    }

    /// Adds an entry to the builder.
    pub fn entry(&mut self, entry: T) -> &mut OrderedSet<T> {
        self.map.entry(entry, ());
        self
    }

    /// Constructs a `phf::OrderedSet`.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate entries.
    pub fn build(self) -> phf::OrderedSet<T> {
        phf::OrderedSet {
            map: self.map.build(),
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2018 Google LLC
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

//! Public key cryptography.

pub mod ec;
pub mod ed25519;

use boringssl::{CHeapWrapper, CStackWrapper};
use public::inner::BoringDerKey;
use util::Sealed;
use Error;

/// The public component of a public/private key pair.
pub trait PublicKey: Sealed + Sized {
    /// The type of the private component.
    type Private: PrivateKey<Public = Self>;
}

/// The private component of a public/private key pair.
pub trait PrivateKey: Sealed + Sized {
    /// The type of the public component.
    type Public: PublicKey<Private = Self>;

    /// Gets the public key corresponding to this private key.
    #[must_use]
    fn public(&self) -> Self::Public;
}

/// A public key which can be encoded as a DER object.
pub trait DerPublicKey: PublicKey + self::inner::DerKey {}

/// A private key which can be encoded as a DER object.
pub trait DerPrivateKey: PrivateKey + self::inner::DerKey {}

/// A cryptographic signature generated by a private key.
pub trait Signature: Sealed + Sized {
    /// The private key type used to generate this signature.
    type PrivateKey: PrivateKey;

    /// Sign a message.
    ///
    /// The input to this function is always a message, never a digest. If a
    /// signature scheme calls for hashing a message and signing the hash
    /// digest, `sign` is responsible for both hashing and signing.
    #[must_use]
    fn sign(key: &Self::PrivateKey, message: &[u8]) -> Result<Self, Error>;

    /// Verify a signature.
    ///
    /// The input to this function is always a message, never a digest. If a
    /// signature scheme calls for hashing a message and signing the hash
    /// digest, `verify` is responsible for both hashing and verifying the
    /// digest.
    #[must_use]
    fn verify(&self, key: &<Self::PrivateKey as PrivateKey>::Public, message: &[u8]) -> bool;
}

mod inner {
    use boringssl::{self, CHeapWrapper, CStackWrapper};
    use Error;

    /// A wrapper around a BoringSSL key object.
    pub trait BoringDerKey: Sized {
        // evp_pkey_assign_xxx
        fn pkey_assign(&self, pkey: &mut CHeapWrapper<boringssl::EVP_PKEY>);

        // evp_pkey_get_xxx; panics if the key is an EC key and doesn't have a group set,
        // and errors if pkey isn't the expected key type
        fn pkey_get(pkey: &mut CHeapWrapper<boringssl::EVP_PKEY>) -> Result<Self, Error>;

        // xxx_parse_private_key
        fn parse_private_key(cbs: &mut CStackWrapper<boringssl::CBS>) -> Result<Self, Error>;

        // xxx_marshal_private_key
        fn marshal_private_key(&self, cbb: &mut CStackWrapper<boringssl::CBB>)
            -> Result<(), Error>;
    }

    /// Properties shared by both public and private keys of a given type.
    pub trait DerKey {
        /// The underlying BoringSSL object wrapper type.
        type Boring: BoringDerKey;

        fn boring(&self) -> &Self::Boring;

        fn from_boring(Self::Boring) -> Self;
    }
}

/// Marshals a public key in DER format.
///
/// `marshal_public_key_der` marshals a public key as a DER-encoded
/// SubjectPublicKeyInfo structure as defined in [RFC 5280].
///
/// [RFC 5280]: https://tools.ietf.org/html/rfc5280
#[must_use]
pub fn marshal_public_key_der<P: DerPublicKey>(key: &P) -> Vec<u8> {
    let mut evp_pkey = CHeapWrapper::default();
    key.boring().pkey_assign(&mut evp_pkey);
    // cbb_new can only fail due to OOM
    let mut cbb = CStackWrapper::cbb_new(64).unwrap();
    evp_pkey
        .evp_marshal_public_key(&mut cbb)
        .expect("failed to marshal public key");
    cbb.cbb_with_data(<[u8]>::to_vec)
}

/// Marshals a private key in DER format.
///
/// `marshal_private_key_der` marshal a private key as a DER-encoded structure.
/// The exact structure encoded depends on the type of key:
/// - For an EC key, it is an ECPrivateKey structure as defined in [RFC 5915].
/// - For an RSA key, it is an RSAPrivateKey structure as defined in [RFC 3447].
///
/// [RFC 5915]: https://tools.ietf.org/html/rfc5915
/// [RFC 3447]: https://tools.ietf.org/html/rfc3447
#[must_use]
pub fn marshal_private_key_der<P: DerPrivateKey>(key: &P) -> Vec<u8> {
    // cbb_new can only fail due to OOM
    let mut cbb = CStackWrapper::cbb_new(64).unwrap();
    key.boring()
        .marshal_private_key(&mut cbb)
        .expect("failed to marshal private key");
    cbb.cbb_with_data(<[u8]>::to_vec)
}

/// Parses a public key in DER format.
///
/// `parse_public_key_der` parses a public key from a DER-encoded
/// SubjectPublicKeyInfo structure as defined in [RFC 5280].
///
/// # Elliptic Curve Keys
///
/// For Elliptic Curve keys ([`EcPubKey`]), the curve itself is validated. If
/// the curve is not known ahead of time, and any curve must be supported at
/// runtime, use the [`parse_public_key_der_any_curve`] function.
///
/// [RFC 5280]: https://tools.ietf.org/html/rfc5280
/// [`EcPubKey`]: ::public::ec::EcPubKey
/// [`parse_public_key_der_any_curve`]: ::public::ec::parse_public_key_der_any_curve
#[must_use]
pub fn parse_public_key_der<P: DerPublicKey>(bytes: &[u8]) -> Result<P, Error> {
    CStackWrapper::cbs_with_temp_buffer(bytes, |cbs| {
        let mut evp_pkey = CHeapWrapper::evp_parse_public_key(cbs)?;
        // NOTE: For EC, panics if evp_pkey doesn't have its group set. This is
        // OK because EVP_parse_public_key guarantees that the returned key has
        // its group set.
        let key = P::Boring::pkey_get(&mut evp_pkey)?;
        if cbs.cbs_len() > 0 {
            return Err(Error::new("malformed DER input".to_string()));
        }
        Ok(P::from_boring(key))
    })
}

/// Parses a private key in DER format.
///
/// `parse_private_key_der` parses a private key from a DER-encoded format. The
/// exact structure expected depends on the type of key:
/// - For an EC key, it is an ECPrivateKey structure as defined in [RFC 5915].
/// - For an RSA key, it is an RSAPrivateKey structure as defined in [RFC 3447].
///
/// # Elliptic Curve Keys
///
/// For Elliptic Curve keys ([`EcPrivKey`]), the curve itself is validated. If
/// the curve is not known ahead of time, and any curve must be supported at
/// runtime, use the [`parse_private_key_der_any_curve`] function.
///
/// [RFC 5915]: https://tools.ietf.org/html/rfc5915
/// [RFC 3447]: https://tools.ietf.org/html/rfc3447
/// [`EcPrivKey`]: ::public::ec::EcPrivKey
/// [`parse_private_key_der_any_curve`]: ::public::ec::parse_private_key_der_any_curve
#[must_use]
pub fn parse_private_key_der<P: DerPrivateKey>(bytes: &[u8]) -> Result<P, Error> {
    CStackWrapper::cbs_with_temp_buffer(bytes, |cbs| {
        let key = P::Boring::parse_private_key(cbs)?;
        if cbs.cbs_len() > 0 {
            return Err(Error::new("malformed DER input".to_string()));
        }
        Ok(P::from_boring(key))
    })
}

#[cfg(test)]
mod testutil {
    use super::*;

    /// Smoke test a signature scheme.
    ///
    /// `sig_from_bytes` takes a byte slice and converts it into a signature. If
    /// the byte slice is too long, it either truncate it or treats it as
    /// invalid (it's up to the caller). If the byte slice is too short, it
    /// fills in the remaining bytes with zeroes.
    pub fn test_signature_smoke<S: Signature, F: Fn(&[u8]) -> S, G: Fn(&S) -> &[u8]>(
        key: &S::PrivateKey,
        sig_from_bytes: F,
        bytes_from_sig: G,
    ) {
        // Sign the message, verify the signature, and return the signature.
        // Also verify that, if the wrong signature is used, the signature fails
        // to verify. Also verify that sig_from_bytes works.
        fn sign_and_verify<S: Signature, F: Fn(&[u8]) -> S, G: Fn(&S) -> &[u8]>(
            key: &S::PrivateKey,
            message: &[u8],
            sig_from_bytes: F,
            bytes_from_sig: G,
        ) -> S {
            let sig = S::sign(key, message).unwrap();
            assert!(sig.verify(&key.public(), message));
            let sig2 = S::sign(&key, bytes_from_sig(&sig)).unwrap();
            assert!(!sig2.verify(&key.public(), message));
            sig_from_bytes(bytes_from_sig(&sig))
        }

        // Sign an empty message, and verify the signature. Use the signature as
        // the next message to test, and repeat many times.
        let mut msg = Vec::new();
        for _ in 0..16 {
            msg = bytes_from_sig(&sign_and_verify(
                key,
                &msg,
                &sig_from_bytes,
                &bytes_from_sig,
            ))
            .to_vec();
        }
    }
}
<commit_msg>[public] Provide methods on PrivateKey and PublicKey for signing/verification<commit_after>// Copyright 2018 Google LLC
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

//! Public key cryptography.

pub mod ec;
pub mod ed25519;

use boringssl::{CHeapWrapper, CStackWrapper};
use public::inner::BoringDerKey;
use util::Sealed;
use Error;

/// The public component of a public/private key pair.
pub trait PublicKey: Sealed + Sized {
    /// The type of the private component.
    type Private: PrivateKey<Public = Self>;

    /// Verifies a message with this public key.
    ///
    /// `verify` verifies that a message was signed by the private key
    /// corresponding to this public key. It is equivalent to
    /// `signature.verify(self, message)`.
    #[must_use]
    fn verify<S: Signature<PrivateKey = Self::Private>>(&self, message: &[u8], signature: &S) -> bool {
        signature.verify(self, message)
    }
}

/// The private component of a public/private key pair.
pub trait PrivateKey: Sealed + Sized {
    /// The type of the public component.
    type Public: PublicKey<Private = Self>;

    /// Gets the public key corresponding to this private key.
    #[must_use]
    fn public(&self) -> Self::Public;

    /// Signs a message with this private key.
    ///
    /// `sign` signs a message with this key using the signature scheme `S`. It
    /// is equivalent to `S::sign(self, message)`.
    #[must_use]
    fn sign<S: Signature<PrivateKey = Self>>(&self, message: &[u8]) -> Result<S, Error> {
        S::sign(self, message)
    }
}

/// A public key which can be encoded as a DER object.
pub trait DerPublicKey: PublicKey + self::inner::DerKey {}

/// A private key which can be encoded as a DER object.
pub trait DerPrivateKey: PrivateKey + self::inner::DerKey {}

/// A cryptographic signature generated by a private key.
pub trait Signature: Sealed + Sized {
    /// The private key type used to generate this signature.
    type PrivateKey: PrivateKey;

    /// Sign a message.
    ///
    /// The input to this function is always a message, never a digest. If a
    /// signature scheme calls for hashing a message and signing the hash
    /// digest, `sign` is responsible for both hashing and signing.
    #[must_use]
    fn sign(key: &Self::PrivateKey, message: &[u8]) -> Result<Self, Error>;

    /// Verify a signature.
    ///
    /// The input to this function is always a message, never a digest. If a
    /// signature scheme calls for hashing a message and signing the hash
    /// digest, `verify` is responsible for both hashing and verifying the
    /// digest.
    #[must_use]
    fn verify(&self, key: &<Self::PrivateKey as PrivateKey>::Public, message: &[u8]) -> bool;
}

mod inner {
    use boringssl::{self, CHeapWrapper, CStackWrapper};
    use Error;

    /// A wrapper around a BoringSSL key object.
    pub trait BoringDerKey: Sized {
        // evp_pkey_assign_xxx
        fn pkey_assign(&self, pkey: &mut CHeapWrapper<boringssl::EVP_PKEY>);

        // evp_pkey_get_xxx; panics if the key is an EC key and doesn't have a group set,
        // and errors if pkey isn't the expected key type
        fn pkey_get(pkey: &mut CHeapWrapper<boringssl::EVP_PKEY>) -> Result<Self, Error>;

        // xxx_parse_private_key
        fn parse_private_key(cbs: &mut CStackWrapper<boringssl::CBS>) -> Result<Self, Error>;

        // xxx_marshal_private_key
        fn marshal_private_key(&self, cbb: &mut CStackWrapper<boringssl::CBB>)
            -> Result<(), Error>;
    }

    /// Properties shared by both public and private keys of a given type.
    pub trait DerKey {
        /// The underlying BoringSSL object wrapper type.
        type Boring: BoringDerKey;

        fn boring(&self) -> &Self::Boring;

        fn from_boring(Self::Boring) -> Self;
    }
}

/// Marshals a public key in DER format.
///
/// `marshal_public_key_der` marshals a public key as a DER-encoded
/// SubjectPublicKeyInfo structure as defined in [RFC 5280].
///
/// [RFC 5280]: https://tools.ietf.org/html/rfc5280
#[must_use]
pub fn marshal_public_key_der<P: DerPublicKey>(key: &P) -> Vec<u8> {
    let mut evp_pkey = CHeapWrapper::default();
    key.boring().pkey_assign(&mut evp_pkey);
    // cbb_new can only fail due to OOM
    let mut cbb = CStackWrapper::cbb_new(64).unwrap();
    evp_pkey
        .evp_marshal_public_key(&mut cbb)
        .expect("failed to marshal public key");
    cbb.cbb_with_data(<[u8]>::to_vec)
}

/// Marshals a private key in DER format.
///
/// `marshal_private_key_der` marshal a private key as a DER-encoded structure.
/// The exact structure encoded depends on the type of key:
/// - For an EC key, it is an ECPrivateKey structure as defined in [RFC 5915].
/// - For an RSA key, it is an RSAPrivateKey structure as defined in [RFC 3447].
///
/// [RFC 5915]: https://tools.ietf.org/html/rfc5915
/// [RFC 3447]: https://tools.ietf.org/html/rfc3447
#[must_use]
pub fn marshal_private_key_der<P: DerPrivateKey>(key: &P) -> Vec<u8> {
    // cbb_new can only fail due to OOM
    let mut cbb = CStackWrapper::cbb_new(64).unwrap();
    key.boring()
        .marshal_private_key(&mut cbb)
        .expect("failed to marshal private key");
    cbb.cbb_with_data(<[u8]>::to_vec)
}

/// Parses a public key in DER format.
///
/// `parse_public_key_der` parses a public key from a DER-encoded
/// SubjectPublicKeyInfo structure as defined in [RFC 5280].
///
/// # Elliptic Curve Keys
///
/// For Elliptic Curve keys ([`EcPubKey`]), the curve itself is validated. If
/// the curve is not known ahead of time, and any curve must be supported at
/// runtime, use the [`parse_public_key_der_any_curve`] function.
///
/// [RFC 5280]: https://tools.ietf.org/html/rfc5280
/// [`EcPubKey`]: ::public::ec::EcPubKey
/// [`parse_public_key_der_any_curve`]: ::public::ec::parse_public_key_der_any_curve
#[must_use]
pub fn parse_public_key_der<P: DerPublicKey>(bytes: &[u8]) -> Result<P, Error> {
    CStackWrapper::cbs_with_temp_buffer(bytes, |cbs| {
        let mut evp_pkey = CHeapWrapper::evp_parse_public_key(cbs)?;
        // NOTE: For EC, panics if evp_pkey doesn't have its group set. This is
        // OK because EVP_parse_public_key guarantees that the returned key has
        // its group set.
        let key = P::Boring::pkey_get(&mut evp_pkey)?;
        if cbs.cbs_len() > 0 {
            return Err(Error::new("malformed DER input".to_string()));
        }
        Ok(P::from_boring(key))
    })
}

/// Parses a private key in DER format.
///
/// `parse_private_key_der` parses a private key from a DER-encoded format. The
/// exact structure expected depends on the type of key:
/// - For an EC key, it is an ECPrivateKey structure as defined in [RFC 5915].
/// - For an RSA key, it is an RSAPrivateKey structure as defined in [RFC 3447].
///
/// # Elliptic Curve Keys
///
/// For Elliptic Curve keys ([`EcPrivKey`]), the curve itself is validated. If
/// the curve is not known ahead of time, and any curve must be supported at
/// runtime, use the [`parse_private_key_der_any_curve`] function.
///
/// [RFC 5915]: https://tools.ietf.org/html/rfc5915
/// [RFC 3447]: https://tools.ietf.org/html/rfc3447
/// [`EcPrivKey`]: ::public::ec::EcPrivKey
/// [`parse_private_key_der_any_curve`]: ::public::ec::parse_private_key_der_any_curve
#[must_use]
pub fn parse_private_key_der<P: DerPrivateKey>(bytes: &[u8]) -> Result<P, Error> {
    CStackWrapper::cbs_with_temp_buffer(bytes, |cbs| {
        let key = P::Boring::parse_private_key(cbs)?;
        if cbs.cbs_len() > 0 {
            return Err(Error::new("malformed DER input".to_string()));
        }
        Ok(P::from_boring(key))
    })
}

#[cfg(test)]
mod testutil {
    use super::*;

    /// Smoke test a signature scheme.
    ///
    /// `sig_from_bytes` takes a byte slice and converts it into a signature. If
    /// the byte slice is too long, it either truncate it or treats it as
    /// invalid (it's up to the caller). If the byte slice is too short, it
    /// fills in the remaining bytes with zeroes.
    pub fn test_signature_smoke<S: Signature, F: Fn(&[u8]) -> S, G: Fn(&S) -> &[u8]>(
        key: &S::PrivateKey,
        sig_from_bytes: F,
        bytes_from_sig: G,
    ) {
        // Sign the message, verify the signature, and return the signature.
        // Also verify that, if the wrong signature is used, the signature fails
        // to verify. Also verify that sig_from_bytes works.
        fn sign_and_verify<S: Signature, F: Fn(&[u8]) -> S, G: Fn(&S) -> &[u8]>(
            key: &S::PrivateKey,
            message: &[u8],
            sig_from_bytes: F,
            bytes_from_sig: G,
        ) -> S {
            let sig = S::sign(key, message).unwrap();
            assert!(sig.verify(&key.public(), message));
            // Make sure the PrivateKey::sign and PublicKey::verify convenience
            // functions also work.
            let sig = key.sign::<S>(message).unwrap();
            assert!(key.public().verify(message, &sig));
            let sig2 = S::sign(&key, bytes_from_sig(&sig)).unwrap();
            assert!(!sig2.verify(&key.public(), message));
            // Make sure the PrivateKey::sign and PublicKey::verify convenience
            // functions also work.
            let sig2 = key.sign::<S>(bytes_from_sig(&sig)).unwrap();
            assert!(!key.public().verify(message, &sig2));
            sig_from_bytes(bytes_from_sig(&sig))
        }

        // Sign an empty message, and verify the signature. Use the signature as
        // the next message to test, and repeat many times.
        let mut msg = Vec::new();
        for _ in 0..16 {
            msg = bytes_from_sig(&sign_and_verify(
                key,
                &msg,
                &sig_from_bytes,
                &bytes_from_sig,
            ))
            .to_vec();
        }
    }
}
<|endoftext|>