<commit_before>#[macro_use]
extern crate nom;

pub mod metadata;
mod frame;
mod utility;

use metadata::metadata_parser;

pub struct Stream {
  pub info: metadata::StreamInfo,
  pub metadata: Vec<metadata::Block>,
  pub frames: Vec<frame::Frame>
}

named!(stream <&[u8], Stream>,
  chain!(
    blocks: metadata_parser ~
    move|| {
      Stream {
        info: blocks.0,
        metadata: blocks.1,
      }
    }
  )
);
<commit_msg>Parse and add frames to stream parser<commit_after>#[macro_use]
extern crate nom;

pub mod metadata;
mod frame;
mod utility;

use metadata::metadata_parser;
use frame::frame_parser;

pub struct Stream {
  pub info: metadata::StreamInfo,
  pub metadata: Vec<metadata::Block>,
  pub frames: Vec<frame::Frame>
}

named!(stream <&[u8], Stream>,
  chain!(
    blocks: metadata_parser ~
    frames: many1!(apply!(frame_parser, blocks.0.channels)),
    move|| {
      Stream {
        info: blocks.0,
        metadata: blocks.1,
        frames: frames,
      }
    }
  )
);
<|endoftext|>


<commit_before>#![cfg_attr(feature = "cargo-clippy", allow(large_enum_variant))]

#[cfg(feature = "printing")]
extern crate quote;

#[cfg(feature = "parsing")]
extern crate unicode_xid;

#[cfg(feature = "parsing")]
#[macro_use]
extern crate synom;

#[cfg(feature = "aster")]
pub mod aster;

mod attr;
pub use attr::{Attribute, AttrStyle, MetaItem, NestedMetaItem};

mod constant;
pub use constant::ConstExpr;

mod data;
pub use data::{Field, Variant, VariantData, Visibility};

#[cfg(feature = "parsing")]
mod escape;

#[cfg(feature = "full")]
mod expr;
#[cfg(feature = "full")]
pub use expr::{Arm, BindingMode, Block, CaptureBy, Expr, ExprKind, FieldPat, FieldValue,
               Local, MacStmtStyle, Pat, RangeLimits, Stmt};

mod generics;
pub use generics::{Generics, Lifetime, LifetimeDef, TraitBoundModifier, TyParam, TyParamBound,
                   WhereBoundPredicate, WhereClause, WhereEqPredicate, WherePredicate,
                   WhereRegionPredicate};
#[cfg(feature = "printing")]
pub use generics::{ImplGenerics, Turbofish, TyGenerics};

mod ident;
pub use ident::Ident;

#[cfg(feature = "full")]
mod item;
#[cfg(feature = "full")]
pub use item::{Constness, Defaultness, FnArg, FnDecl, ForeignItemKind, ForeignItem, ForeignMod,
               ImplItem, ImplItemKind, ImplPolarity, Item, ItemKind, MethodSig, PathListItem,
               TraitItem, TraitItemKind, ViewPath};

#[cfg(feature = "full")]
mod krate;
#[cfg(feature = "full")]
pub use krate::Crate;

mod lit;
pub use lit::{FloatTy, IntTy, Lit, StrStyle};
#[cfg(feature = "parsing")]
pub use lit::{ByteStrLit, FloatLit, IntLit, StrLit};

mod mac;
pub use mac::{BinOpToken, DelimToken, Delimited, Mac, Token, TokenTree};

mod derive;
pub use derive::{Body, DeriveInput};
// Deprecated. Use `DeriveInput` instead.
#[doc(hidden)]
pub type MacroInput = DeriveInput;

mod op;
pub use op::{BinOp, UnOp};

mod ty;
pub use ty::{Abi, AngleBracketedParameterData, BareFnArg, BareFnTy, FunctionRetTy, MutTy,
             Mutability, ParenthesizedParameterData, Path, PathParameters, PathSegment,
             PolyTraitRef, QSelf, Ty, TypeBinding, Unsafety};

#[cfg(feature = "visit")]
pub mod visit;

#[cfg(feature = "fold")]
pub mod fold;

#[cfg(feature = "parsing")]
pub use parsing::*;

#[cfg(feature = "parsing")]
mod parsing {
    use super::*;
    use {derive, generics, ident, mac, ty};
    use synom::{space, IResult};

    #[cfg(feature = "full")]
    use {expr, item, krate};

    pub fn parse_derive_input(input: &str) -> Result<DeriveInput, String> {
        unwrap("derive input", derive::parsing::derive_input, input)
    }

    #[cfg(feature = "full")]
    pub fn parse_crate(input: &str) -> Result<Crate, String> {
        unwrap("crate", krate::parsing::krate, input)
    }

    #[cfg(feature = "full")]
    pub fn parse_item(input: &str) -> Result<Item, String> {
        unwrap("item", item::parsing::item, input)
    }

    #[cfg(feature = "full")]
    pub fn parse_items(input: &str) -> Result<Vec<Item>, String> {
        unwrap("items", item::parsing::items, input)
    }

    #[cfg(feature = "full")]
    pub fn parse_expr(input: &str) -> Result<Expr, String> {
        unwrap("expression", expr::parsing::expr, input)
    }

    pub fn parse_type(input: &str) -> Result<Ty, String> {
        unwrap("type", ty::parsing::ty, input)
    }

    pub fn parse_path(input: &str) -> Result<Path, String> {
        unwrap("path", ty::parsing::path, input)
    }

    pub fn parse_where_clause(input: &str) -> Result<WhereClause, String> {
        unwrap("where clause", generics::parsing::where_clause, input)
    }

    pub fn parse_token_trees(input: &str) -> Result<Vec<TokenTree>, String> {
        unwrap("token trees", mac::parsing::token_trees, input)
    }

    pub fn parse_ident(input: &str) -> Result<Ident, String> {
        unwrap("identifier", ident::parsing::ident, input)
    }

    pub fn parse_ty_param_bound(input: &str) -> Result<TyParamBound, String> {
        unwrap("type parameter bound", generics::parsing::ty_param_bound, input)
    }

    // Deprecated. Use `parse_derive_input` instead.
    #[doc(hidden)]
    pub fn parse_macro_input(input: &str) -> Result<MacroInput, String> {
        parse_derive_input(input)
    }

    fn unwrap<T>(name: &'static str,
                 f: fn(&str) -> IResult<&str, T>,
                 input: &str)
                 -> Result<T, String> {
        match f(input) {
            IResult::Done(mut rest, t) => {
                rest = space::skip_whitespace(rest);
                if rest.is_empty() {
                    Ok(t)
                } else if rest.len() == input.len() {
                    // parsed nothing
                    Err(format!("failed to parse {}: {:?}", name, rest))
                } else {
                    Err(format!("unparsed tokens after {}: {:?}", name, rest))
                }
            }
            IResult::Error => Err(format!("failed to parse {}: {:?}", name, input)),
        }
    }
}

#[cfg(feature = "parsing")]
pub mod parse {
    //! This module contains a set of exported nom parsers which can be used to
    //! parse custom grammars when used alongside the `synom` crate.
    //!
    //! Internally, `syn` uses a fork of `nom` called `synom` which resolves a
    //! persistent pitfall of using `nom` to parse Rust by eliminating the
    //! `IResult::Incomplete` variant. The `synom` crate should be used instead
    //! of `nom` when working with the parsers in this module.

    pub use synom::IResult;

    #[cfg(feature = "full")]
    pub use item::parsing::item;

    #[cfg(feature = "full")]
    pub use expr::parsing::{expr, pat, block, stmt};

    pub use lit::parsing::{lit, string, byte_string, byte, character, float, int, boolean};

    pub use ty::parsing::{ty, path};

    pub use mac::parsing::token_tree as tt;

    pub use ident::parsing::ident;

    pub use generics::parsing::lifetime;
}
<commit_msg>public attribute parsers<commit_after>#![cfg_attr(feature = "cargo-clippy", allow(large_enum_variant))]

#[cfg(feature = "printing")]
extern crate quote;

#[cfg(feature = "parsing")]
extern crate unicode_xid;

#[cfg(feature = "parsing")]
#[macro_use]
extern crate synom;

#[cfg(feature = "aster")]
pub mod aster;

mod attr;
pub use attr::{Attribute, AttrStyle, MetaItem, NestedMetaItem};

mod constant;
pub use constant::ConstExpr;

mod data;
pub use data::{Field, Variant, VariantData, Visibility};

#[cfg(feature = "parsing")]
mod escape;

#[cfg(feature = "full")]
mod expr;
#[cfg(feature = "full")]
pub use expr::{Arm, BindingMode, Block, CaptureBy, Expr, ExprKind, FieldPat, FieldValue,
               Local, MacStmtStyle, Pat, RangeLimits, Stmt};

mod generics;
pub use generics::{Generics, Lifetime, LifetimeDef, TraitBoundModifier, TyParam, TyParamBound,
                   WhereBoundPredicate, WhereClause, WhereEqPredicate, WherePredicate,
                   WhereRegionPredicate};
#[cfg(feature = "printing")]
pub use generics::{ImplGenerics, Turbofish, TyGenerics};

mod ident;
pub use ident::Ident;

#[cfg(feature = "full")]
mod item;
#[cfg(feature = "full")]
pub use item::{Constness, Defaultness, FnArg, FnDecl, ForeignItemKind, ForeignItem, ForeignMod,
               ImplItem, ImplItemKind, ImplPolarity, Item, ItemKind, MethodSig, PathListItem,
               TraitItem, TraitItemKind, ViewPath};

#[cfg(feature = "full")]
mod krate;
#[cfg(feature = "full")]
pub use krate::Crate;

mod lit;
pub use lit::{FloatTy, IntTy, Lit, StrStyle};
#[cfg(feature = "parsing")]
pub use lit::{ByteStrLit, FloatLit, IntLit, StrLit};

mod mac;
pub use mac::{BinOpToken, DelimToken, Delimited, Mac, Token, TokenTree};

mod derive;
pub use derive::{Body, DeriveInput};
// Deprecated. Use `DeriveInput` instead.
#[doc(hidden)]
pub type MacroInput = DeriveInput;

mod op;
pub use op::{BinOp, UnOp};

mod ty;
pub use ty::{Abi, AngleBracketedParameterData, BareFnArg, BareFnTy, FunctionRetTy, MutTy,
             Mutability, ParenthesizedParameterData, Path, PathParameters, PathSegment,
             PolyTraitRef, QSelf, Ty, TypeBinding, Unsafety};

#[cfg(feature = "visit")]
pub mod visit;

#[cfg(feature = "fold")]
pub mod fold;

#[cfg(feature = "parsing")]
pub use parsing::*;

#[cfg(feature = "parsing")]
mod parsing {
    use super::*;
    use {derive, generics, ident, mac, ty};
    use synom::{space, IResult};

    #[cfg(feature = "full")]
    use {expr, item, krate};

    pub fn parse_derive_input(input: &str) -> Result<DeriveInput, String> {
        unwrap("derive input", derive::parsing::derive_input, input)
    }

    #[cfg(feature = "full")]
    pub fn parse_crate(input: &str) -> Result<Crate, String> {
        unwrap("crate", krate::parsing::krate, input)
    }

    #[cfg(feature = "full")]
    pub fn parse_item(input: &str) -> Result<Item, String> {
        unwrap("item", item::parsing::item, input)
    }

    #[cfg(feature = "full")]
    pub fn parse_items(input: &str) -> Result<Vec<Item>, String> {
        unwrap("items", item::parsing::items, input)
    }

    #[cfg(feature = "full")]
    pub fn parse_expr(input: &str) -> Result<Expr, String> {
        unwrap("expression", expr::parsing::expr, input)
    }

    pub fn parse_type(input: &str) -> Result<Ty, String> {
        unwrap("type", ty::parsing::ty, input)
    }

    pub fn parse_path(input: &str) -> Result<Path, String> {
        unwrap("path", ty::parsing::path, input)
    }

    pub fn parse_where_clause(input: &str) -> Result<WhereClause, String> {
        unwrap("where clause", generics::parsing::where_clause, input)
    }

    pub fn parse_token_trees(input: &str) -> Result<Vec<TokenTree>, String> {
        unwrap("token trees", mac::parsing::token_trees, input)
    }

    pub fn parse_ident(input: &str) -> Result<Ident, String> {
        unwrap("identifier", ident::parsing::ident, input)
    }

    pub fn parse_ty_param_bound(input: &str) -> Result<TyParamBound, String> {
        unwrap("type parameter bound", generics::parsing::ty_param_bound, input)
    }

    pub fn parse_outer_attr(input: &str) -> Result<Attribute, String> {
        unwrap("outer attribute", attr::parsing::outer_attr, input)
    }

    #[cfg(feature = "full")]
    pub fn parse_inner_attr(input: &str) -> Result<Attribute, String> {
        unwrap("inner attribute", attr::parsing::inner_attr, input)
    }

    // Deprecated. Use `parse_derive_input` instead.
    #[doc(hidden)]
    pub fn parse_macro_input(input: &str) -> Result<MacroInput, String> {
        parse_derive_input(input)
    }

    fn unwrap<T>(name: &'static str,
                 f: fn(&str) -> IResult<&str, T>,
                 input: &str)
                 -> Result<T, String> {
        match f(input) {
            IResult::Done(mut rest, t) => {
                rest = space::skip_whitespace(rest);
                if rest.is_empty() {
                    Ok(t)
                } else if rest.len() == input.len() {
                    // parsed nothing
                    Err(format!("failed to parse {}: {:?}", name, rest))
                } else {
                    Err(format!("unparsed tokens after {}: {:?}", name, rest))
                }
            }
            IResult::Error => Err(format!("failed to parse {}: {:?}", name, input)),
        }
    }
}

#[cfg(feature = "parsing")]
pub mod parse {
    //! This module contains a set of exported nom parsers which can be used to
    //! parse custom grammars when used alongside the `synom` crate.
    //!
    //! Internally, `syn` uses a fork of `nom` called `synom` which resolves a
    //! persistent pitfall of using `nom` to parse Rust by eliminating the
    //! `IResult::Incomplete` variant. The `synom` crate should be used instead
    //! of `nom` when working with the parsers in this module.

    pub use synom::IResult;

    #[cfg(feature = "full")]
    pub use item::parsing::item;

    #[cfg(feature = "full")]
    pub use expr::parsing::{expr, pat, block, stmt};

    pub use lit::parsing::{lit, string, byte_string, byte, character, float, int, boolean};

    pub use ty::parsing::{ty, path};

    pub use mac::parsing::token_tree as tt;

    pub use ident::parsing::ident;

    pub use generics::parsing::lifetime;
}
<|endoftext|>


<commit_before>#![deny(missing_docs, warnings)]

//! Request logging middleware for Iron

extern crate iron;
extern crate term;
extern crate time;

use iron::{AfterMiddleware, BeforeMiddleware, IronResult, IronError, Request, Response, status};
use iron::typemap::Key;
use term::{StdoutTerminal, color, stdout};

use std::io;
use std::io::Write;

use format::FormatText::{Str, Method, URI, Status, ResponseTime, RemoteAddr, RequestTime};
use format::FormatColor::{ConstantColor, FunctionColor};
use format::FormatAttr::{ConstantAttrs, FunctionAttrs};
use format::{Format, FormatText};

pub mod format;

/// `Middleware` for logging request and response info to the terminal.
pub struct Logger {
    format: Option<Format>
}

impl Logger {
    /// Create a pair of `Logger` middlewares with the specified `format`. If a `None` is passed in, uses the default format:
    ///
    /// ```ignore
    /// {method} {uri} -> {status} ({response-time} ms)
    /// ```
    ///
    /// While the returned value can be passed straight to `Chain::link`, consider making the logger `BeforeMiddleware`
    /// the first in your chain and the logger `AfterMiddleware` the last by doing something like this:
    ///
    /// ```ignore
    /// let mut chain = Chain::new(handler);
    /// let (logger_before, logger_after) = Logger::new(None);
    /// chain.link_before(logger_before);
    /// // link other middlewares here...
    /// chain.link_after(logger_after);
    /// ```
    pub fn new(format: Option<Format>) -> (Logger, Logger) {
        (Logger { format: format.clone() }, Logger { format: format })
    }
}

struct StartTime;
impl Key for StartTime { type Value = time::Tm; }

impl Logger {
    fn initialise(&self, req: &mut Request) {
        req.extensions.insert::<StartTime>(time::now());
    }

    fn log(&self, req: &mut Request, res: &Response) -> IronResult<()> {
        let entry_time = *req.extensions.get::<StartTime>().unwrap();

        let response_time = time::now() - entry_time;
        let response_time_ms = (response_time.num_seconds() * 1000) as f64 + (response_time.num_nanoseconds().unwrap_or(0) as f64) / 1000000.0;
        let Format(format) = self.format.clone().unwrap_or_default();

        {
            macro_rules! tryio {
                ($expr:expr) => (match $expr {
                    std::result::Result::Ok(val) => val,
                    std::result::Result::Err(err) => {
                        return Err(IronError::new(err, status::InternalServerError))
                    }
                })
            }

            let render = |text: &FormatText| {
                match *text {
                    Str(ref string) => string.clone(),
                    Method => format!("{}", req.method),
                    URI => format!("{}", req.url),
                    Status => format!("{}", res.status.unwrap()),
                    ResponseTime => format!("{} ms", response_time_ms),
                    RemoteAddr => format!("{}", req.remote_addr),
                    RequestTime => format!("{}", entry_time.strftime("%Y-%m-%dT%H:%M:%S.%fZ%z").unwrap()),
                }
            };

            let log = |w: &mut LogWriter| -> IronResult<()> {
                for unit in format.iter() {
                    let c = match unit.color {
                        ConstantColor(color) => color,
                        FunctionColor(f) => f(req, res)
                    };
                    let fn_attrs;
                    let ref attrs = match unit.attrs {
                        ConstantAttrs(ref attrs) => attrs,
                        FunctionAttrs(f) => {
                            fn_attrs = f(req, res);
                            &fn_attrs
                        }
                    };
                    tryio!(w.write_item(render(&unit.text), c, attrs));
                }
                tryio!(w.new_line());
                Ok(())
            };

            match stdout() {
                Some(terminal) => {
                    try!(log(&mut TermWriter::new(terminal)));
                }
                None => {
                    try!(log(&mut io::stdout()));
                }
            };
        }

        Ok(())
    }
}

trait LogWriter {
    fn write_item(&mut self, text: String, color: Option<color::Color>, attrs: &Vec<term::Attr>) -> io::Result<()>;
    fn new_line(&mut self) -> io::Result<()>;
}

struct TermWriter {
    term: Box<StdoutTerminal>
}

impl TermWriter {
    fn new(term: Box<StdoutTerminal>) -> TermWriter {
        TermWriter {
            term: term
        }
    }
}

impl LogWriter for TermWriter {
    fn write_item(&mut self, text: String, color: Option<color::Color>, attrs: &Vec<term::Attr>) -> io::Result<()> {
        match color {
            Some(c) => { try!(self.term.fg(c)); }
            None => {},
        }
        for &attr in attrs.iter() {
            try!(self.term.attr(attr));
        }
        try!(write!(self.term, "{}", text));
        try!(self.term.reset());
        Ok(())
    }

    fn new_line(&mut self) -> io::Result<()> {
        try!(writeln!(self.term, ""));
        Ok(())
    }
}

impl<T: Write> LogWriter for T {
    fn write_item(&mut self, text: String, _: Option<color::Color>, _: &Vec<term::Attr>) -> io::Result<()> {
        try!(write!(self, "{}", text));
        Ok(())
    }

    fn new_line(&mut self) -> io::Result<()> {
        try!(writeln!(self, ""));
        Ok(())
    }
}

impl BeforeMiddleware for Logger {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        self.initialise(req);
        Ok(())
    }

    fn catch(&self, req: &mut Request, err: IronError) -> IronResult<()> {
        self.initialise(req);
        Err(err)
    }
}

impl AfterMiddleware for Logger {
    fn after(&self, req: &mut Request, res: Response) -> IronResult<Response> {
        try!(self.log(req, &res));
        Ok(res)
    }

    fn catch(&self, req: &mut Request, err: IronError) -> IronResult<Response> {
        try!(self.log(req, &err.response));
        Err(err)
    }
}
<commit_msg>Log if a request doesn't have the status code set<commit_after>#![deny(missing_docs, warnings)]

//! Request logging middleware for Iron

extern crate iron;
extern crate term;
extern crate time;

use iron::{AfterMiddleware, BeforeMiddleware, IronResult, IronError, Request, Response, status};
use iron::typemap::Key;
use term::{StdoutTerminal, color, stdout};

use std::io;
use std::io::Write;

use format::FormatText::{Str, Method, URI, Status, ResponseTime, RemoteAddr, RequestTime};
use format::FormatColor::{ConstantColor, FunctionColor};
use format::FormatAttr::{ConstantAttrs, FunctionAttrs};
use format::{Format, FormatText};

pub mod format;

/// `Middleware` for logging request and response info to the terminal.
pub struct Logger {
    format: Option<Format>
}

impl Logger {
    /// Create a pair of `Logger` middlewares with the specified `format`. If a `None` is passed in, uses the default format:
    ///
    /// ```ignore
    /// {method} {uri} -> {status} ({response-time} ms)
    /// ```
    ///
    /// While the returned value can be passed straight to `Chain::link`, consider making the logger `BeforeMiddleware`
    /// the first in your chain and the logger `AfterMiddleware` the last by doing something like this:
    ///
    /// ```ignore
    /// let mut chain = Chain::new(handler);
    /// let (logger_before, logger_after) = Logger::new(None);
    /// chain.link_before(logger_before);
    /// // link other middlewares here...
    /// chain.link_after(logger_after);
    /// ```
    pub fn new(format: Option<Format>) -> (Logger, Logger) {
        (Logger { format: format.clone() }, Logger { format: format })
    }
}

struct StartTime;
impl Key for StartTime { type Value = time::Tm; }

impl Logger {
    fn initialise(&self, req: &mut Request) {
        req.extensions.insert::<StartTime>(time::now());
    }

    fn log(&self, req: &mut Request, res: &Response) -> IronResult<()> {
        let entry_time = *req.extensions.get::<StartTime>().unwrap();

        let response_time = time::now() - entry_time;
        let response_time_ms = (response_time.num_seconds() * 1000) as f64 + (response_time.num_nanoseconds().unwrap_or(0) as f64) / 1000000.0;
        let Format(format) = self.format.clone().unwrap_or_default();

        {
            macro_rules! tryio {
                ($expr:expr) => (match $expr {
                    std::result::Result::Ok(val) => val,
                    std::result::Result::Err(err) => {
                        return Err(IronError::new(err, status::InternalServerError))
                    }
                })
            }

            let render = |text: &FormatText| {
                match *text {
                    Str(ref string) => string.clone(),
                    Method => format!("{}", req.method),
                    URI => format!("{}", req.url),
                    Status => res.status
                        .map(|status| format!("{}", status))
                        .unwrap_or("<missing status code>".to_owned()),
                    ResponseTime => format!("{} ms", response_time_ms),
                    RemoteAddr => format!("{}", req.remote_addr),
                    RequestTime => format!("{}", entry_time.strftime("%Y-%m-%dT%H:%M:%S.%fZ%z").unwrap()),
                }
            };

            let log = |w: &mut LogWriter| -> IronResult<()> {
                for unit in format.iter() {
                    let c = match unit.color {
                        ConstantColor(color) => color,
                        FunctionColor(f) => f(req, res)
                    };
                    let fn_attrs;
                    let ref attrs = match unit.attrs {
                        ConstantAttrs(ref attrs) => attrs,
                        FunctionAttrs(f) => {
                            fn_attrs = f(req, res);
                            &fn_attrs
                        }
                    };
                    tryio!(w.write_item(render(&unit.text), c, attrs));
                }
                tryio!(w.new_line());
                Ok(())
            };

            match stdout() {
                Some(terminal) => {
                    try!(log(&mut TermWriter::new(terminal)));
                }
                None => {
                    try!(log(&mut io::stdout()));
                }
            };
        }

        Ok(())
    }
}

trait LogWriter {
    fn write_item(&mut self, text: String, color: Option<color::Color>, attrs: &Vec<term::Attr>) -> io::Result<()>;
    fn new_line(&mut self) -> io::Result<()>;
}

struct TermWriter {
    term: Box<StdoutTerminal>
}

impl TermWriter {
    fn new(term: Box<StdoutTerminal>) -> TermWriter {
        TermWriter {
            term: term
        }
    }
}

impl LogWriter for TermWriter {
    fn write_item(&mut self, text: String, color: Option<color::Color>, attrs: &Vec<term::Attr>) -> io::Result<()> {
        match color {
            Some(c) => { try!(self.term.fg(c)); }
            None => {},
        }
        for &attr in attrs.iter() {
            try!(self.term.attr(attr));
        }
        try!(write!(self.term, "{}", text));
        try!(self.term.reset());
        Ok(())
    }

    fn new_line(&mut self) -> io::Result<()> {
        try!(writeln!(self.term, ""));
        Ok(())
    }
}

impl<T: Write> LogWriter for T {
    fn write_item(&mut self, text: String, _: Option<color::Color>, _: &Vec<term::Attr>) -> io::Result<()> {
        try!(write!(self, "{}", text));
        Ok(())
    }

    fn new_line(&mut self) -> io::Result<()> {
        try!(writeln!(self, ""));
        Ok(())
    }
}

impl BeforeMiddleware for Logger {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        self.initialise(req);
        Ok(())
    }

    fn catch(&self, req: &mut Request, err: IronError) -> IronResult<()> {
        self.initialise(req);
        Err(err)
    }
}

impl AfterMiddleware for Logger {
    fn after(&self, req: &mut Request, res: Response) -> IronResult<Response> {
        try!(self.log(req, &res));
        Ok(res)
    }

    fn catch(&self, req: &mut Request, err: IronError) -> IronResult<Response> {
        try!(self.log(req, &err.response));
        Err(err)
    }
}
<|endoftext|>


<commit_before>//! Idiomatic and safe APIs for interacting with the
//! [Lightning Memory-mapped Database (LMDB)](https://symas.com/lmdb).

#![cfg_attr(test, feature(test))]
#![deny(warnings)]
#![deny(missing_docs)]
#![doc(html_root_url = "https://docs.rs/lmdb/0.7.2")]

extern crate libc;
extern crate lmdb_sys as ffi;

#[cfg(test)] extern crate rand;
#[cfg(test)] extern crate tempdir;
#[cfg(test)] extern crate test;
#[macro_use] extern crate bitflags;

pub use cursor::{
    Cursor,
    RoCursor,
    RwCursor,
    Iter,
    IterDup,
};
pub use database::Database;
pub use environment::{Environment, Stat, EnvironmentBuilder};
pub use error::{Error, Result};
pub use flags::*;
pub use transaction::{
    InactiveTransaction,
    RoTransaction,
    RwTransaction,
    Transaction,
};

macro_rules! lmdb_try {
    ($expr:expr) => ({
        match $expr {
            ::ffi::MDB_SUCCESS => (),
            err_code => return Err(::Error::from_err_code(err_code)),
        }
    })
}

macro_rules! lmdb_try_with_cleanup {
    ($expr:expr, $cleanup:expr) => ({
        match $expr {
            ::ffi::MDB_SUCCESS => (),
            err_code => {
                let _ = $cleanup;
                return Err(::Error::from_err_code(err_code))
            },
        }
    })
}

mod flags;
mod cursor;
mod database;
mod environment;
mod error;
mod transaction;

#[cfg(test)]
mod test_utils {

    extern crate byteorder;

    use self::byteorder::{ByteOrder, LittleEndian};
    use tempdir::TempDir;

    use super::*;

    pub fn get_key(n: u32) -> String {
        format!("key{}", n)
    }

    pub fn get_data(n: u32) -> String {
        format!("data{}", n)
    }

    pub fn setup_bench_db<'a>(num_rows: u32) -> (TempDir, Environment) {
        let dir = TempDir::new("test").unwrap();
        let env = Environment::new().open(dir.path()).unwrap();

        {
            let db = env.open_db(None).unwrap();
            let mut txn = env.begin_rw_txn().unwrap();
            for i in 0..num_rows {
                txn.put(db, &get_key(i), &get_data(i), WriteFlags::empty()).unwrap();
            }
            txn.commit().unwrap();
        }
        (dir, env)
    }

    /// Regression test for https://github.com/danburkert/lmdb-rs/issues/21.
    /// This test reliably segfaults when run against lmbdb compiled with opt level -O3 and newer
    /// GCC compilers.
    #[test]
    fn issue_21_regression() {
        const HEIGHT_KEY: [u8; 1] = [0];

        let dir = TempDir::new("test").unwrap();

        let env = {
            let mut builder = Environment::new();
            builder.set_max_dbs(2);
            builder.set_map_size(1_000_000);
            builder.open(dir.path()).expect("open lmdb env")
        };
        let index = env.create_db(None, DatabaseFlags::DUP_SORT).expect("open index db");

        for height in 0..1000 {
            let mut value = [0u8; 8];
            LittleEndian::write_u64(&mut value, height);
            let mut tx = env.begin_rw_txn().expect("begin_rw_txn");
            tx.put(index,
                   &HEIGHT_KEY,
                   &value,
                   WriteFlags::empty()).expect("tx.put");
            tx.commit().expect("tx.commit")
        }
    }
}
<commit_msg>Remove deny(warnings)<commit_after>//! Idiomatic and safe APIs for interacting with the
//! [Lightning Memory-mapped Database (LMDB)](https://symas.com/lmdb).

#![cfg_attr(test, feature(test))]
#![deny(missing_docs)]
#![doc(html_root_url = "https://docs.rs/lmdb/0.7.2")]

extern crate libc;
extern crate lmdb_sys as ffi;

#[cfg(test)] extern crate rand;
#[cfg(test)] extern crate tempdir;
#[cfg(test)] extern crate test;
#[macro_use] extern crate bitflags;

pub use cursor::{
    Cursor,
    RoCursor,
    RwCursor,
    Iter,
    IterDup,
};
pub use database::Database;
pub use environment::{Environment, Stat, EnvironmentBuilder};
pub use error::{Error, Result};
pub use flags::*;
pub use transaction::{
    InactiveTransaction,
    RoTransaction,
    RwTransaction,
    Transaction,
};

macro_rules! lmdb_try {
    ($expr:expr) => ({
        match $expr {
            ::ffi::MDB_SUCCESS => (),
            err_code => return Err(::Error::from_err_code(err_code)),
        }
    })
}

macro_rules! lmdb_try_with_cleanup {
    ($expr:expr, $cleanup:expr) => ({
        match $expr {
            ::ffi::MDB_SUCCESS => (),
            err_code => {
                let _ = $cleanup;
                return Err(::Error::from_err_code(err_code))
            },
        }
    })
}

mod flags;
mod cursor;
mod database;
mod environment;
mod error;
mod transaction;

#[cfg(test)]
mod test_utils {

    extern crate byteorder;

    use self::byteorder::{ByteOrder, LittleEndian};
    use tempdir::TempDir;

    use super::*;

    pub fn get_key(n: u32) -> String {
        format!("key{}", n)
    }

    pub fn get_data(n: u32) -> String {
        format!("data{}", n)
    }

    pub fn setup_bench_db<'a>(num_rows: u32) -> (TempDir, Environment) {
        let dir = TempDir::new("test").unwrap();
        let env = Environment::new().open(dir.path()).unwrap();

        {
            let db = env.open_db(None).unwrap();
            let mut txn = env.begin_rw_txn().unwrap();
            for i in 0..num_rows {
                txn.put(db, &get_key(i), &get_data(i), WriteFlags::empty()).unwrap();
            }
            txn.commit().unwrap();
        }
        (dir, env)
    }

    /// Regression test for https://github.com/danburkert/lmdb-rs/issues/21.
    /// This test reliably segfaults when run against lmbdb compiled with opt level -O3 and newer
    /// GCC compilers.
    #[test]
    fn issue_21_regression() {
        const HEIGHT_KEY: [u8; 1] = [0];

        let dir = TempDir::new("test").unwrap();

        let env = {
            let mut builder = Environment::new();
            builder.set_max_dbs(2);
            builder.set_map_size(1_000_000);
            builder.open(dir.path()).expect("open lmdb env")
        };
        let index = env.create_db(None, DatabaseFlags::DUP_SORT).expect("open index db");

        for height in 0..1000 {
            let mut value = [0u8; 8];
            LittleEndian::write_u64(&mut value, height);
            let mut tx = env.begin_rw_txn().expect("begin_rw_txn");
            tx.put(index,
                   &HEIGHT_KEY,
                   &value,
                   WriteFlags::empty()).expect("tx.put");
            tx.commit().expect("tx.commit")
        }
    }
}
<|endoftext|>


<commit_before>#![crate_id = "docopt#0.1.0"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "UNLICENSE"]
#![doc(html_root_url = "http://burntsushi.net/rustdoc/docopt")]

#![allow(dead_code, unused_variable, unused_imports)]
#![allow(visible_private_types)]

//! Docopt for Rust.

#![feature(macro_rules, phase)]

extern crate debug;
extern crate libc;
// #[cfg(test)]
#[phase(plugin, link)]
extern crate log;
extern crate regex;
#[phase(plugin)] extern crate regex_macros;

use std::collections::HashMap;
use std::fmt;
use parse::Parser;
use synonym::SynonymMap;

macro_rules! werr(
    ($($arg:tt)*) => (
        match io::stderr().write_str(format!($($arg)*).as_slice()) {
            Ok(_) => (),
            Err(err) => fail!("{}", err),
        }
    )
)

pub enum Error {
    NoMatch,
    Usage(String),
}

impl fmt::Show for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &NoMatch => write!(f, "Invalid arguments."),
            &Usage(ref s) => write!(f, "{}", s),
        }
    }
}

#[deriving(Show)]
pub struct Docopt {
    p: Parser,
    conf: Config,
}

#[deriving(Clone, Show)]
pub struct Config {
    pub options_first: bool,
    pub help: bool,
    pub version: Option<String>,
}

impl Docopt {
    pub fn new(doc: &str, conf: Config) -> Result<Docopt, Error> {
        Parser::new(doc, conf.options_first)
            .map(|p| Docopt { p: p, conf: conf.clone() })
            .or_else(|s| Err(Usage(s)))
    }

    pub fn argv(&self, args: &[&str]) -> Result<ValueMap, Error> {
        self.p.parse_argv(args)
            .or_else(|s| Err(Usage(s)))
            .and_then(|argv|
                self.p.matches(&argv)
                    .map(|m| Ok(ValueMap { map: m }))
                    .unwrap_or_else(|| Err(NoMatch)))
    }
}

#[deriving(Clone)]
pub struct ValueMap {
    map: SynonymMap<String, Value>,
}

#[deriving(Clone, PartialEq, Show)]
pub enum Value {
    Switch(bool),
    Counted(uint),
    Plain(Option<String>),
    List(Vec<String>),
}

impl ValueMap {
    pub fn get_bool(&self, key: &str) -> bool {
        self.find(&key).map(|v| v.as_bool()).unwrap_or(false)
    }
    pub fn get_count(&self, key: &str) -> uint {
        self.find(&key).map(|v| v.as_count()).unwrap_or(0)
    }
    pub fn get_str<'a>(&'a self, key: &str) -> &'a str {
        self.find(&key).map(|v| v.as_str()).unwrap_or("")
    }
    pub fn get_vec<'a>(&'a self, key: &str) -> Vec<&'a str> {
        self.find(&key).map(|v| v.as_vec()).unwrap_or(vec!())
    }
}

impl Value {
    pub fn as_bool(&self) -> bool {
        match self {
            &Switch(b) => b,
            &Counted(n) => n > 0,
            &Plain(None) => false,
            &Plain(Some(_)) => true,
            &List(ref vs) => !vs.is_empty(),
        }
    }
    pub fn as_count(&self) -> uint {
        match self {
            &Switch(b) => if b { 1 } else { 0 },
            &Counted(n) => n,
            &Plain(None) => 0,
            &Plain(Some(_)) => 1,
            &List(ref vs) => vs.len(),
        }
    }
    pub fn as_str<'a>(&'a self) -> &'a str {
        match self {
            &Switch(_) | &Counted(_) | &Plain(None) | &List(_) => "",
            &Plain(Some(ref s)) => s.as_slice(),
        }
    }
    pub fn as_vec<'a>(&'a self) -> Vec<&'a str> {
        match self {
            &Switch(_) | &Counted(_) | &Plain(None) => vec!(),
            &Plain(Some(ref s)) => vec!(s.as_slice()),
            &List(ref vs) => vs.iter().map(|s| s.as_slice()).collect(),
        }
    }
}

impl Collection for ValueMap {
    fn len(&self) -> uint { self.map.len() }
}

impl<'k> Map<&'k str, Value> for ValueMap {
    fn find<'a>(&'a self, key: & &'k str) -> Option<&'a Value> {
        self.map.find(&key.to_string())
    }
}

impl fmt::Show for ValueMap {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.is_empty() {
            return write!(f, "{{EMPTY}}");
        }

        // This is a little crazy, but we want to group synonyms with
        // their keys and sort them for predictable output.
        let reverse: HashMap<&String, &String> =
            self.map.synonyms().map(|(from, to)| (to, from)).collect();
        let mut keys: Vec<&String> = self.map.keys().collect();
        keys.sort();
        let mut first = true;
        for &k in keys.iter() {
            if !first { try!(write!(f, "\n")); } else { first = false; }
            match reverse.find(&k) {
                None => {
                    try!(write!(f, "{} => {}", k, self.map.get(k)))
                }
                Some(s) => {
                    try!(write!(f, "{}, {} => {}", s, k, self.map.get(k)))
                }
            }
        }
        Ok(())
    }
}

pub fn docopt(doc: &str) -> ValueMap {
    docopt_conf(doc, Config { options_first: false, help: true, version: None })
}

pub fn docopt_conf(doc: &str, conf: Config) -> ValueMap {
    match Docopt::new(doc, conf) {
        Ok(dopt) => convenient_parse_argv(&dopt),
        Err(err) => fail!("{}", err),
    }
}

fn convenient_parse_argv(dopt: &Docopt) -> ValueMap {
    use std::io;
    use std::os;

    let os_argv = os::args();
    let argv: Vec<&str> = os_argv.iter().skip(1).map(|s|s.as_slice()).collect();
    if dopt.conf.help && argv_has_help(argv.as_slice()) {
        werr!("{}\n", dopt.p.full_doc.as_slice().trim());
        exit(1);
    }
    match dopt.conf.version {
        Some(ref v) if argv_has_version(argv.as_slice()) => {
            werr!("{}\n", v);
            exit(0);
        }
        _ => {},
    }
    dopt.argv(argv.as_slice()).unwrap_or_else(|err| {
        werr!("{}\n", err);
        werr!("{}\n", dopt.p.usage.as_slice().trim());
        exit(1);
    })
}

fn argv_has_help(argv: &[&str]) -> bool {
    argv.contains(&"-h") || argv.contains(&"--help")
}

fn argv_has_version(argv: &[&str]) -> bool {
    argv.contains(&"--version")
}

// I've been warned that this is wildly unsafe.
// Unless there's a reasonable alternative, I'm inclined to say that this is
// the price you pay for convenience.
fn exit(code: uint) -> ! {
    unsafe { libc::exit(code as libc::c_int) }
}

mod parse;
mod synonym;
#[cfg(test)]
mod test;

<commit_msg>Start work on a decoder from ValueMap.<commit_after>#![crate_id = "docopt#0.1.0"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "UNLICENSE"]
#![doc(html_root_url = "http://burntsushi.net/rustdoc/docopt")]

#![allow(dead_code, unused_variable, unused_imports)]
#![allow(visible_private_types)]

//! Docopt for Rust.

#![feature(macro_rules, phase)]

extern crate debug;
extern crate libc;
// #[cfg(test)]
#[phase(plugin, link)]
extern crate log;
extern crate regex;
#[phase(plugin)] extern crate regex_macros;
extern crate serialize;

use std::collections::HashMap;
use std::fmt;
use std::from_str::{FromStr, from_str};
use serialize::Decodable;
use parse::Parser;
use synonym::SynonymMap;

macro_rules! werr(
    ($($arg:tt)*) => (
        match io::stderr().write_str(format!($($arg)*).as_slice()) {
            Ok(_) => (),
            Err(err) => fail!("{}", err),
        }
    )
)

pub enum Error {
    NoMatch,
    Usage(String),
}

impl fmt::Show for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &NoMatch => write!(f, "Invalid arguments."),
            &Usage(ref s) => write!(f, "{}", s),
        }
    }
}

#[deriving(Show)]
pub struct Docopt {
    p: Parser,
    conf: Config,
}

#[deriving(Clone, Show)]
pub struct Config {
    pub options_first: bool,
    pub help: bool,
    pub version: Option<String>,
}

impl Docopt {
    pub fn new(doc: &str, conf: Config) -> Result<Docopt, Error> {
        Parser::new(doc, conf.options_first)
            .map(|p| Docopt { p: p, conf: conf.clone() })
            .or_else(|s| Err(Usage(s)))
    }

    pub fn argv(&self, args: &[&str]) -> Result<ValueMap, Error> {
        self.p.parse_argv(args)
            .or_else(|s| Err(Usage(s)))
            .and_then(|argv|
                self.p.matches(&argv)
                    .map(|m| Ok(ValueMap { map: m }))
                    .unwrap_or_else(|| Err(NoMatch)))
    }
}

#[deriving(Clone)]
pub struct ValueMap {
    map: SynonymMap<String, Value>,
}

#[deriving(Clone, PartialEq, Show)]
pub enum Value {
    Switch(bool),
    Counted(uint),
    Plain(Option<String>),
    List(Vec<String>),
}

impl Value {
    pub fn as_bool(&self) -> bool {
        match self {
            &Switch(b) => b,
            &Counted(n) => n > 0,
            &Plain(None) => false,
            &Plain(Some(_)) => true,
            &List(ref vs) => !vs.is_empty(),
        }
    }
    pub fn as_count(&self) -> uint {
        match self {
            &Switch(b) => if b { 1 } else { 0 },
            &Counted(n) => n,
            &Plain(None) => 0,
            &Plain(Some(_)) => 1,
            &List(ref vs) => vs.len(),
        }
    }
    pub fn as_str<'a>(&'a self) -> &'a str {
        match self {
            &Switch(_) | &Counted(_) | &Plain(None) | &List(_) => "",
            &Plain(Some(ref s)) => s.as_slice(),
        }
    }
    pub fn as_vec<'a>(&'a self) -> Vec<&'a str> {
        match self {
            &Switch(_) | &Counted(_) | &Plain(None) => vec!(),
            &Plain(Some(ref s)) => vec!(s.as_slice()),
            &List(ref vs) => vs.iter().map(|s| s.as_slice()).collect(),
        }
    }
}

impl ValueMap {
    pub fn decode<'a, T: Decodable<Decoder<'a>, DecoderError>>
                 (&'a self) -> Result<T, DecoderError> {
        Decodable::decode(&mut Decoder { vals: self, cur: None })
    }
    pub fn get_bool(&self, key: &str) -> bool {
        self.find(&key).map(|v| v.as_bool()).unwrap_or(false)
    }
    pub fn get_count(&self, key: &str) -> uint {
        self.find(&key).map(|v| v.as_count()).unwrap_or(0)
    }
    pub fn get_str<'a>(&'a self, key: &str) -> &'a str {
        self.find(&key).map(|v| v.as_str()).unwrap_or("")
    }
    pub fn get_vec<'a>(&'a self, key: &str) -> Vec<&'a str> {
        self.find(&key).map(|v| v.as_vec()).unwrap_or(vec!())
    }

    fn key_to_struct_field(name: &str) -> String {
        fn sanitize(name: &str) -> String {
            name.replace("-", "_")
        }

        let r = regex!(r"--?(?P<flag>[^-]+)|(?:(?P<argu>\p{Lu})|<(?P<argb>[^>]+)>)|(?P<cmd>\S+)");
        r.replace(name, |cap: &regex::Captures| {
            let (flag, cmd) = (cap.name("flag"), cap.name("cmd"));
            let (argu, argb) = (cap.name("argu"), cap.name("argb"));
            let (prefix, name) =
                if !flag.is_empty() {
                    ("flag_", flag)
                } else if !argu.is_empty() {
                    ("arg_", argu)
                } else if !argb.is_empty() {
                    ("arg_", argb)
                } else if !cmd.is_empty() {
                    ("cmd_", cmd)
                } else {
                    fail!("Unknown ValueMap key: '{}'", name)
                };
            prefix.to_string().append(sanitize(name).as_slice())
        })
    }

    fn struct_field_to_key(field: &str) -> String {
        fn desanitize(name: &str) -> String {
            name.replace("_", "-")
        }
        let name =
            if field.starts_with("flag_") {
                let name = regex!(r"^flag_").replace(field, "");
                if name.len() == 1 {
                    "-".to_string().append(name.as_slice())
                } else {
                    "--".to_string().append(name.as_slice())
                }
            } else if field.starts_with("arg_") {
                let name = regex!(r"^arg_").replace(field, "");
                if regex!(r"^\p{Lu}+$").is_match(name.as_slice()) {
                    name
                } else {
                    "<".to_string().append(name.as_slice()).append(">")
                }
            } else if field.starts_with("cmd_") {
                { regex!(r"^cmd_") }.replace(field, "")
            } else {
                fail!("Unrecognized struct field: '{}'", field)
            };
        desanitize(name.as_slice())
    }
}

impl Collection for ValueMap {
    fn len(&self) -> uint { self.map.len() }
}

impl<'k> Map<&'k str, Value> for ValueMap {
    fn find<'a>(&'a self, key: & &'k str) -> Option<&'a Value> {
        self.map.find(&key.to_string())
    }
}

impl fmt::Show for ValueMap {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.is_empty() {
            return write!(f, "{{EMPTY}}");
        }

        // This is a little crazy, but we want to group synonyms with
        // their keys and sort them for predictable output.
        let reverse: HashMap<&String, &String> =
            self.map.synonyms().map(|(from, to)| (to, from)).collect();
        let mut keys: Vec<&String> = self.map.keys().collect();
        keys.sort();
        let mut first = true;
        for &k in keys.iter() {
            if !first { try!(write!(f, "\n")); } else { first = false; }
            match reverse.find(&k) {
                None => {
                    try!(write!(f, "{} => {}", k, self.map.get(k)))
                }
                Some(s) => {
                    try!(write!(f, "{}, {} => {}", s, k, self.map.get(k)))
                }
            }
        }
        Ok(())
    }
}

struct Decoder<'a> {
    vals: &'a ValueMap,
    cur: Option<String>,
}

pub type DecoderError = String;

impl<'a> Decoder<'a> {
    fn with_key_value<T>(&self, f: |&str, &Value| -> Result<T, DecoderError>)
                    -> Result<T, DecoderError> {
        match self.cur {
            None => Err(format!("Could not decode value into unknown key.")),
            Some(ref key) => {
                match self.vals.find(&key.as_slice()) {
                    None => Err(format!("Could not find argument '{}'.", key)),
                    Some(v) => f(key.as_slice(), v),
                }
            }
        }
    }

    fn map<T>(&self, f: |&Value| -> T) -> Result<T, DecoderError> {
        self.with_key_value(|_, v| Ok(f(v)))
    }

    fn from_str<T: FromStr>(&self, expect: &str) -> Result<T, DecoderError> {
        self.with_key_value(|k, v| {
            match from_str(v.as_str()) {
                None => Err(format!(
                            "Could not decode '{}' from string to {} for '{}'.",
                            v.as_str(), expect, k)),
                Some(v) => Ok(v),
            }
        })
    }
}

impl<'a> serialize::Decoder<DecoderError> for Decoder<'a> {
    fn read_nil(&mut self) -> Result<(), DecoderError> {
        // I don't know what the right thing is here, so just fail for now.
        fail!("I don't know how to read into a nil value.")
    }
    fn read_uint(&mut self) -> Result<uint, DecoderError> {
        self.from_str("uint")
    }
    fn read_u64(&mut self) -> Result<u64, DecoderError> {
        self.from_str("u64")
    }
    fn read_u32(&mut self) -> Result<u32, DecoderError> {
        self.from_str("u32")
    }
    fn read_u16(&mut self) -> Result<u16, DecoderError> {
        self.from_str("u16")
    }
    fn read_u8(&mut self) -> Result<u8, DecoderError> {
        self.from_str("u8")
    }
    fn read_int(&mut self) -> Result<int, DecoderError> {
        self.from_str("int")
    }
    fn read_i64(&mut self) -> Result<i64, DecoderError> {
        self.from_str("i64")
    }
    fn read_i32(&mut self) -> Result<i32, DecoderError> {
        self.from_str("i32")
    }
    fn read_i16(&mut self) -> Result<i16, DecoderError> {
        self.from_str("i16")
    }
    fn read_i8(&mut self) -> Result<i8, DecoderError> {
        self.from_str("i8")
    }
    fn read_bool(&mut self) -> Result<bool, DecoderError> {
        self.map(|v| v.as_bool())
    }
    fn read_f64(&mut self) -> Result<f64, DecoderError> {
        self.from_str("f64")
    }
    fn read_f32(&mut self) -> Result<f32, DecoderError> {
        self.from_str("f32")
    }
    fn read_char(&mut self) -> Result<char, DecoderError> {
        self.with_key_value(|k, v| {
            let vstr = v.as_str();
            match vstr.len() {
                1 => Ok(vstr.char_at(0)),
                _ => Err(format!("Could not decode '{}' into char for '{}'.",
                                 vstr, k)),
            }
        })
    }
    fn read_str(&mut self) -> Result<String, DecoderError> {
        self.map(|v| v.as_str().to_string())
    }
    fn read_enum<T>(&mut self, name: &str,
                    f: |&mut Decoder<'a>| -> Result<T, DecoderError>)
                    -> Result<T, DecoderError> {
        unimplemented!()
    }
    fn read_enum_variant<T>(&mut self, names: &[&str],
                            f: |&mut Decoder<'a>, uint| -> Result<T, DecoderError>)
                            -> Result<T, DecoderError> {
        unimplemented!()
    }
    fn read_enum_variant_arg<T>(
        &mut self, a_idx: uint,
        f: |&mut Decoder<'a>| -> Result<T, DecoderError>)
        -> Result<T, DecoderError> {
        unimplemented!()
    }
    fn read_enum_struct_variant<T>(
        &mut self, names: &[&str],
        f: |&mut Decoder<'a>, uint| -> Result<T, DecoderError>)
        -> Result<T, DecoderError> {
        unimplemented!()
    }
    fn read_enum_struct_variant_field<T>(
        &mut self, f_name: &str, f_idx: uint,
        f: |&mut Decoder<'a>| -> Result<T, DecoderError>)
        -> Result<T, DecoderError> {
        unimplemented!()
    }
    fn read_struct<T>(&mut self, s_name: &str, len: uint,
                      f: |&mut Decoder<'a>| -> Result<T, DecoderError>)
                      -> Result<T, DecoderError> {
        f(self)
    }
    fn read_struct_field<T>(&mut self, f_name: &str, f_idx: uint,
                            f: |&mut Decoder<'a>| -> Result<T, DecoderError>)
                            -> Result<T, DecoderError> {
        self.cur = Some(ValueMap::struct_field_to_key(f_name));
        let r = f(self);
        self.cur = None;
        r
    }
    fn read_tuple<T>(&mut self,
                     f: |&mut Decoder<'a>, uint| -> Result<T, DecoderError>)
                     -> Result<T, DecoderError> {
        unimplemented!()
    }
    fn read_tuple_arg<T>(&mut self, a_idx: uint,
                         f: |&mut Decoder<'a>| -> Result<T, DecoderError>)
                         -> Result<T, DecoderError> {
        unimplemented!()
    }
    fn read_tuple_struct<T>(&mut self, s_name: &str,
                            f: |&mut Decoder<'a>, uint| -> Result<T, DecoderError>)
                            -> Result<T, DecoderError> {
        unimplemented!()
    }
    fn read_tuple_struct_arg<T>(&mut self, a_idx: uint,
                                f: |&mut Decoder<'a>| -> Result<T, DecoderError>)
                                -> Result<T, DecoderError> {
        unimplemented!()
    }
    fn read_option<T>(&mut self,
                      f: |&mut Decoder<'a>, bool| -> Result<T, DecoderError>)
                      -> Result<T, DecoderError> {
        unimplemented!()
    }
    fn read_seq<T>(&mut self,
                   f: |&mut Decoder<'a>, uint| -> Result<T, DecoderError>)
                   -> Result<T, DecoderError> {
        unimplemented!()
    }
    fn read_seq_elt<T>(&mut self, idx: uint,
                       f: |&mut Decoder<'a>| -> Result<T, DecoderError>)
                       -> Result<T, DecoderError> {
        unimplemented!()
    }
    fn read_map<T>(&mut self,
                   f: |&mut Decoder<'a>, uint| -> Result<T, DecoderError>)
                   -> Result<T, DecoderError> {
        unimplemented!()
    }
    fn read_map_elt_key<T>(&mut self, idx: uint,
                           f: |&mut Decoder<'a>| -> Result<T, DecoderError>)
                           -> Result<T, DecoderError> {
        unimplemented!()
    }
    fn read_map_elt_val<T>(&mut self, idx: uint,
                           f: |&mut Decoder<'a>| -> Result<T, DecoderError>)
                           -> Result<T, DecoderError> {
        unimplemented!()
    }
}

pub fn docopt(doc: &str) -> ValueMap {
    docopt_conf(doc, Config { options_first: false, help: true, version: None })
}

pub fn docopt_conf(doc: &str, conf: Config) -> ValueMap {
    match Docopt::new(doc, conf) {
        Ok(dopt) => convenient_parse_argv(&dopt),
        Err(err) => fail!("{}", err),
    }
}

fn convenient_parse_argv(dopt: &Docopt) -> ValueMap {
    use std::io;
    use std::os;

    let os_argv = os::args();
    let argv: Vec<&str> = os_argv.iter().skip(1).map(|s|s.as_slice()).collect();
    if dopt.conf.help && argv_has_help(argv.as_slice()) {
        werr!("{}\n", dopt.p.full_doc.as_slice().trim());
        exit(1);
    }
    match dopt.conf.version {
        Some(ref v) if argv_has_version(argv.as_slice()) => {
            werr!("{}\n", v);
            exit(0);
        }
        _ => {},
    }
    dopt.argv(argv.as_slice()).unwrap_or_else(|err| {
        werr!("{}\n", err);
        werr!("{}\n", dopt.p.usage.as_slice().trim());
        exit(1);
    })
}

fn argv_has_help(argv: &[&str]) -> bool {
    argv.contains(&"-h") || argv.contains(&"--help")
}

fn argv_has_version(argv: &[&str]) -> bool {
    argv.contains(&"--version")
}

// I've been warned that this is wildly unsafe.
// Unless there's a reasonable alternative, I'm inclined to say that this is
// the price you pay for convenience.
fn exit(code: uint) -> ! {
    unsafe { libc::exit(code as libc::c_int) }
}

mod parse;
mod synonym;
#[cfg(test)]
mod test;

<|endoftext|>


<commit_before>#![crate_id = "dsp"]
#![deny(missing_doc)]
#![feature(macro_rules)]
#![feature(phase)]

//! A pure Rust audio digital signal processing library for Piston.

extern crate portaudio;
extern crate time;

pub use SoundStream = sound_stream::SoundStream;
pub use SoundStreamSettings = sound_stream_settings::SoundStreamSettings;
pub use Node = node::Node;
pub use IsNode = node::IsNode;
pub use Signal = signal::Signal;
pub use Waveform = waveform::Waveform;

mod port_audio_back_end;
mod sound_stream;
mod sound_stream_settings;
mod node;

<commit_msg>Updated with new modules<commit_after>#![crate_id = "dsp"]
#![deny(missing_doc)]
#![feature(macro_rules)]
#![feature(phase)]
#![feature(globs)]

//! A pure Rust audio digital signal processing library for Piston.

extern crate portaudio;
extern crate time;

pub use Frequency = frequency::Frequency;
pub use HasFrequency = frequency::HasFrequency;
pub use Node = node::Node;
pub use IsNode = node::IsNode;
pub use Oscillator = oscillator::Oscillator;
pub use Pitch = pitch::Pitch;
pub use HasPitch = pitch::HasPitch;
pub use Signal = signal::Signal;
pub use SoundStream = sound_stream::SoundStream;
pub use SoundStreamSettings = sound_stream_settings::SoundStreamSettings;
pub use Waveform = waveform::Waveform;

mod frequency;
mod math;
mod node;
mod oscillator;
mod pitch;
mod port_audio_back_end;
mod signal;
mod sound_stream;
mod sound_stream_settings;
mod waveform;

<|endoftext|>


<commit_before>//use discrete::{DiscreteSampler32};

use operator::{DiffOperatorOutput};
use sharedmem::{RwSlice};

use bit_set::{BitSet};

use rand::{Rng};
use std::cell::{RefCell};
use std::fmt::{Debug};
use std::io::{Write};
use std::rc::{Rc};

pub trait Action: Clone {
  fn dim() -> usize;
}

impl Action for f32 {
  fn dim() -> usize {
    1
  }
}

pub trait DiscreteAction: Action + Copy {
  fn from_idx(idx: u32) -> Self where Self: Sized;
  fn idx(&self) -> u32;
}

pub trait Response: Copy + Debug {
  fn lreduce(&mut self, prefix: Self);
  fn as_scalar(&self) -> f32;
}

impl Response for bool {
  #[inline]
  fn lreduce(&mut self, _: bool) {
    // Do nothing.
  }

  #[inline]
  fn as_scalar(&self) -> f32 {
    match *self {
      false => 0.0,
      true  => 1.0,
    }
  }
}

impl Response for f32 {
  #[inline]
  fn lreduce(&mut self, prefix: f32) {
    //println!("DEBUG: lreduce: {:e} {:e}", prefix, *self);
    *self += prefix;
  }

  #[inline]
  fn as_scalar(&self) -> f32 {
    *self
  }
}

#[derive(Clone, Copy, Debug)]
pub struct HorizonAveraged<T> where T: Copy {
  pub value:    T,
  pub horizon:  usize,
}

impl Response for HorizonAveraged<f32> {
  #[inline]
  fn lreduce(&mut self, prefix: HorizonAveraged<f32>) {
    assert_eq!(self.horizon, prefix.horizon);
    self.value += prefix.value;
  }

  #[inline]
  fn as_scalar(&self) -> f32 {
    self.value / self.horizon as f32
  }
}

#[derive(Clone, Copy, Debug)]
pub struct OnlineAveraged<T> where T: Copy {
  pub value:    T,
  pub count:    usize,
}

impl<T> OnlineAveraged<T> where T: Copy {
  pub fn new(value: T) -> OnlineAveraged<T> {
    OnlineAveraged{
      value:    value,
      count:    1,
    }
  }
}

impl Response for OnlineAveraged<f32> {
  #[inline]
  fn lreduce(&mut self, prefix: OnlineAveraged<f32>) {
    assert_eq!(1, prefix.count);
    self.value = self.value + (prefix.value - self.value) / (self.count + 1) as f32;
    self.count += 1;
  }

  #[inline]
  fn as_scalar(&self) -> f32 {
    self.value
  }
}

#[derive(Clone, Copy, Debug)]
pub struct Discounted<T> where T: Copy {
  pub value:    T,
  pub discount: T,
}

impl<T> Discounted<T> where T: Copy {
  pub fn new(value: T, discount: T) -> Discounted<T> {
    Discounted{
      value:    value,
      discount: discount,
    }
  }
}

impl Response for Discounted<f32> {
  #[inline]
  fn lreduce(&mut self, prefix: Discounted<f32>) {
    self.value = prefix.value + prefix.discount * self.value;
  }

  #[inline]
  fn as_scalar(&self) -> f32 {
    self.value * (1.0 - self.discount)
  }
}

#[derive(Clone, Copy, Debug)]
pub struct NormalizeDiscounted<T> where T: Copy {
  pub value:    T,
  pub discount: T,
  pub count:    usize,
}

impl<T> NormalizeDiscounted<T> where T: Copy {
  pub fn new(value: T, discount: T) -> NormalizeDiscounted<T> {
    NormalizeDiscounted{
      value:    value,
      discount: discount,
      count:    1,
    }
  }
}

impl Response for NormalizeDiscounted<f32> {
  #[inline]
  fn lreduce(&mut self, prefix: NormalizeDiscounted<f32>) {
    assert_eq!(1, prefix.count);
    self.value = prefix.value + prefix.discount * self.value;
    self.count += 1;
  }

  #[inline]
  fn as_scalar(&self) -> f32 {
    self.value * (1.0 - self.discount) / (1.0 - self.discount.powi(self.count as i32))
  }
}

pub trait Value: Copy + Debug {
  type Cfg: Copy;
  type Res: Response;

  fn from_res(res: Self::Res, cfg: Self::Cfg) -> Self where Self: Sized;
  fn from_scalar(scalar_value: f32, cfg: Self::Cfg) -> Self where Self: Sized;
  fn to_scalar(&self) -> f32;
  fn lreduce(&mut self, prefix: Self::Res);
}

#[derive(Clone, Copy, Debug)]
pub struct Discount<T>(pub T) where T: Copy;

#[derive(Clone, Copy, Debug)]
pub struct DiscountedValue<T> where T: Copy {
  pub value:    T,
  pub discount: T,
}

impl Value for DiscountedValue<f32> {
  type Cfg = Discount<f32>;
  type Res = f32;

  fn from_res(res: f32, cfg: Discount<f32>) -> DiscountedValue<f32> {
    DiscountedValue{
      value:    res,
      discount: cfg.0,
    }
  }

  fn from_scalar(scalar_value: f32, cfg: Discount<f32>) -> DiscountedValue<f32> {
    DiscountedValue{
      value:    scalar_value,
      discount: cfg.0,
    }
  }

  fn to_scalar(&self) -> f32 {
    self.value
  }

  fn lreduce(&mut self, prefix: f32) {
    self.value = prefix + self.discount * self.value;
  }
}

#[derive(Clone, Copy, Debug)]
pub struct NormDiscountedValue<T> where T: Copy {
  pub value:    T,
  pub discount: T,
}

impl Value for NormDiscountedValue<f32> {
  type Cfg = Discount<f32>;
  type Res = f32;

  fn from_res(res: f32, cfg: Discount<f32>) -> NormDiscountedValue<f32> {
    NormDiscountedValue{
      value:    res,
      discount: cfg.0,
    }
  }

  fn from_scalar(scalar_value: f32, cfg: Discount<f32>) -> NormDiscountedValue<f32> {
    NormDiscountedValue{
      value:    scalar_value,
      discount: cfg.0,
    }
  }

  fn to_scalar(&self) -> f32 {
    self.value * (1.0 - self.discount)
  }

  fn lreduce(&mut self, prefix: f32) {
    self.value = prefix + self.discount * self.value;
  }
}

pub trait Env: Default {
  type Init;
  type Action: Action;
  type Response: Response;

  /// Reset the environment according to the initial state distribution and
  /// other initial configuration.
  fn reset<R>(&self, init: &Self::Init, rng: &mut R) where R: Rng + Sized;

  /// Check if the environment is at a terminal state (no more legal actions).
  fn is_terminal(&self) -> bool;

  /// Check if an action is legal. Can be expensive if this involves simulating
  /// the action using `step`.
  fn is_legal_action(&self, action: &Self::Action) -> bool;

  /// Try to execute an action, returning an error if the action is illegal.
  fn step(&self, action: &Self::Action) -> Result<Option<Self::Response>, ()>;
}

pub trait DiscreteEnv: Env where Self::Action: DiscreteAction {
  /// Extracting discrete actions.
  fn extract_all_actions_buf(&mut self, actions_buf: &mut Vec<Self::Action>);
  fn extract_legal_actions_buf(&mut self, actions_buf: &mut Vec<Self::Action>);
  fn extract_legal_actions_set(&mut self, actions_set: &mut BitSet);
}

pub trait EnvSerialize: Env {
  fn serialize(&mut self, buf: &mut Write);
}

/*pub trait EnvOpaqueRepr<Obs>: Env {
  fn extract_opaque_observable(&mut self, obs: &mut Obs);
}*/

pub trait EnvInputRepr<U: ?Sized>: Env {
  fn _shape3d(&self) -> (usize, usize, usize);
}

pub trait EnvRepr<T>: Env {
  #[deprecated] fn observable_len(&mut self) -> usize { self.observable_sz() }
  fn observable_sz(&self) -> usize;
  fn extract_observable(&self, obs: &mut [T]);
}

pub trait EnvConvert<Target>: Env where Target: Env {
  fn clone_from_env(&mut self, other: &Target);

  fn from_env(other: &Target) -> Self where Self: Sized {
    let mut env: Self = Default::default();
    env.clone_from_env(other);
    env
  }
}

//#[derive(Clone)]
pub struct EpisodeStep<E> where E: Env {
  pub action:   E::Action,
  pub res:      Option<E::Response>,
  //pub next_env: Rc<RefCell<E>>,
  pub next_env: Rc<E>,
}

impl<E> Clone for EpisodeStep<E> where E: Env {
  fn clone(&self) -> EpisodeStep<E> {
    EpisodeStep{
      action:   self.action.clone(),
      res:      self.res,
      next_env: self.next_env.clone(),
    }
  }
}

//#[derive(Clone)]
pub struct Episode<E> where E: Env {
  //pub init_env: Rc<RefCell<E>>,
  pub init_env: Rc<E>,
  pub steps:    Vec<EpisodeStep<E>>,
  pub suffixes: Vec<Option<E::Response>>,
  //final_value:  Option<E::Response>,
}

impl<E> Clone for Episode<E> where E: Env {
  fn clone(&self) -> Episode<E> {
    Episode{
      init_env: self.init_env.clone(),
      steps:    self.steps.clone(),
      suffixes: self.suffixes.clone(),
      //final_value:  self.final_value,
    }
  }
}

impl<E> Episode<E> where E: Env {
  pub fn new() -> Episode<E> {
    Episode{
      //init_env: Rc::new(RefCell::new(Default::default())),
      init_env: Rc::new(Default::default()),
      steps:    vec![],
      suffixes: vec![],
      //final_value:  None,
    }
  }

  pub fn horizon(&self) -> usize {
    self.steps.len()
  }

  pub fn value(&self) -> Option<f32> {
    self.suffixes[0].map(|r| r.as_scalar())
  }

  pub fn reset<R>(&mut self, init_cfg: &E::Init, rng: &mut R) where R: Rng + Sized {
    self.init_env.reset(init_cfg, rng);
    self.steps.clear();
    self.suffixes.clear();
  }

  pub fn terminated(&self) -> bool {
    match self.steps.len() {
      0   => self.init_env.is_terminal(),
      len => self.steps[len-1].next_env.is_terminal(),
    }
  }

  /*pub fn set_final_value(&mut self, v: E::Response) {
    self.final_value = Some(v);
  }*/

  pub fn _fill_suffixes(&mut self) {
    let horizon = self.steps.len();
    self.suffixes.clear();
    for k in 0 .. horizon {
      self.suffixes.push(self.steps[k].res);
    }
    /*let mut suffix = if self.terminated() {
      None
    } else if let Some(v) = self.final_value {
      Some(v)
    } else {
      None
    };*/
    let mut suffix = None;
    for k in (0 .. horizon).rev() {
      if suffix.is_none() {
        suffix = self.steps[k].res;
      } else if let Some(prefix) = self.steps[k].res {
        suffix.as_mut().unwrap().lreduce(prefix);
      }
      self.suffixes[k] = suffix;
    }
  }

  pub fn _value(&self) -> Option<f32> {
    if !self.suffixes.is_empty() {
      assert_eq!(self.steps.len(), self.suffixes.len());
      self.suffixes[0].map(|r| r.as_scalar())
    } else {
      None
    }
  }
}
<commit_msg>Implement summed value and clipped discounted value.<commit_after>//use discrete::{DiscreteSampler32};

use operator::{DiffOperatorOutput};
use sharedmem::{RwSlice};

use bit_set::{BitSet};

use rand::{Rng};
use std::cell::{RefCell};
use std::fmt::{Debug};
use std::io::{Write};
use std::rc::{Rc};

pub trait Action: Clone {
  fn dim() -> usize;
}

impl Action for f32 {
  fn dim() -> usize {
    1
  }
}

pub trait DiscreteAction: Action + Copy {
  fn from_idx(idx: u32) -> Self where Self: Sized;
  fn idx(&self) -> u32;
}

pub trait Response: Copy + Debug {
  fn lreduce(&mut self, prefix: Self);
  fn as_scalar(&self) -> f32;
}

impl Response for bool {
  #[inline]
  fn lreduce(&mut self, _: bool) {
    // Do nothing.
  }

  #[inline]
  fn as_scalar(&self) -> f32 {
    match *self {
      false => 0.0,
      true  => 1.0,
    }
  }
}

impl Response for f32 {
  #[inline]
  fn lreduce(&mut self, prefix: f32) {
    //println!("DEBUG: lreduce: {:e} {:e}", prefix, *self);
    *self += prefix;
  }

  #[inline]
  fn as_scalar(&self) -> f32 {
    *self
  }
}

#[derive(Clone, Copy, Debug)]
pub struct HorizonAveraged<T> where T: Copy {
  pub value:    T,
  pub horizon:  usize,
}

impl Response for HorizonAveraged<f32> {
  #[inline]
  fn lreduce(&mut self, prefix: HorizonAveraged<f32>) {
    assert_eq!(self.horizon, prefix.horizon);
    self.value += prefix.value;
  }

  #[inline]
  fn as_scalar(&self) -> f32 {
    self.value / self.horizon as f32
  }
}

#[derive(Clone, Copy, Debug)]
pub struct OnlineAveraged<T> where T: Copy {
  pub value:    T,
  pub count:    usize,
}

impl<T> OnlineAveraged<T> where T: Copy {
  pub fn new(value: T) -> OnlineAveraged<T> {
    OnlineAveraged{
      value:    value,
      count:    1,
    }
  }
}

impl Response for OnlineAveraged<f32> {
  #[inline]
  fn lreduce(&mut self, prefix: OnlineAveraged<f32>) {
    assert_eq!(1, prefix.count);
    self.value = self.value + (prefix.value - self.value) / (self.count + 1) as f32;
    self.count += 1;
  }

  #[inline]
  fn as_scalar(&self) -> f32 {
    self.value
  }
}

#[derive(Clone, Copy, Debug)]
pub struct Discounted<T> where T: Copy {
  pub value:    T,
  pub discount: T,
}

impl<T> Discounted<T> where T: Copy {
  pub fn new(value: T, discount: T) -> Discounted<T> {
    Discounted{
      value:    value,
      discount: discount,
    }
  }
}

impl Response for Discounted<f32> {
  #[inline]
  fn lreduce(&mut self, prefix: Discounted<f32>) {
    self.value = prefix.value + prefix.discount * self.value;
  }

  #[inline]
  fn as_scalar(&self) -> f32 {
    self.value * (1.0 - self.discount)
  }
}

#[derive(Clone, Copy, Debug)]
pub struct NormalizeDiscounted<T> where T: Copy {
  pub value:    T,
  pub discount: T,
  pub count:    usize,
}

impl<T> NormalizeDiscounted<T> where T: Copy {
  pub fn new(value: T, discount: T) -> NormalizeDiscounted<T> {
    NormalizeDiscounted{
      value:    value,
      discount: discount,
      count:    1,
    }
  }
}

impl Response for NormalizeDiscounted<f32> {
  #[inline]
  fn lreduce(&mut self, prefix: NormalizeDiscounted<f32>) {
    assert_eq!(1, prefix.count);
    self.value = prefix.value + prefix.discount * self.value;
    self.count += 1;
  }

  #[inline]
  fn as_scalar(&self) -> f32 {
    self.value * (1.0 - self.discount) / (1.0 - self.discount.powi(self.count as i32))
  }
}

pub trait Value: Copy + Debug {
  type Cfg: Copy;
  type Res: Response;

  fn from_res(res: Self::Res, cfg: Self::Cfg) -> Self where Self: Sized;
  fn from_scalar(scalar_value: f32, cfg: Self::Cfg) -> Self where Self: Sized;
  fn to_scalar(&self) -> f32;
  fn lreduce(&mut self, prefix: Self::Res);
}

#[derive(Clone, Copy, Debug)]
pub struct SumValue<T> where T: Copy {
  pub value:    T,
}

impl Value for SumValue<f32> {
  type Cfg = ();
  type Res = f32;

  fn from_res(res: f32, cfg: ()) -> SumValue<f32> {
    SumValue{
      value:    res,
    }
  }

  fn from_scalar(scalar_value: f32, cfg: ()) -> SumValue<f32> {
    SumValue{
      value:    scalar_value,
    }
  }

  fn to_scalar(&self) -> f32 {
    self.value
  }

  fn lreduce(&mut self, prefix: f32) {
    self.value = prefix + self.value;
  }
}

#[derive(Clone, Copy, Debug)]
pub struct Discount<T>(pub T) where T: Copy;

#[derive(Clone, Copy, Debug)]
pub struct DiscountedValue<T> where T: Copy {
  pub value:    T,
  pub discount: T,
}

impl Value for DiscountedValue<f32> {
  type Cfg = Discount<f32>;
  type Res = f32;

  fn from_res(res: f32, cfg: Discount<f32>) -> DiscountedValue<f32> {
    DiscountedValue{
      value:    res,
      discount: cfg.0,
    }
  }

  fn from_scalar(scalar_value: f32, cfg: Discount<f32>) -> DiscountedValue<f32> {
    DiscountedValue{
      value:    scalar_value,
      discount: cfg.0,
    }
  }

  fn to_scalar(&self) -> f32 {
    self.value
  }

  fn lreduce(&mut self, prefix: f32) {
    self.value = prefix + self.discount * self.value;
  }
}

#[derive(Clone, Copy, Debug)]
pub struct ClipDiscountedValue<T> where T: Copy {
  pub value:    T,
  pub discount: T,
}

impl Value for ClipDiscountedValue<f32> {
  type Cfg = Discount<f32>;
  type Res = f32;

  fn from_res(res: f32, cfg: Discount<f32>) -> ClipDiscountedValue<f32> {
    let clipped_res = if res > 0.0 {
      1.0
    } else if res < 0.0 {
      -1.0
    } else {
      0.0
    };
    ClipDiscountedValue{
      value:    clipped_res,
      discount: cfg.0,
    }
  }

  fn from_scalar(scalar_value: f32, cfg: Discount<f32>) -> ClipDiscountedValue<f32> {
    ClipDiscountedValue{
      value:    scalar_value,
      discount: cfg.0,
    }
  }

  fn to_scalar(&self) -> f32 {
    self.value
  }

  fn lreduce(&mut self, prefix: f32) {
    let clipped_prefix = if prefix > 0.0 {
      1.0
    } else if prefix < 0.0 {
      -1.0
    } else {
      0.0
    };
    self.value = clipped_prefix + self.discount * self.value;
  }
}

#[derive(Clone, Copy, Debug)]
pub struct NormDiscountedValue<T> where T: Copy {
  pub value:    T,
  pub discount: T,
}

impl Value for NormDiscountedValue<f32> {
  type Cfg = Discount<f32>;
  type Res = f32;

  fn from_res(res: f32, cfg: Discount<f32>) -> NormDiscountedValue<f32> {
    NormDiscountedValue{
      value:    res,
      discount: cfg.0,
    }
  }

  fn from_scalar(scalar_value: f32, cfg: Discount<f32>) -> NormDiscountedValue<f32> {
    NormDiscountedValue{
      value:    scalar_value,
      discount: cfg.0,
    }
  }

  fn to_scalar(&self) -> f32 {
    self.value * (1.0 - self.discount)
  }

  fn lreduce(&mut self, prefix: f32) {
    self.value = prefix + self.discount * self.value;
  }
}

pub trait Env: Default {
  type Init;
  type Action: Action;
  type Response: Response;

  /// Reset the environment according to the initial state distribution and
  /// other initial configuration.
  fn reset<R>(&self, init: &Self::Init, rng: &mut R) where R: Rng + Sized;

  /// Check if the environment is at a terminal state (no more legal actions).
  fn is_terminal(&self) -> bool;

  /// Check if an action is legal. Can be expensive if this involves simulating
  /// the action using `step`.
  fn is_legal_action(&self, action: &Self::Action) -> bool;

  /// Try to execute an action, returning an error if the action is illegal.
  fn step(&self, action: &Self::Action) -> Result<Option<Self::Response>, ()>;
}

pub trait DiscreteEnv: Env where Self::Action: DiscreteAction {
  /// Extracting discrete actions.
  fn extract_all_actions_buf(&mut self, actions_buf: &mut Vec<Self::Action>);
  fn extract_legal_actions_buf(&mut self, actions_buf: &mut Vec<Self::Action>);
  fn extract_legal_actions_set(&mut self, actions_set: &mut BitSet);
}

pub trait EnvSerialize: Env {
  fn serialize(&mut self, buf: &mut Write);
}

/*pub trait EnvOpaqueRepr<Obs>: Env {
  fn extract_opaque_observable(&mut self, obs: &mut Obs);
}*/

pub trait EnvInputRepr<U: ?Sized>: Env {
  fn _shape3d(&self) -> (usize, usize, usize);
}

pub trait EnvRepr<T>: Env {
  #[deprecated] fn observable_len(&mut self) -> usize { self.observable_sz() }
  fn observable_sz(&self) -> usize;
  fn extract_observable(&self, obs: &mut [T]);
}

pub trait EnvConvert<Target>: Env where Target: Env {
  fn clone_from_env(&mut self, other: &Target);

  fn from_env(other: &Target) -> Self where Self: Sized {
    let mut env: Self = Default::default();
    env.clone_from_env(other);
    env
  }
}

//#[derive(Clone)]
pub struct EpisodeStep<E> where E: Env {
  pub action:   E::Action,
  pub res:      Option<E::Response>,
  //pub next_env: Rc<RefCell<E>>,
  pub next_env: Rc<E>,
}

impl<E> Clone for EpisodeStep<E> where E: Env {
  fn clone(&self) -> EpisodeStep<E> {
    EpisodeStep{
      action:   self.action.clone(),
      res:      self.res,
      next_env: self.next_env.clone(),
    }
  }
}

//#[derive(Clone)]
pub struct Episode<E> where E: Env {
  //pub init_env: Rc<RefCell<E>>,
  pub init_env: Rc<E>,
  pub steps:    Vec<EpisodeStep<E>>,
  pub suffixes: Vec<Option<E::Response>>,
  //final_value:  Option<E::Response>,
}

impl<E> Clone for Episode<E> where E: Env {
  fn clone(&self) -> Episode<E> {
    Episode{
      init_env: self.init_env.clone(),
      steps:    self.steps.clone(),
      suffixes: self.suffixes.clone(),
      //final_value:  self.final_value,
    }
  }
}

impl<E> Episode<E> where E: Env {
  pub fn new() -> Episode<E> {
    Episode{
      //init_env: Rc::new(RefCell::new(Default::default())),
      init_env: Rc::new(Default::default()),
      steps:    vec![],
      suffixes: vec![],
      //final_value:  None,
    }
  }

  pub fn horizon(&self) -> usize {
    self.steps.len()
  }

  pub fn value(&self) -> Option<f32> {
    self.suffixes[0].map(|r| r.as_scalar())
  }

  pub fn reset<R>(&mut self, init_cfg: &E::Init, rng: &mut R) where R: Rng + Sized {
    self.init_env.reset(init_cfg, rng);
    self.steps.clear();
    self.suffixes.clear();
  }

  pub fn terminated(&self) -> bool {
    match self.steps.len() {
      0   => self.init_env.is_terminal(),
      len => self.steps[len-1].next_env.is_terminal(),
    }
  }

  /*pub fn set_final_value(&mut self, v: E::Response) {
    self.final_value = Some(v);
  }*/

  pub fn _fill_suffixes(&mut self) {
    let horizon = self.steps.len();
    self.suffixes.clear();
    for k in 0 .. horizon {
      self.suffixes.push(self.steps[k].res);
    }
    /*let mut suffix = if self.terminated() {
      None
    } else if let Some(v) = self.final_value {
      Some(v)
    } else {
      None
    };*/
    let mut suffix = None;
    for k in (0 .. horizon).rev() {
      if suffix.is_none() {
        suffix = self.steps[k].res;
      } else if let Some(prefix) = self.steps[k].res {
        suffix.as_mut().unwrap().lreduce(prefix);
      }
      self.suffixes[k] = suffix;
    }
  }

  pub fn _value(&self) -> Option<f32> {
    if !self.suffixes.is_empty() {
      assert_eq!(self.steps.len(), self.suffixes.len());
      self.suffixes[0].map(|r| r.as_scalar())
    } else {
      None
    }
  }
}
<|endoftext|>


<commit_before>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Support code for encoding and decoding types.

#![feature(macro_rules, default_type_params, slicing_syntax, globs)]

// test harness access
#[cfg(test)]
extern crate test;

pub use self::serialize::{Decoder, Encoder, Decodable, Encodable,
                          DecoderHelpers, EncoderHelpers};

mod serialize;
mod collection_impls;

pub mod base64;
pub mod hex;
pub mod json;
<commit_msg>Add doc URL to the crate<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Support code for encoding and decoding types.

#![feature(macro_rules, default_type_params, slicing_syntax, globs)]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/rustc-serialize/")]

// test harness access
#[cfg(test)]
extern crate test;

pub use self::serialize::{Decoder, Encoder, Decodable, Encodable,
                          DecoderHelpers, EncoderHelpers};

mod serialize;
mod collection_impls;

pub mod base64;
pub mod hex;
pub mod json;
<|endoftext|>


<commit_before>use libc::{uint16_t, int16_t, uint8_t, c_void};

use encparams::NtruEncParams;
use types::{NtruIntPoly, NtruProdPoly, NtruTernPoly, NtruEncKeyPair, NtruPrivPoly, NtruEncPubKey,
            NtruEncPrivKey};
use rand::NtruRandGen;

#[repr(C)]
pub struct CNtruRandContext {
    pub rand_gen: *const NtruRandGen,
    /// For deterministic RNGs
    pub seed: *const uint8_t,
    /// For deterministic RNGs
    pub seed_len: uint16_t,
    pub state: *const c_void,
}

extern {
    // ntru.h
    pub fn ntru_gen_key_pair(params: *const NtruEncParams,
                             kp: *mut NtruEncKeyPair,
                             rand_ctx: *const CNtruRandContext)
                             -> uint8_t;
    pub fn ntru_gen_key_pair_multi(params: *const NtruEncParams,
                                   private: *mut NtruEncPrivKey,
                                   public: *mut NtruEncPubKey,
                                   rand_ctx: *const CNtruRandContext,
                                   num_pub: u32)
                                   -> uint8_t;
    pub fn ntru_gen_pub(params: *const NtruEncParams,
                        private: *const NtruEncPrivKey,
                        public: *mut NtruEncPubKey,
                        rand_ctx: *const CNtruRandContext)
                        -> uint8_t;
    pub fn ntru_encrypt(msg: *const uint8_t,
                        msg_len: uint16_t,
                        public: *const NtruEncPubKey,
                        params: *const NtruEncParams,
                        rand_ctx: *const CNtruRandContext,
                        enc: *const uint8_t)
                        -> uint8_t;
    pub fn ntru_decrypt(enc: *const uint8_t,
                        kp: *const NtruEncKeyPair,
                        params: *const NtruEncParams,
                        dec: *const uint8_t,
                        dec_len: *const uint16_t)
                        -> uint8_t;

    // hash.h
    pub fn ntru_sha1(input: *const uint8_t, input_len: uint16_t, digest: *mut uint8_t);
    pub fn ntru_sha1_4way(input: *const *const uint8_t,
                          input_len: uint16_t,
                          digest: *mut *mut uint8_t);
    pub fn ntru_sha256(input: *const uint8_t, input_len: uint16_t, digest: *mut uint8_t);
    pub fn ntru_sha256_4way(input: *const *const uint8_t,
                            input_len: uint16_t,
                            digest: *mut *mut uint8_t);

    // rand.h
    pub fn ntru_rand_init(rand_ctx: *mut CNtruRandContext,
                          rand_gen: *const NtruRandGen)
                          -> uint8_t;
    pub fn ntru_rand_init_det(rand_ctx: *mut CNtruRandContext,
                              rand_gen: *const NtruRandGen,
                              seed: *const uint8_t,
                              seed_len: uint16_t)
                              -> uint8_t;
    pub fn ntru_rand_generate(rand_data: *mut uint8_t,
                              len: uint16_t,
                              rand_ctx: *const CNtruRandContext)
                              -> uint8_t;
    pub fn ntru_rand_release(rand_ctx: *mut CNtruRandContext) -> uint8_t;

    #[cfg(target_os = "windows")]
    pub fn ntru_rand_wincrypt_init(rand_ctx: *mut NtruRandContext,
                                   rand_gen: *const NtruRandGen)
                                   -> uint8_t;
    #[cfg(target_os = "windows")]
    pub fn ntru_rand_wincrypt_generate(rand_data: *mut uint8_t,
                                       len: uint16_t,
                                       rand_ctx: *const NtruRandContext)
                                       -> uint8_t;
    #[cfg(target_os = "windows")]
    pub fn ntru_rand_wincrypt_release(rand_ctx: *mut NtruRandContext) -> uint8_t;

    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devrandom_init(rand_ctx: *mut CNtruRandContext,
                                    rand_gen: *const NtruRandGen)
                                    -> uint8_t;
    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devrandom_generate(rand_data: *mut uint8_t,
                                        len: uint16_t,
                                        rand_ctx: *const CNtruRandContext)
                                        -> uint8_t;
    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devrandom_release(rand_ctx: *mut CNtruRandContext) -> uint8_t;

    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devurandom_init(rand_ctx: *mut CNtruRandContext,
                                     rand_gen: *const NtruRandGen)
                                     -> uint8_t;
    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devurandom_generate(rand_data: *mut uint8_t,
                                         len: uint16_t,
                                         rand_ctx: *const CNtruRandContext)
                                         -> uint8_t;
    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devurandom_release(rand_ctx: *mut CNtruRandContext) -> uint8_t;

    pub fn ntru_rand_igf2_init(rand_ctx: *mut CNtruRandContext,
                               rand_gen: *const NtruRandGen)
                               -> uint8_t;
    pub fn ntru_rand_igf2_generate(rand_data: *mut uint8_t,
                                   len: uint16_t,
                                   rand_ctx: *const CNtruRandContext)
                                   -> uint8_t;
    pub fn ntru_rand_igf2_release(rand_ctx: *mut CNtruRandContext) -> uint8_t;

    // poly.h
    pub fn ntru_rand_tern(n: uint16_t,
                          num_ones: uint16_t,
                          num_neg_ones: uint16_t,
                          poly: *mut NtruTernPoly,
                          rand_ctx: *const CNtruRandContext)
                          -> uint8_t;
    pub fn ntru_mult_tern(a: *const NtruIntPoly,
                          b: *const NtruTernPoly,
                          c: *mut NtruIntPoly,
                          mod_mask: uint16_t)
                          -> uint8_t;
    pub fn ntru_mult_tern_32(a: *const NtruIntPoly,
                             b: *const NtruTernPoly,
                             c: *mut NtruIntPoly,
                             mod_mask: uint16_t)
                             -> uint8_t;
    pub fn ntru_mult_tern_64(a: *const NtruIntPoly,
                             b: *const NtruTernPoly,
                             c: *mut NtruIntPoly,
                             mod_mask: uint16_t)
                             -> uint8_t;
    #[cfg(SSE3)]
    pub fn ntru_mult_tern_sse(a: *const NtruIntPoly,
                              b: *const NtruTernPoly,
                              c: *mut NtruIntPoly,
                              mod_mask: uint16_t)
                              -> uint8_t;
    pub fn ntru_mult_prod(a: *const NtruIntPoly,
                          b: *const NtruProdPoly,
                          c: *mut NtruIntPoly,
                          mod_mask: uint16_t)
                          -> uint8_t;
    pub fn ntru_mult_priv(a: *const NtruPrivPoly,
                          b: *const NtruIntPoly,
                          c: *mut NtruIntPoly,
                          mod_mask: uint16_t)
                          -> uint8_t;
    pub fn ntru_mult_int(a: *const NtruIntPoly,
                         b: *const NtruIntPoly,
                         c: *mut NtruIntPoly,
                         mod_mask: uint16_t)
                         -> uint8_t;
    pub fn ntru_mult_int_16(a: *const NtruIntPoly,
                            b: *const NtruIntPoly,
                            c: *mut NtruIntPoly,
                            mod_mask: uint16_t)
                            -> uint8_t;
    pub fn ntru_mult_int_64(a: *const NtruIntPoly,
                            b: *const NtruIntPoly,
                            c: *mut NtruIntPoly,
                            mod_mask: uint16_t)
                            -> uint8_t;
    pub fn ntru_add(a: *mut NtruIntPoly, b: *const NtruIntPoly);
    pub fn ntru_sub(a: *mut NtruIntPoly, b: *const NtruIntPoly);
    pub fn ntru_mod_mask(p: *mut NtruIntPoly, mod_mask: uint16_t);
    pub fn ntru_mult_fac(a: *mut NtruIntPoly, factor: int16_t);
    pub fn ntru_mod_center(p: *mut NtruIntPoly, modulus: uint16_t);
    pub fn ntru_mod3(p: *mut NtruIntPoly);
    pub fn ntru_to_arr_32(p: *const NtruIntPoly, q: uint16_t, a: *mut uint8_t);
    pub fn ntru_to_arr_64(p: *const NtruIntPoly, q: uint16_t, a: *mut uint8_t);
    #[cfg(SSE3)]
    pub fn ntru_to_arr_sse_2048(p: *const NtruIntPoly, a: *mut uint8_t);
    pub fn ntru_from_arr(arr: *const uint8_t, n: uint16_t, q: uint16_t, p: *mut NtruIntPoly);
    pub fn ntru_invert(a: *const NtruPrivPoly,
                       mod_mask: uint16_t,
                       fq: *mut NtruIntPoly)
                       -> uint8_t;
    pub fn ntru_invert_32(a: *const NtruPrivPoly,
                          mod_mask: uint16_t,
                          fq: *mut NtruIntPoly)
                          -> uint8_t;
    pub fn ntru_invert_64(a: *const NtruPrivPoly,
                          mod_mask: uint16_t,
                          fq: *mut NtruIntPoly)
                          -> uint8_t;

    // key.h
    pub fn ntru_export_pub(key: *const NtruEncPubKey, arr: *mut uint8_t);
    pub fn ntru_import_pub(arr: *const uint8_t, key: *mut NtruEncPubKey) -> uint16_t;

    pub fn ntru_export_priv(key: *const NtruEncPrivKey, arr: *mut uint8_t) -> uint16_t;
    pub fn ntru_import_priv(arr: *const uint8_t, key: *mut NtruEncPrivKey);

    pub fn ntru_params_from_priv_key(key: *const NtruEncPrivKey,
                                     params: *mut NtruEncParams)
                                     -> uint8_t;
}
<commit_msg>Rusty formating to extern<commit_after>use libc::{uint16_t, int16_t, uint8_t, c_void};

use encparams::NtruEncParams;
use types::{NtruIntPoly, NtruProdPoly, NtruTernPoly, NtruEncKeyPair, NtruPrivPoly, NtruEncPubKey,
            NtruEncPrivKey};
use rand::NtruRandGen;

#[repr(C)]
pub struct CNtruRandContext {
    pub rand_gen: *const NtruRandGen,
    /// For deterministic RNGs
    pub seed: *const uint8_t,
    /// For deterministic RNGs
    pub seed_len: uint16_t,
    pub state: *const c_void,
}

extern "C" {
    // ntru.h
    pub fn ntru_gen_key_pair(params: *const NtruEncParams,
                             kp: *mut NtruEncKeyPair,
                             rand_ctx: *const CNtruRandContext)
                             -> uint8_t;
    pub fn ntru_gen_key_pair_multi(params: *const NtruEncParams,
                                   private: *mut NtruEncPrivKey,
                                   public: *mut NtruEncPubKey,
                                   rand_ctx: *const CNtruRandContext,
                                   num_pub: u32)
                                   -> uint8_t;
    pub fn ntru_gen_pub(params: *const NtruEncParams,
                        private: *const NtruEncPrivKey,
                        public: *mut NtruEncPubKey,
                        rand_ctx: *const CNtruRandContext)
                        -> uint8_t;
    pub fn ntru_encrypt(msg: *const uint8_t,
                        msg_len: uint16_t,
                        public: *const NtruEncPubKey,
                        params: *const NtruEncParams,
                        rand_ctx: *const CNtruRandContext,
                        enc: *const uint8_t)
                        -> uint8_t;
    pub fn ntru_decrypt(enc: *const uint8_t,
                        kp: *const NtruEncKeyPair,
                        params: *const NtruEncParams,
                        dec: *const uint8_t,
                        dec_len: *const uint16_t)
                        -> uint8_t;

    // hash.h
    pub fn ntru_sha1(input: *const uint8_t, input_len: uint16_t, digest: *mut uint8_t);
    pub fn ntru_sha1_4way(input: *const *const uint8_t,
                          input_len: uint16_t,
                          digest: *mut *mut uint8_t);
    pub fn ntru_sha256(input: *const uint8_t, input_len: uint16_t, digest: *mut uint8_t);
    pub fn ntru_sha256_4way(input: *const *const uint8_t,
                            input_len: uint16_t,
                            digest: *mut *mut uint8_t);

    // rand.h
    pub fn ntru_rand_init(rand_ctx: *mut CNtruRandContext,
                          rand_gen: *const NtruRandGen)
                          -> uint8_t;
    pub fn ntru_rand_init_det(rand_ctx: *mut CNtruRandContext,
                              rand_gen: *const NtruRandGen,
                              seed: *const uint8_t,
                              seed_len: uint16_t)
                              -> uint8_t;
    pub fn ntru_rand_generate(rand_data: *mut uint8_t,
                              len: uint16_t,
                              rand_ctx: *const CNtruRandContext)
                              -> uint8_t;
    pub fn ntru_rand_release(rand_ctx: *mut CNtruRandContext) -> uint8_t;

    #[cfg(target_os = "windows")]
    pub fn ntru_rand_wincrypt_init(rand_ctx: *mut NtruRandContext,
                                   rand_gen: *const NtruRandGen)
                                   -> uint8_t;
    #[cfg(target_os = "windows")]
    pub fn ntru_rand_wincrypt_generate(rand_data: *mut uint8_t,
                                       len: uint16_t,
                                       rand_ctx: *const NtruRandContext)
                                       -> uint8_t;
    #[cfg(target_os = "windows")]
    pub fn ntru_rand_wincrypt_release(rand_ctx: *mut NtruRandContext) -> uint8_t;

    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devrandom_init(rand_ctx: *mut CNtruRandContext,
                                    rand_gen: *const NtruRandGen)
                                    -> uint8_t;
    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devrandom_generate(rand_data: *mut uint8_t,
                                        len: uint16_t,
                                        rand_ctx: *const CNtruRandContext)
                                        -> uint8_t;
    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devrandom_release(rand_ctx: *mut CNtruRandContext) -> uint8_t;

    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devurandom_init(rand_ctx: *mut CNtruRandContext,
                                     rand_gen: *const NtruRandGen)
                                     -> uint8_t;
    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devurandom_generate(rand_data: *mut uint8_t,
                                         len: uint16_t,
                                         rand_ctx: *const CNtruRandContext)
                                         -> uint8_t;
    #[cfg(not(target_os = "windows"))]
    pub fn ntru_rand_devurandom_release(rand_ctx: *mut CNtruRandContext) -> uint8_t;

    pub fn ntru_rand_igf2_init(rand_ctx: *mut CNtruRandContext,
                               rand_gen: *const NtruRandGen)
                               -> uint8_t;
    pub fn ntru_rand_igf2_generate(rand_data: *mut uint8_t,
                                   len: uint16_t,
                                   rand_ctx: *const CNtruRandContext)
                                   -> uint8_t;
    pub fn ntru_rand_igf2_release(rand_ctx: *mut CNtruRandContext) -> uint8_t;

    // poly.h
    pub fn ntru_rand_tern(n: uint16_t,
                          num_ones: uint16_t,
                          num_neg_ones: uint16_t,
                          poly: *mut NtruTernPoly,
                          rand_ctx: *const CNtruRandContext)
                          -> uint8_t;
    pub fn ntru_mult_tern(a: *const NtruIntPoly,
                          b: *const NtruTernPoly,
                          c: *mut NtruIntPoly,
                          mod_mask: uint16_t)
                          -> uint8_t;
    pub fn ntru_mult_tern_32(a: *const NtruIntPoly,
                             b: *const NtruTernPoly,
                             c: *mut NtruIntPoly,
                             mod_mask: uint16_t)
                             -> uint8_t;
    pub fn ntru_mult_tern_64(a: *const NtruIntPoly,
                             b: *const NtruTernPoly,
                             c: *mut NtruIntPoly,
                             mod_mask: uint16_t)
                             -> uint8_t;
    #[cfg(SSE3)]
    pub fn ntru_mult_tern_sse(a: *const NtruIntPoly,
                              b: *const NtruTernPoly,
                              c: *mut NtruIntPoly,
                              mod_mask: uint16_t)
                              -> uint8_t;
    pub fn ntru_mult_prod(a: *const NtruIntPoly,
                          b: *const NtruProdPoly,
                          c: *mut NtruIntPoly,
                          mod_mask: uint16_t)
                          -> uint8_t;
    pub fn ntru_mult_priv(a: *const NtruPrivPoly,
                          b: *const NtruIntPoly,
                          c: *mut NtruIntPoly,
                          mod_mask: uint16_t)
                          -> uint8_t;
    pub fn ntru_mult_int(a: *const NtruIntPoly,
                         b: *const NtruIntPoly,
                         c: *mut NtruIntPoly,
                         mod_mask: uint16_t)
                         -> uint8_t;
    pub fn ntru_mult_int_16(a: *const NtruIntPoly,
                            b: *const NtruIntPoly,
                            c: *mut NtruIntPoly,
                            mod_mask: uint16_t)
                            -> uint8_t;
    pub fn ntru_mult_int_64(a: *const NtruIntPoly,
                            b: *const NtruIntPoly,
                            c: *mut NtruIntPoly,
                            mod_mask: uint16_t)
                            -> uint8_t;
    pub fn ntru_add(a: *mut NtruIntPoly, b: *const NtruIntPoly);
    pub fn ntru_sub(a: *mut NtruIntPoly, b: *const NtruIntPoly);
    pub fn ntru_mod_mask(p: *mut NtruIntPoly, mod_mask: uint16_t);
    pub fn ntru_mult_fac(a: *mut NtruIntPoly, factor: int16_t);
    pub fn ntru_mod_center(p: *mut NtruIntPoly, modulus: uint16_t);
    pub fn ntru_mod3(p: *mut NtruIntPoly);
    pub fn ntru_to_arr_32(p: *const NtruIntPoly, q: uint16_t, a: *mut uint8_t);
    pub fn ntru_to_arr_64(p: *const NtruIntPoly, q: uint16_t, a: *mut uint8_t);
    #[cfg(SSE3)]
    pub fn ntru_to_arr_sse_2048(p: *const NtruIntPoly, a: *mut uint8_t);
    pub fn ntru_from_arr(arr: *const uint8_t, n: uint16_t, q: uint16_t, p: *mut NtruIntPoly);
    pub fn ntru_invert(a: *const NtruPrivPoly,
                       mod_mask: uint16_t,
                       fq: *mut NtruIntPoly)
                       -> uint8_t;
    pub fn ntru_invert_32(a: *const NtruPrivPoly,
                          mod_mask: uint16_t,
                          fq: *mut NtruIntPoly)
                          -> uint8_t;
    pub fn ntru_invert_64(a: *const NtruPrivPoly,
                          mod_mask: uint16_t,
                          fq: *mut NtruIntPoly)
                          -> uint8_t;

    // key.h
    pub fn ntru_export_pub(key: *const NtruEncPubKey, arr: *mut uint8_t);
    pub fn ntru_import_pub(arr: *const uint8_t, key: *mut NtruEncPubKey) -> uint16_t;

    pub fn ntru_export_priv(key: *const NtruEncPrivKey, arr: *mut uint8_t) -> uint16_t;
    pub fn ntru_import_priv(arr: *const uint8_t, key: *mut NtruEncPrivKey);

    pub fn ntru_params_from_priv_key(key: *const NtruEncPrivKey,
                                     params: *mut NtruEncParams)
                                     -> uint8_t;
}
<|endoftext|>