<commit_before>//! The config module is used to change the behavior of bincode's encoding and decoding logic.
//!
//! *Important* make sure you use the same config for encoding and decoding, or else bincode will not work properly.
//!
//! To use a config, first create a type of [Configuration]. This type will implement trait [Config] for use with bincode.
//!
//! ```
//! use bincode::config::{Config, Configuration};
//! let config = Configuration::standard()
//!     // pick one of:
//!     .with_big_endian()
//!     .with_little_endian()
//!     // pick one of:
//!     .with_variable_int_encoding()
//!     .with_fixed_int_encoding()
//!     // pick one of:
//!     .skip_fixed_array_length()
//!     .write_fixed_array_length();
//! ```
//!
//! See [Config] for more information on the configuration options.

pub(crate) use self::internal::*;
use core::marker::PhantomData;

/// The Configuration struct is used to build bincode configurations. The [Config] trait is implemented
/// by this struct when a valid configuration has been constructed.
///
/// The following methods are mutually exclusive and will overwrite each other. The last call to one of these methods determines the behavior of the configuration:
///
/// - [with_little_endian] and [with_big_endian]
/// - [with_fixed_int_encoding] and [with_variable_int_encoding]
/// - [skip_fixed_array_length] and [write_fixed_array_length]
///
///
/// [with_little_endian]: #method.with_little_endian
/// [with_big_endian]: #method.with_big_endian
/// [with_fixed_int_encoding]: #method.with_fixed_int_encoding
/// [with_variable_int_encoding]: #method.with_variable_int_encoding
/// [skip_fixed_array_length]: #method.skip_fixed_array_length
/// [write_fixed_array_length]: #method.write_fixed_array_length
#[derive(Copy, Clone)]
pub struct Configuration<E = LittleEndian, I = Varint, A = SkipFixedArrayLength> {
    _e: PhantomData<E>,
    _i: PhantomData<I>,
    _a: PhantomData<A>,
}

impl Configuration {
    /// The default config for bincode 2.0. By default this will be:
    /// - Little endian
    /// - Variable int encoding
    /// - Skip fixed array length
    pub fn standard() -> Self {
        Self::generate()
    }

    /// Creates the "legacy" default config. This is the default config that was present in bincode 1.0
    /// - Little endian
    /// - Fixed int length encoding
    /// - Write array lengths
    pub fn legacy() -> Configuration<LittleEndian, Fixint, WriteFixedArrayLength> {
        Self::generate()
    }
}

impl<E, I, A> Configuration<E, I, A> {
    fn generate<_E, _I, _A>() -> Configuration<_E, _I, _A> {
        Configuration {
            _e: PhantomData,
            _i: PhantomData,
            _a: PhantomData,
        }
    }

    /// Makes bincode encode all integer types in big endian.
    pub fn with_big_endian(self) -> Configuration<BigEndian, I, A> {
        Self::generate()
    }

    /// Makes bincode encode all integer types in little endian.
    pub fn with_little_endian(self) -> Configuration<LittleEndian, I, A> {
        Self::generate()
    }

    /// Makes bincode encode all integer types with a variable integer encoding.
    ///
    /// Encoding an unsigned integer v (of any type excepting u8) works as follows:
    ///
    /// 1. If `u < 251`, encode it as a single byte with that value.
    /// 2. If `251 <= u < 2**16`, encode it as a literal byte 251, followed by a u16 with value `u`.
    /// 3. If `2**16 <= u < 2**32`, encode it as a literal byte 252, followed by a u32 with value `u`.
    /// 4. If `2**32 <= u < 2**64`, encode it as a literal byte 253, followed by a u64 with value `u`.
    /// 5. If `2**64 <= u < 2**128`, encode it as a literal byte 254, followed by a
    ///   u128 with value `u`.
    ///
    /// Then, for signed integers, we first convert to unsigned using the zigzag algorithm,
    /// and then encode them as we do for unsigned integers generally. The reason we use this
    /// algorithm is that it encodes those values which are close to zero in less bytes; the
    /// obvious algorithm, where we encode the cast values, gives a very large encoding for all
    /// negative values.
    ///
    /// The zigzag algorithm is defined as follows:
    ///
    /// ```ignore
    /// fn zigzag(v: Signed) -> Unsigned {
    ///     match v {
    ///         0 => 0,
    ///         v if v < 0 => |v| * 2 - 1
    ///         v if v > 0 => v * 2
    ///     }
    /// }
    /// ```
    ///
    /// And works such that:
    ///
    /// ```ignore
    /// assert_eq!(zigzag(0), 0);
    /// assert_eq!(zigzag(-1), 1);
    /// assert_eq!(zigzag(1), 2);
    /// assert_eq!(zigzag(-2), 3);
    /// assert_eq!(zigzag(2), 4);
    /// assert_eq!(zigzag(i64::min_value()), u64::max_value());
    /// ```
    ///
    /// Note that u256 and the like are unsupported by this format; if and when they are added to the
    /// language, they may be supported via the extension point given by the 255 byte.
    pub fn with_variable_int_encoding(self) -> Configuration<E, Varint, A> {
        Self::generate()
    }

    /// Fixed-size integer encoding.
    ///
    /// * Fixed size integers are encoded directly
    /// * Enum discriminants are encoded as u32
    /// * Lengths and usize are encoded as u64
    pub fn with_fixed_int_encoding(self) -> Configuration<E, Fixint, A> {
        Self::generate()
    }

    /// Skip writing the length of fixed size arrays (`[u8; N]`) before writing the array
    pub fn skip_fixed_array_length(self) -> Configuration<E, I, SkipFixedArrayLength> {
        Self::generate()
    }

    /// Write the length of fixed size arrays (`[u8; N]`) before writing the array
    pub fn write_fixed_array_length(self) -> Configuration<E, I, WriteFixedArrayLength> {
        Self::generate()
    }
}

/// Indicates a type is valid for controlling the bincode configuration
pub trait Config:
    InternalEndianConfig + InternalArrayLengthConfig + InternalIntEncodingConfig + Copy + Clone
{
}

impl<T> Config for T where
    T: InternalEndianConfig + InternalArrayLengthConfig + InternalIntEncodingConfig + Copy + Clone
{
}

#[doc(hidden)]
#[derive(Copy, Clone)]
pub struct BigEndian {}

impl InternalEndianConfig for BigEndian {
    const ENDIAN: Endian = Endian::Big;
}

#[doc(hidden)]
#[derive(Copy, Clone)]
pub struct LittleEndian {}

impl InternalEndianConfig for LittleEndian {
    const ENDIAN: Endian = Endian::Little;
}

#[doc(hidden)]
#[derive(Copy, Clone)]
pub struct Fixint {}

impl InternalIntEncodingConfig for Fixint {
    const INT_ENCODING: IntEncoding = IntEncoding::Fixed;
}

#[doc(hidden)]
#[derive(Copy, Clone)]
pub struct Varint {}

impl InternalIntEncodingConfig for Varint {
    const INT_ENCODING: IntEncoding = IntEncoding::Variable;
}

#[doc(hidden)]
#[derive(Copy, Clone)]
pub struct SkipFixedArrayLength {}

impl InternalArrayLengthConfig for SkipFixedArrayLength {
    const SKIP_FIXED_ARRAY_LENGTH: bool = true;
}

#[doc(hidden)]
#[derive(Copy, Clone)]
pub struct WriteFixedArrayLength {}

impl InternalArrayLengthConfig for WriteFixedArrayLength {
    const SKIP_FIXED_ARRAY_LENGTH: bool = false;
}

mod internal {
    use super::Configuration;

    pub trait InternalEndianConfig {
        const ENDIAN: Endian;
    }

    impl<E: InternalEndianConfig, I, A> InternalEndianConfig for Configuration<E, I, A> {
        const ENDIAN: Endian = E::ENDIAN;
    }

    #[derive(PartialEq, Eq)]
    pub enum Endian {
        Little,
        Big,
    }

    pub trait InternalIntEncodingConfig {
        const INT_ENCODING: IntEncoding;
    }

    impl<E, I: InternalIntEncodingConfig, A> InternalIntEncodingConfig for Configuration<E, I, A> {
        const INT_ENCODING: IntEncoding = I::INT_ENCODING;
    }

    #[derive(PartialEq, Eq)]
    pub enum IntEncoding {
        Fixed,
        Variable,
    }

    pub trait InternalArrayLengthConfig {
        const SKIP_FIXED_ARRAY_LENGTH: bool;
    }

    impl<E, I, A: InternalArrayLengthConfig> InternalArrayLengthConfig for Configuration<E, I, A> {
        const SKIP_FIXED_ARRAY_LENGTH: bool = A::SKIP_FIXED_ARRAY_LENGTH;
    }
}
<commit_msg>Made the zigzag encoding examples compile and run (#421)<commit_after>//! The config module is used to change the behavior of bincode's encoding and decoding logic.
//!
//! *Important* make sure you use the same config for encoding and decoding, or else bincode will not work properly.
//!
//! To use a config, first create a type of [Configuration]. This type will implement trait [Config] for use with bincode.
//!
//! ```
//! use bincode::config::{Config, Configuration};
//! let config = Configuration::standard()
//!     // pick one of:
//!     .with_big_endian()
//!     .with_little_endian()
//!     // pick one of:
//!     .with_variable_int_encoding()
//!     .with_fixed_int_encoding()
//!     // pick one of:
//!     .skip_fixed_array_length()
//!     .write_fixed_array_length();
//! ```
//!
//! See [Config] for more information on the configuration options.

pub(crate) use self::internal::*;
use core::marker::PhantomData;

/// The Configuration struct is used to build bincode configurations. The [Config] trait is implemented
/// by this struct when a valid configuration has been constructed.
///
/// The following methods are mutually exclusive and will overwrite each other. The last call to one of these methods determines the behavior of the configuration:
///
/// - [with_little_endian] and [with_big_endian]
/// - [with_fixed_int_encoding] and [with_variable_int_encoding]
/// - [skip_fixed_array_length] and [write_fixed_array_length]
///
///
/// [with_little_endian]: #method.with_little_endian
/// [with_big_endian]: #method.with_big_endian
/// [with_fixed_int_encoding]: #method.with_fixed_int_encoding
/// [with_variable_int_encoding]: #method.with_variable_int_encoding
/// [skip_fixed_array_length]: #method.skip_fixed_array_length
/// [write_fixed_array_length]: #method.write_fixed_array_length
#[derive(Copy, Clone)]
pub struct Configuration<E = LittleEndian, I = Varint, A = SkipFixedArrayLength> {
    _e: PhantomData<E>,
    _i: PhantomData<I>,
    _a: PhantomData<A>,
}

impl Configuration {
    /// The default config for bincode 2.0. By default this will be:
    /// - Little endian
    /// - Variable int encoding
    /// - Skip fixed array length
    pub fn standard() -> Self {
        Self::generate()
    }

    /// Creates the "legacy" default config. This is the default config that was present in bincode 1.0
    /// - Little endian
    /// - Fixed int length encoding
    /// - Write array lengths
    pub fn legacy() -> Configuration<LittleEndian, Fixint, WriteFixedArrayLength> {
        Self::generate()
    }
}

impl<E, I, A> Configuration<E, I, A> {
    fn generate<_E, _I, _A>() -> Configuration<_E, _I, _A> {
        Configuration {
            _e: PhantomData,
            _i: PhantomData,
            _a: PhantomData,
        }
    }

    /// Makes bincode encode all integer types in big endian.
    pub fn with_big_endian(self) -> Configuration<BigEndian, I, A> {
        Self::generate()
    }

    /// Makes bincode encode all integer types in little endian.
    pub fn with_little_endian(self) -> Configuration<LittleEndian, I, A> {
        Self::generate()
    }

    /// Makes bincode encode all integer types with a variable integer encoding.
    ///
    /// Encoding an unsigned integer v (of any type excepting u8) works as follows:
    ///
    /// 1. If `u < 251`, encode it as a single byte with that value.
    /// 2. If `251 <= u < 2**16`, encode it as a literal byte 251, followed by a u16 with value `u`.
    /// 3. If `2**16 <= u < 2**32`, encode it as a literal byte 252, followed by a u32 with value `u`.
    /// 4. If `2**32 <= u < 2**64`, encode it as a literal byte 253, followed by a u64 with value `u`.
    /// 5. If `2**64 <= u < 2**128`, encode it as a literal byte 254, followed by a
    ///   u128 with value `u`.
    ///
    /// Then, for signed integers, we first convert to unsigned using the zigzag algorithm,
    /// and then encode them as we do for unsigned integers generally. The reason we use this
    /// algorithm is that it encodes those values which are close to zero in less bytes; the
    /// obvious algorithm, where we encode the cast values, gives a very large encoding for all
    /// negative values.
    ///
    /// The zigzag algorithm is defined as follows:
    ///
    /// ```rust
    /// # type Signed = i32;
    /// # type Unsigned = u32;
    /// fn zigzag(v: Signed) -> Unsigned {
    ///     match v {
    ///         0 => 0,
    ///         // To avoid the edge case of Signed::min_value()
    ///         // !n is equal to `-n - 1`, so this is:
    ///         // !n * 2 + 1 = 2(-n - 1) + 1 = -2n - 2 + 1 = -2n - 1
    ///         v if v < 0 => !(v as Unsigned) * 2 - 1,
    ///         v if v > 0 => (v as Unsigned) * 2,
    /// #       _ => unreachable!()
    ///     }
    /// }
    /// ```
    ///
    /// And works such that:
    ///
    /// ```rust
    /// # let zigzag = |n: i64| -> u64 {
    /// #     match n {
    /// #         0 => 0,
    /// #         v if v < 0 => !(v as u64) * 2 + 1,
    /// #         v if v > 0 => (v as u64) * 2,
    /// #         _ => unreachable!(),
    /// #     }
    /// # };
    /// assert_eq!(zigzag(0), 0);
    /// assert_eq!(zigzag(-1), 1);
    /// assert_eq!(zigzag(1), 2);
    /// assert_eq!(zigzag(-2), 3);
    /// assert_eq!(zigzag(2), 4);
    /// // etc
    /// assert_eq!(zigzag(i64::min_value()), u64::max_value());
    /// ```
    ///
    /// Note that u256 and the like are unsupported by this format; if and when they are added to the
    /// language, they may be supported via the extension point given by the 255 byte.
    pub fn with_variable_int_encoding(self) -> Configuration<E, Varint, A> {
        Self::generate()
    }

    /// Fixed-size integer encoding.
    ///
    /// * Fixed size integers are encoded directly
    /// * Enum discriminants are encoded as u32
    /// * Lengths and usize are encoded as u64
    pub fn with_fixed_int_encoding(self) -> Configuration<E, Fixint, A> {
        Self::generate()
    }

    /// Skip writing the length of fixed size arrays (`[u8; N]`) before writing the array
    pub fn skip_fixed_array_length(self) -> Configuration<E, I, SkipFixedArrayLength> {
        Self::generate()
    }

    /// Write the length of fixed size arrays (`[u8; N]`) before writing the array
    pub fn write_fixed_array_length(self) -> Configuration<E, I, WriteFixedArrayLength> {
        Self::generate()
    }
}

/// Indicates a type is valid for controlling the bincode configuration
pub trait Config:
    InternalEndianConfig + InternalArrayLengthConfig + InternalIntEncodingConfig + Copy + Clone
{
}

impl<T> Config for T where
    T: InternalEndianConfig + InternalArrayLengthConfig + InternalIntEncodingConfig + Copy + Clone
{
}

#[doc(hidden)]
#[derive(Copy, Clone)]
pub struct BigEndian {}

impl InternalEndianConfig for BigEndian {
    const ENDIAN: Endian = Endian::Big;
}

#[doc(hidden)]
#[derive(Copy, Clone)]
pub struct LittleEndian {}

impl InternalEndianConfig for LittleEndian {
    const ENDIAN: Endian = Endian::Little;
}

#[doc(hidden)]
#[derive(Copy, Clone)]
pub struct Fixint {}

impl InternalIntEncodingConfig for Fixint {
    const INT_ENCODING: IntEncoding = IntEncoding::Fixed;
}

#[doc(hidden)]
#[derive(Copy, Clone)]
pub struct Varint {}

impl InternalIntEncodingConfig for Varint {
    const INT_ENCODING: IntEncoding = IntEncoding::Variable;
}

#[doc(hidden)]
#[derive(Copy, Clone)]
pub struct SkipFixedArrayLength {}

impl InternalArrayLengthConfig for SkipFixedArrayLength {
    const SKIP_FIXED_ARRAY_LENGTH: bool = true;
}

#[doc(hidden)]
#[derive(Copy, Clone)]
pub struct WriteFixedArrayLength {}

impl InternalArrayLengthConfig for WriteFixedArrayLength {
    const SKIP_FIXED_ARRAY_LENGTH: bool = false;
}

mod internal {
    use super::Configuration;

    pub trait InternalEndianConfig {
        const ENDIAN: Endian;
    }

    impl<E: InternalEndianConfig, I, A> InternalEndianConfig for Configuration<E, I, A> {
        const ENDIAN: Endian = E::ENDIAN;
    }

    #[derive(PartialEq, Eq)]
    pub enum Endian {
        Little,
        Big,
    }

    pub trait InternalIntEncodingConfig {
        const INT_ENCODING: IntEncoding;
    }

    impl<E, I: InternalIntEncodingConfig, A> InternalIntEncodingConfig for Configuration<E, I, A> {
        const INT_ENCODING: IntEncoding = I::INT_ENCODING;
    }

    #[derive(PartialEq, Eq)]
    pub enum IntEncoding {
        Fixed,
        Variable,
    }

    pub trait InternalArrayLengthConfig {
        const SKIP_FIXED_ARRAY_LENGTH: bool;
    }

    impl<E, I, A: InternalArrayLengthConfig> InternalArrayLengthConfig for Configuration<E, I, A> {
        const SKIP_FIXED_ARRAY_LENGTH: bool = A::SKIP_FIXED_ARRAY_LENGTH;
    }
}
<|endoftext|>


<commit_before>/*!
This module just contains any big string literals I don't want cluttering up the rest of the code.
*/

/**
The message output when the user invokes `cargo script` with no further arguments.  We need to do this ourselves because `clap` doesn't provide any way to generate this message manually.
*/
pub const NO_ARGS_MESSAGE: &'static str = "\
The following required arguments were not supplied:
\t'<script>'

USAGE:
\tcargo script [FLAGS OPTIONS] [--] <script> <args>...

For more information try --help";

/*
What follows are the templates used to wrap script input.  The input provided by the user is inserted in place of `%%`.  *Proper* templates of some kind would be nice, but damnit, I'm lazy.
*/

/// The template used for script file inputs.
pub const FILE_TEMPLATE: &'static str = r#"%%"#;

/// The template used for `--expr` input.
pub const EXPR_TEMPLATE: &'static str = r#"
fn main() {
    println!("{:?}",
{%%}
    );
}
"#;

/*
Regarding the loop templates: what I *want* is for the result of the closure to be printed to standard output *only* if it's not `()`.

* TODO: Just use TypeId, dumbass.
* TODO: Merge the `LOOP_*` templates so there isn't duplicated code.  It's icky.
*/

/// The template used for `--loop` input, assuming no `--count` flag is also given.
pub const LOOP_TEMPLATE: &'static str = r#"
use std::io::prelude::*;

fn main() {
    let mut closure = enforce_closure(
{%%}
    );
    let mut out_buffer: Vec<u8> = vec![];
    let mut line_buffer = String::new();
    let mut stdin = std::io::stdin();
    loop {
        line_buffer.clear();
        let read_res = stdin.read_line(&mut line_buffer).unwrap_or(0);
        if read_res == 0 { break }
        let output = closure(&line_buffer);

        out_buffer.clear();
        write!(&mut out_buffer, "{:?}", output).unwrap();
        let out_str = String::from_utf8_lossy(&out_buffer);
        if &*out_str != "()" {
            println!("{}", out_str);
        }
    }
}

fn enforce_closure<F, T>(closure: F) -> F
where F: FnMut(&str) -> T {
    closure
}
"#;

/// The template used for `--count --loop` input.
pub const LOOP_COUNT_TEMPLATE: &'static str = r#"
use std::io::prelude::*;

fn main() {
    let mut closure = enforce_closure(
{%%}
    );
    let mut out_buffer: Vec<u8> = vec![];
    let mut line_buffer = String::new();
    let mut stdin = std::io::stdin();
    let mut count = 0;
    loop {
        line_buffer.clear();
        let read_res = stdin.read_line(&mut line_buffer).unwrap_or(0);
        if read_res == 0 { break }
        count += 1;
        let output = closure(&line_buffer, count);

        out_buffer.clear();
        write!(&mut out_buffer, "{:?}", output).unwrap();
        let out_str = String::from_utf8_lossy(&out_buffer);
        if &*out_str != "()" {
            println!("{}", out_str);
        }
    }
}

fn enforce_closure<F, T>(closure: F) -> F
where F: FnMut(&str, usize) -> T {
    closure
}
"#;

/**
The default manifest used for packages.  `%n` is replaced with the "safe name" of the input, which *should* be safe to use as a file name.
*/
pub const DEFAULT_MANIFEST: &'static str = r#"
[package]
name = "%n"
version = "0.1.0"
authors = ["Anonymous"]

[[bin]]
name = "%n"
path = "%n.rs"
"#;

/**
The name of the package metadata file.
*/
pub const METADATA_FILE: &'static str = "metadata.json";

/**
Extensions to check when trying to find script input by name.
*/
pub const SEARCH_EXTS: &'static [&'static str] = &["crs", "rs"];

/*
These relate to Input::compute_id.
*/

/**
When generating a package's unique ID, how many hex nibbles of the compressed path should be used *at most*?
*/
pub const DEFLATE_PATH_LEN_MAX: usize = 20;

/**
When generating a package's unique ID, how many hex nibbles of the script digest should be used *at most*?
*/
pub const CONTENT_DIGEST_LEN_MAX: usize = 20;

/**
How old can stuff in the cache be before we automatically clear it out?

Measured in milliseconds.
*/
// It's been *one week* since you looked at me,
// cocked your head to the side and said "I'm angry."
pub const MAX_CACHE_AGE_MS: u64 = 1*7*24*60*60*1000;
<commit_msg>Changed the way `()` is detected for loops.<commit_after>/*!
This module just contains any big string literals I don't want cluttering up the rest of the code.
*/

/**
The message output when the user invokes `cargo script` with no further arguments.  We need to do this ourselves because `clap` doesn't provide any way to generate this message manually.
*/
pub const NO_ARGS_MESSAGE: &'static str = "\
The following required arguments were not supplied:
\t'<script>'

USAGE:
\tcargo script [FLAGS OPTIONS] [--] <script> <args>...

For more information try --help";

/*
What follows are the templates used to wrap script input.  The input provided by the user is inserted in place of `%%`.  *Proper* templates of some kind would be nice, but damnit, I'm lazy.
*/

/// The template used for script file inputs.
pub const FILE_TEMPLATE: &'static str = r#"%%"#;

/// The template used for `--expr` input.
pub const EXPR_TEMPLATE: &'static str = r#"
fn main() {
    println!("{:?}",
{%%}
    );
}
"#;

/*
Regarding the loop templates: what I *want* is for the result of the closure to be printed to standard output *only* if it's not `()`.

* TODO: Just use TypeId, dumbass.
* TODO: Merge the `LOOP_*` templates so there isn't duplicated code.  It's icky.
*/

/// The template used for `--loop` input, assuming no `--count` flag is also given.
pub const LOOP_TEMPLATE: &'static str = r#"
use std::any::Any;
use std::io::prelude::*;

fn main() {
    let mut closure = enforce_closure(
{%%}
    );
    let mut line_buffer = String::new();
    let mut stdin = std::io::stdin();
    loop {
        line_buffer.clear();
        let read_res = stdin.read_line(&mut line_buffer).unwrap_or(0);
        if read_res == 0 { break }
        let output = closure(&line_buffer);

        let display = {
            let output_any: &Any = &output;
            !output_any.is::<()>()
        };

        if display {
            println!("{:?}", output);
        }
    }
}

fn enforce_closure<F, T>(closure: F) -> F
where F: FnMut(&str) -> T, T: 'static {
    closure
}
"#;

/// The template used for `--count --loop` input.
pub const LOOP_COUNT_TEMPLATE: &'static str = r#"
use std::any::Any;
use std::io::prelude::*;

fn main() {
    let mut closure = enforce_closure(
{%%}
    );
    let mut line_buffer = String::new();
    let mut stdin = std::io::stdin();
    let mut count = 0;
    loop {
        line_buffer.clear();
        let read_res = stdin.read_line(&mut line_buffer).unwrap_or(0);
        if read_res == 0 { break }
        count += 1;
        let output = closure(&line_buffer, count);

        let display = {
            let output_any: &Any = &output;
            !output_any.is::<()>()
        };

        if display {
            println!("{:?}", output);
        }
    }
}

fn enforce_closure<F, T>(closure: F) -> F
where F: FnMut(&str, usize) -> T, T: 'static {
    closure
}
"#;

/**
The default manifest used for packages.  `%n` is replaced with the "safe name" of the input, which *should* be safe to use as a file name.
*/
pub const DEFAULT_MANIFEST: &'static str = r#"
[package]
name = "%n"
version = "0.1.0"
authors = ["Anonymous"]

[[bin]]
name = "%n"
path = "%n.rs"
"#;

/**
The name of the package metadata file.
*/
pub const METADATA_FILE: &'static str = "metadata.json";

/**
Extensions to check when trying to find script input by name.
*/
pub const SEARCH_EXTS: &'static [&'static str] = &["crs", "rs"];

/*
These relate to Input::compute_id.
*/

/**
When generating a package's unique ID, how many hex nibbles of the compressed path should be used *at most*?
*/
pub const DEFLATE_PATH_LEN_MAX: usize = 20;

/**
When generating a package's unique ID, how many hex nibbles of the script digest should be used *at most*?
*/
pub const CONTENT_DIGEST_LEN_MAX: usize = 20;

/**
How old can stuff in the cache be before we automatically clear it out?

Measured in milliseconds.
*/
// It's been *one week* since you looked at me,
// cocked your head to the side and said "I'm angry."
pub const MAX_CACHE_AGE_MS: u64 = 1*7*24*60*60*1000;
<|endoftext|>


<commit_before>//! This module contains traits that are usable with the `#[derive(...)].`
//! macros in [`clap_derive`].

use crate::{App, ArgMatches, Error};

use std::ffi::OsString;

/// The primary one-stop-shop trait used to create an instance of a `clap`
/// [`App`], conduct the parsing, and turn the resulting [`ArgMatches`] back
/// into concrete instance of the user struct.
///
/// This trait is primarily a convenience on top of [`FromArgMatches`] +
/// [`IntoApp`] which uses those two underlying traits to build the two
/// fundamental functions `parse` which uses the `std::env::args_os` iterator,
/// and `parse_from` which allows the consumer to supply the iterator (along
/// with fallible options for each).
///
/// # Examples
///
/// The following example creates a `Context` struct that would be used
/// throughout the application representing the normalized values coming from
/// the CLI.
///
/// ```rust
/// # use clap::{Clap};
/// /// My super CLI
/// #[derive(Clap)]
/// #[clap(name = "demo")]
/// struct Context {
///     /// More verbose output
///     #[clap(long)]
///     verbose: bool,
///     /// An optional name
///     #[clap(short, long)]
///     name: Option<String>,
/// }
/// ```
///
/// The equivalent [`App`] struct + `From` implementation:
///
/// ```rust
/// # use clap::{App, Arg, ArgMatches};
/// App::new("demo")
///     .about("My super CLI")
///     .arg(Arg::new("verbose")
///         .long("verbose")
///         .about("More verbose output"))
///     .arg(Arg::new("name")
///         .long("name")
///         .long("n")
///         .about("An optional name")
///         .takes_value(true));
///
/// struct Context {
///     verbose: bool,
///     name: Option<String>,
/// }
///
/// impl From<ArgMatches> for Context {
///     fn from(m: ArgMatches) -> Self {
///         Context {
///             verbose: m.is_present("verbose"),
///             name: m.value_of("name").map(|n| n.to_owned()),
///         }
///     }
/// }
/// ```
///
/// [`App`]: ./struct.App.html
/// [`ArgMatches`]: ./struct.ArgMatches.html
/// [`FromArgMatches`]: ./trait.FromArgMatches.html
/// [`IntoApp`]: ./trait.IntoApp.html
pub trait Clap: FromArgMatches + IntoApp + Sized {
    /// Parse from `std::env::args_os()`, exit on error
    fn parse() -> Self {
        let matches = <Self as IntoApp>::into_app().get_matches();
        <Self as FromArgMatches>::from_arg_matches(&matches)
    }

    /// Parse from `std::env::args_os()`, return Err on error.
    fn try_parse() -> Result<Self, Error> {
        let matches = <Self as IntoApp>::into_app().try_get_matches()?;
        Ok(<Self as FromArgMatches>::from_arg_matches(&matches))
    }

    /// Parse from iterator, exit on error
    fn parse_from<I, T>(itr: I) -> Self
    where
        I: IntoIterator<Item = T>,
        // TODO (@CreepySkeleton): discover a way to avoid cloning here
        T: Into<OsString> + Clone,
    {
        let matches = <Self as IntoApp>::into_app().get_matches_from(itr);
        <Self as FromArgMatches>::from_arg_matches(&matches)
    }

    /// Parse from iterator, return Err on error.
    fn try_parse_from<I, T>(itr: I) -> Result<Self, Error>
    where
        I: IntoIterator<Item = T>,
        // TODO (@CreepySkeleton): discover a way to avoid cloning here
        T: Into<OsString> + Clone,
    {
        let matches = <Self as IntoApp>::into_app().try_get_matches_from(itr)?;
        Ok(<Self as FromArgMatches>::from_arg_matches(&matches))
    }

    /// Update from iterator, exit on error
    fn update_from<I, T>(&mut self, itr: I)
    where
        I: IntoIterator<Item = T>,
        // TODO (@CreepySkeleton): discover a way to avoid cloning here
        T: Into<OsString> + Clone,
    {
        // TODO find a way to get partial matches
        let matches = <Self as IntoApp>::into_app_for_update().get_matches_from(itr);
        <Self as FromArgMatches>::update_from_arg_matches(self, &matches);
    }

    /// Update from iterator, return Err on error.
    fn try_update_from<I, T>(&mut self, itr: I) -> Result<(), Error>
    where
        I: IntoIterator<Item = T>,
        // TODO (@CreepySkeleton): discover a way to avoid cloning here
        T: Into<OsString> + Clone,
    {
        let matches = <Self as IntoApp>::into_app_for_update().try_get_matches_from(itr)?;
        <Self as FromArgMatches>::update_from_arg_matches(self, &matches);
        Ok(())
    }
}

/// Build an App according to the struct
///
/// Also serves for flattening
pub trait IntoApp: Sized {
    /// @TODO @release @docs
    fn into_app<'help>() -> App<'help>;
    /// @TODO @release @docs
    fn augment_clap(app: App<'_>) -> App<'_>;
    /// @TODO @release @docs
    fn into_app_for_update<'help>() -> App<'help>;
    /// @TODO @release @docs
    fn augment_clap_for_update(app: App<'_>) -> App<'_>;
}

/// Converts an instance of [`ArgMatches`] to a consumer defined struct.
///
/// [`ArgMatches`]: ./struct.ArgMatches.html
pub trait FromArgMatches: Sized {
    /// It's common to have an "application context" struct (sometimes called
    /// config) that represents all the normalized values after being processed by
    /// the CLI.
    ///
    /// For instance, if an application we made had two CLI options, `--name
    /// <STRING>` and a flag `--debug` to distinguish "debugging mode" for our made
    /// up CLI, we may create a context struct as follows:
    ///
    /// ```no_run
    /// struct Context {
    ///     name: String,
    ///     debug: bool
    /// }
    /// ```
    ///
    /// And after letting `clap` parse the CLI, we get back and instance of
    /// `ArgMatches`, we may create a `From` implementation like so:
    ///
    /// ```no_run
    /// # use clap::ArgMatches;
    /// # struct Context {
    /// #   name: String,
    /// #   debug: bool
    /// # }
    /// impl From<ArgMatches> for Context {
    ///    fn from(m: ArgMatches) -> Self {
    ///        Context {
    ///            name: m.value_of("name").unwrap().to_string(),
    ///            debug: m.is_present("debug"),
    ///        }
    ///    }
    /// }
    /// ```
    fn from_arg_matches(matches: &ArgMatches) -> Self;

    /// @TODO@ @release @docs
    fn update_from_arg_matches(&mut self, matches: &ArgMatches);
}

/// @TODO @release @docs
pub trait Subcommand: Sized {
    /// @TODO @release @docs
    fn from_subcommand(subcommand: Option<(&str, &ArgMatches)>) -> Option<Self>;
    /// @TODO @release @docs
    fn update_from_subcommand(&mut self, subcommand: Option<(&str, &ArgMatches)>);
    /// @TODO @release @docs
    fn augment_subcommands(app: App<'_>) -> App<'_>;
    /// @TODO @release @docs
    fn augment_subcommands_for_update(app: App<'_>) -> App<'_>;
}

/// @TODO @release @docs
pub trait ArgEnum: Sized {
    /// @TODO @release @docs
    const VARIANTS: &'static [&'static str];

    /// @TODO @release @docs
    fn from_str(input: &str, case_insensitive: bool) -> Result<Self, String>;
}

impl<T: Clap> Clap for Box<T> {
    fn parse() -> Self {
        Box::new(<T as Clap>::parse())
    }

    fn try_parse() -> Result<Self, Error> {
        <T as Clap>::try_parse().map(Box::new)
    }

    fn parse_from<I, It>(itr: I) -> Self
    where
        I: IntoIterator<Item = It>,
        // TODO (@CreepySkeleton): discover a way to avoid cloning here
        It: Into<OsString> + Clone,
    {
        Box::new(<T as Clap>::parse_from(itr))
    }

    fn try_parse_from<I, It>(itr: I) -> Result<Self, Error>
    where
        I: IntoIterator<Item = It>,
        // TODO (@CreepySkeleton): discover a way to avoid cloning here
        It: Into<OsString> + Clone,
    {
        <T as Clap>::try_parse_from(itr).map(Box::new)
    }
}

impl<T: IntoApp> IntoApp for Box<T> {
    fn into_app<'help>() -> App<'help> {
        <T as IntoApp>::into_app()
    }
    fn augment_clap(app: App<'_>) -> App<'_> {
        <T as IntoApp>::augment_clap(app)
    }
    fn into_app_for_update<'help>() -> App<'help> {
        <T as IntoApp>::into_app_for_update()
    }
    fn augment_clap_for_update(app: App<'_>) -> App<'_> {
        <T as IntoApp>::augment_clap_for_update(app)
    }
}

impl<T: FromArgMatches> FromArgMatches for Box<T> {
    fn from_arg_matches(matches: &ArgMatches) -> Self {
        Box::new(<T as FromArgMatches>::from_arg_matches(matches))
    }
    fn update_from_arg_matches(&mut self, matches: &ArgMatches) {
        <T as FromArgMatches>::update_from_arg_matches(self, matches);
    }
}

impl<T: Subcommand> Subcommand for Box<T> {
    fn from_subcommand(subcommand: Option<(&str, &ArgMatches)>) -> Option<Self> {
        <T as Subcommand>::from_subcommand(subcommand).map(Box::new)
    }
    fn update_from_subcommand(&mut self, subcommand: Option<(&str, &ArgMatches)>) {
        <T as Subcommand>::update_from_subcommand(self, subcommand);
    }
    fn augment_subcommands(app: App<'_>) -> App<'_> {
        <T as Subcommand>::augment_subcommands(app)
    }
    fn augment_subcommands_for_update(app: App<'_>) -> App<'_> {
        <T as Subcommand>::augment_subcommands_for_update(app)
    }
}
<commit_msg>Fix a typo in the Clap trait docs (#2243)<commit_after>//! This module contains traits that are usable with the `#[derive(...)].`
//! macros in [`clap_derive`].

use crate::{App, ArgMatches, Error};

use std::ffi::OsString;

/// The primary one-stop-shop trait used to create an instance of a `clap`
/// [`App`], conduct the parsing, and turn the resulting [`ArgMatches`] back
/// into concrete instance of the user struct.
///
/// This trait is primarily a convenience on top of [`FromArgMatches`] +
/// [`IntoApp`] which uses those two underlying traits to build the two
/// fundamental functions `parse` which uses the `std::env::args_os` iterator,
/// and `parse_from` which allows the consumer to supply the iterator (along
/// with fallible options for each).
///
/// # Examples
///
/// The following example creates a `Context` struct that would be used
/// throughout the application representing the normalized values coming from
/// the CLI.
///
/// ```rust
/// # use clap::{Clap};
/// /// My super CLI
/// #[derive(Clap)]
/// #[clap(name = "demo")]
/// struct Context {
///     /// More verbose output
///     #[clap(long)]
///     verbose: bool,
///     /// An optional name
///     #[clap(short, long)]
///     name: Option<String>,
/// }
/// ```
///
/// The equivalent [`App`] struct + `From` implementation:
///
/// ```rust
/// # use clap::{App, Arg, ArgMatches};
/// App::new("demo")
///     .about("My super CLI")
///     .arg(Arg::new("verbose")
///         .long("verbose")
///         .about("More verbose output"))
///     .arg(Arg::new("name")
///         .long("name")
///         .short('n')
///         .about("An optional name")
///         .takes_value(true));
///
/// struct Context {
///     verbose: bool,
///     name: Option<String>,
/// }
///
/// impl From<ArgMatches> for Context {
///     fn from(m: ArgMatches) -> Self {
///         Context {
///             verbose: m.is_present("verbose"),
///             name: m.value_of("name").map(|n| n.to_owned()),
///         }
///     }
/// }
/// ```
///
/// [`App`]: ./struct.App.html
/// [`ArgMatches`]: ./struct.ArgMatches.html
/// [`FromArgMatches`]: ./trait.FromArgMatches.html
/// [`IntoApp`]: ./trait.IntoApp.html
pub trait Clap: FromArgMatches + IntoApp + Sized {
    /// Parse from `std::env::args_os()`, exit on error
    fn parse() -> Self {
        let matches = <Self as IntoApp>::into_app().get_matches();
        <Self as FromArgMatches>::from_arg_matches(&matches)
    }

    /// Parse from `std::env::args_os()`, return Err on error.
    fn try_parse() -> Result<Self, Error> {
        let matches = <Self as IntoApp>::into_app().try_get_matches()?;
        Ok(<Self as FromArgMatches>::from_arg_matches(&matches))
    }

    /// Parse from iterator, exit on error
    fn parse_from<I, T>(itr: I) -> Self
    where
        I: IntoIterator<Item = T>,
        // TODO (@CreepySkeleton): discover a way to avoid cloning here
        T: Into<OsString> + Clone,
    {
        let matches = <Self as IntoApp>::into_app().get_matches_from(itr);
        <Self as FromArgMatches>::from_arg_matches(&matches)
    }

    /// Parse from iterator, return Err on error.
    fn try_parse_from<I, T>(itr: I) -> Result<Self, Error>
    where
        I: IntoIterator<Item = T>,
        // TODO (@CreepySkeleton): discover a way to avoid cloning here
        T: Into<OsString> + Clone,
    {
        let matches = <Self as IntoApp>::into_app().try_get_matches_from(itr)?;
        Ok(<Self as FromArgMatches>::from_arg_matches(&matches))
    }

    /// Update from iterator, exit on error
    fn update_from<I, T>(&mut self, itr: I)
    where
        I: IntoIterator<Item = T>,
        // TODO (@CreepySkeleton): discover a way to avoid cloning here
        T: Into<OsString> + Clone,
    {
        // TODO find a way to get partial matches
        let matches = <Self as IntoApp>::into_app_for_update().get_matches_from(itr);
        <Self as FromArgMatches>::update_from_arg_matches(self, &matches);
    }

    /// Update from iterator, return Err on error.
    fn try_update_from<I, T>(&mut self, itr: I) -> Result<(), Error>
    where
        I: IntoIterator<Item = T>,
        // TODO (@CreepySkeleton): discover a way to avoid cloning here
        T: Into<OsString> + Clone,
    {
        let matches = <Self as IntoApp>::into_app_for_update().try_get_matches_from(itr)?;
        <Self as FromArgMatches>::update_from_arg_matches(self, &matches);
        Ok(())
    }
}

/// Build an App according to the struct
///
/// Also serves for flattening
pub trait IntoApp: Sized {
    /// @TODO @release @docs
    fn into_app<'help>() -> App<'help>;
    /// @TODO @release @docs
    fn augment_clap(app: App<'_>) -> App<'_>;
    /// @TODO @release @docs
    fn into_app_for_update<'help>() -> App<'help>;
    /// @TODO @release @docs
    fn augment_clap_for_update(app: App<'_>) -> App<'_>;
}

/// Converts an instance of [`ArgMatches`] to a consumer defined struct.
///
/// [`ArgMatches`]: ./struct.ArgMatches.html
pub trait FromArgMatches: Sized {
    /// It's common to have an "application context" struct (sometimes called
    /// config) that represents all the normalized values after being processed by
    /// the CLI.
    ///
    /// For instance, if an application we made had two CLI options, `--name
    /// <STRING>` and a flag `--debug` to distinguish "debugging mode" for our made
    /// up CLI, we may create a context struct as follows:
    ///
    /// ```no_run
    /// struct Context {
    ///     name: String,
    ///     debug: bool
    /// }
    /// ```
    ///
    /// And after letting `clap` parse the CLI, we get back and instance of
    /// `ArgMatches`, we may create a `From` implementation like so:
    ///
    /// ```no_run
    /// # use clap::ArgMatches;
    /// # struct Context {
    /// #   name: String,
    /// #   debug: bool
    /// # }
    /// impl From<ArgMatches> for Context {
    ///    fn from(m: ArgMatches) -> Self {
    ///        Context {
    ///            name: m.value_of("name").unwrap().to_string(),
    ///            debug: m.is_present("debug"),
    ///        }
    ///    }
    /// }
    /// ```
    fn from_arg_matches(matches: &ArgMatches) -> Self;

    /// @TODO@ @release @docs
    fn update_from_arg_matches(&mut self, matches: &ArgMatches);
}

/// @TODO @release @docs
pub trait Subcommand: Sized {
    /// @TODO @release @docs
    fn from_subcommand(subcommand: Option<(&str, &ArgMatches)>) -> Option<Self>;
    /// @TODO @release @docs
    fn update_from_subcommand(&mut self, subcommand: Option<(&str, &ArgMatches)>);
    /// @TODO @release @docs
    fn augment_subcommands(app: App<'_>) -> App<'_>;
    /// @TODO @release @docs
    fn augment_subcommands_for_update(app: App<'_>) -> App<'_>;
}

/// @TODO @release @docs
pub trait ArgEnum: Sized {
    /// @TODO @release @docs
    const VARIANTS: &'static [&'static str];

    /// @TODO @release @docs
    fn from_str(input: &str, case_insensitive: bool) -> Result<Self, String>;
}

impl<T: Clap> Clap for Box<T> {
    fn parse() -> Self {
        Box::new(<T as Clap>::parse())
    }

    fn try_parse() -> Result<Self, Error> {
        <T as Clap>::try_parse().map(Box::new)
    }

    fn parse_from<I, It>(itr: I) -> Self
    where
        I: IntoIterator<Item = It>,
        // TODO (@CreepySkeleton): discover a way to avoid cloning here
        It: Into<OsString> + Clone,
    {
        Box::new(<T as Clap>::parse_from(itr))
    }

    fn try_parse_from<I, It>(itr: I) -> Result<Self, Error>
    where
        I: IntoIterator<Item = It>,
        // TODO (@CreepySkeleton): discover a way to avoid cloning here
        It: Into<OsString> + Clone,
    {
        <T as Clap>::try_parse_from(itr).map(Box::new)
    }
}

impl<T: IntoApp> IntoApp for Box<T> {
    fn into_app<'help>() -> App<'help> {
        <T as IntoApp>::into_app()
    }
    fn augment_clap(app: App<'_>) -> App<'_> {
        <T as IntoApp>::augment_clap(app)
    }
    fn into_app_for_update<'help>() -> App<'help> {
        <T as IntoApp>::into_app_for_update()
    }
    fn augment_clap_for_update(app: App<'_>) -> App<'_> {
        <T as IntoApp>::augment_clap_for_update(app)
    }
}

impl<T: FromArgMatches> FromArgMatches for Box<T> {
    fn from_arg_matches(matches: &ArgMatches) -> Self {
        Box::new(<T as FromArgMatches>::from_arg_matches(matches))
    }
    fn update_from_arg_matches(&mut self, matches: &ArgMatches) {
        <T as FromArgMatches>::update_from_arg_matches(self, matches);
    }
}

impl<T: Subcommand> Subcommand for Box<T> {
    fn from_subcommand(subcommand: Option<(&str, &ArgMatches)>) -> Option<Self> {
        <T as Subcommand>::from_subcommand(subcommand).map(Box::new)
    }
    fn update_from_subcommand(&mut self, subcommand: Option<(&str, &ArgMatches)>) {
        <T as Subcommand>::update_from_subcommand(self, subcommand);
    }
    fn augment_subcommands(app: App<'_>) -> App<'_> {
        <T as Subcommand>::augment_subcommands(app)
    }
    fn augment_subcommands_for_update(app: App<'_>) -> App<'_> {
        <T as Subcommand>::augment_subcommands_for_update(app)
    }
}
<|endoftext|>


<commit_before>//! An emulated 128 bit unsigned integer.
//!
//! This module provides `Emu128`, a 128 bit unsigned integer that is
//! emulated using two `u64` types. This is useful for operations on
//! IPv6 address, which are 128 bit unsigned integers.
//!
//! Currently `Emu128` only implements those operations that are useful
//! for the `Ipv6Net` type. It is not intended to become a full `u128`
//! implementation.
//!
//! Conversion between `Ipv6Addr` and `Emu128` is provided by a `From`
//! and `Into` implementation on `Emu128`.
//!
//! [`Emu128`]: struct.Emu128.html

use std;
use std::ops::{BitAnd, BitOr, Shr, Shl};

/// An emulated 128 bit unsigned integer.
///
/// This module provides `Emu128`, a 128 bit unsigned integer that is
/// emulated using two `u64` types. This is useful for operations on
/// IPv6 address, which are 128 bit unsigned integers.
///
/// Currently `Emu128` only implements those operations that are useful
/// for the `Ipv6Net` type. It is not intended to become a full `u128`
/// implementation.
///
/// Conversion between `Ipv6Addr` and `Emu128` is provided by a `From`
/// and `Into` implementation on `Emu128`.
///
/// # Examples
///
/// ```
/// use std::u64;
/// use ipnet::Emu128;
///
/// let i0 = Emu128::min_value();
/// let i1 = Emu128::from([1, 1]);
/// let i2 = Emu128::max_value();
/// let i3 = Emu128::from([1, u64::MAX]);
///
/// assert_eq!(i0, Emu128 { hi: 0, lo: 0 });
/// assert_eq!(i2, Emu128 { hi: std::u64::MAX, lo: std::u64::MAX });
/// assert_eq!(i0.saturating_sub(i2), Emu128::min_value());
/// assert_eq!(i2.saturating_add(i2), Emu128::max_value());
/// assert_eq!(i1.saturating_add(i1), Emu128 { hi: 2, lo: 2 });
/// assert_eq!(i2.saturating_sub(i1), Emu128 { hi: std::u64::MAX-1, lo: std::u64::MAX-1 });
/// assert_eq!(i3.saturating_add(i1), Emu128 { hi: 3, lo: 0 });
/// assert_eq!(i3.saturating_sub(i1), Emu128 { hi: 0, lo: std::u64::MAX-1 });
/// assert_eq!(i1 << 1, Emu128 { hi: 2, lo: 2 });
/// assert_eq!(i1 << 63, Emu128 { hi: 1 << 63, lo: 1 << 63 });
/// assert_eq!(i1 << 127, Emu128 { hi: 1 << 63, lo: 0 });
/// assert_eq!(i1 >> 1, Emu128 { hi: 0, lo: 1u64 << 63 });
/// assert_eq!(i1 >> 63, Emu128 { hi: 0, lo: 2 });
/// assert_eq!(i1 >> 127, Emu128 { hi: 0, lo: 0 });
/// assert_eq!(i0 | i1, Emu128 { hi: 1, lo: 1 });
/// assert_eq!(i1 & i1, Emu128 { hi: 1, lo: 1 });
/// assert_eq!(i1 & i3, Emu128 { hi: 1, lo: 1 });
/// assert_eq!(i1 | i3, Emu128 { hi: 1, lo: std::u64::MAX });
/// ```
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Emu128 {
    pub hi: u64,
    pub lo: u64,
}

impl Emu128 {
    pub fn min_value() -> Emu128 {
        Emu128 { hi: 0, lo: 0 }
    }

    pub fn max_value() -> Emu128 {
        Emu128 { hi: std::u64::MAX, lo: std::u64::MAX }
    }

    pub fn saturating_add(self, other: Emu128) -> Emu128 {
        let (lo, ov) = self.lo.overflowing_add(other.lo);
        let res = self.hi.checked_add(other.hi).and_then(|x| x.checked_add(if ov { 1 } else { 0 }));
        match res {
            Some(hi) => Emu128 { hi: hi, lo: lo },
            None => Emu128::max_value(),
        }
    }

    pub fn saturating_sub(self, other: Emu128) -> Emu128 {
        let (lo, ov) = self.lo.overflowing_sub(other.lo);
        let res = self.hi.checked_sub(other.hi).and_then(|x| x.checked_sub(if ov { 1 } else { 0 }));
        match res {
            Some(hi) => Emu128 { hi: hi, lo: lo },
            None => Emu128::min_value(),
        }
    }

    pub fn leading_zeros(self) -> u32 {
        if self.hi > 0 { self.hi.leading_zeros() } else { self.lo.leading_zeros() + 64 }
    }

    pub fn trailing_zeros(self) -> u32 {
        if self.lo > 0 { self.lo.trailing_zeros() } else { self.hi.trailing_zeros() + 64 }
    }
}

impl Shl<u8> for Emu128 {
    type Output = Self;

    fn shl(self, rhs: u8) -> Emu128 {
        if rhs < 64 {
            Emu128 {
                hi: self.hi << rhs | self.lo >> (64-rhs),
                lo: self.lo << rhs
            }
        }
        else {
            Emu128 {
                hi: self.lo << (rhs-64),
                lo: 0
            }
        }
    }
}

impl Shr<u8> for Emu128 {
    type Output = Self;

    fn shr(self, rhs: u8) -> Emu128 {
        if rhs < 64 {
            Emu128 {
                hi: self.hi >> rhs,
                lo: self.lo >> rhs | self.hi << (64-rhs),
            }
        }
        else {
            Emu128 {
                hi: 0,
                lo: self.hi >> (rhs-64),
            }
        }
    }
}

impl BitAnd for Emu128 {
    type Output = Self;
    fn bitand(self, rhs: Emu128) -> Emu128 {
        Emu128 {
            hi: self.hi & rhs.hi,
            lo: self.lo & rhs.lo,
        }
    }
}

impl BitOr for Emu128 {
    type Output = Self;
    fn bitor(self, rhs: Emu128) -> Emu128 {
        Emu128 {
            hi: self.hi | rhs.hi,
            lo: self.lo | rhs.lo,
        }
    }
}

/// Convert an a `[u64; 2]` slice into an `Emu128`.
///
/// # Examples
///
/// ```
/// use ipnet::Emu128;
///
/// let u = Emu128::from([123u64, 123u64]);
/// let v: [u64; 2] = u.into();
/// assert_eq!(v, [123u64, 123u64]);
/// ```
impl From<[u64; 2]> for Emu128 {
    fn from(slice: [u64; 2]) -> Self {
        Emu128 {
            hi: slice[0],
            lo: slice[1],
        }
    }
}

/// Convert an Emu128 into a `[u64; 2]` slice.
///
/// # Examples
///
/// ```
/// use ipnet::Emu128;
///
/// let u = Emu128::from([123u64, 123u64]);
/// let v: [u64; 2] = u.into();
/// assert_eq!(v, [123u64, 123u64]);
/// ```
impl From<Emu128> for [u64; 2] {
    fn from(u: Emu128) -> Self {
        [u.hi, u.lo]
    }
}
<commit_msg>Converting ::std::u64::MAX to u64::max_value()<commit_after>//! An emulated 128 bit unsigned integer.
//!
//! This module provides `Emu128`, a 128 bit unsigned integer that is
//! emulated using two `u64` types. This is useful for operations on
//! IPv6 address, which are 128 bit unsigned integers.
//!
//! Currently `Emu128` only implements those operations that are useful
//! for the `Ipv6Net` type. It is not intended to become a full `u128`
//! implementation.
//!
//! Conversion between `Ipv6Addr` and `Emu128` is provided by a `From`
//! and `Into` implementation on `Emu128`.
//!
//! [`Emu128`]: struct.Emu128.html

use std::ops::{BitAnd, BitOr, Shr, Shl};

/// An emulated 128 bit unsigned integer.
///
/// This module provides `Emu128`, a 128 bit unsigned integer that is
/// emulated using two `u64` types. This is useful for operations on
/// IPv6 address, which are 128 bit unsigned integers.
///
/// Currently `Emu128` only implements those operations that are useful
/// for the `Ipv6Net` type. It is not intended to become a full `u128`
/// implementation.
///
/// Conversion between `Ipv6Addr` and `Emu128` is provided by a `From`
/// and `Into` implementation on `Emu128`.
///
/// # Examples
///
/// ```
/// use std::u64;
/// use ipnet::Emu128;
///
/// let i0 = Emu128::min_value();
/// let i1 = Emu128::from([1, 1]);
/// let i2 = Emu128::max_value();
/// let i3 = Emu128::from([1, u64::MAX]);
///
/// assert_eq!(i0, Emu128 { hi: 0, lo: 0 });
/// assert_eq!(i2, Emu128 { hi: std::u64::MAX, lo: std::u64::MAX });
/// assert_eq!(i0.saturating_sub(i2), Emu128::min_value());
/// assert_eq!(i2.saturating_add(i2), Emu128::max_value());
/// assert_eq!(i1.saturating_add(i1), Emu128 { hi: 2, lo: 2 });
/// assert_eq!(i2.saturating_sub(i1), Emu128 { hi: std::u64::MAX-1, lo: std::u64::MAX-1 });
/// assert_eq!(i3.saturating_add(i1), Emu128 { hi: 3, lo: 0 });
/// assert_eq!(i3.saturating_sub(i1), Emu128 { hi: 0, lo: std::u64::MAX-1 });
/// assert_eq!(i1 << 1, Emu128 { hi: 2, lo: 2 });
/// assert_eq!(i1 << 63, Emu128 { hi: 1 << 63, lo: 1 << 63 });
/// assert_eq!(i1 << 127, Emu128 { hi: 1 << 63, lo: 0 });
/// assert_eq!(i1 >> 1, Emu128 { hi: 0, lo: 1u64 << 63 });
/// assert_eq!(i1 >> 63, Emu128 { hi: 0, lo: 2 });
/// assert_eq!(i1 >> 127, Emu128 { hi: 0, lo: 0 });
/// assert_eq!(i0 | i1, Emu128 { hi: 1, lo: 1 });
/// assert_eq!(i1 & i1, Emu128 { hi: 1, lo: 1 });
/// assert_eq!(i1 & i3, Emu128 { hi: 1, lo: 1 });
/// assert_eq!(i1 | i3, Emu128 { hi: 1, lo: std::u64::MAX });
/// ```
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Emu128 {
    pub hi: u64,
    pub lo: u64,
}

impl Emu128 {
    pub fn min_value() -> Emu128 {
        Emu128 { hi: 0, lo: 0 }
    }

    pub fn max_value() -> Emu128 {
        Emu128 { hi: u64::max_value(), lo: u64::max_value() }
    }

    pub fn saturating_add(self, other: Emu128) -> Emu128 {
        let (lo, ov) = self.lo.overflowing_add(other.lo);
        let res = self.hi.checked_add(other.hi).and_then(|x| x.checked_add(if ov { 1 } else { 0 }));
        match res {
            Some(hi) => Emu128 { hi: hi, lo: lo },
            None => Emu128::max_value(),
        }
    }

    pub fn saturating_sub(self, other: Emu128) -> Emu128 {
        let (lo, ov) = self.lo.overflowing_sub(other.lo);
        let res = self.hi.checked_sub(other.hi).and_then(|x| x.checked_sub(if ov { 1 } else { 0 }));
        match res {
            Some(hi) => Emu128 { hi: hi, lo: lo },
            None => Emu128::min_value(),
        }
    }

    pub fn leading_zeros(self) -> u32 {
        if self.hi > 0 { self.hi.leading_zeros() } else { self.lo.leading_zeros() + 64 }
    }

    pub fn trailing_zeros(self) -> u32 {
        if self.lo > 0 { self.lo.trailing_zeros() } else { self.hi.trailing_zeros() + 64 }
    }
}

impl Shl<u8> for Emu128 {
    type Output = Self;

    fn shl(self, rhs: u8) -> Emu128 {
        if rhs < 64 {
            Emu128 {
                hi: self.hi << rhs | self.lo >> (64-rhs),
                lo: self.lo << rhs
            }
        }
        else {
            Emu128 {
                hi: self.lo << (rhs-64),
                lo: 0
            }
        }
    }
}

impl Shr<u8> for Emu128 {
    type Output = Self;

    fn shr(self, rhs: u8) -> Emu128 {
        if rhs < 64 {
            Emu128 {
                hi: self.hi >> rhs,
                lo: self.lo >> rhs | self.hi << (64-rhs),
            }
        }
        else {
            Emu128 {
                hi: 0,
                lo: self.hi >> (rhs-64),
            }
        }
    }
}

impl BitAnd for Emu128 {
    type Output = Self;
    fn bitand(self, rhs: Emu128) -> Emu128 {
        Emu128 {
            hi: self.hi & rhs.hi,
            lo: self.lo & rhs.lo,
        }
    }
}

impl BitOr for Emu128 {
    type Output = Self;
    fn bitor(self, rhs: Emu128) -> Emu128 {
        Emu128 {
            hi: self.hi | rhs.hi,
            lo: self.lo | rhs.lo,
        }
    }
}

/// Convert an a `[u64; 2]` slice into an `Emu128`.
///
/// # Examples
///
/// ```
/// use ipnet::Emu128;
///
/// let u = Emu128::from([123u64, 123u64]);
/// let v: [u64; 2] = u.into();
/// assert_eq!(v, [123u64, 123u64]);
/// ```
impl From<[u64; 2]> for Emu128 {
    fn from(slice: [u64; 2]) -> Self {
        Emu128 {
            hi: slice[0],
            lo: slice[1],
        }
    }
}

/// Convert an Emu128 into a `[u64; 2]` slice.
///
/// # Examples
///
/// ```
/// use ipnet::Emu128;
///
/// let u = Emu128::from([123u64, 123u64]);
/// let v: [u64; 2] = u.into();
/// assert_eq!(v, [123u64, 123u64]);
/// ```
impl From<Emu128> for [u64; 2] {
    fn from(u: Emu128) -> Self {
        [u.hi, u.lo]
    }
}
<|endoftext|>


<commit_before>use libc::{c_int, c_uint, c_ulonglong};
use ffi::{core, target};
use ffi::execution_engine as engine;
use ffi::execution_engine::*;
use ffi::target_machine::LLVMCodeModel;
use cbox::CBox;
use std::marker::PhantomData;
use std::{mem, ptr};
use std::ops::*;
use compile::Compile;
use context::{Context, GetContext};
use module::Module;
use ty::{StructType, Type};
use util::{self, CastFrom};
use value::{Function, Value};

/// An abstract interface for implementation execution of LLVM modules.
///
/// This is designed to support both interpreter and just-in-time (JIT) compiler implementations.
pub trait ExecutionEngine<'a, 'b:'a>:Sized+'b where LLVMExecutionEngineRef:From<&'b Self> {
    /// The options given to the engine upon creation.
    type Options : Copy;
    /// Create a new execution engine with the given `Module` and options, or return a
    /// description of the error.
    fn new(module: &'a Module, options: Self::Options) -> Result<Self, CBox<str>>;

    /// Add a module to the list of modules to interpret or compile.
    fn add_module(&'b self, module: &'a Module) {
        unsafe { engine::LLVMAddModule(self.into(), (&*module).into()) }
    }
    /// Remove a module from the list of modules to interpret or compile.
    fn remove_module(&'b self, module: &'a Module) -> &'a Module {
        unsafe {
            let mut out = mem::uninitialized();
            engine::LLVMRemoveModule(self.into(), module.into(), &mut out, ptr::null_mut());
            out.into()
        }
    }
    /// Execute all of the static constructors for this program.
    fn run_static_constructors(&'b self) {
        unsafe { engine::LLVMRunStaticConstructors(self.into()) }
    }
    /// Execute all of the static destructors for this program.
    fn run_static_destructors(&'b self) {
        unsafe { engine::LLVMRunStaticDestructors(self.into()) }
    }
    /// Attempt to find a function with the name given, or `None` if there wasn't
    /// a function with that name.
    fn find_function(&'b self, name: &str) -> Option<&'a Function> {
        util::with_cstr(name, |c_name| unsafe {
            let mut out = mem::zeroed();
            engine::LLVMFindFunction(self.into(), c_name, &mut out);
            mem::transmute(out)
        })
    }
    /// Run `function` with the arguments given as ``GenericValue`s, then return the result as one.
    ///
    /// Note that if this engine is a `JitEngine`, it only supports a small fraction of combinations
    /// for the arguments and return value, so be warned.
    ///
    /// To convert the arguments to `GenericValue`s, you should use the `GenericValueCast::to_generic` method.
    /// To convert the return value from a `GenericValue`, you should use the `GenericValueCast::from_generic` method.
    fn run_function(&'b self, function: &'a Function, args: &[GenericValue<'a>]) -> GenericValue<'a> {
        let ptr = args.as_ptr() as *mut LLVMGenericValueRef;
        unsafe { engine::LLVMRunFunction(self.into(), function.into(), args.len() as c_uint, ptr).into() }
    }
    /// Returns a pointer to the global value given.
    ///
    /// This is marked as unsafe because the type cannot be guranteed to be the same as the
    /// type of the global value at this point.
    unsafe fn get_global<T>(&'b self, global: &'a Value) -> &'b T {
        mem::transmute(engine::LLVMGetPointerToGlobal(self.into(), global.into()))
    }
    /// Returns a pointer to the global value with the name given.
    ///
    /// This is marked as unsafe because the type cannot be guranteed to be the same as the
    /// type of the global value at this point.
    unsafe fn find_global<T>(&'b self, name: &str) -> Option<&'b T> {
        util::with_cstr(name, |ptr|
            mem::transmute(engine::LLVMGetGlobalValueAddress(self.into(), ptr))
        )
    }
}

/// The options to pass to the MCJIT backend.
#[derive(Copy, Clone)]
pub struct JitOptions {
    /// The degree to which optimizations should be done, between 0 and 3.
    ///
    /// 0 represents no optimizations, 3 represents maximum optimization
    pub opt_level: usize
}
/// The MCJIT backend, which compiles functions and values into machine code.
pub struct JitEngine<'a> {
    engine: LLVMExecutionEngineRef,
    marker: PhantomData<&'a ()>
}
native_ref!{contra JitEngine, engine: LLVMExecutionEngineRef}
impl<'a, 'b> JitEngine<'a> {
    /// Run the closure `cb` with the machine code for the function `function`.
    ///
    /// This will check that the types match at runtime when in debug mode, but not release mode.
    /// You should make sure to use debug mode if you want it to error when the types don't match.
    pub fn with_function<C, A, R>(&self, function: &'b Function, cb: C) where A:Compile<'b>, R:Compile<'b>, C:FnOnce(extern fn(A) -> R) {
        if cfg!(not(ndebug)) {
            let ctx = function.get_context();
            let sig = function.get_signature();
            assert_eq!(Type::get::<R>(ctx), sig.get_return());
            let arg = Type::get::<A>(ctx);
            if let Some(args) = StructType::cast(arg) {
                assert_eq!(sig.get_params(), args.get_elements());
            } else {
                assert_eq!(arg, sig.get_return());
            }
        }
        unsafe {
            cb(self.get_function::<A, R>(function));
        }
    }
    /// Run the closure `cb` with the machine code for the function `function`.
    pub unsafe fn with_function_unchecked<C, A, R>(&self, function: &'b Function, cb: C) where A:Compile<'b>, R:Compile<'b>, C:FnOnce(extern fn(A) -> R) {
        cb(self.get_function::<A, R>(function));
    }
    /// Returns a pointer to the machine code for the function `function`.
    ///
    /// This is marked as unsafe because the types given as arguments and return could be different
    /// from their internal representation.
    pub unsafe fn get_function<A, R>(&self, function: &'b Function) -> extern fn(A) -> R {
        let ptr:&u8 = self.get_global(function);
        mem::transmute(ptr)
    }
}
impl<'a, 'b:'a> ExecutionEngine<'a, 'b> for JitEngine<'b> {
    type Options = JitOptions;
    fn new(module: &'a Module, options: JitOptions) -> Result<JitEngine<'b>, CBox<str>> {
        unsafe {
            let mut ee = mem::uninitialized();
            let mut out = mem::zeroed();
            engine::LLVMLinkInMCJIT();
            if target::LLVM_InitializeNativeTarget() == 1 {
                return Err("failed to initialize native target".into())
            }
            if target::LLVM_InitializeNativeAsmPrinter() == 1 {
                return Err("failed to initialize native asm printer".into())
            }
            let mut options = LLVMMCJITCompilerOptions {
                OptLevel: options.opt_level as c_uint,
                CodeModel: LLVMCodeModel::LLVMCodeModelDefault,
                NoFramePointerElim: 0,
                EnableFastISel: 1,
                MCJMM: ptr::null_mut()
            };
            let size = mem::size_of::<LLVMMCJITCompilerOptions>();
            let result = engine::LLVMCreateMCJITCompilerForModule(&mut ee, (&*module).into(), &mut options, size as u64, &mut out);
            if result == 0 {
                Ok(ee.into())
            } else {
                Err(CBox::new(out))
            }
        }
    }
}
/// The interpreter backend
pub struct Interpreter<'a> {
    engine: LLVMExecutionEngineRef,
    marker: PhantomData<&'a ()>
}
native_ref!{contra Interpreter, engine: LLVMExecutionEngineRef}
impl<'a> Interpreter<'a> {
    /// Run `function` with the arguments given as ``GenericValue`s, then return the result as one.
    ///
    /// To convert the arguments to `GenericValue`s, you should use the `GenericValueCast::to_generic` method.
    /// To convert the return value from a `GenericValue`, you should use the `GenericValueCast::from_generic` method.
    pub fn run_function(&self, function: &'a Function, args: &[GenericValue<'a>]) -> GenericValue<'a> {
        let ptr = args.as_ptr() as *mut LLVMGenericValueRef;
        unsafe { engine::LLVMRunFunction(self.into(), function.into(), args.len() as c_uint, ptr).into() }
    }
}
impl<'a, 'b:'a> ExecutionEngine<'a, 'b> for Interpreter<'b> {
    type Options = ();
    fn new(module: &'a Module, _: ()) -> Result<Interpreter<'b>, CBox<str>> {
        unsafe {
            let mut ee = mem::uninitialized();
            let mut out = mem::zeroed();
            engine::LLVMLinkInInterpreter();
            let result = engine::LLVMCreateInterpreterForModule(&mut ee, (&*module).into(), &mut out);
            if result == 0 {
                Ok(ee.into())
            } else {
                Err(CBox::new(out))
            }
        }
    }
}
/// A wrapped value that can be passed to an interpreted function or returned from one
pub struct GenericValue<'a> {
    value: LLVMGenericValueRef,
    marker: PhantomData<&'a ()>
}
native_ref!(contra GenericValue, value: LLVMGenericValueRef);
impl<'a> Drop for GenericValue<'a> {
    fn drop(&mut self) {
        unsafe {
            engine::LLVMDisposeGenericValue(self.value)
        }
    }
}

/// A value that can be cast into a `GenericValue` and that a `GenericValue` can be cast into.
///
/// Both these methods require contexts because some `Type` constructors are needed for the
/// conversion and these constructors need a context.
pub trait GenericValueCast<'a> {
    /// Create a `GenericValue` from this value.
    fn to_generic(self, context: &'a Context) -> GenericValue<'a>;
    /// Convert the `GenericValue` into a value of this type again.
    fn from_generic(value: GenericValue<'a>, context: &'a Context) -> Self;
}

impl<'a> GenericValueCast<'a> for f64 {
    fn to_generic(self, ctx: &'a Context) -> GenericValue<'a> {
        unsafe {
            let ty = core::LLVMDoubleTypeInContext(ctx.into());
            engine::LLVMCreateGenericValueOfFloat(ty, self).into()
        }
    }
    fn from_generic(value: GenericValue<'a>, ctx: &'a Context) -> f64 {
        unsafe {
            let ty = core::LLVMDoubleTypeInContext(ctx.into());
            engine::LLVMGenericValueToFloat(ty, value.into())
        }
    }
}
impl<'a> GenericValueCast<'a> for f32 {
    fn to_generic(self, ctx: &'a Context) -> GenericValue<'a> {
        unsafe {
            let ty = core::LLVMFloatTypeInContext(ctx.into());
            engine::LLVMCreateGenericValueOfFloat(ty, self as f64).into()
        }
    }
    fn from_generic(value: GenericValue<'a>, ctx: &'a Context) -> f32 {
        unsafe {
            let ty = core::LLVMFloatTypeInContext(ctx.into());
            engine::LLVMGenericValueToFloat(ty, value.into()) as f32
        }
    }
}
macro_rules! generic_int(
    ($ty:ty, $signed:expr) => (
        impl<'a> GenericValueCast<'a> for $ty {
            fn to_generic(self, ctx: &'a Context) -> GenericValue<'a> {
                unsafe {
                    let ty = <Self as Compile<'a>>::get_type(ctx);
                    engine::LLVMCreateGenericValueOfInt(ty.into(), self as c_ulonglong, $signed as c_int).into()
                }
            }
            fn from_generic(value: GenericValue<'a>, _: &'a Context) -> $ty {
                unsafe {
                    engine::LLVMGenericValueToInt(value.into(), $signed as c_int) as $ty
                }
            }
        }
    );
    (some $signed:ty, $unsigned:ty) => (
        generic_int!{$signed, true}
        generic_int!{$unsigned, false}
    );
);

impl<'a> GenericValueCast<'a> for bool {
    fn to_generic(self, ctx: &'a Context) -> GenericValue<'a> {
        unsafe {
            let ty = <Self as Compile<'a>>::get_type(ctx);
            engine::LLVMCreateGenericValueOfInt(ty.into(), self as c_ulonglong, 0).into()
        }
    }
    fn from_generic(value: GenericValue<'a>, _: &'a Context) -> bool {
        unsafe {
            engine::LLVMGenericValueToInt(value.into(), 0) != 0
        }
    }
}
generic_int!{some i8, u8}
generic_int!{some i16, u16}
generic_int!{some i32, u32}
generic_int!{some i64, u64}
<commit_msg>Fix `usize` as `u64`<commit_after>use libc::{c_int, c_uint, c_ulonglong};
use ffi::{core, target};
use ffi::execution_engine as engine;
use ffi::execution_engine::*;
use ffi::target_machine::LLVMCodeModel;
use cbox::CBox;
use std::marker::PhantomData;
use std::{mem, ptr};
use std::ops::*;
use compile::Compile;
use context::{Context, GetContext};
use module::Module;
use ty::{StructType, Type};
use util::{self, CastFrom};
use value::{Function, Value};

/// An abstract interface for implementation execution of LLVM modules.
///
/// This is designed to support both interpreter and just-in-time (JIT) compiler implementations.
pub trait ExecutionEngine<'a, 'b:'a>:Sized+'b where LLVMExecutionEngineRef:From<&'b Self> {
    /// The options given to the engine upon creation.
    type Options : Copy;
    /// Create a new execution engine with the given `Module` and options, or return a
    /// description of the error.
    fn new(module: &'a Module, options: Self::Options) -> Result<Self, CBox<str>>;

    /// Add a module to the list of modules to interpret or compile.
    fn add_module(&'b self, module: &'a Module) {
        unsafe { engine::LLVMAddModule(self.into(), (&*module).into()) }
    }
    /// Remove a module from the list of modules to interpret or compile.
    fn remove_module(&'b self, module: &'a Module) -> &'a Module {
        unsafe {
            let mut out = mem::uninitialized();
            engine::LLVMRemoveModule(self.into(), module.into(), &mut out, ptr::null_mut());
            out.into()
        }
    }
    /// Execute all of the static constructors for this program.
    fn run_static_constructors(&'b self) {
        unsafe { engine::LLVMRunStaticConstructors(self.into()) }
    }
    /// Execute all of the static destructors for this program.
    fn run_static_destructors(&'b self) {
        unsafe { engine::LLVMRunStaticDestructors(self.into()) }
    }
    /// Attempt to find a function with the name given, or `None` if there wasn't
    /// a function with that name.
    fn find_function(&'b self, name: &str) -> Option<&'a Function> {
        util::with_cstr(name, |c_name| unsafe {
            let mut out = mem::zeroed();
            engine::LLVMFindFunction(self.into(), c_name, &mut out);
            mem::transmute(out)
        })
    }
    /// Run `function` with the arguments given as ``GenericValue`s, then return the result as one.
    ///
    /// Note that if this engine is a `JitEngine`, it only supports a small fraction of combinations
    /// for the arguments and return value, so be warned.
    ///
    /// To convert the arguments to `GenericValue`s, you should use the `GenericValueCast::to_generic` method.
    /// To convert the return value from a `GenericValue`, you should use the `GenericValueCast::from_generic` method.
    fn run_function(&'b self, function: &'a Function, args: &[GenericValue<'a>]) -> GenericValue<'a> {
        let ptr = args.as_ptr() as *mut LLVMGenericValueRef;
        unsafe { engine::LLVMRunFunction(self.into(), function.into(), args.len() as c_uint, ptr).into() }
    }
    /// Returns a pointer to the global value given.
    ///
    /// This is marked as unsafe because the type cannot be guranteed to be the same as the
    /// type of the global value at this point.
    unsafe fn get_global<T>(&'b self, global: &'a Value) -> &'b T {
        mem::transmute(engine::LLVMGetPointerToGlobal(self.into(), global.into()))
    }
    /// Returns a pointer to the global value with the name given.
    ///
    /// This is marked as unsafe because the type cannot be guranteed to be the same as the
    /// type of the global value at this point.
    unsafe fn find_global<T>(&'b self, name: &str) -> Option<&'b T> {
        util::with_cstr(name, |ptr|
            mem::transmute(engine::LLVMGetGlobalValueAddress(self.into(), ptr))
        )
    }
}

/// The options to pass to the MCJIT backend.
#[derive(Copy, Clone)]
pub struct JitOptions {
    /// The degree to which optimizations should be done, between 0 and 3.
    ///
    /// 0 represents no optimizations, 3 represents maximum optimization
    pub opt_level: usize
}
/// The MCJIT backend, which compiles functions and values into machine code.
pub struct JitEngine<'a> {
    engine: LLVMExecutionEngineRef,
    marker: PhantomData<&'a ()>
}
native_ref!{contra JitEngine, engine: LLVMExecutionEngineRef}
impl<'a, 'b> JitEngine<'a> {
    /// Run the closure `cb` with the machine code for the function `function`.
    ///
    /// This will check that the types match at runtime when in debug mode, but not release mode.
    /// You should make sure to use debug mode if you want it to error when the types don't match.
    pub fn with_function<C, A, R>(&self, function: &'b Function, cb: C) where A:Compile<'b>, R:Compile<'b>, C:FnOnce(extern fn(A) -> R) {
        if cfg!(not(ndebug)) {
            let ctx = function.get_context();
            let sig = function.get_signature();
            assert_eq!(Type::get::<R>(ctx), sig.get_return());
            let arg = Type::get::<A>(ctx);
            if let Some(args) = StructType::cast(arg) {
                assert_eq!(sig.get_params(), args.get_elements());
            } else {
                assert_eq!(arg, sig.get_return());
            }
        }
        unsafe {
            cb(self.get_function::<A, R>(function));
        }
    }
    /// Run the closure `cb` with the machine code for the function `function`.
    pub unsafe fn with_function_unchecked<C, A, R>(&self, function: &'b Function, cb: C) where A:Compile<'b>, R:Compile<'b>, C:FnOnce(extern fn(A) -> R) {
        cb(self.get_function::<A, R>(function));
    }
    /// Returns a pointer to the machine code for the function `function`.
    ///
    /// This is marked as unsafe because the types given as arguments and return could be different
    /// from their internal representation.
    pub unsafe fn get_function<A, R>(&self, function: &'b Function) -> extern fn(A) -> R {
        let ptr:&u8 = self.get_global(function);
        mem::transmute(ptr)
    }
}
impl<'a, 'b:'a> ExecutionEngine<'a, 'b> for JitEngine<'b> {
    type Options = JitOptions;
    fn new(module: &'a Module, options: JitOptions) -> Result<JitEngine<'b>, CBox<str>> {
        unsafe {
            let mut ee = mem::uninitialized();
            let mut out = mem::zeroed();
            engine::LLVMLinkInMCJIT();
            if target::LLVM_InitializeNativeTarget() == 1 {
                return Err("failed to initialize native target".into())
            }
            if target::LLVM_InitializeNativeAsmPrinter() == 1 {
                return Err("failed to initialize native asm printer".into())
            }
            let mut options = LLVMMCJITCompilerOptions {
                OptLevel: options.opt_level as c_uint,
                CodeModel: LLVMCodeModel::LLVMCodeModelDefault,
                NoFramePointerElim: 0,
                EnableFastISel: 1,
                MCJMM: ptr::null_mut()
            };
            let size = mem::size_of::<LLVMMCJITCompilerOptions>();
            let result = engine::LLVMCreateMCJITCompilerForModule(&mut ee, (&*module).into(), &mut options, size, &mut out);
            if result == 0 {
                Ok(ee.into())
            } else {
                Err(CBox::new(out))
            }
        }
    }
}
/// The interpreter backend
pub struct Interpreter<'a> {
    engine: LLVMExecutionEngineRef,
    marker: PhantomData<&'a ()>
}
native_ref!{contra Interpreter, engine: LLVMExecutionEngineRef}
impl<'a> Interpreter<'a> {
    /// Run `function` with the arguments given as ``GenericValue`s, then return the result as one.
    ///
    /// To convert the arguments to `GenericValue`s, you should use the `GenericValueCast::to_generic` method.
    /// To convert the return value from a `GenericValue`, you should use the `GenericValueCast::from_generic` method.
    pub fn run_function(&self, function: &'a Function, args: &[GenericValue<'a>]) -> GenericValue<'a> {
        let ptr = args.as_ptr() as *mut LLVMGenericValueRef;
        unsafe { engine::LLVMRunFunction(self.into(), function.into(), args.len() as c_uint, ptr).into() }
    }
}
impl<'a, 'b:'a> ExecutionEngine<'a, 'b> for Interpreter<'b> {
    type Options = ();
    fn new(module: &'a Module, _: ()) -> Result<Interpreter<'b>, CBox<str>> {
        unsafe {
            let mut ee = mem::uninitialized();
            let mut out = mem::zeroed();
            engine::LLVMLinkInInterpreter();
            let result = engine::LLVMCreateInterpreterForModule(&mut ee, (&*module).into(), &mut out);
            if result == 0 {
                Ok(ee.into())
            } else {
                Err(CBox::new(out))
            }
        }
    }
}
/// A wrapped value that can be passed to an interpreted function or returned from one
pub struct GenericValue<'a> {
    value: LLVMGenericValueRef,
    marker: PhantomData<&'a ()>
}
native_ref!(contra GenericValue, value: LLVMGenericValueRef);
impl<'a> Drop for GenericValue<'a> {
    fn drop(&mut self) {
        unsafe {
            engine::LLVMDisposeGenericValue(self.value)
        }
    }
}

/// A value that can be cast into a `GenericValue` and that a `GenericValue` can be cast into.
///
/// Both these methods require contexts because some `Type` constructors are needed for the
/// conversion and these constructors need a context.
pub trait GenericValueCast<'a> {
    /// Create a `GenericValue` from this value.
    fn to_generic(self, context: &'a Context) -> GenericValue<'a>;
    /// Convert the `GenericValue` into a value of this type again.
    fn from_generic(value: GenericValue<'a>, context: &'a Context) -> Self;
}

impl<'a> GenericValueCast<'a> for f64 {
    fn to_generic(self, ctx: &'a Context) -> GenericValue<'a> {
        unsafe {
            let ty = core::LLVMDoubleTypeInContext(ctx.into());
            engine::LLVMCreateGenericValueOfFloat(ty, self).into()
        }
    }
    fn from_generic(value: GenericValue<'a>, ctx: &'a Context) -> f64 {
        unsafe {
            let ty = core::LLVMDoubleTypeInContext(ctx.into());
            engine::LLVMGenericValueToFloat(ty, value.into())
        }
    }
}
impl<'a> GenericValueCast<'a> for f32 {
    fn to_generic(self, ctx: &'a Context) -> GenericValue<'a> {
        unsafe {
            let ty = core::LLVMFloatTypeInContext(ctx.into());
            engine::LLVMCreateGenericValueOfFloat(ty, self as f64).into()
        }
    }
    fn from_generic(value: GenericValue<'a>, ctx: &'a Context) -> f32 {
        unsafe {
            let ty = core::LLVMFloatTypeInContext(ctx.into());
            engine::LLVMGenericValueToFloat(ty, value.into()) as f32
        }
    }
}
macro_rules! generic_int(
    ($ty:ty, $signed:expr) => (
        impl<'a> GenericValueCast<'a> for $ty {
            fn to_generic(self, ctx: &'a Context) -> GenericValue<'a> {
                unsafe {
                    let ty = <Self as Compile<'a>>::get_type(ctx);
                    engine::LLVMCreateGenericValueOfInt(ty.into(), self as c_ulonglong, $signed as c_int).into()
                }
            }
            fn from_generic(value: GenericValue<'a>, _: &'a Context) -> $ty {
                unsafe {
                    engine::LLVMGenericValueToInt(value.into(), $signed as c_int) as $ty
                }
            }
        }
    );
    (some $signed:ty, $unsigned:ty) => (
        generic_int!{$signed, true}
        generic_int!{$unsigned, false}
    );
);

impl<'a> GenericValueCast<'a> for bool {
    fn to_generic(self, ctx: &'a Context) -> GenericValue<'a> {
        unsafe {
            let ty = <Self as Compile<'a>>::get_type(ctx);
            engine::LLVMCreateGenericValueOfInt(ty.into(), self as c_ulonglong, 0).into()
        }
    }
    fn from_generic(value: GenericValue<'a>, _: &'a Context) -> bool {
        unsafe {
            engine::LLVMGenericValueToInt(value.into(), 0) != 0
        }
    }
}
generic_int!{some i8, u8}
generic_int!{some i16, u16}
generic_int!{some i32, u32}
generic_int!{some i64, u64}
<|endoftext|>


<commit_before>use std::fmt;

use itertools::Itertools;
use rand::{Rng, SeedableRng};
use rand::rngs::StdRng;
use rand::seq::SliceRandom;

use constants::MAX_PLUGS;
use plugboard::Plugboard;
use reflector::Reflector;
use rotor::Rotor;

/// Represents an Enigma machine with rotor, key, and ring settings.
#[derive(Clone, Debug)]
pub struct Enigma {
    slow: Rotor,
    mid: Rotor,
    fast: Rotor,
    reflector: Reflector,
    plugboard: Plugboard,
}

impl Enigma {
    /// Creates a new `Enigma`, where `rotors` is a string of three digits
    /// ranging from 1-8 (corresponding to rotors I through VIII of the real
    /// Enigma machine), `keys` and `rings` are three character strings
    /// containing the key and ring settings, `reflector` is one of `'A'`,
    /// `'B'`, or `'C'`, and `plugboard` is a string of whitespace-delimited
    /// pairs of characters.
    ///
    /// # Examples
    ///
    /// `Enigma` with rotors I, II, and III, key setting `ABC`, ring setting
    /// `DEF`, reflector B, and a plugboard connection between 'P' and 'Y'.
    ///
    /// ```
    /// use ultra::Enigma;
    ///
    /// let mut enigma = Enigma::new("123", "ABC", "DEF", 'B', "PY");
    /// ```
    pub fn new(rotors: &str, keys: &str, rings: &str, reflector: char, plugboard: &str) -> Enigma {
        let rotors: Vec<usize> = rotors.chars()
            .filter_map(|c| c.to_digit(10))
            .map(|n| n as usize)
            .collect();

        if rotors.len() != 3 {
            panic!("Exactly 3 rotors must be given.");
        }

        let keys: Vec<char> = keys.chars().collect();
        let rings: Vec<char> = rings.chars().collect();

        Enigma {
            slow: Rotor::from_enigma(rotors[0], keys[0], rings[0]),
            mid: Rotor::from_enigma(rotors[1], keys[1], rings[1]),
            fast: Rotor::from_enigma(rotors[2], keys[2], rings[2]),
            reflector: Reflector::from_enigma(reflector),
            plugboard: Plugboard::new(plugboard),
        }
    }

    /// Creates a new random `Enigma` with random settings based on
    /// thread-local RNG.
    ///
    /// # Examples
    ///
    /// ```
    /// use ultra::Enigma;
    ///
    /// let mut enigma_1 = Enigma::random();
    /// let mut enigma_2 = Enigma::random();
    /// assert!(enigma_1.encrypt("ENIGMA") != enigma_2.encrypt("ENIGMA"));
    /// ```
    pub fn random() -> Enigma {
        Enigma::random_from_rng(&mut rand::thread_rng())
    }

    /// Creates a new random `Enigma` from a given u64 seed.
    ///
    /// # Examples
    ///
    /// ```
    /// use ultra::Enigma;
    ///
    /// let mut enigma_1 = Enigma::random_from_u64_seed(42);
    /// let mut enigma_2 = Enigma::random_from_u64_seed(42);
    /// assert_eq!(enigma_1.encrypt("ENIGMA"), enigma_2.encrypt("ENIGMA"));
    /// ```
    pub fn random_from_u64_seed(seed: u64) -> Enigma {
        Enigma::random_from_rng(&mut StdRng::seed_from_u64(seed))
    }

    fn random_from_rng<R: Rng>(rng: &mut R) -> Enigma {
        let rotors: String = {
            let mut rotor_pool: Vec<char> = "12345".chars().collect();
            rotor_pool.shuffle(rng);
            rotor_pool[..3].iter().collect()
        };

        // Randomize key and ring settings for the rotors.
        let mut alpha: Vec<char> = ('A'..='Z').collect();

        alpha.shuffle(rng);
        let key: String = alpha[..3].iter().collect();

        alpha.shuffle(rng);
        let ring: String = alpha[..3].iter().collect();

        // Pick random plugs to fill plugboard with.
        let mut plug_pool = alpha.clone();
        plug_pool.shuffle(rng);
        let plugboard = plug_pool
            .chunks(2)
            .take(rng.gen_range(0..=MAX_PLUGS))
            .map(|chrs| chrs.iter().collect::<String>())
            .join(" ");

        Enigma::new(&rotors, &key, &ring, 'B', &plugboard)
    }

    /// Encrypts an entire message, advancing the rotors of the machine
    /// after each alphabetic character is encrypted.
    ///
    /// # Examples
    ///
    /// ```
    /// use ultra::Enigma;
    ///
    /// let mut enigma = Enigma::new("123", "ABC", "DEF", 'B', "PY");
    /// assert_eq!(enigma.encrypt("ENIGMA"), "HKAJWW");
    /// ```
    pub fn encrypt(&mut self, msg: &str) -> String {
        msg.chars().map(|c| self.encrypt_char(c)).collect()
    }

    /// Advances the rotors then returns the substitution of
    /// a character, if the input character was alphabetic.
    fn encrypt_char(&mut self, c: char) -> char {
        if !c.is_ascii() || !c.is_alphabetic() {
            return c;
        }

        self.advance();
        self.substitute(c.to_ascii_uppercase())
    }

    /// Returns the substitution of a character, which is determined by
    /// passing the character in sequence through the plugboard, the rotors
    /// from `fast` to `slow`, through the reflector, inverted through the
    /// rotors from `slow` to `fast`, and finally through the plugboard.
    fn substitute(&self, c: char) -> char {
        let mut c = self.plugboard.map(c);
        c = self.slow.substitute(self.mid.substitute(self.fast.substitute(c)));
        c = self.reflector.reflect(c);
        c = self.fast.invert(self.mid.invert(self.slow.invert(c)));
        self.plugboard.map(c)
    }

    /// Advances the `fast` rotor, and also advances the
    /// `mid` and `slow` rotors if appropriate.
    fn advance(&mut self) {
        // Check for double-rotation situation
        if self.mid.at_notch() {
            self.mid.advance();
            self.slow.advance();
        } else if self.fast.at_notch() {
            self.mid.advance();
        }

        // Finally, advance the fast rotor
        self.fast.advance();
    }

    /// Resets the `Enigma` to its initial state.
    ///
    /// # Examples
    ///
    /// ```
    /// use ultra::Enigma;
    ///
    /// let msg = "THIS IS A TEST";
    ///
    /// let mut enigma = Enigma::random();
    /// let ciphertext_1 = enigma.encrypt(msg);
    /// let ciphertext_2 = enigma.encrypt(msg);
    ///
    /// enigma.reset();
    ///
    /// assert_eq!(ciphertext_1, enigma.encrypt(msg));
    /// assert!(ciphertext_1 != ciphertext_2);
    /// ```
    pub fn reset(&mut self) {
        self.slow.reset();
        self.mid.reset();
        self.fast.reset();
    }

    /// Returns a string representing the `Enigma`'s rotor list.
    ///
    /// # Examples
    ///
    /// ```
    /// use ultra::Enigma;
    ///
    /// let enigma = Enigma::new("123", "ABC", "DEF", 'B', "PY");
    /// assert_eq!(enigma.rotor_list(), "123");
    /// ```
    pub fn rotor_list(&self) -> String {
        self.rotors().map(|r| r.to_string()).collect()
    }

    /// Returns a string representing the `Enigma`'s key settings.
    ///
    /// # Examples
    ///
    /// ```
    /// use ultra::Enigma;
    ///
    /// let enigma = Enigma::new("123", "ABC", "DEF", 'B', "PY");
    /// assert_eq!(enigma.key_settings(), "ABC");
    /// ```
    pub fn key_settings(&self) -> String {
        self.rotors()
            .map(|r| ((r.key_setting as u8) + b'A') as char)
            .collect()
    }

    /// Returns a string representing the `Enigma`'s ring settings.
    ///
    /// # Examples
    ///
    /// ```
    /// use ultra::Enigma;
    ///
    /// let enigma = Enigma::new("123", "ABC", "DEF", 'B', "PY");
    /// assert_eq!(enigma.ring_settings(), "DEF");
    /// ```
    pub fn ring_settings(&self) -> String {
        self.rotors()
            .map(|r| ((r.ring_setting as u8) + b'A') as char)
            .collect()
    }

    /// Returns an iterator over the slow, middle, and fast rotors.
    fn rotors(&self) -> std::vec::IntoIter<Rotor> {
        vec![self.slow.clone(), self.mid.clone(), self.fast.clone()].into_iter()
    }
}

impl fmt::Display for Enigma {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Rotors: {} / Key: {} / Ring: {} / Plugs: {}",
            self.rotor_list().chars().join("-"),
            self.key_settings().chars().join("-"),
            self.ring_settings().chars().join("-"),
            self.plugboard)
    }
}

#[cfg(test)]
mod tests {
    use super::Enigma;

    #[test]
    fn symmetrical_behaviour() {
        let msg = "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG".repeat(10);

        for _ in 0..10 {
            let mut enigma = Enigma::random();
            let ciphertext = enigma.encrypt(&msg);

            enigma.reset();
            let plaintext = enigma.encrypt(&ciphertext);

            assert_eq!(plaintext, msg);
        }
    }

    #[test]
    fn identical_from_same_seed() {
        let mut enigma_1 = Enigma::random_from_u64_seed(42);
        let mut enigma_2 = Enigma::random_from_u64_seed(42);
        assert_eq!(enigma_1.encrypt("ENIGMA"), enigma_2.encrypt("ENIGMA"));
    }

    #[test]
    fn case_insensitive_encryption() {
        let mut enigma = Enigma::new("123", "AAA", "AAA", 'B', "");
        let ciphertext1 = enigma.encrypt("Test Message");

        enigma.reset();
        let ciphertext2 = enigma.encrypt("TEST MESSAGE");

        assert_eq!(ciphertext1, ciphertext2);
    }

    #[test]
    fn key_settings() {
        let mut enigma = Enigma::new("123", "CAT", "AAA", 'B', "");
        assert_eq!(enigma.encrypt("AAAAA"), "XLEPK");
    }

    #[test]
    fn ring_settings() {
        let mut enigma = Enigma::new("123", "AAA", "DOG", 'B', "");
        assert_eq!(enigma.encrypt("AAAAA"), "XKJZE");
    }

    #[test]
    fn repetition_period() {
        // Due to the double-rotation of the middle rotor, the Enigma
        // has a period of 26 * 25 * 26 rather the expected 26^3.
        let mut enigma = Enigma::new("123", "AAA", "AAA", 'B', "");

        for _ in 0..(26 * 25 * 26) {
            enigma.advance();
        }

        assert_eq!(enigma.slow.offset, 0);
        assert_eq!(enigma.mid.offset, 0);
        assert_eq!(enigma.fast.offset, 0);
    }

    #[test]
    #[should_panic]
    fn invalid_rotor_count() {
        Enigma::new("12", "AAA", "AAA", 'B', "");
    }
}
<commit_msg>Add Enigma::plugboard() getter<commit_after>use std::fmt;

use itertools::Itertools;
use rand::{Rng, SeedableRng};
use rand::rngs::StdRng;
use rand::seq::SliceRandom;

use constants::MAX_PLUGS;
use plugboard::Plugboard;
use reflector::Reflector;
use rotor::Rotor;

/// Represents an Enigma machine with rotor, key, and ring settings.
#[derive(Clone, Debug)]
pub struct Enigma {
    slow: Rotor,
    mid: Rotor,
    fast: Rotor,
    reflector: Reflector,
    plugboard: Plugboard,
}

impl Enigma {
    /// Creates a new `Enigma`, where `rotors` is a string of three digits
    /// ranging from 1-8 (corresponding to rotors I through VIII of the real
    /// Enigma machine), `keys` and `rings` are three character strings
    /// containing the key and ring settings, `reflector` is one of `'A'`,
    /// `'B'`, or `'C'`, and `plugboard` is a string of whitespace-delimited
    /// pairs of characters.
    ///
    /// # Examples
    ///
    /// `Enigma` with rotors I, II, and III, key setting `ABC`, ring setting
    /// `DEF`, reflector B, and a plugboard connection between 'P' and 'Y'.
    ///
    /// ```
    /// use ultra::Enigma;
    ///
    /// let mut enigma = Enigma::new("123", "ABC", "DEF", 'B', "PY");
    /// ```
    pub fn new(rotors: &str, keys: &str, rings: &str, reflector: char, plugboard: &str) -> Enigma {
        let rotors: Vec<usize> = rotors.chars()
            .filter_map(|c| c.to_digit(10))
            .map(|n| n as usize)
            .collect();

        if rotors.len() != 3 {
            panic!("Exactly 3 rotors must be given.");
        }

        let keys: Vec<char> = keys.chars().collect();
        let rings: Vec<char> = rings.chars().collect();

        Enigma {
            slow: Rotor::from_enigma(rotors[0], keys[0], rings[0]),
            mid: Rotor::from_enigma(rotors[1], keys[1], rings[1]),
            fast: Rotor::from_enigma(rotors[2], keys[2], rings[2]),
            reflector: Reflector::from_enigma(reflector),
            plugboard: Plugboard::new(plugboard),
        }
    }

    /// Creates a new random `Enigma` with random settings based on
    /// thread-local RNG.
    ///
    /// # Examples
    ///
    /// ```
    /// use ultra::Enigma;
    ///
    /// let mut enigma_1 = Enigma::random();
    /// let mut enigma_2 = Enigma::random();
    /// assert!(enigma_1.encrypt("ENIGMA") != enigma_2.encrypt("ENIGMA"));
    /// ```
    pub fn random() -> Enigma {
        Enigma::random_from_rng(&mut rand::thread_rng())
    }

    /// Creates a new random `Enigma` from a given u64 seed.
    ///
    /// # Examples
    ///
    /// ```
    /// use ultra::Enigma;
    ///
    /// let mut enigma_1 = Enigma::random_from_u64_seed(42);
    /// let mut enigma_2 = Enigma::random_from_u64_seed(42);
    /// assert_eq!(enigma_1.encrypt("ENIGMA"), enigma_2.encrypt("ENIGMA"));
    /// ```
    pub fn random_from_u64_seed(seed: u64) -> Enigma {
        Enigma::random_from_rng(&mut StdRng::seed_from_u64(seed))
    }

    fn random_from_rng<R: Rng>(rng: &mut R) -> Enigma {
        let rotors: String = {
            let mut rotor_pool: Vec<char> = "12345".chars().collect();
            rotor_pool.shuffle(rng);
            rotor_pool[..3].iter().collect()
        };

        // Randomize key and ring settings for the rotors.
        let mut alpha: Vec<char> = ('A'..='Z').collect();

        alpha.shuffle(rng);
        let key: String = alpha[..3].iter().collect();

        alpha.shuffle(rng);
        let ring: String = alpha[..3].iter().collect();

        // Pick random plugs to fill plugboard with.
        let mut plug_pool = alpha.clone();
        plug_pool.shuffle(rng);
        let plugboard = plug_pool
            .chunks(2)
            .take(rng.gen_range(0..=MAX_PLUGS))
            .map(|chrs| chrs.iter().collect::<String>())
            .join(" ");

        Enigma::new(&rotors, &key, &ring, 'B', &plugboard)
    }

    /// Encrypts an entire message, advancing the rotors of the machine
    /// after each alphabetic character is encrypted.
    ///
    /// # Examples
    ///
    /// ```
    /// use ultra::Enigma;
    ///
    /// let mut enigma = Enigma::new("123", "ABC", "DEF", 'B', "PY");
    /// assert_eq!(enigma.encrypt("ENIGMA"), "HKAJWW");
    /// ```
    pub fn encrypt(&mut self, msg: &str) -> String {
        msg.chars().map(|c| self.encrypt_char(c)).collect()
    }

    /// Advances the rotors then returns the substitution of
    /// a character, if the input character was alphabetic.
    fn encrypt_char(&mut self, c: char) -> char {
        if !c.is_ascii() || !c.is_alphabetic() {
            return c;
        }

        self.advance();
        self.substitute(c.to_ascii_uppercase())
    }

    /// Returns the substitution of a character, which is determined by
    /// passing the character in sequence through the plugboard, the rotors
    /// from `fast` to `slow`, through the reflector, inverted through the
    /// rotors from `slow` to `fast`, and finally through the plugboard.
    fn substitute(&self, c: char) -> char {
        let mut c = self.plugboard.map(c);
        c = self.slow.substitute(self.mid.substitute(self.fast.substitute(c)));
        c = self.reflector.reflect(c);
        c = self.fast.invert(self.mid.invert(self.slow.invert(c)));
        self.plugboard.map(c)
    }

    /// Advances the `fast` rotor, and also advances the
    /// `mid` and `slow` rotors if appropriate.
    fn advance(&mut self) {
        // Check for double-rotation situation
        if self.mid.at_notch() {
            self.mid.advance();
            self.slow.advance();
        } else if self.fast.at_notch() {
            self.mid.advance();
        }

        // Finally, advance the fast rotor
        self.fast.advance();
    }

    /// Resets the `Enigma` to its initial state.
    ///
    /// # Examples
    ///
    /// ```
    /// use ultra::Enigma;
    ///
    /// let msg = "THIS IS A TEST";
    ///
    /// let mut enigma = Enigma::random();
    /// let ciphertext_1 = enigma.encrypt(msg);
    /// let ciphertext_2 = enigma.encrypt(msg);
    ///
    /// enigma.reset();
    ///
    /// assert_eq!(ciphertext_1, enigma.encrypt(msg));
    /// assert!(ciphertext_1 != ciphertext_2);
    /// ```
    pub fn reset(&mut self) {
        self.slow.reset();
        self.mid.reset();
        self.fast.reset();
    }

    /// Returns a string representing the `Enigma`'s rotor list.
    ///
    /// # Examples
    ///
    /// ```
    /// use ultra::Enigma;
    ///
    /// let enigma = Enigma::new("123", "ABC", "DEF", 'B', "PY");
    /// assert_eq!(enigma.rotor_list(), "123");
    /// ```
    pub fn rotor_list(&self) -> String {
        self.rotors().map(|r| r.to_string()).collect()
    }

    /// Returns a string representing the `Enigma`'s key settings.
    ///
    /// # Examples
    ///
    /// ```
    /// use ultra::Enigma;
    ///
    /// let enigma = Enigma::new("123", "ABC", "DEF", 'B', "PY");
    /// assert_eq!(enigma.key_settings(), "ABC");
    /// ```
    pub fn key_settings(&self) -> String {
        self.rotors()
            .map(|r| ((r.key_setting as u8) + b'A') as char)
            .collect()
    }

    /// Returns a string representing the `Enigma`'s ring settings.
    ///
    /// # Examples
    ///
    /// ```
    /// use ultra::Enigma;
    ///
    /// let enigma = Enigma::new("123", "ABC", "DEF", 'B', "PY");
    /// assert_eq!(enigma.ring_settings(), "DEF");
    /// ```
    pub fn ring_settings(&self) -> String {
        self.rotors()
            .map(|r| ((r.ring_setting as u8) + b'A') as char)
            .collect()
    }

    /// Returns a string representing the `Enigma`'s plugboard.
    ///
    /// # Examples
    ///
    /// ```
    /// use ultra::Enigma;
    ///
    /// let enigma = Enigma::new("123", "ABC", "DEF", 'B', "PY");
    /// assert_eq!(enigma.plugboard(), "PY");
    /// ```
    pub fn plugboard(&self) -> String {
        self.plugboard.to_string()
    }

    /// Returns an iterator over the slow, middle, and fast rotors.
    fn rotors(&self) -> std::vec::IntoIter<Rotor> {
        vec![self.slow.clone(), self.mid.clone(), self.fast.clone()].into_iter()
    }
}

impl fmt::Display for Enigma {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Rotors: {} / Key: {} / Ring: {} / Plugs: {}",
            self.rotor_list().chars().join("-"),
            self.key_settings().chars().join("-"),
            self.ring_settings().chars().join("-"),
            self.plugboard)
    }
}

#[cfg(test)]
mod tests {
    use super::Enigma;

    #[test]
    fn symmetrical_behaviour() {
        let msg = "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG".repeat(10);

        for _ in 0..10 {
            let mut enigma = Enigma::random();
            let ciphertext = enigma.encrypt(&msg);

            enigma.reset();
            let plaintext = enigma.encrypt(&ciphertext);

            assert_eq!(plaintext, msg);
        }
    }

    #[test]
    fn identical_from_same_seed() {
        let mut enigma_1 = Enigma::random_from_u64_seed(42);
        let mut enigma_2 = Enigma::random_from_u64_seed(42);
        assert_eq!(enigma_1.encrypt("ENIGMA"), enigma_2.encrypt("ENIGMA"));
    }

    #[test]
    fn case_insensitive_encryption() {
        let mut enigma = Enigma::new("123", "AAA", "AAA", 'B', "");
        let ciphertext1 = enigma.encrypt("Test Message");

        enigma.reset();
        let ciphertext2 = enigma.encrypt("TEST MESSAGE");

        assert_eq!(ciphertext1, ciphertext2);
    }

    #[test]
    fn key_settings() {
        let mut enigma = Enigma::new("123", "CAT", "AAA", 'B', "");
        assert_eq!(enigma.encrypt("AAAAA"), "XLEPK");
    }

    #[test]
    fn ring_settings() {
        let mut enigma = Enigma::new("123", "AAA", "DOG", 'B', "");
        assert_eq!(enigma.encrypt("AAAAA"), "XKJZE");
    }

    #[test]
    fn repetition_period() {
        // Due to the double-rotation of the middle rotor, the Enigma
        // has a period of 26 * 25 * 26 rather the expected 26^3.
        let mut enigma = Enigma::new("123", "AAA", "AAA", 'B', "");

        for _ in 0..(26 * 25 * 26) {
            enigma.advance();
        }

        assert_eq!(enigma.slow.offset, 0);
        assert_eq!(enigma.mid.offset, 0);
        assert_eq!(enigma.fast.offset, 0);
    }

    #[test]
    #[should_panic]
    fn invalid_rotor_count() {
        Enigma::new("12", "AAA", "AAA", 'B', "");
    }
}
<|endoftext|>


<commit_before>pub use transform::Transform;

/// An entity is anything that has spatial properties (i.e. a `Transform`).
#[derive(Debug)]
pub struct Entity<T> {
  pub object: T,
  pub transform: Transform
}

impl<T> Entity<T> {
  pub fn new(object: T, transform: Transform) -> Self {
    Entity {
      object: object,
      transform: transform
    }
  }
}
<commit_msg>Default entities if T: Default.<commit_after>use std::default::Default;

pub use transform::Transform;

/// An entity is anything that has spatial properties (i.e. a `Transform`).
#[derive(Debug)]
pub struct Entity<T> {
  pub object: T,
  pub transform: Transform
}

impl<T> Entity<T> {
  pub fn new(object: T, transform: Transform) -> Self {
    Entity {
      object: object,
      transform: transform
    }
  }
}

impl<T> Default for Entity<T> where T: Default {
  fn default() -> Self {
    Self::new(T::default(), Transform::default())
  }
}
<|endoftext|>