<commit_before>//! # Examples
//!
//! Building a template from a context.
//! ```
//! fn main() {
//!     let mut router = Router::new();
//!     router.get("/user", user_handler, "user");
//!
//!     let mut chain = Chain::new(router);
//!     let teng = TeraEngine::new("src/examples/templates/**/*");
//!     chain.link_after(teng);
//!
//!     Iron::new(chain).http("localhost:5000").unwrap();
//! }
//!
//! fn user_handler(_: &mut Request) -> IronResult<Response> {
//!     let mut resp = Response::new();
//!
//!     let mut context = Context::new();
//!     context.add("username", &"Bob");
//!     context.add("numbers", &vec![1, 2, 3]);
//!     context.add("bio", &"<script>alert('pwnd');</script>");
//!
//!     resp.set_mut(Template::new("users/profile.html", TemplateMode::from_context(context)))
//!         .set_mut(status::Ok);
//!     Ok(resp)
//! }
//! ```
//! # Examples
//!
//! Note that serialize requires serde.
//! ```
//! #[derive(Serialize)]
//! struct Product {
//!     name: String,
//!     value: i32,
//! }
//!
//! fn produce_handler(_: &mut Request) -> IronResult<Response> {
//!     let mut resp = Response::new();
//!
//!     // Using serialized values
//!     let product = Product {
//!         name: "Foo".into(),
//!         value: 42,
//!     };
//!     resp.set_mut(Template::new("product.html", TemplateMode::from_serial(&product)))
//!         .set_mut(status::Ok);
//!     Ok(resp)
//! }
//! ```

#![feature(proc_macro)]
#![allow(dead_code)]

extern crate serde_json;

#[macro_use] extern crate tera;

extern crate iron;

extern crate serde;

use iron::prelude::*;
use iron::{AfterMiddleware, typemap, status};
use iron::modifier::Modifier;
use iron::headers::ContentType;

use tera::{Tera, Context};

use serde::Serialize;
use serde_json::{Value, to_value};

/// There are 2 main ways to pass data to generate a template.
#[derive(Clone)]
pub enum TemplateMode {
    /// TeraContext constructor takes a `Context`
    TeraContext(Context),
    /// Serialized constructor takes a `Value` from `serde_json`
    Serialized(Value),
}

/// TemplateMode should only ever be created from these smart constructors,
/// not with the enums type constructors.
impl TemplateMode {
    pub fn from_context(context: Context) -> TemplateMode {
        TemplateMode::TeraContext(context)
    }
    pub fn from_serial<S: Serialize>(serialized: S) -> TemplateMode {
        TemplateMode::Serialized(to_value(serialized))
    }
}

/// Our template holds a name (path to template) and a mode (constructed with `from_context` or `from_serial`)
#[derive(Clone)]
pub struct Template {
    mode: TemplateMode,
    name: String,
}

impl Template {
    pub fn new(name: &str, mode: TemplateMode) -> Template {
        Template {
            name: name.into(),
            mode: mode,
        }
    }
}

/// TeraEngine holds the Tera struct so that it can be used by many handlers without explicitly passing
pub struct TeraEngine {
    pub tera: Tera,
}

/// `compile_templates!` is used to parse the contents of a dir for all templates.
impl TeraEngine {
    pub fn new(dir: &str) -> TeraEngine {
        TeraEngine { tera: compile_templates!(dir) }
    }
}

impl typemap::Key for TeraEngine {
    type Value = Template;
}

impl Modifier<Response> for Template {
    fn modify(self, resp: &mut Response) {
        resp.extensions.insert::<TeraEngine>(self);
    }
}

/// The middleware implementation for TeraEngine
impl AfterMiddleware for TeraEngine {
    /// This is where all the magic happens. We extract `TeraEngine` from Iron's `Response`,
    /// determine what `TemplateMode` we should render in, and pass the appropriate values to
    /// tera's render methods.
    fn after(&self, _: &mut Request, mut resp: Response) -> IronResult<Response> {
        let wrapper = resp.extensions.remove::<TeraEngine>().and_then(|t| {
            match t.mode {
                TemplateMode::TeraContext(context) => Some(self.tera.render(&t.name, context)),
                TemplateMode::Serialized(value) => Some(self.tera.value_render(&t.name, &value)),
            }
        });
        match wrapper {
            Some(result) => {
                result.map_err(|e| IronError::new(e, status::InternalServerError))
                    .and_then(|page| {
                        if !resp.headers.has::<ContentType>() {
                            resp.headers.set(ContentType::html());
                        }
                        resp.set_mut(page);
                        Ok(resp)
                    })
            }
            None => Ok(resp),
        }
    }

    fn catch(&self, req: &mut Request, mut err: IronError) -> IronResult<Response> {
        err.response = self.after(req, err.response)?;
        Err(err)
    }
}

#[cfg(test)]
mod tests {
    use super::{TeraEngine, Template, TemplateMode};
    use iron::prelude::*;
    use tera::{Tera, Context};

    #[derive(Serialize)]
    struct Product {
        name: String,
        value: i32,
    }

    fn test_resp() -> IronResult<Response> {
        let resp = Response::new();

        let mut context = Context::new();
        context.add("username", &"Foo");
        context.add("bio", &"Bar");
        context.add("numbers", &vec![1, 2, 3]);

        Ok(resp.set(Template::new("users/foo.html", TemplateMode::from_context(context))))
    }

    #[test]
    fn example() {
        let mut resp = test_resp().ok().expect("response expected");

        match resp.get::<TeraEngine>() {
            Ok(h) => {
                assert_eq!(h.name.unwrap(), "users/profile.html".to_string());
                assert_eq!(h.value
                               .as_object()
                               .unwrap()
                               .get(&"Foo".to_string())
                               .unwrap()
                               .as_string()
                               .unwrap(),
                           "Bar");
            }
            _ => panic!("template expected"),
        }
        // let teng = TeraEngine::new("src/test_template/**/*");
        // // Context option 1
        // let mut context = Context::new();
        // context.add("firstname", &"Foo");
        // context.add("lastname", &"Bar");
        //
        // let t = Template::new("index", TemplateMode::TeraContext(context));
        //
        // // Context option 2
        // let mut c2 = Context::new();
        // c2.add("firstname", &"Foo");
        // c2.add("lastname", &"Bar");
        //
        // let t4 = Template::new("index", TemplateMode::from_context(c2));
        //
        // // Using serialized values
        // let product = Product {
        //     name: "Foo".into(),
        //     value: 42,
        // };
        // // option 2
        // let t2 = Template::new("index", TemplateMode::from_serial(&product));
    }
}
<commit_msg>take generic string AsRef<commit_after>//! # Examples
//!
//! Building a template from a context.
//! ```
//! fn main() {
//!     let mut router = Router::new();
//!     router.get("/user", user_handler, "user");
//!
//!     let mut chain = Chain::new(router);
//!     let teng = TeraEngine::new("src/examples/templates/**/*");
//!     chain.link_after(teng);
//!
//!     Iron::new(chain).http("localhost:5000").unwrap();
//! }
//!
//! fn user_handler(_: &mut Request) -> IronResult<Response> {
//!     let mut resp = Response::new();
//!
//!     let mut context = Context::new();
//!     context.add("username", &"Bob");
//!     context.add("numbers", &vec![1, 2, 3]);
//!     context.add("bio", &"<script>alert('pwnd');</script>");
//!
//!     resp.set_mut(Template::new("users/profile.html", TemplateMode::from_context(context)))
//!         .set_mut(status::Ok);
//!     Ok(resp)
//! }
//! ```
//! # Examples
//!
//! Note that serialize requires serde.
//! ```
//! #[derive(Serialize)]
//! struct Product {
//!     name: String,
//!     value: i32,
//! }
//!
//! fn produce_handler(_: &mut Request) -> IronResult<Response> {
//!     let mut resp = Response::new();
//!
//!     // Using serialized values
//!     let product = Product {
//!         name: "Foo".into(),
//!         value: 42,
//!     };
//!     resp.set_mut(Template::new("product.html", TemplateMode::from_serial(&product)))
//!         .set_mut(status::Ok);
//!     Ok(resp)
//! }
//! ```

#![feature(proc_macro)]
#![allow(dead_code)]

extern crate serde_json;

#[macro_use] extern crate tera;

extern crate iron;

extern crate serde;

use iron::prelude::*;
use iron::{AfterMiddleware, typemap, status};
use iron::modifier::Modifier;
use iron::headers::ContentType;

use tera::{Tera, Context};

use serde::Serialize;
use serde_json::{Value, to_value};

/// There are 2 main ways to pass data to generate a template.
#[derive(Clone)]
pub enum TemplateMode {
    /// TeraContext constructor takes a `Context`
    TeraContext(Context),
    /// Serialized constructor takes a `Value` from `serde_json`
    Serialized(Value),
}

/// TemplateMode should only ever be created from these smart constructors,
/// not with the enums type constructors.
impl TemplateMode {
    pub fn from_context(context: Context) -> TemplateMode {
        TemplateMode::TeraContext(context)
    }
    pub fn from_serial<S: Serialize>(serialized: S) -> TemplateMode {
        TemplateMode::Serialized(to_value(serialized))
    }
}

/// Our template holds a name (path to template) and a mode (constructed with `from_context` or `from_serial`)
#[derive(Clone)]
pub struct Template {
    mode: TemplateMode,
    name: String,
}

impl Template {
    pub fn new(name: &str, mode: TemplateMode) -> Template {
        Template {
            name: name.into(),
            mode: mode,
        }
    }
}

/// TeraEngine holds the Tera struct so that it can be used by many handlers without explicitly passing
pub struct TeraEngine {
    pub tera: Tera,
}

/// `compile_templates!` is used to parse the contents of a dir for all templates.
impl TeraEngine {
    /// Take a `String` and convert to a slice or preferably a `&str`
    pub fn new<S: AsRef<str>>(dir: &S) -> TeraEngine {
        TeraEngine { tera: compile_templates!(dir.as_ref()) }
    }
}

impl typemap::Key for TeraEngine {
    type Value = Template;
}

impl Modifier<Response> for Template {
    fn modify(self, resp: &mut Response) {
        resp.extensions.insert::<TeraEngine>(self);
    }
}

/// The middleware implementation for TeraEngine
impl AfterMiddleware for TeraEngine {
    /// This is where all the magic happens. We extract `TeraEngine` from Iron's `Response`,
    /// determine what `TemplateMode` we should render in, and pass the appropriate values to
    /// tera's render methods.
    fn after(&self, _: &mut Request, mut resp: Response) -> IronResult<Response> {
        let wrapper = resp.extensions.remove::<TeraEngine>().and_then(|t| {
            match t.mode {
                TemplateMode::TeraContext(context) => Some(self.tera.render(&t.name, context)),
                TemplateMode::Serialized(value) => Some(self.tera.value_render(&t.name, &value)),
            }
        });
        match wrapper {
            Some(result) => {
                result.map_err(|e| IronError::new(e, status::InternalServerError))
                    .and_then(|page| {
                        if !resp.headers.has::<ContentType>() {
                            resp.headers.set(ContentType::html());
                        }
                        resp.set_mut(page);
                        Ok(resp)
                    })
            }
            None => Ok(resp),
        }
    }

    fn catch(&self, req: &mut Request, mut err: IronError) -> IronResult<Response> {
        err.response = self.after(req, err.response)?;
        Err(err)
    }
}

#[cfg(test)]
mod tests {
    use super::{TeraEngine, Template, TemplateMode};
    use iron::prelude::*;
    use tera::{Tera, Context};

    #[derive(Serialize)]
    struct Product {
        name: String,
        value: i32,
    }

    fn test_resp() -> IronResult<Response> {
        let resp = Response::new();

        let mut context = Context::new();
        context.add("username", &"Foo");
        context.add("bio", &"Bar");
        context.add("numbers", &vec![1, 2, 3]);

        Ok(resp.set(Template::new("users/foo.html", TemplateMode::from_context(context))))
    }

    #[test]
    fn example() {
        let mut resp = test_resp().ok().expect("response expected");

        match resp.get::<TeraEngine>() {
            Ok(h) => {
                assert_eq!(h.name.unwrap(), "users/profile.html".to_string());
                assert_eq!(h.value
                               .as_object()
                               .unwrap()
                               .get(&"Foo".to_string())
                               .unwrap()
                               .as_string()
                               .unwrap(),
                           "Bar");
            }
            _ => panic!("template expected"),
        }
        // let teng = TeraEngine::new("src/test_template/**/*");
        // // Context option 1
        // let mut context = Context::new();
        // context.add("firstname", &"Foo");
        // context.add("lastname", &"Bar");
        //
        // let t = Template::new("index", TemplateMode::TeraContext(context));
        //
        // // Context option 2
        // let mut c2 = Context::new();
        // c2.add("firstname", &"Foo");
        // c2.add("lastname", &"Bar");
        //
        // let t4 = Template::new("index", TemplateMode::from_context(c2));
        //
        // // Using serialized values
        // let product = Product {
        //     name: "Foo".into(),
        //     value: 42,
        // };
        // // option 2
        // let t2 = Template::new("index", TemplateMode::from_serial(&product));
    }
}
<|endoftext|>


<commit_before>#![feature(plugin_registrar)]
#![crate_type = "dylib"]
#![feature(rustc_private, core)]

extern crate syntax;
extern crate rustc;

use syntax::ast;
use syntax::codemap::{Span};
use syntax::ext::base;
use syntax::ext::base::{ExtCtxt, DummyResult};
use rustc::plugin::Registry;

use Severity::{Note, Warning, Error, Fatal};

enum Severity {
    Note,
    Warning,
    Error,
    Fatal,
}

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    macro_rules! register_specifics {
        ($($name: expr => $sev: ident),*) => {
            {
                $(
                    reg.register_macro($name, {
                        fn f(cx: &mut ExtCtxt, sp: Span,
                             args: &[ast::TokenTree]) -> Box<base::MacResult+'static> {
                            expand_msg($sev, cx, sp, args)
                        }
                        f
                    });
                    )*
            }
        }
    }

    register_specifics! {
        "compile_note" => Note,
        "compile_warning" => Warning,
        "compile_error" => Error,
        "compile_fatal" => Fatal
    }
}

fn expand_msg(sev: Severity,
              cx: &mut ExtCtxt, sp: Span, args: &[ast::TokenTree]) -> Box<base::MacResult+'static> {
    // copied from syntax::ext::concat.
    let es = match base::get_exprs_from_tts(cx, sp, args) {
        Some(e) => e,
        None => return base::DummyResult::expr(sp)
    };
    let mut accumulator = String::new();
    for e in es.into_iter() {
        match e.node {
            ast::ExprLit(ref lit) => {
                match lit.node {
                    ast::LitStr(ref s, _) |
                    ast::LitFloat(ref s, _) |
                    ast::LitFloatUnsuffixed(ref s) => {
                        accumulator.push_str(s);
                    }
                    ast::LitChar(c) => {
                        accumulator.push(c);
                    }
                    ast::LitInt(i, ast::UnsignedIntLit(_)) |
                    ast::LitInt(i, ast::SignedIntLit(_, ast::Plus)) |
                    ast::LitInt(i, ast::UnsuffixedIntLit(ast::Plus)) => {
                        accumulator.push_str(format!("{}", i).as_slice());
                    }
                    ast::LitInt(i, ast::SignedIntLit(_, ast::Minus)) |
                    ast::LitInt(i, ast::UnsuffixedIntLit(ast::Minus)) => {
                        accumulator.push_str(format!("-{}", i).as_slice());
                    }
                    ast::LitBool(b) => {
                        accumulator.push_str(format!("{}", b).as_slice());
                    }
                    ast::LitByte(..) |
                    ast::LitBinary(..) => {
                        cx.span_err(e.span, "cannot concatenate a binary literal");
                    }
                }
            }
            _ => {
                cx.span_err(e.span, "expected a literal");
            }
        }
    }

    macro_rules! emit {
        ($($sev: ident => $method: ident),*) => {
            match sev {
                $($sev => cx.$method(sp, accumulator.as_slice()),)*
            }
        }
    }
    emit! {
        Note => span_note,
        Warning => span_warn,
        Error => span_err,
        Fatal => span_fatal
    }

    DummyResult::any(sp)
}
<commit_msg>Flatten some warnings.<commit_after>#![feature(plugin_registrar)]
#![crate_type = "dylib"]
#![feature(rustc_private)]

extern crate syntax;
extern crate rustc;

use syntax::ast;
use syntax::codemap::{Span};
use syntax::ext::base;
use syntax::ext::base::{ExtCtxt, DummyResult};
use rustc::plugin::Registry;

use Severity::{Note, Warning, Error, Fatal};

enum Severity {
    Note,
    Warning,
    Error,
    Fatal,
}

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    macro_rules! register_specifics {
        ($($name: expr => $sev: ident),*) => {
            {
                $(
                    reg.register_macro($name, {
                        fn f(cx: &mut ExtCtxt, sp: Span,
                             args: &[ast::TokenTree]) -> Box<base::MacResult+'static> {
                            expand_msg($sev, cx, sp, args)
                        }
                        f
                    });
                    )*
            }
        }
    }

    register_specifics! {
        "compile_note" => Note,
        "compile_warning" => Warning,
        "compile_error" => Error,
        "compile_fatal" => Fatal
    }
}

fn expand_msg(sev: Severity,
              cx: &mut ExtCtxt, sp: Span, args: &[ast::TokenTree]) -> Box<base::MacResult+'static> {
    // copied from syntax::ext::concat.
    let es = match base::get_exprs_from_tts(cx, sp, args) {
        Some(e) => e,
        None => return base::DummyResult::expr(sp)
    };
    let mut accumulator = String::new();
    for e in es.into_iter() {
        match e.node {
            ast::ExprLit(ref lit) => {
                match lit.node {
                    ast::LitStr(ref s, _) |
                    ast::LitFloat(ref s, _) |
                    ast::LitFloatUnsuffixed(ref s) => {
                        accumulator.push_str(s);
                    }
                    ast::LitChar(c) => {
                        accumulator.push(c);
                    }
                    ast::LitInt(i, ast::UnsignedIntLit(_)) |
                    ast::LitInt(i, ast::SignedIntLit(_, ast::Plus)) |
                    ast::LitInt(i, ast::UnsuffixedIntLit(ast::Plus)) => {
                        accumulator.push_str(&format!("{}", i));
                    }
                    ast::LitInt(i, ast::SignedIntLit(_, ast::Minus)) |
                    ast::LitInt(i, ast::UnsuffixedIntLit(ast::Minus)) => {
                        accumulator.push_str(&format!("-{}", i));
                    }
                    ast::LitBool(b) => {
                        accumulator.push_str(&format!("{}", b));
                    }
                    ast::LitByte(..) |
                    ast::LitBinary(..) => {
                        cx.span_err(e.span, "cannot concatenate a binary literal");
                    }
                }
            }
            _ => {
                cx.span_err(e.span, "expected a literal");
            }
        }
    }

    macro_rules! emit {
        ($($sev: ident => $method: ident),*) => {
            match sev {
                $($sev => cx.$method(sp, &accumulator),)*
            }
        }
    }
    emit! {
        Note => span_note,
        Warning => span_warn,
        Error => span_err,
        Fatal => span_fatal
    }

    DummyResult::any(sp)
}
<|endoftext|>


<commit_before>#![crate_name = "binstat"]
#![deny(missing_doc)]

//! A library for modelling and reasoning about multidimensional
//! binary states.

#[cfg(test)]
extern crate debug;

use std::collections::Bitv;

/// Contains a binary state and the choices.
#[deriving(PartialEq, Eq, Show, Clone)]
pub struct BinNode {
    /// The state composed of bits.
    pub state: Bitv,
    /// The choices represented as bits that can be flipped.
    pub choices: Bitv
}

impl BinNode {
    /// Gets pairs from pair of booleans.
    pub fn from_pairs(pairs: &[(bool, bool)]) -> BinNode {
        BinNode {
            state: pairs.iter().map(|&(a, _)| a).collect(),
            choices: pairs.iter().map(|&(_, b)| b).collect()
        }
    }

    /// Call closure for each available choice.
    #[inline(always)]
    pub fn with_choices(&self, f: |i: uint|) {
        for i in range(0, self.choices.len())
            .zip(self.choices.iter())
            .filter(|&(_, v)| v == true)
            .map(|(i, _)| i
        ) {
            f(i)
        }
    }

    /// Calls closure for all choices that are not in graph.
    #[inline(always)]
    pub fn with_choices_not_in<TAction>(
        &self,
        graph: &BinGraph<TAction>,
        f: |i: uint|
    ) {
        self.with_choices(|i| if !graph.contains_choice(self, i) { f(i) })
    }
}

/// Models a multidimensional binary state.
pub struct BinGraph<TAction> {
    /// The states and the bits that can be flipped.
    pub data: Vec<BinNode>,
    /// A description the action that takes when flipping bits.
    pub actions: Vec<TAction>,
}

impl<TAction> BinGraph<TAction> {
    /// Creates a new BinGraph.
    pub fn new() -> BinGraph<TAction> {
        BinGraph {
            data: Vec::new(),
            actions: Vec::new()
        }
    }

    /// Adds new information about state and choices.
    ///
    /// The first bool indicate state, the second whether it can change.
    pub fn push_pairs(&mut self, pairs: &[(bool, bool)]) {
        self.data.push(BinNode::from_pairs(pairs));
    }

    /// Returns true if the graph contains a choice.
    pub fn contains_choice(&self, state: &BinNode, i: uint) -> bool {
        self.data.iter().any(|st|
            range(0, st.choices.len()).all(|j|
                state.choices.get(j) == if j == i {
                        !state.choices.get(j)
                    } else {
                        state.choices.get(j)
                    }
            )
        )
    }

    /// Returns the suggestion in default state that are open to all choices.
    pub fn default_suggestion(&self) -> BinNode {
        let open_for_all_choices: Vec<(bool, bool)> =
            range(0, self.actions.len()).map(|_| (false, true)).collect();
        BinNode::from_pairs(open_for_all_choices.as_slice())
    }

    /// Suggests a missing state with choices.
    pub fn suggestion(&self) -> Option<BinNode> {
        if self.data.len() == 0 {
            Some(self.default_suggestion())
        } else {
            None
        }
    }
}

#[test]
fn test_exclusive() {
    let mut g: BinGraph<&'static str> = BinGraph::new();
    g.actions.push("Go swiming");
    g.actions.push("Read a book");

    let suggestion = g.suggestion().unwrap();
    assert_eq!(suggestion, BinNode::from_pairs([
        (false, true),
        (false, true)
    ]));

    g.data.push(suggestion.clone());

    assert!(!g.contains_choice(&suggestion, 0));

    g.push_pairs([
        (true, true), // is swimming, can stop.
        (false, false), // is not reading book, can't read book.
    ]);
}

<commit_msg>Added `BinGraph::is_complete`<commit_after>#![crate_name = "binstat"]
#![deny(missing_doc)]

//! A library for modelling and reasoning about multidimensional
//! binary states.

#[cfg(test)]
extern crate debug;

use std::collections::Bitv;

/// Contains a binary state and the choices.
#[deriving(PartialEq, Eq, Show, Clone)]
pub struct BinNode {
    /// The state composed of bits.
    pub state: Bitv,
    /// The choices represented as bits that can be flipped.
    pub choices: Bitv
}

impl BinNode {
    /// Gets pairs from pair of booleans.
    pub fn from_pairs(pairs: &[(bool, bool)]) -> BinNode {
        BinNode {
            state: pairs.iter().map(|&(a, _)| a).collect(),
            choices: pairs.iter().map(|&(_, b)| b).collect()
        }
    }

    /// Call closure for each available choice.
    #[inline(always)]
    pub fn with_choices(&self, f: |i: uint|) {
        for i in range(0, self.choices.len())
            .zip(self.choices.iter())
            .filter(|&(_, v)| v)
            .map(|(i, _)| i
        ) {
            f(i)
        }
    }

    /// Calls closure for all choices that are not in graph.
    #[inline(always)]
    pub fn with_choices_not_in<TAction>(
        &self,
        graph: &BinGraph<TAction>,
        f: |i: uint|
    ) {
        self.with_choices(|i| if !graph.contains_choice(self, i) {
            // TEST
            println!("i: {}", i);

            f(i)
        })
    }
}

/// Models a multidimensional binary state.
pub struct BinGraph<TAction> {
    /// The states and the bits that can be flipped.
    pub data: Vec<BinNode>,
    /// A description the action that takes when flipping bits.
    pub actions: Vec<TAction>,
}

impl<TAction> BinGraph<TAction> {
    /// Creates a new BinGraph.
    pub fn new() -> BinGraph<TAction> {
        BinGraph {
            data: Vec::new(),
            actions: Vec::new()
        }
    }

    /// Adds new information about state and choices.
    ///
    /// The first bool indicate state, the second whether it can change.
    pub fn push_pairs(&mut self, pairs: &[(bool, bool)]) {
        self.data.push(BinNode::from_pairs(pairs));
    }

    /// Returns true if the graph contains a choice.
    pub fn contains_choice(&self, state: &BinNode, i: uint) -> bool {
        self.data.iter().any(|n| {
            range(0, n.state.len()).all(|j| {
                let state_val = state.state.get(j);
                let state_val = if i == j { !state_val } else { state_val };
                n.state.get(j) == state_val
            })
        })
    }

    /// Finds out if graph is complete.
    pub fn is_complete(&self) -> bool {
        let mut complete = true;
        for node in self.data.iter() {
            node.with_choices_not_in(self, |_| complete = false);
            if !complete { return false }
        }

        true
    }

    /// Returns the suggestion in default state that are open to all choices.
    pub fn default_suggestion(&self) -> BinNode {
        let open_for_all_choices: Vec<(bool, bool)> =
            range(0, self.actions.len()).map(|_| (false, true)).collect();
        BinNode::from_pairs(open_for_all_choices.as_slice())
    }

    /// Suggests a missing state with choices.
    pub fn suggestion(&self) -> Option<BinNode> {
        if self.data.len() == 0 {
            Some(self.default_suggestion())
        } else {
            None
        }
    }
}

#[test]
fn test_exclusive() {
    let mut g: BinGraph<&'static str> = BinGraph::new();
    g.actions.push("Go swiming");
    g.actions.push("Read a book");

    let suggestion = g.suggestion().unwrap();
    assert_eq!(suggestion, BinNode::from_pairs([
        (false, true),
        (false, true)
    ]));

    g.data.push(suggestion.clone());

    assert!(!g.contains_choice(&suggestion, 0));

    g.push_pairs([
        (true, true), // can stop swimming.
        (false, false), // can't read book.
    ]);

    // TEST
    println!("NOW");

    assert!(g.contains_choice(&suggestion, 0));
    assert!(g.contains_choice(&g.data[1], 0));

    assert!(!g.is_complete());

    g.push_pairs([
        (false, false), // can't start swimming.
        (true, true), // can stop reading book.
    ]);

    assert!(g.is_complete());
}

<|endoftext|>


<commit_before>/*!
Crate `fst` is a library for efficiently storing and searching ordered sets or
maps where the keys are byte strings. A key design goal of this crate is to
support storing and searching *very large* sets or maps (i.e., billions). This
means that much effort has gone in to making sure that all operations are
memory efficient.

Sets and maps are represented by a finite state machine, which acts as a form
of compression on common prefixes and suffixes in the keys. Additionally,
finite state machines can be efficiently queried with automata (like regular
expressions or Levenshtein distance for fuzzy queries) or lexicographic ranges.

To read more about the mechanics of finite state transducers, including a
bibliography for algorithms used in this crate, see the docs for the
[`raw::Fst`](raw/struct.Fst.html) type.

# Installation

Simply add a corresponding entry to your `Cargo.toml` dependency list:

```ignore
[dependencies]
fst = "0.1"
```

And add this to your crate root:

```ignore
extern crate fst;
```

The examples in this documentation will show the rest.

# Overview of types and modules

This crate provides the high level abstractions---namely sets and maps---in the
top-level module. The top-level module also contains types for building
regular expressions (`Regex`) or fuzzy queries (`Levenshtein`), which can be
used to efficiently query a set or a map.

The `set` and `map` sub-modules contain types specific to sets and maps, such
as range queries and streams.

The `raw` module permits direct interaction with finite state transducers.
Namely, the states and transitions of a transducer can be directly accessed
with the `raw` module.

# Example: fuzzy query

This example shows how to create a set of strings in memory, and then execute
a fuzzy query. Namely, the query looks for all keys within an edit distance
of `1` of `foo`. (Edit distance is the number of character insertions,
deletions or substitutions required to get from one string to another. In this
case, a character is a Unicode codepoint.)

```rust
# fn example() -> Result<(), fst::Error> {
use fst::{IntoStreamer, Streamer, Levenshtein, Set};

// A convenient way to create sets in memory.
let keys = vec!["fa", "fo", "fob", "focus", "foo", "food", "foul"];
let set = try!(Set::from_iter(keys));

// Build our fuzzy query.
let lev = try!(Levenshtein::new("foo", 1));

// Apply our fuzzy query to the set we built.
let mut stream = set.search(lev).into_stream();

// Iterate over the stream and collect the matching keys.
let mut keys = vec![];
while let Some(key) = stream.next() {
    keys.push(key.to_vec());
}
assert_eq!(keys, vec![
    "fo".as_bytes(),   // 1 deletion
    "fob".as_bytes(),  // 1 substitution
    "foo".as_bytes(),  // 0 insertions/deletions/substitutions
    "food".as_bytes(), // 1 insertion
]);
# Ok(())
# }
# example().unwrap();
```

# Example: stream a map to a file

This shows how to create a `MapBuilder` that will stream construction of the
map to a file. Notably, this will never store the entire transducer in memory.
Instead, only constant memory is required.

```rust,no_run
# fn example() -> Result<(), fst::Error> {
use std::fs::File;
use std::io;

use fst::{IntoStreamer, Streamer, Map, MapBuilder};

// This is where we'll write our map to.
let mut wtr = io::BufWriter::new(try!(File::create("map.fst")));

// Create a builder that can be used to insert new key-value pairs.
let mut build = try!(MapBuilder::new(wtr));
build.insert("bruce", 1).unwrap();
build.insert("clarence", 2).unwrap();
build.insert("stevie", 3).unwrap();

// Finish construction of the map and flush its contents to disk.
try!(build.finish());

// At this point, the map has been constructed. Now we'd like to search it.
// This creates a memory map, which enables searching the map without loading
// all of it into memory.
let map = try!(Map::from_file_path("map.fst"));

// Query for keys that are greater than or equal to clarence.
let mut stream = map.range().ge("clarence").into_stream();

// Iterate over the stream and collect the matching keys.
let mut kvs = vec![];
while let Some((k, v)) = stream.next() {
    kvs.push((k.to_vec(), v));
}
assert_eq!(kvs, vec![
    (b"clarence".to_vec(), 2),
    (b"stevie".to_vec(), 3),
]);
# Ok(())
# }
# example().unwrap();
```

# Example: case insensitive search

We can perform case insensitive search on a set using a regular expression.
Note that while sets can store arbitrary byte strings, a regular expression
will only match valid UTF-8 encoded byte strings.

```rust
# fn example() -> Result<(), fst::Error> {
use fst::{IntoStreamer, Streamer, Regex, Set};

let set = try!(Set::from_iter(&["FoO", "Foo", "fOO", "foo"]));

let re = try!(Regex::new("(?i)foo"));
let mut stream = set.search(&re).into_stream();

let mut keys = vec![];
while let Some(key) = stream.next() {
    keys.push(key.to_vec());
}
assert_eq!(keys, vec![
    "FoO".as_bytes(),
    "Foo".as_bytes(),
    "fOO".as_bytes(),
    "foo".as_bytes(),
]);
# Ok(())
# }
# example().unwrap();
```

# Example: searching multiple sets efficiently

Since queries can search a transducer without reading the entire data structure
into memory, it is possible to search *many* transducers very quickly.

This crate provides efficient set/map operations that allow one to combine
multiple streams of search results. Each operation only uses memory
proportional to the number of streams.

The example below shows how to find all keys that have at least one capital
letter that doesn't appear at the beginning of the key. The example below uses
sets, but the same operations are available on maps too.

```rust
# fn example() -> Result<(), fst::Error> {
use fst::{Streamer, Regex, Set};
use fst::set;

let set1 = try!(Set::from_iter(&["AC/DC", "Aerosmith"]));
let set2 = try!(Set::from_iter(&["Bob Seger", "Bruce Springsteen"]));
let set3 = try!(Set::from_iter(&["George Thorogood", "Golden Earring"]));
let set4 = try!(Set::from_iter(&["Kansas"]));
let set5 = try!(Set::from_iter(&["Metallica"]));

// Create the regular expression. We can reuse it to search all of the sets.
let re = try!(Regex::new(r".+\p{Lu}.*"));

// Build a set operation. All we need to do is add a search result stream for
// each set and ask for the union. (Other operations, like intersection and
// difference are also available.)
let mut stream =
    set::OpBuilder::new()
    .add(set1.search(&re))
    .add(set2.search(&re))
    .add(set3.search(&re))
    .add(set4.search(&re))
    .add(set5.search(&re))
    .union();

// Now collect all of the keys. Alternatively, you could build another set here
// using `SetBuilder::extend_stream`.
let mut keys = vec![];
while let Some(key) = stream.next() {
    keys.push(key.to_vec());
}
assert_eq!(keys, vec![
    "AC/DC".as_bytes(),
    "Bob Seger".as_bytes(),
    "Bruce Springsteen".as_bytes(),
    "George Thorogood".as_bytes(),
    "Golden Earring".as_bytes(),
]);
# Ok(())
# }
# example().unwrap();
```

# Memory usage

An important advantage of using finite state transducers to represent sets and
maps is that they can compress very well depending on the distribution of keys.
The smaller your set/map is, the more likely it is that it will fit into
memory. If it's in memory, then searching it is faster. Therefore, it is
important to do what we can to limit what actually needs to be in memory.

This is where automata shine, because they can be queried in their compressed
state without loading the entire data structure into memory. This means that
one can store a set/map created by this crate on disk and search it without
actually reading the entire set/map into memory. This use case is served well
by *memory maps*, which lets one assign the entire contents of a file to a
contiguous region of virtual memory.

Indeed, this crate encourages this mode of operation. Both sets and maps have
methods for memory mapping a finite state transducer from disk.

This is particularly important for long running processes that use this crate,
since it enables the operating system to determine which regions of your
finite state transducers are actually in memory.

Of course, there are downsides to this approach. Namely, navigating a
transducer during a key lookup or a search will likely follow a pattern
approximating random access. Supporting random access when reading from disk
can be very slow because of how often `seek` must be called (or, in the case
of memory maps, page faults). This is somewhat mitigated by the prevalence of
solid state drives where seek time is eliminated. Nevertheless, solid state
drives are not ubiquitous and it is possible that the OS will not be smart
enough to keep your memory mapped transducers in the page cache. In that case,
it is advisable to load the entire transducer into your process's memory (e.g.,
`Set::from_bytes`).

# Streams

Searching a set or a map needs to provide some way to iterate over the search
results. Idiomatic Rust calls for something satisfying the `Iterator` trait
to be used here. Unfortunately, this is not possible to do efficiently because
the `Iterator` trait does not permit values emitted by the iterator to borrow
from the iterator. Borrowing from the iterator is required in our case because
keys and values are constructed *during iteration*.

Namely, if we were to use iterators, then every key would need its own
allocation, which could be quite costly.

Instead, this crate provides a `Streamer`, which can be thought of as a
streaming iterator. Namely, a stream in this crate maintains a single key
buffer and lends it out on each iteration.

For more details, including important limitations, see the `Streamer` trait.

# Quirks

There's no doubt about it, finite state transducers are a specialty data
structure. They have a host of restrictions that don't apply to other similar
data structures found in the standard library, such as `BTreeSet` and
`BTreeMap`. Here are some of them:

1. Sets can only contain keys that are byte strings.
2. Maps can also only contain keys that are byte strings, and its values are
   limited to unsigned 64 bit integers. (The restriction on values may be
   relaxed some day.)
3. Creating a set or a map requires inserting keys in lexicographic order.
   Often, keys are not already sorted, which can make constructing large
   sets or maps tricky. One way to do it is to sort pieces of the data and
   build a set/map for each piece. This can be parallelized trivially. Once
   done, they can be merged together into one big set/map if desired.
   An example of this procedure can be seen in `fst-bin/src/merge.rs` from the
   root of this crate's repository.

# Warning: regexes and Levenshtein automatons use a lot of memory

The construction of automatons for both regular expressions and Levenshtein
automatons should be consider "proof of concept" quality. Namely, they do just
enough to be *correct*. But they haven't had any effort put into them to be
memory conscious. These are important parts of this library, so they will be
improved.

Note that whether you're using regexes or Levenshtein automatons, an error
will be returned if the automaton gets too big (tens of MB in heap usage).
*/

#![deny(missing_docs)]

extern crate byteorder;
extern crate memchr;
extern crate memmap;
#[cfg(test)] extern crate quickcheck;
#[cfg(test)] extern crate rand;
extern crate regex_syntax;
extern crate utf8_ranges;

pub use automaton::Automaton;
pub use error::{Error, Result};
pub use levenshtein::Error as LevenshteinError;
pub use levenshtein::Levenshtein;
pub use map::{Map, MapBuilder};
pub use regex::Error as RegexError;
pub use regex::Regex;
pub use set::{Set, SetBuilder};
pub use stream::{IntoStreamer, Streamer};

mod automaton;
mod error;
mod levenshtein;
#[path = "map.rs"]
mod inner_map;
pub mod raw;
mod regex;
#[path = "set.rs"]
mod inner_set;
mod stream;

/// Map operations implemented by finite state transducers.
///
/// This API provided by this sub-module is close in spirit to the API
/// provided by
/// [`std::collections::BTreeMap`](http://doc.rust-lang.org/stable/std/collections/struct.BTreeMap.html).
///
/// # Overview of types
///
/// `Map` is a read only interface to pre-constructed sets. `MapBuilder` is
/// used to create new sets. (Once a set is created, it can never be modified.)
/// `Stream`, `Keys` and `Values` are streams that originated from a map.
/// `StreamBuilder` builds range queries. `OpBuilder` collects a set of streams
/// and executes set operations like `union` or `intersection` on them with the
/// option of specifying a merge strategy for a map's values. The rest of the
/// types are streams for set operations.
pub mod map {
    pub use inner_map::*;
}

/// Set operations implemented by finite state transducers.
///
/// This API provided by this sub-module is close in spirit to the API
/// provided by
/// [`std::collections::BTreeSet`](http://doc.rust-lang.org/stable/std/collections/struct.BTreeSet.html).
/// The principle difference, as with everything else in this crate, is that
/// operations are performed on streams of byte strings instead of generic
/// iterators. Another difference is that most of the set operations (union,
/// intersection, difference and symmetric difference) work on multiple sets at
/// the same time, instead of two.
///
/// # Overview of types
///
/// `Set` is a read only interface to pre-constructed sets. `SetBuilder` is
/// used to create new sets. (Once a set is created, it can never be modified.)
/// `Stream` is a stream of values that originated from a set (analogous to an
/// iterator). `StreamBuilder` builds range queries. `OpBuilder` collects a set
/// of streams and executes set operations like `union` or `intersection` on
/// them. The rest of the types are streams for set operations.
pub mod set {
    pub use inner_set::*;
}
<commit_msg>be honest<commit_after>/*!
Crate `fst` is a library for efficiently storing and searching ordered sets or
maps where the keys are byte strings. A key design goal of this crate is to
support storing and searching *very large* sets or maps (i.e., billions). This
means that much effort has gone in to making sure that all operations are
memory efficient.

Sets and maps are represented by a finite state machine, which acts as a form
of compression on common prefixes and suffixes in the keys. Additionally,
finite state machines can be efficiently queried with automata (like regular
expressions or Levenshtein distance for fuzzy queries) or lexicographic ranges.

To read more about the mechanics of finite state transducers, including a
bibliography for algorithms used in this crate, see the docs for the
[`raw::Fst`](raw/struct.Fst.html) type.

# Installation

Simply add a corresponding entry to your `Cargo.toml` dependency list:

```ignore
[dependencies]
fst = "0.1"
```

And add this to your crate root:

```ignore
extern crate fst;
```

The examples in this documentation will show the rest.

# Overview of types and modules

This crate provides the high level abstractions---namely sets and maps---in the
top-level module. The top-level module also contains types for building
regular expressions (`Regex`) or fuzzy queries (`Levenshtein`), which can be
used to efficiently query a set or a map.

The `set` and `map` sub-modules contain types specific to sets and maps, such
as range queries and streams.

The `raw` module permits direct interaction with finite state transducers.
Namely, the states and transitions of a transducer can be directly accessed
with the `raw` module.

# Example: fuzzy query

This example shows how to create a set of strings in memory, and then execute
a fuzzy query. Namely, the query looks for all keys within an edit distance
of `1` of `foo`. (Edit distance is the number of character insertions,
deletions or substitutions required to get from one string to another. In this
case, a character is a Unicode codepoint.)

```rust
# fn example() -> Result<(), fst::Error> {
use fst::{IntoStreamer, Streamer, Levenshtein, Set};

// A convenient way to create sets in memory.
let keys = vec!["fa", "fo", "fob", "focus", "foo", "food", "foul"];
let set = try!(Set::from_iter(keys));

// Build our fuzzy query.
let lev = try!(Levenshtein::new("foo", 1));

// Apply our fuzzy query to the set we built.
let mut stream = set.search(lev).into_stream();

// Iterate over the stream and collect the matching keys.
let mut keys = vec![];
while let Some(key) = stream.next() {
    keys.push(key.to_vec());
}
assert_eq!(keys, vec![
    "fo".as_bytes(),   // 1 deletion
    "fob".as_bytes(),  // 1 substitution
    "foo".as_bytes(),  // 0 insertions/deletions/substitutions
    "food".as_bytes(), // 1 insertion
]);
# Ok(())
# }
# example().unwrap();
```

# Example: stream a map to a file

This shows how to create a `MapBuilder` that will stream construction of the
map to a file. Notably, this will never store the entire transducer in memory.
Instead, only constant memory is required.

```rust,no_run
# fn example() -> Result<(), fst::Error> {
use std::fs::File;
use std::io;

use fst::{IntoStreamer, Streamer, Map, MapBuilder};

// This is where we'll write our map to.
let mut wtr = io::BufWriter::new(try!(File::create("map.fst")));

// Create a builder that can be used to insert new key-value pairs.
let mut build = try!(MapBuilder::new(wtr));
build.insert("bruce", 1).unwrap();
build.insert("clarence", 2).unwrap();
build.insert("stevie", 3).unwrap();

// Finish construction of the map and flush its contents to disk.
try!(build.finish());

// At this point, the map has been constructed. Now we'd like to search it.
// This creates a memory map, which enables searching the map without loading
// all of it into memory.
let map = try!(Map::from_file_path("map.fst"));

// Query for keys that are greater than or equal to clarence.
let mut stream = map.range().ge("clarence").into_stream();

// Iterate over the stream and collect the matching keys.
let mut kvs = vec![];
while let Some((k, v)) = stream.next() {
    kvs.push((k.to_vec(), v));
}
assert_eq!(kvs, vec![
    (b"clarence".to_vec(), 2),
    (b"stevie".to_vec(), 3),
]);
# Ok(())
# }
# example().unwrap();
```

# Example: case insensitive search

We can perform case insensitive search on a set using a regular expression.
Note that while sets can store arbitrary byte strings, a regular expression
will only match valid UTF-8 encoded byte strings.

```rust
# fn example() -> Result<(), fst::Error> {
use fst::{IntoStreamer, Streamer, Regex, Set};

let set = try!(Set::from_iter(&["FoO", "Foo", "fOO", "foo"]));

let re = try!(Regex::new("(?i)foo"));
let mut stream = set.search(&re).into_stream();

let mut keys = vec![];
while let Some(key) = stream.next() {
    keys.push(key.to_vec());
}
assert_eq!(keys, vec![
    "FoO".as_bytes(),
    "Foo".as_bytes(),
    "fOO".as_bytes(),
    "foo".as_bytes(),
]);
# Ok(())
# }
# example().unwrap();
```

# Example: searching multiple sets efficiently

Since queries can search a transducer without reading the entire data structure
into memory, it is possible to search *many* transducers very quickly.

This crate provides efficient set/map operations that allow one to combine
multiple streams of search results. Each operation only uses memory
proportional to the number of streams.

The example below shows how to find all keys that have at least one capital
letter that doesn't appear at the beginning of the key. The example below uses
sets, but the same operations are available on maps too.

```rust
# fn example() -> Result<(), fst::Error> {
use fst::{Streamer, Regex, Set};
use fst::set;

let set1 = try!(Set::from_iter(&["AC/DC", "Aerosmith"]));
let set2 = try!(Set::from_iter(&["Bob Seger", "Bruce Springsteen"]));
let set3 = try!(Set::from_iter(&["George Thorogood", "Golden Earring"]));
let set4 = try!(Set::from_iter(&["Kansas"]));
let set5 = try!(Set::from_iter(&["Metallica"]));

// Create the regular expression. We can reuse it to search all of the sets.
let re = try!(Regex::new(r".+\p{Lu}.*"));

// Build a set operation. All we need to do is add a search result stream for
// each set and ask for the union. (Other operations, like intersection and
// difference are also available.)
let mut stream =
    set::OpBuilder::new()
    .add(set1.search(&re))
    .add(set2.search(&re))
    .add(set3.search(&re))
    .add(set4.search(&re))
    .add(set5.search(&re))
    .union();

// Now collect all of the keys. Alternatively, you could build another set here
// using `SetBuilder::extend_stream`.
let mut keys = vec![];
while let Some(key) = stream.next() {
    keys.push(key.to_vec());
}
assert_eq!(keys, vec![
    "AC/DC".as_bytes(),
    "Bob Seger".as_bytes(),
    "Bruce Springsteen".as_bytes(),
    "George Thorogood".as_bytes(),
    "Golden Earring".as_bytes(),
]);
# Ok(())
# }
# example().unwrap();
```

# Memory usage

An important advantage of using finite state transducers to represent sets and
maps is that they can compress very well depending on the distribution of keys.
The smaller your set/map is, the more likely it is that it will fit into
memory. If it's in memory, then searching it is faster. Therefore, it is
important to do what we can to limit what actually needs to be in memory.

This is where automata shine, because they can be queried in their compressed
state without loading the entire data structure into memory. This means that
one can store a set/map created by this crate on disk and search it without
actually reading the entire set/map into memory. This use case is served well
by *memory maps*, which lets one assign the entire contents of a file to a
contiguous region of virtual memory.

Indeed, this crate encourages this mode of operation. Both sets and maps have
methods for memory mapping a finite state transducer from disk.

This is particularly important for long running processes that use this crate,
since it enables the operating system to determine which regions of your
finite state transducers are actually in memory.

Of course, there are downsides to this approach. Namely, navigating a
transducer during a key lookup or a search will likely follow a pattern
approximating random access. Supporting random access when reading from disk
can be very slow because of how often `seek` must be called (or, in the case
of memory maps, page faults). This is somewhat mitigated by the prevalence of
solid state drives where seek time is eliminated. Nevertheless, solid state
drives are not ubiquitous and it is possible that the OS will not be smart
enough to keep your memory mapped transducers in the page cache. In that case,
it is advisable to load the entire transducer into your process's memory (e.g.,
`Set::from_bytes`).

# Streams

Searching a set or a map needs to provide some way to iterate over the search
results. Idiomatic Rust calls for something satisfying the `Iterator` trait
to be used here. Unfortunately, this is not possible to do efficiently because
the `Iterator` trait does not permit values emitted by the iterator to borrow
from the iterator. Borrowing from the iterator is required in our case because
keys and values are constructed *during iteration*.

Namely, if we were to use iterators, then every key would need its own
allocation, which could be quite costly.

Instead, this crate provides a `Streamer`, which can be thought of as a
streaming iterator. Namely, a stream in this crate maintains a single key
buffer and lends it out on each iteration.

For more details, including important limitations, see the `Streamer` trait.

# Quirks

There's no doubt about it, finite state transducers are a specialty data
structure. They have a host of restrictions that don't apply to other similar
data structures found in the standard library, such as `BTreeSet` and
`BTreeMap`. Here are some of them:

1. Sets can only contain keys that are byte strings.
2. Maps can also only contain keys that are byte strings, and its values are
   limited to unsigned 64 bit integers. (The restriction on values may be
   relaxed some day.)
3. Creating a set or a map requires inserting keys in lexicographic order.
   Often, keys are not already sorted, which can make constructing large
   sets or maps tricky. One way to do it is to sort pieces of the data and
   build a set/map for each piece. This can be parallelized trivially. Once
   done, they can be merged together into one big set/map if desired.
   A somewhat simplistic example of this procedure can be seen in
   `fst-bin/src/merge.rs` from the root of this crate's repository.

# Warning: regexes and Levenshtein automatons use a lot of memory

The construction of automatons for both regular expressions and Levenshtein
automatons should be consider "proof of concept" quality. Namely, they do just
enough to be *correct*. But they haven't had any effort put into them to be
memory conscious. These are important parts of this library, so they will be
improved.

Note that whether you're using regexes or Levenshtein automatons, an error
will be returned if the automaton gets too big (tens of MB in heap usage).
*/

#![deny(missing_docs)]

extern crate byteorder;
extern crate memchr;
extern crate memmap;
#[cfg(test)] extern crate quickcheck;
#[cfg(test)] extern crate rand;
extern crate regex_syntax;
extern crate utf8_ranges;

pub use automaton::Automaton;
pub use error::{Error, Result};
pub use levenshtein::Error as LevenshteinError;
pub use levenshtein::Levenshtein;
pub use map::{Map, MapBuilder};
pub use regex::Error as RegexError;
pub use regex::Regex;
pub use set::{Set, SetBuilder};
pub use stream::{IntoStreamer, Streamer};

mod automaton;
mod error;
mod levenshtein;
#[path = "map.rs"]
mod inner_map;
pub mod raw;
mod regex;
#[path = "set.rs"]
mod inner_set;
mod stream;

/// Map operations implemented by finite state transducers.
///
/// This API provided by this sub-module is close in spirit to the API
/// provided by
/// [`std::collections::BTreeMap`](http://doc.rust-lang.org/stable/std/collections/struct.BTreeMap.html).
///
/// # Overview of types
///
/// `Map` is a read only interface to pre-constructed sets. `MapBuilder` is
/// used to create new sets. (Once a set is created, it can never be modified.)
/// `Stream`, `Keys` and `Values` are streams that originated from a map.
/// `StreamBuilder` builds range queries. `OpBuilder` collects a set of streams
/// and executes set operations like `union` or `intersection` on them with the
/// option of specifying a merge strategy for a map's values. The rest of the
/// types are streams for set operations.
pub mod map {
    pub use inner_map::*;
}

/// Set operations implemented by finite state transducers.
///
/// This API provided by this sub-module is close in spirit to the API
/// provided by
/// [`std::collections::BTreeSet`](http://doc.rust-lang.org/stable/std/collections/struct.BTreeSet.html).
/// The principle difference, as with everything else in this crate, is that
/// operations are performed on streams of byte strings instead of generic
/// iterators. Another difference is that most of the set operations (union,
/// intersection, difference and symmetric difference) work on multiple sets at
/// the same time, instead of two.
///
/// # Overview of types
///
/// `Set` is a read only interface to pre-constructed sets. `SetBuilder` is
/// used to create new sets. (Once a set is created, it can never be modified.)
/// `Stream` is a stream of values that originated from a set (analogous to an
/// iterator). `StreamBuilder` builds range queries. `OpBuilder` collects a set
/// of streams and executes set operations like `union` or `intersection` on
/// them. The rest of the types are streams for set operations.
pub mod set {
    pub use inner_set::*;
}
<|endoftext|>


<commit_before>use std::error::Error;
use std::str::FromStr;

pub fn puzzle(input: &str) -> i32 {
    let instructions: Result<Vec<_>, _> = input.lines().map(|line| line.trim().parse()).collect();
    let instructions = instructions.expect("couldn't parse instructions");
    let mut machine = Machine::new();
    machine.execute(&instructions);
    machine.value_of(Register::A)
}

#[derive(Debug, PartialEq, Copy, Clone)]
pub enum Instruction {
    Copy(FromLocation, Register),
    Increment(Register),
    Decrement(Register),
    JumpNonZero(FromLocation, i32),
}

impl FromStr for Instruction {
    type Err = Box<Error>;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        println!("parsing instruction: {}", s);

        let mut parts = s.split_whitespace();
        match parts.next() {
            Some("cpy") => Ok(
                Instruction::Copy(
                    parts.next().ok_or("no from location")?.parse()?,
                    parts.next().ok_or("no register")?.parse()?
                )
            ),
            Some("inc") => Ok(
                Instruction::Increment(
                    parts.next().ok_or("no register")?.parse()?
                )
            ),
            Some("dec") => Ok(
                Instruction::Decrement(
                    parts.next().ok_or("no register")?.parse()?
                )
            ),
            Some("jnz") => Ok(
                Instruction::JumpNonZero(
                    parts.next().ok_or("no register")?.parse()?,
                    parts.next().ok_or("no offset")?.parse()?
                )
            ),
            Some(other) => Err(format!("Unknown instruction: {}", other).into()),
            None => Err("Instruction missing".into()),
        }
    }
}

#[derive(Debug, PartialEq, Copy, Clone)]
pub enum FromLocation {
    Integer(i32),
    Register(Register),
}

impl FromStr for FromLocation {
    type Err = Box<Error>;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        s.parse().map(FromLocation::Integer)
                 .or_else(|_| s.parse().map(FromLocation::Register))
    }
}

#[derive(Debug, PartialEq, Copy, Clone)]
pub enum Register {
    A,
    B,
    C,
    D,
}

impl FromStr for Register {
    type Err = Box<Error>;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        use Register::*;
        match s {
            "a" => Ok(A),
            "b" => Ok(B),
            "c" => Ok(C),
            "d" => Ok(D),
            other => Err(format!("Unknown register {}", other).into()),
        }
    }
}

pub struct Machine {
    registers: [i32; 4],
}

impl Machine {
    pub fn new() -> Machine {
        Machine {
            registers: [0, 0, 1, 0],
        }
    }

    fn execute(&mut self, instructions: &[Instruction]) {
        let mut program_counter = 0;
        while let Some(&instruction) = instructions.get(program_counter) {
            // println!("registers = {:?}", self.registers);
            // println!("executing instruction at {}: {:?}", program_counter, instruction);

            let mut jump = 0;
            match instruction {
                Instruction::Copy(
                    FromLocation::Integer(i),
                    to
                ) => {
                    let index = Machine::register_index(to);
                    self.registers[index] = i;
                },
                Instruction::Copy(FromLocation::Register(from), to) => {
                    let index_from = Machine::register_index(from);
                    let index_to = Machine::register_index(to);
                    self.registers[index_to] = self.registers[index_from];
                },
                Instruction::Increment(register) => {
                    let index = Machine::register_index(register);
                    self.registers[index] += 1;
                },
                Instruction::Decrement(register) => {
                    let index = Machine::register_index(register);
                    self.registers[index] -= 1;
                },
                Instruction::JumpNonZero(FromLocation::Integer(i), offset) => {
                    if i != 0 {
                        jump = offset - 1;
                    }
                },
                Instruction::JumpNonZero(FromLocation::Register(register), offset) => {
                    let index = Machine::register_index(register);
                    if self.registers[index] != 0 {
                        jump = offset - 1;
                    }
                },
            }
            let next_pc = program_counter as i32 + 1 + jump;
            if next_pc < 0 {
                panic!("Jumped too far back!")
            }
            program_counter = next_pc as usize;
        }
    }

    fn register_index(register: Register) -> usize {
        use Register::*;
        match register {
            A => 0,
            B => 1,
            C => 2,
            D => 3,
        }
    }

    fn value_of(&self, register: Register) -> i32 {
        let index = Machine::register_index(register);
        self.registers[index]
    }
}

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

    #[test]
    fn parse_cpy() {
        let instr: Instruction = "cpy 41 a".parse().expect("couldn't parse");
        assert_eq!(
            instr,
            Instruction::Copy(FromLocation::Integer(41), Register::A)
        );
    }

    #[test]
    fn parse_cpy_register() {
        let instr: Instruction = "cpy a c".parse().expect("couldn't parse");
        assert_eq!(
            instr,
            Instruction::Copy(
                FromLocation::Register(Register::A),
                Register::C,
            )
        );
    }

    #[test]
    fn parse_inc() {
        let instr: Instruction = "inc a".parse().expect("couldn't parse");
        assert_eq!(
            instr,
            Instruction::Increment(Register::A)
        );
    }

    #[test]
    fn parse_dec() {
        let instr: Instruction = "dec a".parse().expect("couldn't parse");
        assert_eq!(
            instr,
            Instruction::Decrement(Register::A)
        );
    }

    #[test]
    fn parse_jnz() {
        let instr: Instruction = "jnz a 2".parse().expect("couldn't parse");
        assert_eq!(
            instr,
            Instruction::JumpNonZero(FromLocation::Register(Register::A), 2)
        );
    }

    #[test]
    fn execute_copy() {
        let mut machine = Machine::new();
        machine.execute(
            &[
                Instruction::Copy(
                    FromLocation::Integer(5),
                    Register::A,
                ),
            ]
        );

        assert_eq!(machine.value_of(Register::A), 5);
    }

    #[test]
    fn execute_copy_register() {
        let mut machine = Machine::new();
        machine.execute(
            &[
                Instruction::Copy(
                    FromLocation::Integer(5),
                    Register::A,
                ),
                Instruction::Copy(
                    FromLocation::Register(Register::A),
                    Register::B,
                ),
            ]
        );

        assert_eq!(machine.value_of(Register::B), 5);
    }

    #[test]
    fn execute_increment() {
        let mut machine = Machine::new();
        machine.execute(
            &[
                Instruction::Increment(
                    Register::C,
                ),
            ]
        );

        assert_eq!(machine.value_of(Register::C), 1);
    }

    #[test]
    fn execute_decrement() {
        let mut machine = Machine::new();
        machine.execute(
            &[
                Instruction::Decrement(
                    Register::D,
                ),
            ]
        );

        assert_eq!(machine.value_of(Register::D), -1);
    }

    #[test]
    fn execute_jnz_when_zero() {
        let mut machine = Machine::new();
        machine.execute(
            &[
                // D should be 0, jump doesn't happen
                Instruction::JumpNonZero(FromLocation::Register(Register::D), 2),
                Instruction::Increment(
                    Register::A,
                ),
            ]
        );

        assert_eq!(machine.value_of(Register::A), 1);
    }

    #[test]
    fn execute_jnz_when_non_zero() {
        let mut machine = Machine::new();
        machine.execute(
            &[
                Instruction::Decrement(
                    Register::D,
                ),
                Instruction::JumpNonZero(FromLocation::Register(Register::D), 2),
                Instruction::Increment(
                    Register::A,
                ),
            ]
        );

        assert_eq!(machine.value_of(Register::A), 0);
    }

    #[test]
    fn sample() {
        let input = "cpy 41 a
            inc a
            inc a
            dec a
            jnz a 2
            dec a";
        assert_eq!(puzzle(input), 42);
    }
}
<commit_msg>Quick hacking since I paired on this with Jake yesterday.<commit_after>use std::collections::{VecDeque, HashSet};

pub fn puzzle(input: &str) -> u32 {
    let start_point = Point { x: 1, y: 1};
    let end_point = Point { x: 31, y: 39 };
    let mut queue = VecDeque::new();
    let mut seen = HashSet::new();

    queue.push_back((start_point, 0));
    seen.insert(start_point);

    while let Some((point, distance)) = queue.pop_front() {
        for &neighbor in point.neighbors().iter().filter(|p| is_empty(p)) {
            if neighbor == end_point {
                return distance + 1;
            }
            if !seen.contains(&neighbor) {
                queue.push_back((neighbor, distance + 1));
                seen.insert(neighbor);
            }
        }
    }
    panic!("never got to the end!");
}

#[derive(PartialEq, Eq, Hash, Copy, Clone)]
struct Point {
    x: u32,
    y: u32,
}

impl Point {
    fn neighbors(&self) -> Vec<Point> {
        let changed_xs = [self.x.checked_sub(1), self.x.checked_add(1)];
        let changed_xs = changed_xs.iter()
            .flat_map(|x| x)
            .map(|&x| Point { x: x, y: self.y });
        let changed_ys = [self.y.checked_sub(1), self.y.checked_add(1)];
        let changed_ys = changed_ys.iter()
            .flat_map(|y| y)
            .map(|&y| Point { x: self.x, y: y });

        changed_xs.chain(changed_ys).collect()
    }
}

fn is_empty(point: &Point) -> bool {
    let &Point { x, y } = point;
    (x*x + 3*x + 2*x*y + y + y*y + 1358).count_ones() % 2 == 0
}

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

}
<|endoftext|>


<commit_before>#![crate_name = "rust-github"]
#![crate_type = "rlib"]
#![feature(core)]
extern crate curl;
extern crate "rustc-serialize" as rustc_serialize;

use client::Client;
use users::UserService;
use repositories::RepositoryService;

pub struct Github {
    pub users: UserService,
    pub repositories: RepositoryService,
}

impl Github {
    pub fn new() -> Github {
        let client = Client;
        Github {
            users: UserService::new(client),
            repositories: RepositoryService::new(client),
        }
    }
}

pub mod client;
pub mod users;
pub mod repositories;
<commit_msg>Removed crate dependency & loading issue<commit_after>#![crate_name = "rust_github"]
#![crate_type = "rlib"]
#![feature(core)]
extern crate curl;
extern crate rustc_serialize;

use client::Client;
use users::UserService;
use repositories::RepositoryService;

pub struct Github {
    pub users: UserService,
    pub repositories: RepositoryService,
}

impl Github {
    pub fn new() -> Github {
        let client = Client;
        Github {
            users: UserService::new(client),
            repositories: RepositoryService::new(client),
        }
    }
}

pub mod client;
pub mod users;
pub mod repositories;
<|endoftext|>


<commit_before>#![crate_name = "amethyst"]
#![crate_type = "lib"]

//! Amethyst is a free and open source game engine written in idiomatic
//! [Rust][rs] for building video games and interactive multimedia applications.
//! The source code is available for download on [GitHub][gh].
//!
//! [rs]: https://www.rust-lang.org/
//! [gh]: https://github.com/ebkalderon/amethyst
//!
//! This project is a work in progress and is very incomplete. Pardon the dust!
//!
//! # Example
//!
//! ```ignore
//! extern crate amethyst;
//!
//! use amethyst::*;
//!
//! struct GameState;
//!
//! impl State for GameState {
//!     fn handle_events(&mut self, events: &Vec<Event>) -> Trans {
//!         for e in events {
//!             match e {
//!                 Event::Closed => Trans::Quit,
//!                 Event::Resized(x, y) => println!("x: {}, y: {}", x, y),
//!                 Event::KeyPressed(k) => if k == Key::Esc { Trans::Quit },
//!             }
//!         }
//!         Trans::None
//!     }
//!
//!     fn update(&mut self, _delta: Duration) -> Trans {
//!         println!("Computing some more whoop-ass...");
//!         Trans::None
//!     }
//! }
//!
//! fn main() {
//!     let mut game = Application::new(GameState);
//!     game.run();
//! }
//! ```

mod engine;
pub mod renderer;

pub use self::engine::app::Application;
pub use self::engine::state::{State, StateMachine, Trans};
pub use self::engine::timing::{Duration, Stopwatch};
<commit_msg>add API doc image<commit_after>#![crate_name = "amethyst"]
#![crate_type = "lib"]
#![doc(html_logo_url = "https://raw.githubusercontent.com/ebkalderon/amethyst/master/book/images/amethyst_thumb.png")]

//! Amethyst is a free and open source game engine written in idiomatic
//! [Rust][rs] for building video games and interactive multimedia applications.
//! The source code is available for download on [GitHub][gh].
//!
//! [rs]: https://www.rust-lang.org/
//! [gh]: https://github.com/ebkalderon/amethyst
//!
//! This project is a work in progress and is very incomplete. Pardon the dust!
//!
//! # Example
//!
//! ```ignore
//! extern crate amethyst;
//!
//! use amethyst::*;
//!
//! struct GameState;
//!
//! impl State for GameState {
//!     fn handle_events(&mut self, events: &Vec<Event>) -> Trans {
//!         for e in events {
//!             match e {
//!                 Event::Closed => Trans::Quit,
//!                 Event::Resized(x, y) => println!("x: {}, y: {}", x, y),
//!                 Event::KeyPressed(k) => if k == Key::Esc { Trans::Quit },
//!             }
//!         }
//!         Trans::None
//!     }
//!
//!     fn update(&mut self, _delta: Duration) -> Trans {
//!         println!("Computing some more whoop-ass...");
//!         Trans::None
//!     }
//! }
//!
//! fn main() {
//!     let mut game = Application::new(GameState);
//!     game.run();
//! }
//! ```

mod engine;
pub mod renderer;

pub use self::engine::app::Application;
pub use self::engine::state::{State, StateMachine, Trans};
pub use self::engine::timing::{Duration, Stopwatch};
<|endoftext|>


<commit_before>// Copyright (c) 2015, 2016, 2017 Mark Lee
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! A set of [cryptographic hash
//! functions](https://en.wikipedia.org/wiki/Cryptographic_hash_function) provided by the operating
//! system, when available.
//!
//! The purpose of this crate is to provide access to hash algorithms with as few dependencies as
//! possible. This means that when possible, the library uses the hashing functions that are
//! provided by the given operating system's bundled cryptographic libraries.
//!
//! # Supported Implementations
//!
//! By operating system:
//!
//! * Windows: `CryptoAPI`
//! * Mac OS X: `CommonCrypto`
//! * Linux/BSD/etc.: `OpenSSL`
//!
//! # Supported Algorithms
//!
//! * MD5
//! * SHA1
//! * SHA256
//! * SHA512

#![warn(missing_docs)]

#[cfg(any(target_os = "macos", target_os = "ios"))]
extern crate commoncrypto;
extern crate hex;
#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "windows")))]
extern crate openssl;
#[cfg(target_os = "windows")]
extern crate winapi;

use std::io::Write;

#[cfg(any(target_os = "macos", target_os = "ios"))]
#[path = "imp/commoncrypto.rs"]
mod imp;
#[cfg(target_os = "windows")]
#[path = "imp/cryptoapi.rs"]
mod imp;
#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "windows")))]
#[path = "imp/openssl.rs"]
mod imp;

mod test;

pub use imp::Hasher;

/// Available cryptographic hash functions.
#[derive(Clone, Debug)]
pub enum Algorithm {
    /// Popular message digest algorithm, only available for backwards compatibility purposes.
    MD5,
    /// SHA-1 algorithm from NIST FIPS, only available for backwards compatibility purposes.
    SHA1,
    /// SHA-2 family algorithm (256 bits).
    SHA256,
    /// SHA-2 family algorithm (512 bits).
    SHA512,
}

/// Helper function for `Hasher` which generates a cryptographic digest from the given
/// data and algorithm.
///
/// # Examples
///
/// ```rust
/// use crypto_hash::{Algorithm, digest};
///
/// let data = b"crypto-hash";
/// let result = digest(Algorithm::SHA256, data);
/// let expected =
///     b"\xfd\x1a\xfb`\"\xcdMG\xc8\x90\x96\x1cS9(\xea\xcf\xe8!\x9f\x1b%$\xf7\xfb*a\x84}\xdf\x8c'"
///     .to_vec();
/// assert_eq!(expected, result)
/// ```
pub fn digest(algorithm: Algorithm, data: &[u8]) -> Vec<u8> {
    let mut hasher = imp::Hasher::new(&algorithm);
    hasher.write_all(data).expect("Could not write hash data");
    hasher.finish()
}

/// Helper function for `Hasher` which generates a cryptographic digest serialized in
/// hexadecimal from the given data and algorithm.
///
/// # Examples
///
/// ```rust
/// use crypto_hash::{Algorithm, hex_digest};
///
/// let data = b"crypto-hash";
/// let result = hex_digest(Algorithm::SHA256, data);
/// let expected = "fd1afb6022cd4d47c890961c533928eacfe8219f1b2524f7fb2a61847ddf8c27";
/// assert_eq!(expected, result)
/// ```
pub fn hex_digest(algorithm: Algorithm, data: &[u8]) -> String {
    hex::encode(digest(algorithm, data))
}
<commit_msg>Rustfmt<commit_after>// Copyright (c) 2015, 2016, 2017 Mark Lee
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! A set of [cryptographic hash
//! functions](https://en.wikipedia.org/wiki/Cryptographic_hash_function) provided by the operating
//! system, when available.
//!
//! The purpose of this crate is to provide access to hash algorithms with as few dependencies as
//! possible. This means that when possible, the library uses the hashing functions that are
//! provided by the given operating system's bundled cryptographic libraries.
//!
//! # Supported Implementations
//!
//! By operating system:
//!
//! * Windows: `CryptoAPI`
//! * Mac OS X: `CommonCrypto`
//! * Linux/BSD/etc.: `OpenSSL`
//!
//! # Supported Algorithms
//!
//! * MD5
//! * SHA1
//! * SHA256
//! * SHA512

#![warn(missing_docs)]

#[cfg(any(target_os = "macos", target_os = "ios"))]
extern crate commoncrypto;
extern crate hex;
#[cfg(
    not(
        any(
            target_os = "macos",
            target_os = "ios",
            target_os = "windows"
        )
    )
)]
extern crate openssl;
#[cfg(target_os = "windows")]
extern crate winapi;

use std::io::Write;

#[cfg(any(target_os = "macos", target_os = "ios"))]
#[path = "imp/commoncrypto.rs"]
mod imp;
#[cfg(target_os = "windows")]
#[path = "imp/cryptoapi.rs"]
mod imp;
#[cfg(
    not(
        any(
            target_os = "macos",
            target_os = "ios",
            target_os = "windows"
        )
    )
)]
#[path = "imp/openssl.rs"]
mod imp;

mod test;

pub use imp::Hasher;

/// Available cryptographic hash functions.
#[derive(Clone, Debug)]
pub enum Algorithm {
    /// Popular message digest algorithm, only available for backwards compatibility purposes.
    MD5,
    /// SHA-1 algorithm from NIST FIPS, only available for backwards compatibility purposes.
    SHA1,
    /// SHA-2 family algorithm (256 bits).
    SHA256,
    /// SHA-2 family algorithm (512 bits).
    SHA512,
}

/// Helper function for `Hasher` which generates a cryptographic digest from the given
/// data and algorithm.
///
/// # Examples
///
/// ```rust
/// use crypto_hash::{Algorithm, digest};
///
/// let data = b"crypto-hash";
/// let result = digest(Algorithm::SHA256, data);
/// let expected =
///     b"\xfd\x1a\xfb`\"\xcdMG\xc8\x90\x96\x1cS9(\xea\xcf\xe8!\x9f\x1b%$\xf7\xfb*a\x84}\xdf\x8c'"
///     .to_vec();
/// assert_eq!(expected, result)
/// ```
pub fn digest(algorithm: Algorithm, data: &[u8]) -> Vec<u8> {
    let mut hasher = imp::Hasher::new(&algorithm);
    hasher.write_all(data).expect("Could not write hash data");
    hasher.finish()
}

/// Helper function for `Hasher` which generates a cryptographic digest serialized in
/// hexadecimal from the given data and algorithm.
///
/// # Examples
///
/// ```rust
/// use crypto_hash::{Algorithm, hex_digest};
///
/// let data = b"crypto-hash";
/// let result = hex_digest(Algorithm::SHA256, data);
/// let expected = "fd1afb6022cd4d47c890961c533928eacfe8219f1b2524f7fb2a61847ddf8c27";
/// assert_eq!(expected, result)
/// ```
pub fn hex_digest(algorithm: Algorithm, data: &[u8]) -> String {
    hex::encode(digest(algorithm, data))
}
<|endoftext|>


<commit_before>pub fn quicksort<T: PartialEq + PartialOrd>(vec: &mut [T]) -> &mut [T] {
    if vec.len() <= 1 {
        return vec;
    }
    let pivot: usize = 0;
    let mut first_opened = Vec::new();
    let mut last_closed: usize = 0;

    for i in 1..vec.len() {
        first_opened.push(i);
        if vec[i] < vec[pivot] {
            let to = first_opened.remove(0);
            vec.swap(i, to);
            last_closed = to;
        }
    }

    vec.swap(pivot, last_closed);
    quicksort(&mut vec[0..last_closed]);
    quicksort(&mut vec[last_closed+1..]);
    vec
}

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

    #[test]
    fn it_works() {
        let mut sorted = vec![1, 1, 2, 3, 3, 4, 5, 5, 6, 9];
        let mut unsorted = vec![3, 1, 4, 1, 5, 9, 2, 6, 5, 3];
        quicksort(&mut unsorted);

        assert_eq!(unsorted, sorted.as_slice());
    }
}
<commit_msg>Rename test case<commit_after>pub fn quicksort<T: PartialEq + PartialOrd>(vec: &mut [T]) -> &mut [T] {
    if vec.len() <= 1 {
        return vec;
    }
    let pivot: usize = 0;
    let mut first_opened = Vec::new();
    let mut last_closed: usize = 0;

    for i in 1..vec.len() {
        first_opened.push(i);
        if vec[i] < vec[pivot] {
            let to = first_opened.remove(0);
            vec.swap(i, to);
            last_closed = to;
        }
    }

    vec.swap(pivot, last_closed);
    quicksort(&mut vec[0..last_closed]);
    quicksort(&mut vec[last_closed+1..]);
    vec
}

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

    #[test]
    fn test_vec_of_u64() {
        let sorted: Vec<u64> = vec![1, 1, 2, 3, 3, 4, 5, 5, 6, 9];
        let mut unsorted: Vec<u64> = vec![3, 1, 4, 1, 5, 9, 2, 6, 5, 3];
        quicksort(&mut unsorted);

        assert_eq!(unsorted, sorted.as_slice());
    }
}
<|endoftext|>


<commit_before>// Copyright (c) <2015> <lummax>
// Licensed under MIT (http://opensource.org/licenses/MIT)

#![feature(libc)]
#![feature(os)]
#![feature(core)]
#![feature(std_misc)]
#![feature(collections)]
#![feature(link_llvm_intrinsics)]

extern crate libc;
use std::{mem, ptr};

pub use self::gc_object::{GCHeader, GCRTTI, GCObject, GCObjectRef};

mod macros;
mod constants;
mod gc_object;
mod spaces;
mod stack;

/// The `RCImmixCons` garbage collector.
///
/// This is the conservative reference counting garbage collector with the
/// immix heap partition schema.
///
/// The `allocate()` function will return a pointer to a `GCObject`. Please
/// see the documentation of `GCHeader`, `GCRTTI` and `GCObject` for details.
///
/// Always call `write_barrier()` on an object before modifying its members.
pub struct RCImmixCons {
    /// The different spaces of this garbage collector.
    spaces: spaces::Spaces,
}

impl RCImmixCons {
    /// Create a new `RCImmixCons`.
    pub fn new() -> RCImmixCons {
        return RCImmixCons {
            spaces: spaces::Spaces::new(),
        };
    }

    /// Allocate a new object described by the `rtti` or returns `None`.
    ///
    /// This may trigger a garbage collection if the allocation was not
    /// succussful. If there is still no memory to fullfill the allocation
    /// request return `None`.
    pub fn allocate(&mut self, rtti: *const GCRTTI) -> Option<GCObjectRef> {
        return self.spaces.allocate(rtti)
                   .or_else(|| { self.collect(true, true);
                                 self.spaces.allocate(rtti) });
    }

    /// Trigger a garbage collection.
    ///
    /// This will always run the referece counting collector. If `evacuation`
    /// is set the collectors will try to evacuate. If `cycle_collect` is set
    /// the immix tracing collector will be used.
    pub fn collect(&mut self, evacuation: bool, cycle_collect: bool) {
        return self.spaces.collect(evacuation, cycle_collect);
    }

    /// A write barrier for the given `object`.
    ///
    /// Call this function before modifying the members of this object!
    pub fn write_barrier(&mut self, object: GCObjectRef) {
        return self.spaces.write_barrier(object);
    }
}

#[no_mangle]
pub extern fn rcx_create() -> *mut RCImmixCons {
    return unsafe { mem::transmute(Box::new(RCImmixCons::new())) };
}

#[no_mangle]
pub extern fn rcx_allocate(this: *mut RCImmixCons, rtti: *const GCRTTI)
    -> GCObjectRef {
    unsafe { return (*this).allocate(rtti).unwrap_or(ptr::null_mut()); }
}

#[no_mangle]
pub extern fn rcx_collect(this: *mut RCImmixCons, evacuation: bool, cycle_collect: bool) {
    unsafe { (*this).collect(evacuation, cycle_collect) };
}

#[no_mangle]
pub extern fn rcx_write_barrier(this: *mut RCImmixCons, object: GCObjectRef) {
    unsafe { (*this).write_barrier(object) };
}

#[no_mangle]
pub extern fn rcx_destroy(this: *mut RCImmixCons) {
    let _to_be_dropped: Box<RCImmixCons> = unsafe{ mem::transmute(this) };
}
<commit_msg>Replace mem:transmute() with from_raw()/into_raw()<commit_after>// Copyright (c) <2015> <lummax>
// Licensed under MIT (http://opensource.org/licenses/MIT)

#![feature(libc)]
#![feature(os)]
#![feature(core)]
#![feature(alloc)]
#![feature(std_misc)]
#![feature(collections)]
#![feature(link_llvm_intrinsics)]

extern crate libc;
use std::ptr;

pub use self::gc_object::{GCHeader, GCRTTI, GCObject, GCObjectRef};

mod macros;
mod constants;
mod gc_object;
mod spaces;
mod stack;

/// The `RCImmixCons` garbage collector.
///
/// This is the conservative reference counting garbage collector with the
/// immix heap partition schema.
///
/// The `allocate()` function will return a pointer to a `GCObject`. Please
/// see the documentation of `GCHeader`, `GCRTTI` and `GCObject` for details.
///
/// Always call `write_barrier()` on an object before modifying its members.
pub struct RCImmixCons {
    /// The different spaces of this garbage collector.
    spaces: spaces::Spaces,
}

impl RCImmixCons {
    /// Create a new `RCImmixCons`.
    pub fn new() -> RCImmixCons {
        return RCImmixCons {
            spaces: spaces::Spaces::new(),
        };
    }

    /// Allocate a new object described by the `rtti` or returns `None`.
    ///
    /// This may trigger a garbage collection if the allocation was not
    /// succussful. If there is still no memory to fullfill the allocation
    /// request return `None`.
    pub fn allocate(&mut self, rtti: *const GCRTTI) -> Option<GCObjectRef> {
        return self.spaces.allocate(rtti)
                   .or_else(|| { self.collect(true, true);
                                 self.spaces.allocate(rtti) });
    }

    /// Trigger a garbage collection.
    ///
    /// This will always run the referece counting collector. If `evacuation`
    /// is set the collectors will try to evacuate. If `cycle_collect` is set
    /// the immix tracing collector will be used.
    pub fn collect(&mut self, evacuation: bool, cycle_collect: bool) {
        return self.spaces.collect(evacuation, cycle_collect);
    }

    /// A write barrier for the given `object`.
    ///
    /// Call this function before modifying the members of this object!
    pub fn write_barrier(&mut self, object: GCObjectRef) {
        return self.spaces.write_barrier(object);
    }
}

#[no_mangle]
pub extern fn rcx_create() -> *mut RCImmixCons {
    return unsafe { std::boxed::into_raw(Box::new(RCImmixCons::new())) };
}

#[no_mangle]
pub extern fn rcx_allocate(this: *mut RCImmixCons, rtti: *const GCRTTI)
    -> GCObjectRef {
    unsafe { return (*this).allocate(rtti).unwrap_or(ptr::null_mut()); }
}

#[no_mangle]
pub extern fn rcx_collect(this: *mut RCImmixCons, evacuation: bool, cycle_collect: bool) {
    unsafe { (*this).collect(evacuation, cycle_collect) };
}

#[no_mangle]
pub extern fn rcx_write_barrier(this: *mut RCImmixCons, object: GCObjectRef) {
    unsafe { (*this).write_barrier(object) };
}

#[no_mangle]
pub extern fn rcx_destroy(this: *mut RCImmixCons) {
    let _to_be_dropped = unsafe{ Box::from_raw(this) };
}
<|endoftext|>