<commit_before>/// Macro for implementing `Entrypoint` or `DecodedEntryPoint` boilerplate in an algorithm
///
/// Algorithmia support for Rust algorithms is hard-coded to call `Algo::apply(AlgoInput)`
///   but for the sake of convenience the `EntryPoint` trait provides a default implementation
///   of `apply` that delegates to `apply_str`, `apply_bytes`, or `apply_json` depending on
///   the variant of `AlgoInput`. The `DecodedEntryPoint` trait overrides the default `apply`
///   to provide a method that uses a deserialized associated type when calling `apply_decoded`.
///   This pattern is incredibly flexible, but adds boilerplate and still requires
///   converting output and error types back.
///
/// The `algo_entrypoint!` macro hides all that boilerplate code behind a single macro invocation.
///   `algo_entrypoint(type => your_fn)` wires up the boilerplate for calling `your_fn(type)`.
///   Additionally, you can use the macro as `algo_entrypoint(type)` which is equivalent to
///   `algo_entrypoint!(type => apply)`.
///
/// Use the following types:
///
/// - `&str` if your algorithm accepts text input
/// - `&[u8]` if your algorithm accepts binary input
/// - Any deserializeable type if your algorithm accepts JSON input
/// - `&Value` is you want your algorithm to work directly with the typed JSON input
/// - `AlgoInput` if you want to work with the full enum of possible input types
///
/// In all cases, the return value of `your_fn` should be `Result<T, E>` where:
///
/// - `T` implements `Into<AlgoOutput>` which includes `String`, `Vec<u8>`, `Value`, and boxed* serializeable types
/// - `E` implements `Into<Box<::std::error::Error>>` which includes `String` and all `Error` types
///
/// ** support for unboxed serializeable depends on specialization implemented behind the 'nightly' feature.*
///
/// # Examples
///
/// ## Text Input/Output
/// To set the entrypoint to a function that receives and returns text:
///
/// ```no_run
/// # #[macro_use] extern crate algorithmia;
/// # fn main() {}
/// # use algorithmia::prelude::*;
/// algo_entrypoint!(&str);
///
/// fn apply(input: &str) -> Result<String, String> {
///     unimplemented!()
/// }
/// ```
///
/// which generates:
///
/// ```ignore
/// #[derive(Default)]
/// pub struct Algo;
///
/// impl EntryPoint for Algo {
///     fn apply_str(&self, input: &str) -> Result<AlgoOutput, Box<::std::error::Error>> {
///         apply(input).map(AlgoOutput::from).map_err(|err| err.into())
///     }
/// }
///
/// fn apply(input: &str) -> Result<String, String> {
///     unimplemented!()
/// }
/// ```
///
/// ## Binary Input/Output
/// To set the entrypoint to a function that receives and returns binary data:
///
/// ```no_run
/// # #[macro_use] extern crate algorithmia;
/// # fn main() {}
/// # use algorithmia::prelude::*;
/// algo_entrypoint!(&[u8]);
///
/// fn apply(input: &[u8]) -> Result<Vec<u8>, String> {
///     unimplemented!()
/// }
/// ```
///
/// ## JSON Input/Output
/// To set the entrypoint to a function that receives and returns JSON data,
///   you can work directly with the `Value`:
///
/// ```no_run
/// # #[macro_use] extern crate algorithmia;
/// # fn main() {}
/// # use algorithmia::prelude::*;
/// algo_entrypoint!(&Value);
///
/// fn apply(input: &Value) -> Result<Value, String> {
///     unimplemented!()
/// }
/// ```
///
/// Although, often the preferred way to work with JSON is to automatically
///   deserialize into and serialize from a custom type.
///
/// ```ignore
/// # #[macro_use] extern crate algorithmia;
/// # fn main() {}
/// # use algorithmia::prelude::*;
/// #[derive(Deserialize)]
/// pub struct MyInput { corpus: String, msg: String }
///
/// #[derive(Serialize)]
/// pub struct MyOutput { probabilities: Vec<(String, f32)> }
///
/// algo_entrypoint!(MyInput);
///
/// fn apply(input: MyInput) -> Result<Box<MyOutput>, String> {
///     unimplemented!()
/// }
/// ```
///
/// Note: `Box` for serializeable output is currently required for lack of specialization.
///   The specialization implementation already exists behind the `nightly` feature.
///   Alternatively, you can return `AlgoOutput` via `AlgoOutput::from(&myOutput)`
///
/// The previous example expands into:
///
/// ```ignore
/// #[derive(Deserialize)]
/// pub struct MyInput { corpus: String, msg: String };
///
/// #[derive(Serialize)]
/// pub struct MyOutput { probabilities: Vec<(String, f32)> };
///
/// #[derive(Default)]
/// pub struct Algo;
///
/// impl DecodedEntryPoint for Algo {
///     type Input (String, String);
///     fn apply_decoded(&self, input: MyInput) -> Result<AlgoOutput, Box<::std::error::Error>> {
///         apply(input).map(AlgoOutput::from).map_err(|err| err.into())
///     }
/// }
///
/// fn apply(input: MyInput) -> Result<Box<MyOutput>, String> {
///     unimplemented!()
/// }
/// ```
///
/// ## Customizing `Default`
/// And finally, it is possible to provide a custom `Default` implementation
///   and pass that state into your method by prefixing `your_fn` with
///   the `Algo::` namespace.
///
/// ```no_run
/// # #[macro_use] extern crate algorithmia;
/// # fn main() {}
/// # use algorithmia::prelude::*;
/// pub struct Algo{ init_id: String }
///
/// algo_entrypoint!(&str => Algo::hello_text);
///
/// impl Algo {
///     fn hello_text(&self, input: &str) -> Result<String, String> {
///         unimplemented!()
///     }
/// }
///
/// impl Default for Algo {
///     fn default() -> Algo {
///         Algo { init_id: "foo".into() }
///     }
/// }
/// ```
#[macro_export]
macro_rules! algo_entrypoint {
    // Helpers for recursively implementing text/bytes/Value/AlgoInput
    ($t:ty, $apply:ident, Algo::$method:ident) => {
        impl EntryPoint for Algo {
            fn $apply(&self, input: $t) -> ::std::result::Result<AlgoOutput, Box<::std::error::Error>> {
                self.$method(input).map(AlgoOutput::from).map_err(|err| err.into())
            }
        }
    };
    ($t:ty, $apply:ident, $p:path) => {
        #[derive(Default)] pub struct Algo;
        impl EntryPoint for Algo {
            fn $apply(&self, input: $t) -> ::std::result::Result<AlgoOutput, Box<::std::error::Error>> {
                $p(input).map(AlgoOutput::from).map_err(|err| err.into())
            }
        }
    };
    // Implement short-hand variants using free apply function
    (&str) => {
        algo_entrypoint!(&str => apply);
    };
    (&[u8]) => {
        algo_entrypoint!(&[u8] => apply);
    };
    (&Value) => {
        algo_entrypoint!(&Value => apply);
    };
    (AlgoInput) => {
        algo_entrypoint!(AlgoInput => apply);
    };
    ($t:ty) => {
        algo_entrypoint!($t => apply);
    };

    // Implement EntryPoint to call methods on `Algo`
    (&str => Algo::$i:ident) => {
        algo_entrypoint!(&str, apply_str, Algo::$i);
    };
    (&[u8] => Algo::$i:ident) => {
        algo_entrypoint!(&[u8], apply_bytes, Algo::$i);
    };
    (&Value => Algo::$i:ident) => {
        algo_entrypoint!(&Value, apply_json, Algo::$i);
    };
    (AlgoInput => Algo::$i:ident) => {
        algo_entrypoint!(AlgoInput, apply, Algo::$i);
    };
    ($t:ty => Algo::$i:ident) => {
        impl DecodedEntryPoint for Algo {
            type Input = $t;
            fn apply_decoded(&self, input: $t) -> ::std::result::Result<AlgoOutput, Box<::std::error::Error>> {
                self.$i(input).map(AlgoOutput::from).map_err(|err| err.into())
            }
        }
    };

    // Implement EntryPoint to call free functions
    (&str => $p:path) => {
        algo_entrypoint!(&str, apply_str, $p);
    };
    (&[u8] => $p:path) => {
        algo_entrypoint!(&[u8], apply_bytes, $p);
    };
    (&Value => $p:path) => {
        algo_entrypoint!(&Value, apply_json, $p);
    };
    (AlgoInput => $p:path) => {
        algo_entrypoint!(AlgoInput, apply, $p);
    };

    ($t:ty => $p:path) => {
        #[derive(Default)] pub struct Algo;
        impl DecodedEntryPoint for Algo {
            type Input = $t;
            fn apply_decoded(&self, input: $t) -> ::std::result::Result<AlgoOutput, Box<::std::error::Error>> {
                $p(input).map(AlgoOutput::from).map_err(|err| err.into())
            }
        }
    };
}

// Testing all the variants with unused code
mod test_str {
    use prelude::*;
    algo_entrypoint!(&str => hello_text);
    fn hello_text(_input: &str) -> Result<String, String> {
        unimplemented!()
    }
}

mod test_bytes {
    use prelude::*;
    algo_entrypoint!(&[u8] => hello_bytes);
    fn hello_bytes(_input: &[u8]) -> Result<Vec<u8>, String> {
        unimplemented!()
    }
}

mod test_json {
    use prelude::*;
    algo_entrypoint!(&Value => hello_json);
    fn hello_json(_input: &Value) -> Result<Value, String> {
        unimplemented!()
    }
}

mod test_enum {
    use prelude::*;
    algo_entrypoint!(AlgoInput => hello_enum);
    fn hello_enum(_input: AlgoInput) -> Result<AlgoOutput, String> {
        unimplemented!()
    }
}

mod test_decode {
    use prelude::*;

    #[derive(Deserialize, Serialize)]
    pub struct Custom {
        foo: String,
        bar: Vec<u32>,
        baz: bool,
    }
    algo_entrypoint!(Custom => hello_decoded);
    fn hello_decoded(_input: Custom) -> Result<Box<Custom>, String> {
        unimplemented!()
    }
}

mod test_decode_with_default {
    use prelude::*;

    pub struct Algo { _magic: u32 }

    #[derive(Deserialize, Serialize)]
    pub struct Custom {
        foo: String,
        bar: Vec<u32>,
        baz: bool,
    }
    algo_entrypoint!(Custom => Algo::hello_decoded);
    impl Algo {
        fn hello_decoded(&self, _input: Custom) -> Result<Box<Custom>, String> {
            unimplemented!()
        }
    }

    impl Default for Algo {
        fn default() -> Self {
            Algo { _magic: 42 }
        }
    }
}

mod test_shorthand_str {
    use prelude::*;
    algo_entrypoint!(&str => apply);
    fn apply(_input: &str) -> Result<String, String> {
        unimplemented!()
    }
}

mod test_shorthand_bytes {
    use prelude::*;
    algo_entrypoint!(&[u8]);
    fn apply(_input: &[u8]) -> Result<Vec<u8>, String> {
        unimplemented!()
    }
}

mod test_shorthand_json {
    use prelude::*;
    algo_entrypoint!(&Value);
    fn apply(_input: &Value) -> Result<Value, String> {
        unimplemented!()
    }
}

mod test_shorthand_enum {
    use prelude::*;
    algo_entrypoint!(AlgoInput);
    fn apply(_input: AlgoInput) -> Result<AlgoOutput, String> {
        unimplemented!()
    }
}

mod test_shorthand_decode {
    use prelude::*;

    #[derive(Deserialize, Serialize)]
    pub struct Custom {
        foo: String,
        bar: Vec<u32>,
        baz: bool,
    }
    algo_entrypoint!(Custom);
    fn apply(_input: Custom) -> Result<Box<Custom>, String> {
        unimplemented!()
    }
}
<commit_msg>Test specialization with algo_entrypoint<commit_after>/// Macro for implementing `Entrypoint` or `DecodedEntryPoint` boilerplate in an algorithm
///
/// Algorithmia support for Rust algorithms is hard-coded to call `Algo::apply(AlgoInput)`
///   but for the sake of convenience the `EntryPoint` trait provides a default implementation
///   of `apply` that delegates to `apply_str`, `apply_bytes`, or `apply_json` depending on
///   the variant of `AlgoInput`. The `DecodedEntryPoint` trait overrides the default `apply`
///   to provide a method that uses a deserialized associated type when calling `apply_decoded`.
///   This pattern is incredibly flexible, but adds boilerplate and still requires
///   converting output and error types back.
///
/// The `algo_entrypoint!` macro hides all that boilerplate code behind a single macro invocation.
///   `algo_entrypoint(type => your_fn)` wires up the boilerplate for calling `your_fn(type)`.
///   Additionally, you can use the macro as `algo_entrypoint(type)` which is equivalent to
///   `algo_entrypoint!(type => apply)`.
///
/// Use the following types:
///
/// - `&str` if your algorithm accepts text input
/// - `&[u8]` if your algorithm accepts binary input
/// - Any deserializeable type if your algorithm accepts JSON input
/// - `&Value` is you want your algorithm to work directly with the typed JSON input
/// - `AlgoInput` if you want to work with the full enum of possible input types
///
/// In all cases, the return value of `your_fn` should be `Result<T, E>` where:
///
/// - `T` implements `Into<AlgoOutput>` which includes `String`, `Vec<u8>`, `Value`, and boxed* serializeable types
/// - `E` implements `Into<Box<::std::error::Error>>` which includes `String` and all `Error` types
///
/// ** support for unboxed serializeable depends on specialization implemented behind the 'nightly' feature.*
///
/// # Examples
///
/// ## Text Input/Output
/// To set the entrypoint to a function that receives and returns text:
///
/// ```no_run
/// # #[macro_use] extern crate algorithmia;
/// # fn main() {}
/// # use algorithmia::prelude::*;
/// algo_entrypoint!(&str);
///
/// fn apply(input: &str) -> Result<String, String> {
///     unimplemented!()
/// }
/// ```
///
/// which generates:
///
/// ```ignore
/// #[derive(Default)]
/// pub struct Algo;
///
/// impl EntryPoint for Algo {
///     fn apply_str(&self, input: &str) -> Result<AlgoOutput, Box<::std::error::Error>> {
///         apply(input).map(AlgoOutput::from).map_err(|err| err.into())
///     }
/// }
///
/// fn apply(input: &str) -> Result<String, String> {
///     unimplemented!()
/// }
/// ```
///
/// ## Binary Input/Output
/// To set the entrypoint to a function that receives and returns binary data:
///
/// ```no_run
/// # #[macro_use] extern crate algorithmia;
/// # fn main() {}
/// # use algorithmia::prelude::*;
/// algo_entrypoint!(&[u8]);
///
/// fn apply(input: &[u8]) -> Result<Vec<u8>, String> {
///     unimplemented!()
/// }
/// ```
///
/// ## JSON Input/Output
/// To set the entrypoint to a function that receives and returns JSON data,
///   you can work directly with the `Value`:
///
/// ```no_run
/// # #[macro_use] extern crate algorithmia;
/// # fn main() {}
/// # use algorithmia::prelude::*;
/// algo_entrypoint!(&Value);
///
/// fn apply(input: &Value) -> Result<Value, String> {
///     unimplemented!()
/// }
/// ```
///
/// Although, often the preferred way to work with JSON is to automatically
///   deserialize into and serialize from a custom type.
///
/// ```ignore
/// # #[macro_use] extern crate algorithmia;
/// # fn main() {}
/// # use algorithmia::prelude::*;
/// #[derive(Deserialize)]
/// pub struct MyInput { corpus: String, msg: String }
///
/// #[derive(Serialize)]
/// pub struct MyOutput { probabilities: Vec<(String, f32)> }
///
/// algo_entrypoint!(MyInput);
///
/// fn apply(input: MyInput) -> Result<Box<MyOutput>, String> {
///     unimplemented!()
/// }
/// ```
///
/// Note: `Box` for serializeable output is currently required for lack of specialization.
///   The specialization implementation already exists behind the `nightly` feature.
///   Alternatively, you can return `AlgoOutput` via `AlgoOutput::from(&myOutput)`
///
/// The previous example expands into:
///
/// ```ignore
/// #[derive(Deserialize)]
/// pub struct MyInput { corpus: String, msg: String };
///
/// #[derive(Serialize)]
/// pub struct MyOutput { probabilities: Vec<(String, f32)> };
///
/// #[derive(Default)]
/// pub struct Algo;
///
/// impl DecodedEntryPoint for Algo {
///     type Input (String, String);
///     fn apply_decoded(&self, input: MyInput) -> Result<AlgoOutput, Box<::std::error::Error>> {
///         apply(input).map(AlgoOutput::from).map_err(|err| err.into())
///     }
/// }
///
/// fn apply(input: MyInput) -> Result<Box<MyOutput>, String> {
///     unimplemented!()
/// }
/// ```
///
/// ## Customizing `Default`
/// And finally, it is possible to provide a custom `Default` implementation
///   and pass that state into your method by prefixing `your_fn` with
///   the `Algo::` namespace.
///
/// ```no_run
/// # #[macro_use] extern crate algorithmia;
/// # fn main() {}
/// # use algorithmia::prelude::*;
/// pub struct Algo{ init_id: String }
///
/// algo_entrypoint!(&str => Algo::hello_text);
///
/// impl Algo {
///     fn hello_text(&self, input: &str) -> Result<String, String> {
///         unimplemented!()
///     }
/// }
///
/// impl Default for Algo {
///     fn default() -> Algo {
///         Algo { init_id: "foo".into() }
///     }
/// }
/// ```
#[macro_export]
macro_rules! algo_entrypoint {
    // Helpers for recursively implementing text/bytes/Value/AlgoInput
    ($t:ty, $apply:ident, Algo::$method:ident) => {
        impl EntryPoint for Algo {
            fn $apply(&self, input: $t) -> ::std::result::Result<AlgoOutput, Box<::std::error::Error>> {
                self.$method(input).map(AlgoOutput::from).map_err(|err| err.into())
            }
        }
    };
    ($t:ty, $apply:ident, $p:path) => {
        #[derive(Default)] pub struct Algo;
        impl EntryPoint for Algo {
            fn $apply(&self, input: $t) -> ::std::result::Result<AlgoOutput, Box<::std::error::Error>> {
                $p(input).map(AlgoOutput::from).map_err(|err| err.into())
            }
        }
    };
    // Implement short-hand variants using free apply function
    (&str) => {
        algo_entrypoint!(&str => apply);
    };
    (&[u8]) => {
        algo_entrypoint!(&[u8] => apply);
    };
    (&Value) => {
        algo_entrypoint!(&Value => apply);
    };
    (AlgoInput) => {
        algo_entrypoint!(AlgoInput => apply);
    };
    ($t:ty) => {
        algo_entrypoint!($t => apply);
    };

    // Implement EntryPoint to call methods on `Algo`
    (&str => Algo::$i:ident) => {
        algo_entrypoint!(&str, apply_str, Algo::$i);
    };
    (&[u8] => Algo::$i:ident) => {
        algo_entrypoint!(&[u8], apply_bytes, Algo::$i);
    };
    (&Value => Algo::$i:ident) => {
        algo_entrypoint!(&Value, apply_json, Algo::$i);
    };
    (AlgoInput => Algo::$i:ident) => {
        algo_entrypoint!(AlgoInput, apply, Algo::$i);
    };
    ($t:ty => Algo::$i:ident) => {
        impl DecodedEntryPoint for Algo {
            type Input = $t;
            fn apply_decoded(&self, input: $t) -> ::std::result::Result<AlgoOutput, Box<::std::error::Error>> {
                self.$i(input).map(AlgoOutput::from).map_err(|err| err.into())
            }
        }
    };

    // Implement EntryPoint to call free functions
    (&str => $p:path) => {
        algo_entrypoint!(&str, apply_str, $p);
    };
    (&[u8] => $p:path) => {
        algo_entrypoint!(&[u8], apply_bytes, $p);
    };
    (&Value => $p:path) => {
        algo_entrypoint!(&Value, apply_json, $p);
    };
    (AlgoInput => $p:path) => {
        algo_entrypoint!(AlgoInput, apply, $p);
    };

    ($t:ty => $p:path) => {
        #[derive(Default)] pub struct Algo;
        impl DecodedEntryPoint for Algo {
            type Input = $t;
            fn apply_decoded(&self, input: $t) -> ::std::result::Result<AlgoOutput, Box<::std::error::Error>> {
                $p(input).map(AlgoOutput::from).map_err(|err| err.into())
            }
        }
    };
}

// Testing all the variants with unused code
mod test_str {
    use prelude::*;
    algo_entrypoint!(&str => hello_text);
    fn hello_text(_input: &str) -> Result<String, String> {
        unimplemented!()
    }
}

mod test_bytes {
    use prelude::*;
    algo_entrypoint!(&[u8] => hello_bytes);
    fn hello_bytes(_input: &[u8]) -> Result<Vec<u8>, String> {
        unimplemented!()
    }
}

mod test_json {
    use prelude::*;
    algo_entrypoint!(&Value => hello_json);
    fn hello_json(_input: &Value) -> Result<Value, String> {
        unimplemented!()
    }
}

mod test_enum {
    use prelude::*;
    algo_entrypoint!(AlgoInput => hello_enum);
    fn hello_enum(_input: AlgoInput) -> Result<AlgoOutput, String> {
        unimplemented!()
    }
}

mod test_decode {
    use prelude::*;

    #[derive(Deserialize, Serialize)]
    pub struct Custom {
        foo: String,
        bar: Vec<u32>,
        baz: bool,
    }
    algo_entrypoint!(Custom => hello_decoded);
    fn hello_decoded(_input: Custom) -> Result<Box<Custom>, String> {
        unimplemented!()
    }
}

#[cfg(feature="nightly")]
mod test_decode_specialized {
    use prelude::*;

    #[derive(Deserialize, Serialize)]
    pub struct Custom {
        foo: String,
        bar: Vec<u32>,
        baz: bool,
    }
    algo_entrypoint!(Custom => hello_decoded);
    fn hello_decoded(_input: Custom) -> Result<Custom, String> {
        unimplemented!()
    }
}

mod test_decode_with_default {
    use prelude::*;

    pub struct Algo { _magic: u32 }

    #[derive(Deserialize, Serialize)]
    pub struct Custom {
        foo: String,
        bar: Vec<u32>,
        baz: bool,
    }
    algo_entrypoint!(Custom => Algo::hello_decoded);
    impl Algo {
        fn hello_decoded(&self, _input: Custom) -> Result<Box<Custom>, String> {
            unimplemented!()
        }
    }

    impl Default for Algo {
        fn default() -> Self {
            Algo { _magic: 42 }
        }
    }
}

mod test_shorthand_str {
    use prelude::*;
    algo_entrypoint!(&str => apply);
    fn apply(_input: &str) -> Result<String, String> {
        unimplemented!()
    }
}

mod test_shorthand_bytes {
    use prelude::*;
    algo_entrypoint!(&[u8]);
    fn apply(_input: &[u8]) -> Result<Vec<u8>, String> {
        unimplemented!()
    }
}

mod test_shorthand_json {
    use prelude::*;
    algo_entrypoint!(&Value);
    fn apply(_input: &Value) -> Result<Value, String> {
        unimplemented!()
    }
}

mod test_shorthand_enum {
    use prelude::*;
    algo_entrypoint!(AlgoInput);
    fn apply(_input: AlgoInput) -> Result<AlgoOutput, String> {
        unimplemented!()
    }
}

mod test_shorthand_decode {
    use prelude::*;

    #[derive(Deserialize, Serialize)]
    pub struct Custom {
        foo: String,
        bar: Vec<u32>,
        baz: bool,
    }
    algo_entrypoint!(Custom);
    fn apply(_input: Custom) -> Result<Box<Custom>, String> {
        unimplemented!()
    }
}

#[cfg(feature="nightly")]
mod test_shorthand_decode_specialized {
    use prelude::*;

    #[derive(Deserialize, Serialize)]
    pub struct Custom {
        foo: String,
        bar: Vec<u32>,
        baz: bool,
    }
    algo_entrypoint!(Custom);
    fn apply(_input: Custom) -> Result<Custom, String> {
        unimplemented!()
    }
}
<|endoftext|>


<commit_before>use std::thread::AccessError;

use super::action::Action;
use super::game_state::GameState;

pub trait Agent {
    fn act(&self, game_state: &GameState) -> Action;
}

pub struct FoldingAgent {}

impl Agent for FoldingAgent {
    fn act(&self, game_state: &GameState) -> Action {
        if game_state.player_active.count_ones(..) == game_state.num_players {
            Action::Fold
        } else {
            Action::Check
        }
    }
}
<commit_msg>Clean up unused code<commit_after>use super::action::Action;
use super::game_state::GameState;

pub trait Agent {
    fn act(&self, game_state: &GameState) -> Action;
}

pub struct FoldingAgent {}

impl Agent for FoldingAgent {
    fn act(&self, game_state: &GameState) -> Action {
        if game_state.player_active.count_ones(..) == game_state.num_players {
            Action::Fold
        } else {
            Action::Check
        }
    }
}
<|endoftext|>


<commit_before>/* automatically generated by rust-bindgen */

use bindgen::{glutCreateWindow, glutDestroyWindow, glutDisplayFunc, glutGetWindow, glutInit};
use bindgen::{glutInitDisplayMode, glutPostRedisplay, glutReshapeFunc, glutReshapeWindow};
use bindgen::{glutSetWindow, glutSwapBuffers, glutTimerFunc};
use libc::*;
use dvec::DVec;
use ptr::{addr_of, null};
use str::to_bytes;
use task::local_data::{local_data_get, local_data_set};
use cast::reinterpret_cast;
use vec::raw::to_ptr;

/* FIXME: global variable glutStrokeRoman */

/* FIXME: global variable glutStrokeMonoRoman */

/* FIXME: global variable glutBitmap9By15 */

/* FIXME: global variable glutBitmap8By13 */

/* FIXME: global variable glutBitmapTimesRoman10 */

/* FIXME: global variable glutBitmapTimesRoman24 */

/* FIXME: global variable glutBitmapHelvetica10 */

/* FIXME: global variable glutBitmapHelvetica12 */

/* FIXME: global variable glutBitmapHelvetica18 */

type GLenum = i32;
type GLint = i32;
type GLfloat = f32;
type GLdouble = f64;

enum Window = c_int;

const DOUBLE: c_uint = 2 as c_uint;

fn destroy<T>(-_value: ~[T]) {
    // let it drop
}

fn init() unsafe {
    let argc = 0 as c_int;
    let command = to_bytes(~"glut");
    let argv: (*u8, *u8) = (to_ptr(command), null());
    let argv_p = reinterpret_cast(&addr_of(argv));

    glutInit(addr_of(argc), argv_p);

    destroy(command);
}

fn create_window(name: ~str) -> Window unsafe {
    let bytes = to_bytes(name);
    return Window(glutCreateWindow(to_ptr(bytes) as *c_char));
}

fn destroy_window(window: Window) unsafe {
    glutDestroyWindow(*window);
}

fn reshape_window(window: Window, width: c_int, height: c_int) unsafe {
    let current_window = glutGetWindow();
    glutSetWindow(*window);
    glutReshapeWindow(width, height);
    glutSetWindow(current_window);
}

fn display_callback_tls_key(+_callback: @fn@()) {
    // Empty.
}

extern fn display_callback() unsafe {
    let callback = local_data_get(display_callback_tls_key).get();
    (*callback)();
}

fn display_func(callback: fn@()) unsafe {
    local_data_set(display_callback_tls_key, @callback);
    glutDisplayFunc(display_callback);
}

fn timer_callback_tls_key(+_callback: @DVec<fn@()>) {
    // Empty.
}

extern fn timer_callback(index: int) unsafe {
    let callbacks = local_data_get(timer_callback_tls_key).get();
    ((*callbacks)[index as uint])();
}

fn timer_func(msecs: u32, callback: fn@()) unsafe {
    let callbacks;
    match local_data_get(timer_callback_tls_key) {
        None => {
            callbacks = @DVec();
            local_data_set(timer_callback_tls_key, copy callbacks);
        }
        Some(existing_callbacks) => {
            callbacks = existing_callbacks;
        }
    }

    callbacks.push(callback);
    let index = (callbacks.len() - 1) as c_int;
    glutTimerFunc(msecs, timer_callback, index);
}

fn reshape_callback_tls_key(+_callback: @fn@(x: ++c_int, y: ++c_int)) {
    // Empty.
}

extern fn reshape_callback(++width: c_int, ++height: c_int) unsafe {
    let callback = local_data_get(reshape_callback_tls_key).get();
    (*callback)(width, height);
}

fn reshape_func(_window: Window, callback: fn@(++c_int, ++c_int)) unsafe {
    local_data_set(reshape_callback_tls_key, @callback);
    glutReshapeFunc(reshape_callback);
}

#[cfg(target_os="macos")]
fn check_loop() unsafe {
    ext::glutCheckLoop();
}

#[cfg(target_os="linux")]
fn check_loop() unsafe {
    ext::glutMainLoopEvent();
}

fn init_display_mode(mode: c_uint) unsafe {
    glutInitDisplayMode(mode);
}

fn swap_buffers() unsafe {
    glutSwapBuffers();
}

fn post_redisplay() unsafe {
    glutPostRedisplay();
}

#[cfg(target_os="macos")]
#[nolink]
#[link_args="-framework GLUT"]
extern mod dummy {
}

#[cfg(target_os="linux")]
#[link_name="glut"]
extern mod dummy {
}

#[cfg(target_os="macos")]
#[nolink]
extern mod ext {
    // Mac GLUT extension.
    fn glutCheckLoop();
}

#[cfg(target_os="linux")]
#[nolink]
extern mod ext {
    // freeglut extension.
    fn glutMainLoopEvent();
}

#[nolink]
extern mod bindgen {

fn glutInit(++argcp: *c_int, ++argv: **c_char);

fn glutInitDisplayMode(++mode: c_uint);

fn glutInitDisplayString(++string: *c_char);

fn glutInitWindowPosition(++x: c_int, ++y: c_int);

fn glutInitWindowSize(++width: c_int, ++height: c_int);

fn glutMainLoop();

fn glutCreateWindow(++title: *c_char) -> c_int;

fn glutCreateSubWindow(++win: c_int, ++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int) -> c_int;

fn glutDestroyWindow(++win: c_int);

fn glutPostRedisplay();

fn glutPostWindowRedisplay(++win: c_int);

fn glutSwapBuffers();

fn glutGetWindow() -> c_int;

fn glutSetWindow(++win: c_int);

fn glutSetWindowTitle(++title: *c_char);

fn glutSetIconTitle(++title: *c_char);

fn glutPositionWindow(++x: c_int, ++y: c_int);

fn glutReshapeWindow(++width: c_int, ++height: c_int);

fn glutPopWindow();

fn glutPushWindow();

fn glutIconifyWindow();

fn glutShowWindow();

fn glutHideWindow();

fn glutFullScreen();

fn glutSetCursor(++cursor: c_int);

fn glutWarpPointer(++x: c_int, ++y: c_int);

fn glutEstablishOverlay();

fn glutRemoveOverlay();

fn glutUseLayer(++layer: GLenum);

fn glutPostOverlayRedisplay();

fn glutPostWindowOverlayRedisplay(++win: c_int);

fn glutShowOverlay();

fn glutHideOverlay();

fn glutCreateMenu(++arg1: *u8) -> c_int;

fn glutDestroyMenu(++menu: c_int);

fn glutGetMenu() -> c_int;

fn glutSetMenu(++menu: c_int);

fn glutAddMenuEntry(++label: *c_char, ++value: c_int);

fn glutAddSubMenu(++label: *c_char, ++submenu: c_int);

fn glutChangeToMenuEntry(++item: c_int, ++label: *c_char, ++value: c_int);

fn glutChangeToSubMenu(++item: c_int, ++label: *c_char, ++submenu: c_int);

fn glutRemoveMenuItem(++item: c_int);

fn glutAttachMenu(++button: c_int);

fn glutDetachMenu(++button: c_int);

fn glutDisplayFunc(++func: *u8);

fn glutReshapeFunc(++func: *u8);

fn glutKeyboardFunc(++func: *u8);

fn glutMouseFunc(++func: *u8);

fn glutMotionFunc(++func: *u8);

fn glutPassiveMotionFunc(++func: *u8);

fn glutEntryFunc(++func: *u8);

fn glutVisibilityFunc(++func: *u8);

fn glutIdleFunc(++func: *u8);

fn glutTimerFunc(++millis: c_uint, ++func: *u8, ++value: c_int);

fn glutMenuStateFunc(++func: *u8);

fn glutSpecialFunc(++func: *u8);

fn glutSpaceballMotionFunc(++func: *u8);

fn glutSpaceballRotateFunc(++func: *u8);

fn glutSpaceballButtonFunc(++func: *u8);

fn glutButtonBoxFunc(++func: *u8);

fn glutDialsFunc(++func: *u8);

fn glutTabletMotionFunc(++func: *u8);

fn glutTabletButtonFunc(++func: *u8);

fn glutMenuStatusFunc(++func: *u8);

fn glutOverlayDisplayFunc(++func: *u8);

fn glutWindowStatusFunc(++func: *u8);

fn glutKeyboardUpFunc(++func: *u8);

fn glutSpecialUpFunc(++func: *u8);

fn glutJoystickFunc(++func: *u8, ++pollInterval: c_int);

fn glutSetColor(++arg1: c_int, ++red: GLfloat, ++green: GLfloat, ++blue: GLfloat);

fn glutGetColor(++ndx: c_int, ++component: c_int) -> GLfloat;

fn glutCopyColormap(++win: c_int);

fn glutGet(++_type: GLenum) -> c_int;

fn glutDeviceGet(++_type: GLenum) -> c_int;

fn glutExtensionSupported(++name: *c_char) -> c_int;

fn glutGetModifiers() -> c_int;

fn glutLayerGet(++_type: GLenum) -> c_int;

fn glutGetProcAddress(++procName: *c_char) -> *c_void;

fn glutBitmapCharacter(++font: *c_void, ++character: c_int);

fn glutBitmapWidth(++font: *c_void, ++character: c_int) -> c_int;

fn glutStrokeCharacter(++font: *c_void, ++character: c_int);

fn glutStrokeWidth(++font: *c_void, ++character: c_int) -> c_int;

fn glutBitmapLength(++font: *c_void, ++string: *c_uchar) -> c_int;

fn glutStrokeLength(++font: *c_void, ++string: *c_uchar) -> c_int;

fn glutWireSphere(++radius: GLdouble, ++slices: GLint, ++stacks: GLint);

fn glutSolidSphere(++radius: GLdouble, ++slices: GLint, ++stacks: GLint);

fn glutWireCone(++base: GLdouble, ++height: GLdouble, ++slices: GLint, ++stacks: GLint);

fn glutSolidCone(++base: GLdouble, ++height: GLdouble, ++slices: GLint, ++stacks: GLint);

fn glutWireCube(++size: GLdouble);

fn glutSolidCube(++size: GLdouble);

fn glutWireTorus(++innerRadius: GLdouble, ++outerRadius: GLdouble, ++sides: GLint, ++rings: GLint);

fn glutSolidTorus(++innerRadius: GLdouble, ++outerRadius: GLdouble, ++sides: GLint, ++rings: GLint);

fn glutWireDodecahedron();

fn glutSolidDodecahedron();

fn glutWireTeapot(++size: GLdouble);

fn glutSolidTeapot(++size: GLdouble);

fn glutWireOctahedron();

fn glutSolidOctahedron();

fn glutWireTetrahedron();

fn glutSolidTetrahedron();

fn glutWireIcosahedron();

fn glutSolidIcosahedron();

fn glutVideoResizeGet(++param: GLenum) -> c_int;

fn glutSetupVideoResizing();

fn glutStopVideoResizing();

fn glutVideoResize(++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int);

fn glutVideoPan(++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int);

fn glutReportErrors();

fn glutIgnoreKeyRepeat(++ignore: c_int);

fn glutSetKeyRepeat(++repeatMode: c_int);

fn glutForceJoystickFunc();

fn glutGameModeString(++string: *c_char);

fn glutEnterGameMode() -> c_int;

fn glutLeaveGameMode();

fn glutGameModeGet(++mode: GLenum) -> c_int;

}
<commit_msg>Fix updates for language changes<commit_after>/* automatically generated by rust-bindgen */

use bindgen::{glutCreateWindow, glutDestroyWindow, glutDisplayFunc, glutGetWindow, glutInit};
use bindgen::{glutInitDisplayMode, glutPostRedisplay, glutReshapeFunc, glutReshapeWindow};
use bindgen::{glutSetWindow, glutSwapBuffers, glutTimerFunc};
use libc::*;
use dvec::DVec;
use ptr::{addr_of, null};
use str::to_bytes;
use task::local_data::{local_data_get, local_data_set};
use cast::reinterpret_cast;
use vec::raw::to_ptr;

/* FIXME: global variable glutStrokeRoman */

/* FIXME: global variable glutStrokeMonoRoman */

/* FIXME: global variable glutBitmap9By15 */

/* FIXME: global variable glutBitmap8By13 */

/* FIXME: global variable glutBitmapTimesRoman10 */

/* FIXME: global variable glutBitmapTimesRoman24 */

/* FIXME: global variable glutBitmapHelvetica10 */

/* FIXME: global variable glutBitmapHelvetica12 */

/* FIXME: global variable glutBitmapHelvetica18 */

type GLenum = i32;
type GLint = i32;
type GLfloat = f32;
type GLdouble = f64;

enum Window = c_int;

const DOUBLE: c_uint = 2 as c_uint;

fn destroy<T>(-_value: ~[T]) {
    // let it drop
}

fn init() unsafe {
    let argc = 0 as c_int;
    let command = to_bytes(~"glut");
    let argv: (*u8, *u8) = (to_ptr(command), null());
    let argv_p = reinterpret_cast(&addr_of(argv));

    glutInit(addr_of(argc), argv_p);

    destroy(command);
}

fn create_window(name: ~str) -> Window unsafe {
    let bytes = to_bytes(name);
    return Window(glutCreateWindow(to_ptr(bytes) as *c_char));
}

fn destroy_window(window: Window) unsafe {
    glutDestroyWindow(*window);
}

fn reshape_window(window: Window, width: c_int, height: c_int) unsafe {
    let current_window = glutGetWindow();
    glutSetWindow(*window);
    glutReshapeWindow(width, height);
    glutSetWindow(current_window);
}

fn display_callback_tls_key(+_callback: @fn@()) {
    // Empty.
}

extern fn display_callback() unsafe {
    let callback = local_data_get(display_callback_tls_key).get();
    (*callback)();
}

fn display_func(callback: fn@()) unsafe {
    local_data_set(display_callback_tls_key, @callback);
    glutDisplayFunc(display_callback);
}

fn timer_callback_tls_key(+_callback: @DVec<fn@()>) {
    // Empty.
}

extern fn timer_callback(index: int) unsafe {
    let callbacks = local_data_get(timer_callback_tls_key).get();
    ((*callbacks)[index as uint])();
}

fn timer_func(msecs: u32, callback: fn@()) unsafe {
    let callbacks;
    match local_data_get(timer_callback_tls_key) {
        None => {
            callbacks = @DVec();
            local_data_set(timer_callback_tls_key, copy callbacks);
        }
        Some(existing_callbacks) => {
            callbacks = existing_callbacks;
        }
    }

    callbacks.push(callback);
    let index = (callbacks.len() - 1) as c_int;
    glutTimerFunc(msecs, timer_callback, index);
}

fn reshape_callback_tls_key(+_callback: @fn@(++x: c_int, ++y: c_int)) {
    // Empty.
}

extern fn reshape_callback(++width: c_int, ++height: c_int) unsafe {
    let callback = local_data_get(reshape_callback_tls_key).get();
    (*callback)(width, height);
}

fn reshape_func(_window: Window, callback: fn@(++x: c_int, ++y: c_int)) unsafe {
    local_data_set(reshape_callback_tls_key, @callback);
    glutReshapeFunc(reshape_callback);
}

#[cfg(target_os="macos")]
fn check_loop() unsafe {
    ext::glutCheckLoop();
}

#[cfg(target_os="linux")]
fn check_loop() unsafe {
    ext::glutMainLoopEvent();
}

fn init_display_mode(mode: c_uint) unsafe {
    glutInitDisplayMode(mode);
}

fn swap_buffers() unsafe {
    glutSwapBuffers();
}

fn post_redisplay() unsafe {
    glutPostRedisplay();
}

#[cfg(target_os="macos")]
#[nolink]
#[link_args="-framework GLUT"]
extern mod dummy {
}

#[cfg(target_os="linux")]
#[link_name="glut"]
extern mod dummy {
}

#[cfg(target_os="macos")]
#[nolink]
extern mod ext {
    // Mac GLUT extension.
    fn glutCheckLoop();
}

#[cfg(target_os="linux")]
#[nolink]
extern mod ext {
    // freeglut extension.
    fn glutMainLoopEvent();
}

#[nolink]
extern mod bindgen {

fn glutInit(++argcp: *c_int, ++argv: **c_char);

fn glutInitDisplayMode(++mode: c_uint);

fn glutInitDisplayString(++string: *c_char);

fn glutInitWindowPosition(++x: c_int, ++y: c_int);

fn glutInitWindowSize(++width: c_int, ++height: c_int);

fn glutMainLoop();

fn glutCreateWindow(++title: *c_char) -> c_int;

fn glutCreateSubWindow(++win: c_int, ++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int) -> c_int;

fn glutDestroyWindow(++win: c_int);

fn glutPostRedisplay();

fn glutPostWindowRedisplay(++win: c_int);

fn glutSwapBuffers();

fn glutGetWindow() -> c_int;

fn glutSetWindow(++win: c_int);

fn glutSetWindowTitle(++title: *c_char);

fn glutSetIconTitle(++title: *c_char);

fn glutPositionWindow(++x: c_int, ++y: c_int);

fn glutReshapeWindow(++width: c_int, ++height: c_int);

fn glutPopWindow();

fn glutPushWindow();

fn glutIconifyWindow();

fn glutShowWindow();

fn glutHideWindow();

fn glutFullScreen();

fn glutSetCursor(++cursor: c_int);

fn glutWarpPointer(++x: c_int, ++y: c_int);

fn glutEstablishOverlay();

fn glutRemoveOverlay();

fn glutUseLayer(++layer: GLenum);

fn glutPostOverlayRedisplay();

fn glutPostWindowOverlayRedisplay(++win: c_int);

fn glutShowOverlay();

fn glutHideOverlay();

fn glutCreateMenu(++arg1: *u8) -> c_int;

fn glutDestroyMenu(++menu: c_int);

fn glutGetMenu() -> c_int;

fn glutSetMenu(++menu: c_int);

fn glutAddMenuEntry(++label: *c_char, ++value: c_int);

fn glutAddSubMenu(++label: *c_char, ++submenu: c_int);

fn glutChangeToMenuEntry(++item: c_int, ++label: *c_char, ++value: c_int);

fn glutChangeToSubMenu(++item: c_int, ++label: *c_char, ++submenu: c_int);

fn glutRemoveMenuItem(++item: c_int);

fn glutAttachMenu(++button: c_int);

fn glutDetachMenu(++button: c_int);

fn glutDisplayFunc(++func: *u8);

fn glutReshapeFunc(++func: *u8);

fn glutKeyboardFunc(++func: *u8);

fn glutMouseFunc(++func: *u8);

fn glutMotionFunc(++func: *u8);

fn glutPassiveMotionFunc(++func: *u8);

fn glutEntryFunc(++func: *u8);

fn glutVisibilityFunc(++func: *u8);

fn glutIdleFunc(++func: *u8);

fn glutTimerFunc(++millis: c_uint, ++func: *u8, ++value: c_int);

fn glutMenuStateFunc(++func: *u8);

fn glutSpecialFunc(++func: *u8);

fn glutSpaceballMotionFunc(++func: *u8);

fn glutSpaceballRotateFunc(++func: *u8);

fn glutSpaceballButtonFunc(++func: *u8);

fn glutButtonBoxFunc(++func: *u8);

fn glutDialsFunc(++func: *u8);

fn glutTabletMotionFunc(++func: *u8);

fn glutTabletButtonFunc(++func: *u8);

fn glutMenuStatusFunc(++func: *u8);

fn glutOverlayDisplayFunc(++func: *u8);

fn glutWindowStatusFunc(++func: *u8);

fn glutKeyboardUpFunc(++func: *u8);

fn glutSpecialUpFunc(++func: *u8);

fn glutJoystickFunc(++func: *u8, ++pollInterval: c_int);

fn glutSetColor(++arg1: c_int, ++red: GLfloat, ++green: GLfloat, ++blue: GLfloat);

fn glutGetColor(++ndx: c_int, ++component: c_int) -> GLfloat;

fn glutCopyColormap(++win: c_int);

fn glutGet(++_type: GLenum) -> c_int;

fn glutDeviceGet(++_type: GLenum) -> c_int;

fn glutExtensionSupported(++name: *c_char) -> c_int;

fn glutGetModifiers() -> c_int;

fn glutLayerGet(++_type: GLenum) -> c_int;

fn glutGetProcAddress(++procName: *c_char) -> *c_void;

fn glutBitmapCharacter(++font: *c_void, ++character: c_int);

fn glutBitmapWidth(++font: *c_void, ++character: c_int) -> c_int;

fn glutStrokeCharacter(++font: *c_void, ++character: c_int);

fn glutStrokeWidth(++font: *c_void, ++character: c_int) -> c_int;

fn glutBitmapLength(++font: *c_void, ++string: *c_uchar) -> c_int;

fn glutStrokeLength(++font: *c_void, ++string: *c_uchar) -> c_int;

fn glutWireSphere(++radius: GLdouble, ++slices: GLint, ++stacks: GLint);

fn glutSolidSphere(++radius: GLdouble, ++slices: GLint, ++stacks: GLint);

fn glutWireCone(++base: GLdouble, ++height: GLdouble, ++slices: GLint, ++stacks: GLint);

fn glutSolidCone(++base: GLdouble, ++height: GLdouble, ++slices: GLint, ++stacks: GLint);

fn glutWireCube(++size: GLdouble);

fn glutSolidCube(++size: GLdouble);

fn glutWireTorus(++innerRadius: GLdouble, ++outerRadius: GLdouble, ++sides: GLint, ++rings: GLint);

fn glutSolidTorus(++innerRadius: GLdouble, ++outerRadius: GLdouble, ++sides: GLint, ++rings: GLint);

fn glutWireDodecahedron();

fn glutSolidDodecahedron();

fn glutWireTeapot(++size: GLdouble);

fn glutSolidTeapot(++size: GLdouble);

fn glutWireOctahedron();

fn glutSolidOctahedron();

fn glutWireTetrahedron();

fn glutSolidTetrahedron();

fn glutWireIcosahedron();

fn glutSolidIcosahedron();

fn glutVideoResizeGet(++param: GLenum) -> c_int;

fn glutSetupVideoResizing();

fn glutStopVideoResizing();

fn glutVideoResize(++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int);

fn glutVideoPan(++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int);

fn glutReportErrors();

fn glutIgnoreKeyRepeat(++ignore: c_int);

fn glutSetKeyRepeat(++repeatMode: c_int);

fn glutForceJoystickFunc();

fn glutGameModeString(++string: *c_char);

fn glutEnterGameMode() -> c_int;

fn glutLeaveGameMode();

fn glutGameModeGet(++mode: GLenum) -> c_int;

}
<|endoftext|>


<commit_before>#![crate_name = "bindgen"]
#![crate_type = "bin"]

extern crate bindgen;
extern crate env_logger;
#[macro_use]
extern crate log;
extern crate clang_sys;
extern crate clap;
extern crate rustc_serialize;

use bindgen::clang_version;
use std::env;

mod options;
use options::builder_from_flags;

pub fn main() {
    log::set_logger(|max_log_level| {
            use env_logger::Logger;
            let env_logger = Logger::new();
            max_log_level.set(env_logger.filter());
            Box::new(env_logger)
        })
        .expect("Failed to set logger.");

    let mut bind_args: Vec<_> = env::args().collect();

    let version = clang_version();
    let expected_version = if cfg!(feature = "llvm_stable") {
        (3, 8)
    } else {
        (3, 9)
    };

    info!("Clang Version: {}", version.full);

    match version.parsed {
        None => warn!("Couldn't parse libclang version"),
        Some(version) if version != expected_version => {
            error!("Using clang {:?}, expected {:?}",
                   version,
                   expected_version);
        }
        _ => {}
    }

    if let Some(clang) = clang_sys::support::Clang::find(None) {
        let has_clang_args =
            bind_args.iter().rposition(|arg| *arg == "--").is_some();
        if !has_clang_args {
            bind_args.push("--".to_owned());
        }

        // If --target is specified, assume caller knows what they're doing and
        // don't mess with
        // include paths for them
        let has_target_arg = bind_args.iter()
            .rposition(|arg| arg.starts_with("--target"))
            .is_some();
        if !has_target_arg {
            // TODO: distinguish C and C++ paths? C++'s should be enough, I
            // guess.
            for path in clang.cpp_search_paths.into_iter() {
                if let Ok(path) = path.into_os_string().into_string() {
                    bind_args.push("-isystem".to_owned());
                    bind_args.push(path);
                }
            }
        }
    }

    match builder_from_flags(env::args()) {
        Ok((builder, output)) => {
            let mut bindings = builder.generate()
                .expect("Unable to generate bindings");
            bindings.write(output)
                .expect("Unable to write output");
            bindings.write_dummy_uses()
                .expect("Unable to write dummy uses to file.");
        }
        Err(error) => {
            println!("{}", error);
            std::process::exit(1);
        }
    };
}
<commit_msg>Fix path detection after #228<commit_after>#![crate_name = "bindgen"]
#![crate_type = "bin"]

extern crate bindgen;
extern crate env_logger;
#[macro_use]
extern crate log;
extern crate clang_sys;
extern crate clap;
extern crate rustc_serialize;

use bindgen::clang_version;
use std::env;

mod options;
use options::builder_from_flags;

pub fn main() {
    log::set_logger(|max_log_level| {
            use env_logger::Logger;
            let env_logger = Logger::new();
            max_log_level.set(env_logger.filter());
            Box::new(env_logger)
        })
        .expect("Failed to set logger.");

    let mut bind_args: Vec<_> = env::args().collect();

    let version = clang_version();
    let expected_version = if cfg!(feature = "llvm_stable") {
        (3, 8)
    } else {
        (3, 9)
    };

    info!("Clang Version: {}", version.full);

    match version.parsed {
        None => warn!("Couldn't parse libclang version"),
        Some(version) if version != expected_version => {
            error!("Using clang {:?}, expected {:?}",
                   version,
                   expected_version);
        }
        _ => {}
    }

    if let Some(clang) = clang_sys::support::Clang::find(None) {
        let has_clang_args =
            bind_args.iter().rposition(|arg| *arg == "--").is_some();
        if !has_clang_args {
            bind_args.push("--".to_owned());
        }

        // If --target is specified, assume caller knows what they're doing and
        // don't mess with
        // include paths for them
        let has_target_arg = bind_args.iter()
            .rposition(|arg| arg.starts_with("--target"))
            .is_some();
        if !has_target_arg {
            // TODO: distinguish C and C++ paths? C++'s should be enough, I
            // guess.
            for path in clang.cpp_search_paths.into_iter() {
                if let Ok(path) = path.into_os_string().into_string() {
                    bind_args.push("-isystem".to_owned());
                    bind_args.push(path);
                }
            }
        }
    }

    match builder_from_flags(bind_args.into_iter()) {
        Ok((builder, output)) => {
            let mut bindings = builder.generate()
                .expect("Unable to generate bindings");
            bindings.write(output)
                .expect("Unable to write output");
            bindings.write_dummy_uses()
                .expect("Unable to write dummy uses to file.");
        }
        Err(error) => {
            println!("{}", error);
            std::process::exit(1);
        }
    };
}
<|endoftext|>


<commit_before>extern crate rustc_serialize;
extern crate docopt;
extern crate users;

use docopt::Docopt;
use users::{Users, OSUsers};
use std::env;
use std::fs;
use std::io::{stdin, Read};
use std::os::unix::fs::PermissionsExt;
use std::path::PathBuf;

static CRONTAB_DIR: &'static str = "/var/spool/cron";
static REBOOT_FILE: &'static str = "/run/crond.reboot";

static USAGE: &'static str = r#"
Usage: crontab [-u USER] -l
       crontab [-u USER] -e [FILE]
       crontab [-u USER] -s
       crontab [-u USER] -r [-i]
       crontab -h | --help

Maintain crontab files for individual users

Options:

  -h, --help            Show this help message and exit.
  -u USER, --user USER  It specifies the name of the user whose crontab is to
                        be tweaked. If this option is not given, crontab
                        examines "your" crontab, i.e., the crontab of the
                        person executing the command. Note that su(8) can
                        confuse crontab and that if you are running inside of
                        su(8) you should always use the -u option for safety's
                        sake. The first form of this command is used to
                        install a new crontab from some named file or standard
                        input if the pseudo-filename "-" is given.
  -l, --list            The current crontab will be displayed on standard
                        output.
  -r, --remove          The current crontab will be removed.
  -e, --edit            This option is used to edit the current crontab using
                        the editor specified by the VISUAL or EDITOR
                        environment variables. After you exit from the editor,
                        the modified crontab will be installed automatically.
  -s, --show            Show all user who have a crontab.
  -i, --ask             This option modifies the -r option to prompt the user
                        for a 'y/Y' response before actually removing the
                        crontab.
"#;

#[derive(Debug, RustcDecodable)]
#[allow(non_snake_case)]
struct Args {
    arg_FILE: Option<String>,
    flag_user: Option<String>,
    flag_list: bool,
    flag_remove: bool,
    flag_edit: bool,
    flag_show: bool,
    flag_ask: bool
}

fn get_editor() -> Option<String> {
    env::var("EDITOR").ok()
        .or_else(|| env::var("VISUAL").ok())
        .or_else(|| ["/usr/bin/editor", "/usr/bin/vim", "/usr/bin/nano", "/usr/bin/mcedit"].iter()
                 .filter(|editor| fs::metadata(editor).map(|meta| meta.is_file() && meta.permissions().mode() & 0o0111 != 0).unwrap_or(false))
                 .next()
                 .map(|&s| s.to_owned()))
}

fn confirm(msg: &str) -> bool {
    let mut stdin = stdin();
    loop {
        print!("{}", msg);
        let mut buf = [0u8; 1];
        match stdin.read(&mut buf) {
            Ok(1) => return buf[0] == 121 || buf[0] == 89,
            _ => println!("Please reply \"y\" or \"n\""),
        }
    }
}

fn main() {
    let args: Args = Docopt::new(USAGE)
                            .and_then(|d| d.decode())
                            .unwrap_or_else(|e| e.exit());

    let editor = get_editor();

    match fs::metadata(CRONTAB_DIR) {
        Ok(ref meta) if meta.is_dir() => (),
        Ok(_) => return println!("{} is not a directory!", CRONTAB_DIR),
        Err(_) => if let Err(_) = fs::create_dir_all(CRONTAB_DIR) {
            return println!("{} doesn't exist!", CRONTAB_DIR);
        }
    }

    let mut users = OSUsers::empty_cache();
    let cron_file = PathBuf::from(CRONTAB_DIR).join(args.flag_user.clone().or_else(|| users.get_current_username()).unwrap());

    println!("{:?}", cron_file);
    println!("{:?}", editor);
    println!("{:?}", args);
}
<commit_msg>fix confirm function stdout & stdin caching<commit_after>extern crate rustc_serialize;
extern crate docopt;
extern crate users;

use docopt::Docopt;
use users::{Users, OSUsers};
use std::env;
use std::fs;
use std::io::{stdin, stdout, Write, Read};
use std::os::unix::fs::PermissionsExt;
use std::path::PathBuf;

static CRONTAB_DIR: &'static str = "/var/spool/cron";
static REBOOT_FILE: &'static str = "/run/crond.reboot";

static USAGE: &'static str = r#"
Usage: crontab [-u USER] -l
       crontab [-u USER] -e [FILE]
       crontab [-u USER] -s
       crontab [-u USER] -r [-i]
       crontab -h | --help

Maintain crontab files for individual users

Options:

  -h, --help            Show this help message and exit.
  -u USER, --user USER  It specifies the name of the user whose crontab is to
                        be tweaked. If this option is not given, crontab
                        examines "your" crontab, i.e., the crontab of the
                        person executing the command. Note that su(8) can
                        confuse crontab and that if you are running inside of
                        su(8) you should always use the -u option for safety's
                        sake. The first form of this command is used to
                        install a new crontab from some named file or standard
                        input if the pseudo-filename "-" is given.
  -l, --list            The current crontab will be displayed on standard
                        output.
  -r, --remove          The current crontab will be removed.
  -e, --edit            This option is used to edit the current crontab using
                        the editor specified by the VISUAL or EDITOR
                        environment variables. After you exit from the editor,
                        the modified crontab will be installed automatically.
  -s, --show            Show all user who have a crontab.
  -i, --ask             This option modifies the -r option to prompt the user
                        for a 'y/Y' response before actually removing the
                        crontab.
"#;

#[derive(Debug, RustcDecodable)]
#[allow(non_snake_case)]
struct Args {
    arg_FILE: Option<String>,
    flag_user: Option<String>,
    flag_list: bool,
    flag_remove: bool,
    flag_edit: bool,
    flag_show: bool,
    flag_ask: bool
}

fn get_editor() -> Option<String> {
    env::var("EDITOR").ok()
        .or_else(|| env::var("VISUAL").ok())
        .or_else(|| ["/usr/bin/editor", "/usr/bin/vim", "/usr/bin/nano", "/usr/bin/mcedit"].iter()
                 .filter(|editor| fs::metadata(editor).map(|meta| meta.is_file() && meta.permissions().mode() & 0o0111 != 0).unwrap_or(false))
                 .next()
                 .map(|&s| s.to_owned()))
}

fn confirm(msg: &str) -> bool {
    let mut stdin = stdin();
    let mut stdout = stdout();
    loop {
        stdout.write_all(msg.as_bytes()).unwrap();
        stdout.flush();
        let mut buf = [0u8; 1024];
        match stdin.read(&mut buf) {
            Ok(n) if n > 0 && (buf[0] == 121 || buf[0] == 89) => return true,
            Ok(n) if n > 0 && (buf[0] == 110 || buf[0] == 78) => return false,
            _ => { stdout.write_all("Please reply \"y\" or \"n\"\n".as_bytes()).unwrap(); },
        }
    }
}

fn main() {
    let args: Args = Docopt::new(USAGE)
                            .and_then(|d| d.decode())
                            .unwrap_or_else(|e| e.exit());

    let editor = get_editor();

    match fs::metadata(CRONTAB_DIR) {
        Ok(ref meta) if meta.is_dir() => (),
        Ok(_) => return println!("{} is not a directory!", CRONTAB_DIR),
        Err(_) => if let Err(_) = fs::create_dir_all(CRONTAB_DIR) {
            return println!("{} doesn't exist!", CRONTAB_DIR);
        }
    }

    let mut users = OSUsers::empty_cache();
    let cron_file = PathBuf::from(CRONTAB_DIR).join(args.flag_user.clone().or_else(|| users.get_current_username()).unwrap());

    println!("{:?}", cron_file);
    println!("{:?}", editor);
    println!("{:?}", args);
}
<|endoftext|>


<commit_before>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the
// terms of the Mozilla Public License, v.
// 2.0. If a copy of the MPL was not
// distributed with this file, You can
// obtain one at
// http://mozilla.org/MPL/2.0/.

//! Bstream module.
//! This is a blocking stream designed to block on read/write until

use std::result::Result;
use std::net::TcpStream;
use std::io::{Read, Write, Error};

use super::readbuffer::ReadBuffer;

/// Represents the result of attempting a read on the underlying file descriptor
pub type ReadResult = Result<Vec<u8>, Error>;

/// Represents the result attempting a write on the underlying fild descriptor
pub type WriteResult = Result<(), Error>;

/// States the current stream can be in
#[derive(PartialEq, Clone)]
enum ReadState {
    /// Currently reading the payload length
    PayloadLen,
    /// Currently reading the payload
    Payload
}

pub struct Bstream {
    /// Current state
    state: ReadState,
    /// Underlying std::net::TcpStream
    stream: TcpStream,
    /// Message buffer
    buffer: ReadBuffer
}

impl Bstream {

    /// Returns a new Bstream
    pub fn new(stream: TcpStream) -> Bstream {
        Bstream {
            state: ReadState::PayloadLen,
            stream: stream,
            buffer: ReadBuffer::new()
        }
    }

    /// Performs a blocking read and returns when a complete message
    /// has been returned, or an error has occured
    pub fn read(&mut self) -> ReadResult {
        loop {
            // Create a buffer for this specific read iteration
            let count = self.buffer.remaining();
            let mut buffer = Vec::<u8>::with_capacity(count as usize);
            unsafe { buffer.set_len(count as usize); }

            let result = self.stream.read(&mut buffer[..]);
            if result.is_err() {
                return Err(result.unwrap_err());
            }

            let num_read = result.unwrap();
            for x in 0..num_read {
                self.buffer.push(buffer[x]);
            }

            if self.buffer.remaining() == 0 {
                if self.state == ReadState::PayloadLen {

                    println!("Payload length read complete");
                    println!("Printing buffer...");
                    let mut index = 0;
                    for byte in self.buffer.current_buffer().iter() {
                        println!("byte {}: {}", index, byte);
                        index += 1;
                    }

                    self.buffer.calc_payload_len();
                    let p_len = self.buffer.payload_len();

                    println!("Payload length: {}", p_len);

                    self.buffer.set_capacity(p_len);
                    self.state = ReadState::Payload;
                } else { // Payload completely read

                    println!("Payload read complete");
                    println!("Printing buffer...");
                    let mut index = 0;
                    for byte in self.buffer.current_buffer().iter() {
                        println!("byte {}: {}", index, byte);
                        index += 1;
                    }

                    self.buffer.reset();
                    self.state = ReadState::PayloadLen;
                    break;
                }
            }
        }
        let mut buffer = self.buffer.drain_queue();

        // This should always be .len() of 1
        // if it isn't - we're doing some bad stuff in here
        if buffer.len() != 1 {
            panic!("Error - Bstream.read() - Internal buffer was not equal to one...?")
        }

        match buffer.pop() {
            Some(buf) => Ok(buf),
            None => unimplemented!()
        }
    }

    /// Performs a blocking write operation and returns the complete buffer has
    /// been written, or an error has occured
    pub fn write(&mut self, buffer: &Vec<u8>) -> WriteResult {
        let mut plen_buf = [0u8; 2];
        let plen = buffer.len() as u16;
        plen_buf[0] = (plen >> 8) as u8;
        plen_buf[1] = plen as u8;

        let mut n_buffer = Vec::<u8>::with_capacity(buffer.len() + 2);
        n_buffer.push(plen_buf[0]);
        n_buffer.push(plen_buf[1]);

        for x in 0..buffer.len() {
            n_buffer.push(buffer[x]);
        }

        match self.stream.write_all(&n_buffer[..]) {
            Ok(()) => {
                let _ = self.stream.flush();
                Ok(())
            }
            Err(e) => Err(e)
        }
    }
}

impl Clone for Bstream {
    fn clone(&self) -> Bstream {
        Bstream {
            state: self.state.clone(),
            stream: self.stream.try_clone().unwrap(),
            buffer: self.buffer.clone()
        }
    }
}
<commit_msg>Added shutdown method<commit_after>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the
// terms of the Mozilla Public License, v.
// 2.0. If a copy of the MPL was not
// distributed with this file, You can
// obtain one at
// http://mozilla.org/MPL/2.0/.

//! Bstream module.
//! This is a blocking stream designed to block on read/write until

use std::result::Result;
use std::net::{TcpStream, Shutdown};
use std::io::{Read, Write, Error};

use super::readbuffer::ReadBuffer;

/// Represents the result of attempting a read on the underlying file descriptor
pub type ReadResult = Result<Vec<u8>, Error>;

/// Represents the result attempting a write on the underlying fild descriptor
pub type WriteResult = Result<(), Error>;

/// States the current stream can be in
#[derive(PartialEq, Clone)]
enum ReadState {
    /// Currently reading the payload length
    PayloadLen,
    /// Currently reading the payload
    Payload
}

pub struct Bstream {
    /// Current state
    state: ReadState,
    /// Underlying std::net::TcpStream
    stream: TcpStream,
    /// Message buffer
    buffer: ReadBuffer
}

impl Bstream {

    /// Returns a new Bstream
    pub fn new(stream: TcpStream) -> Bstream {
        Bstream {
            state: ReadState::PayloadLen,
            stream: stream,
            buffer: ReadBuffer::new()
        }
    }

    /// Performs a blocking read and returns when a complete message
    /// has been returned, or an error has occured
    pub fn read(&mut self) -> ReadResult {
        loop {
            // Create a buffer for this specific read iteration
            let count = self.buffer.remaining();
            let mut buffer = Vec::<u8>::with_capacity(count as usize);
            unsafe { buffer.set_len(count as usize); }

            let result = self.stream.read(&mut buffer[..]);
            if result.is_err() {
                return Err(result.unwrap_err());
            }

            let num_read = result.unwrap();
            for x in 0..num_read {
                self.buffer.push(buffer[x]);
            }

            if self.buffer.remaining() == 0 {
                if self.state == ReadState::PayloadLen {
                    let mut index = 0;
                    for byte in self.buffer.current_buffer().iter() {
                        println!("byte {}: {}", index, byte);
                        index += 1;
                    }

                    self.buffer.calc_payload_len();
                    let p_len = self.buffer.payload_len();
                    self.buffer.set_capacity(p_len);
                    self.state = ReadState::Payload;
                } else { // Payload completely read
                    let mut index = 0;
                    for byte in self.buffer.current_buffer().iter() {
                        println!("byte {}: {}", index, byte);
                        index += 1;
                    }

                    self.buffer.reset();
                    self.state = ReadState::PayloadLen;
                    break;
                }
            }
        }
        let mut buffer = self.buffer.drain_queue();

        // This should always be .len() of 1
        // if it isn't - we're doing some bad stuff in here
        if buffer.len() != 1 {
            panic!("Error - Bstream.read() - Internal buffer was not equal to one...?")
        }

        match buffer.pop() {
            Some(buf) => Ok(buf),
            None => unimplemented!()
        }
    }

    /// Performs a blocking write operation and returns the complete buffer has
    /// been written, or an error has occured
    pub fn write(&mut self, buffer: &Vec<u8>) -> WriteResult {
        let mut plen_buf = [0u8; 2];
        let plen = buffer.len() as u16;
        plen_buf[0] = (plen >> 8) as u8;
        plen_buf[1] = plen as u8;

        let mut n_buffer = Vec::<u8>::with_capacity(buffer.len() + 2);
        n_buffer.push(plen_buf[0]);
        n_buffer.push(plen_buf[1]);

        for x in 0..buffer.len() {
            n_buffer.push(buffer[x]);
        }

        match self.stream.write_all(&n_buffer[..]) {
            Ok(()) => {
                let _ = self.stream.flush();
                Ok(())
            }
            Err(e) => Err(e)
        }
    }

    /// Shuts down the connection
    pub fn shutdown(&self) {
        let result = self.stream.shutdown(Shutdown::Both);
        if result.is_err() {
            panic!("Error shutting down stream: {}", result.unwrap_err())
        }
    }
}

impl Clone for Bstream {
    fn clone(&self) -> Bstream {
        Bstream {
            state: self.state.clone(),
            stream: self.stream.try_clone().unwrap(),
            buffer: self.buffer.clone()
        }
    }
}
<|endoftext|>


<commit_before>use std::collections::hash_map::DefaultHasher;
use std::fmt;
use std::hash::{Hash, Hasher};

use bit_vec::BitVec;

struct HashIter<'a, T>
where
    T: 'a,
{
    m: usize,
    k: usize,
    i: usize,
    obj: &'a T,
}

impl<'a, T> HashIter<'a, T>
where
    T: 'a,
{
    fn new(m: usize, k: usize, obj: &'a T) -> HashIter<'a, T> {
        HashIter {
            m: m,
            k: k,
            i: 0,
            obj: obj,
        }
    }
}

impl<'a, T> Iterator for HashIter<'a, T>
where
    T: 'a + Hash,
{
    type Item = usize;

    fn next(&mut self) -> Option<usize> {
        if self.i < self.k {
            let mut hasher = DefaultHasher::new();
            hasher.write_usize(self.i);
            self.obj.hash(&mut hasher);
            let x = (hasher.finish() as usize) % self.m;

            self.i += 1;

            Some(x)
        } else {
            None
        }
    }
}

/// Simple implementation of a [BloomFilter](https://en.wikipedia.org/wiki/Bloom_filter)
#[derive(Clone)]
pub struct BloomFilter {
    bv: BitVec,
    k: usize,
}

impl BloomFilter {
    /// Create new, empty BloomFilter with internal parameters.
    ///
    /// - `k` is the number of hash functions
    /// - `m` is the number of bits used to store state
    pub fn with_params(m: usize, k: usize) -> BloomFilter {
        BloomFilter {
            bv: BitVec::from_elem(m, false),
            k: k,
        }
    }

    /// Create new, empty BloomFilter with given properties.
    ///
    /// - `n` number of unique elements the BloomFilter is expected to hold, must be `> 0`
    /// - `p` false positive property when querying the BloomFilter after adding `n` unique
    ///   elements, must be `> 0` and `< 1`
    ///
    /// Panics if the parameters are not in range.
    pub fn with_properties(n: usize, p: f64) -> BloomFilter {
        assert!(n > 0);
        assert!(p > 0.);
        assert!(p < 1.);

        let k = (-p.log2()) as usize;
        let ln2 = (2f64).ln();
        let m = (-((n as f64) * p.ln()) / (ln2 * ln2)) as usize;

        BloomFilter::with_params(m, k)
    }

    /// Get `k` (number of hash functions).
    pub fn get_k(&self) -> usize {
        self.k
    }

    /// Get `m` (number of stored bits).
    pub fn get_m(&self) -> usize {
        self.bv.len()
    }

    /// Add new element to the BloomFilter.
    ///
    /// If the same element is added multiple times or if an element results in the same hash
    /// signature, this method does not have any effect.
    pub fn add<T>(&mut self, obj: &T)
    where
        T: Hash,
    {
        for pos in HashIter::new(self.bv.len(), self.k, obj) {
            self.bv.set(pos, true);
        }
    }

    /// Guess if the given element was added to the BloomFilter.
    pub fn query<T>(&self, obj: &T) -> bool
    where
        T: Hash,
    {
        for pos in HashIter::new(self.bv.len(), self.k, obj) {
            if !self.bv.get(pos).unwrap() {
                return false;
            }
        }
        true
    }

    /// Clear state of the BloomFilter, so that it behaves like a fresh one.
    pub fn clear(&mut self) {
        self.bv.clear()
    }

    /// Check whether the BloomFilter is empty.
    pub fn is_empty(&self) -> bool {
        !self.bv.iter().any(|x| x)
    }

    /// Add the entire content of another bloomfilter to this BloomFilter.
    ///
    /// The result is the same as adding all elements added to `other` to `self` in the first
    /// place.
    ///
    /// Panics if `k` and `m` of the two BloomFilters are not identical.
    pub fn union(&mut self, other: &BloomFilter) {
        assert!(self.k == other.k);
        assert!(self.bv.len() == other.bv.len());
        self.bv.union(&other.bv);
    }

    /// Guess the number of unique elements added to the BloomFilter.
    pub fn guess_n(&self) -> usize {
        let m = self.bv.len() as f64;
        let k = self.k as f64;
        let x = self.bv.iter().filter(|x| *x).count() as f64;

        (-m / k * (1. - x / m).ln()) as usize
    }
}

impl fmt::Debug for BloomFilter {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "BloomFilter {{ m: {}, k: {} }}", self.bv.len(), self.k)
    }
}

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

    #[test]
    fn getter() {
        let bf = BloomFilter::with_params(100, 2);
        assert!(bf.get_k() == 2);
        assert!(bf.get_m() == 100);
    }

    #[test]
    fn empty() {
        let bf = BloomFilter::with_params(100, 2);
        assert!(!bf.query(&1));
    }

    #[test]
    fn add() {
        let mut bf = BloomFilter::with_params(100, 2);

        bf.add(&1);
        assert!(bf.query(&1));
        assert!(!bf.query(&2));
    }

    #[test]
    fn clear() {
        let mut bf = BloomFilter::with_params(100, 2);

        bf.add(&1);
        bf.clear();
        assert!(!bf.query(&1));
    }

    #[test]
    fn is_empty() {
        let mut bf = BloomFilter::with_params(100, 2);
        assert!(bf.is_empty());

        bf.add(&1);
        assert!(!bf.is_empty());

        bf.clear();
        assert!(bf.is_empty());
    }

    #[test]
    fn clone() {
        let mut bf1 = BloomFilter::with_params(100, 2);
        bf1.add(&1);

        let bf2 = bf1.clone();
        bf1.add(&2);
        assert!(bf2.query(&1));
        assert!(!bf2.query(&2));
    }

    #[test]
    fn union() {
        let mut bf1 = BloomFilter::with_params(100, 2);
        bf1.add(&1);
        assert!(bf1.query(&1));
        assert!(!bf1.query(&2));
        assert!(!bf1.query(&3));

        let mut bf2 = BloomFilter::with_params(100, 2);
        bf2.add(&2);
        assert!(!bf2.query(&1));
        assert!(bf2.query(&2));
        assert!(!bf2.query(&3));

        bf1.union(&bf2);
        assert!(bf1.query(&1));
        assert!(bf1.query(&2));
        assert!(!bf1.query(&3));
    }

    #[test]
    fn with_properties() {
        let bf = BloomFilter::with_properties(1000, 0.1);
        assert!(bf.get_k() == 3);
        assert!(bf.get_m() == 4792);
    }

    #[test]
    fn guess_n() {
        let mut bf = BloomFilter::with_params(100, 2);
        assert!(bf.guess_n() == 0);

        bf.add(&1);
        assert!(bf.guess_n() == 1);

        bf.add(&1);
        assert!(bf.guess_n() == 1);

        bf.add(&2);
        assert!(bf.guess_n() == 2);
    }

    #[test]
    fn debug() {
        let bf = BloomFilter::with_params(100, 2);
        assert!(format!("{:?}", bf) == "BloomFilter { m: 100, k: 2 }");
    }
}
<commit_msg>bloomfilter: use assert_eq<commit_after>use std::collections::hash_map::DefaultHasher;
use std::fmt;
use std::hash::{Hash, Hasher};

use bit_vec::BitVec;

struct HashIter<'a, T>
where
    T: 'a,
{
    m: usize,
    k: usize,
    i: usize,
    obj: &'a T,
}

impl<'a, T> HashIter<'a, T>
where
    T: 'a,
{
    fn new(m: usize, k: usize, obj: &'a T) -> HashIter<'a, T> {
        HashIter {
            m: m,
            k: k,
            i: 0,
            obj: obj,
        }
    }
}

impl<'a, T> Iterator for HashIter<'a, T>
where
    T: 'a + Hash,
{
    type Item = usize;

    fn next(&mut self) -> Option<usize> {
        if self.i < self.k {
            let mut hasher = DefaultHasher::new();
            hasher.write_usize(self.i);
            self.obj.hash(&mut hasher);
            let x = (hasher.finish() as usize) % self.m;

            self.i += 1;

            Some(x)
        } else {
            None
        }
    }
}

/// Simple implementation of a [BloomFilter](https://en.wikipedia.org/wiki/Bloom_filter)
#[derive(Clone)]
pub struct BloomFilter {
    bv: BitVec,
    k: usize,
}

impl BloomFilter {
    /// Create new, empty BloomFilter with internal parameters.
    ///
    /// - `k` is the number of hash functions
    /// - `m` is the number of bits used to store state
    pub fn with_params(m: usize, k: usize) -> BloomFilter {
        BloomFilter {
            bv: BitVec::from_elem(m, false),
            k: k,
        }
    }

    /// Create new, empty BloomFilter with given properties.
    ///
    /// - `n` number of unique elements the BloomFilter is expected to hold, must be `> 0`
    /// - `p` false positive property when querying the BloomFilter after adding `n` unique
    ///   elements, must be `> 0` and `< 1`
    ///
    /// Panics if the parameters are not in range.
    pub fn with_properties(n: usize, p: f64) -> BloomFilter {
        assert!(n > 0);
        assert!(p > 0.);
        assert!(p < 1.);

        let k = (-p.log2()) as usize;
        let ln2 = (2f64).ln();
        let m = (-((n as f64) * p.ln()) / (ln2 * ln2)) as usize;

        BloomFilter::with_params(m, k)
    }

    /// Get `k` (number of hash functions).
    pub fn get_k(&self) -> usize {
        self.k
    }

    /// Get `m` (number of stored bits).
    pub fn get_m(&self) -> usize {
        self.bv.len()
    }

    /// Add new element to the BloomFilter.
    ///
    /// If the same element is added multiple times or if an element results in the same hash
    /// signature, this method does not have any effect.
    pub fn add<T>(&mut self, obj: &T)
    where
        T: Hash,
    {
        for pos in HashIter::new(self.bv.len(), self.k, obj) {
            self.bv.set(pos, true);
        }
    }

    /// Guess if the given element was added to the BloomFilter.
    pub fn query<T>(&self, obj: &T) -> bool
    where
        T: Hash,
    {
        for pos in HashIter::new(self.bv.len(), self.k, obj) {
            if !self.bv.get(pos).unwrap() {
                return false;
            }
        }
        true
    }

    /// Clear state of the BloomFilter, so that it behaves like a fresh one.
    pub fn clear(&mut self) {
        self.bv.clear()
    }

    /// Check whether the BloomFilter is empty.
    pub fn is_empty(&self) -> bool {
        !self.bv.iter().any(|x| x)
    }

    /// Add the entire content of another bloomfilter to this BloomFilter.
    ///
    /// The result is the same as adding all elements added to `other` to `self` in the first
    /// place.
    ///
    /// Panics if `k` and `m` of the two BloomFilters are not identical.
    pub fn union(&mut self, other: &BloomFilter) {
        assert!(self.k == other.k);
        assert!(self.bv.len() == other.bv.len());
        self.bv.union(&other.bv);
    }

    /// Guess the number of unique elements added to the BloomFilter.
    pub fn guess_n(&self) -> usize {
        let m = self.bv.len() as f64;
        let k = self.k as f64;
        let x = self.bv.iter().filter(|x| *x).count() as f64;

        (-m / k * (1. - x / m).ln()) as usize
    }
}

impl fmt::Debug for BloomFilter {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "BloomFilter {{ m: {}, k: {} }}", self.bv.len(), self.k)
    }
}

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

    #[test]
    fn getter() {
        let bf = BloomFilter::with_params(100, 2);
        assert_eq!(bf.get_k(), 2);
        assert_eq!(bf.get_m(), 100);
    }

    #[test]
    fn empty() {
        let bf = BloomFilter::with_params(100, 2);
        assert!(!bf.query(&1));
    }

    #[test]
    fn add() {
        let mut bf = BloomFilter::with_params(100, 2);

        bf.add(&1);
        assert!(bf.query(&1));
        assert!(!bf.query(&2));
    }

    #[test]
    fn clear() {
        let mut bf = BloomFilter::with_params(100, 2);

        bf.add(&1);
        bf.clear();
        assert!(!bf.query(&1));
    }

    #[test]
    fn is_empty() {
        let mut bf = BloomFilter::with_params(100, 2);
        assert!(bf.is_empty());

        bf.add(&1);
        assert!(!bf.is_empty());

        bf.clear();
        assert!(bf.is_empty());
    }

    #[test]
    fn clone() {
        let mut bf1 = BloomFilter::with_params(100, 2);
        bf1.add(&1);

        let bf2 = bf1.clone();
        bf1.add(&2);
        assert!(bf2.query(&1));
        assert!(!bf2.query(&2));
    }

    #[test]
    fn union() {
        let mut bf1 = BloomFilter::with_params(100, 2);
        bf1.add(&1);
        assert!(bf1.query(&1));
        assert!(!bf1.query(&2));
        assert!(!bf1.query(&3));

        let mut bf2 = BloomFilter::with_params(100, 2);
        bf2.add(&2);
        assert!(!bf2.query(&1));
        assert!(bf2.query(&2));
        assert!(!bf2.query(&3));

        bf1.union(&bf2);
        assert!(bf1.query(&1));
        assert!(bf1.query(&2));
        assert!(!bf1.query(&3));
    }

    #[test]
    fn with_properties() {
        let bf = BloomFilter::with_properties(1000, 0.1);
        assert_eq!(bf.get_k(), 3);
        assert_eq!(bf.get_m(), 4792);
    }

    #[test]
    fn guess_n() {
        let mut bf = BloomFilter::with_params(100, 2);
        assert_eq!(bf.guess_n(), 0);

        bf.add(&1);
        assert_eq!(bf.guess_n(), 1);

        bf.add(&1);
        assert_eq!(bf.guess_n(), 1);

        bf.add(&2);
        assert_eq!(bf.guess_n(), 2);
    }

    #[test]
    fn debug() {
        let bf = BloomFilter::with_params(100, 2);
        assert_eq!(format!("{:?}", bf), "BloomFilter { m: 100, k: 2 }");
    }
}
<|endoftext|>