<commit_before>#![feature(box_syntax)]
#![feature(zero_one)]

pub mod expr;
pub mod symbol;

use std::{fmt, iter};
use expr::NumType;

pub use expr::{Expr, Condition, ExprError};

/// Used to name symbols and variables.
pub trait Alphabet: fmt::Display + fmt::Debug + PartialEq + Eq + Clone {}

impl Alphabet for &'static str {}
impl Alphabet for char {}
impl Alphabet for u8 {}
impl Alphabet for u16 {}
impl Alphabet for u32 {}
impl Alphabet for u64 {}
impl Alphabet for usize {}

/// The common interface for Symbols. Basically this abstracts over
/// the argument implementation.
pub trait Symbol: Clone + PartialEq + fmt::Debug {
    type A: Alphabet;

    type T: NumType;

    fn symbol(&self) -> &Self::A;

    fn args(&self) -> &[Expr<Self::T>];

    fn from_result_iter<I, E>(symbol: Self::A, args_iter: I) -> Result<Self, E> where I: Iterator<Item = Result<Expr<Self::T>, E>>;

    fn new(symbol: Self::A) -> Self {
        Self::from_iter(symbol, iter::empty())
    }

    fn from_iter<I>(symbol: Self::A, args_iter: I) -> Self where I: Iterator<Item = Expr<Self::T>> {
        let res: Result<_, ()> = Self::from_result_iter(symbol, args_iter.map(|i| Ok(i)));
        res.unwrap()
    }

    fn evaluate(&self, bindings: &[Expr<Self::T>]) -> Result<Self, ExprError> {
        Self::from_result_iter((*self.symbol()).clone(),
                          self.args()
                              .iter()
                              .map(|expr| expr.evaluate(bindings).map(|ok| Expr::Const(ok))))

    }

    fn debug_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let args = self.args();
        try!(write!(f, "{}", *self.symbol()));
        if args.is_empty() {
            return Ok(());
        }

        try!(write!(f, "("));
        for (i, expr) in args.iter().enumerate() {
            if i > 0 {
                try!(write!(f, ", "));
            }
            try!(write!(f, "{:?}", expr));
        }
        write!(f, ")")
    }
}

/// A list of Symbols.
#[derive(PartialEq, Eq, Clone)]
pub struct SymbolString<S:Symbol>(pub Vec<S>);

impl<S:Symbol> fmt::Debug for SymbolString<S> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for sym in self.0.iter() {
            try!(write!(f, "{:?}", sym));
        }
        Ok(())
    }
}

impl<S:Symbol> SymbolString<S> {
    fn from_result_iter<I, E>(symbol_iter: I) -> Result<SymbolString<S>, E>
        where I: Iterator<Item = Result<S, E>>
    {
        let mut symbols = Vec::with_capacity(symbol_iter.size_hint().0);
        for sym in symbol_iter.into_iter() {
            symbols.push(try!(sym));
        }
        Ok(SymbolString(symbols))
    }

    pub fn evaluate(&self, bindings: &[Expr<S::T>]) -> Result<SymbolString<S>, ExprError> {
        SymbolString::from_result_iter(self.0.iter().map(|sym| sym.evaluate(bindings)))
    }
}

#[derive(Debug)]
pub struct Rule<S: Symbol> {
    pub symbol: S::A,
    pub condition: Condition<S::T>,
    pub successor: SymbolString<S>,
}

#[derive(Debug, Eq, PartialEq)]
pub enum RuleError {
    SymbolMismatch,
    ConditionFalse,
    ConditionFailed,
    ExprFailed(ExprError),
}

impl<S:Symbol> Rule<S> {
    pub fn new(symbol: S::A, successor: SymbolString<S>) -> Rule<S> {
        Rule {
            symbol: symbol,
            condition: Condition::True,
            successor: successor,
        }
    }

    pub fn new_conditional(symbol: S::A,
                           successor: SymbolString<S>,
                           condition: Condition<S::T>)
                           -> Rule<S> {
        Rule {
            symbol: symbol,
            condition: condition,
            successor: successor,
        }
    }

    /// Apply the rule to the given (constant) symbol and if possible, produce
    /// a successor.
    pub fn apply(&self, sym: &S) -> Result<SymbolString<S>, RuleError> {
        let args = sym.args();
        if self.symbol.eq(sym.symbol()) {
            match self.condition.evaluate(args) {
                Ok(true) => {
                    match self.successor.evaluate(args) {
                        Ok(symstr) => Ok(symstr),
                        Err(e) => Err(RuleError::ExprFailed(e)),
                    }
                }
                Ok(false) => {
                    Err(RuleError::ConditionFalse)
                }
                _ => {
                    Err(RuleError::ConditionFailed)
                }
            }
        } else {
            Err(RuleError::SymbolMismatch)
        }
    }
}

#[test]
fn test_rule_apply() {
    use symbol::DSym;
    let p = DSym::new_parametric("P", vec![Expr::Const(123u32)]);
    let rule = Rule::new("A", SymbolString(vec![p.clone()]));
    assert_eq!(Err(RuleError::SymbolMismatch),
               rule.apply(&DSym::new("P")));
    assert_eq!(Ok(SymbolString(vec![DSym::new_parametric("P", vec![Expr::Const(123u32)])])),
               rule.apply(&DSym::new("A")));

    let rule = Rule::new_conditional("A", SymbolString(vec![p.clone()]), Condition::False);
    assert_eq!(Err(RuleError::ConditionFalse),
               rule.apply(&DSym::new("A")));
}

#[derive(Debug)]
pub struct System<S: Symbol> {
    rules: Vec<Rule<S>>,
}

impl<S:Symbol> System<S> {
    pub fn new() -> System<S> {
        System { rules: vec![] }
    }

    pub fn add_rule(&mut self, rule: Rule<S>) {
        self.rules.push(rule);
    }

    /// Apply first matching rule and return expanded successor.
    fn apply_first_rule(&self, sym: &S) -> Option<SymbolString<S>> {
        for rule in self.rules.iter() {
            if let Ok(successor) = rule.apply(sym) {
                return Some(successor);
            }
        }
        return None;
    }

    /// Apply in parallel the first matching rule to each symbol in the string.
    /// Returns the total number of rule applications.
    pub fn develop_step(&self, axiom: &SymbolString<S>) -> (SymbolString<S>, usize) {
        let mut expanded = Vec::new();
        let mut rule_applications = 0;

        for sym in axiom.0.iter() {
            match self.apply_first_rule(sym) {
                Some(successor) => {
                    expanded.extend(successor.0);
                    rule_applications += 1;
                    // XXX: Count rule applications of the matching rule.
                }
                None => {
                    expanded.push(sym.clone());
                }
            }
        }

        (SymbolString(expanded), rule_applications)
    }

    /// Develop the system starting with `axiom` up to `max_iterations`. Return iteration count.
    pub fn develop(&self,
                   axiom: SymbolString<S>,
                   max_iterations: usize)
                   -> (SymbolString<S>, usize) {
        let mut current = axiom;

        for iter in 0..max_iterations {
            let (next, rule_applications) = self.develop_step(&current);
            if rule_applications == 0 {
                return (current, iter);
            }
            current = next;
        }
        return (current, max_iterations);
    }
}
<commit_msg>More derive(Clone)<commit_after>#![feature(box_syntax)]
#![feature(zero_one)]

pub mod expr;
pub mod symbol;

use std::{fmt, iter};
use expr::NumType;

pub use expr::{Expr, Condition, ExprError};

/// Used to name symbols and variables.
pub trait Alphabet: fmt::Display + fmt::Debug + PartialEq + Eq + Clone {}

impl Alphabet for &'static str {}
impl Alphabet for char {}
impl Alphabet for u8 {}
impl Alphabet for u16 {}
impl Alphabet for u32 {}
impl Alphabet for u64 {}
impl Alphabet for usize {}

/// The common interface for Symbols. Basically this abstracts over
/// the argument implementation.
pub trait Symbol: Clone + PartialEq + fmt::Debug {
    type A: Alphabet;

    type T: NumType;

    fn symbol(&self) -> &Self::A;

    fn args(&self) -> &[Expr<Self::T>];

    fn from_result_iter<I, E>(symbol: Self::A, args_iter: I) -> Result<Self, E> where I: Iterator<Item = Result<Expr<Self::T>, E>>;

    fn new(symbol: Self::A) -> Self {
        Self::from_iter(symbol, iter::empty())
    }

    fn from_iter<I>(symbol: Self::A, args_iter: I) -> Self where I: Iterator<Item = Expr<Self::T>> {
        let res: Result<_, ()> = Self::from_result_iter(symbol, args_iter.map(|i| Ok(i)));
        res.unwrap()
    }

    fn evaluate(&self, bindings: &[Expr<Self::T>]) -> Result<Self, ExprError> {
        Self::from_result_iter((*self.symbol()).clone(),
                          self.args()
                              .iter()
                              .map(|expr| expr.evaluate(bindings).map(|ok| Expr::Const(ok))))

    }

    fn debug_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let args = self.args();
        try!(write!(f, "{}", *self.symbol()));
        if args.is_empty() {
            return Ok(());
        }

        try!(write!(f, "("));
        for (i, expr) in args.iter().enumerate() {
            if i > 0 {
                try!(write!(f, ", "));
            }
            try!(write!(f, "{:?}", expr));
        }
        write!(f, ")")
    }
}

/// A list of Symbols.
#[derive(PartialEq, Eq, Clone)]
pub struct SymbolString<S:Symbol>(pub Vec<S>);

impl<S:Symbol> fmt::Debug for SymbolString<S> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for sym in self.0.iter() {
            try!(write!(f, "{:?}", sym));
        }
        Ok(())
    }
}

impl<S:Symbol> SymbolString<S> {
    fn from_result_iter<I, E>(symbol_iter: I) -> Result<SymbolString<S>, E>
        where I: Iterator<Item = Result<S, E>>
    {
        let mut symbols = Vec::with_capacity(symbol_iter.size_hint().0);
        for sym in symbol_iter.into_iter() {
            symbols.push(try!(sym));
        }
        Ok(SymbolString(symbols))
    }

    pub fn evaluate(&self, bindings: &[Expr<S::T>]) -> Result<SymbolString<S>, ExprError> {
        SymbolString::from_result_iter(self.0.iter().map(|sym| sym.evaluate(bindings)))
    }
}

#[derive(Debug, Clone)]
pub struct Rule<S: Symbol> {
    pub symbol: S::A,
    pub condition: Condition<S::T>,
    pub successor: SymbolString<S>,
}

#[derive(Debug, Eq, PartialEq)]
pub enum RuleError {
    SymbolMismatch,
    ConditionFalse,
    ConditionFailed,
    ExprFailed(ExprError),
}

impl<S:Symbol> Rule<S> {
    pub fn new(symbol: S::A, successor: SymbolString<S>) -> Rule<S> {
        Rule {
            symbol: symbol,
            condition: Condition::True,
            successor: successor,
        }
    }

    pub fn new_conditional(symbol: S::A,
                           successor: SymbolString<S>,
                           condition: Condition<S::T>)
                           -> Rule<S> {
        Rule {
            symbol: symbol,
            condition: condition,
            successor: successor,
        }
    }

    /// Apply the rule to the given (constant) symbol and if possible, produce
    /// a successor.
    pub fn apply(&self, sym: &S) -> Result<SymbolString<S>, RuleError> {
        let args = sym.args();
        if self.symbol.eq(sym.symbol()) {
            match self.condition.evaluate(args) {
                Ok(true) => {
                    match self.successor.evaluate(args) {
                        Ok(symstr) => Ok(symstr),
                        Err(e) => Err(RuleError::ExprFailed(e)),
                    }
                }
                Ok(false) => {
                    Err(RuleError::ConditionFalse)
                }
                _ => {
                    Err(RuleError::ConditionFailed)
                }
            }
        } else {
            Err(RuleError::SymbolMismatch)
        }
    }
}

#[test]
fn test_rule_apply() {
    use symbol::DSym;
    let p = DSym::new_parametric("P", vec![Expr::Const(123u32)]);
    let rule = Rule::new("A", SymbolString(vec![p.clone()]));
    assert_eq!(Err(RuleError::SymbolMismatch),
               rule.apply(&DSym::new("P")));
    assert_eq!(Ok(SymbolString(vec![DSym::new_parametric("P", vec![Expr::Const(123u32)])])),
               rule.apply(&DSym::new("A")));

    let rule = Rule::new_conditional("A", SymbolString(vec![p.clone()]), Condition::False);
    assert_eq!(Err(RuleError::ConditionFalse),
               rule.apply(&DSym::new("A")));
}

#[derive(Debug, Clone)]
pub struct System<S: Symbol> {
    rules: Vec<Rule<S>>,
}

impl<S:Symbol> System<S> {
    pub fn new() -> System<S> {
        System { rules: vec![] }
    }

    pub fn add_rule(&mut self, rule: Rule<S>) {
        self.rules.push(rule);
    }

    /// Apply first matching rule and return expanded successor.
    fn apply_first_rule(&self, sym: &S) -> Option<SymbolString<S>> {
        for rule in self.rules.iter() {
            if let Ok(successor) = rule.apply(sym) {
                return Some(successor);
            }
        }
        return None;
    }

    /// Apply in parallel the first matching rule to each symbol in the string.
    /// Returns the total number of rule applications.
    pub fn develop_step(&self, axiom: &SymbolString<S>) -> (SymbolString<S>, usize) {
        let mut expanded = Vec::new();
        let mut rule_applications = 0;

        for sym in axiom.0.iter() {
            match self.apply_first_rule(sym) {
                Some(successor) => {
                    expanded.extend(successor.0);
                    rule_applications += 1;
                    // XXX: Count rule applications of the matching rule.
                }
                None => {
                    expanded.push(sym.clone());
                }
            }
        }

        (SymbolString(expanded), rule_applications)
    }

    /// Develop the system starting with `axiom` up to `max_iterations`. Return iteration count.
    pub fn develop(&self,
                   axiom: SymbolString<S>,
                   max_iterations: usize)
                   -> (SymbolString<S>, usize) {
        let mut current = axiom;

        for iter in 0..max_iterations {
            let (next, rule_applications) = self.develop_step(&current);
            if rule_applications == 0 {
                return (current, iter);
            }
            current = next;
        }
        return (current, max_iterations);
    }
}
<|endoftext|>


<commit_before>//! A native RethinkDB driver written in Rust

#[macro_use]
extern crate reql_derive;
extern crate ql2;
extern crate protobuf;
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate derive_error;
/*
#[macro_use]
extern crate serde_derive;
*/
extern crate byteorder;
extern crate bufstream;
extern crate uuid;

#[cfg(test)]
mod tests;

#[macro_use]
mod macros;
mod types;
mod args;
pub mod commands;
pub mod errors;

#[doc(hidden)]
pub use ql2::proto::Term;

use protobuf::ProtobufEnum;
use ql2::proto::{Datum,
    Term_TermType as TT,
    Term_AssocPair as TA,
    Datum_DatumType as DT,
};

/// The result of any ReQL command that can potentially return an error
pub type Result<T> = ::std::result::Result<T, errors::Error>;

/// The argument that is passed to any ReQL command
pub trait ToArg {
    fn to_arg(&self) -> Term;
}

/// Any object that can be used as a ReQL connection
pub trait Connection {
}

trait IsDatum {
    fn is_datum(&self) -> bool;
}

trait IsEmpty {
    fn is_empty(&self) -> bool;
}

trait Encode {
    fn encode(&self) -> String;
}

impl IsDatum for Term {
    fn is_datum(&self) -> bool {
        self.get_field_type() == TT::DATUM
    }
}

impl IsEmpty for Term {
    fn is_empty(&self) -> bool {
        *self == Term::new()
    }
}

impl Encode for Vec<TA> {
    fn encode(&self) -> String {
        let mut opts = String::from("{");
        for term in self {
            opts.push_str(&format!("\"{}\":{},", term.get_key(), term.get_val().encode()));
        }
        opts = opts.trim_right_matches(",").to_string();
        opts.push_str("}");
        opts
    }
}

impl Encode for Datum {
    fn encode(&self) -> String {
        match self.get_field_type() {
            DT::R_NULL => {
                String::from("null")
            },
            DT::R_BOOL => {
                format!("{}", self.get_r_bool())
            },
            DT::R_NUM => {
                format!("{}", self.get_r_num())
            },
            DT::R_STR => {
                format!("\"{}\"", self.get_r_str())
            },
            DT::R_ARRAY => {
                let mut args = format!("[{},[", TT::MAKE_ARRAY.value());
                for term in self.get_r_array() {
                    args.push_str(&format!("{},", term.encode()));
                }
                args = args.trim_right_matches(",").to_string();
                args.push_str("]]");
                args
            },
            DT::R_OBJECT => {
                let mut args = String::from("{");
                for term in self.get_r_object() {
                    args.push_str(&format!("\"{}\":{},", term.get_key(), term.get_val().encode()));
                }
                args = args.trim_right_matches(",").to_string();
                args.push_str("}");
                args
            },
            DT::R_JSON => {
                unimplemented!();
            },
        }
    }
}

impl Encode for Term {
    fn encode(&self) -> String {
        let mut res = Vec::new();
        if !self.is_datum() {
            res.push(format!("[{}", self.get_field_type().value()));
        }
        if self.has_datum() {
            let datum = self.get_datum();
            res.push(datum.encode());
        }
        let terms = self.get_args();
        if !terms.is_empty() {
            let mut args = String::from("[");
            for term in terms {
                args.push_str(&format!("{},", term.encode()));
            }
            args = args.trim_right_matches(",").to_string();
            args.push_str("]");
            res.push(args);
        }
        let opts = self.clone().take_optargs().into_vec();
        if !opts.is_empty() {
            res.push(format!("{}", opts.encode()));
        }
        let mut res = res.join(",");
        if !self.is_datum() {
            res.push_str("]");
        }
        res
    }
}
<commit_msg>Add Connection::broken()<commit_after>//! A native RethinkDB driver written in Rust

#[macro_use]
extern crate reql_derive;
extern crate ql2;
extern crate protobuf;
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate derive_error;
/*
#[macro_use]
extern crate serde_derive;
*/
extern crate byteorder;
extern crate bufstream;
extern crate uuid;

#[cfg(test)]
mod tests;

#[macro_use]
mod macros;
mod types;
mod args;
pub mod commands;
pub mod errors;

#[doc(hidden)]
pub use ql2::proto::Term;

use protobuf::ProtobufEnum;
use ql2::proto::{Datum,
    Term_TermType as TT,
    Term_AssocPair as TA,
    Datum_DatumType as DT,
};

/// The result of any ReQL command that can potentially return an error
pub type Result<T> = ::std::result::Result<T, errors::Error>;

/// The argument that is passed to any ReQL command
pub trait ToArg {
    fn to_arg(&self) -> Term;
}

/// Any object that can be used as a ReQL connection
pub trait Connection {
    /*
    fn stream(&mut self) -> &mut TcpStream;
    fn incr_token(&mut self) -> &mut Self;
    fn token(&self) -> u64;
    fn set_broken(&mut self, b: bool) -> &mut Self;
    */
    fn broken(&self) -> bool;
}

trait IsDatum {
    fn is_datum(&self) -> bool;
}

trait IsEmpty {
    fn is_empty(&self) -> bool;
}

trait Encode {
    fn encode(&self) -> String;
}

impl IsDatum for Term {
    fn is_datum(&self) -> bool {
        self.get_field_type() == TT::DATUM
    }
}

impl IsEmpty for Term {
    fn is_empty(&self) -> bool {
        *self == Term::new()
    }
}

impl Encode for Vec<TA> {
    fn encode(&self) -> String {
        let mut opts = String::from("{");
        for term in self {
            opts.push_str(&format!("\"{}\":{},", term.get_key(), term.get_val().encode()));
        }
        opts = opts.trim_right_matches(",").to_string();
        opts.push_str("}");
        opts
    }
}

impl Encode for Datum {
    fn encode(&self) -> String {
        match self.get_field_type() {
            DT::R_NULL => {
                String::from("null")
            },
            DT::R_BOOL => {
                format!("{}", self.get_r_bool())
            },
            DT::R_NUM => {
                format!("{}", self.get_r_num())
            },
            DT::R_STR => {
                format!("\"{}\"", self.get_r_str())
            },
            DT::R_ARRAY => {
                let mut args = format!("[{},[", TT::MAKE_ARRAY.value());
                for term in self.get_r_array() {
                    args.push_str(&format!("{},", term.encode()));
                }
                args = args.trim_right_matches(",").to_string();
                args.push_str("]]");
                args
            },
            DT::R_OBJECT => {
                let mut args = String::from("{");
                for term in self.get_r_object() {
                    args.push_str(&format!("\"{}\":{},", term.get_key(), term.get_val().encode()));
                }
                args = args.trim_right_matches(",").to_string();
                args.push_str("}");
                args
            },
            DT::R_JSON => {
                unimplemented!();
            },
        }
    }
}

impl Encode for Term {
    fn encode(&self) -> String {
        let mut res = Vec::new();
        if !self.is_datum() {
            res.push(format!("[{}", self.get_field_type().value()));
        }
        if self.has_datum() {
            let datum = self.get_datum();
            res.push(datum.encode());
        }
        let terms = self.get_args();
        if !terms.is_empty() {
            let mut args = String::from("[");
            for term in terms {
                args.push_str(&format!("{},", term.encode()));
            }
            args = args.trim_right_matches(",").to_string();
            args.push_str("]");
            res.push(args);
        }
        let opts = self.clone().take_optargs().into_vec();
        if !opts.is_empty() {
            res.push(format!("{}", opts.encode()));
        }
        let mut res = res.join(",");
        if !self.is_datum() {
            res.push_str("]");
        }
        res
    }
}
<|endoftext|>


<commit_before>#![crate_type = "lib"]
#![warn(missing_docs)]

//! Synchronization primitives based on spinning

#![cfg_attr(feature = "asm", feature(asm))]
#![cfg_attr(feature = "core_intrinsics", feature(core_intrinsics))]
#![cfg_attr(feature = "const_fn", feature(const_fn, const_unsafe_cell_new, const_atomic_usize_new))]

#![no_std]

#[cfg(test)]
#[macro_use]
extern crate std;

pub use mutex::*;
pub use rw_lock::*;

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

mod mutex;
mod rw_lock;

#[cfg(feature = "once")]
mod once;

mod util;
<commit_msg>chmod -x src/lib.rs<commit_after>#![crate_type = "lib"]
#![warn(missing_docs)]

//! Synchronization primitives based on spinning

#![cfg_attr(feature = "asm", feature(asm))]
#![cfg_attr(feature = "core_intrinsics", feature(core_intrinsics))]
#![cfg_attr(feature = "const_fn", feature(const_fn, const_unsafe_cell_new, const_atomic_usize_new))]

#![no_std]

#[cfg(test)]
#[macro_use]
extern crate std;

pub use mutex::*;
pub use rw_lock::*;

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

mod mutex;
mod rw_lock;

#[cfg(feature = "once")]
mod once;

mod util;
<|endoftext|>


<commit_before>
//! A serialization framework supporting the following features:
//!
//! - Arbitrary types can implement the `Encodable` and `Decodable` traits
//!   to support serialization
//! - Serialization can be "context-aware", that is, `Encodables` and
//!   `Decodables` can specify what kind of context they need to be serialized
//!   or deserialized. For example, certain values may always need to be
//!   interned at runtime. Such a value would implement `Decodable` with a
//!   context from which the needed interner is reachable.
//! - The framework supports "objects", that is, types can implement the
//!   `EncodableObject` and `DecodableObject` traits, which will make their
//!   actual data only be emitted once within some encoded dataset. Other
//!   `Encodables` only store a reference to where the objects data is located.
//! - `Encodables` do not need to know there encoded size beforehand and can
//!   indeed be of variable size. This allows for space-efficient encodings
//!   like using the LEB128 format for integers.
//! - Encoding and decoding generally does not need to do dynamic memory
//!   allocation.
//! - The API is designed in a way that should allow for easily auto-generating
//!   serialization and deserialization code.
//! - Completely safe implementation (no `unsafe` used).

use std::collections::HashMap;
use std::collections::hash_map::Entry::{Vacant, Occupied};

//=-----------------------------------------------------------------------------
// ENCODING
//=-----------------------------------------------------------------------------

#[derive(Clone, Copy, Eq, PartialEq, Hash)]
pub struct ObjectUid(u64);
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
pub struct ObjectTableIndex(u32);

/// Something that can be encoded given a certain context ECX.
pub trait Encodable<ECX> {
    fn encode<'ecx, 'encodable>(&'encodable self,
                                session: &mut EncodingContext<'ecx, ECX>)
        where 'encodable: 'ecx;
}

/// Values implementing this trait will only be emitted once during an
/// EncodingSession. Other values referencing them only store an address where
/// actual object can be found within the encoded data.
pub trait EncodableObject<ECX> : Encodable<ECX> {
    fn object_uid(&self) -> ObjectUid;

    fn encode_contents<'encodable, 'ecx>(&'encodable self,
                                         session: &mut EncodingContext<'ecx, ECX>)
        where 'encodable: 'ecx;
}

pub trait Encoder {
    fn position(&self) -> u64;
    fn finalize(self: Box<Self>, four_cc: [u8; 4], object_table_address: u64);

    fn emit_u32(&mut self, value: u32);
    fn emit_u64(&mut self, value: u64);
    // TODO: Add emit_* methods of other primitive and composite types
}

pub struct EncodingContext<'ctx, ECX: 'ctx> {
    encoder: &'ctx mut Encoder,
    object_table_indices: &'ctx mut HashMap<ObjectUid, ObjectTableIndex>,
    object_table: &'ctx mut Vec<u64>,
    delayed_writes: &'ctx mut Vec<(&'ctx EncodableObject<ECX>, ObjectTableIndex)>,
    pub extra: &'ctx mut ECX
}

impl<'sess, ECX: 'sess> EncodingContext<'sess, ECX> {

    pub fn encoder(&mut self) -> &mut Encoder {
        &mut *self.encoder
    }

    pub fn encode_object<'object, O>(&mut self, object: &'object O)
        where O: EncodableObject<ECX>,
              'object: 'sess
    {
        let object_uid = EncodableObject::object_uid(object);
        let (object_table_index, is_new) = self.get_object_table_index(object_uid);

        self.encoder().emit_u32(object_table_index.0);

        if is_new {
            self.enqueue_object_encoding(object_table_index,
                                         object as &'sess EncodableObject<ECX>);
        }
    }

    fn get_object_table_index(&mut self, object_uid: ObjectUid) -> (ObjectTableIndex, bool) {
        match self.object_table_indices.entry(object_uid) {
            Occupied(occupied) => (*occupied.get(), false),
            Vacant(vacant) => {
                // TODO: make this a safe conversion
                let index = ObjectTableIndex(self.object_table.len() as u32);
                vacant.insert(index);
                self.object_table.push(u64::max_value());
                (index, true)
            }
        }
    }

    fn write_enqueued_objects(&mut self) {
        loop {
            // encoding objects might add more to this queue, so we can't do
            // this in a for loop
            let item = self.delayed_writes.pop();

            match item {
                Some((object, object_table_index)) => {
                    let position = self.encoder.position();
                    object.encode_contents(self);
                    // Now that we know the address, write it to the table
                    self.object_table[object_table_index.0 as usize] = position;
                },
                None => break,
            }
        }
    }

    fn enqueue_object_encoding(&mut self,
                               object_table_index: ObjectTableIndex,
                               encodable: &'sess EncodableObject<ECX>) {
        self.delayed_writes.push((encodable, object_table_index));
    }
}

pub struct EncodingSession<ECX> {
    encoder: Box<Encoder>,
    object_table_indices: HashMap<ObjectUid, ObjectTableIndex>,
    object_table: Vec<u64>,
    pub context: ECX
}

impl<ECX> EncodingSession<ECX> {

    pub fn new<E: Encoder+'static>(encoder: E, ecx: ECX) -> EncodingSession<ECX> {
        EncodingSession {
            encoder: Box::new(encoder),
            object_table_indices: HashMap::new(),
            object_table: Vec::new(),
            context: ecx
        }
    }

    pub fn encode<T: Encodable<ECX>>(&mut self, encodable: &T) {
        let mut delayed_writes = Vec::new();

        let mut context = EncodingContext {
            encoder: &mut *self.encoder,
            object_table_indices: &mut self.object_table_indices,
            object_table: &mut self.object_table,
            delayed_writes: &mut delayed_writes,
            extra: &mut self.context,
        };

        encodable.encode(&mut context);
        context.write_enqueued_objects();
    }

    pub fn finalize(mut self, four_cc: [u8; 4]) {
        let object_table_address = self.encoder.position();

        for object_table_entry in self.object_table {
            self.encoder.emit_u64(object_table_entry);
        }

        self.encoder.finalize(four_cc, object_table_address);
    }
}

//=-----------------------------------------------------------------------------
// DECODING
//=-----------------------------------------------------------------------------
// TODO: The decoding API is still in flux.

pub trait Decodable<DCX> {
    fn decode(context: &mut DecodingContext<DCX>) -> Self;
}

pub trait DecodableObject<DCX> : Decodable<DCX> {
    fn decode_contents(context: &mut DecodingContext<DCX>) -> Self;
}

pub trait Decoder {
    fn set_position(&mut self, position: u64);
    fn position(&self) -> u64;
    fn read_u32(&mut self) -> u32;
    fn read_u64(&mut self) -> u64;
}

pub struct DecodingContext<'ctx, DCX> {
    decoder: &'ctx mut Decoder,
    object_table: Vec<u64>,
    pub extra: DCX,
}

impl<'ctx, DCX> DecodingContext<'ctx, DCX> {

    pub fn decoder(&mut self) -> &mut Decoder {
        self.decoder
    }

    pub fn decode_object<T:DecodableObject<DCX>>(&mut self) -> T {
        let object_table_index = self.decoder.read_u32();

        let address = self.object_table[object_table_index as usize];

        let current_position = self.decoder.position();
        self.decoder.set_position(address);

        let object = DecodableObject::decode_contents(self);

        self.decoder.set_position(current_position);

        object
    }
}

pub struct DecodingSession<'ctx, DCX> {
    context: DecodingContext<'ctx, DCX>
}

impl<'ctx, DCX> DecodingSession<'ctx, DCX> {

    pub fn decode<T: Decodable<DCX>>(&mut self) -> T {
        Decodable::decode(&mut self.context)
    }
}

//=-----------------------------------------------------------------------------
// TEST
//=-----------------------------------------------------------------------------

struct Ast {
    id: u64
}

impl<ECX> Encodable<ECX> for u64 {
    fn encode<'ecx, 'a: 'ecx>(&'a self, ecx: &mut EncodingContext<'ecx, ECX>) {
        ecx.encoder().emit_u64(*self)
    }
}

impl<DCX> Decodable<DCX> for u64 {
    fn decode(context: &mut DecodingContext<DCX>) -> u64 {
        context.decoder().read_u64()
    }
}

impl<ECX> Encodable<ECX> for Ast {
    fn encode<'ecx, 'a: 'ecx>(&'a self, ecx: &mut EncodingContext<'ecx, ECX>) {
        Encodable::encode(&self.id, ecx)
    }
}

impl<DCX> Decodable<DCX> for Ast {
    fn decode(context: &mut DecodingContext<DCX>) -> Ast {
        Ast { id: Decodable::decode(context) }
    }
}

impl<T: Encodable<ECX>, ECX> Encodable<ECX> for Option<T> {
    fn encode<'ecx, 'a: 'ecx>(&'a self, ecx: &mut EncodingContext<'ecx, ECX>) {
        match *self {
            None => {
                ecx.encoder().emit_u32(0)
            }
            Some(ref value) => {
                ecx.encoder.emit_u32(1);
                Encodable::encode(value, ecx)
            }
        }
    }
}

impl<T: Decodable<DCX>, DCX> Decodable<DCX> for Option<T> {
    fn decode(context: &mut DecodingContext<DCX>) -> Option<T> {
        let disr = context.decoder().read_u32();
        if disr == 0 {
            None
        }
        else {
            Some(Decodable::decode(context))
        }
    }
}

struct Ty<'tcx> {
    id: u64,
    ast: Ast,
    sub_ty: Option<&'tcx Ty<'tcx>>
}

trait TyRestoreContext<'tcx> {
    fn create_interned(&self, id: u64, ast: Ast, sub_ty: Option<&'tcx Ty<'tcx>>) -> &'tcx Ty<'tcx>;
}

impl<'tcx, DCX: TyRestoreContext<'tcx>> Decodable<DCX> for &'tcx Ty<'tcx> {
    fn decode(context: &mut DecodingContext<DCX>) -> &'tcx Ty<'tcx> {
        let id = Decodable::decode(context);
        let ast = Decodable::decode(context);
        let sub_ty = Decodable::decode(context);

        context.extra.create_interned(id, ast, sub_ty)
    }
}

impl<'tcx, DCX: TyRestoreContext<'tcx>> Decodable<DCX> for Ty<'tcx> {
    fn decode(context: &mut DecodingContext<DCX>) -> Ty<'tcx> {
        let id = Decodable::decode(context);
        let ast = Decodable::decode(context);
        let sub_ty = Decodable::decode(context);

        Ty {
            id: id,
            ast: ast,
            sub_ty: sub_ty
        }
    }
}
<commit_msg>Add Address type<commit_after>
//! A serialization framework supporting the following features:
//!
//! - Arbitrary types can implement the `Encodable` and `Decodable` traits
//!   to support serialization
//! - Serialization can be "context-aware", that is, `Encodables` and
//!   `Decodables` can specify what kind of context they need to be serialized
//!   or deserialized. For example, certain values may always need to be
//!   interned at runtime. Such a value would implement `Decodable` with a
//!   context from which the needed interner is reachable.
//! - The framework supports "objects", that is, types can implement the
//!   `EncodableObject` and `DecodableObject` traits, which will make their
//!   actual data only be emitted once within some encoded dataset. Other
//!   `Encodables` only store a reference to where the objects data is located.
//! - `Encodables` do not need to know there encoded size beforehand and can
//!   indeed be of variable size. This allows for space-efficient encodings
//!   like using the LEB128 format for integers.
//! - Encoding and decoding generally does not need to do dynamic memory
//!   allocation.
//! - The API is designed in a way that should allow for easily auto-generating
//!   serialization and deserialization code.
//! - Completely safe implementation (no `unsafe` used).

use std::collections::HashMap;
use std::collections::hash_map::Entry::{Vacant, Occupied};

//=-----------------------------------------------------------------------------
// ENCODING
//=-----------------------------------------------------------------------------

#[derive(Clone, Copy, Eq, PartialEq, Hash)]
pub struct Address(u64);
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
pub struct ObjectTableIndex(u32);
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
pub struct ObjectUid(u64);

/// Something that can be encoded given a certain context ECX.
pub trait Encodable<ECX> {
    fn encode<'ecx, 'encodable>(&'encodable self,
                                session: &mut EncodingContext<'ecx, ECX>)
        where 'encodable: 'ecx;
}

/// Values implementing this trait will only be emitted once during an
/// EncodingSession. Other values referencing them only store an address where
/// actual object can be found within the encoded data.
pub trait EncodableObject<ECX> : Encodable<ECX> {
    fn object_uid(&self) -> ObjectUid;

    fn encode_contents<'encodable, 'ecx>(&'encodable self,
                                         session: &mut EncodingContext<'ecx, ECX>)
        where 'encodable: 'ecx;
}

pub trait Encoder {
    fn position(&self) -> Address;
    fn finalize(self: Box<Self>, four_cc: [u8; 4], object_table_address: Address);

    fn emit_u32(&mut self, value: u32);
    fn emit_u64(&mut self, value: u64);
    // TODO: Add emit_* methods of other primitive and composite types
}

pub struct EncodingContext<'ctx, ECX: 'ctx> {
    encoder: &'ctx mut Encoder,
    object_table_indices: &'ctx mut HashMap<ObjectUid, ObjectTableIndex>,
    object_table: &'ctx mut Vec<Address>,
    delayed_writes: &'ctx mut Vec<(&'ctx EncodableObject<ECX>, ObjectTableIndex)>,
    pub extra: &'ctx mut ECX
}

impl<'sess, ECX: 'sess> EncodingContext<'sess, ECX> {

    pub fn encoder(&mut self) -> &mut Encoder {
        &mut *self.encoder
    }

    pub fn encode_object<'object, O>(&mut self, object: &'object O)
        where O: EncodableObject<ECX>,
              'object: 'sess
    {
        let object_uid = EncodableObject::object_uid(object);
        let (object_table_index, is_new) = self.get_object_table_index(object_uid);

        self.encoder().emit_u32(object_table_index.0);

        if is_new {
            self.enqueue_object_encoding(object_table_index,
                                         object as &'sess EncodableObject<ECX>);
        }
    }

    fn get_object_table_index(&mut self, object_uid: ObjectUid) -> (ObjectTableIndex, bool) {
        match self.object_table_indices.entry(object_uid) {
            Occupied(occupied) => (*occupied.get(), false),
            Vacant(vacant) => {
                // TODO: make this a safe conversion
                let index = ObjectTableIndex(self.object_table.len() as u32);
                vacant.insert(index);
                self.object_table.push(Address(u64::max_value()));
                (index, true)
            }
        }
    }

    fn write_enqueued_objects(&mut self) {
        loop {
            // encoding objects might add more to this queue, so we can't do
            // this in a for loop
            let item = self.delayed_writes.pop();

            match item {
                Some((object, object_table_index)) => {
                    let position = self.encoder.position();
                    object.encode_contents(self);
                    // Now that we know the address, write it to the table
                    self.object_table[object_table_index.0 as usize] = position;
                },
                None => break,
            }
        }
    }

    fn enqueue_object_encoding(&mut self,
                               object_table_index: ObjectTableIndex,
                               encodable: &'sess EncodableObject<ECX>) {
        self.delayed_writes.push((encodable, object_table_index));
    }
}

pub struct EncodingSession<ECX> {
    encoder: Box<Encoder>,
    object_table_indices: HashMap<ObjectUid, ObjectTableIndex>,
    object_table: Vec<Address>,
    pub context: ECX
}

impl<ECX> EncodingSession<ECX> {

    pub fn new<E: Encoder+'static>(encoder: E, ecx: ECX) -> EncodingSession<ECX> {
        EncodingSession {
            encoder: Box::new(encoder),
            object_table_indices: HashMap::new(),
            object_table: Vec::new(),
            context: ecx
        }
    }

    pub fn encode<T: Encodable<ECX>>(&mut self, encodable: &T) -> Address {
        let mut delayed_writes = Vec::new();

        let address = self.encoder.position();

        let mut context = EncodingContext {
            encoder: &mut *self.encoder,
            object_table_indices: &mut self.object_table_indices,
            object_table: &mut self.object_table,
            delayed_writes: &mut delayed_writes,
            extra: &mut self.context,
        };

        encodable.encode(&mut context);
        context.write_enqueued_objects();

        address
    }

    pub fn finalize(mut self, four_cc: [u8; 4]) {
        let object_table_address = self.encoder.position();

        for object_table_entry in self.object_table {
            self.encoder.emit_u64(object_table_entry.0);
        }

        self.encoder.finalize(four_cc, object_table_address);
    }
}

//=-----------------------------------------------------------------------------
// DECODING
//=-----------------------------------------------------------------------------
// TODO: The decoding API is still in flux.

pub trait Decodable<DCX> {
    fn decode(context: &mut DecodingContext<DCX>) -> Self;
}

pub trait DecodableObject<DCX> : Decodable<DCX> {
    fn decode_contents(context: &mut DecodingContext<DCX>) -> Self;
}

pub trait Decoder {
    fn set_position(&mut self, position: Address);
    fn position(&self) -> Address;
    fn read_u32(&mut self) -> u32;
    fn read_u64(&mut self) -> u64;
}

pub struct DecodingContext<'ctx, DCX> {
    decoder: &'ctx mut Decoder,
    object_table: Vec<Address>,
    pub extra: DCX,
}

impl<'ctx, DCX> DecodingContext<'ctx, DCX> {

    pub fn decoder(&mut self) -> &mut Decoder {
        self.decoder
    }

    pub fn decode_object<T:DecodableObject<DCX>>(&mut self) -> T {
        let object_table_index = self.decoder.read_u32();

        let address = self.object_table[object_table_index as usize];

        let current_position = self.decoder.position();
        self.decoder.set_position(address);

        let object = DecodableObject::decode_contents(self);

        self.decoder.set_position(current_position);

        object
    }
}

pub struct DecodingSession<'ctx, DCX> {
    context: DecodingContext<'ctx, DCX>
}

impl<'ctx, DCX> DecodingSession<'ctx, DCX> {

    pub fn decode<T: Decodable<DCX>>(&mut self) -> T {
        Decodable::decode(&mut self.context)
    }
}

//=-----------------------------------------------------------------------------
// TEST
//=-----------------------------------------------------------------------------

struct Ast {
    id: u64
}

impl<ECX> Encodable<ECX> for u64 {
    fn encode<'ecx, 'a: 'ecx>(&'a self, ecx: &mut EncodingContext<'ecx, ECX>) {
        ecx.encoder().emit_u64(*self)
    }
}

impl<DCX> Decodable<DCX> for u64 {
    fn decode(context: &mut DecodingContext<DCX>) -> u64 {
        context.decoder().read_u64()
    }
}

impl<ECX> Encodable<ECX> for Ast {
    fn encode<'ecx, 'a: 'ecx>(&'a self, ecx: &mut EncodingContext<'ecx, ECX>) {
        Encodable::encode(&self.id, ecx)
    }
}

impl<DCX> Decodable<DCX> for Ast {
    fn decode(context: &mut DecodingContext<DCX>) -> Ast {
        Ast { id: Decodable::decode(context) }
    }
}

impl<T: Encodable<ECX>, ECX> Encodable<ECX> for Option<T> {
    fn encode<'ecx, 'a: 'ecx>(&'a self, ecx: &mut EncodingContext<'ecx, ECX>) {
        match *self {
            None => {
                ecx.encoder().emit_u32(0)
            }
            Some(ref value) => {
                ecx.encoder.emit_u32(1);
                Encodable::encode(value, ecx)
            }
        }
    }
}

impl<T: Decodable<DCX>, DCX> Decodable<DCX> for Option<T> {
    fn decode(context: &mut DecodingContext<DCX>) -> Option<T> {
        let disr = context.decoder().read_u32();
        if disr == 0 {
            None
        }
        else {
            Some(Decodable::decode(context))
        }
    }
}

struct Ty<'tcx> {
    id: u64,
    ast: Ast,
    sub_ty: Option<&'tcx Ty<'tcx>>
}

trait TyRestoreContext<'tcx> {
    fn create_interned(&self, id: u64, ast: Ast, sub_ty: Option<&'tcx Ty<'tcx>>) -> &'tcx Ty<'tcx>;
}

impl<'tcx, DCX: TyRestoreContext<'tcx>> Decodable<DCX> for &'tcx Ty<'tcx> {
    fn decode(context: &mut DecodingContext<DCX>) -> &'tcx Ty<'tcx> {
        let id = Decodable::decode(context);
        let ast = Decodable::decode(context);
        let sub_ty = Decodable::decode(context);

        context.extra.create_interned(id, ast, sub_ty)
    }
}

impl<'tcx, DCX: TyRestoreContext<'tcx>> Decodable<DCX> for Ty<'tcx> {
    fn decode(context: &mut DecodingContext<DCX>) -> Ty<'tcx> {
        let id = Decodable::decode(context);
        let ast = Decodable::decode(context);
        let sub_ty = Decodable::decode(context);

        Ty {
            id: id,
            ast: ast,
            sub_ty: sub_ty
        }
    }
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![cfg_attr(test, plugin(stainless))]

pub mod vm;
pub mod value;
pub mod builder;

pub mod util;

pub use self::vm::{VM,ErrorKind};
pub use self::value::Value;

extern crate libc;
extern crate mri_sys as ffi;

<commit_msg>Don't use #[feature(plugin)] in test<commit_after>#![cfg_attr(test, feature(plugin))]
#![cfg_attr(test, plugin(stainless))]

pub mod vm;
pub mod value;
pub mod builder;

pub mod util;

pub use self::vm::{VM,ErrorKind};
pub use self::value::Value;

extern crate libc;
extern crate mri_sys as ffi;

<|endoftext|>


<commit_before>extern crate libc;
extern crate pocketsphinx_sys as bindings;

use std::ptr;
use std::ffi::{CStr, CString};
use std::mem;
use libc::c_char;

pub use search::*;
pub use nbest::*;
pub use jsgf::*;
pub use error::*;

mod search;
mod nbest;
mod jsgf;
mod error;

pub struct CmdLn {
    raw: *mut bindings::cmd_ln_t,
}

impl CmdLn {
    pub fn init(strict: bool, args: &[&str]) -> Result<Self> {
        // Sphinx assumes that `args` are valid as long as returned
        // `cmd_ln_t` is alive, so copy them.
        let c_args: Vec<_> = args.iter().map(|s| CString::new(*s).unwrap()).collect();
        let args_ptrs: Vec<_> = c_args.iter().map(|s| s.as_ptr()).collect();
        let raw = unsafe {
            bindings::cmd_ln_parse_r(ptr::null_mut(),
                                     bindings::ps_args(),
                                     args_ptrs.len() as i32,
                                     args_ptrs.as_ptr(),
                                     strict as i32)
        };
        if raw.is_null() {
            return Err(Error);
        }
        Ok(CmdLn{raw: raw})
    }

    pub unsafe fn get_str(&self, name: &str) -> &str {
        let c_str = bindings::cmd_ln_str_r(self.raw, CString::new(name).unwrap().as_ptr());
        CStr::from_ptr(c_str).to_str().unwrap()
    }

    pub unsafe fn get_int(&self, name: &str) -> i64 {
        bindings::cmd_ln_int_r(self.raw, CString::new(name).unwrap().as_ptr())
    }

    pub unsafe fn get_float(&self, name: &str) -> f64 {
        bindings::cmd_ln_float_r(self.raw, CString::new(name).unwrap().as_ptr())
    }

    pub fn exists(&self, name: &str) -> bool {
        let res = unsafe { bindings::cmd_ln_exists_r(self.raw, CString::new(name).unwrap().as_ptr()) };
        res != 0
    }

    pub unsafe fn get_boolean(&self, name: &str) -> bool {
        self.get_int(name) != 0
    }

    pub unsafe fn get_int32(&self, name: &str) -> i32 {
        self.get_int(name) as i32
    }

    pub unsafe fn get_float32(&self, name: &str) -> f32 {
        self.get_float(name) as f32
    }

    pub unsafe fn get_float64(&self, name: &str) -> f64 {
        self.get_float(name) as f64
    }

    fn into_raw(mut self) -> *mut bindings::cmd_ln_t {
        mem::replace(&mut self.raw, ptr::null_mut())
    }
}

impl Drop for CmdLn {
    fn drop(&mut self) {
        if !self.raw.is_null() {
            let ref_count = unsafe { bindings::cmd_ln_free_r(self.raw) };
            assert!(ref_count == 0);
        }
    }
}

pub struct PsDecoder {
    raw: *mut bindings::ps_decoder_t,
}

impl PsDecoder {
    pub fn init(config: CmdLn) -> Self {
        let raw = unsafe { bindings::ps_init(config.into_raw()) };
        assert!(!raw.is_null());
        PsDecoder{raw: raw}
    }

    pub fn start_utt(&self, utt_id: Option<&str>) -> Result<()>  {
        let (_id_cstr, id_ptr) = utt_id.map_or_else(
            ||  { (CString::new("").unwrap(), ptr::null()) },
            |s| {
                let cstr = CString::new(s).unwrap();
                let cptr = cstr.as_ptr();
                (cstr, cptr)
            }
        );
        let code = unsafe { bindings::ps_start_utt(self.raw, id_ptr) };
        if code == 0 { Ok(()) } else { Err(Error) }
    }

    pub fn process_raw(&self,
                       data: &[i16],
                       no_search: bool,
                       full_utt: bool) -> Result<i32> {
        let frames = unsafe {
            bindings::ps_process_raw(self.raw, data.as_ptr(), data.len(),
                                     no_search as i32, full_utt as i32)
        };
        if frames < 0 { return Err(Error); }
        Ok(frames)
    }

    pub fn end_utt(&self) -> Result<()> {
        let code = unsafe { bindings::ps_end_utt(self.raw) };
        if code < 0 { return Err(Error); }
        Ok(())
    }

    pub fn get_hyp(&self) -> Option<(String, Option<String>, i32)> {
        let mut score: i32 = 0;
        let mut c_utt_id: *const c_char = ptr::null();
        let c_hyp = unsafe { bindings::ps_get_hyp(self.raw, &mut score, &mut c_utt_id) };
        if c_hyp.is_null() { return None; }

        let hyp = unsafe { CStr::from_ptr(c_hyp) }.to_string_lossy().into_owned();
        let utt_id = if c_utt_id.is_null() {
            None
        } else {
            Some(unsafe { CStr::from_ptr(c_utt_id) }.to_string_lossy().into_owned())
        };
        Some((hyp, utt_id, score))
    }

    pub fn get_in_speech(&self) -> bool {
        let res = unsafe { bindings::ps_get_in_speech(self.raw) };
        res == 1
    }

    pub fn get_prob(&self) -> i32 {
        unsafe { bindings::ps_get_prob(self.raw) }
    }

    pub fn get_n_frames(&self) -> i32 {
        unsafe { bindings::ps_get_n_frames(self.raw) }
    }

    pub fn nbest(&self, start_frame: i32, end_frame: i32,
                 ctx1: Option<&str>, ctx2: Option<&str>) -> NBestIter {
        let c_ctx1 = ctx1.map(|s| CString::new(s).unwrap());
        let c_ctx2 = ctx2.map(|s| CString::new(s).unwrap());
        let raw_nbest = unsafe {
            bindings::ps_nbest(self.raw, start_frame, end_frame,
                               c_ctx1.map_or(ptr::null(), |c| c.as_ptr()),
                               c_ctx2.map_or(ptr::null(), |c| c.as_ptr()))
        };
        NBestIter::new(raw_nbest)
    }

    pub fn nbest_simple(&self) -> NBestIter {
        self.nbest(0, -1, None, None)
    }

    pub fn seg_iter(&self) -> SegIter {
        let mut best_score: i32 = 0;
        SegIter::new(unsafe { bindings::ps_seg_iter(self.raw, &mut best_score) })
    }

    pub fn searches(&self) -> Searches {
        Searches::new(self.raw)
    }
}

impl Drop for PsDecoder {
    fn drop(&mut self) {
        let ref_count = unsafe { bindings::ps_free(self.raw) };
        assert!(ref_count == 0);
    }
}
<commit_msg>Fix memory leak of PsDecoder taking a CmdLn config without dropping it<commit_after>extern crate libc;
extern crate pocketsphinx_sys as bindings;

use std::ptr;
use std::ffi::{CStr, CString};
use libc::c_char;

pub use search::*;
pub use nbest::*;
pub use jsgf::*;
pub use error::*;

mod search;
mod nbest;
mod jsgf;
mod error;

pub struct CmdLn {
    raw: *mut bindings::cmd_ln_t,
}

impl CmdLn {
    pub fn init(strict: bool, args: &[&str]) -> Result<Self> {
        // Sphinx assumes that `args` are valid as long as returned
        // `cmd_ln_t` is alive, so copy them.
        let c_args: Vec<_> = args.iter().map(|s| CString::new(*s).unwrap()).collect();
        let args_ptrs: Vec<_> = c_args.iter().map(|s| s.as_ptr()).collect();
        let raw = unsafe {
            bindings::cmd_ln_parse_r(ptr::null_mut(),
                                     bindings::ps_args(),
                                     args_ptrs.len() as i32,
                                     args_ptrs.as_ptr(),
                                     strict as i32)
        };
        if raw.is_null() {
            return Err(Error);
        }
        Ok(CmdLn{raw: raw})
    }

    pub unsafe fn get_str(&self, name: &str) -> &str {
        let c_str = bindings::cmd_ln_str_r(self.raw, CString::new(name).unwrap().as_ptr());
        CStr::from_ptr(c_str).to_str().unwrap()
    }

    pub unsafe fn get_int(&self, name: &str) -> i64 {
        bindings::cmd_ln_int_r(self.raw, CString::new(name).unwrap().as_ptr())
    }

    pub unsafe fn get_float(&self, name: &str) -> f64 {
        bindings::cmd_ln_float_r(self.raw, CString::new(name).unwrap().as_ptr())
    }

    pub fn exists(&self, name: &str) -> bool {
        let res = unsafe { bindings::cmd_ln_exists_r(self.raw, CString::new(name).unwrap().as_ptr()) };
        res != 0
    }

    pub unsafe fn get_boolean(&self, name: &str) -> bool {
        self.get_int(name) != 0
    }

    pub unsafe fn get_int32(&self, name: &str) -> i32 {
        self.get_int(name) as i32
    }

    pub unsafe fn get_float32(&self, name: &str) -> f32 {
        self.get_float(name) as f32
    }

    pub unsafe fn get_float64(&self, name: &str) -> f64 {
        self.get_float(name) as f64
    }
}

impl Drop for CmdLn {
    fn drop(&mut self) {
        if !self.raw.is_null() {
            let ref_count = unsafe { bindings::cmd_ln_free_r(self.raw) };
            assert!(ref_count == 0);
        }
    }
}

pub struct PsDecoder {
    raw: *mut bindings::ps_decoder_t,
    #[allow(dead_code)]
    config: CmdLn,
}

impl PsDecoder {
    pub fn init(config: CmdLn) -> Self {
        let raw = unsafe { bindings::ps_init(config.raw) };
        assert!(!raw.is_null());
        PsDecoder{raw: raw, config: config}
    }

    pub fn start_utt(&self, utt_id: Option<&str>) -> Result<()>  {
        let (_id_cstr, id_ptr) = utt_id.map_or_else(
            ||  { (CString::new("").unwrap(), ptr::null()) },
            |s| {
                let cstr = CString::new(s).unwrap();
                let cptr = cstr.as_ptr();
                (cstr, cptr)
            }
        );
        let code = unsafe { bindings::ps_start_utt(self.raw, id_ptr) };
        if code == 0 { Ok(()) } else { Err(Error) }
    }

    pub fn process_raw(&self,
                       data: &[i16],
                       no_search: bool,
                       full_utt: bool) -> Result<i32> {
        let frames = unsafe {
            bindings::ps_process_raw(self.raw, data.as_ptr(), data.len(),
                                     no_search as i32, full_utt as i32)
        };
        if frames < 0 { return Err(Error); }
        Ok(frames)
    }

    pub fn end_utt(&self) -> Result<()> {
        let code = unsafe { bindings::ps_end_utt(self.raw) };
        if code < 0 { return Err(Error); }
        Ok(())
    }

    pub fn get_hyp(&self) -> Option<(String, Option<String>, i32)> {
        let mut score: i32 = 0;
        let mut c_utt_id: *const c_char = ptr::null();
        let c_hyp = unsafe { bindings::ps_get_hyp(self.raw, &mut score, &mut c_utt_id) };
        if c_hyp.is_null() { return None; }

        let hyp = unsafe { CStr::from_ptr(c_hyp) }.to_string_lossy().into_owned();
        let utt_id = if c_utt_id.is_null() {
            None
        } else {
            Some(unsafe { CStr::from_ptr(c_utt_id) }.to_string_lossy().into_owned())
        };
        Some((hyp, utt_id, score))
    }

    pub fn get_in_speech(&self) -> bool {
        let res = unsafe { bindings::ps_get_in_speech(self.raw) };
        res == 1
    }

    pub fn get_prob(&self) -> i32 {
        unsafe { bindings::ps_get_prob(self.raw) }
    }

    pub fn get_n_frames(&self) -> i32 {
        unsafe { bindings::ps_get_n_frames(self.raw) }
    }

    pub fn nbest(&self, start_frame: i32, end_frame: i32,
                 ctx1: Option<&str>, ctx2: Option<&str>) -> NBestIter {
        let c_ctx1 = ctx1.map(|s| CString::new(s).unwrap());
        let c_ctx2 = ctx2.map(|s| CString::new(s).unwrap());
        let raw_nbest = unsafe {
            bindings::ps_nbest(self.raw, start_frame, end_frame,
                               c_ctx1.map_or(ptr::null(), |c| c.as_ptr()),
                               c_ctx2.map_or(ptr::null(), |c| c.as_ptr()))
        };
        NBestIter::new(raw_nbest)
    }

    pub fn nbest_simple(&self) -> NBestIter {
        self.nbest(0, -1, None, None)
    }

    pub fn seg_iter(&self) -> SegIter {
        let mut best_score: i32 = 0;
        SegIter::new(unsafe { bindings::ps_seg_iter(self.raw, &mut best_score) })
    }

    pub fn searches(&self) -> Searches {
        Searches::new(self.raw)
    }
}

impl Drop for PsDecoder {
    fn drop(&mut self) {
        let ref_count = unsafe { bindings::ps_free(self.raw) };
        assert!(ref_count == 0);
    }
}
<|endoftext|>


<commit_before>//! A simple library for parsing an XML file into an in-memory tree structure
//!
//! Not recommended for large XML files, as it will load the entire file into memory.
//!
//! # Example
//!
//! ```no_run
//! use xmltree::Element;
//! use std::fs::File;
//!
//! let data: &'static str = r##"
//! <?xml version="1.0" encoding="utf-8" standalone="yes"?>
//! <names>
//!     <name first="bob" last="jones" />
//!     <name first="elizabeth" last="smith" />
//! </names>
//! "##;
//!
//! let mut names_element = Element::parse(data.as_bytes()).unwrap();
//!
//! println!("{:#?}", names_element);
//! {
//!     // get first `name` element
//!     let name = names_element.get_mut_child("name").expect("Can't find name element");
//!     name.attributes.insert("suffix".to_owned(), "mr".to_owned());
//! }
//! names_element.write(File::create("result.xml").unwrap());
//!
//!
//! ```
extern crate xml;

use std::collections::HashMap;
use std::io::{Read, Write};
use std::borrow::Cow;
use std::fmt;

use xml::reader::{EventReader, XmlEvent};

/// Represents an XML element.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Element {
    /// The name of the Element.  Does not include any namespace info
    pub name: String,

    /// The Element attributes
    pub attributes: HashMap<String, String>,

    /// Children
    pub children: Vec<Element>,

    /// The text data for this element
    pub text: Option<String>
}

/// Errors that can occur parsing XML
#[derive(Debug)]
pub enum ParseError {
    /// The XML is invalid
    MalformedXml(xml::reader::Error),
    /// This library is unable to process this XML. This can occur if, for
    /// example, the XML contains processing instructions.
    CannotParse,
}

impl fmt::Display for ParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &ParseError::MalformedXml(ref e) => write!(f, "Malformed XML. {}", e),
            &ParseError::CannotParse => write!(f, "Cannot parse"),
        }
    }
}

impl std::error::Error for ParseError {
    fn description(&self) -> &str {
        match self {
            &ParseError::MalformedXml(..) => "Malformed XML",
            &ParseError::CannotParse      => "Cannot parse",
        }
    }

    fn cause(&self) -> Option<&std::error::Error> {
        match self {
            &ParseError::MalformedXml(ref e) => Some(e),
            &ParseError::CannotParse => None,
        }
    }
}

fn build<B: Read>(reader: &mut EventReader<B>, mut elem: Element) -> Result<Element, ParseError> {
    loop {
        match reader.next() {
            Ok(XmlEvent::EndElement{ref name}) => {
                if name.local_name == elem.name {
                    return Ok(elem);
                }
                else {
                    return Err(ParseError::CannotParse);
                }
            },
            Ok(XmlEvent::StartElement{name, attributes, ..}) => {
                let mut attr_map = HashMap::new();
                for attr in attributes { attr_map.insert(attr.name.local_name, attr.value); }
                let new_elem = Element{name: name.local_name, attributes: attr_map, children: Vec::new(), text: None};
                elem.children.push(try!(build(reader, new_elem)));
            }
            Ok(XmlEvent::Characters(s)) => { elem.text = Some(s); }
            Ok(XmlEvent::Whitespace(..)) => (),
            Ok(XmlEvent::CData(s)) => { elem.text = Some(s) }
            Ok(XmlEvent::Comment(..)) => (),
            Ok(XmlEvent::StartDocument { .. }) |
            Ok(XmlEvent::EndDocument) |
            Ok(XmlEvent::ProcessingInstruction { .. }) => return Err(ParseError::CannotParse),
            Err(e) => return Err(ParseError::MalformedXml(e)),
        }
    }

}

impl Element {
    /// Parses some data into an Element
    pub fn parse<R: Read>(r: R) -> Result<Element, ParseError> {
        let mut reader = EventReader::new(r);
        loop {
            match reader.next() {
                Ok(XmlEvent::StartElement{name, attributes, ..}) => {
                    let mut attr_map = HashMap::new();
                    for attr in attributes { attr_map.insert(attr.name.local_name, attr.value); }

                    let root = Element{name: name.local_name, attributes: attr_map, children: Vec::new(), text: None};
                    return build(&mut reader, root);
                }
                Ok(XmlEvent::Comment(..)) |
                Ok(XmlEvent::Whitespace(..)) |
                Ok(XmlEvent::StartDocument { .. }) => continue,
                Ok(XmlEvent::EndDocument) |
                Ok(XmlEvent::EndElement { .. }) |
                Ok(XmlEvent::Characters(..)) |
                Ok(XmlEvent::CData(..)) |
                Ok(XmlEvent::ProcessingInstruction { .. }) => return Err(ParseError::CannotParse),
                Err(e) => return Err(ParseError::MalformedXml(e)),
            }
        }
    }

    fn _write<B: Write>(&self, emitter: &mut xml::writer::EventWriter<B>) {
        use xml::writer::events::XmlEvent;
        use xml::name::Name;
        use xml::namespace::Namespace;
        use xml::attribute::Attribute;

        let name = Name::local(&self.name);
        let mut attributes = Vec::with_capacity(self.attributes.len());
        for (k, v) in self.attributes.iter() {
            attributes.push(Attribute{name: Name::local(k), value: v});
        }

        let namespace = Namespace::empty();

        emitter.write(XmlEvent::StartElement{name: name, attributes: Cow::Owned(attributes), namespace: Cow::Borrowed(&namespace)}).unwrap();
        if let Some(ref t) = self.text {
            emitter.write(XmlEvent::Characters(t)).unwrap();
        }
        for elem in &self.children {
            elem._write(emitter);
        }
        emitter.write(XmlEvent::EndElement{name: Some(name)}).unwrap();

    }

    /// Writes out this element as the root element in an new XML document
    pub fn write<W: Write>(&self, w:W) {
        use xml::writer::EventWriter;
        use xml::writer::events::XmlEvent;
        use xml::common::XmlVersion;

        let mut emitter = EventWriter::new(w);
        emitter.write(XmlEvent::StartDocument{version: XmlVersion::Version10, encoding: None, standalone: None}).unwrap();
        self._write(&mut emitter);
    }

    /// Find a child element with the given name and return a reference to it.
    pub fn get_child<K>(&self, k: K) -> Option<&Element>
      where String: PartialEq<K> {
          self.children.iter().find(|e| e.name == k)
    }

    /// Find a child element with the given name and return a mutable reference to it.
    pub fn get_mut_child<'a, K>(&'a mut self, k: K) -> Option<&'a mut Element>
      where String: PartialEq<K> {
          self.children.iter_mut().find(|e| e.name == k)
    }

    /// Find a child element with the given name, remove and return it.
    pub fn take_child<'a, K>(&'a mut self, k: K) -> Option<Element>
      where String: PartialEq<K> {
          self.children.iter().position(|e| e.name == k).map(|i| self.children.remove(i))
    }
}

<commit_msg>Add support for namespaces and prefixes in Element<commit_after>//! A simple library for parsing an XML file into an in-memory tree structure
//!
//! Not recommended for large XML files, as it will load the entire file into memory.
//!
//! # Example
//!
//! ```no_run
//! use xmltree::Element;
//! use std::fs::File;
//!
//! let data: &'static str = r##"
//! <?xml version="1.0" encoding="utf-8" standalone="yes"?>
//! <names>
//!     <name first="bob" last="jones" />
//!     <name first="elizabeth" last="smith" />
//! </names>
//! "##;
//!
//! let mut names_element = Element::parse(data.as_bytes()).unwrap();
//!
//! println!("{:#?}", names_element);
//! {
//!     // get first `name` element
//!     let name = names_element.get_mut_child("name").expect("Can't find name element");
//!     name.attributes.insert("suffix".to_owned(), "mr".to_owned());
//! }
//! names_element.write(File::create("result.xml").unwrap());
//!
//!
//! ```
extern crate xml;

use std::collections::HashMap;
use std::io::{Read, Write};
use std::borrow::Cow;
use std::fmt;

use xml::reader::{EventReader, XmlEvent};

/// Represents an XML element.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Element {
    pub prefix: Option<String>,

    pub namespace: Option<String>,

    /// The name of the Element.  Does not include any namespace info
    pub name: String,

    /// The Element attributes
    pub attributes: HashMap<String, String>,

    /// Children
    pub children: Vec<Element>,

    /// The text data for this element
    pub text: Option<String>
}

/// Errors that can occur parsing XML
#[derive(Debug)]
pub enum ParseError {
    /// The XML is invalid
    MalformedXml(xml::reader::Error),
    /// This library is unable to process this XML. This can occur if, for
    /// example, the XML contains processing instructions.
    CannotParse,
}

impl fmt::Display for ParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &ParseError::MalformedXml(ref e) => write!(f, "Malformed XML. {}", e),
            &ParseError::CannotParse => write!(f, "Cannot parse"),
        }
    }
}

impl std::error::Error for ParseError {
    fn description(&self) -> &str {
        match self {
            &ParseError::MalformedXml(..) => "Malformed XML",
            &ParseError::CannotParse      => "Cannot parse",
        }
    }

    fn cause(&self) -> Option<&std::error::Error> {
        match self {
            &ParseError::MalformedXml(ref e) => Some(e),
            &ParseError::CannotParse => None,
        }
    }
}

fn build<B: Read>(reader: &mut EventReader<B>, mut elem: Element) -> Result<Element, ParseError> {
    loop {
        match reader.next() {
            Ok(XmlEvent::EndElement{ref name}) => {
                if name.local_name == elem.name {
                    return Ok(elem);
                }
                else {
                    return Err(ParseError::CannotParse);
                }
            },
            Ok(XmlEvent::StartElement{name, attributes, ..}) => {
                let mut attr_map = HashMap::new();
                for attr in attributes { attr_map.insert(attr.name.local_name, attr.value); }

                let new_elem = Element {
                    prefix: name.prefix,
                    namespace: name.namespace,
                    name: name.local_name,
                    attributes: attr_map,
                    children: Vec::new(),
                    text: None
                };
                elem.children.push(try!(build(reader, new_elem)));
            }
            Ok(XmlEvent::Characters(s)) => { elem.text = Some(s); }
            Ok(XmlEvent::Whitespace(..)) => (),
            Ok(XmlEvent::CData(s)) => { elem.text = Some(s) }
            Ok(XmlEvent::Comment(..)) => (),
            Ok(XmlEvent::StartDocument { .. }) |
            Ok(XmlEvent::EndDocument) |
            Ok(XmlEvent::ProcessingInstruction { .. }) => return Err(ParseError::CannotParse),
            Err(e) => return Err(ParseError::MalformedXml(e)),
        }
    }

}

impl Element {
    /// Parses some data into an Element
    pub fn parse<R: Read>(r: R) -> Result<Element, ParseError> {
        let mut reader = EventReader::new(r);
        loop {
            match reader.next() {
                Ok(XmlEvent::StartElement { name, attributes, .. }) => {
                    let mut attr_map = HashMap::new();
                    for attr in attributes { attr_map.insert(attr.name.local_name, attr.value); }

                    let root = Element {
                        prefix: name.prefix,
                        namespace: name.namespace,
                        name: name.local_name,
                        attributes: attr_map,
                        children: Vec::new(),
                        text: None
                    };
                    return build(&mut reader, root);
                }
                Ok(XmlEvent::Comment(..)) |
                Ok(XmlEvent::Whitespace(..)) |
                Ok(XmlEvent::StartDocument { .. }) => continue,
                Ok(XmlEvent::EndDocument) |
                Ok(XmlEvent::EndElement { .. }) |
                Ok(XmlEvent::Characters(..)) |
                Ok(XmlEvent::CData(..)) |
                Ok(XmlEvent::ProcessingInstruction { .. }) => return Err(ParseError::CannotParse),
                Err(e) => return Err(ParseError::MalformedXml(e)),
            }
        }
    }

    fn _write<B: Write>(&self, emitter: &mut xml::writer::EventWriter<B>) {
        use xml::writer::events::XmlEvent;
        use xml::name::Name;
        use xml::namespace::Namespace;
        use xml::attribute::Attribute;

        let name = Name::local(&self.name);
        let mut attributes = Vec::with_capacity(self.attributes.len());
        for (k, v) in self.attributes.iter() {
            attributes.push(Attribute{name: Name::local(k), value: v});
        }

        let namespace = Namespace::empty();

        emitter.write(XmlEvent::StartElement{name: name, attributes: Cow::Owned(attributes), namespace: Cow::Borrowed(&namespace)}).unwrap();
        if let Some(ref t) = self.text {
            emitter.write(XmlEvent::Characters(t)).unwrap();
        }
        for elem in &self.children {
            elem._write(emitter);
        }
        emitter.write(XmlEvent::EndElement{name: Some(name)}).unwrap();
    }

    /// Writes out this element as the root element in an new XML document
    pub fn write<W: Write>(&self, w: W) {
        use xml::writer::EventWriter;
        use xml::writer::events::XmlEvent;
        use xml::common::XmlVersion;

        let mut emitter = EventWriter::new(w);
        emitter.write(XmlEvent::StartDocument{version: XmlVersion::Version10, encoding: None, standalone: None}).unwrap();
        self._write(&mut emitter);
    }

    /// Find a child element with the given name and return a reference to it.
    pub fn get_child<K>(&self, k: K) -> Option<&Element>
      where String: PartialEq<K> {
          self.children.iter().find(|e| e.name == k)
    }

    /// Find a child element with the given name and return a mutable reference to it.
    pub fn get_mut_child<'a, K>(&'a mut self, k: K) -> Option<&'a mut Element>
      where String: PartialEq<K> {
          self.children.iter_mut().find(|e| e.name == k)
    }

    /// Find a child element with the given name, remove and return it.
    pub fn take_child<'a, K>(&'a mut self, k: K) -> Option<Element>
      where String: PartialEq<K> {
          self.children.iter().position(|e| e.name == k).map(|i| self.children.remove(i))
    }
}

<|endoftext|>


<commit_before>// Copyright 2014-2015 The GeoRust Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// TODO
// generic number instead of f64 for position?

extern crate "rustc-serialize" as rustc_serialize;

pub use types::pos::Pos;

pub use types::ring::Ring;

pub use types::point::Point;
pub use types::multipoint::MultiPoint;

pub use types::linestring::LineString;
pub use types::multilinestring::MultiLineString;

pub use types::poly::Poly;
pub use types::polygon::Polygon;
pub use types::multipolygon::MultiPolygon;

pub use types::geometry::Geometry;
pub use types::geometrycollection::GeometryCollection;

pub use types::feature::Feature;
pub use types::featurecollection::FeatureCollection;
pub use types::featurecollection::from_str;

mod types;
<commit_msg>Removes unnecessary todo<commit_after>// Copyright 2014-2015 The GeoRust Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate "rustc-serialize" as rustc_serialize;

pub use types::pos::Pos;

pub use types::ring::Ring;

pub use types::point::Point;
pub use types::multipoint::MultiPoint;

pub use types::linestring::LineString;
pub use types::multilinestring::MultiLineString;

pub use types::poly::Poly;
pub use types::polygon::Polygon;
pub use types::multipolygon::MultiPolygon;

pub use types::geometry::Geometry;
pub use types::geometrycollection::GeometryCollection;

pub use types::feature::Feature;
pub use types::featurecollection::FeatureCollection;
pub use types::featurecollection::from_str;

mod types;
<|endoftext|>


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

//! A set of middleware for sharing data between requests in the Iron
//! framework.

extern crate iron;
extern crate plugin;

use iron::{Request, Response, BeforeMiddleware, AfterMiddleware, IronResult};
use iron::typemap::Key;
use std::sync::{Arc, RwLock, Mutex};
use std::{error,fmt};
use plugin::Plugin;

/// The type that can be returned by `eval` to indicate error.
#[derive(Clone, Debug)]
pub enum PersistentError {
    /// The value was not found.
    NotFound
}

impl fmt::Display for PersistentError {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.description().fmt(f)
    }
}

impl error::Error for PersistentError {
    fn description(&self) -> &str {
        match *self {
            PersistentError::NotFound => "Value not found in extensions."
        }
    }
}

/// Middleware for data that persists between requests with read and write capabilities.
///
/// The data is stored behind a `RwLock`, so multiple read locks
/// can be taken out concurrently.
///
/// If most threads need to take out a write lock, you may want to
/// consider `Write`, which stores the data behind a `Mutex`, which
/// has a faster locking speed.
///
/// `State` can be linked as `BeforeMiddleware` to add data to the `Request`
/// extensions and it can be linked as an `AfterMiddleware` to add data to
/// the `Response` extensions.
///
/// `State` also implements `Plugin`, so the data stored within can be
/// accessed through `request.get::<State<P>>()` as an `Arc<RwLock<P::Value>>`.
pub struct State<P: Key> {
    data: Arc<RwLock<P::Value>>
}

/// Middleware for data that persists between Requests with read-only capabilities.
///
/// The data is stored behind an Arc, so multiple threads can have
/// concurrent, non-blocking access.
///
/// `Read` can be linked as `BeforeMiddleware` to add data to the `Request`
/// extensions and it can be linked as an `AfterMiddleware` to add data to
/// the `Response` extensions.
///
/// `Read` also implements `Plugin`, so the data stored within can be
/// accessed through `request.get::<Read<P>>()` as an `Arc<P::Value>`.
pub struct Read<P: Key> {
    data: Arc<P::Value>
}

/// Middleware for data that persists between Requests for data which mostly
/// needs to be written instead of read.
///
/// The data is stored behind a `Mutex`, so only one request at a time can
/// access the data. This is more performant than `State` in the case where
/// most uses of the data require a write lock.
///
/// `Write` can be linked as `BeforeMiddleware` to add data to the `Request`
/// extensions and it can be linked as an `AfterMiddleware` to add data to
/// the `Response` extensions.
///
/// `Write` also implements `Plugin`, so the data stored within can be
/// accessed through `request.get::<Write<P>>()` as an `Arc<Mutex<P::Value>>`.
pub struct Write<P: Key> {
    data: Arc<Mutex<P::Value>>
}

macro_rules! impl_persistent {
    ($name:ty, $out:ty, $param:ident) => {
    }
}

impl<P: Key> Clone for Read<P> where P::Value: Send + Sync {
    fn clone(&self) -> Read<P> {
        Read { data: self.data.clone() }
    }
}

impl<P: Key> Clone for State<P> where P::Value: Send + Sync {
    fn clone(&self) -> State<P> {
        State { data: self.data.clone() }
    }
}

impl<P: Key> Clone for Write<P> where P::Value: Send {
    fn clone(&self) -> Write<P> {
        Write { data: self.data.clone() }
    }
}

impl<P: Key> Key for State<P> where P::Value: 'static {
    type Value = Arc<RwLock<P::Value>>;
}

impl<P: Key> Key for Read<P> where P::Value: 'static {
    type Value = Arc<P::Value>;
}

impl<P: Key> Key for Write<P> where P::Value: 'static {
    type Value = Arc<Mutex<P::Value>>;
}

impl<'a, 'b, P: Key> Plugin<Request<'a, 'b>> for State<P> where P::Value: Send + Sync {
    type Error = PersistentError;
    fn eval(req: &mut Request<'a, 'b>) -> Result<Arc<RwLock<P::Value>>, PersistentError> {
        req.extensions.get::<State<P>>().cloned().ok_or(PersistentError::NotFound)
    }
}

impl<'a, 'b, P: Key> Plugin<Request<'a, 'b>> for Read<P> where P::Value: Send + Sync {
    type Error = PersistentError;
    fn eval(req: &mut Request<'a, 'b>) -> Result<Arc<P::Value>, PersistentError> {
        req.extensions.get::<Read<P>>().cloned().ok_or(PersistentError::NotFound)
    }
}

impl<'a, 'b, P: Key> Plugin<Request<'a, 'b>> for Write<P> where P::Value: Send {
    type Error = PersistentError;
    fn eval(req: &mut Request<'a, 'b>) -> Result<Arc<Mutex<P::Value>>, PersistentError> {
        req.extensions.get::<Write<P>>().cloned().ok_or(PersistentError::NotFound)
    }
}

impl<P: Key> BeforeMiddleware for State<P> where P::Value: Send + Sync {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions.insert::<State<P>>(self.data.clone());
        Ok(())
    }
}

impl<P: Key> BeforeMiddleware for Read<P> where P::Value: Send + Sync {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions.insert::<Read<P>>(self.data.clone());
        Ok(())
    }
}

impl<P: Key> BeforeMiddleware for Write<P> where P::Value: Send {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions.insert::<Write<P>>(self.data.clone());
        Ok(())
    }
}

impl<P: Key> AfterMiddleware for State<P> where P::Value: Send + Sync {
    fn after(&self, _: &mut Request, mut res: Response) -> IronResult<Response> {
        res.extensions.insert::<State<P>>(self.data.clone());
        Ok(res)
    }
}

impl<P: Key> AfterMiddleware for Read<P> where P::Value: Send + Sync {
    fn after(&self, _: &mut Request, mut res: Response) -> IronResult<Response> {
        res.extensions.insert::<Read<P>>(self.data.clone());
        Ok(res)
    }
}

impl<P: Key> AfterMiddleware for Write<P> where P::Value: Send {
    fn after(&self, _: &mut Request, mut res: Response) -> IronResult<Response> {
        res.extensions.insert::<Write<P>>(self.data.clone());
        Ok(res)
    }
}

impl<P: Key> State<P> where P::Value: Send + Sync {
    /// Construct a new pair of `State` that can be passed directly to `Chain::link`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn both(start: P::Value) -> (State<P>, State<P>) {
        let x = State { data: Arc::new(RwLock::new(start)) };
        (x.clone(), x)
    }

    /// Construct a new `State` that can be passed directly to
    /// `Chain::link_before` or `Chain::link_after`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn one(start: P::Value) -> State<P> {
        State { data: Arc::new(RwLock::new(start)) }
    }
}

impl<P: Key> Read<P> where P::Value: Send + Sync {
    /// Construct a new pair of `Read` that can be passed directly to `Chain::link`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn both(start: P::Value) -> (Read<P>, Read<P>) {
        let x = Read { data: Arc::new(start) };
        (x.clone(), x)
    }

    /// Construct a new `Read` that can be passed directly to
    /// `Chain::link_before` or `Chain::link_after`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn one(start: P::Value) -> Read<P> {
        Read { data: Arc::new(start) }
    }
}

impl<P: Key> Write<P> where P::Value: Send {
    /// Construct a new pair of `Write` that can be passed directly to `Chain::link`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn both(start: P::Value) -> (Write<P>, Write<P>) {
        let x = Write { data: Arc::new(Mutex::new(start)) };
        (x.clone(), x)
    }

    /// Construct a new `Write` that can be passed directly to
    /// `Chain::link_before` or `Chain::link_after`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn one(start: P::Value) -> Write<P> {
        Write { data: Arc::new(Mutex::new(start)) }
    }
}
<commit_msg>Fix infinite recursion error<commit_after>#![cfg_attr(test, deny(warnings))]
#![deny(missing_docs)]

//! A set of middleware for sharing data between requests in the Iron
//! framework.

extern crate iron;
extern crate plugin;

use iron::{Request, Response, BeforeMiddleware, AfterMiddleware, IronResult};
use iron::typemap::Key;
use std::sync::{Arc, RwLock, Mutex};
use std::fmt;
use std::error::Error;
use plugin::Plugin;

/// The type that can be returned by `eval` to indicate error.
#[derive(Clone, Debug)]
pub enum PersistentError {
    /// The value was not found.
    NotFound
}

impl Error for PersistentError {
    fn description(&self) -> &str {
        match *self {
            PersistentError::NotFound => "Value not found in extensions."
        }
    }
}

impl fmt::Display for PersistentError {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.description().fmt(f)
    }
}

/// Middleware for data that persists between requests with read and write capabilities.
///
/// The data is stored behind a `RwLock`, so multiple read locks
/// can be taken out concurrently.
///
/// If most threads need to take out a write lock, you may want to
/// consider `Write`, which stores the data behind a `Mutex`, which
/// has a faster locking speed.
///
/// `State` can be linked as `BeforeMiddleware` to add data to the `Request`
/// extensions and it can be linked as an `AfterMiddleware` to add data to
/// the `Response` extensions.
///
/// `State` also implements `Plugin`, so the data stored within can be
/// accessed through `request.get::<State<P>>()` as an `Arc<RwLock<P::Value>>`.
pub struct State<P: Key> {
    data: Arc<RwLock<P::Value>>
}

/// Middleware for data that persists between Requests with read-only capabilities.
///
/// The data is stored behind an Arc, so multiple threads can have
/// concurrent, non-blocking access.
///
/// `Read` can be linked as `BeforeMiddleware` to add data to the `Request`
/// extensions and it can be linked as an `AfterMiddleware` to add data to
/// the `Response` extensions.
///
/// `Read` also implements `Plugin`, so the data stored within can be
/// accessed through `request.get::<Read<P>>()` as an `Arc<P::Value>`.
pub struct Read<P: Key> {
    data: Arc<P::Value>
}

/// Middleware for data that persists between Requests for data which mostly
/// needs to be written instead of read.
///
/// The data is stored behind a `Mutex`, so only one request at a time can
/// access the data. This is more performant than `State` in the case where
/// most uses of the data require a write lock.
///
/// `Write` can be linked as `BeforeMiddleware` to add data to the `Request`
/// extensions and it can be linked as an `AfterMiddleware` to add data to
/// the `Response` extensions.
///
/// `Write` also implements `Plugin`, so the data stored within can be
/// accessed through `request.get::<Write<P>>()` as an `Arc<Mutex<P::Value>>`.
pub struct Write<P: Key> {
    data: Arc<Mutex<P::Value>>
}

macro_rules! impl_persistent {
    ($name:ty, $out:ty, $param:ident) => {
    }
}

impl<P: Key> Clone for Read<P> where P::Value: Send + Sync {
    fn clone(&self) -> Read<P> {
        Read { data: self.data.clone() }
    }
}

impl<P: Key> Clone for State<P> where P::Value: Send + Sync {
    fn clone(&self) -> State<P> {
        State { data: self.data.clone() }
    }
}

impl<P: Key> Clone for Write<P> where P::Value: Send {
    fn clone(&self) -> Write<P> {
        Write { data: self.data.clone() }
    }
}

impl<P: Key> Key for State<P> where P::Value: 'static {
    type Value = Arc<RwLock<P::Value>>;
}

impl<P: Key> Key for Read<P> where P::Value: 'static {
    type Value = Arc<P::Value>;
}

impl<P: Key> Key for Write<P> where P::Value: 'static {
    type Value = Arc<Mutex<P::Value>>;
}

impl<'a, 'b, P: Key> Plugin<Request<'a, 'b>> for State<P> where P::Value: Send + Sync {
    type Error = PersistentError;
    fn eval(req: &mut Request<'a, 'b>) -> Result<Arc<RwLock<P::Value>>, PersistentError> {
        req.extensions.get::<State<P>>().cloned().ok_or(PersistentError::NotFound)
    }
}

impl<'a, 'b, P: Key> Plugin<Request<'a, 'b>> for Read<P> where P::Value: Send + Sync {
    type Error = PersistentError;
    fn eval(req: &mut Request<'a, 'b>) -> Result<Arc<P::Value>, PersistentError> {
        req.extensions.get::<Read<P>>().cloned().ok_or(PersistentError::NotFound)
    }
}

impl<'a, 'b, P: Key> Plugin<Request<'a, 'b>> for Write<P> where P::Value: Send {
    type Error = PersistentError;
    fn eval(req: &mut Request<'a, 'b>) -> Result<Arc<Mutex<P::Value>>, PersistentError> {
        req.extensions.get::<Write<P>>().cloned().ok_or(PersistentError::NotFound)
    }
}

impl<P: Key> BeforeMiddleware for State<P> where P::Value: Send + Sync {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions.insert::<State<P>>(self.data.clone());
        Ok(())
    }
}

impl<P: Key> BeforeMiddleware for Read<P> where P::Value: Send + Sync {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions.insert::<Read<P>>(self.data.clone());
        Ok(())
    }
}

impl<P: Key> BeforeMiddleware for Write<P> where P::Value: Send {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions.insert::<Write<P>>(self.data.clone());
        Ok(())
    }
}

impl<P: Key> AfterMiddleware for State<P> where P::Value: Send + Sync {
    fn after(&self, _: &mut Request, mut res: Response) -> IronResult<Response> {
        res.extensions.insert::<State<P>>(self.data.clone());
        Ok(res)
    }
}

impl<P: Key> AfterMiddleware for Read<P> where P::Value: Send + Sync {
    fn after(&self, _: &mut Request, mut res: Response) -> IronResult<Response> {
        res.extensions.insert::<Read<P>>(self.data.clone());
        Ok(res)
    }
}

impl<P: Key> AfterMiddleware for Write<P> where P::Value: Send {
    fn after(&self, _: &mut Request, mut res: Response) -> IronResult<Response> {
        res.extensions.insert::<Write<P>>(self.data.clone());
        Ok(res)
    }
}

impl<P: Key> State<P> where P::Value: Send + Sync {
    /// Construct a new pair of `State` that can be passed directly to `Chain::link`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn both(start: P::Value) -> (State<P>, State<P>) {
        let x = State { data: Arc::new(RwLock::new(start)) };
        (x.clone(), x)
    }

    /// Construct a new `State` that can be passed directly to
    /// `Chain::link_before` or `Chain::link_after`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn one(start: P::Value) -> State<P> {
        State { data: Arc::new(RwLock::new(start)) }
    }
}

impl<P: Key> Read<P> where P::Value: Send + Sync {
    /// Construct a new pair of `Read` that can be passed directly to `Chain::link`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn both(start: P::Value) -> (Read<P>, Read<P>) {
        let x = Read { data: Arc::new(start) };
        (x.clone(), x)
    }

    /// Construct a new `Read` that can be passed directly to
    /// `Chain::link_before` or `Chain::link_after`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn one(start: P::Value) -> Read<P> {
        Read { data: Arc::new(start) }
    }
}

impl<P: Key> Write<P> where P::Value: Send {
    /// Construct a new pair of `Write` that can be passed directly to `Chain::link`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn both(start: P::Value) -> (Write<P>, Write<P>) {
        let x = Write { data: Arc::new(Mutex::new(start)) };
        (x.clone(), x)
    }

    /// Construct a new `Write` that can be passed directly to
    /// `Chain::link_before` or `Chain::link_after`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn one(start: P::Value) -> Write<P> {
        Write { data: Arc::new(Mutex::new(start)) }
    }
}
<|endoftext|>