<commit_before>//! This library provides [`anyhow::Error`][Error], a trait object based error
//! type for easy idiomatic error handling in Rust applications.
//!
//!

//!
//! # Details
//!
//! - Use `Result<T, anyhow::Error>`, or equivalently `anyhow::Result<T>`, as
//!   the return type of any fallible function.
//!
//!   Within the function, use `?` to easily propagate any error that implements
//!   the `std::error::Error` trait.
//!
//!   ```
//!   # pub trait Deserialize {}
//!   #
//!   # mod serde_json {
//!   #     use super::Deserialize;
//!   #     use std::io;
//!   #
//!   #     pub fn from_str<T: Deserialize>(json: &str) -> io::Result<T> {
//!   #         unimplemented!()
//!   #     }
//!   # }
//!   #
//!   # struct ClusterMap;
//!   #
//!   # impl Deserialize for ClusterMap {}
//!   #
//!   use anyhow::Result;
//!
//!   fn get_cluster_info() -> Result<ClusterMap> {
//!       let config = std::fs::read_to_string("cluster.json")?;
//!       let map: ClusterMap = serde_json::from_str(&config)?;
//!       Ok(map)
//!   }
//!   #
//!   # fn main() {}
//!   ```
//!
//! - Attach context to help the person troubleshooting the error understand
//!   where things went wrong. A low-level error like "No such file or
//!   directory" can be annoying to debug without more context about what higher
//!   level step the application was in the middle of.
//!
//!   ```
//!   # struct It;
//!   #
//!   # impl It {
//!   #     fn detach(&self) -> Result<()> {
//!   #         unimplemented!()
//!   #     }
//!   # }
//!   #
//!   use anyhow::{Context, Result};
//!
//!   fn main() -> Result<()> {
//!       # return Ok(());
//!       #
//!       # const _: &str = stringify! {
//!       ...
//!       # };
//!       #
//!       # let it = It;
//!       # let path = "./path/to/instrs.jsox";
//!       #
//!       it.detach().context("failed to detach the important thing")?;
//!
//!       let content = std::fs::read(path)
//!           .with_context(|| format!("failed to read instrs from {}", path))?;
//!       #
//!       # const _: &str = stringify! {
//!       ...
//!       # };
//!       #
//!       # Ok(())
//!   }
//!   ```
//!
//!   ```console
//!   Error: failed to read instrs from ./path/to/instrs.jsox
//!
//!   Caused by:
//!       No such file or directory (os error 2)
//!   ```
//!
//! - Downcasting is supported and can be by value, by shared reference, or by
//!   mutable reference as needed.
//!
//!   ```
//!   # use anyhow::anyhow;
//!   # use std::fmt::{self, Display};
//!   # use std::task::Poll;
//!   #
//!   # #[derive(Debug)]
//!   # enum DataStoreError {
//!   #     Censored(()),
//!   # }
//!   #
//!   # impl Display for DataStoreError {
//!   #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
//!   #         unimplemented!()
//!   #     }
//!   # }
//!   #
//!   # impl std::error::Error for DataStoreError {}
//!   #
//!   # const REDACTED_CONTENT: () = ();
//!   #
//!   # let error = anyhow!("...");
//!   # let root_cause = &error;
//!   #
//!   # let ret =
//!   // If the error was caused by redaction, then return a
//!   // tombstone instead of the content.
//!   match root_cause.downcast_ref::<DataStoreError>() {
//!       Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
//!       None => Err(error),
//!   }
//!   # ;
//!   ```
//!
//! - A backtrace is captured and printed with the error if the underlying error
//!   type does not already provide its own. In order to see backtraces, the
//!   `RUST_LIB_BACKTRACE=1` environment variable must be defined.
//!
//! - Anyhow works with any error type that has an impl of `std::error::Error`,
//!   including ones defined in your crate. We do not bundle a `derive(Error)`
//!   macro but you can write the impls yourself or use a standalone macro like
//!   [thiserror].
//!
//!   [thiserror]: https://github.com/dtolnay/thiserror
//!
//!   ```
//!   use thiserror::Error;
//!
//!   #[derive(Error, Debug)]
//!   pub enum FormatError {
//!       #[error("invalid header (expected {expected:?}, got {found:?})")]
//!       InvalidHeader {
//!           expected: String,
//!           found: String,
//!       },
//!       #[error("missing attribute: {0}")]
//!       MissingAttribute(String),
//!   }
//!   ```
//!
//! - One-off error messages can be constructed using the `anyhow!` macro, which
//!   supports string interpolation and produces an `anyhow::Error`.
//!
//!   ```
//!   # use anyhow::{anyhow, Result};
//!   #
//!   # fn demo() -> Result<()> {
//!   #     let missing = "...";
//!   return Err(anyhow!("missing attribute: {}", missing));
//!   #     Ok(())
//!   # }
//!   ```
//!
//!

//!
//! # Acknowledgements
//!
//! The implementation of the `anyhow::Error` type is originally forked from
//! `fehler::Exception` ([https://github.com/withoutboats/fehler][fehler]). This
//! library exposes it under the more standard `Error` / `Result` terminology
//! rather than the `throw!` / `#[throws]` / `Exception` language of exceptions.
//!
//! [fehler]: https://github.com/withoutboats/fehler

#![doc(html_root_url = "https://docs.rs/anyhow/1.0.14")]
#![cfg_attr(backtrace, feature(backtrace))]
#![allow(clippy::new_ret_no_self, clippy::wrong_self_convention)]

#[macro_use]
mod backtrace;
mod context;
mod error;
mod kind;

#[cfg(not(feature = "std"))]
compile_error!("no_std support is not implemented yet");

pub use crate::context::Context;
pub use crate::error::{Chain, Error};

/// `Result<T, Error>`
///
/// This is a reasonable return type to use throughout your application but also
/// for `fn main`; if you do, failures will be printed along with any
/// [context][Context] and a backtrace if one was captured.
///
/// # Example
///
/// ```
/// # pub trait Deserialize {}
/// #
/// # mod serde_json {
/// #     use super::Deserialize;
/// #     use std::io;
/// #
/// #     pub fn from_str<T: Deserialize>(json: &str) -> io::Result<T> {
/// #         unimplemented!()
/// #     }
/// # }
/// #
/// # #[derive(Debug)]
/// # struct ClusterMap;
/// #
/// # impl Deserialize for ClusterMap {}
/// #
/// use anyhow::Result;
///
/// fn main() -> Result<()> {
///     # return Ok(());
///     let config = std::fs::read_to_string("cluster.json")?;
///     let map: ClusterMap = serde_json::from_str(&config)?;
///     println!("cluster info: {:#?}", map);
///     Ok(())
/// }
/// ```
pub type Result<T, E = Error> = std::result::Result<T, E>;

/// Return early with an error.
///
/// This macro is equivalent to `return Err(From::from($err))`.
///
/// # Example
///
/// ```
/// # use anyhow::{bail, Result};
/// #
/// # fn has_permission(user: usize, resource: usize) -> bool {
/// #     true
/// # }
/// #
/// # fn main() -> Result<()> {
/// #     let user = 0;
/// #     let resource = 0;
/// #
/// if !has_permission(user, resource) {
///     bail!("permission denied for accessing {}", resource);
/// }
/// #     Ok(())
/// # }
/// ```
///
/// ```
/// # use anyhow::{bail, Result};
/// # use std::fmt::{self, Display};
/// #
/// # #[derive(Debug)]
/// # enum ScienceError {
/// #     RecursionLimitExceeded,
/// # }
/// #
/// # impl std::error::Error for ScienceError {}
/// #
/// # impl Display for ScienceError {
/// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
/// #         unimplemented!()
/// #     }
/// # }
/// #
/// # const MAX_DEPTH: usize = 1;
/// #
/// # const IGNORE: &str = stringify! {
/// #[derive(Error, Debug)]
/// enum ScienceError {
///     #[error(display = "recursion limit exceeded")]
///     RecursionLimitExceeded,
///     ...
/// }
/// # };
///
/// # fn main() -> Result<()> {
/// #     let depth = 0;
/// #
/// if depth > MAX_DEPTH {
///     bail!(ScienceError::RecursionLimitExceeded);
/// }
/// #     Ok(())
/// # }
/// ```
#[macro_export]
macro_rules! bail {
    ($msg:literal $(,)?) => {
        return std::result::Result::Err($crate::anyhow!($msg));
    };
    ($err:expr $(,)?) => {
        return std::result::Result::Err($crate::anyhow!($err));
    };
    ($fmt:expr, $($arg:tt)*) => {
        return std::result::Result::Err($crate::anyhow!($fmt, $($arg)*));
    };
}

/// Return early with an error if a condition is not satisfied.
///
/// This macro is equivalent to `if !$cond { return Err(From::from($err)); }`.
///
/// Analogously to `assert!`, `ensure!` takes a condition and exits the function
/// if the condition fails. Unlike `assert!`, `ensure!` returns an `Error`
/// rather than panicking.
///
/// # Example
///
/// ```
/// # use anyhow::{ensure, Result};
/// #
/// # fn main() -> Result<()> {
/// #     let user = 0;
/// #
/// ensure!(user == 0, "only user 0 is allowed");
/// #     Ok(())
/// # }
/// ```
///
/// ```
/// # use anyhow::{ensure, Result};
/// # use std::fmt::{self, Display};
/// #
/// # #[derive(Debug)]
/// # enum ScienceError {
/// #     RecursionLimitExceeded,
/// # }
/// #
/// # impl std::error::Error for ScienceError {}
/// #
/// # impl Display for ScienceError {
/// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
/// #         unimplemented!()
/// #     }
/// # }
/// #
/// # const MAX_DEPTH: usize = 1;
/// #
/// # const IGNORE: &str = stringify! {
/// #[derive(Error, Debug)]
/// enum ScienceError {
///     #[error(display = "recursion limit exceeded")]
///     RecursionLimitExceeded,
///     ...
/// }
/// # };
///
/// # fn main() -> Result<()> {
/// #     let depth = 0;
/// #
/// ensure!(depth <= MAX_DEPTH, ScienceError::RecursionLimitExceeded);
/// #     Ok(())
/// # }
/// ```
#[macro_export]
macro_rules! ensure {
    ($cond:expr, $msg:literal $(,)?) => {
        if !$cond {
            return std::result::Result::Err($crate::anyhow!($msg));
        }
    };
    ($cond:expr, $err:expr $(,)?) => {
        if !$cond {
            return std::result::Result::Err($crate::anyhow!($err));
        }
    };
    ($cond:expr, $fmt:expr, $($arg:tt)*) => {
        if !$cond {
            return std::result::Result::Err($crate::anyhow!($fmt, $($arg)*));
        }
    };
}

/// Construct an ad-hoc error from a string.
///
/// This evaluates to an `Error`. It can take either just a string, or a format
/// string with arguments. It also can take any custom type which implements
/// `Debug` and `Display`.
///
/// # Example
///
/// ```
/// # type V = ();
/// #
/// use anyhow::{anyhow, Result};
///
/// fn lookup(key: &str) -> Result<V> {
///     if key.len() != 16 {
///         return Err(anyhow!("key length must be 16 characters, got {:?}", key));
///     }
///
///     // ...
///     # Ok(())
/// }
/// ```
#[macro_export]
macro_rules! anyhow {
    ($msg:literal $(,)?) => {
        // Handle $:literal as a special case to make cargo-expanded code more
        // concise in the common case.
        $crate::private::new_adhoc($msg)
    };
    ($err:expr $(,)?) => ({
        #[allow(unused_imports)]
        use $crate::private::{AdhocKind, TraitKind};
        let error = $err;
        (&error).anyhow_kind().new(error)
    });
    ($fmt:expr, $($arg:tt)*) => {
        $crate::private::new_adhoc(format!($fmt, $($arg)*))
    };
}

// Not public API.
#[doc(hidden)]
pub mod private {
    use crate::Error;
    use std::fmt::{Debug, Display};

    #[cfg(backtrace)]
    use std::backtrace::Backtrace;

    pub use crate::kind::{AdhocKind, TraitKind};

    pub fn new_adhoc<M>(message: M) -> Error
    where
        M: Display + Debug + Send + Sync + 'static,
    {
        Error::from_adhoc(message, backtrace!())
    }
}
<commit_msg>Show example of anyhow::Result with two type parameters<commit_after>//! This library provides [`anyhow::Error`][Error], a trait object based error
//! type for easy idiomatic error handling in Rust applications.
//!
//!

//!
//! # Details
//!
//! - Use `Result<T, anyhow::Error>`, or equivalently `anyhow::Result<T>`, as
//!   the return type of any fallible function.
//!
//!   Within the function, use `?` to easily propagate any error that implements
//!   the `std::error::Error` trait.
//!
//!   ```
//!   # pub trait Deserialize {}
//!   #
//!   # mod serde_json {
//!   #     use super::Deserialize;
//!   #     use std::io;
//!   #
//!   #     pub fn from_str<T: Deserialize>(json: &str) -> io::Result<T> {
//!   #         unimplemented!()
//!   #     }
//!   # }
//!   #
//!   # struct ClusterMap;
//!   #
//!   # impl Deserialize for ClusterMap {}
//!   #
//!   use anyhow::Result;
//!
//!   fn get_cluster_info() -> Result<ClusterMap> {
//!       let config = std::fs::read_to_string("cluster.json")?;
//!       let map: ClusterMap = serde_json::from_str(&config)?;
//!       Ok(map)
//!   }
//!   #
//!   # fn main() {}
//!   ```
//!
//! - Attach context to help the person troubleshooting the error understand
//!   where things went wrong. A low-level error like "No such file or
//!   directory" can be annoying to debug without more context about what higher
//!   level step the application was in the middle of.
//!
//!   ```
//!   # struct It;
//!   #
//!   # impl It {
//!   #     fn detach(&self) -> Result<()> {
//!   #         unimplemented!()
//!   #     }
//!   # }
//!   #
//!   use anyhow::{Context, Result};
//!
//!   fn main() -> Result<()> {
//!       # return Ok(());
//!       #
//!       # const _: &str = stringify! {
//!       ...
//!       # };
//!       #
//!       # let it = It;
//!       # let path = "./path/to/instrs.jsox";
//!       #
//!       it.detach().context("failed to detach the important thing")?;
//!
//!       let content = std::fs::read(path)
//!           .with_context(|| format!("failed to read instrs from {}", path))?;
//!       #
//!       # const _: &str = stringify! {
//!       ...
//!       # };
//!       #
//!       # Ok(())
//!   }
//!   ```
//!
//!   ```console
//!   Error: failed to read instrs from ./path/to/instrs.jsox
//!
//!   Caused by:
//!       No such file or directory (os error 2)
//!   ```
//!
//! - Downcasting is supported and can be by value, by shared reference, or by
//!   mutable reference as needed.
//!
//!   ```
//!   # use anyhow::anyhow;
//!   # use std::fmt::{self, Display};
//!   # use std::task::Poll;
//!   #
//!   # #[derive(Debug)]
//!   # enum DataStoreError {
//!   #     Censored(()),
//!   # }
//!   #
//!   # impl Display for DataStoreError {
//!   #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
//!   #         unimplemented!()
//!   #     }
//!   # }
//!   #
//!   # impl std::error::Error for DataStoreError {}
//!   #
//!   # const REDACTED_CONTENT: () = ();
//!   #
//!   # let error = anyhow!("...");
//!   # let root_cause = &error;
//!   #
//!   # let ret =
//!   // If the error was caused by redaction, then return a
//!   // tombstone instead of the content.
//!   match root_cause.downcast_ref::<DataStoreError>() {
//!       Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
//!       None => Err(error),
//!   }
//!   # ;
//!   ```
//!
//! - A backtrace is captured and printed with the error if the underlying error
//!   type does not already provide its own. In order to see backtraces, the
//!   `RUST_LIB_BACKTRACE=1` environment variable must be defined.
//!
//! - Anyhow works with any error type that has an impl of `std::error::Error`,
//!   including ones defined in your crate. We do not bundle a `derive(Error)`
//!   macro but you can write the impls yourself or use a standalone macro like
//!   [thiserror].
//!
//!   [thiserror]: https://github.com/dtolnay/thiserror
//!
//!   ```
//!   use thiserror::Error;
//!
//!   #[derive(Error, Debug)]
//!   pub enum FormatError {
//!       #[error("invalid header (expected {expected:?}, got {found:?})")]
//!       InvalidHeader {
//!           expected: String,
//!           found: String,
//!       },
//!       #[error("missing attribute: {0}")]
//!       MissingAttribute(String),
//!   }
//!   ```
//!
//! - One-off error messages can be constructed using the `anyhow!` macro, which
//!   supports string interpolation and produces an `anyhow::Error`.
//!
//!   ```
//!   # use anyhow::{anyhow, Result};
//!   #
//!   # fn demo() -> Result<()> {
//!   #     let missing = "...";
//!   return Err(anyhow!("missing attribute: {}", missing));
//!   #     Ok(())
//!   # }
//!   ```
//!
//!

//!
//! # Acknowledgements
//!
//! The implementation of the `anyhow::Error` type is originally forked from
//! `fehler::Exception` ([https://github.com/withoutboats/fehler][fehler]). This
//! library exposes it under the more standard `Error` / `Result` terminology
//! rather than the `throw!` / `#[throws]` / `Exception` language of exceptions.
//!
//! [fehler]: https://github.com/withoutboats/fehler

#![doc(html_root_url = "https://docs.rs/anyhow/1.0.14")]
#![cfg_attr(backtrace, feature(backtrace))]
#![allow(clippy::new_ret_no_self, clippy::wrong_self_convention)]

#[macro_use]
mod backtrace;
mod context;
mod error;
mod kind;

#[cfg(not(feature = "std"))]
compile_error!("no_std support is not implemented yet");

pub use crate::context::Context;
pub use crate::error::{Chain, Error};

/// `Result<T, Error>`
///
/// This is a reasonable return type to use throughout your application but also
/// for `fn main`; if you do, failures will be printed along with any
/// [context][Context] and a backtrace if one was captured.
///
/// `anyhow::Result` may be used with one *or* two type parameters.
///
/// ```rust
/// use anyhow::Result;
///
/// # const IGNORE: &str = stringify! {
/// fn demo1() -> Result<T> {...}
///            // ^ equivalent to std::result::Result<T, anyhow::Error>
///
/// fn demo2() -> Result<T, OtherError> {...}
///            // ^ equivalent to std::result::Result<T, OtherError>
/// # };
/// ```
///
/// # Example
///
/// ```
/// # pub trait Deserialize {}
/// #
/// # mod serde_json {
/// #     use super::Deserialize;
/// #     use std::io;
/// #
/// #     pub fn from_str<T: Deserialize>(json: &str) -> io::Result<T> {
/// #         unimplemented!()
/// #     }
/// # }
/// #
/// # #[derive(Debug)]
/// # struct ClusterMap;
/// #
/// # impl Deserialize for ClusterMap {}
/// #
/// use anyhow::Result;
///
/// fn main() -> Result<()> {
///     # return Ok(());
///     let config = std::fs::read_to_string("cluster.json")?;
///     let map: ClusterMap = serde_json::from_str(&config)?;
///     println!("cluster info: {:#?}", map);
///     Ok(())
/// }
/// ```
pub type Result<T, E = Error> = std::result::Result<T, E>;

/// Return early with an error.
///
/// This macro is equivalent to `return Err(From::from($err))`.
///
/// # Example
///
/// ```
/// # use anyhow::{bail, Result};
/// #
/// # fn has_permission(user: usize, resource: usize) -> bool {
/// #     true
/// # }
/// #
/// # fn main() -> Result<()> {
/// #     let user = 0;
/// #     let resource = 0;
/// #
/// if !has_permission(user, resource) {
///     bail!("permission denied for accessing {}", resource);
/// }
/// #     Ok(())
/// # }
/// ```
///
/// ```
/// # use anyhow::{bail, Result};
/// # use std::fmt::{self, Display};
/// #
/// # #[derive(Debug)]
/// # enum ScienceError {
/// #     RecursionLimitExceeded,
/// # }
/// #
/// # impl std::error::Error for ScienceError {}
/// #
/// # impl Display for ScienceError {
/// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
/// #         unimplemented!()
/// #     }
/// # }
/// #
/// # const MAX_DEPTH: usize = 1;
/// #
/// # const IGNORE: &str = stringify! {
/// #[derive(Error, Debug)]
/// enum ScienceError {
///     #[error(display = "recursion limit exceeded")]
///     RecursionLimitExceeded,
///     ...
/// }
/// # };
///
/// # fn main() -> Result<()> {
/// #     let depth = 0;
/// #
/// if depth > MAX_DEPTH {
///     bail!(ScienceError::RecursionLimitExceeded);
/// }
/// #     Ok(())
/// # }
/// ```
#[macro_export]
macro_rules! bail {
    ($msg:literal $(,)?) => {
        return std::result::Result::Err($crate::anyhow!($msg));
    };
    ($err:expr $(,)?) => {
        return std::result::Result::Err($crate::anyhow!($err));
    };
    ($fmt:expr, $($arg:tt)*) => {
        return std::result::Result::Err($crate::anyhow!($fmt, $($arg)*));
    };
}

/// Return early with an error if a condition is not satisfied.
///
/// This macro is equivalent to `if !$cond { return Err(From::from($err)); }`.
///
/// Analogously to `assert!`, `ensure!` takes a condition and exits the function
/// if the condition fails. Unlike `assert!`, `ensure!` returns an `Error`
/// rather than panicking.
///
/// # Example
///
/// ```
/// # use anyhow::{ensure, Result};
/// #
/// # fn main() -> Result<()> {
/// #     let user = 0;
/// #
/// ensure!(user == 0, "only user 0 is allowed");
/// #     Ok(())
/// # }
/// ```
///
/// ```
/// # use anyhow::{ensure, Result};
/// # use std::fmt::{self, Display};
/// #
/// # #[derive(Debug)]
/// # enum ScienceError {
/// #     RecursionLimitExceeded,
/// # }
/// #
/// # impl std::error::Error for ScienceError {}
/// #
/// # impl Display for ScienceError {
/// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
/// #         unimplemented!()
/// #     }
/// # }
/// #
/// # const MAX_DEPTH: usize = 1;
/// #
/// # const IGNORE: &str = stringify! {
/// #[derive(Error, Debug)]
/// enum ScienceError {
///     #[error(display = "recursion limit exceeded")]
///     RecursionLimitExceeded,
///     ...
/// }
/// # };
///
/// # fn main() -> Result<()> {
/// #     let depth = 0;
/// #
/// ensure!(depth <= MAX_DEPTH, ScienceError::RecursionLimitExceeded);
/// #     Ok(())
/// # }
/// ```
#[macro_export]
macro_rules! ensure {
    ($cond:expr, $msg:literal $(,)?) => {
        if !$cond {
            return std::result::Result::Err($crate::anyhow!($msg));
        }
    };
    ($cond:expr, $err:expr $(,)?) => {
        if !$cond {
            return std::result::Result::Err($crate::anyhow!($err));
        }
    };
    ($cond:expr, $fmt:expr, $($arg:tt)*) => {
        if !$cond {
            return std::result::Result::Err($crate::anyhow!($fmt, $($arg)*));
        }
    };
}

/// Construct an ad-hoc error from a string.
///
/// This evaluates to an `Error`. It can take either just a string, or a format
/// string with arguments. It also can take any custom type which implements
/// `Debug` and `Display`.
///
/// # Example
///
/// ```
/// # type V = ();
/// #
/// use anyhow::{anyhow, Result};
///
/// fn lookup(key: &str) -> Result<V> {
///     if key.len() != 16 {
///         return Err(anyhow!("key length must be 16 characters, got {:?}", key));
///     }
///
///     // ...
///     # Ok(())
/// }
/// ```
#[macro_export]
macro_rules! anyhow {
    ($msg:literal $(,)?) => {
        // Handle $:literal as a special case to make cargo-expanded code more
        // concise in the common case.
        $crate::private::new_adhoc($msg)
    };
    ($err:expr $(,)?) => ({
        #[allow(unused_imports)]
        use $crate::private::{AdhocKind, TraitKind};
        let error = $err;
        (&error).anyhow_kind().new(error)
    });
    ($fmt:expr, $($arg:tt)*) => {
        $crate::private::new_adhoc(format!($fmt, $($arg)*))
    };
}

// Not public API.
#[doc(hidden)]
pub mod private {
    use crate::Error;
    use std::fmt::{Debug, Display};

    #[cfg(backtrace)]
    use std::backtrace::Backtrace;

    pub use crate::kind::{AdhocKind, TraitKind};

    pub fn new_adhoc<M>(message: M) -> Error
    where
        M: Display + Debug + Send + Sync + 'static,
    {
        Error::from_adhoc(message, backtrace!())
    }
}
<|endoftext|>


<commit_before>extern crate ladspa;
extern crate mio;

use std::default::Default;
use std::thread;
use std::sync::mpsc::{self, sync_channel};
use std::mem;
use std::io::Read;

use mio::*;
use mio::tcp::{TcpStream, TcpListener};

use ladspa::{Port, PortDescriptor, PortConnection};
use ladspa::{PluginDescriptor, Plugin};
use ladspa::{PROP_NONE};
use ladspa::{HINT_INTEGER};
use ladspa::{DefaultValue};
use ladspa::Data;

const BUFFER_SIZE: usize = 1024;
const BASE_PORT: u16 = 21300;

const SERVER: Token = Token(0);
const CLIENT: Token = Token(1);

struct Packet {
    position: usize,
    data: [Data; BUFFER_SIZE],
}

impl Packet {
    pub fn parse(bytes: [u8; BUFFER_SIZE*4]) -> Packet {
        Packet {
            position: 0,
            data: unsafe { mem::transmute(bytes) },
        }
    }

    pub fn read(&mut self) -> Data {
        if self.position >= BUFFER_SIZE {
            return 0_f32;
        }
        let data = self.data[self.position];
        self.position += 1;
        data
    }

    pub fn active(&self) -> bool {
        self.position < BUFFER_SIZE
    }
}

struct Transmitter {
    sample_rate: u64,
}

impl Transmitter {
    pub fn new(desc: &PluginDescriptor, sample_rate: u64) -> Box<Plugin + Send> {
        Box::new(Transmitter {
            sample_rate: sample_rate
        })
    }
}

impl Plugin for Transmitter {
    fn run<'a>(&mut self, sample_count: usize, ports: &[&'a PortConnection<'a>]) {
    }
}

struct Receiver {
    sample_rate: u64,
    channel: u16,
    packet_rx: Option<mpsc::Receiver<Packet>>,
    active_packets: Vec<Packet>,
    notify_tx: Option<Sender<<PacketReceiver as Handler>::Message>>,
}

impl Receiver {
    pub fn new(desc: &PluginDescriptor, sample_rate: u64) -> Box<Plugin + Send> {
        println!("receiver::new");
        Box::new(Receiver {
            sample_rate: sample_rate,
            channel: 0,
            packet_rx: None,
            active_packets: Vec::new(),
            notify_tx: None,
        })
    }

    fn init_server(&mut self) {
        let (data_tx, data_rx) = sync_channel(16);
        self.packet_rx = Some(data_rx);

        let channel = self.channel;
        let mut event_loop = EventLoop::new().unwrap();
        self.notify_tx = Some(event_loop.channel());
        thread::spawn(move || {
            let addr = format!("127.0.0.1:{}", BASE_PORT + channel).parse().unwrap();
            let server = TcpListener::bind(&addr).unwrap();
            event_loop.register(&server, SERVER).unwrap();
            event_loop.run(&mut PacketReceiver {
                server: server,
                data_tx: data_tx,
            }).unwrap();
        });
    }

    fn kill_server(&mut self) {
        self.notify_tx.as_ref().unwrap().send(()).unwrap();
    }
}

impl Plugin for Receiver {
    fn run<'a>(&mut self, sample_count: usize, ports: &[&'a PortConnection<'a>]) {
        let inputl = ports[0].unwrap_audio();
        let inputr = ports[1].unwrap_audio();
        let mut outputl = ports[2].unwrap_audio_mut();
        let mut outputr = ports[3].unwrap_audio_mut();

        let channel = *ports[4].unwrap_control() as u16;

        if channel != self.channel {
            self.channel = channel;
            self.kill_server();
            self.init_server();
        }

        let recv = match self.packet_rx.as_ref() {
            Some(rx) => rx,
            None => panic!("packet_rx is None!"),
        };

        loop {
            let packet = match recv.try_recv() {
                Ok(packet) => packet,
                Err(_) => break,
            };
            self.active_packets.push(packet);
            println!("have data!");
        }

        for i in 0..sample_count {
            outputl[i] = inputl[i];
            outputr[i] = inputr[i];
            for packet in self.active_packets.iter_mut() {
                let val = packet.read();
                outputl[i] += val;
                outputr[i] += val;
            }
        }

        self.active_packets.retain(|x| x.active());
    }

    fn activate(&mut self) {
        println!("activate {}", self.channel);
        self.init_server();
    }

    fn deactivate(&mut self) {
        println!("deactivate {}", self.channel);
        self.kill_server();
    }
}

struct PacketReceiver {
    server: TcpListener,
    data_tx: mpsc::SyncSender<Packet>,
}

impl Handler for PacketReceiver {
    type Timeout = ();
    type Message = ();

    fn ready(&mut self, event_loop: &mut mio::EventLoop<Self>, token: mio::Token, events: mio::EventSet) {
        match token {
            SERVER => {
                // Only receive readable events
                assert!(events.is_readable());

                println!("the server socket is ready to accept a connection");
                match self.server.accept() {
                    Ok(Some(mut socket)) => {
                        let tx = self.data_tx.clone();
                        loop {
                            let mut bytes = [0; BUFFER_SIZE*4];
                            let res = socket.read(&mut bytes);
                            match res {
                                Ok(size) => {
                                    if size == 0 {
                                        println!("zero buffer");
                                        return;
                                    }
                                }
                                Err(e) => {
                                    if let Some(11) = e.raw_os_error() {
                                        continue;
                                    }
                                    panic!(e);
                                }
                            }
                            let packet = Packet::parse(bytes);
                            tx.send(packet).unwrap();
                            println!("recv data!");
                        }
                    }
                    Ok(None) => {
                        println!("the server socket wasn't actually ready");
                    }
                    Err(e) => {
                        println!("listener.accept() errored: {}", e);
                        event_loop.shutdown();
                    }
                }
            }
            _ => panic!("Received unknown token"),
        }
    }
    fn notify(&mut self, event_loop: &mut EventLoop<Self>, msg: Self::Message) {
        event_loop.shutdown();
    }
}

#[no_mangle]
pub extern fn get_ladspa_descriptor(index: u64) -> Option<PluginDescriptor> {
    match index {
        0 => Some(PluginDescriptor {
            unique_id: 5877,
            label: "feedback_tx",
            properties: PROP_NONE,
            name: "Feedback Transmitter",
            maker: "Noah Weninger",
            copyright: "None",
            ports: vec![
                Port {
                    name: "Audio In",
                    desc: PortDescriptor::AudioInput,
                    ..Default::default()
                },
                Port {
                    name: "Audio Out",
                    desc: PortDescriptor::AudioOutput,
                    ..Default::default()
                },
                Port {
                    name: "Channel",
                    desc: PortDescriptor::ControlInput,
                    hint: Some(HINT_INTEGER),
                    default: Some(DefaultValue::Value0),
                    lower_bound: Some(0_f32),
                    upper_bound: Some(255_f32),
                }
            ],
            new: Transmitter::new,
        }),
        1 => Some(PluginDescriptor {
            unique_id: 5878,
            label: "feedback_rx",
            properties: PROP_NONE,
            name: "Feedback Receiver",
            maker: "Noah Weninger",
            copyright: "None",
            ports: vec![
                Port {
                    name: "Left Audio In",
                    desc: PortDescriptor::AudioInput,
                    ..Default::default()
                },
                Port {
                    name: "Right Audio In",
                    desc: PortDescriptor::AudioInput,
                    ..Default::default()
                },
                Port {
                    name: "Left Audio Out",
                    desc: PortDescriptor::AudioOutput,
                    ..Default::default()
                },
                Port {
                    name: "Right Audio Out",
                    desc: PortDescriptor::AudioOutput,
                    ..Default::default()
                },
                Port {
                    name: "Channel",
                    desc: PortDescriptor::ControlInput,
                    hint: Some(HINT_INTEGER),
                    default: Some(DefaultValue::Value0),
                    lower_bound: Some(0_f32),
                    upper_bound: Some(255_f32),
                }
            ],
            new: Receiver::new,
        }),
        _ => None
    }
}
<commit_msg>transmitter shell<commit_after>extern crate ladspa;
extern crate mio;

use std::default::Default;
use std::thread;
use std::sync::mpsc::{self, sync_channel};
use std::mem;
use std::io::Read;

use mio::*;
use mio::tcp::{TcpStream, TcpListener};

use ladspa::{Port, PortDescriptor, PortConnection};
use ladspa::{PluginDescriptor, Plugin};
use ladspa::{PROP_NONE};
use ladspa::{HINT_INTEGER};
use ladspa::{DefaultValue};
use ladspa::Data;

const BUFFER_SIZE: usize = 1024;
const BASE_PORT: u16 = 21300;

const SERVER: Token = Token(0);
const CLIENT: Token = Token(1);

struct Packet {
    position: usize,
    data: [Data; BUFFER_SIZE],
}

impl Packet {
    pub fn parse(bytes: [u8; BUFFER_SIZE*4]) -> Packet {
        Packet {
            position: 0,
            data: unsafe { mem::transmute(bytes) },
        }
    }

    pub fn read(&mut self) -> Data {
        if self.position >= BUFFER_SIZE {
            return 0_f32;
        }
        let data = self.data[self.position];
        self.position += 1;
        data
    }

    pub fn active(&self) -> bool {
        self.position < BUFFER_SIZE
    }
}

struct Transmitter {
    sample_rate: u64,
    channel: u16,
}

impl Transmitter {
    pub fn new(desc: &PluginDescriptor, sample_rate: u64) -> Box<Plugin + Send> {
        Box::new(Transmitter {
            sample_rate: sample_rate,
            channel: 0,
        })
    }

    fn init_client(&mut self) {
        //TODO
    }

    fn kill_client(&mut self) {
        //TODO
    }
}

impl Plugin for Transmitter {
    fn run<'a>(&mut self, sample_count: usize, ports: &[&'a PortConnection<'a>]) {
        let inputl = ports[0].unwrap_audio();
        let inputr = ports[1].unwrap_audio();
        let mut outputl = ports[2].unwrap_audio_mut();
        let mut outputr = ports[3].unwrap_audio_mut();

        let channel = *ports[4].unwrap_control() as u16;

        if channel != self.channel {
            println!("set channel {}", self.channel);
            self.channel = channel;
            self.kill_client();
            self.init_client();
        }

        //TODO
    }

    fn activate(&mut self) {
        println!("activate {}", self.channel);
        self.init_client();
    }

    fn deactivate(&mut self) {
        println!("deactivate {}", self.channel);
        self.kill_client();
    }
}

struct PacketTransmitter {
    socket: TcpStream,
    //TODO
}

struct Receiver {
    sample_rate: u64,
    channel: u16,
    packet_rx: Option<mpsc::Receiver<Packet>>,
    active_packets: Vec<Packet>,
    notify_tx: Option<Sender<<PacketReceiver as Handler>::Message>>,
}

impl Receiver {
    pub fn new(desc: &PluginDescriptor, sample_rate: u64) -> Box<Plugin + Send> {
        println!("receiver::new");
        Box::new(Receiver {
            sample_rate: sample_rate,
            channel: 0,
            packet_rx: None,
            active_packets: Vec::new(),
            notify_tx: None,
        })
    }

    fn init_server(&mut self) {
        let (data_tx, data_rx) = sync_channel(16);
        self.packet_rx = Some(data_rx);

        let channel = self.channel;
        let mut event_loop = EventLoop::new().unwrap();
        self.notify_tx = Some(event_loop.channel());
        thread::spawn(move || {
            let addr = format!("127.0.0.1:{}", BASE_PORT + channel).parse().unwrap();
            let server = TcpListener::bind(&addr).unwrap();
            event_loop.register(&server, SERVER).unwrap();
            event_loop.run(&mut PacketReceiver {
                server: server,
                data_tx: data_tx,
            }).unwrap();
        });
    }

    fn kill_server(&mut self) {
        self.notify_tx.as_ref().unwrap().send(()).unwrap();
    }
}

impl Plugin for Receiver {
    fn run<'a>(&mut self, sample_count: usize, ports: &[&'a PortConnection<'a>]) {
        let inputl = ports[0].unwrap_audio();
        let inputr = ports[1].unwrap_audio();
        let mut outputl = ports[2].unwrap_audio_mut();
        let mut outputr = ports[3].unwrap_audio_mut();

        let channel = *ports[4].unwrap_control() as u16;

        if channel != self.channel {
            println!("set channel {}", self.channel);
            self.channel = channel;
            self.kill_server();
            self.init_server();
        }

        let recv = match self.packet_rx.as_ref() {
            Some(rx) => rx,
            None => panic!("packet_rx is None!"),
        };

        loop {
            let packet = match recv.try_recv() {
                Ok(packet) => packet,
                Err(_) => break,
            };
            self.active_packets.push(packet);
            println!("have data!");
        }

        for i in 0..sample_count {
            outputl[i] = inputl[i];
            outputr[i] = inputr[i];
            for packet in self.active_packets.iter_mut() {
                let val = packet.read();
                outputl[i] += val;
                outputr[i] += val;
            }
        }

        self.active_packets.retain(|x| x.active());
    }

    fn activate(&mut self) {
        println!("activate {}", self.channel);
        self.init_server();
    }

    fn deactivate(&mut self) {
        println!("deactivate {}", self.channel);
        self.kill_server();
    }
}

struct PacketReceiver {
    server: TcpListener,
    data_tx: mpsc::SyncSender<Packet>,
}

impl Handler for PacketReceiver {
    type Timeout = ();
    type Message = ();

    fn ready(&mut self, event_loop: &mut mio::EventLoop<Self>, token: mio::Token, events: mio::EventSet) {
        match token {
            SERVER => {
                // Only receive readable events
                assert!(events.is_readable());

                println!("the server socket is ready to accept a connection");
                match self.server.accept() {
                    Ok(Some(mut socket)) => {
                        let tx = self.data_tx.clone();
                        loop {
                            let mut bytes = [0; BUFFER_SIZE*4];
                            let res = socket.read(&mut bytes);
                            match res {
                                Ok(size) => {
                                    if size == 0 {
                                        println!("zero buffer");
                                        return;
                                    }
                                }
                                Err(e) => {
                                    if let Some(11) = e.raw_os_error() {
                                        continue;
                                    }
                                    panic!(e);
                                }
                            }
                            let packet = Packet::parse(bytes);
                            tx.send(packet).unwrap();
                            println!("recv data!");
                        }
                    }
                    Ok(None) => {
                        println!("the server socket wasn't actually ready");
                    }
                    Err(e) => {
                        println!("listener.accept() errored: {}", e);
                        event_loop.shutdown();
                    }
                }
            },
            _ => panic!("Received unknown token"),
        }
    }
    fn notify(&mut self, event_loop: &mut EventLoop<Self>, msg: Self::Message) {
        event_loop.shutdown();
    }
}

#[no_mangle]
pub extern fn get_ladspa_descriptor(index: u64) -> Option<PluginDescriptor> {
    match index {
        0 => Some(PluginDescriptor {
            unique_id: 5877,
            label: "feedback_tx",
            properties: PROP_NONE,
            name: "Feedback Transmitter",
            maker: "Noah Weninger",
            copyright: "None",
            ports: vec![
                Port {
                    name: "Left Audio In",
                    desc: PortDescriptor::AudioInput,
                    ..Default::default()
                },
                Port {
                    name: "Right Audio In",
                    desc: PortDescriptor::AudioInput,
                    ..Default::default()
                },
                Port {
                    name: "Left Audio Out",
                    desc: PortDescriptor::AudioOutput,
                    ..Default::default()
                },
                Port {
                    name: "Right Audio Out",
                    desc: PortDescriptor::AudioOutput,
                    ..Default::default()
                },
                Port {
                    name: "Channel",
                    desc: PortDescriptor::ControlInput,
                    hint: Some(HINT_INTEGER),
                    default: Some(DefaultValue::Value0),
                    lower_bound: Some(0_f32),
                    upper_bound: Some(255_f32),
                }
            ],
            new: Transmitter::new,
        }),
        1 => Some(PluginDescriptor {
            unique_id: 5878,
            label: "feedback_rx",
            properties: PROP_NONE,
            name: "Feedback Receiver",
            maker: "Noah Weninger",
            copyright: "None",
            ports: vec![
                Port {
                    name: "Left Audio In",
                    desc: PortDescriptor::AudioInput,
                    ..Default::default()
                },
                Port {
                    name: "Right Audio In",
                    desc: PortDescriptor::AudioInput,
                    ..Default::default()
                },
                Port {
                    name: "Left Audio Out",
                    desc: PortDescriptor::AudioOutput,
                    ..Default::default()
                },
                Port {
                    name: "Right Audio Out",
                    desc: PortDescriptor::AudioOutput,
                    ..Default::default()
                },
                Port {
                    name: "Channel",
                    desc: PortDescriptor::ControlInput,
                    hint: Some(HINT_INTEGER),
                    default: Some(DefaultValue::Value0),
                    lower_bound: Some(0_f32),
                    upper_bound: Some(255_f32),
                }
            ],
            new: Receiver::new,
        }),
        _ => None
    }
}
<|endoftext|>


<commit_before>/*!

The afsort crate implements a sorting implementation based on
[American Flag sort](https://en.wikipedia.org/wiki/American_flag_sort). The implementation is
currently limited to sort byte slices, e.g. Strings. The main motivation is to sort strings of
text, so most of the benchmarks are based on English text strings. This implementation seems
to be about 40% faster than `sort_unstable` from the Rust standard library.

For small input, this method falls back to the standard library.

# Installation

Add the depndency to your `Cargo.toml`:

```ignore
[dependencies]
afsort = "0.1"
```
In your crate root:
```ignore
extern crate afsort;
```

# Usage

You can now use afsort to e.g. sort arrays of strings or string slices.

```rust
use afsort;
let mut strings = vec!("red", "green", "blue");
afsort::sort_unstable(&mut strings);
assert_eq!(strings, vec!["blue", "green", "red"]);
```

You can also sort by an extractor function, e.g.:

```rust
use afsort;
let mut tuples = vec![("b", 2), ("a", 1)];
afsort::sort_unstable_by(&mut tuples, |t| t.0.as_bytes());
assert_eq!(tuples, vec![("a", 1), ("b", 2)]);
```

# Motivation

Essentially, I noticed that sorting of strings took a long time when using the
[fst](https://github.com/BurntSushi/fst) crate, since it requires the input to be ordered.
Since sorting strings is a general problem, this is now a crate.

# Performance

As mentioned, this implementation seems to be about 40% faster than the sort in the standard
library, when sorting strings of random English words.  The implementation is fairly naive,
so I would not be surprised if it could be improved further.

You can run the benchmark tests using `cargo bench` (currently requires nightly rust), like this:

```ignore
% cargo bench
   Compiling afsort v0.1.0 (file:///home/anton/dev/off/afsort)
    Finished release [optimized] target(s) in 5.66 secs
     Running target/release/deps/afsort-ca28db3ba0643253

running 12 tests
test tests::sorts_strings_same_as_unstable ... ignored
test tests::sorts_tuples_same_as_unstable ... ignored
test tests::sort_100000_en_af        ... bench:  20,402,968 ns/iter (+/- 1,512,907)
test tests::sort_100000_en_std       ... bench:  30,132,067 ns/iter (+/- 1,698,223)
test tests::sort_10000_en_af         ... bench:   1,377,303 ns/iter (+/- 114,481)
test tests::sort_10000_en_lower_af   ... bench:   1,371,022 ns/iter (+/- 95,391)
test tests::sort_10000_en_lower_std  ... bench:   2,227,486 ns/iter (+/- 127,281)
test tests::sort_10000_en_sorted_af  ... bench:     878,665 ns/iter (+/- 545,256)
test tests::sort_10000_en_sorted_std ... bench:     618,329 ns/iter (+/- 536,338)
test tests::sort_10000_en_std        ... bench:   2,221,089 ns/iter (+/- 157,461)
test tests::sort_1000_en_af          ... bench:     101,625 ns/iter (+/- 6,946)
test tests::sort_1000_en_std         ... bench:     171,655 ns/iter (+/- 9,844)

test result: ok. 0 passed; 0 failed; 2 ignored; 10 measured; 0 filtered out

```
# Limitations

Currently, this crate only supports sorting elements of `AsRef<[u8]>`. I think that this is a
good first step, since it supports sorting of Strings. There is however no reason why American
Flag sorting should be limited to this data type. Any kind of element that can deliver a radix
to a certain digit/depth can be sorted using this technique.

The American Flag algorithm is unstable, in the same way that sort_unstable in the standard
library. That is, equal elements might be re-ordered.

This crate can _only_ sort strings based on their `utf-8` byte values. For many problems, this
is fine. However, if you want to sort strings for display to a user, Locale might matter. This
crate does not try to address this issue.

# Testing

Testing is done using the [quickcheck](https://github.com/BurntSushi/quickcheck) crate. We run
about 50k different variations of input strings. We make sure that the afsort implementation
sorts in the same way as the standard library's sort_unstable methods.

*/

#[cfg(test)]
extern crate quickcheck;

/// Enhances slices of e.g. Strings to have a `af_sort_unstable` method, as a more idiomatic
/// way to call sort.
///
/// #Example
///
/// ```rust
/// use afsort::AFSortable;
///
/// let mut strings = vec!["c", "a", "b"];
/// strings.af_sort_unstable();
/// assert_eq!(strings, vec!["a", "b", "c"]);
/// ```

pub trait AFSortable {
    fn af_sort_unstable(&mut self);
}

impl<T> AFSortable for [T]
where
    T: AsRef<[u8]>,
{
    fn af_sort_unstable(&mut self) {
        sort_unstable(self);
    }
}

/// Main sort method.
///
/// #Example
///
/// ```rust
/// let mut strings = vec!["c", "a", "b"];
/// afsort::sort_unstable(&mut strings);
/// assert_eq!(strings, vec!["a", "b", "c"]);
/// ```
pub fn sort_unstable<'a, T>(vec: &'a mut [T])
where
    T: AsRef<[u8]>,
{
    sort_unstable_by(vec, (|s| s.as_ref()));
}

/// Sort method which accepts function to convert elements to &[u8].
///
/// #Example
///
/// ```rust
/// let mut tuples = vec![("b", 2), ("a", 1)];
///afsort::sort_unstable_by(&mut tuples, |ref t| t.0.as_bytes());
///assert_eq!(tuples, vec![("a", 1), ("b", 2)]);
/// ```
pub fn sort_unstable_by<T, F>(vec: &mut [T], to_slice: F)
where
    F: Fn(&T) -> &[u8],
{
    sort_req(vec, &to_slice, 0);
}

fn sort_req<T, F>(vec: &mut [T], to_slice: &F, depth: usize)
where
    F: Fn(&T) -> &[u8],
{
    if vec.len() <= 32 {
        vec.sort_unstable_by(|e1, e2| to_slice(e1).cmp(to_slice(e2)));
        return;
    }
    let mut min = u16::max_value();
    let mut max = 0u16;
    for elem in vec.iter() {
        let val = to_slice(elem);
        if val.len() > depth {
            let radix_val = val[depth] as u16;
            if radix_val < min {
                min = radix_val;
            }
            if radix_val > max {
                max = radix_val;
            }
        }
    }
    if min == u16::max_value() {
        return;
    }

    let num_items = (max - min + 2) as usize;
    let mut counts: Vec<usize> = vec![0usize; num_items as usize];

    for elem in vec.iter() {
        let radix_val = radix_for_str(to_slice(elem), depth, min);
        counts[radix_val as usize] += 1;
    }

    let mut sum = 0usize;
    let mut offsets: Vec<usize> = vec![0usize; num_items as usize];
    for i in 0..num_items {
        offsets[i as usize] = sum;
        sum += counts[i as usize];
    }
    let mut next_free = offsets.clone();

    let mut block = 0usize;
    let mut i = 0usize;
    while block < num_items - 1 {
        if i >= offsets[block as usize + 1] as usize {
            block += 1;
        } else {
            let radix_val = radix_for_str(to_slice(&vec[i]), depth, min);
            if radix_val == block as u16 {
                i += 1;
            } else {
                vec.swap(i as usize, next_free[radix_val as usize] as usize);
                next_free[radix_val as usize] += 1;
            }
        }
    }
    for i in 0..num_items - 1 {
        sort_req(
            &mut vec[offsets[i as usize] as usize..offsets[i as usize + 1] as usize],
            to_slice,
            depth + 1,
        );
    }
    sort_req(&mut vec[offsets[num_items - 1]..], to_slice, depth + 1);
}

fn radix_for_str(s: &[u8], d: usize, base: u16) -> u16 {
    if s.len() > d {
        s[d] as u16 + 1 - base
    } else {
        0
    }
}
//}

#[cfg(test)]
mod tests {
    use super::AFSortable;
    use quickcheck::QuickCheck;

    #[test]
    fn sorts_strings_same_as_unstable() {
        fn compare_sort(mut strings: Vec<String>) -> bool {
            let mut copy = strings.clone();
            copy.sort_unstable();
            strings.af_sort_unstable();
            strings == copy
        }
        QuickCheck::new().tests(50000).quickcheck(
            compare_sort as
                fn(Vec<String>) -> bool,
        );
    }

    #[test]
    fn sorts_tuples_same_as_unstable() {
        fn compare_sort(mut tuples: Vec<(String, u8)>) -> bool {
            let mut copy = tuples.clone();
            copy.sort_unstable_by(|t1, t2| t1.0.cmp(&t2.0));
            super::sort_unstable_by(&mut tuples, |t| t.0.as_bytes());
            tuples.into_iter().map(|t| t.0).collect::<Vec<String>>() ==
                copy.into_iter().map(|t| t.0).collect::<Vec<String>>()
        }
        QuickCheck::new().tests(50000).quickcheck(
            compare_sort as
                fn(Vec<(String, u8)>)
                   -> bool,
        );
    }
}
<commit_msg>Fixed docs to compile.<commit_after>/*!

The afsort crate implements a sorting implementation based on
[American Flag sort](https://en.wikipedia.org/wiki/American_flag_sort). The implementation is
currently limited to sort byte slices, e.g. Strings. The main motivation is to sort strings of
text, so most of the benchmarks are based on English text strings. This implementation seems
to be about 40% faster than `sort_unstable` from the Rust standard library.

For small input, this method falls back to the standard library.

# Installation

Add the depndency to your `Cargo.toml`:

```ignore
[dependencies]
afsort = "0.1"
```
In your crate root:
```ignore
extern crate afsort;
```

# Usage

You can now use afsort to e.g. sort arrays of strings or string slices.

```rust
use afsort;
let mut strings = vec!("red", "green", "blue");
afsort::sort_unstable(&mut strings);
assert_eq!(strings, vec!["blue", "green", "red"]);
```

You can also sort by an extractor function, e.g.:

```rust
use afsort;
let mut tuples = vec![("b", 2), ("a", 1)];
afsort::sort_unstable_by(&mut tuples, |t: &(&str, _) | t.0.as_bytes());
assert_eq!(tuples, vec![("a", 1), ("b", 2)]);
```

# Motivation

Essentially, I noticed that sorting of strings took a long time when using the
[fst](https://github.com/BurntSushi/fst) crate, since it requires the input to be ordered.
Since sorting strings is a general problem, this is now a crate.

# Performance

As mentioned, this implementation seems to be about 40% faster than the sort in the standard
library, when sorting strings of random English words.  The implementation is fairly naive,
so I would not be surprised if it could be improved further.

You can run the benchmark tests using `cargo bench` (currently requires nightly rust), like this:

```ignore
% cargo bench
   Compiling afsort v0.1.0 (file:///home/anton/dev/off/afsort)
    Finished release [optimized] target(s) in 5.66 secs
     Running target/release/deps/afsort-ca28db3ba0643253

running 12 tests
test tests::sorts_strings_same_as_unstable ... ignored
test tests::sorts_tuples_same_as_unstable ... ignored
test tests::sort_100000_en_af        ... bench:  20,402,968 ns/iter (+/- 1,512,907)
test tests::sort_100000_en_std       ... bench:  30,132,067 ns/iter (+/- 1,698,223)
test tests::sort_10000_en_af         ... bench:   1,377,303 ns/iter (+/- 114,481)
test tests::sort_10000_en_lower_af   ... bench:   1,371,022 ns/iter (+/- 95,391)
test tests::sort_10000_en_lower_std  ... bench:   2,227,486 ns/iter (+/- 127,281)
test tests::sort_10000_en_sorted_af  ... bench:     878,665 ns/iter (+/- 545,256)
test tests::sort_10000_en_sorted_std ... bench:     618,329 ns/iter (+/- 536,338)
test tests::sort_10000_en_std        ... bench:   2,221,089 ns/iter (+/- 157,461)
test tests::sort_1000_en_af          ... bench:     101,625 ns/iter (+/- 6,946)
test tests::sort_1000_en_std         ... bench:     171,655 ns/iter (+/- 9,844)

test result: ok. 0 passed; 0 failed; 2 ignored; 10 measured; 0 filtered out

```
# Limitations

Currently, this crate only supports sorting elements of `AsRef<[u8]>`. I think that this is a
good first step, since it supports sorting of Strings. There is however no reason why American
Flag sorting should be limited to this data type. Any kind of element that can deliver a radix
to a certain digit/depth can be sorted using this technique.

The American Flag algorithm is unstable, in the same way that sort_unstable in the standard
library. That is, equal elements might be re-ordered.

This crate can _only_ sort strings based on their `utf-8` byte values. For many problems, this
is fine. However, if you want to sort strings for display to a user, Locale might matter. This
crate does not try to address this issue.

# Testing

Testing is done using the [quickcheck](https://github.com/BurntSushi/quickcheck) crate. We run
about 50k different variations of input strings. We make sure that the afsort implementation
sorts in the same way as the standard library's sort_unstable methods.

*/

#[cfg(test)]
extern crate quickcheck;

/// Enhances slices of e.g. Strings to have a `af_sort_unstable` method, as a more idiomatic
/// way to call sort.
///
/// #Example
///
/// ```rust
/// use afsort::AFSortable;
///
/// let mut strings = vec!["c", "a", "b"];
/// strings.af_sort_unstable();
/// assert_eq!(strings, vec!["a", "b", "c"]);
/// ```

pub trait AFSortable {
    #[inline]
    fn af_sort_unstable(&mut self);
}

impl<T> AFSortable for [T]
where
    T: AsRef<[u8]>,
{
    #[inline]
    fn af_sort_unstable(&mut self) {
        sort_unstable(self);
    }
}

/// Main sort method.
///
/// #Example
///
/// ```rust
/// let mut strings = vec!["c", "a", "b"];
/// afsort::sort_unstable(&mut strings);
/// assert_eq!(strings, vec!["a", "b", "c"]);
/// ```
#[inline]
pub fn sort_unstable<'a, T>(vec: &'a mut [T])
where
    T: AsRef<[u8]>,
{
    sort_unstable_by(vec, (|s| s.as_ref()));
}

/// Sort method which accepts function to convert elements to &[u8].
///
/// #Example
///
/// ```rust
/// let mut tuples = vec![("b", 2), ("a", 1)];
///afsort::sort_unstable_by(&mut tuples, |t: &(&str, _) | t.0.as_bytes());
///assert_eq!(tuples, vec![("a", 1), ("b", 2)]);
/// ```
///
/// Footnote: The explicit type annotacion in the closure seems to be needed (even though it should
/// not). See
/// [this discussion](https://users.rust-lang.org/t/lifetime-issue-with-str-in-closure/13137).
#[inline]
pub fn sort_unstable_by<T, F>(vec: &mut [T], to_slice: F)
where
    F: Fn(&T) -> &[u8],
{
    sort_req(vec, &to_slice, 0);
}

fn sort_req<T, F>(vec: &mut [T], to_slice: &F, depth: usize)
where
    F: Fn(&T) -> &[u8],
{
    if vec.len() <= 32 {
        vec.sort_unstable_by(|e1, e2| to_slice(e1).cmp(to_slice(e2)));
        return;
    }
    let mut min = u16::max_value();
    let mut max = 0u16;
    {
        //Find min/max to be able to allocate less memory
        for elem in vec.iter() {
            let val = to_slice(elem);
            if val.len() > depth {
                let radix_val = val[depth] as u16;
                if radix_val < min {
                    min = radix_val;
                }
                if radix_val > max {
                    max = radix_val;
                }
            }
        }
    }
    //No item had a value for this depth
    if min == u16::max_value() {
        return;
    }

    // +2 instead of +1 for special 0 bucket
    let num_items = (max - min + 2) as usize;
    let mut counts: Vec<usize> = vec![0usize; num_items as usize];
    {
        //Count occurences per value. Elements without a value gets
        //the special value 0, while others get the u8 value +1.
        for elem in vec.iter() {
            let radix_val = radix_for_str(to_slice(elem), depth, min);
            counts[radix_val as usize] += 1;
        }
    }

    let mut offsets: Vec<usize> = vec![0usize; num_items as usize];
    {
        //Sets the offsets for each count
        let mut sum = 0usize;
        for i in 0..counts.len() {
            offsets[i as usize] = sum;
            sum += counts[i as usize];
        }
    }

    {
        //Swap objects into the correct bucket, based on the offsets
        let mut next_free = offsets.clone();
        let mut block = 0usize;
        let mut i = 0usize;
        while block < counts.len() - 1 {
            if i >= offsets[block as usize + 1] as usize {
                block += 1;
            } else {
                let radix_val = radix_for_str(to_slice(&vec[i]), depth, min);
                if radix_val == block as u16 {
                    i += 1;
                } else {
                    vec.swap(i as usize, next_free[radix_val as usize] as usize);
                    next_free[radix_val as usize] += 1;
                }
            }
        }
    }
    {
        //Within each bucket, sort recursively
        for i in 0..offsets.len() - 1 {
            sort_req(
                &mut vec[offsets[i as usize] as usize..offsets[i as usize + 1] as usize],
                to_slice,
                depth + 1,
            );
        }
        sort_req(&mut vec[offsets[offsets.len() - 1]..], to_slice, depth + 1);
    }
}

fn radix_for_str(s: &[u8], d: usize, base: u16) -> u16 {
    if s.len() > d {
        s[d] as u16 + 1 - base
    } else {
        0
    }
}

#[cfg(test)]
mod tests {
    use super::AFSortable;
    use quickcheck::QuickCheck;

    #[test]
    fn sorts_strings_same_as_unstable() {
        fn compare_sort(mut strings: Vec<String>) -> bool {
            let mut copy = strings.clone();
            copy.sort_unstable();
            strings.af_sort_unstable();
            strings == copy
        }
        QuickCheck::new().tests(50000).quickcheck(
            compare_sort as
                fn(Vec<String>) -> bool,
        );
    }

    #[test]
    fn sorts_tuples_same_as_unstable() {
        fn compare_sort(mut tuples: Vec<(String, u8)>) -> bool {
            let mut copy = tuples.clone();
            copy.sort_unstable_by(|t1, t2| t1.0.cmp(&t2.0));
            super::sort_unstable_by(&mut tuples, |t| t.0.as_bytes());
            tuples.into_iter().map(|t| t.0).collect::<Vec<String>>() ==
                copy.into_iter().map(|t| t.0).collect::<Vec<String>>()
        }
        QuickCheck::new().tests(50000).quickcheck(
            compare_sort as
                fn(Vec<(String, u8)>)
                   -> bool,
        );
    }
}
<|endoftext|>


<commit_before>extern crate bincode;
extern crate rustc_serialize;

use bincode::SizeLimit;
use bincode::rustc_serialize::{encode, decode};
use rustc_serialize::{Encodable, Decodable};

use std::cmp::max;
use std::convert::From;
use std::error::Error;
use std::fs::File;
use std::fs::OpenOptions;
use std::io::{Read, Write, Seek, SeekFrom, ErrorKind};
use std::mem::{size_of};
use std::str;

const NUM_CHILDREN: usize = 32;
const FILE_HEADER: &'static str = "B+Tree\0";
const CURRENT_VERSION: u8 = 0x01;

// specify the types for the keys & values
pub trait KeyType: Ord + Encodable + Decodable {}
pub trait ValueType: Encodable + Decodable {}

// provide generic implementations
impl<T> KeyType for T where T: Ord + Encodable + Decodable {}
impl<T> ValueType for T where T: Encodable + Decodable {}

#[derive(RustcEncodable, RustcDecodable, PartialEq)]
enum Payload<K: KeyType, V: ValueType> {
        Value(V),
        Children([(K,u64); NUM_CHILDREN]),
    }

#[derive(RustcEncodable, RustcDecodable, PartialEq)]
struct Node<K: KeyType, V: ValueType> {
    key: K,
    parent: u64,
    payload: Payload<K,V>, // either children, or actual values
}

/// This struct represents an on-disk B+Tree. There are NUM_CHILDREN keys at each
/// level in the tree. The on-disk format is as follows where VV is the version
/// number:
/// |-------------------------------------------|
/// | 0x42 0x2b 0x54 0x72 | 0x65 0x65 0x00 0xVV |
/// | B    +    T    r    | e    e    \0   0xVV |
/// |-------------------------------------------|
/// | smallest record in bincode format         |
/// |-------------------------------------------|
/// | ...                                       |
/// |-------------------------------------------|
/// | largest record in bincode format          |
/// |-------------------------------------------|
/// | internal nodes ...                        |
/// |-------------------------------------------|
/// | root node                                 |
/// |-------------------------------------------|
pub struct BTree<K: KeyType, V: ValueType> {
    fd: File,                // the file backing the whole thing
    root: Option<Node<K,V>>, // optional in-memory copy of the root node
    key_size: usize,         // the size of the key in bytes
    value_size: usize,       // the size of the value in bytes
}

impl <K: KeyType, V: ValueType> BTree<K, V> {
    pub fn new(file_path: &str, key_size: usize, value_size: usize) -> Result<BTree<K,V>, Box<Error>> {
        let mut file = try!(OpenOptions::new()
                                  .read(true)
                                  .write(true)
                                  .create(true)
                                  .open(file_path));

        // check to see if this is a new file
        let metadata = try!(file.metadata());

        if metadata.len() == 0 {
            // write out our header
            try!(file.write(FILE_HEADER.as_bytes()));
            // write out our version
            try!(file.write(&[CURRENT_VERSION]));

            Ok(BTree{fd: file, key_size: key_size, value_size: value_size, root: None})
        } else {
            // make sure we've opened a proper file
            let mut version_string = Vec::with_capacity(8);

            try!(file.read_exact(&mut version_string));

            if try!(str::from_utf8(&version_string[0..FILE_HEADER.len()])) != FILE_HEADER ||
               version_string[FILE_HEADER.len()] != CURRENT_VERSION {
                return Err(From::from(std::io::Error::new(ErrorKind::InvalidData, "Invalid BTree file version")));
            }

            // total size of a Node
            let total_size = key_size + size_of::<u64>() + max(value_size, (key_size+size_of::<u64>()) * NUM_CHILDREN);
            let mut buff = Vec::with_capacity(total_size);

            // seek total_size in from the end of the file to read the root node
            try!(file.seek(SeekFrom::End(total_size as i64)));
            try!(file.read_exact(&mut buff));

            let root_node: Node<K,V> = try!(decode(&buff[..]));

            Ok(BTree{fd: file, key_size: key_size, value_size: value_size, root: Some(root_node)})
        }
    }
}

#[cfg(test)]
mod tests {
    use std::fs;
    use ::BTree;

    #[test]
    fn new_blank_file() {
        // make sure we remove any old files
        fs::remove_file("/tmp/btree_test.btr");

        BTree::<u8, u8>::new("/tmp/btree_test.btr", 1, 1).unwrap();
    }
}
<commit_msg>Added another unit test<commit_after>extern crate bincode;
extern crate rustc_serialize;

use bincode::SizeLimit;
use bincode::rustc_serialize::{encode, decode};
use rustc_serialize::{Encodable, Decodable};

use std::cmp::max;
use std::convert::From;
use std::error::Error;
use std::fs::File;
use std::fs::OpenOptions;
use std::io::{Read, Write, Seek, SeekFrom, ErrorKind};
use std::mem::{size_of};
use std::str;

const NUM_CHILDREN: usize = 32;
const FILE_HEADER: &'static str = "B+Tree\0";
const CURRENT_VERSION: u8 = 0x01;

// specify the types for the keys & values
pub trait KeyType: Ord + Encodable + Decodable {}
pub trait ValueType: Encodable + Decodable {}

// provide generic implementations
impl<T> KeyType for T where T: Ord + Encodable + Decodable {}
impl<T> ValueType for T where T: Encodable + Decodable {}

#[derive(RustcEncodable, RustcDecodable, PartialEq)]
enum Payload<K: KeyType, V: ValueType> {
        Value(V),
        Children([(K,u64); NUM_CHILDREN]),
    }

#[derive(RustcEncodable, RustcDecodable, PartialEq)]
struct Node<K: KeyType, V: ValueType> {
    key: K,
    parent: u64,
    payload: Payload<K,V>, // either children, or actual values
}

/// This struct represents an on-disk B+Tree. There are NUM_CHILDREN keys at each
/// level in the tree. The on-disk format is as follows where VV is the version
/// number:
/// |-------------------------------------------|
/// | 0x42 0x2b 0x54 0x72 | 0x65 0x65 0x00 0xVV |
/// | B    +    T    r    | e    e    \0   0xVV |
/// |-------------------------------------------|
/// | smallest record in bincode format         |
/// |-------------------------------------------|
/// | ...                                       |
/// |-------------------------------------------|
/// | largest record in bincode format          |
/// |-------------------------------------------|
/// | internal nodes ...                        |
/// |-------------------------------------------|
/// | root node                                 |
/// |-------------------------------------------|
pub struct BTree<K: KeyType, V: ValueType> {
    fd: File,                // the file backing the whole thing
    root: Option<Node<K,V>>, // optional in-memory copy of the root node
    key_size: usize,         // the size of the key in bytes
    value_size: usize,       // the size of the value in bytes
}

impl <K: KeyType, V: ValueType> BTree<K, V> {
    pub fn new(file_path: &str, key_size: usize, value_size: usize) -> Result<BTree<K,V>, Box<Error>> {
        let mut file = try!(OpenOptions::new()
                                  .read(true)
                                  .write(true)
                                  .create(true)
                                  .open(file_path));

        // check to see if this is a new file
        let metadata = try!(file.metadata());

        println!("FILE HAS LENGTH: {}", metadata.len());

        if metadata.len() == 0 {
            // write out our header
            try!(file.write(FILE_HEADER.as_bytes()));
            // write out our version
            try!(file.write(&[CURRENT_VERSION]));

            Ok(BTree{fd: file, key_size: key_size, value_size: value_size, root: None})
        } else {
            // make sure we've opened a proper file
            let mut version_string = [0; 8];

            try!(file.read_exact(&mut version_string));

            if try!(str::from_utf8(&version_string[0..FILE_HEADER.len()])) != FILE_HEADER ||
               version_string[FILE_HEADER.len()] != CURRENT_VERSION {
                return Err(From::from(std::io::Error::new(ErrorKind::InvalidData, "Invalid BTree file version")));
            }

            // total size of a Node
            let total_size = key_size + size_of::<u64>() + max(value_size, (key_size+size_of::<u64>()) * NUM_CHILDREN);
            let mut buff = Vec::with_capacity(total_size);

            // seek total_size in from the end of the file to read the root node
            try!(file.seek(SeekFrom::End(total_size as i64)));
            try!(file.read_exact(&mut buff));

            let root_node: Node<K,V> = try!(decode(&buff[..]));

            Ok(BTree{fd: file, key_size: key_size, value_size: value_size, root: Some(root_node)})
        }
    }
}

#[cfg(test)]
mod tests {
    use std::fs;
    use ::BTree;

    #[test]
    fn new_blank_file() {
        // make sure we remove any old files
        fs::remove_file("/tmp/btree_test.btr");

        BTree::<u8, u8>::new("/tmp/btree_test.btr", 1, 1).unwrap();
    }

    #[test]
    fn new_existing_file() {
        new_blank_file();  // assume this works

        let btree = BTree::<u8, u8>::new("/tmp/btree_test.btr", 1, 1).unwrap();
    }
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

use std::io;
use std::net::{Ipv4Addr, SocketAddrV4, UdpSocket};

//use Endianness::{Big, Little};

enum Endianness {
    Big,
    Little,
}

type Bit = bool;

struct Message {
    frame: Frame,
    frame_address: FrameAddress,
    protocol_header: ProtocolHeader,
    //payload: Payload,
}

// BitFrame is an intermediate representation.
struct BitFrame {
    // First 2 bytes
    size: u16,

    // Second two bytes
    origin: [Bit; 2],
    // For discovery using Device::GetService use true and target all zeroes.
    // For all other messages set to false and target to device MAC address.
    tagged: Bit,
    addressable: Bit,  // Must be true
    protocol: [Bit; 12],  // Must be 1024

    // Final 4 bytes
    source: u32,
}

impl<'a> From<&'a Frame> for BitFrame {
    fn from(f: &Frame) -> BitFrame {
        BitFrame {
            // First two bytes
            size: f.size,

            // Second two bytes
            origin: {
                // Format as zero padded boolean string.
                let s = format!("{:02b}", f.origin);
                // Convert boolean string to vec of 1s and 0s.
                let v: Vec<bool> = s.as_bytes().iter().map(|&n|
                    if n == 49 { true }
                    else { false }).collect();
                let a: [Bit; 2] = [v[0], v[1]];
                a
            },
            tagged: f.tagged,
            addressable: f.addressable,
            protocol: {
               // Format as zero padded boolean string.
                let s = format!("{:012b}", f.protocol);
                // Convert boolean string to vec of 1s and 0s.
                let v: Vec<bool> = s.as_bytes().iter().map(|&n|
                    if n == 49 { true }
                    else { false }).collect();
                let a: [Bit; 12] = [
                    v[0], v[1], v[2], v[3],  v[4],  v[5],  v[6],
                    v[7], v[8], v[9], v[10], v[11],
                ];
                a
            },

            // Final four bytes
            source: f.source,
        }
    }
}

impl<'a> From<&'a FrameAddress> for BitFrameAddress {
    fn from(f: &FrameAddress) -> BitFrameAddress {
        BitFrameAddress {
            target: f.target,
            reserved: f.reserved,
            reserved_2: {
                let s = format!("{:06b}", f.reserved_2);
                let v: Vec<bool> = s.as_bytes().iter().map(|&n|
                    if n == 49 { true }
                    else { false }).collect();
                let a: [Bit; 6] = [
                    v[0], v[1], v[2], v[3],  v[4],  v[5],
                ];
                a
            },
            ack_required: f.ack_required,
            res_required: f.res_required,
            sequence: f.sequence,
        }
    }
}

struct Frame {
    // First 2 bytes
    size: u16,

    // Second two bytes
    origin: u8,
    // For discovery using Device::GetService use true and target all zeroes.
    // For all other messages set to false and target to device MAC address.
    tagged: bool,
    addressable: bool,  // Must be true
    protocol: u16,  // Must be 1024

    // Final 4 bytes
    source: u32,
}

struct FrameAddress {
    // MAC address (6 bytes) left-justified with two 0 bytes, or all 0s for all devices
    target: [u8; 8],
    reserved: [u8; 6],
    reserved_2: u8,
    ack_required: bool,
    res_required: bool,
    sequence: u8,
}

struct BitFrameAddress {
    // MAC address (6 bytes) left-justified with two 0 bytes, or all 0s for all devices
    target: [u8; 8],
    reserved: [u8; 6],
    reserved_2: [Bit; 6],
    ack_required: Bit,
    res_required: Bit,
    sequence: u8,
}

struct ProtocolHeader {
    reserved: u64,
    message_type: u16,
    reserved_2: u16,
}

struct Payload {}

#[derive(Debug)]
struct Packet(Vec<u8>);

impl Packet {
    fn build(&mut self, msg: Message) {
        // First 2 bytes of Frame
        self.extend_with_u16(msg.frame.size);

        // Second 2 bytes of Frame
        let bitframe = BitFrame::from(&msg.frame);

        let mut fr_pt2: [Bit; 16] = [false; 16];
        fr_pt2[0] = bitframe.origin[0];
        fr_pt2[1] =    bitframe.origin[1];
        fr_pt2[2] =   bitframe.tagged;
        fr_pt2[3] =  bitframe.addressable;
        for i in 0..bitframe.protocol.len() {
            fr_pt2[i+4] = bitframe.protocol[i];
        }

        let (fr_pt2_a_bits, fr_pt2_b_bits) = fr_pt2.split_at(8);
        let fr_pt2_a = Packet::bits_to_byte(fr_pt2_a_bits);
        let fr_pt2_b = Packet::bits_to_byte(fr_pt2_b_bits);

        // Add these two bytes in little endian order.
        self.extend_with_u8(fr_pt2_b);
        self.extend_with_u8(fr_pt2_a);

        // Final 4 bytes of Frame
        self.extend_with_u32(msg.frame.source);

        // First, 8 bytes of FrameAddress
        self.extend_with_u8_array_8(msg.frame_address.target);

        // Second, 6 bytes of FrameAddress
        self.extend_with_u8_array_6(msg.frame_address.reserved);

        // Third, 1 byte of FrameAddress
        let bitframeaddress = BitFrameAddress::from(&msg.frame_address);

        let mut fa_pt2: [Bit; 8] = [false; 8];
        let rlen = bitframeaddress.reserved_2.len();
        for i in 0..rlen {
            fa_pt2[i] = bitframeaddress.reserved_2[i];
        }
        fa_pt2[rlen + 0] = bitframeaddress.ack_required;
        fa_pt2[rlen + 1] = bitframeaddress.res_required;

        let fa_pt2_byte = Packet::bits_to_byte(&fa_pt2);
        self.extend_with_u8(fa_pt2_byte);

        // Final byte of FrameAddress
        self.extend_with_u8(msg.frame_address.sequence);

        // First 8 bytes of ProtocolHeader
        self.extend_with_u64(msg.protocol_header.reserved);
        // Second, 2 bytes of ProtocolHeader
        self.extend_with_u16(msg.protocol_header.message_type);
        // Final 2 bytes of ProtocolHeader
        self.extend_with_u16(msg.protocol_header.reserved_2);

        // Set packet size in first 2 bytes of packet, Frame.
        let mut p = Packet::u16_to_u8_array(self.0.len() as u16);
        p.reverse();
        self.0[0] = p[0];
        self.0[1] = p[1];
    }

    fn bits_to_byte(bits: &[Bit]) -> u8 {
        bits.iter().fold(0, |acc, b| (acc << 1) + if *b { 1 } else { 0 } )
    }

    fn extend_with_bool(&mut self, field: bool) {
        // No need to reverse endianness, single byte.
        self.0.extend_from_slice(&Packet::bool_to_u8_array(field));
        self.pp();
    }

    fn extend_with_u8(&mut self, field: u8) {
        // No need to reverse endianness, single byte.
        self.0.extend_from_slice(&[field]);
        self.pp();
    }

    fn extend_with_u8_array_8(&mut self, mut field: [u8; 8]) {
        field.reverse();
        for b in field.iter() {
            self.0.extend_from_slice(&[*b]);
        }
        self.pp();
    }

    fn extend_with_u8_array_6(&mut self, mut field: [u8; 6]) {
        field.reverse();
        for b in field.iter() {
            self.0.extend_from_slice(&[*b]);
        }
        self.pp();
    }

    fn extend_with_u16(&mut self, field: u16) {
        let mut p = Packet::u16_to_u8_array(field);
        p.reverse();
        self.pp();
        self.0.extend_from_slice(&p);
        self.pp();
    }

    fn pp(&self) {
        return;
        // TODO: implement debug switch
        /*
        println!("Packet: ");
        for b in self.0.iter() {
            print!("{:x} ", b);
        }
        println!("");
        */
    }

    fn extend_with_u32(&mut self, field: u32) {
        let mut p = Packet::u32_to_u8_array(field);
        p.reverse();
        self.0.extend_from_slice(&p);
        self.pp();
    }

    fn extend_with_u64(&mut self, field: u64) {
        let mut p = Packet::u64_to_u8_array(field);
        p.reverse();
        self.0.extend_from_slice(&p);
        self.pp();
    }

    fn bool_to_u8_array(b: bool) -> [u8; 1] {
        match b {
            true => [1],
            false => [0],
        }
    }

    fn u16_to_u8_array(x: u16) -> [u8; 2] {
        let b1: u8 = ((x >> 8) & 0xff) as u8;
        let b2: u8 = (x & 0xff) as u8;
        [b1, b2]
    }

    fn u32_to_u8_array(x: u32) -> [u8; 4] {
        let b1: u8 = ((x >> 24) & 0xff) as u8;
        let b2: u8 = ((x >> 16) & 0xff) as u8;
        let b3: u8 = ((x >> 8) & 0xff) as u8;
        let b4: u8 = (x & 0xff) as u8;
        [b1, b2, b3, b4]
    }

    fn u64_to_u8_array(x: u64) -> [u8; 8] {
        let b1: u8 = ((x >> 56) & 0xff) as u8;
        let b2: u8 = ((x >> 48) & 0xff) as u8;
        let b3: u8 = ((x >> 40) & 0xff) as u8;
        let b4: u8 = ((x >> 32) & 0xff) as u8;
        let b5: u8 = ((x >> 24) & 0xff) as u8;
        let b6: u8 = ((x >> 16) & 0xff) as u8;
        let b7: u8 = ((x >> 8) & 0xff) as u8;
        let b8: u8 = (x & 0xff) as u8;
        [b1, b2, b3, b4, b5, b6, b7, b8]
    }
}

fn send(msg: Message) -> Result<(), io::Error> {
    let local_ip = Ipv4Addr::new(192, 168, 0, 2);
    //let local_ip = Ipv4Addr::new(127,0,0,1);
    let conn = SocketAddrV4::new(local_ip, 56700);
    let socket = try!(UdpSocket::bind(conn));

    let mut buf = [0; 100]; // for recv

    //let remote_ip = Ipv4Addr::new(127,0,0,1);
    let remote_ip = Ipv4Addr::new(192, 168, 0, 5);
    let remote_conn = SocketAddrV4::new(remote_ip, 56700);

    socket.set_broadcast(true)?;

    let mut packet: Packet = Packet(vec![0u8; 0]);
    packet.build(msg);

    let p = &packet.0;
    println!("Dec: {:?}", p);

    println!("---- Sending packet: ----");
        for b in p.iter() {
            print!("{:x} ", b);
        }
    println!("\n----");

    try!(socket.send_to(&p, remote_conn));

    // Read from the socket
    let (amt, src) = try!(socket.recv_from(&mut buf));

    println!("Received from {} : {:?}", src, &buf[0 .. amt]);

    Ok(())
}

fn all_le(v: Vec<u8>) -> Vec<u8> {
    // TODO: implement
    let mut le_vec: Vec<u8> = vec![];
    for b in v {
        le_vec.push(b.to_le());
    }
    le_vec
}

pub fn get_service() {
    let msg = Message {
        frame: Frame {
            size: 0,
            origin: 0,
            tagged: true,
            addressable: true,
            protocol: 1024,
            source: 321,
        },
        frame_address: FrameAddress {
            //target: [0x31, 0x19, 0x95, 0x4c, 0xb9, 0xbc, 0x00, 0x00],
            target: [0; 8],
            reserved: [0; 6],
            reserved_2: 0,
            ack_required: false,
            res_required: false,
            sequence: 156,
        },
        protocol_header: ProtocolHeader {
            reserved: 0,
            message_type: 2,
            reserved_2: 0,
        },
    };

    match send(msg) {
        Ok(()) => println!("good send"),
        Err(e) => println!("bad send: {}", e),
    };
}

fn get_device_state() {
    let _ = Message {
        frame: Frame {
            size: 0,
            origin: 0,
            tagged: false,
            addressable: true,
            protocol: 1024,
            source: 321,
        },
        frame_address: FrameAddress {
            target: [0; 8],
            reserved: [0; 6],
            reserved_2: 0,
            ack_required: false,
            res_required: false,
            sequence: 156,
        },
        protocol_header: ProtocolHeader {
            reserved: 0,
            message_type: 101,
            reserved_2: 0,
        },
    };
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<commit_msg>Introduce header struct.<commit_after>#![allow(dead_code)]

use std::io;
use std::net::{Ipv4Addr, SocketAddrV4, UdpSocket};

//use Endianness::{Big, Little};

enum Endianness {
    Big,
    Little,
}

type Bit = bool;

struct Message {
    header: Header,
    //payload: Payload,
}

struct Header {
    frame: Frame,
    frame_address: FrameAddress,
    protocol_header: ProtocolHeader,
}

// BitFrame is an intermediate representation.
struct BitFrame {
    // First 2 bytes
    size: u16,

    // Second two bytes
    origin: [Bit; 2],
    // For discovery using Device::GetService use true and target all zeroes.
    // For all other messages set to false and target to device MAC address.
    tagged: Bit,
    addressable: Bit,  // Must be true
    protocol: [Bit; 12],  // Must be 1024

    // Final 4 bytes
    source: u32,
}

impl<'a> From<&'a Frame> for BitFrame {
    fn from(f: &Frame) -> BitFrame {
        BitFrame {
            // First two bytes
            size: f.size,

            // Second two bytes
            origin: {
                // Format as zero padded boolean string.
                let s = format!("{:02b}", f.origin);
                // Convert boolean string to vec of 1s and 0s.
                let v: Vec<bool> = s.as_bytes().iter().map(|&n|
                    if n == 49 { true }
                    else { false }).collect();
                let a: [Bit; 2] = [v[0], v[1]];
                a
            },
            tagged: f.tagged,
            addressable: f.addressable,
            protocol: {
               // Format as zero padded boolean string.
                let s = format!("{:012b}", f.protocol);
                // Convert boolean string to vec of 1s and 0s.
                let v: Vec<bool> = s.as_bytes().iter().map(|&n|
                    if n == 49 { true }
                    else { false }).collect();
                let a: [Bit; 12] = [
                    v[0], v[1], v[2], v[3],  v[4],  v[5],  v[6],
                    v[7], v[8], v[9], v[10], v[11],
                ];
                a
            },

            // Final four bytes
            source: f.source,
        }
    }
}

impl<'a> From<&'a FrameAddress> for BitFrameAddress {
    fn from(f: &FrameAddress) -> BitFrameAddress {
        BitFrameAddress {
            target: f.target,
            reserved: f.reserved,
            reserved_2: {
                let s = format!("{:06b}", f.reserved_2);
                let v: Vec<bool> = s.as_bytes().iter().map(|&n|
                    if n == 49 { true }
                    else { false }).collect();
                let a: [Bit; 6] = [
                    v[0], v[1], v[2], v[3],  v[4],  v[5],
                ];
                a
            },
            ack_required: f.ack_required,
            res_required: f.res_required,
            sequence: f.sequence,
        }
    }
}

struct Frame {
    // First 2 bytes
    size: u16,

    // Second two bytes
    origin: u8,
    // For discovery using Device::GetService use true and target all zeroes.
    // For all other messages set to false and target to device MAC address.
    tagged: bool,
    addressable: bool,  // Must be true
    protocol: u16,  // Must be 1024

    // Final 4 bytes
    source: u32,
}

struct FrameAddress {
    // MAC address (6 bytes) left-justified with two 0 bytes, or all 0s for all devices
    target: [u8; 8],
    reserved: [u8; 6],
    reserved_2: u8,
    ack_required: bool,
    res_required: bool,
    sequence: u8,
}

struct BitFrameAddress {
    // MAC address (6 bytes) left-justified with two 0 bytes, or all 0s for all devices
    target: [u8; 8],
    reserved: [u8; 6],
    reserved_2: [Bit; 6],
    ack_required: Bit,
    res_required: Bit,
    sequence: u8,
}

struct ProtocolHeader {
    reserved: u64,
    message_type: u16,
    reserved_2: u16,
}

// TODO: This varies from message type to message type
struct Payload {}

#[derive(Debug)]
struct Packet(Vec<u8>);

//impl Packet {
impl Header {
    fn build(&mut self, msg: Message) {
        // First 2 bytes of Frame
        self.extend_with_u16(msg.header.frame.size);

        // Second 2 bytes of Frame
        let bitframe = BitFrame::from(&msg.header.frame);

        let mut fr_pt2: [Bit; 16] = [false; 16];
        fr_pt2[0] = bitframe.origin[0];
        fr_pt2[1] = bitframe.origin[1];
        fr_pt2[2] = bitframe.tagged;
        fr_pt2[3] = bitframe.addressable;
        for i in 0..bitframe.protocol.len() {
            fr_pt2[i+4] = bitframe.protocol[i];
        }

        let (fr_pt2_a_bits, fr_pt2_b_bits) = fr_pt2.split_at(8);
        let fr_pt2_a = Header::bits_to_byte(fr_pt2_a_bits);
        let fr_pt2_b = Header::bits_to_byte(fr_pt2_b_bits);

        // Add these two bytes in little endian order.
        self.extend_with_u8(fr_pt2_b);
        self.extend_with_u8(fr_pt2_a);

        // Final 4 bytes of Frame
        self.extend_with_u32(msg.header.frame.source);

        // First, 8 bytes of FrameAddress
        self.extend_with_u8_array_8(msg.header.frame_address.target);

        // Second, 6 bytes of FrameAddress
        self.extend_with_u8_array_6(msg.header.frame_address.reserved);

        // Third, 1 byte of FrameAddress
        let bitframeaddress = BitFrameAddress::from(&msg.header.frame_address);

        let mut fa_pt2: [Bit; 8] = [false; 8];
        let rlen = bitframeaddress.reserved_2.len();
        for i in 0..rlen {
            fa_pt2[i] = bitframeaddress.reserved_2[i];
        }
        fa_pt2[rlen + 0] = bitframeaddress.ack_required;
        fa_pt2[rlen + 1] = bitframeaddress.res_required;

        let fa_pt2_byte = Header::bits_to_byte(&fa_pt2);
        self.extend_with_u8(fa_pt2_byte);

        // Final byte of FrameAddress
        self.extend_with_u8(msg.header.frame_address.sequence);

        // First 8 bytes of ProtocolHeader
        self.extend_with_u64(msg.header.protocol_header.reserved);
        // Second, 2 bytes of ProtocolHeader
        self.extend_with_u16(msg.header.protocol_header.message_type);
        // Final 2 bytes of ProtocolHeader
        self.extend_with_u16(msg.header.protocol_header.reserved_2);

        // Set packet size in first 2 bytes of packet, Frame.
        let mut p = Header::u16_to_u8_array(self.len() as u16);
        //let mut p = Header::u16_to_u8_array(self.0.len() as u16);
        p.reverse();
        self.0[0] = p[0];
        self.0[1] = p[1];
    }

    fn bits_to_byte(bits: &[Bit]) -> u8 {
        bits.iter().fold(0, |acc, b| (acc << 1) + if *b { 1 } else { 0 } )
    }

    fn extend_with_bool(&mut self, field: bool) {
        // No need to reverse endianness, single byte.
        self.0.extend_from_slice(&Packet::bool_to_u8_array(field));
        self.pp();
    }

    fn extend_with_u8(&mut self, field: u8) {
        // No need to reverse endianness, single byte.
        self.0.extend_from_slice(&[field]);
        self.pp();
    }

    fn extend_with_u8_array_8(&mut self, mut field: [u8; 8]) {
        field.reverse();
        for b in field.iter() {
            self.0.extend_from_slice(&[*b]);
        }
        self.pp();
    }

    fn extend_with_u8_array_6(&mut self, mut field: [u8; 6]) {
        field.reverse();
        for b in field.iter() {
            self.0.extend_from_slice(&[*b]);
        }
        self.pp();
    }

    fn extend_with_u16(&mut self, field: u16) {
        let mut p = Packet::u16_to_u8_array(field);
        p.reverse();
        self.pp();
        self.0.extend_from_slice(&p);
        self.pp();
    }

    fn pp(&self) {
        return;
        // TODO: implement debug switch
        /*
        println!("Packet: ");
        for b in self.0.iter() {
            print!("{:x} ", b);
        }
        println!("");
        */
    }

    fn extend_with_u32(&mut self, field: u32) {
        let mut p = Packet::u32_to_u8_array(field);
        p.reverse();
        self.0.extend_from_slice(&p);
        self.pp();
    }

    fn extend_with_u64(&mut self, field: u64) {
        let mut p = Packet::u64_to_u8_array(field);
        p.reverse();
        self.0.extend_from_slice(&p);
        self.pp();
    }

    fn bool_to_u8_array(b: bool) -> [u8; 1] {
        match b {
            true => [1],
            false => [0],
        }
    }

    fn u16_to_u8_array(x: u16) -> [u8; 2] {
        let b1: u8 = ((x >> 8) & 0xff) as u8;
        let b2: u8 = (x & 0xff) as u8;
        [b1, b2]
    }

    fn u32_to_u8_array(x: u32) -> [u8; 4] {
        let b1: u8 = ((x >> 24) & 0xff) as u8;
        let b2: u8 = ((x >> 16) & 0xff) as u8;
        let b3: u8 = ((x >> 8) & 0xff) as u8;
        let b4: u8 = (x & 0xff) as u8;
        [b1, b2, b3, b4]
    }

    fn u64_to_u8_array(x: u64) -> [u8; 8] {
        let b1: u8 = ((x >> 56) & 0xff) as u8;
        let b2: u8 = ((x >> 48) & 0xff) as u8;
        let b3: u8 = ((x >> 40) & 0xff) as u8;
        let b4: u8 = ((x >> 32) & 0xff) as u8;
        let b5: u8 = ((x >> 24) & 0xff) as u8;
        let b6: u8 = ((x >> 16) & 0xff) as u8;
        let b7: u8 = ((x >> 8) & 0xff) as u8;
        let b8: u8 = (x & 0xff) as u8;
        [b1, b2, b3, b4, b5, b6, b7, b8]
    }
}

fn send(msg: Message) -> Result<(), io::Error> {
    let dev = true;
    let (local_ip, remote_ip) = match dev {
        true => (Ipv4Addr::new(127, 0, 0, 1), Ipv4Addr::new(127, 0, 0, 1)),
        false => (Ipv4Addr::new(192, 168, 0, 2), Ipv4Addr::new(192, 168, 0, 5)),
    };

    //let local_ip = Ipv4Addr::new(192, 168, 0, 2);
    //let local_ip = Ipv4Addr::new(127,0,0,1);
    let conn = SocketAddrV4::new(local_ip, 56700);
    let socket = try!(UdpSocket::bind(conn));

    let mut buf = [0; 100]; // for recv

    //let remote_ip = Ipv4Addr::new(127,0,0,1);
    //let remote_ip = Ipv4Addr::new(192, 168, 0, 5);
    let remote_conn = SocketAddrV4::new(remote_ip, 56700);

    socket.set_broadcast(true)?;

    //let mut packet: Packet = Packet(vec![0u8; 0]);
    let mut header: Header = Header::new();
    header.build(msg);
    let packet: Packet = Packet { Header: header };

    let p = &packet.0;
    println!("Dec: {:?}", p);

    println!("---- Sending packet: ----");
        for b in p.iter() {
            print!("{:x} ", b);
        }
    println!("\n----");

    try!(socket.send_to(&p, remote_conn));

    // Read from the socket
    let (amt, src) = try!(socket.recv_from(&mut buf));

    let resp_packet = &buf[0..amt];
    println!("Received from {} : {:?}", src, resp_packet);

    parse_response(resp_packet.to_vec());
    // let resp_obj = parse_response(resp);
    // display_response(resp_obj);

    Ok(())
}

fn parse_response(resp: Vec<u8>) {
    // let mut res = StateServiceMessage {
    //     Header:
    // };
    println!("Parse: {:?}", resp);
}

fn all_le(v: Vec<u8>) -> Vec<u8> {
    // TODO: implement
    let mut le_vec: Vec<u8> = vec![];
    for b in v {
        le_vec.push(b.to_le());
    }
    le_vec
}

pub fn get_service() {
    let msg = Message {
        frame: Frame {
            size: 0,
            origin: 0,
            tagged: true,
            addressable: true,
            protocol: 1024,
            source: 321,
        },
        frame_address: FrameAddress {
            //target: [0x31, 0x19, 0x95, 0x4c, 0xb9, 0xbc, 0x00, 0x00],
            target: [0; 8],
            reserved: [0; 6],
            reserved_2: 0,
            ack_required: false,
            res_required: false,
            sequence: 156,
        },
        protocol_header: ProtocolHeader {
            reserved: 0,
            message_type: 2,
            reserved_2: 0,
        },
    };

    match send(msg) {
        Ok(()) => println!("good send"),
        Err(e) => println!("bad send: {}", e),
    };
}

fn get_device_state() {
    let _ = Message {
        frame: Frame {
            size: 0,
            origin: 0,
            tagged: false,
            addressable: true,
            protocol: 1024,
            source: 321,
        },
        frame_address: FrameAddress {
            target: [0; 8],
            reserved: [0; 6],
            reserved_2: 0,
            ack_required: false,
            res_required: false,
            sequence: 156,
        },
        protocol_header: ProtocolHeader {
            reserved: 0,
            message_type: 101,
            reserved_2: 0,
        },
    };
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<|endoftext|>


<commit_before>//!
//! Rust wrapper around freetype 2 library
//!
//! # Initialization
//!
//! To create a new freetype context, instantiate the Library struct as below.
//! The Library (along with other objects) obeys RAII and is dropped when the struct goes out of
//! scope.
//!
//! # Example
//!
//! ```no_run
//! extern crate freetype;
//!
//! fn main() {
//!     use freetype::Library;
//!
//!     // Init the library
//!     let lib = Library::init().unwrap();
//!     // Load a font face
//!     let face = lib.new_face("/path/to/a/font/file.ttf", 0).unwrap();
//!     // Set the font size
//!     face.set_char_size(40 * 64, 0, 50, 0).unwrap();
//!     // Load a character
//!     face.load_char('A').unwrap();
//!     // Get the glyph instance
//!     let glyph = face.glyph();
//!     do_something_with_bitmap(glyph.bitmap().buffer());
//! }
//! ```
//!
//! See in the `examples/` folder for more examples.
//!
//! # External links
//! - See [freetype docs](http://www.freetype.org/freetype2/docs/reference/ft2-index.html)
//!   for more information

#![deny(missing_copy_implementations)]

#[macro_use]
extern crate bitflags;
extern crate libc;
pub extern crate freetype_sys;

pub use bitmap::Bitmap;
pub use bitmap_glyph::BitmapGlyph;
pub use error::{ FtResult, Error };
pub use face::Face;
pub use glyph::Glyph;
pub use glyph_slot::GlyphSlot;
pub use library::Library;
pub use outline::Outline;
pub use render_mode::RenderMode;
pub use freetype_sys as ffi;

pub mod bitmap;
pub mod bitmap_glyph;
pub mod error;
pub mod face;
pub mod glyph;
pub mod glyph_slot;
pub mod library;
pub mod outline;
pub mod render_mode;
pub mod tt_os2;

pub type BBox = ffi::FT_BBox;
pub type GlyphMetrics = ffi::FT_Glyph_Metrics;
pub type Matrix = ffi::FT_Matrix;
pub type Vector = ffi::FT_Vector;
<commit_msg>Use `ignore` not `no_run` for non-compiling code<commit_after>//!
//! Rust wrapper around freetype 2 library
//!
//! # Initialization
//!
//! To create a new freetype context, instantiate the Library struct as below.
//! The Library (along with other objects) obeys RAII and is dropped when the struct goes out of
//! scope.
//!
//! # Example
//!
//! ```ignore
//! extern crate freetype;
//!
//! fn main() {
//!     use freetype::Library;
//!
//!     // Init the library
//!     let lib = Library::init().unwrap();
//!     // Load a font face
//!     let face = lib.new_face("/path/to/a/font/file.ttf", 0).unwrap();
//!     // Set the font size
//!     face.set_char_size(40 * 64, 0, 50, 0).unwrap();
//!     // Load a character
//!     face.load_char('A').unwrap();
//!     // Get the glyph instance
//!     let glyph = face.glyph();
//!     do_something_with_bitmap(glyph.bitmap().buffer());
//! }
//! ```
//!
//! See in the `examples/` folder for more examples.
//!
//! # External links
//! - See [freetype docs](http://www.freetype.org/freetype2/docs/reference/ft2-index.html)
//!   for more information

#![deny(missing_copy_implementations)]

#[macro_use]
extern crate bitflags;
extern crate libc;
pub extern crate freetype_sys;

pub use bitmap::Bitmap;
pub use bitmap_glyph::BitmapGlyph;
pub use error::{ FtResult, Error };
pub use face::Face;
pub use glyph::Glyph;
pub use glyph_slot::GlyphSlot;
pub use library::Library;
pub use outline::Outline;
pub use render_mode::RenderMode;
pub use freetype_sys as ffi;

pub mod bitmap;
pub mod bitmap_glyph;
pub mod error;
pub mod face;
pub mod glyph;
pub mod glyph_slot;
pub mod library;
pub mod outline;
pub mod render_mode;
pub mod tt_os2;

pub type BBox = ffi::FT_BBox;
pub type GlyphMetrics = ffi::FT_Glyph_Metrics;
pub type Matrix = ffi::FT_Matrix;
pub type Vector = ffi::FT_Vector;
<|endoftext|>