<commit_before>//! # Slog -  Structured, composable logging for Rust

#![warn(missing_docs)]

extern crate crossbeam;
extern crate chrono;
extern crate rustc_serialize as serialize;

#[macro_use]
extern crate error_chain;

use std::sync::Arc;
use std::fmt;
use std::str::FromStr;
use std::ascii::AsciiExt;

/// Convenience function for building `&[OwnedKeyValue]`
///
/// ```
/// #[macro_use]
/// extern crate slog;
///
/// fn main() {
///     let drain = slog::discard();
///     let root = slog::Logger::root(drain, o!("key1" => "value1", "key2" => "value2"));
/// }
/// ```
#[macro_export]
macro_rules! o(
    () => {
        vec![]
    };
    ($($k:expr => $v:expr),*) => {
        {
        use std;
        vec![$(($k, std::boxed::Box::new($v))),*]
        }
    };
);

/// Log message of a given level
///
/// Use wrappers `error!`, `warn!` etc. instead
///
/// The `max_level_*` features can be used to statically disable logging at
/// various levels.
///
/// ```
/// #[macro_use]
/// extern crate slog;
///
/// fn main() {
///     let drain = slog::discard();
///     let root = slog::Logger::root(drain, o!("key1" => "value1", "key2" => "value2"));
///     info!(root, "test info log", "log-key" => true);
/// }
/// ```
#[macro_export]
macro_rules! log(
    ($l:expr, $lvl:expr, $msg:expr) => {
        let lvl = $lvl;
        if lvl.as_usize() <= $crate::__slog_static_max_level().as_usize() {
            $l.log(
                &$crate::Record::new(
                    lvl,
                    &$msg,
                    file!(),
                    line!(),
                    module_path!(),
                    &[]
                )
            )
        }
    };
    ($l:expr, $lvl:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        let lvl = $lvl;
        if lvl.as_usize() <= $crate::__slog_static_max_level().as_usize() {
            $l.log(
                &$crate::Record::new(
                    $lvl,
                    &$msg,
                    file!(),
                    line!(),
                    module_path!(),
                    &[$(($k, &$v)),*]
                )
            )
        }
    };
);

/// Log message of a given level
///
/// Prefer shorter version, unless it clashes with
/// existing `log` crate macro.
#[macro_export]
macro_rules! slog_log(
    ($l:expr, $lvl:expr, $msg:expr) => {
        $l.log(
            &$crate::Record::new(
                $lvl,
                &$msg,
                file!(),
                line!(),
                module_path!(),
                &[]
            )
        )
    };
    ($l:expr, $lvl:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        $l.log(
            &$crate::Record::new(
                $lvl,
                &$msg,
                file!(),
                line!(),
                module_path!(),
                &[$(($k, &$v)),*]
            )
        )
    };
);

/// Log critical level record
#[macro_export]
macro_rules! crit(
    ($l:expr, $msg:expr) => {
        log!($l, $crate::Level::Critical, $msg)
    };
    ($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        log!($l, $crate::Level::Critical, $msg, $($k => $v),*)
    };
);

/// Log critical level record (alias)
///
/// Prefer shorter version, unless it clashes with
/// existing `log` crate macro.
#[macro_export]
macro_rules! slog_crit(
    ($l:expr, $msg:expr) => {
        slog_log!($l, $crate::Level::Critical, $msg)
    };
    ($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        slog_log!($l, $crate::Level::Critical, $msg, $($k => $v),*)
    };
);

/// Log error level record
#[macro_export]
macro_rules! error(
    ($l:expr, $msg:expr) => {
        log!($l, $crate::Level::Error, $msg)
    };
    ($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        log!($l, $crate::Level::Error, $msg, $($k => $v),*)
    };
);

/// Log error level record
///
/// Prefer shorter version, unless it clashes with
/// existing `log` crate macro.
#[macro_export]
macro_rules! slog_error(
    ($l:expr, $msg:expr) => {
        slog_log!($l, $crate::Level::Error, $msg)
    };
    ($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        slog_log!($l, $crate::Level::Error, $msg, $($k => $v),*)
    };
);

/// Log warning level record
#[macro_export]
macro_rules! warn(
    ($l:expr, $msg:expr) => {
        log!($l, $crate::Level::Warning, $msg)
    };
    ($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        log!($l, $crate::Level::Warning, $msg, $($k => $v),*)
    };
);

/// Log warning level record (alias)
///
/// Prefer shorter version, unless it clashes with
/// existing `log` crate macro.
#[macro_export]
macro_rules! slog_warn(
    ($l:expr, $msg:expr) => {
    slog_log!($l, $crate::Level::Warning, $msg)
};
($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        slog_log!($l, $crate::Level::Warning, $msg, $($k => $v),*)
    };
);

/// Log info level record
#[macro_export]
macro_rules! info(
    ($l:expr, $msg:expr) => {
        log!($l, $crate::Level::Info, $msg)
    };
    ($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        log!($l, $crate::Level::Info, $msg, $($k => $v),*)
    };
);

/// Log info level record (alias)
///
/// Prefer shorter version, unless it clashes with
/// existing `log` crate macro.
#[macro_export]
macro_rules! slog_info(
    ($l:expr, $msg:expr) => {
        slog_log!($l, $crate::Level::Info, $msg)
    };
    ($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        slog_log!($l, $crate::Level::Info, $msg, $($k => $v),*)
    };
);

/// Log debug level record
#[macro_export]
macro_rules! debug(
    ($l:expr, $msg:expr) => {
        log!($l, $crate::Level::Debug, $msg)
    };
    ($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        log!($l, $crate::Level::Debug, $msg, $($k => $v),*)
    };
);

/// Log debug level record (alias)
///
/// Prefer shorter version, unless it clashes with
/// existing `log` crate macro.
#[macro_export]
macro_rules! slog_debug(
    ($l:expr, $msg:expr) => {
        slog_log!($l, $crate::Level::Debug, $msg)
    };
    ($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        slog_log!($l, $crate::Level::Debug, $msg, $($k => $v),*)
    };
);

/// Log trace level record
#[macro_export]
macro_rules! trace(
    ($l:expr, $msg:expr) => {
        log!($l, $crate::Level::Trace, $msg)
    };
    ($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        log!($l, $crate::Level::Trace, $msg, $($k => $v),*)
    };
);

/// Log trace level record (alias)
///
/// Prefer shorter version, unless it clashes with
/// existing `log` crate macro.
#[macro_export]
macro_rules! slog_trace(
    ($l:expr, $msg:expr) => {
        slog_log!($l, $crate::Level::Trace, $msg)
    };
    ($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        slog_log!($l, $crate::Level::Trace, $msg, $($k => $v),*)
    };
);

/// Serialization
pub mod ser;

/// Output formating
pub mod format;

pub use ser::{PushLazy, ValueSerializer, Serializer, Serialize};

include!("_level.rs");
include!("_logger.rs");
include!("_drain.rs");

/// Key value pair that can be part of a logging record
pub type BorrowedKeyValue<'a> = (&'static str, &'a ser::Serialize);

/// Key value pair that can be owned by `Logger`
///
/// See `o!(...)` macro.
pub type OwnedKeyValue = (&'static str, Box<ser::SyncSerialize>);

/// Chain of `OwnedKeyValue`-s of a `Logger` and its ancestors
pub struct OwnedKeyValueList {
    parent: Option<Arc<OwnedKeyValueList>>,
    values: Vec<OwnedKeyValue>,
}

impl OwnedKeyValueList {
    /// New `OwnedKeyValue` with a parent
    pub fn new(values: Vec<OwnedKeyValue>, parent: Arc<OwnedKeyValueList>) -> Self {
        OwnedKeyValueList {
            parent: Some(parent),
            values: values,
        }
    }

    /// New `OwnedKeyValue` without a parent (root)
    pub fn root(values: Vec<OwnedKeyValue>) -> Self {
        OwnedKeyValueList {
            parent: None,
            values: values,
        }
    }

    /// Iterator over `OwnedKeyValue`-s
    pub fn iter(&self) -> OwnedKeyValueListIterator {
        OwnedKeyValueListIterator::new(self)
    }
}

/// Iterator over `OwnedKeyValue`-s
pub struct OwnedKeyValueListIterator<'a> {
    next_node: &'a Option<Arc<OwnedKeyValueList>>,
    iter: std::slice::Iter<'a, OwnedKeyValue>,
}

impl<'a> OwnedKeyValueListIterator<'a> {
    fn new(node: &'a OwnedKeyValueList) -> Self {
        OwnedKeyValueListIterator {
            next_node: &node.parent,
            iter: node.values.iter(),
        }
    }
}

impl<'a> Iterator for OwnedKeyValueListIterator<'a> {
    type Item = &'a OwnedKeyValue;
    fn next(&mut self) -> Option<Self::Item> {
        loop {
            match self.iter.next() {
                Some(x) => return Some(&*x),
                None => {
                    match self.next_node {
                        &Some(ref node) => {
                            self.iter = node.values.iter();
                            self.next_node = &node.parent;
                        }
                        &None => return None,
                    }
                }
            }
        }
    }
}

#[inline(always)]
#[doc(hidden)]
/// Not an API
pub fn __slog_static_max_level() -> FilterLevel {
    if !cfg!(debug_assertions) {
        if cfg!(feature = "release_max_level_off") {
            return FilterLevel::Off
        } else if cfg!(feature = "release_max_level_error") {
            return FilterLevel::Error
        } else if cfg!(feature = "release_max_level_warn") {
            return FilterLevel::Warning
        } else if cfg!(feature = "release_max_level_info") {
            return FilterLevel::Info
        } else if cfg!(feature = "release_max_level_debug") {
            return FilterLevel::Debug
        } else if cfg!(feature = "release_max_level_trace") {
            return FilterLevel::Trace
        }
    }
    if cfg!(feature = "max_level_off") {
        FilterLevel::Off
    } else if cfg!(feature = "max_level_error") {
        FilterLevel::Error
    } else if cfg!(feature = "max_level_warn") {
        FilterLevel::Warning
    } else if cfg!(feature = "max_level_info") {
        FilterLevel::Info
    } else if cfg!(feature = "max_level_debug") {
        FilterLevel::Debug
    } else {
        FilterLevel::Trace
    }
}

#[cfg(test)]
mod tests;
<commit_msg>docs: Tiny fix<commit_after>//! # Slog -  Structured, composable logging for Rust

#![warn(missing_docs)]

extern crate crossbeam;
extern crate chrono;
extern crate rustc_serialize as serialize;

#[macro_use]
extern crate error_chain;

use std::sync::Arc;
use std::fmt;
use std::str::FromStr;
use std::ascii::AsciiExt;

/// Convenience function for building `&[OwnedKeyValue]`
///
/// ```
/// #[macro_use]
/// extern crate slog;
///
/// fn main() {
///     let drain = slog::discard();
///     let root = slog::Logger::root(drain, o!("key1" => "value1", "key2" => "value2"));
/// }
/// ```
#[macro_export]
macro_rules! o(
    () => {
        vec![]
    };
    ($($k:expr => $v:expr),*) => {
        {
        use std;
        vec![$(($k, std::boxed::Box::new($v))),*]
        }
    };
);

/// Log message of a given level
///
/// Use wrappers `error!`, `warn!` etc. instead
///
/// The `max_level_*` features can be used to statically disable logging at
/// various levels.
///
/// ```
/// #[macro_use]
/// extern crate slog;
///
/// fn main() {
///     let drain = slog::discard();
///     let root = slog::Logger::root(drain, o!("key1" => "value1", "key2" => "value2"));
///     info!(root, "test info log", "log-key" => true);
/// }
/// ```
#[macro_export]
macro_rules! log(
    ($l:expr, $lvl:expr, $msg:expr) => {
        let lvl = $lvl;
        if lvl.as_usize() <= $crate::__slog_static_max_level().as_usize() {
            $l.log(
                &$crate::Record::new(
                    lvl,
                    &$msg,
                    file!(),
                    line!(),
                    module_path!(),
                    &[]
                )
            )
        }
    };
    ($l:expr, $lvl:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        let lvl = $lvl;
        if lvl.as_usize() <= $crate::__slog_static_max_level().as_usize() {
            $l.log(
                &$crate::Record::new(
                    $lvl,
                    &$msg,
                    file!(),
                    line!(),
                    module_path!(),
                    &[$(($k, &$v)),*]
                )
            )
        }
    };
);

/// Log message of a given level (alias)
///
/// Prefer shorter version, unless it clashes with
/// existing `log` crate macro.
#[macro_export]
macro_rules! slog_log(
    ($l:expr, $lvl:expr, $msg:expr) => {
        $l.log(
            &$crate::Record::new(
                $lvl,
                &$msg,
                file!(),
                line!(),
                module_path!(),
                &[]
            )
        )
    };
    ($l:expr, $lvl:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        $l.log(
            &$crate::Record::new(
                $lvl,
                &$msg,
                file!(),
                line!(),
                module_path!(),
                &[$(($k, &$v)),*]
            )
        )
    };
);

/// Log critical level record
#[macro_export]
macro_rules! crit(
    ($l:expr, $msg:expr) => {
        log!($l, $crate::Level::Critical, $msg)
    };
    ($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        log!($l, $crate::Level::Critical, $msg, $($k => $v),*)
    };
);

/// Log critical level record (alias)
///
/// Prefer shorter version, unless it clashes with
/// existing `log` crate macro.
#[macro_export]
macro_rules! slog_crit(
    ($l:expr, $msg:expr) => {
        slog_log!($l, $crate::Level::Critical, $msg)
    };
    ($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        slog_log!($l, $crate::Level::Critical, $msg, $($k => $v),*)
    };
);

/// Log error level record
#[macro_export]
macro_rules! error(
    ($l:expr, $msg:expr) => {
        log!($l, $crate::Level::Error, $msg)
    };
    ($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        log!($l, $crate::Level::Error, $msg, $($k => $v),*)
    };
);

/// Log error level record
///
/// Prefer shorter version, unless it clashes with
/// existing `log` crate macro.
#[macro_export]
macro_rules! slog_error(
    ($l:expr, $msg:expr) => {
        slog_log!($l, $crate::Level::Error, $msg)
    };
    ($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        slog_log!($l, $crate::Level::Error, $msg, $($k => $v),*)
    };
);

/// Log warning level record
#[macro_export]
macro_rules! warn(
    ($l:expr, $msg:expr) => {
        log!($l, $crate::Level::Warning, $msg)
    };
    ($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        log!($l, $crate::Level::Warning, $msg, $($k => $v),*)
    };
);

/// Log warning level record (alias)
///
/// Prefer shorter version, unless it clashes with
/// existing `log` crate macro.
#[macro_export]
macro_rules! slog_warn(
    ($l:expr, $msg:expr) => {
    slog_log!($l, $crate::Level::Warning, $msg)
};
($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        slog_log!($l, $crate::Level::Warning, $msg, $($k => $v),*)
    };
);

/// Log info level record
#[macro_export]
macro_rules! info(
    ($l:expr, $msg:expr) => {
        log!($l, $crate::Level::Info, $msg)
    };
    ($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        log!($l, $crate::Level::Info, $msg, $($k => $v),*)
    };
);

/// Log info level record (alias)
///
/// Prefer shorter version, unless it clashes with
/// existing `log` crate macro.
#[macro_export]
macro_rules! slog_info(
    ($l:expr, $msg:expr) => {
        slog_log!($l, $crate::Level::Info, $msg)
    };
    ($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        slog_log!($l, $crate::Level::Info, $msg, $($k => $v),*)
    };
);

/// Log debug level record
#[macro_export]
macro_rules! debug(
    ($l:expr, $msg:expr) => {
        log!($l, $crate::Level::Debug, $msg)
    };
    ($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        log!($l, $crate::Level::Debug, $msg, $($k => $v),*)
    };
);

/// Log debug level record (alias)
///
/// Prefer shorter version, unless it clashes with
/// existing `log` crate macro.
#[macro_export]
macro_rules! slog_debug(
    ($l:expr, $msg:expr) => {
        slog_log!($l, $crate::Level::Debug, $msg)
    };
    ($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        slog_log!($l, $crate::Level::Debug, $msg, $($k => $v),*)
    };
);

/// Log trace level record
#[macro_export]
macro_rules! trace(
    ($l:expr, $msg:expr) => {
        log!($l, $crate::Level::Trace, $msg)
    };
    ($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        log!($l, $crate::Level::Trace, $msg, $($k => $v),*)
    };
);

/// Log trace level record (alias)
///
/// Prefer shorter version, unless it clashes with
/// existing `log` crate macro.
#[macro_export]
macro_rules! slog_trace(
    ($l:expr, $msg:expr) => {
        slog_log!($l, $crate::Level::Trace, $msg)
    };
    ($l:expr, $msg:expr, $($k:expr => $v:expr),*) => {
        slog_log!($l, $crate::Level::Trace, $msg, $($k => $v),*)
    };
);

/// Serialization
pub mod ser;

/// Output formating
pub mod format;

pub use ser::{PushLazy, ValueSerializer, Serializer, Serialize};

include!("_level.rs");
include!("_logger.rs");
include!("_drain.rs");

/// Key value pair that can be part of a logging record
pub type BorrowedKeyValue<'a> = (&'static str, &'a ser::Serialize);

/// Key value pair that can be owned by `Logger`
///
/// See `o!(...)` macro.
pub type OwnedKeyValue = (&'static str, Box<ser::SyncSerialize>);

/// Chain of `OwnedKeyValue`-s of a `Logger` and its ancestors
pub struct OwnedKeyValueList {
    parent: Option<Arc<OwnedKeyValueList>>,
    values: Vec<OwnedKeyValue>,
}

impl OwnedKeyValueList {
    /// New `OwnedKeyValue` with a parent
    pub fn new(values: Vec<OwnedKeyValue>, parent: Arc<OwnedKeyValueList>) -> Self {
        OwnedKeyValueList {
            parent: Some(parent),
            values: values,
        }
    }

    /// New `OwnedKeyValue` without a parent (root)
    pub fn root(values: Vec<OwnedKeyValue>) -> Self {
        OwnedKeyValueList {
            parent: None,
            values: values,
        }
    }

    /// Iterator over `OwnedKeyValue`-s
    pub fn iter(&self) -> OwnedKeyValueListIterator {
        OwnedKeyValueListIterator::new(self)
    }
}

/// Iterator over `OwnedKeyValue`-s
pub struct OwnedKeyValueListIterator<'a> {
    next_node: &'a Option<Arc<OwnedKeyValueList>>,
    iter: std::slice::Iter<'a, OwnedKeyValue>,
}

impl<'a> OwnedKeyValueListIterator<'a> {
    fn new(node: &'a OwnedKeyValueList) -> Self {
        OwnedKeyValueListIterator {
            next_node: &node.parent,
            iter: node.values.iter(),
        }
    }
}

impl<'a> Iterator for OwnedKeyValueListIterator<'a> {
    type Item = &'a OwnedKeyValue;
    fn next(&mut self) -> Option<Self::Item> {
        loop {
            match self.iter.next() {
                Some(x) => return Some(&*x),
                None => {
                    match self.next_node {
                        &Some(ref node) => {
                            self.iter = node.values.iter();
                            self.next_node = &node.parent;
                        }
                        &None => return None,
                    }
                }
            }
        }
    }
}

#[inline(always)]
#[doc(hidden)]
/// Not an API
pub fn __slog_static_max_level() -> FilterLevel {
    if !cfg!(debug_assertions) {
        if cfg!(feature = "release_max_level_off") {
            return FilterLevel::Off
        } else if cfg!(feature = "release_max_level_error") {
            return FilterLevel::Error
        } else if cfg!(feature = "release_max_level_warn") {
            return FilterLevel::Warning
        } else if cfg!(feature = "release_max_level_info") {
            return FilterLevel::Info
        } else if cfg!(feature = "release_max_level_debug") {
            return FilterLevel::Debug
        } else if cfg!(feature = "release_max_level_trace") {
            return FilterLevel::Trace
        }
    }
    if cfg!(feature = "max_level_off") {
        FilterLevel::Off
    } else if cfg!(feature = "max_level_error") {
        FilterLevel::Error
    } else if cfg!(feature = "max_level_warn") {
        FilterLevel::Warning
    } else if cfg!(feature = "max_level_info") {
        FilterLevel::Info
    } else if cfg!(feature = "max_level_debug") {
        FilterLevel::Debug
    } else {
        FilterLevel::Trace
    }
}

#[cfg(test)]
mod tests;
<|endoftext|>


<commit_before>use error::*;
use handler::*;
use nix::sys::socket::*;
use poll::*;
use slab::Slab;
use RawFd;

#[derive(Debug, Clone, PartialEq)]
pub enum MuxCmd {
  Close,
  Keep,
}

#[derive(Debug)]
pub struct SyncMux<'p, P: HandlerFactory<'p, EpollEvent, MuxCmd> + 'static> {
  epfd: EpollFd,
  handlers: Slab<P::H, usize>,
  factory: P,
  interests: EpollEventKind,
}

impl<'p, P> SyncMux<'p, P>
  where P: HandlerFactory<'p, EpollEvent, MuxCmd> + 'static,
{
  pub fn new(max_handlers: usize, interests: EpollEventKind, epfd: EpollFd, factory: P)
             -> SyncMux<'p, P> {
    SyncMux {
      epfd: epfd,
      handlers: Slab::with_capacity(max_handlers),
      factory: factory,
      interests: interests,
    }
  }

  #[inline(always)]
  fn new_handler(factory: &'p mut P, clifd: RawFd, interests: EpollEventKind, epfd: &EpollFd,
                 handlers: &mut Slab<P::H, usize>)
                 -> Result<(usize, RawFd)> {
    match handlers.vacant_entry() {
      Some(entry) => {

        let i = entry.index();

        let interest = EpollEvent {
          events: interests,
          data: encode(Action::Notify(i, clifd)),
        };

        let h = factory.new(*epfd, i, clifd);

        entry.insert(h);

        match epfd.register(clifd, &interest) {
          Ok(_) => {}
          Err(e) => {
            ::close(clifd).ok();
            return Err(e);
          }
        };

        Ok((i, clifd))
      }
      None => Err("reached maximum number of handlers".into()),
    }
  }

  #[inline(always)]
  fn decode(factory: &'p mut P, epfd: &EpollFd, event: EpollEvent, interests: EpollEventKind,
            handlers: &mut Slab<P::H, usize>)
            -> Result<Option<(usize, RawFd)>> {

    match decode(event.data) {
      Action::Notify(i, fd) => Ok(Some((i, fd))),
      Action::New(data) => {
        let srvfd = data as i32;
        match eintr!(accept, "accept", srvfd) {
          Ok(Some(clifd)) => {
            debug!("accept: accepted new tcp client {}", &clifd);
            Self::new_handler(factory, clifd, interests, epfd, handlers)?;
            Ok(None)
          }
          Ok(None) => Err("accept4: socket not ready".into()),
          Err(e) => Err(e.into()),
        }
      }
    }
  }
}

impl<'p, P> Clone for SyncMux<'p, P>
  where P: HandlerFactory<'p, EpollEvent, MuxCmd> + Clone,
{
  fn clone(&self) -> Self {
    SyncMux {
      epfd: self.epfd,
      handlers: Slab::with_capacity(self.handlers.capacity()),
      factory: self.factory.clone(),
      interests: self.interests.clone(),
    }
  }
}

impl<'p, P> Reset for SyncMux<'p, P>
  where P: HandlerFactory<'p, EpollEvent, MuxCmd>,
{
  fn reset(&mut self, epfd: EpollFd) {
    self.epfd = epfd;
  }
}

impl<'p, P> Handler<EpollEvent, EpollCmd> for SyncMux<'p, P>
  where P: HandlerFactory<'p, EpollEvent, MuxCmd>,
{
  fn ready(&mut self, mut event: EpollEvent) -> EpollCmd {

    // FIXME: solve with associated lifetimes
    let proto: &'p mut P = unsafe { ::std::mem::transmute(&mut self.factory) };

    let (idx, fd) =
      match SyncMux::decode(proto, &self.epfd, event, self.interests, &mut self.handlers) {
        Ok(Some((idx, fd))) => (idx, fd),
        Ok(None) => {
          // new connection
          return EpollCmd::Poll;
        }
        Err(e) => {
          report_err!("{}", e);
          return EpollCmd::Poll;
        }
      };

    event.data = fd as u64;
    match self.handlers[idx].ready(event) {
      MuxCmd::Close => {
        perror!("unistd::close", ::close(fd));
        let handler = self.handlers.remove(idx).unwrap();
        self.factory.done(handler, idx);
      }
      _ => {}
    }

    EpollCmd::Poll
  }
}

pub enum Action {
  Notify(usize, RawFd),
  New(u64),
}

#[inline(always)]
pub fn encode(action: Action) -> u64 {
  match action {
    Action::Notify(data, fd) => ((fd as u64) << 31) | ((data as u64) << 15) | 0,
    Action::New(data) => data,
  }
}

#[inline(always)]
pub fn decode(data: u64) -> Action {
  let arg1 = ((data >> 15) & 0xffff) as usize;
  let fd = (data >> 31) as i32;
  match data & 0x7fff {
    0 => Action::Notify(arg1, fd),
    _ => Action::New(data),
  }
}

#[cfg(test)]
mod tests {
  #[test]
  fn decode_encode_new_action() {
    let data = super::encode(super::Action::New(::std::u64::MAX));

    if let super::Action::New(fd) = super::decode(data) {
      assert!(fd == ::std::u64::MAX);
    } else {
      panic!("action is not Action::New")
    }
  }

  #[test]
  fn decode_encode_notify_action() {
    let data = super::encode(super::Action::Notify(10110, 0));

    if let super::Action::Notify(data, fd) = super::decode(data) {
      assert!(data == 10110);
      assert!(fd == 0);
    } else {
      panic!("action is not Action::Notify")
    }
  }
}
<commit_msg>check on removed handler events being passed to mux<commit_after>use RawFd;
use error::*;
use handler::*;
use nix::sys::socket::*;
use poll::*;
use slab::Slab;

#[derive(Debug, Clone, PartialEq)]
pub enum MuxCmd {
  Close,
  Keep,
}

#[derive(Debug)]
pub struct SyncMux<'p, P: HandlerFactory<'p, EpollEvent, MuxCmd> + 'static> {
  epfd: EpollFd,
  handlers: Slab<P::H, usize>,
  factory: P,
  interests: EpollEventKind,
}

impl<'p, P> SyncMux<'p, P>
  where P: HandlerFactory<'p, EpollEvent, MuxCmd> + 'static,
{
  pub fn new(max_handlers: usize, interests: EpollEventKind, epfd: EpollFd, factory: P)
             -> SyncMux<'p, P> {
    SyncMux {
      epfd: epfd,
      handlers: Slab::with_capacity(max_handlers),
      factory: factory,
      interests: interests,
    }
  }

  #[inline(always)]
  fn new_handler(factory: &'p mut P, clifd: RawFd, interests: EpollEventKind, epfd: &EpollFd,
                 handlers: &mut Slab<P::H, usize>)
                 -> Result<(usize, RawFd)> {
    match handlers.vacant_entry() {
      Some(entry) => {

        let i = entry.index();

        let interest = EpollEvent {
          events: interests,
          data: Action::encode(Action::Notify(i, clifd)),
        };

        let h = factory.new(*epfd, i, clifd);

        entry.insert(h);

        match epfd.register(clifd, &interest) {
          Ok(_) => {}
          Err(e) => {
            ::close(clifd).ok();
            return Err(e);
          }
        };

        Ok((i, clifd))
      }
      None => Err("reached maximum number of handlers".into()),
    }
  }

  #[inline(always)]
  fn decode(factory: &'p mut P, epfd: &EpollFd, event: EpollEvent, interests: EpollEventKind,
            handlers: &mut Slab<P::H, usize>)
            -> Result<Option<(usize, RawFd)>> {

    match Action::decode(event.data) {
      Action::Notify(i, fd) => Ok(Some((i, fd))),
      Action::New(data) => {
        let srvfd = data as i32;
        match eintr!(accept, "accept", srvfd) {
          Ok(Some(clifd)) => {
            debug!("accept: accepted new tcp client {}", &clifd);
            Self::new_handler(factory, clifd, interests, epfd, handlers)?;
            Ok(None)
          }
          Ok(None) => Err("accept4: socket not ready".into()),
          Err(e) => Err(e.into()),
        }
      }
    }
  }
}

impl<'p, P> Clone for SyncMux<'p, P>
  where P: HandlerFactory<'p, EpollEvent, MuxCmd> + Clone,
{
  fn clone(&self) -> Self {
    SyncMux {
      epfd: self.epfd,
      handlers: Slab::with_capacity(self.handlers.capacity()),
      factory: self.factory.clone(),
      interests: self.interests.clone(),
    }
  }
}

impl<'p, P> Reset for SyncMux<'p, P>
  where P: HandlerFactory<'p, EpollEvent, MuxCmd>,
{
  fn reset(&mut self, epfd: EpollFd) {
    self.epfd = epfd;
  }
}

impl<'p, P> Handler<EpollEvent, EpollCmd> for SyncMux<'p, P>
  where P: HandlerFactory<'p, EpollEvent, MuxCmd>,
{
  fn ready(&mut self, mut event: EpollEvent) -> EpollCmd {

    // FIXME: solve with associated lifetimes
    let proto: &'p mut P = unsafe { ::std::mem::transmute(&mut self.factory) };

    let (idx, fd) =
      match SyncMux::decode(proto, &self.epfd, event, self.interests, &mut self.handlers) {
        Ok(Some((idx, fd))) => (idx, fd),
        Ok(None) => {
          // new connection
          return EpollCmd::Poll;
        }
        Err(e) => {
          report_err!("{}", e);
          return EpollCmd::Poll;
        }
      };

    // FIXME: not optimal
    match self.handlers.entry(idx) {
      Some(mut entry) => {
        event.data = fd as u64;
        match entry.get_mut().ready(event) {
          MuxCmd::Close => {
            perror!("unistd::close", ::close(fd));
            let handler = entry.remove();
            self.factory.done(handler, idx);
          }
          _ => {}
        }
      }
      None => warn!("received EpollEvent for handler at index {:?}, but no handler found", idx),
    }
    EpollCmd::Poll
  }
}

pub enum Action {
  Notify(usize, RawFd),
  New(u64),
}

impl Action {
  #[inline(always)]
  pub fn encode(action: Action) -> u64 {
    match action {
      Action::Notify(data, fd) => ((fd as u64) << 31) | ((data as u64) << 15) | 0,
      Action::New(data) => data,
    }
  }

  #[inline(always)]
  pub fn decode(data: u64) -> Action {
    let arg1 = ((data >> 15) & 0xffff) as usize;
    let fd = (data >> 31) as i32;
    match data & 0x7fff {
      0 => Action::Notify(arg1, fd),
      _ => Action::New(data),
    }
  }
}

#[macro_export]
macro_rules! keep {
  ($cmd:expr) => {{
    match $cmd {
      e @ MuxCmd::Close => return e,
      _ => {}
    }
  }}
}

#[cfg(test)]
mod tests {
  #[test]
  fn decode_encode_new_action() {
    let data = super::encode(super::Action::New(::std::u64::MAX));

    if let super::Action::New(fd) = super::decode(data) {
      assert!(fd == ::std::u64::MAX);
    } else {
      panic!("action is not Action::New")
    }
  }

  #[test]
  fn decode_encode_notify_action() {
    let data = super::encode(super::Action::Notify(10110, 0));

    if let super::Action::Notify(data, fd) = super::decode(data) {
      assert!(data == 10110);
      assert!(fd == 0);
    } else {
      panic!("action is not Action::Notify")
    }
  }
}
<|endoftext|>


<commit_before>//! A collection of numeric traits and functions.

use std::ops::Mul;
use std::cmp::Ordering;

/// Types that can be square-rooted.
pub trait Sqrt {
    /// Takes the square root of a number.
    ///
    /// Returns NaN if `self` is a negative number.
    fn sqrt(self) -> Self;

    /// Returns the inverse of the square root of a number. i.e. the value `1/√x`.
    ///
    /// Returns NaN if `self` is a negative number.
    fn inversesqrt(self) -> Self;
}

/// Types that can be square-rooted.
impl Sqrt for f32 {
    /// Takes the square root of a number.
    ///
    /// Returns NaN if self is a negative number.
    fn sqrt(self) -> Self { f32::sqrt(self) }

    /// Returns the inverse of the square root of a number. i.e. the value `1/√x`.
    ///
    /// Returns NaN if `self` is a negative number.
    fn inversesqrt(self) -> Self { self.sqrt().recip() }
}
/// Types that can be square-rooted.
impl Sqrt for f64 {
    /// Takes the square root of a number.
    ///
    /// Returns NaN if self is a negative number.
    fn sqrt(self) -> Self { f64::sqrt(self) }

    /// Returns the inverse of the square root of a number. i.e. the value `1/√x`.
    ///
    /// Returns NaN if `self` is a negative number.
    fn inversesqrt(self) -> Self { self.sqrt().recip() }
}

// Types that implment hyperbolic angle functions
pub trait Hyperbolic {
    // Hyperbolic sine function.
    fn sinh(self) -> Self;
    // Hyperbolic cosine function.
    fn cosh(self) -> Self;
    // Hyperbolic tangent function.
    fn tanh(self) -> Self;
    // Hyperbolic sine function.
    fn asinh(self) -> Self;
    // Hyperbolic cosine function.
    fn acosh(self) -> Self;
    // Hyperbolic tangent function.
    fn atanh(self) -> Self;
}

// Types that implment hyperbolic angle functions
impl Hyperbolic for f32 {
    // Hyperbolic sine function.
    fn sinh(self) -> Self { f32::sinh(self) }
    // Hyperbolic cosine function.
    fn cosh(self) -> Self { f32::cosh(self) }
    // Hyperbolic tangent function.
    fn tanh(self) -> Self { f32::tanh(self) }
    // Hyperbolic sine function.
    fn asinh(self) -> Self { f32::asinh(self) }
    // Hyperbolic cosine function.
    fn acosh(self) -> Self { f32::acosh(self) }
    // Hyperbolic tangent function.
    fn atanh(self) -> Self { f32::atanh(self) }
}

// Types that implment hyperbolic angle functions
impl Hyperbolic for f64 {
    // Hyperbolic sine function.
    fn sinh(self) -> Self { f64::sinh(self) }
    // Hyperbolic cosine function.
    fn cosh(self) -> Self { f64::cosh(self) }
    // Hyperbolic tangent function.
    fn tanh(self) -> Self { f64::tanh(self) }
    // Hyperbolic sine function.
    fn asinh(self) -> Self { f64::asinh(self) }
    // Hyperbolic cosine function.
    fn acosh(self) -> Self { f64::acosh(self) }
    // Hyperbolic tangent function.
    fn atanh(self) -> Self { f64::atanh(self) }
}

/// Types that can be sign functions.
pub trait Sign {
    /// The resulting type
    type Output;

    /// Returns `true` if `self` is strictly less than zero
    fn is_negative(&self) -> Self::Output;
    /// Returns `true` if `self` is strictly greater than zero
    fn is_positive(&self) -> Self::Output;

    /// Returns `true` if `self`'s sign is negative (including `-0`).
    fn is_sign_negative(&self) -> Self::Output;
    /// Returns `true` if `self`'s sign is positive (including `+0`).
    fn is_sign_positive(&self) -> Self::Output;

    /// Returns a number that represents the sign of self.
    /// NaN if `self` is NaN
    /// One if the `self.is_sign_positive()`
    /// Negative one if `self.is_sign_negative()`
    fn signum(self) -> Self;

    /// Returns a number that represents the sign of self.
    /// NaN if `self` is NaN
    /// One if the `self.is_positive()`
    /// Negative one if `self.is_negative()`
    /// else Zero
    fn sign(self) -> Self;
}

impl Sign for f32 {
    /// The resulting type
    type Output = bool;

    /// Returns `true` if `self` is strictly less than zero
    fn is_negative(&self) -> Self::Output { self.lt(&0f32) }
    /// Returns `true` if `self` is strictly greater than zero
    fn is_positive(&self) -> Self::Output { self.gt(&0f32) }

    /// Returns `true` if `self`'s sign is negative (including `-0`).
    fn is_sign_negative(&self) -> Self::Output { f32::is_sign_negative(*self) }
    /// Returns `true` if `self`'s sign is positive (including `+0`).
    fn is_sign_positive(&self) -> Self::Output { f32::is_sign_positive(*self) }

    /// Returns a number that represents the sign of self.
    /// NaN if `self` is NaN
    /// One if the `self.is_sign_positive()`
    /// Negative one if `self.is_sign_negative()`
    fn signum(self) -> Self { f32::signum(self) }

    /// Returns a number that represents the sign of self.
    /// NaN if `self` is NaN
    /// One if the `self.is_positive()`
    /// Negative one if `self.is_negative()`
    /// else Zero
    fn sign(self) -> Self {
        match self.partial_cmp(&0f32) {
            Some(Ordering::Less) => -1f32,
            Some(Ordering::Greater) => 1f32,
            _ => self,
        }
    }
}
impl Sign for f64 {
    /// The resulting type
    type Output = bool;

    /// Returns `true` if `self` is strictly less than zero
    fn is_negative(&self) -> Self::Output { self.lt(&0f64) }
    /// Returns `true` if `self` is strictly greater than zero
    fn is_positive(&self) -> Self::Output { self.gt(&0f64) }

    /// Returns `true` if `self`'s sign is negative (including `-0`).
    fn is_sign_negative(&self) -> Self::Output { f64::is_sign_negative(*self) }
    /// Returns `true` if `self`'s sign is positive (including `+0`).
    fn is_sign_positive(&self) -> Self::Output { f64::is_sign_positive(*self) }

    /// Returns a number that represents the sign of self.
    /// One if the `self.is_sign_positive()`
    /// Negative one if `self.is_sign_negative()`
    fn signum(self) -> Self {
        use std::mem;
        let u: u64 = unsafe { mem::transmute(self) } ;
        let u = u & (1 << 63); // Mask to just the signed bit
        let u = u | 0x3ff0000000000000; // Convert it to a 1
        unsafe { mem::transmute(u) }
        //f64::signum(self)
    }

    /// Returns a number that represents the sign of self.
    /// One if the `self.is_positive()`
    /// Negative one if `self.is_negative()`
    /// else Zero
    fn sign(self) -> Self {
        match self.partial_cmp(&0f64) {
            Some(Ordering::Less) => -1f64,
            Some(Ordering::Greater) => 1f64,
            _ => 0f64
        }
    }
}

/// Types that can be used with compared to be approximate equal.
pub trait Approx<T> {
    /// Returns true if `lhs` is approximately `rhs`.
    fn approx(&self, lhs: T, rhs: T) -> bool;
}

/// Types that can be used to compare to zero efficiently.
pub trait ApproxZero<T> {
    /// Returns true if `a` is approximately zero.
    fn approx_zero(&self, a: T) -> bool;

    /// Returns true if `a/b` is approximately zero.
    fn approx_zero_ratio(&self, a: T, b: T) -> bool;
}

/// An approximator using simple episilon.
pub struct AbsoluteEpsilon<F>(pub F);

impl <T: Copy+Mul<Output=T>> AbsoluteEpsilon<T> {
    /// Tighten approximation so that `self.approx_zero(x) == self.squared().approx_zero(x*x)`.
    pub fn squared(&self) -> Self { AbsoluteEpsilon(self.0*self.0) }
}

/// Types that can be used with compared to be approximate equal.
impl Approx<f32> for AbsoluteEpsilon<f32> {
    /// Returns true if `lhs` is approximately `rhs`.
    fn approx(&self, lhs: f32, rhs: f32) -> bool {
        f32::abs(lhs - rhs) <= self.0
    }
}

/// Types that can be used to compare to zero efficiently.
impl ApproxZero<f32> for AbsoluteEpsilon<f32> {
    /// Returns true if `a` is approximately zero.
    fn approx_zero(&self, a: f32) -> bool {
        f32::abs(a) <= self.0
    }
    /// Returns true if `a/b` is approximately zero without doing a division.
    fn approx_zero_ratio(&self, a: f32, b: f32) -> bool {
        f32::abs(a) <= f32::abs(b) * self.0
    }
}

/// Types that can be used with compared to be approximate equal.
impl Approx<f64> for AbsoluteEpsilon<f64> {
    fn approx(&self, lhs: f64, rhs: f64) -> bool {
        f64::abs(lhs - rhs) <= self.0
    }
}

/// Types that can be used to compare to zero efficiently.
impl ApproxZero<f64> for AbsoluteEpsilon<f64> {
    /// Returns true if `a` is approximately zero.
    fn approx_zero(&self, a: f64) -> bool {
        f64::abs(a) <= self.0
    }
    /// Returns true if `a/b` is approximately zero without doing a division.
    fn approx_zero_ratio(&self, a: f64, b: f64) -> bool {
        f64::abs(a) <= f64::abs(b) * self.0
    }
}
<commit_msg>Fixed f64 Sign<commit_after>//! A collection of numeric traits and functions.

use std::ops::Mul;
use std::cmp::Ordering;

/// Types that can be square-rooted.
pub trait Sqrt {
    /// Takes the square root of a number.
    ///
    /// Returns NaN if `self` is a negative number.
    fn sqrt(self) -> Self;

    /// Returns the inverse of the square root of a number. i.e. the value `1/√x`.
    ///
    /// Returns NaN if `self` is a negative number.
    fn inversesqrt(self) -> Self;
}

/// Types that can be square-rooted.
impl Sqrt for f32 {
    /// Takes the square root of a number.
    ///
    /// Returns NaN if self is a negative number.
    fn sqrt(self) -> Self { f32::sqrt(self) }

    /// Returns the inverse of the square root of a number. i.e. the value `1/√x`.
    ///
    /// Returns NaN if `self` is a negative number.
    fn inversesqrt(self) -> Self { self.sqrt().recip() }
}
/// Types that can be square-rooted.
impl Sqrt for f64 {
    /// Takes the square root of a number.
    ///
    /// Returns NaN if self is a negative number.
    fn sqrt(self) -> Self { f64::sqrt(self) }

    /// Returns the inverse of the square root of a number. i.e. the value `1/√x`.
    ///
    /// Returns NaN if `self` is a negative number.
    fn inversesqrt(self) -> Self { self.sqrt().recip() }
}

// Types that implment hyperbolic angle functions
pub trait Hyperbolic {
    // Hyperbolic sine function.
    fn sinh(self) -> Self;
    // Hyperbolic cosine function.
    fn cosh(self) -> Self;
    // Hyperbolic tangent function.
    fn tanh(self) -> Self;
    // Hyperbolic sine function.
    fn asinh(self) -> Self;
    // Hyperbolic cosine function.
    fn acosh(self) -> Self;
    // Hyperbolic tangent function.
    fn atanh(self) -> Self;
}

// Types that implment hyperbolic angle functions
impl Hyperbolic for f32 {
    // Hyperbolic sine function.
    fn sinh(self) -> Self { f32::sinh(self) }
    // Hyperbolic cosine function.
    fn cosh(self) -> Self { f32::cosh(self) }
    // Hyperbolic tangent function.
    fn tanh(self) -> Self { f32::tanh(self) }
    // Hyperbolic sine function.
    fn asinh(self) -> Self { f32::asinh(self) }
    // Hyperbolic cosine function.
    fn acosh(self) -> Self { f32::acosh(self) }
    // Hyperbolic tangent function.
    fn atanh(self) -> Self { f32::atanh(self) }
}

// Types that implment hyperbolic angle functions
impl Hyperbolic for f64 {
    // Hyperbolic sine function.
    fn sinh(self) -> Self { f64::sinh(self) }
    // Hyperbolic cosine function.
    fn cosh(self) -> Self { f64::cosh(self) }
    // Hyperbolic tangent function.
    fn tanh(self) -> Self { f64::tanh(self) }
    // Hyperbolic sine function.
    fn asinh(self) -> Self { f64::asinh(self) }
    // Hyperbolic cosine function.
    fn acosh(self) -> Self { f64::acosh(self) }
    // Hyperbolic tangent function.
    fn atanh(self) -> Self { f64::atanh(self) }
}

/// Types that can be sign functions.
pub trait Sign {
    /// The resulting type
    type Output;

    /// Returns `true` if `self` is strictly less than zero
    fn is_negative(&self) -> Self::Output;
    /// Returns `true` if `self` is strictly greater than zero
    fn is_positive(&self) -> Self::Output;

    /// Returns `true` if `self`'s sign is negative (including `-0`).
    fn is_sign_negative(&self) -> Self::Output;
    /// Returns `true` if `self`'s sign is positive (including `+0`).
    fn is_sign_positive(&self) -> Self::Output;

    /// Returns a number that represents the sign of self.
    /// NaN if `self` is NaN
    /// One if the `self.is_sign_positive()`
    /// Negative one if `self.is_sign_negative()`
    fn signum(self) -> Self;

    /// Returns a number that represents the sign of self.
    /// NaN if `self` is NaN
    /// One if the `self.is_positive()`
    /// Negative one if `self.is_negative()`
    /// else Zero
    fn sign(self) -> Self;
}

impl Sign for f32 {
    /// The resulting type
    type Output = bool;

    /// Returns `true` if `self` is strictly less than zero
    fn is_negative(&self) -> Self::Output { self.lt(&0f32) }
    /// Returns `true` if `self` is strictly greater than zero
    fn is_positive(&self) -> Self::Output { self.gt(&0f32) }

    /// Returns `true` if `self`'s sign is negative (including `-0`).
    fn is_sign_negative(&self) -> Self::Output { f32::is_sign_negative(*self) }
    /// Returns `true` if `self`'s sign is positive (including `+0`).
    fn is_sign_positive(&self) -> Self::Output { f32::is_sign_positive(*self) }

    /// Returns a number that represents the sign of self.
    /// NaN if `self` is NaN
    /// One if the `self.is_sign_positive()`
    /// Negative one if `self.is_sign_negative()`
    fn signum(self) -> Self { f32::signum(self) }

    /// Returns a number that represents the sign of self.
    /// NaN if `self` is NaN
    /// One if the `self.is_positive()`
    /// Negative one if `self.is_negative()`
    /// else Zero
    fn sign(self) -> Self {
        match self.partial_cmp(&0f32) {
            Some(Ordering::Less) => -1f32,
            Some(Ordering::Greater) => 1f32,
            _ => self,
        }
    }
}
impl Sign for f64 {
    /// The resulting type
    type Output = bool;

    /// Returns `true` if `self` is strictly less than zero
    fn is_negative(&self) -> Self::Output { self.lt(&0f64) }
    /// Returns `true` if `self` is strictly greater than zero
    fn is_positive(&self) -> Self::Output { self.gt(&0f64) }

    /// Returns `true` if `self`'s sign is negative (including `-0`).
    fn is_sign_negative(&self) -> Self::Output { f64::is_sign_negative(*self) }
    /// Returns `true` if `self`'s sign is positive (including `+0`).
    fn is_sign_positive(&self) -> Self::Output { f64::is_sign_positive(*self) }

    /// Returns a number that represents the sign of self.
    /// NaN if `self` is NaN
    /// One if the `self.is_sign_positive()`
    /// Negative one if `self.is_sign_negative()`
    fn signum(self) -> Self { f64::signum(self) }

    /// Returns a number that represents the sign of self.
    /// NaN if `self` is NaN
    /// One if the `self.is_positive()`
    /// Negative one if `self.is_negative()`
    /// else Zero
    fn sign(self) -> Self {
        match self.partial_cmp(&0f64) {
            Some(Ordering::Less) => -1f64,
            Some(Ordering::Greater) => 1f64,
            _ => self,
        }
    }
}

/// Types that can be used with compared to be approximate equal.
pub trait Approx<T> {
    /// Returns true if `lhs` is approximately `rhs`.
    fn approx(&self, lhs: T, rhs: T) -> bool;
}

/// Types that can be used to compare to zero efficiently.
pub trait ApproxZero<T> {
    /// Returns true if `a` is approximately zero.
    fn approx_zero(&self, a: T) -> bool;

    /// Returns true if `a/b` is approximately zero.
    fn approx_zero_ratio(&self, a: T, b: T) -> bool;
}

/// An approximator using simple episilon.
pub struct AbsoluteEpsilon<F>(pub F);

impl <T: Copy+Mul<Output=T>> AbsoluteEpsilon<T> {
    /// Tighten approximation so that `self.approx_zero(x) == self.squared().approx_zero(x*x)`.
    pub fn squared(&self) -> Self { AbsoluteEpsilon(self.0*self.0) }
}

/// Types that can be used with compared to be approximate equal.
impl Approx<f32> for AbsoluteEpsilon<f32> {
    /// Returns true if `lhs` is approximately `rhs`.
    fn approx(&self, lhs: f32, rhs: f32) -> bool {
        f32::abs(lhs - rhs) <= self.0
    }
}

/// Types that can be used to compare to zero efficiently.
impl ApproxZero<f32> for AbsoluteEpsilon<f32> {
    /// Returns true if `a` is approximately zero.
    fn approx_zero(&self, a: f32) -> bool {
        f32::abs(a) <= self.0
    }
    /// Returns true if `a/b` is approximately zero without doing a division.
    fn approx_zero_ratio(&self, a: f32, b: f32) -> bool {
        f32::abs(a) <= f32::abs(b) * self.0
    }
}

/// Types that can be used with compared to be approximate equal.
impl Approx<f64> for AbsoluteEpsilon<f64> {
    fn approx(&self, lhs: f64, rhs: f64) -> bool {
        f64::abs(lhs - rhs) <= self.0
    }
}

/// Types that can be used to compare to zero efficiently.
impl ApproxZero<f64> for AbsoluteEpsilon<f64> {
    /// Returns true if `a` is approximately zero.
    fn approx_zero(&self, a: f64) -> bool {
        f64::abs(a) <= self.0
    }
    /// Returns true if `a/b` is approximately zero without doing a division.
    fn approx_zero_ratio(&self, a: f64, b: f64) -> bool {
        f64::abs(a) <= f64::abs(b) * self.0
    }
}
<|endoftext|>


<commit_before>//! The functions in this section provide optimized copying to persistent memory
//!
//! The `copy`, `copy_nonoverlapping`, and `write_bytes`, provide the same memory copying as
//! `memmove(3)`, `memcpy(3)`, and `memset(3)`, and ensure that the result has been flushed to persistence before returning.
//!
//! > **Warning:** Using these functions where `is_pmem(1)` returns false may not do anything useful.
//! >              Use the normal libc functions in that case.

use ::std::mem;
use ::std::io;
use ::std::marker::PhantomData;

use ::libc::{c_void, c_int};
use ::libc::size_t;
use ::pmem_sys as ffi;

use pmap::PersistentMap;

/// Persistent memory virtual pointer
///
/// This pointer is safe to store.
#[derive(Copy, Clone)]
pub struct PmemConstVirtualPtr<T: ?Sized> {
    poolid: usize,
    offset: usize,
    _t: PhantomData<T>,
}

impl<T: ?Sized> PmemConstVirtualPtr<T> {
    pub unsafe fn new(poolid: usize, offset: usize) -> Self {
        assert!(poolid != 0, "Poolid 0 is reserved for null pointers");
        PmemConstVirtualPtr { poolid: poolid, offset: offset, _t: PhantomData }
    }

    pub fn null() -> Self { PmemConstVirtualPtr { poolid: 0, offset: 0, _t: PhantomData } }

    pub fn is_null(&self) -> bool { self.poolid == 0 }

    pub unsafe fn as_type<U>(self) -> PmemConstVirtualPtr<U> {
        PmemConstVirtualPtr { poolid: self.poolid, offset: self.offset, _t: PhantomData }
    }

    pub unsafe fn as_mut(self) -> PmemMutVirtualPtr<T> {
        PmemMutVirtualPtr { poolid: self.poolid, offset: self.offset, _t: PhantomData }
    }
}

impl<T> PmemConstVirtualPtr<T> {
    pub unsafe fn offset(&self, count: isize) -> Self {
        if self.is_null() {
            PmemConstVirtualPtr::null()
        } else {
            let new_offset = self.offset as isize + mem::size_of::<T>() as isize * count;
            PmemConstVirtualPtr { poolid: self.poolid, offset: new_offset as usize, _t: self._t }
        }
    }

    pub unsafe fn link(self, pool: &PersistentMap) -> PmemConstPtr<T> {
        PmemConstPtr { virt: self, pool: pool.as_ptr() }
    }
}

/// Persistent memory virtual mutable pointer
///
/// This pointer is safe to store.
#[derive(Copy, Clone)]
pub struct PmemMutVirtualPtr<T: ?Sized> {
    poolid: usize,
    offset: usize,
    _t: PhantomData<T>,
}

impl<T: ?Sized> PmemMutVirtualPtr<T> {
    pub unsafe fn new(poolid: usize, offset: usize) -> Self {
        assert!(poolid != 0, "Poolid 0 is reserved for null pointers");
        PmemMutVirtualPtr { poolid: poolid, offset: offset, _t: PhantomData }
    }

    pub fn null() -> Self { PmemMutVirtualPtr { poolid: 0, offset: 0, _t: PhantomData } }

    pub fn is_null(&self) -> bool { self.poolid == 0 }

    pub unsafe fn as_type<U>(self) -> PmemMutVirtualPtr<U> {
        PmemMutVirtualPtr { poolid: self.poolid, offset: self.offset, _t: PhantomData }
    }

    pub unsafe fn as_const(self) -> PmemConstVirtualPtr<T> {
        PmemConstVirtualPtr { poolid: self.poolid, offset: self.offset, _t: PhantomData }
    }
}

impl<T> PmemMutVirtualPtr<T> {
    pub unsafe fn offset(&self, count: isize) -> Self {
        if self.is_null() {
            PmemMutVirtualPtr::null()
        } else {
            let new_offset = self.offset as isize + mem::size_of::<T>() as isize * count;
            PmemMutVirtualPtr { poolid: self.poolid, offset: new_offset as usize, _t: self._t }
        }
    }

    pub unsafe fn link(self, pool: &mut PersistentMap) -> PmemMutPtr<T> {
        PmemMutPtr { virt: self, pool: pool.as_mut_ptr() }
    }
}

/// Direct `*const T` pointer to a pmem location
///
/// # Safety
///
/// This pointer is **not** safe to store directly on pmem.
/// You can get a _safe_ virtual pointer using `as_virtual()`.
#[derive(Copy, Clone)]
pub struct PmemConstPtr<T: ?Sized> {
    virt: PmemConstVirtualPtr<T>,
    pool: *const T,
}

impl<T: ?Sized> PmemConstPtr<T> {
    pub fn is_null(&self) -> bool { self.virt.is_null() }

    pub unsafe fn as_mut(self) -> PmemMutPtr<T> {
        PmemMutPtr { virt: self.virt.as_mut(), pool: self.pool as *mut T }
    }
}

impl<T> PmemConstPtr<T> {
    pub unsafe fn direct(&self) -> *const T {
        if self.is_null() {
            ::std::ptr::null()
        } else {
            self.pool.offset(self.virt.offset as isize) as *const T
        }
    }

    pub fn as_virtual(self) -> PmemConstVirtualPtr<T> {
        self.virt
    }

    pub unsafe fn offset(&self, count: isize) -> Self {
        let new_virt = self.virt.offset(count);
        PmemConstPtr { virt: new_virt, pool: self.pool }
    }

    pub unsafe fn as_type<U>(self) -> PmemConstPtr<U> {
        let new_virt = self.virt.as_type();
        PmemConstPtr { virt: new_virt, pool: self.pool as *mut U }
    }
}

/// Direct `*mut T` pointer to a pmem location
///
/// # Safety
///
/// This pointer is **not** safe to store directly on pmem.
/// You can get a _safe_ virtual pointer using `as_virtual()`.
#[derive(Copy, Clone)]
pub struct PmemMutPtr<T: ?Sized> {
    virt: PmemMutVirtualPtr<T>,
    pool: *mut T,
}

impl<T: ?Sized> PmemMutPtr<T> {
    pub fn is_null(&self) -> bool { self.virt.is_null() }

    pub unsafe fn as_const(self) -> PmemConstPtr<T> {
        PmemConstPtr { virt: self.virt.as_const(), pool: self.pool as *const T }
    }
}

impl<T> PmemMutPtr<T> {
    pub unsafe fn direct(&self) -> *mut T {
        if self.is_null() {
            ::std::ptr::null_mut()
        } else {
            self.pool.offset(self.virt.offset as isize) as *mut T
        }
    }

    pub fn as_virtual(self) -> PmemMutVirtualPtr<T> {
        self.virt
    }

    pub unsafe fn offset(&self, count: isize) -> Self {
        let new_virt = self.virt.offset(count);
        PmemMutPtr { virt: new_virt, pool: self.pool }
    }

    pub unsafe fn as_type<U>(self) -> PmemMutPtr<U> {
        let new_virt = self.virt.as_type();
        PmemMutPtr { virt: new_virt, pool: self.pool as *mut U }
    }
}

pub fn null<T>() -> PmemConstVirtualPtr<T> {
    PmemConstVirtualPtr::null()
}

pub fn null_mut<T>() -> PmemMutVirtualPtr<T> {
    PmemMutVirtualPtr::null()
}

/// Copies `count * size_of<T>` bytes from `src` to `pmemdest`. The source and destination may overlap.
///
/// `copy` is semantically equivalent to C's `memmove` and is optimized for persitent memory.
///
/// Ensures that the result has been flushed to persistence before returning.
///
/// # Safety
///
/// Care must be taken with the ownership of `src` and `pmemdest`.
/// This method semantically moves the values of `src` into `pmemdest`.
/// However it does not drop the contents of `pmemdest`, or prevent the contents of `src` from being dropped or used.
pub unsafe fn copy<T>(src: *const T, pmemdest: *mut T, count: usize) {
    let len = mem::size_of::<T>() * count;
    ffi::pmem_memmove_persist(pmemdest as *mut c_void, src as *const c_void, len as size_t);
}

/// Copies `count * size_of<T>` bytes from `src` to `pmemdest`. The source and destination may _not_ overlap.
///
/// `copy_nonoverlapping` is semantically equivalent to C's `memcpy` and is optimized for persitent memory.
///
/// Ensures that the result has been flushed to persistence before returning.
///
/// # Safety
///
/// Beyond requiring that the program must be allowed to access both regions of memory,
/// it is _Undefined Behavior_ for source and destination to overlap.
/// Care must also be taken with the ownership of `src` and `pmemdest`.
/// This method semantically moves the values of `src` into `pmemdest`.
/// However it does not drop the contents of `pmemdest`, or prevent the contents of `src` from being dropped or used.
pub unsafe fn copy_nonoverlapping<T>(src: *const T, pmemdest: *mut T, count: usize) {
    let len = mem::size_of::<T>() * count;
    ffi::pmem_memcpy_persist(pmemdest as *mut c_void, src as *const c_void, len as size_t);
}

/// Invokes memset on the specified pointer, setting `count * size_of::<T>()` bytes of memory starting at `pmemdest` to `val`.
///
/// Ensures that the result has been flushed to persistence before returning.
pub unsafe fn write_bytes<T>(pmemdest: *mut T, val: u8, count: usize) {
    let len = mem::size_of::<T>() * count;
    ffi::pmem_memset_persist(pmemdest as *mut c_void, val as c_int, len as size_t);
}

/// Overwrites a memory location with the given value without reading or dropping the old value.
///
/// Ensures that the result has been flushed to persistence before returning.
///
/// # Safety
///
/// This operation is marked unsafe because it accepts a raw pointer.
///
/// It does not drop the contents of dst. This is safe, but it could leak allocations or resources,
/// so care must be taken not to overwrite an object that should be dropped.
///
/// This is appropriate for initializing uninitialized memory, or overwriting memory that has previously been read from.
pub unsafe fn write<T>(pmemdest: *mut T, val: T) { copy_nonoverlapping(&val as *const _, pmemdest, 1) }

pub unsafe fn msync<T>(pmemdest: *const T, count: usize) -> Result<(), io::Error> {
    let len = count * mem::size_of::<T>();
    let r = ffi::pmem_msync(pmemdest as *const c_void, len as size_t);
    if r == -1 {
        Err(io::Error::last_os_error())
    } else {
        Ok(())
    }
}
<commit_msg>feat: links take by ref<commit_after>//! The functions in this section provide optimized copying to persistent memory
//!
//! The `copy`, `copy_nonoverlapping`, and `write_bytes`, provide the same memory copying as
//! `memmove(3)`, `memcpy(3)`, and `memset(3)`, and ensure that the result has been flushed to persistence before returning.
//!
//! > **Warning:** Using these functions where `is_pmem(1)` returns false may not do anything useful.
//! >              Use the normal libc functions in that case.

use ::std::mem;
use ::std::io;
use ::std::marker::PhantomData;

use ::libc::{c_void, c_int};
use ::libc::size_t;
use ::pmem_sys as ffi;

use pmap::PersistentMap;

/// Persistent memory virtual pointer
///
/// This pointer is safe to store.
#[derive(Copy, Clone)]
pub struct PmemConstVirtualPtr<T: ?Sized> {
    poolid: usize,
    offset: usize,
    _t: PhantomData<T>,
}

impl<T: ?Sized> PmemConstVirtualPtr<T> {
    pub unsafe fn new(poolid: usize, offset: usize) -> Self {
        assert!(poolid != 0, "Poolid 0 is reserved for null pointers");
        PmemConstVirtualPtr { poolid: poolid, offset: offset, _t: PhantomData }
    }

    pub fn null() -> Self { PmemConstVirtualPtr { poolid: 0, offset: 0, _t: PhantomData } }

    pub fn is_null(&self) -> bool { self.poolid == 0 }

    pub unsafe fn as_type<U>(self) -> PmemConstVirtualPtr<U> {
        PmemConstVirtualPtr { poolid: self.poolid, offset: self.offset, _t: PhantomData }
    }

    pub unsafe fn as_mut(self) -> PmemMutVirtualPtr<T> {
        PmemMutVirtualPtr { poolid: self.poolid, offset: self.offset, _t: PhantomData }
    }
}

impl<T> PmemConstVirtualPtr<T> {
    pub unsafe fn offset(&self, count: isize) -> Self {
        if self.is_null() {
            PmemConstVirtualPtr::null()
        } else {
            let new_offset = self.offset as isize + mem::size_of::<T>() as isize * count;
            PmemConstVirtualPtr { poolid: self.poolid, offset: new_offset as usize, _t: self._t }
        }
    }

    pub unsafe fn link(&self, pool: &PersistentMap) -> PmemConstPtr<T> {
        let new_virt = PmemConstVirtualPtr { poolid: self.poolid, offset: self.offset, _t: self._t };
        PmemConstPtr { virt: new_virt, pool: pool.as_ptr() }
    }
}

/// Persistent memory virtual mutable pointer
///
/// This pointer is safe to store.
#[derive(Copy, Clone)]
pub struct PmemMutVirtualPtr<T: ?Sized> {
    poolid: usize,
    offset: usize,
    _t: PhantomData<T>,
}

impl<T: ?Sized> PmemMutVirtualPtr<T> {
    pub unsafe fn new(poolid: usize, offset: usize) -> Self {
        assert!(poolid != 0, "Poolid 0 is reserved for null pointers");
        PmemMutVirtualPtr { poolid: poolid, offset: offset, _t: PhantomData }
    }

    pub fn null() -> Self { PmemMutVirtualPtr { poolid: 0, offset: 0, _t: PhantomData } }

    pub fn is_null(&self) -> bool { self.poolid == 0 }

    pub unsafe fn as_type<U>(self) -> PmemMutVirtualPtr<U> {
        PmemMutVirtualPtr { poolid: self.poolid, offset: self.offset, _t: PhantomData }
    }

    pub unsafe fn as_const(self) -> PmemConstVirtualPtr<T> {
        PmemConstVirtualPtr { poolid: self.poolid, offset: self.offset, _t: PhantomData }
    }
}

impl<T> PmemMutVirtualPtr<T> {
    pub unsafe fn offset(&self, count: isize) -> Self {
        if self.is_null() {
            PmemMutVirtualPtr::null()
        } else {
            let new_offset = self.offset as isize + mem::size_of::<T>() as isize * count;
            PmemMutVirtualPtr { poolid: self.poolid, offset: new_offset as usize, _t: self._t }
        }
    }

    pub unsafe fn link(&self, pool: &mut PersistentMap) -> PmemMutPtr<T> {
        let new_virt = PmemMutVirtualPtr { poolid: self.poolid, offset: self.offset, _t: self._t };
        PmemMutPtr { virt: new_virt, pool: pool.as_mut_ptr() }
    }
}

/// Direct `*const T` pointer to a pmem location
///
/// # Safety
///
/// This pointer is **not** safe to store directly on pmem.
/// You can get a _safe_ virtual pointer using `as_virtual()`.
#[derive(Copy, Clone)]
pub struct PmemConstPtr<T: ?Sized> {
    virt: PmemConstVirtualPtr<T>,
    pool: *const T,
}

impl<T: ?Sized> PmemConstPtr<T> {
    pub fn is_null(&self) -> bool { self.virt.is_null() }

    pub unsafe fn as_mut(self) -> PmemMutPtr<T> {
        PmemMutPtr { virt: self.virt.as_mut(), pool: self.pool as *mut T }
    }
}

impl<T> PmemConstPtr<T> {
    pub unsafe fn direct(&self) -> *const T {
        if self.is_null() {
            ::std::ptr::null()
        } else {
            self.pool.offset(self.virt.offset as isize) as *const T
        }
    }

    pub fn as_virtual(self) -> PmemConstVirtualPtr<T> {
        self.virt
    }

    pub unsafe fn offset(&self, count: isize) -> Self {
        let new_virt = self.virt.offset(count);
        PmemConstPtr { virt: new_virt, pool: self.pool }
    }

    pub unsafe fn as_type<U>(self) -> PmemConstPtr<U> {
        let new_virt = self.virt.as_type();
        PmemConstPtr { virt: new_virt, pool: self.pool as *mut U }
    }
}

/// Direct `*mut T` pointer to a pmem location
///
/// # Safety
///
/// This pointer is **not** safe to store directly on pmem.
/// You can get a _safe_ virtual pointer using `as_virtual()`.
#[derive(Copy, Clone)]
pub struct PmemMutPtr<T: ?Sized> {
    virt: PmemMutVirtualPtr<T>,
    pool: *mut T,
}

impl<T: ?Sized> PmemMutPtr<T> {
    pub fn is_null(&self) -> bool { self.virt.is_null() }

    pub unsafe fn as_const(self) -> PmemConstPtr<T> {
        PmemConstPtr { virt: self.virt.as_const(), pool: self.pool as *const T }
    }
}

impl<T> PmemMutPtr<T> {
    pub unsafe fn direct(&self) -> *mut T {
        if self.is_null() {
            ::std::ptr::null_mut()
        } else {
            self.pool.offset(self.virt.offset as isize) as *mut T
        }
    }

    pub fn as_virtual(self) -> PmemMutVirtualPtr<T> {
        self.virt
    }

    pub unsafe fn offset(&self, count: isize) -> Self {
        let new_virt = self.virt.offset(count);
        PmemMutPtr { virt: new_virt, pool: self.pool }
    }

    pub unsafe fn as_type<U>(self) -> PmemMutPtr<U> {
        let new_virt = self.virt.as_type();
        PmemMutPtr { virt: new_virt, pool: self.pool as *mut U }
    }
}

pub fn null<T>() -> PmemConstVirtualPtr<T> {
    PmemConstVirtualPtr::null()
}

pub fn null_mut<T>() -> PmemMutVirtualPtr<T> {
    PmemMutVirtualPtr::null()
}

/// Copies `count * size_of<T>` bytes from `src` to `pmemdest`. The source and destination may overlap.
///
/// `copy` is semantically equivalent to C's `memmove` and is optimized for persitent memory.
///
/// Ensures that the result has been flushed to persistence before returning.
///
/// # Safety
///
/// Care must be taken with the ownership of `src` and `pmemdest`.
/// This method semantically moves the values of `src` into `pmemdest`.
/// However it does not drop the contents of `pmemdest`, or prevent the contents of `src` from being dropped or used.
pub unsafe fn copy<T>(src: *const T, pmemdest: *mut T, count: usize) {
    let len = mem::size_of::<T>() * count;
    ffi::pmem_memmove_persist(pmemdest as *mut c_void, src as *const c_void, len as size_t);
}

/// Copies `count * size_of<T>` bytes from `src` to `pmemdest`. The source and destination may _not_ overlap.
///
/// `copy_nonoverlapping` is semantically equivalent to C's `memcpy` and is optimized for persitent memory.
///
/// Ensures that the result has been flushed to persistence before returning.
///
/// # Safety
///
/// Beyond requiring that the program must be allowed to access both regions of memory,
/// it is _Undefined Behavior_ for source and destination to overlap.
/// Care must also be taken with the ownership of `src` and `pmemdest`.
/// This method semantically moves the values of `src` into `pmemdest`.
/// However it does not drop the contents of `pmemdest`, or prevent the contents of `src` from being dropped or used.
pub unsafe fn copy_nonoverlapping<T>(src: *const T, pmemdest: *mut T, count: usize) {
    let len = mem::size_of::<T>() * count;
    ffi::pmem_memcpy_persist(pmemdest as *mut c_void, src as *const c_void, len as size_t);
}

/// Invokes memset on the specified pointer, setting `count * size_of::<T>()` bytes of memory starting at `pmemdest` to `val`.
///
/// Ensures that the result has been flushed to persistence before returning.
pub unsafe fn write_bytes<T>(pmemdest: *mut T, val: u8, count: usize) {
    let len = mem::size_of::<T>() * count;
    ffi::pmem_memset_persist(pmemdest as *mut c_void, val as c_int, len as size_t);
}

/// Overwrites a memory location with the given value without reading or dropping the old value.
///
/// Ensures that the result has been flushed to persistence before returning.
///
/// # Safety
///
/// This operation is marked unsafe because it accepts a raw pointer.
///
/// It does not drop the contents of dst. This is safe, but it could leak allocations or resources,
/// so care must be taken not to overwrite an object that should be dropped.
///
/// This is appropriate for initializing uninitialized memory, or overwriting memory that has previously been read from.
pub unsafe fn write<T>(pmemdest: *mut T, val: T) { copy_nonoverlapping(&val as *const _, pmemdest, 1) }

pub unsafe fn msync<T>(pmemdest: *const T, count: usize) -> Result<(), io::Error> {
    let len = count * mem::size_of::<T>();
    let r = ffi::pmem_msync(pmemdest as *const c_void, len as size_t);
    if r == -1 {
        Err(io::Error::last_os_error())
    } else {
        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::borrow::Cow;
use std::fmt;

use serde::ser::{Serialize, Serializer, SerializeStruct};
use serde::de::{self, Deserialize, Deserializer, DeserializeSeed, IntoDeserializer, MapAccess, Unexpected, Visitor};
use serde::de::value::BorrowedStrDeserializer;

use error::Error;

/// Represents any valid JSON value as a series of raw bytes.
///
/// This type can be used to defer parsing parts of a payload until later,
/// or to embed it verbatim into another JSON payload.
///
/// When serializing, a value of this type will retain its original formatting
/// and will not be minified or pretty-printed.
///
/// When deserializing, this type can not be used with the `#[serde(flatten)]` attribute,
/// as it relies on the original input buffer.

#[derive(Debug, Clone, PartialEq)]
pub struct RawValue<'a>(Cow<'a, str>);

impl<'a> AsRef<str> for RawValue<'a> {
    fn as_ref(&self) -> &str {
        &self.0
    }
}

impl<'a> fmt::Display for RawValue<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&self.0)
    }
}

pub const SERDE_STRUCT_NAME: &'static str = "$serde_json::RawValue";
pub const SERDE_STRUCT_FIELD_NAME: &'static str = "$serde_json::RawValue::id";

impl<'a> Serialize for RawValue<'a> {
    #[inline]
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut s = serializer.serialize_struct(SERDE_STRUCT_NAME, 1)?;
        s.serialize_field(SERDE_STRUCT_FIELD_NAME, &self.0)?;
        s.end()
    }
}

impl<'a, 'de: 'a> Deserialize<'de> for RawValue<'a> {
    #[inline]
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct RawValueVisitor;

        impl<'de> Visitor<'de> for RawValueVisitor {
            type Value = RawValue<'de>;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                write!(formatter, "any valid JSON value")
            }

            fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
            where
                V: MapAccess<'de>,
            {
                let value = visitor.next_key::<RawKey>()?;
                if value.is_none() {
                    return Err(de::Error::invalid_type(Unexpected::Map, &self));
                }
                visitor.next_value_seed(RawValueFromString)
            }
        }

        deserializer.deserialize_newtype_struct(SERDE_STRUCT_NAME, RawValueVisitor)
    }
}

struct RawKey;

impl<'de> Deserialize<'de> for RawKey {
    fn deserialize<D>(deserializer: D) -> Result<RawKey, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct FieldVisitor;

        impl<'de> Visitor<'de> for FieldVisitor {
            type Value = ();

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("raw value")
            }

            fn visit_str<E>(self, s: &str) -> Result<(), E>
            where
                E: de::Error,
            {
                if s == SERDE_STRUCT_FIELD_NAME {
                    Ok(())
                } else {
                    Err(de::Error::custom("unexpected raw value"))
                }
            }
        }

        deserializer.deserialize_identifier(FieldVisitor)?;
        Ok(RawKey)
    }
}

pub struct RawValueFromString;

impl<'de> DeserializeSeed<'de> for RawValueFromString {
    type Value = RawValue<'de>;

    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_str(self)
    }
}

impl<'de> Visitor<'de> for RawValueFromString {
    type Value = RawValue<'de>;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("raw value")
    }

    fn visit_borrowed_str<E>(self, s: &'de str) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        Ok(RawValue(Cow::Borrowed(s)))
    }

    fn visit_string<E>(self, s: String) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        Ok(RawValue(Cow::Owned(s)))
    }
}

struct RawKeyDeserializer;

impl<'de> Deserializer<'de> for RawKeyDeserializer {
    type Error = Error;

    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
    where
        V: de::Visitor<'de>,
    {
        visitor.visit_borrowed_str(SERDE_STRUCT_FIELD_NAME)
    }

    forward_to_deserialize_any! {
        bool u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 char str string seq
        bytes byte_buf map struct option unit newtype_struct ignored_any
        unit_struct tuple_struct tuple enum identifier
    }
}

pub struct OwnedRawDeserializer {
    pub raw_value: Option<String>,
}

impl<'de> MapAccess<'de> for OwnedRawDeserializer {
    type Error = Error;

    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
    where
        K: de::DeserializeSeed<'de>,
    {
        if self.raw_value.is_none() {
            return Ok(None);
        }
        seed.deserialize(RawKeyDeserializer).map(Some)
    }

    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
    where
        V: de::DeserializeSeed<'de>,
    {
        seed.deserialize(self.raw_value.take().unwrap().into_deserializer())
    }
}

pub struct BorrowedRawDeserializer<'de> {
    pub raw_value: Option<&'de str>,
}

impl<'de> MapAccess<'de> for BorrowedRawDeserializer<'de> {
    type Error = Error;

    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
    where
        K: de::DeserializeSeed<'de>,
    {
        if self.raw_value.is_none() {
            return Ok(None);
        }
        seed.deserialize(RawKeyDeserializer).map(Some)
    }

    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
    where
        V: de::DeserializeSeed<'de>,
    {
        seed.deserialize(BorrowedStrDeserializer::new(self.raw_value.take().unwrap()))
    }
}
<commit_msg>Remove PartialEq from RawValue<commit_after>use std::borrow::Cow;
use std::fmt;

use serde::ser::{Serialize, Serializer, SerializeStruct};
use serde::de::{self, Deserialize, Deserializer, DeserializeSeed, IntoDeserializer, MapAccess, Unexpected, Visitor};
use serde::de::value::BorrowedStrDeserializer;

use error::Error;

/// Represents any valid JSON value as a series of raw bytes.
///
/// This type can be used to defer parsing parts of a payload until later,
/// or to embed it verbatim into another JSON payload.
///
/// When serializing, a value of this type will retain its original formatting
/// and will not be minified or pretty-printed.
///
/// When deserializing, this type can not be used with the `#[serde(flatten)]` attribute,
/// as it relies on the original input buffer.

#[derive(Debug, Clone)]
pub struct RawValue<'a>(Cow<'a, str>);

impl<'a> AsRef<str> for RawValue<'a> {
    fn as_ref(&self) -> &str {
        &self.0
    }
}

impl<'a> fmt::Display for RawValue<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&self.0)
    }
}

pub const SERDE_STRUCT_NAME: &'static str = "$serde_json::RawValue";
pub const SERDE_STRUCT_FIELD_NAME: &'static str = "$serde_json::RawValue::id";

impl<'a> Serialize for RawValue<'a> {
    #[inline]
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut s = serializer.serialize_struct(SERDE_STRUCT_NAME, 1)?;
        s.serialize_field(SERDE_STRUCT_FIELD_NAME, &self.0)?;
        s.end()
    }
}

impl<'a, 'de: 'a> Deserialize<'de> for RawValue<'a> {
    #[inline]
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct RawValueVisitor;

        impl<'de> Visitor<'de> for RawValueVisitor {
            type Value = RawValue<'de>;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                write!(formatter, "any valid JSON value")
            }

            fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
            where
                V: MapAccess<'de>,
            {
                let value = visitor.next_key::<RawKey>()?;
                if value.is_none() {
                    return Err(de::Error::invalid_type(Unexpected::Map, &self));
                }
                visitor.next_value_seed(RawValueFromString)
            }
        }

        deserializer.deserialize_newtype_struct(SERDE_STRUCT_NAME, RawValueVisitor)
    }
}

struct RawKey;

impl<'de> Deserialize<'de> for RawKey {
    fn deserialize<D>(deserializer: D) -> Result<RawKey, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct FieldVisitor;

        impl<'de> Visitor<'de> for FieldVisitor {
            type Value = ();

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("raw value")
            }

            fn visit_str<E>(self, s: &str) -> Result<(), E>
            where
                E: de::Error,
            {
                if s == SERDE_STRUCT_FIELD_NAME {
                    Ok(())
                } else {
                    Err(de::Error::custom("unexpected raw value"))
                }
            }
        }

        deserializer.deserialize_identifier(FieldVisitor)?;
        Ok(RawKey)
    }
}

pub struct RawValueFromString;

impl<'de> DeserializeSeed<'de> for RawValueFromString {
    type Value = RawValue<'de>;

    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_str(self)
    }
}

impl<'de> Visitor<'de> for RawValueFromString {
    type Value = RawValue<'de>;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("raw value")
    }

    fn visit_borrowed_str<E>(self, s: &'de str) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        Ok(RawValue(Cow::Borrowed(s)))
    }

    fn visit_string<E>(self, s: String) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        Ok(RawValue(Cow::Owned(s)))
    }
}

struct RawKeyDeserializer;

impl<'de> Deserializer<'de> for RawKeyDeserializer {
    type Error = Error;

    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
    where
        V: de::Visitor<'de>,
    {
        visitor.visit_borrowed_str(SERDE_STRUCT_FIELD_NAME)
    }

    forward_to_deserialize_any! {
        bool u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 char str string seq
        bytes byte_buf map struct option unit newtype_struct ignored_any
        unit_struct tuple_struct tuple enum identifier
    }
}

pub struct OwnedRawDeserializer {
    pub raw_value: Option<String>,
}

impl<'de> MapAccess<'de> for OwnedRawDeserializer {
    type Error = Error;

    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
    where
        K: de::DeserializeSeed<'de>,
    {
        if self.raw_value.is_none() {
            return Ok(None);
        }
        seed.deserialize(RawKeyDeserializer).map(Some)
    }

    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
    where
        V: de::DeserializeSeed<'de>,
    {
        seed.deserialize(self.raw_value.take().unwrap().into_deserializer())
    }
}

pub struct BorrowedRawDeserializer<'de> {
    pub raw_value: Option<&'de str>,
}

impl<'de> MapAccess<'de> for BorrowedRawDeserializer<'de> {
    type Error = Error;

    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
    where
        K: de::DeserializeSeed<'de>,
    {
        if self.raw_value.is_none() {
            return Ok(None);
        }
        seed.deserialize(RawKeyDeserializer).map(Some)
    }

    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
    where
        V: de::DeserializeSeed<'de>,
    {
        seed.deserialize(BorrowedStrDeserializer::new(self.raw_value.take().unwrap()))
    }
}
<|endoftext|>


<commit_before>use std::iter;
use byteorder::{BigEndian, ByteOrder};

pub struct SHA512 {}

impl SHA512 {
    /// Only supports messages with at most 2^64 bytes for now
    pub fn pad(bytes: &mut Vec<u8>) {
        let len = len(bytes);
        bytes.push(0x80);
        let padding = (128 + 112 - bytes.len() % 128) % 128;
        bytes.extend(iter::repeat(0).take(padding));
        bytes.extend_from_slice(&[0; 8]);
        bytes.extend_from_slice(&len);
    }
}

fn len(bytes: &[u8]) -> [u8; 8] {
    let mut len = [0; 8];
    BigEndian::write_u64(&mut len, 8 * bytes.len() as u64);
    len
}

#[cfg(test)]
mod tests {
    use sha::*;
    use test_helpers::*;

    #[test]
    fn test_pad() {
        let mut message = vec![0b01100001, 0b01100010, 0b01100011, 0b01100100, 0b01100101];
        let expected = h2b(
            "6162636465800000000000000000000000000000000000000000000000000000\
             0000000000000000000000000000000000000000000000000000000000000000\
             0000000000000000000000000000000000000000000000000000000000000000\
             0000000000000000000000000000000000000000000000000000000000000028",
        );
        SHA512::pad(&mut message);
        assert_eq!(expected, message);
    }
}
<commit_msg>sha: correct current max length<commit_after>use std::iter;
use byteorder::{BigEndian, ByteOrder};

pub struct SHA512 {}

impl SHA512 {
    /// Only supports messages with at most 2^64 - 1 bits for now
    pub fn pad(bytes: &mut Vec<u8>) {
        let len = len(bytes);
        bytes.push(0x80);
        let padding = (128 + 112 - bytes.len() % 128) % 128;
        bytes.extend(iter::repeat(0).take(padding));
        bytes.extend_from_slice(&[0; 8]);
        bytes.extend_from_slice(&len);
    }
}

fn len(bytes: &[u8]) -> [u8; 8] {
    let mut len = [0; 8];
    BigEndian::write_u64(&mut len, 8 * bytes.len() as u64);
    len
}

#[cfg(test)]
mod tests {
    use sha::*;
    use test_helpers::*;

    #[test]
    fn test_pad() {
        let mut message = vec![0b01100001, 0b01100010, 0b01100011, 0b01100100, 0b01100101];
        let expected = h2b(
            "6162636465800000000000000000000000000000000000000000000000000000\
             0000000000000000000000000000000000000000000000000000000000000000\
             0000000000000000000000000000000000000000000000000000000000000000\
             0000000000000000000000000000000000000000000000000000000000000028",
        );
        SHA512::pad(&mut message);
        assert_eq!(expected, message);
    }
}
<|endoftext|>


<commit_before>
use std::marker;
use std::ops::Add;

// TODO: mm: Implement from_str_radix()

#[derive(Debug,Clone,Copy,PartialEq,Eq,PartialOrd,Ord)]
pub struct U12(u16);

// MARK: - Public Constants

pub const MAX: U12 = U12(0xFFF);
pub const MIN: U12 = U12(0x000);

// MARK: - Implementation

impl U12 {

  /// Returns the smallest value that can be represented by this integer type.
  pub fn min_value() -> Self {
    MIN
  }

  /// Returns the largest value that can be represented by this integer type.
  pub fn max_value() -> Self {
    MAX
  }

  /// Returns the number of ones in the binary representation of `self`.
  pub fn count_ones(self) -> u32 {
    self.0.count_ones()
  }

  /// Returns the number of zeros in the binary representation of `self`.
  pub fn count_zeros(self) -> u32 {
    self.0.count_zeros() - 4
  }

  /// Returns the number of leading zeros in the binary representation of `self`.
  pub fn leading_zeros(self) -> u32 {
    self.0.leading_zeros() - 4
  }

  /// Returns the number of trailing zeros in the binary representation of `self`.
  pub fn trailing_zeros(self) -> u32 {
    self.0.trailing_zeros()
  }

  /// Checked integer addition.
  /// Computes `self + other`, returning `None` if overflow occurred.
  pub fn checked_add(self, other: Self) -> Option<Self> {
    match self.0 + other.0 {
      result @ 0...4095 => Some(U12(result)),
      _ => None
    }
  }

  /// Saturating integer addition.
  /// Computes `self + other`, saturating at the numeric bounds instead of overflowing.
  pub fn saturating_add(self, other: Self) -> Self {
    match self.0 + other.0 {
      result @ 0...4095 => U12(result),
      _ => Self::max_value()
    }
  }

  /// Wrapping (modular) addition.
  /// Computes `self + other`, wrapping around at the boundary of the type.
  pub fn wrapping_add(self, other: Self) -> Self {
    U12((self.0 + other.0) & 0xFFF)
  }

}

// MARK: - Non-Failable Conversions - From Smaller Types

impl From<u8> for U12 {
  fn from(small: u8) -> Self {
    U12(small as u16)
  }
}

// MARK: - Non-Failable Conversions - Into Larger Types

/// Implements From<U12> for the specified type.
macro_rules! impl_from_u12 {
  ($result:path) => {
    impl From<U12> for $result {
      fn from(small: U12) -> Self {
        small.0 as Self
      }
    }
  }
}

impl_from_u12!(u16);
impl_from_u12!(u32);
impl_from_u12!(u64);
impl_from_u12!(usize);

// MARK: - Failable Conversions - From Larger Types

/// Trait for implementing failable conversions in a generic way.
pub trait FailableInto<T> where Self: marker::Sized, T: marker::Sized {

  /// Returns the receiver as `Some(T)` if non-truncating, or `None`.
  fn failable_into(self) -> Option<T>;

  /// Returns the receiver as `T` by using `convert_as()` and unwrapping the result.
  ///
  /// # Panics
  /// This method will panic if `convert_as` fails.
  fn unchecked_into(self) -> T {
    self.failable_into().unwrap()
  }

}

/// Implements FailableAs<U12> for the specified type.
macro_rules! impl_failable_into_u12 {
  ($from:path) => {
    impl FailableInto<U12> for $from {
      fn failable_into(self) -> Option<U12> {
        if self > 0xFFF {
          None
        } else {
          Some(U12(self as u16))
        }
      }
    }
  }
}

impl_failable_into_u12!(u16);
impl_failable_into_u12!(u32);
impl_failable_into_u12!(u64);
impl_failable_into_u12!(usize);

// MARK: - Default Value

impl Default for U12 {
  fn default() -> Self {
    U12::min_value()
  }
}

// MARK: - Add

impl Add<U12> for U12 {
  type Output = U12;
  fn add(self, other: U12) -> Self::Output {
    match self.checked_add(other) {
      Some(result) => result,
      None => panic!("arithmetic overflow")
    }
  }
}

impl<'a> Add<U12> for &'a U12 {
  type Output = U12;
  fn add(self, other: U12) -> Self::Output {
    (*self).add(other)
  }
}

impl<'a> Add<&'a U12> for U12 {
  type Output = U12;
  fn add(self, other: &'a U12) -> Self::Output {
    self.add(*other)
  }
}

impl<'a,'b> Add<&'a U12> for &'b U12 {
  type Output = U12;
  fn add(self, other: &'a U12) -> Self::Output {
    (*self).add(*other)
  }
}
<commit_msg>Rustdoc tests for Add and Sub variants.<commit_after>
use std::marker;
use std::ops::Add;

// TODO: mm: Implement from_str_radix()

#[derive(Debug,Clone,Copy,PartialEq,Eq,PartialOrd,Ord)]
pub struct U12(u16);

// MARK: - Public Constants

pub const MAX: U12 = U12(0xFFF);
pub const MIN: U12 = U12(0x000);

// MARK: - Implementation

impl U12 {

  /// Returns the smallest value that can be represented by this integer type.
  pub fn min_value() -> Self {
    MIN
  }

  /// Returns the largest value that can be represented by this integer type.
  pub fn max_value() -> Self {
    MAX
  }

  /// Returns the number of ones in the binary representation of `self`.
  pub fn count_ones(self) -> u32 {
    self.0.count_ones()
  }

  /// Returns the number of zeros in the binary representation of `self`.
  pub fn count_zeros(self) -> u32 {
    self.0.count_zeros() - 4
  }

  /// Returns the number of leading zeros in the binary representation of `self`.
  pub fn leading_zeros(self) -> u32 {
    self.0.leading_zeros() - 4
  }

  /// Returns the number of trailing zeros in the binary representation of `self`.
  pub fn trailing_zeros(self) -> u32 {
    self.0.trailing_zeros()
  }

  /// Checked integer addition.
  /// Computes `self + other`, returning `None` if overflow occurred.
  ///
  /// # Examples
  /// Basic usage:
  ///
  /// ```
  /// use twelve_bit::u12::U12;
  ///
  /// assert_eq!(U12::from(1u8).checked_add(1u8.into()), Some(U12::from(2u8)));
  /// assert_eq!(U12::max_value().checked_add(1u8.into()), None);
  /// ```
  pub fn checked_add(self, other: Self) -> Option<Self> {
    match self.0 + other.0 {
      result @ 0...4095 => Some(U12(result)),
      _ => None
    }
  }

  /// Saturating integer addition.
  /// Computes `self + other`, saturating at the numeric bounds instead of overflowing.
  ///
  /// # Examples
  /// Basic usage:
  ///
  /// ```
  /// use twelve_bit::u12::U12;
  ///
  /// assert_eq!(U12::from(1u8).saturating_add(1u8.into()), U12::from(2u8));
  /// assert_eq!(U12::max_value().saturating_add(1u8.into()), U12::max_value());
  /// ```
  pub fn saturating_add(self, other: Self) -> Self {
    match self.0 + other.0 {
      result @ 0...4095 => U12(result),
      _ => Self::max_value()
    }
  }

  /// Wrapping (modular) addition.
  /// Computes `self + other`, wrapping around at the boundary of the type.
  ///
  /// # Examples
  /// Basic usage:
  ///
  /// ```
  /// use twelve_bit::u12::U12;
  ///
  /// assert_eq!(U12::from(1u8).wrapping_add(1u8.into()), U12::from(2u8));
  /// assert_eq!(U12::max_value().wrapping_add(3u8.into()), U12::from(2u8));
  /// ```
  pub fn wrapping_add(self, other: Self) -> Self {
    U12((self.0 + other.0) & 0xFFF)
  }

  /// Checked integer subtraction.
  /// Computes `self - other`, returning `None` if underflow occurred.
  ///
  /// # Examples
  /// Basic usage:
  ///
  /// ```
  /// use twelve_bit::u12::U12;
  ///
  /// assert_eq!(U12::from(1u8).checked_sub(1u8.into()), Some(U12::from(0u8)));
  /// assert_eq!(U12::min_value().checked_sub(1u8.into()), None);
  /// ```
  pub fn checked_sub(self, other: Self) -> Option<Self> {
    match self.0.checked_sub(other.0) {
      Some(value) => Some(U12(value)),
      None => None
    }
  }

  /// Saturating integer subtraction.
  /// Computes `self - other`, saturating at the numeric bounds instead of overflowing.
  ///
  /// # Examples
  /// Basic usage:
  ///
  /// ```
  /// use twelve_bit::u12::U12;
  ///
  /// assert_eq!(U12::from(1u8).saturating_sub(1u8.into()), U12::min_value());
  /// assert_eq!(U12::min_value().saturating_sub(5u8.into()), U12::min_value());
  /// ```
  pub fn saturating_sub(self, other: Self) -> Self {
    U12(self.0.saturating_sub(other.0))
  }

  /// Wrapping (modular) subtraction.
  /// Computes `self - other`, wrapping around at the boundary of the type.
  ///
  /// # Examples
  /// Basic usage:
  ///
  /// ```
  /// use twelve_bit::u12::*;
  ///
  /// assert_eq!(U12::from(1u8).wrapping_sub(1u8.into()), U12::min_value());
  /// assert_eq!(U12::min_value().wrapping_sub(5u8.into()), (0xFFB as u16).unchecked_into());
  /// ```
  pub fn wrapping_sub(self, other: Self) -> Self {
    U12(self.0.wrapping_sub(other.0) & 0xFFF)
  }

}

// MARK: - Non-Failable Conversions - From Smaller Types

impl From<u8> for U12 {
  fn from(small: u8) -> Self {
    U12(small as u16)
  }
}

// MARK: - Non-Failable Conversions - Into Larger Types

/// Implements From<U12> for the specified type.
macro_rules! impl_from_u12 {
  ($result:path) => {
    impl From<U12> for $result {
      fn from(small: U12) -> Self {
        small.0 as Self
      }
    }
  }
}

impl_from_u12!(u16);
impl_from_u12!(u32);
impl_from_u12!(u64);
impl_from_u12!(usize);

// MARK: - Failable Conversions - From Larger Types

/// Trait for implementing failable conversions in a generic way.
pub trait FailableInto<T> where Self: marker::Sized, T: marker::Sized {

  /// Returns the receiver as `Some(T)` if non-truncating, or `None`.
  fn failable_into(self) -> Option<T>;

  /// Returns the receiver as `T` by using `convert_as()` and unwrapping the result.
  ///
  /// # Panics
  /// This method will panic if `convert_as` fails.
  fn unchecked_into(self) -> T {
    self.failable_into().unwrap()
  }

}

/// Implements FailableAs<U12> for the specified type.
macro_rules! impl_failable_into_u12 {
  ($from:path) => {
    impl FailableInto<U12> for $from {
      fn failable_into(self) -> Option<U12> {
        if self > 0xFFF {
          None
        } else {
          Some(U12(self as u16))
        }
      }
    }
  }
}

impl_failable_into_u12!(u16);
impl_failable_into_u12!(u32);
impl_failable_into_u12!(u64);
impl_failable_into_u12!(usize);

// MARK: - Default Value

impl Default for U12 {
  fn default() -> Self {
    U12::min_value()
  }
}

// MARK: - Add

impl Add<U12> for U12 {
  type Output = U12;
  fn add(self, other: U12) -> Self::Output {
    match self.checked_add(other) {
      Some(result) => result,
      None => panic!("arithmetic overflow")
    }
  }
}

impl<'a> Add<U12> for &'a U12 {
  type Output = U12;
  fn add(self, other: U12) -> Self::Output {
    (*self).add(other)
  }
}

impl<'a> Add<&'a U12> for U12 {
  type Output = U12;
  fn add(self, other: &'a U12) -> Self::Output {
    self.add(*other)
  }
}

impl<'a,'b> Add<&'a U12> for &'b U12 {
  type Output = U12;
  fn add(self, other: &'a U12) -> Self::Output {
    (*self).add(*other)
  }
}
<|endoftext|>


<commit_before>
use iron::{Iron, IronResult, Listening, status};
use iron::error::HttpResult;
use iron::response::Response;
use iron::request::Request;
use iron::middleware::Handler;
use iron::mime::Mime;

use sysinfo::{System, SystemExt};
use std::sync::{Arc, RwLock};
use std::thread;
use std::time::Duration;
use SysinfoExt;
use serde_json;

const INDEX_HTML: &'static str = include_str!("index.html");

struct SysinfoIronHandler(Arc<RwLock<System>>);

impl Handler for SysinfoIronHandler {
    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        match req.url.path().last() {
            Some(path) => {
                if *path == "" {
                    Ok(Response::with((status::Ok,
                                       "text/html".parse::<Mime>().unwrap(),
                                       INDEX_HTML)))
                } else {
                    let system = self.0.read().unwrap();
                    let sysinfo = SysinfoExt::new(&system);
                    Ok(Response::with((status::Ok,
                                       "application/json".parse::<Mime>().unwrap(),
                                       serde_json::to_string(&sysinfo).unwrap_or(String::new()))))
                }
            },
            None => Ok(Response::with((status::NotFound, "Not found")))
        }
    }
}

pub fn start_web_server(sock_addr: Option<String>) -> HttpResult<Listening> {
    let system = Arc::new(RwLock::new(System::new()));
    let system_clone = system.clone();
    thread::spawn(move || {
        loop {
            {
                let mut system = system_clone.write().unwrap();
                system.refresh_all();
            }
            thread::sleep(Duration::new(5, 0));
        }
    });
    let mut iron = Iron::new(SysinfoIronHandler(system));
    iron.threads = 4;
    iron.http(sock_addr.unwrap_or("localhost:3000".to_owned()))
}
<commit_msg>If no user connected in 10 minutes, system information won't be updated<commit_after>
use iron::{Iron, IronResult, Listening, status};
use iron::error::HttpResult;
use iron::response::Response;
use iron::request::Request;
use iron::middleware::Handler;
use iron::mime::Mime;

use sysinfo::{System, SystemExt};
use std::sync::{Arc, Mutex, RwLock};
use std::thread;
use std::time::{Duration, SystemTime};
use SysinfoExt;
use serde_json;

const INDEX_HTML: &'static str = include_str!("index.html");
const REFRESH_DELAY: u64 = 60 * 10; // 10 minutes

struct SysinfoIronHandler(Arc<DataHandler>);

struct DataHandler {
    system: RwLock<System>,
    last_connection: Mutex<SystemTime>,
}

impl DataHandler {
    fn can_update_system_info(&self) -> bool {
        SystemTime::now().duration_since(*self.last_connection.lock().unwrap())
                         .unwrap()
                         .as_secs() < REFRESH_DELAY
    }

    fn update_last_connection(&self) {
        *self.last_connection.lock().unwrap() = SystemTime::now();
    }
}

impl Handler for SysinfoIronHandler {
    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        match req.url.path().last() {
            Some(path) => {
                if *path == "" {
                    Ok(Response::with((status::Ok,
                                       "text/html".parse::<Mime>().unwrap(),
                                       INDEX_HTML)))
                } else {
                    self.0.update_last_connection();
                    let system = self.0.system.read().unwrap();
                    let sysinfo = SysinfoExt::new(&system);
                    Ok(Response::with((status::Ok,
                                       "application/json".parse::<Mime>().unwrap(),
                                       serde_json::to_string(&sysinfo).unwrap_or(String::new()))))
                }
            },
            None => Ok(Response::with((status::NotFound, "Not found")))
        }
    }
}

pub fn start_web_server(sock_addr: Option<String>) -> HttpResult<Listening> {
    let data_handler = Arc::new(DataHandler {
        system: RwLock::new(System::new()),
        last_connection: Mutex::new(SystemTime::now()),
    });
    let data_handler_clone = data_handler.clone();
    thread::spawn(move || {
        loop {
            if data_handler_clone.can_update_system_info() {
                {
                    let mut system = data_handler_clone.system.write().unwrap();
                    system.refresh_all();
                }
                thread::sleep(Duration::new(5, 0));
            } else {
                // If we don't need to refresh the system information, we can sleep a lot less.
                thread::sleep(Duration::from_millis(500));
            }
        }
    });
    let mut iron = Iron::new(SysinfoIronHandler(data_handler));
    iron.threads = 4;
    iron.http(sock_addr.unwrap_or("localhost:3000".to_owned()))
}
<|endoftext|>


<commit_before>#[cfg_attr(target_os = "emscripten", ignore)]
#[rustversion::attr(not(nightly), ignore)]
#[test]
fn ui() {
    let t = trybuild::TestCases::new();
    t.compile_fail("tests/ui/**/*.rs");
}
<commit_msg>Disable ui test on miri<commit_after>#[cfg_attr(target_os = "emscripten", ignore)]
#[rustversion::attr(not(nightly), ignore)]
#[cfg_attr(miri, ignore)]
#[test]
fn ui() {
    let t = trybuild::TestCases::new();
    t.compile_fail("tests/ui/**/*.rs");
}
<|endoftext|>