<commit_before>//! This crate provides a function for parsing a GDL description to an AST. To get an AST, call the
//! `parse` function with the string representing the description. The AST is based off the
//! [AST](http://www.ggp.org/developers/gdl.html) used in
//! [GGP Base](https://github.com/ggp-org/ggp-base).

#![feature(plugin, collections, str_char)]
#![plugin(peg_syntax_ext)]

extern crate rustc_serialize;

use std::fmt::{Display, Formatter, Error};

use gdl::description;
use self::Clause::{RuleClause, SentenceClause};
use self::Sentence::{PropSentence, RelSentence};
use self::Literal::{NotLit, DistinctLit, OrLit, PropLit, RelLit};
use self::Term::{VarTerm, FuncTerm, ConstTerm};

pub mod visitor;

peg_file! gdl("grammar.rustpeg");

/// Parse a GDL string to a `Description`. Panics if the description is invalid.
pub fn parse(gdl: &str) -> Description {
    match description(gdl) {
        Ok(d) => d,
        Err(e) => panic!("{}", e)
    }
}

/// A GDL description. Contains a vector of `Clause`s, which are the top-level statements in
/// a GDL description.
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable)]
pub struct Description {
    pub clauses: Vec<Clause>
}

impl Description {
    /// Constructs a new description from a vector of `Clause`s
    pub fn new(clauses: Vec<Clause>) -> Description {
        Description { clauses: clauses }
    }
}

impl Display for Description {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        let mut s = String::new();
        for clause in self.clauses.iter() {
            s.push_str(&clause.to_string());
            s.push(' ');
        }
        let len = s.len();
        s.remove(len - 1);
        write!(f, "{}", s)
    }
}

/// A top level statement in GDL. The only types of top level statements are `Rule`s and
/// `Sentence`s
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable)]
pub enum Clause {
    // A rule clause
    RuleClause(Rule),

    // A sentence clause
    SentenceClause(Sentence)
}

impl Display for Clause {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        match self {
            &RuleClause(ref r) => Display::fmt(r, f),
            &SentenceClause(ref s) => Display::fmt(s, f)
        }
    }
}

/// A GDL rule contains a head `Sentence` that is implied by all the `Literal`s in the body
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable)]
pub struct Rule {
    pub head: Sentence,
    pub body: Vec<Literal>
}

impl Rule {
    pub fn new(head: Sentence, body: Vec<Literal>) -> Rule {
        Rule { head: head, body: body }
    }
}

impl Into<Clause> for Rule {
    fn into(self) -> Clause {
        RuleClause(self)
    }
}

impl Display for Rule {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        let mut s = String::from(&*self.head.to_string());
        for arg in self.body.iter() {
            s.push(' ');
            s.push_str(&arg.to_string());
        }
        write!(f, "(<= {})", s)
    }
}

/// A GDL sentence is like a `Rule` without a body. The two types of `Sentence`s are `Relation`s
/// and `Proposition`s
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable)]
pub enum Sentence {
    /// A proposition sentence
    PropSentence(Proposition),

    /// A relation sentence
    RelSentence(Relation)
}

impl Sentence {
    /// Returns the name of the sentence
    pub fn name(&self) -> &Constant {
        match self {
            &PropSentence(ref p) => &p.name,
            &RelSentence(ref r) => &r.name
        }
    }
}

impl Into<Literal> for Sentence {
    fn into(self) -> Literal {
        match self {
            PropSentence(p) => PropLit(p),
            RelSentence(r) => RelLit(r)
        }
    }
}

impl Into<Rule> for Sentence {
    fn into(self) -> Rule {
        Rule::new(self, Vec::new())
    }
}

impl Into<Clause> for Sentence {
    fn into(self) -> Clause {
        SentenceClause(self)
    }
}

impl Display for Sentence {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        match self {
            &PropSentence(ref p) => Display::fmt(p, f),
            &RelSentence(ref r) => Display::fmt(r, f)
        }
    }
}

/// A GDL literal
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable)]
pub enum Literal {
    NotLit(Not),
    OrLit(Or),
    DistinctLit(Distinct),
    PropLit(Proposition),
    RelLit(Relation)
}

impl Display for Literal {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        match self {
            &NotLit(ref n) => Display::fmt(n, f),
            &OrLit(ref o) => Display::fmt(o, f),
            &DistinctLit(ref d) => Display::fmt(d, f),
            &PropLit(ref p) => Display::fmt(p, f),
            &RelLit(ref r) => Display::fmt(r, f),
        }
    }
}

/// A GDL term is either a variable, a function, or a constant
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable)]
pub enum Term {
    VarTerm(Variable),
    FuncTerm(Function),
    ConstTerm(Constant)
}

impl Term {
    /// Returns the name of the term
    pub fn name(&self) -> &Constant {
        match self {
            &VarTerm(ref v) => &v.name,
            &FuncTerm(ref f) => &f.name,
            &ConstTerm(ref c) => c
        }
    }
}

impl Display for Term {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        match self {
            &VarTerm(ref v) => Display::fmt(v, f),
            &FuncTerm(ref func) => Display::fmt(func, f),
            &ConstTerm(ref c) => Display::fmt(c, f)
        }
    }
}

/// A proposition is a `Relation` with no body; it only has a name.
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable)]
pub struct Proposition {
    pub name: Constant
}

impl Proposition {
    pub fn new<T: Into<Constant>>(name: T) -> Proposition {
        Proposition { name: name.into() }
    }
}

impl Into<Literal> for Proposition {
    fn into(self) -> Literal {
        PropLit(self)
    }
}

impl Into<Sentence> for Proposition {
    fn into(self) -> Sentence {
        PropSentence(self)
    }
}

impl Into<Relation> for Proposition {
    fn into(self) -> Relation {
        Relation::new(self.name, Vec::new())
    }
}

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

/// A GDL relation
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable)]
pub struct Relation {
    pub name: Constant,
    pub args: Vec<Term>
}

impl Relation {
    /// Consruct a new `Relation` given a `name` and a list of `args`
    pub fn new<T: Into<Constant>>(name: T, args: Vec<Term>) -> Relation {
        Relation { name: name.into(), args: args }
    }
}

impl Into<Literal> for Relation {
    fn into(self) -> Literal {
        RelLit(self)
    }
}

impl Into<Sentence> for Relation {
    fn into(self) -> Sentence {
        RelSentence(self)
    }
}

impl Display for Relation {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        let mut s = String::from(&*self.name.name);
        for arg in self.args.iter() {
            s.push(' ');
            s.push_str(&arg.to_string());
        }
        write!(f, "({})", s)
    }
}

/// A not literal
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable)]
pub struct Not {
    pub lit: Box<Literal>
}

impl Not {
    pub fn new(lit: Box<Literal>) -> Not {
        Not { lit: lit }
    }
}

impl Into<Literal> for Not {
    fn into(self) -> Literal {
        NotLit(self)
    }
}

impl Display for Not {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "(not {})", self.lit)
    }
}

/// An or literal
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable)]
pub struct Or {
    pub lits: Vec<Literal>
}

impl Or {
    pub fn new(lits: Vec<Literal>) -> Or {
        Or { lits: lits }
    }
}

impl Into<Literal> for Or {
    fn into(self) -> Literal {
        OrLit(self)
    }
}

impl Display for Or {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        let mut s = String::new();
        for l in self.lits.iter() {
            s.push(' ');
            s.push_str(&l.to_string());
        }
        write!(f, "(or {})", s)
    }
}

/// A distinct literal
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable)]
pub struct Distinct {
    pub term1: Term,
    pub term2: Term
}

impl Distinct {
    pub fn new(term1: Term, term2: Term) -> Distinct {
        Distinct { term1: term1, term2: term2 }
    }
}

impl Into<Literal> for Distinct {
    fn into(self) -> Literal {
        DistinctLit(self)
    }
}

impl Display for Distinct {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "(distinct {} {})", self.term1, self.term2)
    }
}

/// A variable term
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable)]
pub struct Variable {
    pub name: Constant
}

impl Variable {
    pub fn new<T: Into<Constant>>(name: T) -> Variable {
        Variable { name: name.into() }
    }
}

impl Into<Term> for Variable {
    fn into(self) -> Term {
        VarTerm(self)
    }
}

impl Display for Variable {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        let mut s = self.name.to_string();
        s.insert(0, '?');
        write!(f, "?{}", self.name)
    }
}

/// A function term
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable)]
pub struct Function {
    pub name: Constant,
    pub args: Vec<Term>
}

impl Function {
    pub fn new<T: Into<Constant>>(name: T, args: Vec<Term>) -> Function {
        Function { name: name.into(), args: args }
    }
}

impl Into<Term> for Function {
    fn into(self) -> Term {
        FuncTerm(self)
    }
}

impl Display for Function {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        let mut s = String::from(&*self.name.name);
        for arg in self.args.iter() {
            s.push(' ');
            s.push_str(&arg.to_string());
        }
        write!(f, "({})", s)
    }
}

/// A GDL constant
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable)]
pub struct Constant {
    pub name: String
}

impl Constant {
    pub fn new<T: Into<String>>(name: T) -> Constant {
        Constant { name: name.into() }
    }
}

impl Into<Term> for Constant {
    fn into(self) -> Term {
        ConstTerm(self)
    }
}

impl Display for Constant {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "{}", self.name)
    }
}

impl<'a> Into<Constant> for &'a str {
    fn into(self) -> Constant {
        Constant::new(self.to_string())
    }
}
<commit_msg>Added Ord and PartialOrd to all types<commit_after>//! This crate provides a function for parsing a GDL description to an AST. To get an AST, call the
//! `parse` function with the string representing the description. The AST is based off the
//! [AST](http://www.ggp.org/developers/gdl.html) used in
//! [GGP Base](https://github.com/ggp-org/ggp-base).

#![feature(plugin, collections, str_char)]
#![plugin(peg_syntax_ext)]

extern crate rustc_serialize;

use std::fmt::{Display, Formatter, Error};

use gdl::description;
use self::Clause::{RuleClause, SentenceClause};
use self::Sentence::{PropSentence, RelSentence};
use self::Literal::{NotLit, DistinctLit, OrLit, PropLit, RelLit};
use self::Term::{VarTerm, FuncTerm, ConstTerm};

pub mod visitor;

peg_file! gdl("grammar.rustpeg");

/// Parse a GDL string to a `Description`. Panics if the description is invalid.
pub fn parse(gdl: &str) -> Description {
    match description(gdl) {
        Ok(d) => d,
        Err(e) => panic!("{}", e)
    }
}

/// A GDL description. Contains a vector of `Clause`s, which are the top-level statements in
/// a GDL description.
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable, Ord, PartialOrd)]
pub struct Description {
    pub clauses: Vec<Clause>
}

impl Description {
    /// Constructs a new description from a vector of `Clause`s
    pub fn new(clauses: Vec<Clause>) -> Description {
        Description { clauses: clauses }
    }
}

impl Display for Description {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        let mut s = String::new();
        for clause in self.clauses.iter() {
            s.push_str(&clause.to_string());
            s.push(' ');
        }
        let len = s.len();
        s.remove(len - 1);
        write!(f, "{}", s)
    }
}

/// A top level statement in GDL. The only types of top level statements are `Rule`s and
/// `Sentence`s
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable, Ord, PartialOrd)]
pub enum Clause {
    // A rule clause
    RuleClause(Rule),

    // A sentence clause
    SentenceClause(Sentence)
}

impl Display for Clause {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        match self {
            &RuleClause(ref r) => Display::fmt(r, f),
            &SentenceClause(ref s) => Display::fmt(s, f)
        }
    }
}

/// A GDL rule contains a head `Sentence` that is implied by all the `Literal`s in the body
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable, Ord, PartialOrd)]
pub struct Rule {
    pub head: Sentence,
    pub body: Vec<Literal>
}

impl Rule {
    pub fn new(head: Sentence, body: Vec<Literal>) -> Rule {
        Rule { head: head, body: body }
    }
}

impl Into<Clause> for Rule {
    fn into(self) -> Clause {
        RuleClause(self)
    }
}

impl Display for Rule {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        let mut s = String::from(&*self.head.to_string());
        for arg in self.body.iter() {
            s.push(' ');
            s.push_str(&arg.to_string());
        }
        write!(f, "(<= {})", s)
    }
}

/// A GDL sentence is like a `Rule` without a body. The two types of `Sentence`s are `Relation`s
/// and `Proposition`s
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable, Ord, PartialOrd)]
pub enum Sentence {
    /// A proposition sentence
    PropSentence(Proposition),

    /// A relation sentence
    RelSentence(Relation)
}

impl Sentence {
    /// Returns the name of the sentence
    pub fn name(&self) -> &Constant {
        match self {
            &PropSentence(ref p) => &p.name,
            &RelSentence(ref r) => &r.name
        }
    }
}

impl Into<Literal> for Sentence {
    fn into(self) -> Literal {
        match self {
            PropSentence(p) => PropLit(p),
            RelSentence(r) => RelLit(r)
        }
    }
}

impl Into<Rule> for Sentence {
    fn into(self) -> Rule {
        Rule::new(self, Vec::new())
    }
}

impl Into<Clause> for Sentence {
    fn into(self) -> Clause {
        SentenceClause(self)
    }
}

impl Display for Sentence {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        match self {
            &PropSentence(ref p) => Display::fmt(p, f),
            &RelSentence(ref r) => Display::fmt(r, f)
        }
    }
}

/// A GDL literal
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable, Ord, PartialOrd)]
pub enum Literal {
    NotLit(Not),
    OrLit(Or),
    DistinctLit(Distinct),
    PropLit(Proposition),
    RelLit(Relation)
}

impl Display for Literal {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        match self {
            &NotLit(ref n) => Display::fmt(n, f),
            &OrLit(ref o) => Display::fmt(o, f),
            &DistinctLit(ref d) => Display::fmt(d, f),
            &PropLit(ref p) => Display::fmt(p, f),
            &RelLit(ref r) => Display::fmt(r, f),
        }
    }
}

/// A GDL term is either a variable, a function, or a constant
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable, Ord, PartialOrd)]
pub enum Term {
    VarTerm(Variable),
    FuncTerm(Function),
    ConstTerm(Constant)
}

impl Term {
    /// Returns the name of the term
    pub fn name(&self) -> &Constant {
        match self {
            &VarTerm(ref v) => &v.name,
            &FuncTerm(ref f) => &f.name,
            &ConstTerm(ref c) => c
        }
    }
}

impl Display for Term {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        match self {
            &VarTerm(ref v) => Display::fmt(v, f),
            &FuncTerm(ref func) => Display::fmt(func, f),
            &ConstTerm(ref c) => Display::fmt(c, f)
        }
    }
}

/// A proposition is a `Relation` with no body; it only has a name.
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable, Ord, PartialOrd)]
pub struct Proposition {
    pub name: Constant
}

impl Proposition {
    pub fn new<T: Into<Constant>>(name: T) -> Proposition {
        Proposition { name: name.into() }
    }
}

impl Into<Literal> for Proposition {
    fn into(self) -> Literal {
        PropLit(self)
    }
}

impl Into<Sentence> for Proposition {
    fn into(self) -> Sentence {
        PropSentence(self)
    }
}

impl Into<Relation> for Proposition {
    fn into(self) -> Relation {
        Relation::new(self.name, Vec::new())
    }
}

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

/// A GDL relation
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable, Ord, PartialOrd)]
pub struct Relation {
    pub name: Constant,
    pub args: Vec<Term>
}

impl Relation {
    /// Consruct a new `Relation` given a `name` and a list of `args`
    pub fn new<T: Into<Constant>>(name: T, args: Vec<Term>) -> Relation {
        Relation { name: name.into(), args: args }
    }
}

impl Into<Literal> for Relation {
    fn into(self) -> Literal {
        RelLit(self)
    }
}

impl Into<Sentence> for Relation {
    fn into(self) -> Sentence {
        RelSentence(self)
    }
}

impl Display for Relation {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        let mut s = String::from(&*self.name.name);
        for arg in self.args.iter() {
            s.push(' ');
            s.push_str(&arg.to_string());
        }
        write!(f, "({})", s)
    }
}

/// A not literal
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable, Ord, PartialOrd)]
pub struct Not {
    pub lit: Box<Literal>
}

impl Not {
    pub fn new(lit: Box<Literal>) -> Not {
        Not { lit: lit }
    }
}

impl Into<Literal> for Not {
    fn into(self) -> Literal {
        NotLit(self)
    }
}

impl Display for Not {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "(not {})", self.lit)
    }
}

/// An or literal
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable, Ord, PartialOrd)]
pub struct Or {
    pub lits: Vec<Literal>
}

impl Or {
    pub fn new(lits: Vec<Literal>) -> Or {
        Or { lits: lits }
    }
}

impl Into<Literal> for Or {
    fn into(self) -> Literal {
        OrLit(self)
    }
}

impl Display for Or {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        let mut s = String::new();
        for l in self.lits.iter() {
            s.push(' ');
            s.push_str(&l.to_string());
        }
        write!(f, "(or {})", s)
    }
}

/// A distinct literal
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable, Ord, PartialOrd)]
pub struct Distinct {
    pub term1: Term,
    pub term2: Term
}

impl Distinct {
    pub fn new(term1: Term, term2: Term) -> Distinct {
        Distinct { term1: term1, term2: term2 }
    }
}

impl Into<Literal> for Distinct {
    fn into(self) -> Literal {
        DistinctLit(self)
    }
}

impl Display for Distinct {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "(distinct {} {})", self.term1, self.term2)
    }
}

/// A variable term
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable, Ord, PartialOrd)]
pub struct Variable {
    pub name: Constant
}

impl Variable {
    pub fn new<T: Into<Constant>>(name: T) -> Variable {
        Variable { name: name.into() }
    }
}

impl Into<Term> for Variable {
    fn into(self) -> Term {
        VarTerm(self)
    }
}

impl Display for Variable {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        let mut s = self.name.to_string();
        s.insert(0, '?');
        write!(f, "?{}", self.name)
    }
}

/// A function term
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable, Ord, PartialOrd)]
pub struct Function {
    pub name: Constant,
    pub args: Vec<Term>
}

impl Function {
    pub fn new<T: Into<Constant>>(name: T, args: Vec<Term>) -> Function {
        Function { name: name.into(), args: args }
    }
}

impl Into<Term> for Function {
    fn into(self) -> Term {
        FuncTerm(self)
    }
}

impl Display for Function {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        let mut s = String::from(&*self.name.name);
        for arg in self.args.iter() {
            s.push(' ');
            s.push_str(&arg.to_string());
        }
        write!(f, "({})", s)
    }
}

/// A GDL constant
#[derive(Debug, Clone, Hash, Eq, PartialEq, RustcDecodable, RustcEncodable, Ord, PartialOrd)]
pub struct Constant {
    pub name: String
}

impl Constant {
    pub fn new<T: Into<String>>(name: T) -> Constant {
        Constant { name: name.into() }
    }
}

impl Into<Term> for Constant {
    fn into(self) -> Term {
        ConstTerm(self)
    }
}

impl Display for Constant {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "{}", self.name)
    }
}

impl<'a> Into<Constant> for &'a str {
    fn into(self) -> Constant {
        Constant::new(self.to_string())
    }
}
<|endoftext|>


<commit_before>//! ### rust-mysql-simple
//! Mysql client library implemented in rust nightly.
//!
//! #### Install
//! Just include another `[dependencies.*]` section into your Cargo.toml:
//!
//! ```toml
//! [dependencies.mysql]
//! git = "https://github.com/blackbeam/rust-mysql-simple"
//! ```
//!
//! rust-mysql-simple offer support of SSL via `ssl` cargo feature which is enabled by default. If you have no plans to use SSL, then you should disable that feature to not to depend on rust-openssl:
//!
//! ```toml
//! [dependencies.mysql]
//! git = "https://github.com/blackbeam/rust-mysql-simple"
//! default-features = false
//! ```
//!
//! #### Use
//! You should start by creating [`MyOpts`](conn/struct.MyOpts.html) struct.
//!
//! Then you can create [`MyPool`](conn/pool/struct.MyPool.html) which should be
//! enough to work with mysql server.
#![crate_name="mysql"]
#![crate_type="rlib"]
#![crate_type="dylib"]

#![feature(unsafe_destructor)]
#![feature(slicing_syntax)]
#![feature(plugin)]

#![allow(dead_code)]

#[cfg(test)]
extern crate test;

#[cfg(test)]
#[plugin]
extern crate stainless;

extern crate core;
extern crate time;
#[cfg(feature = "openssl")]
extern crate openssl;
extern crate regex;
#[plugin] #[no_link]
extern crate regex_macros;
#[macro_use]
extern crate lazy_static;

mod scramble;
pub mod consts;
pub mod error;
mod packet;
mod io;
pub mod value;
pub mod conn;
<commit_msg>Allow unstable<commit_after>//! ### rust-mysql-simple
//! Mysql client library implemented in rust nightly.
//!
//! #### Install
//! Just include another `[dependencies.*]` section into your Cargo.toml:
//!
//! ```toml
//! [dependencies.mysql]
//! git = "https://github.com/blackbeam/rust-mysql-simple"
//! ```
//!
//! rust-mysql-simple offer support of SSL via `ssl` cargo feature which is enabled by default. If you have no plans to use SSL, then you should disable that feature to not to depend on rust-openssl:
//!
//! ```toml
//! [dependencies.mysql]
//! git = "https://github.com/blackbeam/rust-mysql-simple"
//! default-features = false
//! ```
//!
//! #### Use
//! You should start by creating [`MyOpts`](conn/struct.MyOpts.html) struct.
//!
//! Then you can create [`MyPool`](conn/pool/struct.MyPool.html) which should be
//! enough to work with mysql server.
#![crate_name="mysql"]
#![crate_type="rlib"]
#![crate_type="dylib"]

#![feature(unsafe_destructor)]
#![feature(slicing_syntax)]
#![feature(plugin)]

#![allow(dead_code, unstable)]

#[cfg(test)]
extern crate test;

#[cfg(test)]
#[plugin]
extern crate stainless;

extern crate core;
extern crate time;
#[cfg(feature = "openssl")]
extern crate openssl;
extern crate regex;
#[plugin] #[no_link]
extern crate regex_macros;
#[macro_use]
extern crate lazy_static;

mod scramble;
pub mod consts;
pub mod error;
mod packet;
mod io;
pub mod value;
pub mod conn;
<|endoftext|>


<commit_before><commit_msg>Delete exp.rs<commit_after><|endoftext|>


<commit_before>//! A simple `io::stdout` and `io::stderr` writing `Logger` implementation from the
//! `log` crate, using the `ansi_term` crate for colors and configured at runtime,
//! or at compile time with simple function calls. Designed for simple CLIs.
//!
//! This library only comes with 3 public ways to initialize the global logger.
//! Ensure you call one of these exactly once early in your rust program as shown
//! in one of the examples below.
//!
//! ## Example
//! The standard example with `clap` as the arg parser using the default configuration.
//!
//! ```
//! #[macro_use] extern crate log;
//! extern crate clap;
//! extern crate loggerv;
//!
//! use clap::{Arg, App};
//!
//! fn main() {
//!     let args = App::new("app")
//!                    .arg(Arg::with_name("v")
//!                             .short("v")
//!                             .multiple(true)
//!                             .help("Sets the level of verbosity"))
//!                    .get_matches();
//!
//!     loggerv::init_with_verbosity(args.occurrences_of("v")).unwrap();
//!
//!     error!("this is always printed");
//!     warn!("this too, and it's printed to stderr");
//!     info!("this is optional");  // for ./app -v or higher
//!     debug!("this is optional"); // for ./app -vv or higher
//!     trace!("this is optional"); // for ./app -vvv
//! }
//! ```
//!
//! But obviously use whatever argument parsing methods you prefer.
//!
//! ## Example
//! For a compile time switch, all you really need is `log` (for the macros)
//! and `loggerv` for how to print what's being sent to the macros with the default configuration.
//!
//! ```
//! #[macro_use] extern crate log;
//! extern crate loggerv;
//!
//! use log::LogLevel;
//!
//! fn main() {
//!     loggerv::init_with_level(LogLevel::Info).unwrap();
//!     debug!("this is a debug {}", "message");
//!     error!("this is printed by default");
//! }
//! ```
//!
//! # Example
//! If you don't really care at all you could just use the plain `init_quiet` function
//! to only show warnings and errors with the default configuration:
//!
//! ```
//! #[macro_use] extern crate log;
//! extern crate loggerv;
//!
//! fn main() {
//!     loggerv::init_quiet().unwrap();
//!     info!("hidden");
//!     error!("this is printed by default");
//! }
//! ```
//!
//! # Example
//! If you want to configure the output, the Builder pattern API for Logger can be used.
//!
//! ```
//! #[macro_use] extern crate log;
//! extern crate clap;
//! extern crate loggerv;
//!
//! use clap::{Arg, App};
//!
//! fn main() {
//!     let args = App::new("app")
//!                    .arg(Arg::with_name("v")
//!                             .short("v")
//!                             .multiple(true)
//!                             .help("Sets the level of verbosity"))
//!                    .get_matches();
//!
//!     // This will change the log configuration to include line numbers in the "tag" portion of
//!     // the statement, which is the text to the left of the separator, change the separator from
//!     // a colon to an equal sign, hide or disable the module path, and disable colorized output.
//!     // See the Logger documentation for more configuration methods and the ability to change
//!     // the colors for each log level.
//!     loggerv::Logger::new()
//!         .verbosity(args.occurrences_of("v"))
//!         .line_numbers(true)
//!         .separator(" = ")
//!         .module_path(false)
//!         .colors(false)
//!         .init()
//!         .unwrap();
//!
//!     error!("this is always printed");
//!     warn!("this too, and it's printed to stderr");
//!     info!("this is optional");  // for ./app -v or higher
//!     debug!("this is optional"); // for ./app -vv or higher
//!     trace!("this is optional"); // for ./app -vvv
//! }
//! ```
//!
//! See the documentation for the log crate for more information about its API.
//!

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

#[cfg(not(test))]
extern crate log;

extern crate atty;
extern crate ansi_term;

use log::{Log, LogLevel, LogMetadata, LogRecord, SetLoggerError};
use std::io::{self, Write};
use ansi_term::Colour;

pub const DEFAULT_COLORS: bool = true;
pub const DEFAULT_SEPARATOR: &str = ": ";
pub const DEFAULT_LEVEL: LogLevel = LogLevel::Warn;
pub const DEFAULT_LINE_NUMBERS: bool = false;
pub const DEFAULT_MODULE_PATH: bool = true;
pub const DEFAULT_ERROR_COLOR: Colour = Colour::Fixed(9); // bright red
pub const DEFAULT_WARN_COLOR: Colour = Colour::Fixed(11); // bright yellow
pub const DEFAULT_INFO_COLOR: Colour = Colour::Fixed(10); // bright green
pub const DEFAULT_DEBUG_COLOR: Colour = Colour::Fixed(7); // light grey
pub const DEFAULT_TRACE_COLOR: Colour = Colour::Fixed(8); // grey

#[derive(Debug, Clone, PartialEq)]
pub struct Logger {
    colors: bool,
    line_numbers: bool,
    level: LogLevel,
    module_path: bool,
    separator: String,
    error_color: Colour,
    warn_color: Colour,
    info_color: Colour,
    debug_color: Colour,
    trace_color: Colour,
}

impl Logger {
    /// Creates a new instance of the verbosity-based logger.
    ///
    /// The default level is WARN. Color is enabled if the parent application or library is running
    /// from a terminal, i.e. running a tty. The default separator is the ": " string. The default
    /// output format is `LEVEL [module path]: message`.
    pub fn new() -> Logger {
        Logger {
            colors: DEFAULT_COLORS && atty::is(atty::Stream::Stdout) && atty::is(atty::Stream::Stderr),
            line_numbers: DEFAULT_LINE_NUMBERS,
            level: DEFAULT_LEVEL,
            module_path: DEFAULT_MODULE_PATH,
            separator: String::from(DEFAULT_SEPARATOR),
            error_color: DEFAULT_ERROR_COLOR,
            warn_color: DEFAULT_WARN_COLOR,
            info_color: DEFAULT_INFO_COLOR,
            debug_color: DEFAULT_DEBUG_COLOR,
            trace_color: DEFAULT_TRACE_COLOR,
        }
    }

    /// Sets the output color for the ERROR level. The default is bright red.
    pub fn error_color(mut self, c: Colour) -> Self {
        self.error_color = c;
        self
    }

    /// Sets the output color for the WARN level. The default is bright yellow.
    pub fn warn_color(mut self, c: Colour) -> Self {
        self.warn_color = c;
        self
    }

    /// Sets the output color for the INFO level. The default is bright green.
    pub fn info_color(mut self, c: Colour) -> Self {
        self.info_color = c;
        self
    }

    /// Sets the output color for the DEBUG level. The default is light grey.
    pub fn debug_color(mut self, c: Colour) -> Self {
        self.debug_color = c;
        self
    }

    /// Sets the output color for the TRACE level. The default is grey.
    pub fn trace_color(mut self, c: Colour) -> Self {
        self.trace_color = c;
        self
    }

    /// Gets the color to use for the log statement's tag based on level.
    fn color(&self, l: &LogLevel) -> Colour {
        match *l {
            LogLevel::Error => self.error_color,
            LogLevel::Warn => self.warn_color,
            LogLevel::Info => self.info_color,
            LogLevel::Debug => self.debug_color,
            LogLevel::Trace => self.trace_color,
        }
    }

    /// Sets the separator string.
    ///
    /// The separator is the string between the "tag" and the message that make up a log statement.
    /// The tag will be colorized if enabled, while the message will not. The default is `: `.
    pub fn separator(mut self, s: &str) -> Self {
        self.separator = String::from(s);
        self
    }

    /// Enables or disables colorizing the output.
    ///
    /// If the logger is _not_ used in a terminal, then
    /// the output is _not_ colorized regardless of the parameter value.
    pub fn colors(mut self, c: bool) -> Self {
        self.colors = c && atty::is(atty::Stream::Stdout) && atty::is(atty::Stream::Stderr);
        self
    }

    /// Enables or disables including line numbers in the "tag" portion of the log statement. The
    /// tag is the text to the left of the separator.
    pub fn line_numbers(mut self, l: bool) -> Self {
        self.line_numbers = l;
        self
    }

    /// Explicitly sets the log level instead through a verbosity.
    pub fn level(mut self, l: LogLevel) -> Self {
        self.level = l;
        self
    }

    /// Enables or disables including the module path in the "tag" portion of the log statement.
    /// The tag is the text to the left of the separator.
    pub fn module_path(mut self, m: bool) -> Self {
        self.module_path = m;
        self
    }

    /// Converts the verbosity to a log level.
    ///
    /// A verbosity of zero (0) is the default, which means ERROR and WARN log statements are
    /// printed to `stderr`. No other log statements are printed on any of the standard streams
    /// (`stdout` or `stderr`). As the verbosity is increased, the log level is increased and more
    /// log statements will be printed to `stdout`. A verbosity of 1 will print INFO log statements
    /// to `stdout` in addition to ERROR and WARN. A verbosity of 2 will print INFO and DEBUG log
    /// statements to `stdout`. A verbosity of 3 or higher will print INFO, DEBUG, and TRACE
    /// log statements to `stdout` with ERROR and WARN statements printed to `stderr`.
    pub fn verbosity(mut self, v: u64) -> Self {
        self.level = match v {
                0 => LogLevel::Warn,  // default
                1 => LogLevel::Info,  // -v
                2 => LogLevel::Debug, // -vv
                _ => LogLevel::Trace, // -vvv and above
        };
        self
    }

    /// Initializes the logger.
    ///
    /// This also consumes the logger and cannot no longer be modified after initialization.
    pub fn init(self) -> Result<(), SetLoggerError> {
        log::set_logger(|max_level| {
            max_level.set(self.level.to_log_level_filter());
            Box::new(self)
        })
    }
}

impl Log for Logger {
    fn enabled(&self, metadata: &LogMetadata) -> bool {
        metadata.level() <= self.level
    }

    fn log(&self, record: &LogRecord) {
        if self.enabled(record.metadata()) {
            let level = record.level();
            let module_path = if self.module_path {
                format!(" [{}]", record.location().module_path())
            } else {
                String::new()
            };
            let line = if self.line_numbers {
                format!(" (line {})", record.location().line())
            } else {
                String::new()
            };
            let tag = if self.colors {
                self.color(&level).paint(format!("{}{}{}", level, module_path, line)).to_string()
            } else {
                format!("{}{}{}", level, module_path, line)
            };
            if level <= LogLevel::Warn {
                let _ = writeln!(&mut io::stderr(), "{}{}{}", tag, self.separator, record.args());
            } else {
                println!("{}{}{}", tag, self.separator, record.args());
            }
        }
    }
}

impl Default for Logger {
    fn default() -> Logger {
        Logger::new()
    }
}

/// Initialize loggerv with a maximal log level.
///
/// See the main loggerv documentation page for an example.
pub fn init_with_level(level: LogLevel) -> Result<(), SetLoggerError> {
    Logger::new().level(level).init()
}

/// Initialize loggerv with a verbosity level.
///
/// Intended to be used with an arg parser counting the amount of -v flags.
/// See the main loggerv documentation page for an example.
pub fn init_with_verbosity(verbosity: u64) -> Result<(), SetLoggerError> {
    Logger::new().verbosity(verbosity).init()
}

/// Initializes loggerv with only warnings and errors.
///
/// See the main loggerv documentation page for an example.
pub fn init_quiet() -> Result<(), SetLoggerError> {
    init_with_level(LogLevel::Warn)
}

#[cfg(test)]
mod tests {
    use init_with_verbosity;

    #[test]
    fn init_and_macros() {
        let l = init_with_verbosity(3);
        assert_eq!(l.is_ok(), true);
        error!("error log");
        warn!("warn log");
        info!("info log");
        debug!("debug log");
        trace!("trace log");
    }
}
<commit_msg>Fix formatting of module documentation<commit_after>//! A simple `io::stdout` and `io::stderr` writing `Logger` implementation from the
//! `log` crate, using the `ansi_term` crate for colors and configured at runtime via a verbosity
//! or at compile time with simple function calls. Designed for simple CLIs.
//!
//! This library includes a Builder pattern API for configuring a logger and three initializing
//! helper functions to create a default logger. Ensure you create and initialize only once
//! a global logger with the Builder pattern API or use one of the three public helper functions
//! early in your program as shown in the examples below.
//!
//! ## Example
//!
//! The standard example with `clap` as the arg parser using the default configuration.
//!
//! ```
//! #[macro_use] extern crate log;
//! extern crate clap;
//! extern crate loggerv;
//!
//! use clap::{Arg, App};
//!
//! fn main() {
//!     let args = App::new("app")
//!                    .arg(Arg::with_name("v")
//!                             .short("v")
//!                             .multiple(true)
//!                             .help("Sets the level of verbosity"))
//!                    .get_matches();
//!
//!     loggerv::init_with_verbosity(args.occurrences_of("v")).unwrap();
//!
//!     error!("this is always printed");
//!     warn!("this too, and it's printed to stderr");
//!     info!("this is optional");  // for ./app -v or higher
//!     debug!("this is optional"); // for ./app -vv or higher
//!     trace!("this is optional"); // for ./app -vvv
//! }
//! ```
//!
//! But obviously use whatever argument parsing methods you prefer.
//!
//! ## Example
//!
//! For a compile time switch, all you really need is `log` (for the macros)
//! and `loggerv` for how to print what's being sent to the macros with the default configuration.
//!
//! ```
//! #[macro_use] extern crate log;
//! extern crate loggerv;
//!
//! use log::LogLevel;
//!
//! fn main() {
//!     loggerv::init_with_level(LogLevel::Info).unwrap();
//!     debug!("this is a debug {}", "message");
//!     error!("this is printed by default");
//! }
//! ```
//!
//! ## Example
//!
//! If you don't really care at all you could just use the plain `init_quiet` function
//! to only show warnings and errors with the default configuration:
//!
//! ```
//! #[macro_use] extern crate log;
//! extern crate loggerv;
//!
//! fn main() {
//!     loggerv::init_quiet().unwrap();
//!     info!("hidden");
//!     error!("this is printed by default");
//! }
//! ```
//!
//! ## Example
//!
//! If you want to configure the output, the Builder pattern API for Logger can be used.
//!
//! ```
//! #[macro_use] extern crate log;
//! extern crate clap;
//! extern crate loggerv;
//!
//! use clap::{Arg, App};
//!
//! fn main() {
//!     let args = App::new("app")
//!                    .arg(Arg::with_name("v")
//!                             .short("v")
//!                             .multiple(true)
//!                             .help("Sets the level of verbosity"))
//!                    .get_matches();
//!
//!     // This will change the log configuration to include line numbers in the "tag" portion of
//!     // the statement, which is the text to the left of the separator, change the separator from
//!     // a colon to an equal sign, hide or disable the module path, and disable colorized output.
//!     // See the Logger documentation for more configuration methods and the ability to change
//!     // the colors for each log level.
//!     loggerv::Logger::new()
//!         .verbosity(args.occurrences_of("v"))
//!         .line_numbers(true)
//!         .separator(" = ")
//!         .module_path(false)
//!         .colors(false)
//!         .init()
//!         .unwrap();
//!
//!     error!("this is always printed");
//!     warn!("this too, and it's printed to stderr");
//!     info!("this is optional");  // for ./app -v or higher
//!     debug!("this is optional"); // for ./app -vv or higher
//!     trace!("this is optional"); // for ./app -vvv
//! }
//! ```
//!
//! See the documentation for the log crate for more information about its API.
//!

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

#[cfg(not(test))]
extern crate log;

extern crate atty;
extern crate ansi_term;

use log::{Log, LogLevel, LogMetadata, LogRecord, SetLoggerError};
use std::io::{self, Write};
use ansi_term::Colour;

pub const DEFAULT_COLORS: bool = true;
pub const DEFAULT_SEPARATOR: &str = ": ";
pub const DEFAULT_LEVEL: LogLevel = LogLevel::Warn;
pub const DEFAULT_LINE_NUMBERS: bool = false;
pub const DEFAULT_MODULE_PATH: bool = true;
pub const DEFAULT_ERROR_COLOR: Colour = Colour::Fixed(9); // bright red
pub const DEFAULT_WARN_COLOR: Colour = Colour::Fixed(11); // bright yellow
pub const DEFAULT_INFO_COLOR: Colour = Colour::Fixed(10); // bright green
pub const DEFAULT_DEBUG_COLOR: Colour = Colour::Fixed(7); // light grey
pub const DEFAULT_TRACE_COLOR: Colour = Colour::Fixed(8); // grey

#[derive(Debug, Clone, PartialEq)]
pub struct Logger {
    colors: bool,
    line_numbers: bool,
    level: LogLevel,
    module_path: bool,
    separator: String,
    error_color: Colour,
    warn_color: Colour,
    info_color: Colour,
    debug_color: Colour,
    trace_color: Colour,
}

impl Logger {
    /// Creates a new instance of the verbosity-based logger.
    ///
    /// The default level is WARN. Color is enabled if the parent application or library is running
    /// from a terminal, i.e. running a tty. The default separator is the ": " string. The default
    /// output format is `LEVEL [module path]: message`.
    pub fn new() -> Logger {
        Logger {
            colors: DEFAULT_COLORS && atty::is(atty::Stream::Stdout) && atty::is(atty::Stream::Stderr),
            line_numbers: DEFAULT_LINE_NUMBERS,
            level: DEFAULT_LEVEL,
            module_path: DEFAULT_MODULE_PATH,
            separator: String::from(DEFAULT_SEPARATOR),
            error_color: DEFAULT_ERROR_COLOR,
            warn_color: DEFAULT_WARN_COLOR,
            info_color: DEFAULT_INFO_COLOR,
            debug_color: DEFAULT_DEBUG_COLOR,
            trace_color: DEFAULT_TRACE_COLOR,
        }
    }

    /// Sets the output color for the ERROR level. The default is bright red.
    pub fn error_color(mut self, c: Colour) -> Self {
        self.error_color = c;
        self
    }

    /// Sets the output color for the WARN level. The default is bright yellow.
    pub fn warn_color(mut self, c: Colour) -> Self {
        self.warn_color = c;
        self
    }

    /// Sets the output color for the INFO level. The default is bright green.
    pub fn info_color(mut self, c: Colour) -> Self {
        self.info_color = c;
        self
    }

    /// Sets the output color for the DEBUG level. The default is light grey.
    pub fn debug_color(mut self, c: Colour) -> Self {
        self.debug_color = c;
        self
    }

    /// Sets the output color for the TRACE level. The default is grey.
    pub fn trace_color(mut self, c: Colour) -> Self {
        self.trace_color = c;
        self
    }

    /// Gets the color to use for the log statement's tag based on level.
    fn color(&self, l: &LogLevel) -> Colour {
        match *l {
            LogLevel::Error => self.error_color,
            LogLevel::Warn => self.warn_color,
            LogLevel::Info => self.info_color,
            LogLevel::Debug => self.debug_color,
            LogLevel::Trace => self.trace_color,
        }
    }

    /// Sets the separator string.
    ///
    /// The separator is the string between the "tag" and the message that make up a log statement.
    /// The tag will be colorized if enabled, while the message will not. The default is `: `.
    pub fn separator(mut self, s: &str) -> Self {
        self.separator = String::from(s);
        self
    }

    /// Enables or disables colorizing the output.
    ///
    /// If the logger is _not_ used in a terminal, then
    /// the output is _not_ colorized regardless of the parameter value.
    pub fn colors(mut self, c: bool) -> Self {
        self.colors = c && atty::is(atty::Stream::Stdout) && atty::is(atty::Stream::Stderr);
        self
    }

    /// Enables or disables including line numbers in the "tag" portion of the log statement. The
    /// tag is the text to the left of the separator.
    pub fn line_numbers(mut self, l: bool) -> Self {
        self.line_numbers = l;
        self
    }

    /// Explicitly sets the log level instead through a verbosity.
    pub fn level(mut self, l: LogLevel) -> Self {
        self.level = l;
        self
    }

    /// Enables or disables including the module path in the "tag" portion of the log statement.
    /// The tag is the text to the left of the separator.
    pub fn module_path(mut self, m: bool) -> Self {
        self.module_path = m;
        self
    }

    /// Converts the verbosity to a log level.
    ///
    /// A verbosity of zero (0) is the default, which means ERROR and WARN log statements are
    /// printed to `stderr`. No other log statements are printed on any of the standard streams
    /// (`stdout` or `stderr`). As the verbosity is increased, the log level is increased and more
    /// log statements will be printed to `stdout`. A verbosity of 1 will print INFO log statements
    /// to `stdout` in addition to ERROR and WARN. A verbosity of 2 will print INFO and DEBUG log
    /// statements to `stdout`. A verbosity of 3 or higher will print INFO, DEBUG, and TRACE
    /// log statements to `stdout` with ERROR and WARN statements printed to `stderr`.
    pub fn verbosity(mut self, v: u64) -> Self {
        self.level = match v {
                0 => LogLevel::Warn,  // default
                1 => LogLevel::Info,  // -v
                2 => LogLevel::Debug, // -vv
                _ => LogLevel::Trace, // -vvv and above
        };
        self
    }

    /// Initializes the logger.
    ///
    /// This also consumes the logger and cannot no longer be modified after initialization.
    pub fn init(self) -> Result<(), SetLoggerError> {
        log::set_logger(|max_level| {
            max_level.set(self.level.to_log_level_filter());
            Box::new(self)
        })
    }
}

impl Log for Logger {
    fn enabled(&self, metadata: &LogMetadata) -> bool {
        metadata.level() <= self.level
    }

    fn log(&self, record: &LogRecord) {
        if self.enabled(record.metadata()) {
            let level = record.level();
            let module_path = if self.module_path {
                format!(" [{}]", record.location().module_path())
            } else {
                String::new()
            };
            let line = if self.line_numbers {
                format!(" (line {})", record.location().line())
            } else {
                String::new()
            };
            let tag = if self.colors {
                self.color(&level).paint(format!("{}{}{}", level, module_path, line)).to_string()
            } else {
                format!("{}{}{}", level, module_path, line)
            };
            if level <= LogLevel::Warn {
                let _ = writeln!(&mut io::stderr(), "{}{}{}", tag, self.separator, record.args());
            } else {
                println!("{}{}{}", tag, self.separator, record.args());
            }
        }
    }
}

impl Default for Logger {
    fn default() -> Logger {
        Logger::new()
    }
}

/// Initialize loggerv with a maximal log level.
///
/// See the main loggerv documentation page for an example.
pub fn init_with_level(level: LogLevel) -> Result<(), SetLoggerError> {
    Logger::new().level(level).init()
}

/// Initialize loggerv with a verbosity level.
///
/// Intended to be used with an arg parser counting the amount of -v flags.
/// See the main loggerv documentation page for an example.
pub fn init_with_verbosity(verbosity: u64) -> Result<(), SetLoggerError> {
    Logger::new().verbosity(verbosity).init()
}

/// Initializes loggerv with only warnings and errors.
///
/// See the main loggerv documentation page for an example.
pub fn init_quiet() -> Result<(), SetLoggerError> {
    init_with_level(LogLevel::Warn)
}

#[cfg(test)]
mod tests {
    use init_with_verbosity;

    #[test]
    fn init_and_macros() {
        let l = init_with_verbosity(3);
        assert_eq!(l.is_ok(), true);
        error!("error log");
        warn!("warn log");
        info!("info log");
        debug!("debug log");
        trace!("trace log");
    }
}
<|endoftext|>


<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2013 Jeremy Letang (letang.jeremy@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#![allow(dead_code, non_camel_case_types)]

use libc::{c_char, c_double, c_void};

use types::{PaError, PaDeviceIndex, PaHostApiIndex, PaStreamCallbackFlags,
    PaStreamCallbackTimeInfo, PaStreamInfo, PaTime, PaStreamCallbackResult};

// Sample format
pub type PaSampleFormat = u64;
pub static PaFloat32: PaSampleFormat = 0x00000001;
pub static PaInt32: PaSampleFormat = 0x00000002;
// pub static PaInt24: PaSampleFormat = 0x00000004;
pub static PaInt16: PaSampleFormat = 0x00000008;
pub static PaInt8: PaSampleFormat = 0x00000010;
pub static PaUInt8: PaSampleFormat = 0x00000020;
pub static PaCustomFormat: PaSampleFormat = 0x00010000;
pub static PaNonInterleaved: PaSampleFormat = 0x80000000;

// Stream flags
pub type PaStreamFlags = u64;
pub static PaNoFlag: PaStreamFlags = 0;
pub static PaClipOff: PaStreamFlags = 0x00000001;
pub static PaDitherOff: PaStreamFlags = 0x00000002;
pub static PaNeverDropInput: PaStreamFlags = 0x00000004;
pub static PaPrimeOutputBuffersUsingStreamCallback: PaStreamFlags = 0x00000008;
pub static PaPlatformSpecificFlags: PaStreamFlags = 0xFFFF0000;

/// Unchanging unique identifiers for each supported host API
pub type PaHostApiTypeId = i32;
pub static PaInDevelopment: PaHostApiTypeId = 0;
pub static PaDirectSound: PaHostApiTypeId = 1;
pub static PaMME: PaHostApiTypeId = 2;
pub static PaASIO: PaHostApiTypeId = 3;
pub static PaSoundManager: PaHostApiTypeId = 4;
pub static PaCoreAudio: PaHostApiTypeId = 5;
pub static PaOSS: PaHostApiTypeId = 7;
pub static PaALSA: PaHostApiTypeId = 8;
pub static PaAL: PaHostApiTypeId = 9;
pub static PaBeOS: PaHostApiTypeId = 10;
pub static PaWDMKS: PaHostApiTypeId = 11;
pub static PaJACK: PaHostApiTypeId = 12;
pub static PaWASAPI: PaHostApiTypeId = 13;
pub static PaAudioScienceHPI: PaHostApiTypeId = 14;

pub type C_PaStream = c_void;

#[repr(C)]
pub struct C_PaStreamParameters {
    pub device : PaDeviceIndex,
    pub channel_count : i32,
    pub sample_format : PaSampleFormat,
    pub suggested_latency : PaTime,
    pub host_api_specific_stream_info : *mut c_void
}

#[repr(C)]
pub struct C_PaDeviceInfo {
    pub struct_version: i32,
    pub name: *const c_char,
    pub host_api: PaHostApiIndex,
    pub max_input_channels: i32,
    pub max_output_channels: i32,
    pub default_low_input_latency: PaTime,
    pub default_low_output_latency: PaTime,
    pub default_high_input_latency: PaTime,
    pub default_high_output_latency: PaTime,
    pub default_sample_rate: c_double
}

#[repr(C)]
pub struct C_PaHostErrorInfo {
    pub error_code: u32,
    pub error_text: *const c_char
}

#[repr(C)]
pub struct C_PaHostApiInfo {
    pub struct_version: i32,
    pub host_type: i32,
    pub name: *const c_char,
    pub device_count: i32,
    pub default_input_device: i32,
    pub default_output_device: i32
}

extern "C" {

    /// PortAudio portable API

    pub fn Pa_GetVersion() -> i32;
    pub fn Pa_GetVersionText() -> *const c_char;
    pub fn Pa_GetErrorText(errorCode : PaError) -> *const c_char;
    pub fn Pa_Initialize() -> PaError;
    pub fn Pa_Terminate() -> PaError;
    pub fn Pa_GetHostApiCount() -> PaHostApiIndex;
    pub fn Pa_GetDefaultHostApi() -> PaHostApiIndex;
    pub fn Pa_GetHostApiInfo(hostApi : PaHostApiIndex) -> *const C_PaHostApiInfo;
    pub fn Pa_HostApiTypeIdToHostApiIndex(type_id : PaHostApiTypeId) -> PaHostApiIndex;
    pub fn Pa_HostApiDeviceIndexToDeviceIndex(hostApi : PaHostApiIndex, hostApiDeviceIndex : i32) -> PaDeviceIndex;
    pub fn Pa_GetLastHostErrorInfo() -> *const C_PaHostErrorInfo;
    pub fn Pa_GetDeviceCount() -> PaDeviceIndex;
    pub fn Pa_GetDefaultInputDevice() -> PaDeviceIndex;
    pub fn Pa_GetDefaultOutputDevice() -> PaDeviceIndex;
    pub fn Pa_GetDeviceInfo(device : PaDeviceIndex) -> *const C_PaDeviceInfo;
    pub fn Pa_IsFormatSupported(input_parameters : *const C_PaStreamParameters, outputParameters : *const C_PaStreamParameters, sampleRate : c_double) -> PaError;
    pub fn Pa_GetSampleSize(format : PaSampleFormat) -> PaError;
    pub fn Pa_Sleep(msec : i32) -> ();
    pub fn Pa_OpenStream(stream : *mut *mut C_PaStream,
                         inputParameters : *const C_PaStreamParameters,
                         outputParameters : *const C_PaStreamParameters,
                         sampleRate : c_double,
                         framesPerBuffer : u32,
                         streamFlags : PaStreamFlags,
                         streamCallback : Option<extern "C" fn(*const c_void, *mut c_void, u32, *const PaStreamCallbackTimeInfo, PaStreamCallbackFlags, *mut c_void) -> PaStreamCallbackResult>,
                         userData : *mut c_void)
                         -> PaError;
    pub fn Pa_OpenDefaultStream(stream : *mut *mut C_PaStream,
                                numInputChannels : i32,
                                numOutputChannels : i32,
                                sampleFormat : PaSampleFormat,
                                sampleRate : c_double,
                                framesPerBuffer : u32,
                                streamCallback : Option<extern "C" fn(*const c_void, *mut c_void, u32, *const PaStreamCallbackTimeInfo, PaStreamCallbackFlags, *mut c_void) -> PaStreamCallbackResult>,
                                userData : *mut c_void)
                                -> PaError;
    pub fn Pa_CloseStream(stream : *mut C_PaStream) -> PaError;
    //pub fn Pa_SetStreamFinishedCallback (stream : *PaStream, PaStreamFinishedCallback *streamFinishedCallback) -> PaError;
    pub fn Pa_StartStream(stream : *mut C_PaStream) -> PaError;
    pub fn Pa_StopStream(stream : *mut C_PaStream) -> PaError;
    pub fn Pa_AbortStream(stream : *mut C_PaStream) -> PaError;
    pub fn Pa_IsStreamStopped(stream : *mut C_PaStream) -> PaError;
    pub fn Pa_IsStreamActive(stream : *mut C_PaStream) -> i32;
    pub fn Pa_GetStreamInfo(stream : *mut C_PaStream) -> *const PaStreamInfo;
    pub fn Pa_GetStreamTime(stream : *mut C_PaStream) -> PaTime;
    pub fn Pa_GetStreamCpuLoad(stream : *mut C_PaStream) -> c_double;
    pub fn Pa_ReadStream(stream : *mut C_PaStream, buffer : *mut c_void, frames : u32) -> PaError;
    pub fn Pa_WriteStream(stream : *mut C_PaStream, buffer : *mut c_void, frames : u32) -> PaError;
    pub fn Pa_GetStreamReadAvailable(stream : *mut C_PaStream) -> i64;
    pub fn Pa_GetStreamWriteAvailable(stream : *mut C_PaStream) -> i64;

    /*
    * PortAudio Specific ASIO
    */
    pub fn PaAsio_GetAvailableBufferSizes(device : PaDeviceIndex, minBufferSizeFrames : *mut i32, maxBufferSizeFrames : *mut i32, preferredBufferSizeFrames : *mut i32, granularity : *mut i32) -> PaError;
    pub fn PaAsio_GetInputChannelName(device : PaDeviceIndex, channelIndex : i32, channelName : *mut *const c_char) -> PaError;
    pub fn PaAsio_GetOutputChannelName(device : PaDeviceIndex, channelIndex : i32, channelName : *mut *const c_char) -> PaError;
    pub fn PaAsio_SetStreamSampleRate(stream : *mut C_PaStream, sampleRate : c_double) -> PaError;

    /*
    * PortAudio Specific MAC_CORE
    */
    pub fn PaMacCore_GetStreamInputDevice(s : *mut C_PaStream) -> PaDeviceIndex;
    pub fn PaMacCore_GetStreamOutputDevice(s : *mut C_PaStream) -> PaDeviceIndex;
    // pub fn PaMacCore_GetChannelName (int device, int channelIndex, bool intput) -> *c_char
    pub fn PaMacCore_GetBufferSizeRange(device : PaDeviceIndex, minBufferSizeFrames : *mut u32, maxBufferSizeFrames : *mut u32) -> PaError;
    //pub fn PaMacCore_SetupStreamInfo(PaMacCoreStreamInfo *data, unsigned long flags) -> ();
    //pub fn PaMacCore_SetupChannelMap(PaMacCoreStreamInfo *data, const SInt32 *const channelMap, unsigned long channelMapSize) -> ();
}
<commit_msg>Updated to latest rustc (switched statics to const)<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2013 Jeremy Letang (letang.jeremy@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#![allow(dead_code, non_camel_case_types)]

use libc::{c_char, c_double, c_void};

use types::{PaError, PaDeviceIndex, PaHostApiIndex, PaStreamCallbackFlags,
    PaStreamCallbackTimeInfo, PaStreamInfo, PaTime, PaStreamCallbackResult};

// Sample format
pub type PaSampleFormat = u64;
pub const PaFloat32: PaSampleFormat = 0x00000001;
pub const PaInt32: PaSampleFormat = 0x00000002;
// pub const PaInt24: PaSampleFormat = 0x00000004;
pub const PaInt16: PaSampleFormat = 0x00000008;
pub const PaInt8: PaSampleFormat = 0x00000010;
pub const PaUInt8: PaSampleFormat = 0x00000020;
pub const PaCustomFormat: PaSampleFormat = 0x00010000;
pub const PaNonInterleaved: PaSampleFormat = 0x80000000;

// Stream flags
pub type PaStreamFlags = u64;
pub const PaNoFlag: PaStreamFlags = 0;
pub const PaClipOff: PaStreamFlags = 0x00000001;
pub const PaDitherOff: PaStreamFlags = 0x00000002;
pub const PaNeverDropInput: PaStreamFlags = 0x00000004;
pub const PaPrimeOutputBuffersUsingStreamCallback: PaStreamFlags = 0x00000008;
pub const PaPlatformSpecificFlags: PaStreamFlags = 0xFFFF0000;

/// Unchanging unique identifiers for each supported host API
pub type PaHostApiTypeId = i32;
pub const PaInDevelopment: PaHostApiTypeId = 0;
pub const PaDirectSound: PaHostApiTypeId = 1;
pub const PaMME: PaHostApiTypeId = 2;
pub const PaASIO: PaHostApiTypeId = 3;
pub const PaSoundManager: PaHostApiTypeId = 4;
pub const PaCoreAudio: PaHostApiTypeId = 5;
pub const PaOSS: PaHostApiTypeId = 7;
pub const PaALSA: PaHostApiTypeId = 8;
pub const PaAL: PaHostApiTypeId = 9;
pub const PaBeOS: PaHostApiTypeId = 10;
pub const PaWDMKS: PaHostApiTypeId = 11;
pub const PaJACK: PaHostApiTypeId = 12;
pub const PaWASAPI: PaHostApiTypeId = 13;
pub const PaAudioScienceHPI: PaHostApiTypeId = 14;

pub type C_PaStream = c_void;

#[repr(C)]
pub struct C_PaStreamParameters {
    pub device : PaDeviceIndex,
    pub channel_count : i32,
    pub sample_format : PaSampleFormat,
    pub suggested_latency : PaTime,
    pub host_api_specific_stream_info : *mut c_void
}

#[repr(C)]
pub struct C_PaDeviceInfo {
    pub struct_version: i32,
    pub name: *const c_char,
    pub host_api: PaHostApiIndex,
    pub max_input_channels: i32,
    pub max_output_channels: i32,
    pub default_low_input_latency: PaTime,
    pub default_low_output_latency: PaTime,
    pub default_high_input_latency: PaTime,
    pub default_high_output_latency: PaTime,
    pub default_sample_rate: c_double
}

#[repr(C)]
pub struct C_PaHostErrorInfo {
    pub error_code: u32,
    pub error_text: *const c_char
}

#[repr(C)]
pub struct C_PaHostApiInfo {
    pub struct_version: i32,
    pub host_type: i32,
    pub name: *const c_char,
    pub device_count: i32,
    pub default_input_device: i32,
    pub default_output_device: i32
}

extern "C" {

    /// PortAudio portable API

    pub fn Pa_GetVersion() -> i32;
    pub fn Pa_GetVersionText() -> *const c_char;
    pub fn Pa_GetErrorText(errorCode : PaError) -> *const c_char;
    pub fn Pa_Initialize() -> PaError;
    pub fn Pa_Terminate() -> PaError;
    pub fn Pa_GetHostApiCount() -> PaHostApiIndex;
    pub fn Pa_GetDefaultHostApi() -> PaHostApiIndex;
    pub fn Pa_GetHostApiInfo(hostApi : PaHostApiIndex) -> *const C_PaHostApiInfo;
    pub fn Pa_HostApiTypeIdToHostApiIndex(type_id : PaHostApiTypeId) -> PaHostApiIndex;
    pub fn Pa_HostApiDeviceIndexToDeviceIndex(hostApi : PaHostApiIndex, hostApiDeviceIndex : i32) -> PaDeviceIndex;
    pub fn Pa_GetLastHostErrorInfo() -> *const C_PaHostErrorInfo;
    pub fn Pa_GetDeviceCount() -> PaDeviceIndex;
    pub fn Pa_GetDefaultInputDevice() -> PaDeviceIndex;
    pub fn Pa_GetDefaultOutputDevice() -> PaDeviceIndex;
    pub fn Pa_GetDeviceInfo(device : PaDeviceIndex) -> *const C_PaDeviceInfo;
    pub fn Pa_IsFormatSupported(input_parameters : *const C_PaStreamParameters, outputParameters : *const C_PaStreamParameters, sampleRate : c_double) -> PaError;
    pub fn Pa_GetSampleSize(format : PaSampleFormat) -> PaError;
    pub fn Pa_Sleep(msec : i32) -> ();
    pub fn Pa_OpenStream(stream : *mut *mut C_PaStream,
                         inputParameters : *const C_PaStreamParameters,
                         outputParameters : *const C_PaStreamParameters,
                         sampleRate : c_double,
                         framesPerBuffer : u32,
                         streamFlags : PaStreamFlags,
                         streamCallback : Option<extern "C" fn(*const c_void, *mut c_void, u32, *const PaStreamCallbackTimeInfo, PaStreamCallbackFlags, *mut c_void) -> PaStreamCallbackResult>,
                         userData : *mut c_void)
                         -> PaError;
    pub fn Pa_OpenDefaultStream(stream : *mut *mut C_PaStream,
                                numInputChannels : i32,
                                numOutputChannels : i32,
                                sampleFormat : PaSampleFormat,
                                sampleRate : c_double,
                                framesPerBuffer : u32,
                                streamCallback : Option<extern "C" fn(*const c_void, *mut c_void, u32, *const PaStreamCallbackTimeInfo, PaStreamCallbackFlags, *mut c_void) -> PaStreamCallbackResult>,
                                userData : *mut c_void)
                                -> PaError;
    pub fn Pa_CloseStream(stream : *mut C_PaStream) -> PaError;
    //pub fn Pa_SetStreamFinishedCallback (stream : *PaStream, PaStreamFinishedCallback *streamFinishedCallback) -> PaError;
    pub fn Pa_StartStream(stream : *mut C_PaStream) -> PaError;
    pub fn Pa_StopStream(stream : *mut C_PaStream) -> PaError;
    pub fn Pa_AbortStream(stream : *mut C_PaStream) -> PaError;
    pub fn Pa_IsStreamStopped(stream : *mut C_PaStream) -> PaError;
    pub fn Pa_IsStreamActive(stream : *mut C_PaStream) -> i32;
    pub fn Pa_GetStreamInfo(stream : *mut C_PaStream) -> *const PaStreamInfo;
    pub fn Pa_GetStreamTime(stream : *mut C_PaStream) -> PaTime;
    pub fn Pa_GetStreamCpuLoad(stream : *mut C_PaStream) -> c_double;
    pub fn Pa_ReadStream(stream : *mut C_PaStream, buffer : *mut c_void, frames : u32) -> PaError;
    pub fn Pa_WriteStream(stream : *mut C_PaStream, buffer : *mut c_void, frames : u32) -> PaError;
    pub fn Pa_GetStreamReadAvailable(stream : *mut C_PaStream) -> i64;
    pub fn Pa_GetStreamWriteAvailable(stream : *mut C_PaStream) -> i64;

    /*
    * PortAudio Specific ASIO
    */
    pub fn PaAsio_GetAvailableBufferSizes(device : PaDeviceIndex, minBufferSizeFrames : *mut i32, maxBufferSizeFrames : *mut i32, preferredBufferSizeFrames : *mut i32, granularity : *mut i32) -> PaError;
    pub fn PaAsio_GetInputChannelName(device : PaDeviceIndex, channelIndex : i32, channelName : *mut *const c_char) -> PaError;
    pub fn PaAsio_GetOutputChannelName(device : PaDeviceIndex, channelIndex : i32, channelName : *mut *const c_char) -> PaError;
    pub fn PaAsio_SetStreamSampleRate(stream : *mut C_PaStream, sampleRate : c_double) -> PaError;

    /*
    * PortAudio Specific MAC_CORE
    */
    pub fn PaMacCore_GetStreamInputDevice(s : *mut C_PaStream) -> PaDeviceIndex;
    pub fn PaMacCore_GetStreamOutputDevice(s : *mut C_PaStream) -> PaDeviceIndex;
    // pub fn PaMacCore_GetChannelName (int device, int channelIndex, bool intput) -> *c_char
    pub fn PaMacCore_GetBufferSizeRange(device : PaDeviceIndex, minBufferSizeFrames : *mut u32, maxBufferSizeFrames : *mut u32) -> PaError;
    //pub fn PaMacCore_SetupStreamInfo(PaMacCoreStreamInfo *data, unsigned long flags) -> ();
    //pub fn PaMacCore_SetupChannelMap(PaMacCoreStreamInfo *data, const SInt32 *const channelMap, unsigned long channelMapSize) -> ();
}
<|endoftext|>


<commit_before>//! ByteSize is an utility that easily makes bytes size representation
//! and helps its arithmetic operations.
//!
//! ## Example
//!
//! ```ignore
//! extern crate bytesize;
//!
//! use bytesize::ByteSize;
//!
//! fn byte_arithmetic_operator() {
//!   let x = ByteSize::mb(1);
//!   let y = ByteSize::kb(100);
//!
//!   let plus = x + y;
//!   print!("{} bytes", plus.as_u64());
//!
//!   let minus = ByteSize::tb(100) - ByteSize::gb(4);
//!   print!("{} bytes", minus.as_u64());
//! }
//! ```
//!
//! It also provides its human readable string as follows:
//!
//! ```ignore
//!  assert_eq!("482 GiB".to_string(), ByteSize::gb(518).to_string(true));
//!  assert_eq!("518 GB".to_string(), ByteSize::gb(518).to_string(false));
//! ```

use std::fmt::{Display,Formatter,Result};
use std::ops::{Add,Sub,Mul,Div};

/// byte size for 1 byte
pub static B: u64 = 1;
/// bytes size for 1 kilobyte
pub static KB: u64 = 1000;
/// bytes size for 1 megabyte
pub static MB: u64 = 1000000;
/// bytes size for 1 gigabyte
pub static GB: u64 = 1000000000;
/// bytes size for 1 terabyte
pub static TB: u64 = 1000000000000;
/// bytes size for 1 petabyte
pub static PB: u64 = 1000000000000000;

/// bytes size for 1 kibibyte
pub static KIB: u64 = 1024;
/// bytes size for 1 mebibyte
pub static MIB: u64 = 1048576;
/// bytes size for 1 gibibyte
pub static GIB: u64 = 1073741824;
/// bytes size for 1 tebibyte
pub static TIB: u64 = 1099511627776;
/// bytes size for 1 pebibyte
pub static PIB: u64 = 1125899906842624;

static UNITS:    &'static str = "KMGTPE";
static UNITS_SI: &'static str = "kMGTPE";
static LN_KB:  f64 = 6.931471806; // ln 1024
static LN_KIB: f64 = 6.907755279; // ln 1000

#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Default)]
/// Byte size representation
pub struct ByteSize {
  size: u64
}

impl ByteSize {
  #[inline(always)]
  pub fn b(size: u64) -> ByteSize {
    ByteSize {size: size}
  }

  #[inline(always)]
  pub fn kb(size: u64) -> ByteSize {
    ByteSize {size: size * KB}
  }

  #[inline(always)]
  pub fn kib(size: u64) -> ByteSize {
   ByteSize {size: size * KIB}
  }

  #[inline(always)]
  pub fn mb(size: u64) -> ByteSize {
    ByteSize {size: size * MB}
  }

  #[inline(always)]
  pub fn mib(size: u64) -> ByteSize {
    ByteSize {size: size * MIB}
  }

  #[inline(always)]
  pub fn gb(size: u64) -> ByteSize {
    ByteSize {size: size * GB}
  }

  #[inline(always)]
  pub fn gib(size: u64) -> ByteSize {
    ByteSize {size: size * GIB}
  }

  #[inline(always)]
  pub fn tb(size: u64) -> ByteSize {
    ByteSize {size: size * TB}
  }

  #[inline(always)]
  pub fn tib(size: u64) -> ByteSize {
    ByteSize {size: size * TIB}
  }

  #[inline(always)]
  pub fn pb(size: u64) -> ByteSize {
    ByteSize {size: size * PB}
  }

  #[inline(always)]
  pub fn pib(size: u64) -> ByteSize {
    ByteSize {size: size * PIB}
  }

  #[inline(always)]
  pub fn as_u64(&self) -> u64 {
    self.size
  }

  pub fn to_string(&self, si: bool) -> String {

    let unit = if si { KIB } else { KB };
    let unit_base =  if si { LN_KIB } else { LN_KB };
    let unit_prefix = if si { UNITS_SI.as_bytes() } else { UNITS.as_bytes() };
    let unit_suffix = if si { "iB" } else { "B" };

    if self.size < unit {
      format!("{} B", self.size)

    } else {
      let exp = match ((self.size as f64).ln() / unit_base) as u64 {
        e if e == 0 => 1,
        e => e
      };

      format!("{} {}{}", (self.size / unit.pow(exp as u32)),
        unit_prefix[exp - 1] as char, unit_suffix)
    }
  }
}

impl Display for ByteSize {
  fn fmt(&self, f: &mut Formatter) -> Result {
    write!(f, "{}", self.to_string(false))
  }
}

impl Add<u64> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn add(self, rhs: u64) -> ByteSize {
    ByteSize {size: (self.size + rhs)}
  }
}

impl Add<ByteSize> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn add(self, rhs: ByteSize) -> ByteSize {
    ByteSize {size: (self.size + rhs.size)}
  }
}

impl Sub<u64> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn sub(self, rhs: u64) -> ByteSize {
    ByteSize {size: (self.size - rhs)}
  }
}

impl Sub<ByteSize> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn sub(self, rhs: ByteSize) -> ByteSize {
    ByteSize {size: (self.size - rhs.size)}
  }
}

impl Mul<u64> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn mul(self, rhs: u64) -> ByteSize {
    ByteSize {size: (self.size * rhs)}
  }
}

impl Div<u64> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn div(self, rhs: u64) -> ByteSize {
    ByteSize {size: (self.size / rhs)}
  }
}

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

  #[test]
  fn test_arithmetic() {
    let x = ByteSize::mb(1);
    let y = ByteSize::kb(100);

    assert_eq!(
      (x + y).as_u64(),
      1100000
    );
    assert_eq!(
      (x + (100*1000)).as_u64(),
      1100000
    );

    assert_eq!(
      (x - y).as_u64(),
      900000
    );
    assert_eq!(
      (x - (100*1000)).as_u64(),
      900000
    );
  }

  #[test]
  fn test_comparison() {
    assert!(ByteSize::mb(1) == ByteSize::kb(1000));
    assert!(ByteSize::mib(1) == ByteSize::kib(1024));
    assert!(ByteSize::mb(1) != ByteSize::kib(1024));
    assert!(ByteSize::mb(1) < ByteSize::kib(1024));
    assert!(ByteSize::b(0) < ByteSize::tib(1));
  }

  fn assert_display(expected: &str, b: ByteSize) {
    assert_eq!(expected, format!("{}", b));
  }

  #[test]
  fn test_display() {
    assert_display("215 B", ByteSize::b(215));
    assert_display("1 KB", ByteSize::kb(1));
    assert_display("301 KB", ByteSize::kb(301));
    assert_display("419 MB", ByteSize::mb(419));
    assert_display("518 GB", ByteSize::gb(518));
    assert_display("815 TB", ByteSize::tb(815));
    assert_display("609 PB", ByteSize::pb(609));
  }

  fn assert_to_string(expected: &str, b: ByteSize, si: bool) {
    assert_eq!(expected.to_string(), b.to_string(si));
  }

  #[test]
  fn test_to_string() {
    assert_to_string("215 B", ByteSize::b(215), true);
    assert_to_string("215 B", ByteSize::b(215), false);

    assert_to_string("1 kiB", ByteSize::kib(1), true);
    assert_to_string("1 KB", ByteSize::kib(1), false);

    assert_to_string("293 kiB", ByteSize::kb(301), true);
    assert_to_string("301 KB", ByteSize::kb(301), false);

    assert_to_string("1 MiB", ByteSize::mib(1), true);
    assert_to_string("1048 KB", ByteSize::mib(1), false);

    assert_to_string("399 MiB", ByteSize::mb(419), true);
    assert_to_string("419 MB", ByteSize::mb(419), false);

    assert_to_string("482 GiB", ByteSize::gb(518), true);
    assert_to_string("518 GB", ByteSize::gb(518), false);

    assert_to_string("741 TiB", ByteSize::tb(815), true);
    assert_to_string("815 TB", ByteSize::tb(815), false);

    assert_to_string("540 PiB", ByteSize::pb(609), true);
    assert_to_string("609 PB", ByteSize::pb(609), false);
  }

  #[test]
  fn test_default() {
    assert_eq!(ByteSize::b(0), ByteSize::default());
  }
}
<commit_msg>Reverted overly eager find and replace<commit_after>//! ByteSize is an utility that easily makes bytes size representation
//! and helps its arithmetic operations.
//!
//! ## Example
//!
//! ```ignore
//! extern crate bytesize;
//!
//! use bytesize::ByteSize;
//!
//! fn byte_arithmetic_operator() {
//!   let x = ByteSize::mb(1);
//!   let y = ByteSize::kb(100);
//!
//!   let plus = x + y;
//!   print!("{} bytes", plus.as_u64());
//!
//!   let minus = ByteSize::tb(100) - ByteSize::gb(4);
//!   print!("{} bytes", minus.as_u64());
//! }
//! ```
//!
//! It also provides its human readable string as follows:
//!
//! ```ignore
//!  assert_eq!("482 GiB".to_string(), ByteSize::gb(518).to_string(true));
//!  assert_eq!("518 GB".to_string(), ByteSize::gb(518).to_string(false));
//! ```

use std::fmt::{Display,Formatter,Result};
use std::ops::{Add,Sub,Mul,Div};

/// byte size for 1 byte
pub static B: u64 = 1;
/// bytes size for 1 kilobyte
pub static KB: u64 = 1000;
/// bytes size for 1 megabyte
pub static MB: u64 = 1000000;
/// bytes size for 1 gigabyte
pub static GB: u64 = 1000000000;
/// bytes size for 1 terabyte
pub static TB: u64 = 1000000000000;
/// bytes size for 1 petabyte
pub static PB: u64 = 1000000000000000;

/// bytes size for 1 kibibyte
pub static KIB: u64 = 1024;
/// bytes size for 1 mebibyte
pub static MIB: u64 = 1048576;
/// bytes size for 1 gibibyte
pub static GIB: u64 = 1073741824;
/// bytes size for 1 tebibyte
pub static TIB: u64 = 1099511627776;
/// bytes size for 1 pebibyte
pub static PIB: u64 = 1125899906842624;

static UNITS:    &'static str = "KMGTPE";
static UNITS_SI: &'static str = "kMGTPE";
static LN_KB:  f64 = 6.931471806; // ln 1024
static LN_KIB: f64 = 6.907755279; // ln 1000

#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Default)]
/// Byte size representation
pub struct ByteSize {
  size: u64
}

impl ByteSize {
  #[inline(always)]
  pub fn b(size: u64) -> ByteSize {
    ByteSize {size: size}
  }

  #[inline(always)]
  pub fn kb(size: u64) -> ByteSize {
    ByteSize {size: size * KB}
  }

  #[inline(always)]
  pub fn kib(size: u64) -> ByteSize {
   ByteSize {size: size * KIB}
  }

  #[inline(always)]
  pub fn mb(size: u64) -> ByteSize {
    ByteSize {size: size * MB}
  }

  #[inline(always)]
  pub fn mib(size: u64) -> ByteSize {
    ByteSize {size: size * MIB}
  }

  #[inline(always)]
  pub fn gb(size: u64) -> ByteSize {
    ByteSize {size: size * GB}
  }

  #[inline(always)]
  pub fn gib(size: u64) -> ByteSize {
    ByteSize {size: size * GIB}
  }

  #[inline(always)]
  pub fn tb(size: u64) -> ByteSize {
    ByteSize {size: size * TB}
  }

  #[inline(always)]
  pub fn tib(size: u64) -> ByteSize {
    ByteSize {size: size * TIB}
  }

  #[inline(always)]
  pub fn pb(size: u64) -> ByteSize {
    ByteSize {size: size * PB}
  }

  #[inline(always)]
  pub fn pib(size: u64) -> ByteSize {
    ByteSize {size: size * PIB}
  }

  #[inline(always)]
  pub fn as_u64(&self) -> u64 {
    self.size
  }

  pub fn to_string(&self, si: bool) -> String {

    let unit = if si { KIB } else { KB };
    let unit_base =  if si { LN_KIB } else { LN_KB };
    let unit_prefix = if si { UNITS_SI.as_bytes() } else { UNITS.as_bytes() };
    let unit_suffix = if si { "iB" } else { "B" };

    if self.size < unit {
      format!("{} B", self.size)

    } else {
      let exp = match ((self.size as f64).ln() / unit_base) as usize {
        e if e == 0 => 1,
        e => e
      };

      format!("{} {}{}", (self.size / unit.pow(exp as u32)),
        unit_prefix[exp - 1] as char, unit_suffix)
    }
  }
}

impl Display for ByteSize {
  fn fmt(&self, f: &mut Formatter) -> Result {
    write!(f, "{}", self.to_string(false))
  }
}

impl Add<u64> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn add(self, rhs: u64) -> ByteSize {
    ByteSize {size: (self.size + rhs)}
  }
}

impl Add<ByteSize> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn add(self, rhs: ByteSize) -> ByteSize {
    ByteSize {size: (self.size + rhs.size)}
  }
}

impl Sub<u64> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn sub(self, rhs: u64) -> ByteSize {
    ByteSize {size: (self.size - rhs)}
  }
}

impl Sub<ByteSize> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn sub(self, rhs: ByteSize) -> ByteSize {
    ByteSize {size: (self.size - rhs.size)}
  }
}

impl Mul<u64> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn mul(self, rhs: u64) -> ByteSize {
    ByteSize {size: (self.size * rhs)}
  }
}

impl Div<u64> for ByteSize {
  type Output = ByteSize;

  #[inline(always)]
  fn div(self, rhs: u64) -> ByteSize {
    ByteSize {size: (self.size / rhs)}
  }
}

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

  #[test]
  fn test_arithmetic() {
    let x = ByteSize::mb(1);
    let y = ByteSize::kb(100);

    assert_eq!(
      (x + y).as_u64(),
      1100000
    );
    assert_eq!(
      (x + (100*1000)).as_u64(),
      1100000
    );

    assert_eq!(
      (x - y).as_u64(),
      900000
    );
    assert_eq!(
      (x - (100*1000)).as_u64(),
      900000
    );
  }

  #[test]
  fn test_comparison() {
    assert!(ByteSize::mb(1) == ByteSize::kb(1000));
    assert!(ByteSize::mib(1) == ByteSize::kib(1024));
    assert!(ByteSize::mb(1) != ByteSize::kib(1024));
    assert!(ByteSize::mb(1) < ByteSize::kib(1024));
    assert!(ByteSize::b(0) < ByteSize::tib(1));
  }

  fn assert_display(expected: &str, b: ByteSize) {
    assert_eq!(expected, format!("{}", b));
  }

  #[test]
  fn test_display() {
    assert_display("215 B", ByteSize::b(215));
    assert_display("1 KB", ByteSize::kb(1));
    assert_display("301 KB", ByteSize::kb(301));
    assert_display("419 MB", ByteSize::mb(419));
    assert_display("518 GB", ByteSize::gb(518));
    assert_display("815 TB", ByteSize::tb(815));
    assert_display("609 PB", ByteSize::pb(609));
  }

  fn assert_to_string(expected: &str, b: ByteSize, si: bool) {
    assert_eq!(expected.to_string(), b.to_string(si));
  }

  #[test]
  fn test_to_string() {
    assert_to_string("215 B", ByteSize::b(215), true);
    assert_to_string("215 B", ByteSize::b(215), false);

    assert_to_string("1 kiB", ByteSize::kib(1), true);
    assert_to_string("1 KB", ByteSize::kib(1), false);

    assert_to_string("293 kiB", ByteSize::kb(301), true);
    assert_to_string("301 KB", ByteSize::kb(301), false);

    assert_to_string("1 MiB", ByteSize::mib(1), true);
    assert_to_string("1048 KB", ByteSize::mib(1), false);

    assert_to_string("399 MiB", ByteSize::mb(419), true);
    assert_to_string("419 MB", ByteSize::mb(419), false);

    assert_to_string("482 GiB", ByteSize::gb(518), true);
    assert_to_string("518 GB", ByteSize::gb(518), false);

    assert_to_string("741 TiB", ByteSize::tb(815), true);
    assert_to_string("815 TB", ByteSize::tb(815), false);

    assert_to_string("540 PiB", ByteSize::pb(609), true);
    assert_to_string("609 PB", ByteSize::pb(609), false);
  }

  #[test]
  fn test_default() {
    assert_eq!(ByteSize::b(0), ByteSize::default());
  }
}
<|endoftext|>


<commit_before>//! Manipulations and data types that represent 2d matrix.

#![warn(bad_style, missing_docs,
        unused, unused_extern_crates, unused_import_braces,
        unused_qualifications, unused_results, unused_typecasts)]

extern crate num;

use std::ops::{Add, Index, Mul, Sub};
use num::{One, Zero};

/// 2D matrix.
#[derive(PartialEq, Eq, Clone, Show)]
pub struct Matrix<T> {
    row: usize,
    column: usize,
    data: Vec<T>
}

impl<T> Matrix<T> {
    /// Creates a new `Matrix`.
    #[inline]
    pub fn from_fn<F>(row: usize, column: usize, f: F) -> Matrix<T>
        where F:Fn(usize, usize) -> T
    {
        Matrix {
            row: row,
            column: column,
            data: (0 .. row * column).map(|i| f(i / column, i % column)).collect()
        }
    }

    /// Creates a new `Matrix` from vector.
    #[inline]
    pub fn from_vec(row: usize, column: usize, data: Vec<T>) -> Matrix<T> {
        assert_eq!(row * column, data.len());
        Matrix { row: row, column: column, data: data }
    }

    /// Returns the matrix's row and column.
    #[inline]
    pub fn size(&self) -> (usize, usize) { (self.row(), self.column()) }
    /// Returns the matrix's row.
    #[inline]
    pub fn row(&self) -> usize { self.row }
    /// Returns the matrix's column.
    #[inline]
    pub fn column(&self) -> usize { self.column }
}

impl<T: Zero> Matrix<T> {
    /// Creates a matrix whose elements are all zero.
    #[inline]
    pub fn zero(row: usize, column: usize) -> Matrix<T> {
        Matrix::from_fn(row, column, |_, _| Zero::zero())
    }
}

impl<T: One + Zero> Matrix<T> {
    /// Creates a identity matrix.
    #[inline]
    pub fn one(row: usize, column: usize) -> Matrix<T> {
        Matrix::from_fn(row, column, |i, j| {
            if i == j {
                One::one()
            } else {
                Zero::zero()
            }
        })
    }
}

impl<T: Clone> Matrix<T> {
    #[inline]
    /// Returns transpose of the matrix.
    pub fn trans(&self) -> Matrix<T> {
        Matrix::from_fn(self.column(), self.row(), |i, j| self[(j, i)].clone())
    }
}

impl<T> Index<(usize, usize)> for Matrix<T> {
    type Output = T;

    #[inline]
    fn index(&self, &(i, j): &(usize, usize)) -> &T {
        assert!(i < self.row() && j < self.column());
        &self.data[i * self.column() + j]
    }
}

macro_rules! forward_val_val_binop {
    (impl $imp:ident, $method:ident) => {
        impl<Lhs, Rhs> $imp<Matrix<Rhs>> for Matrix<Lhs>
            where Lhs: $imp<Rhs> + Clone, Rhs: Clone
        {
            type Output = Matrix<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: Matrix<Rhs>) -> Matrix<<Lhs as $imp<Rhs>>::Output> {
                (&self).$method(&other)
            }
        }
    }
}

macro_rules! forward_ref_val_binop {
    (impl $imp:ident, $method:ident) => {
        impl<'a, Lhs, Rhs> $imp<Matrix<Rhs>> for &'a Matrix<Lhs>
            where Lhs: $imp<Rhs> + Clone, Rhs: Clone
        {
            type Output = Matrix<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: Matrix<Rhs>) -> Matrix<<Lhs as $imp<Rhs>>::Output> {
                self.$method(&other)
            }
        }
    }
}

macro_rules! forward_val_ref_binop {
    (impl $imp:ident, $method:ident) => {
        impl<'a, Lhs, Rhs> $imp<&'a Matrix<Rhs>> for Matrix<Lhs>
            where Lhs: $imp<Rhs> + Clone, Rhs: Clone
        {
            type Output = Matrix<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as $imp<Rhs>>::Output> {
                (&self).$method(other)
            }
        }
    }
}

macro_rules! forward_all_binop {
    (impl $imp:ident, $method:ident) => {
        forward_val_val_binop!(impl $imp, $method);
        forward_ref_val_binop!(impl $imp, $method);
        forward_val_ref_binop!(impl $imp, $method);
    };
}

forward_all_binop!(impl Add, add);

impl<'a, 'b, Lhs, Rhs> Add<&'b Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Add<Rhs> + Clone, Rhs: Clone
{
    type Output = Matrix<<Lhs as Add<Rhs>>::Output>;

    #[inline]
    fn add(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Add<Rhs>>::Output> {
        assert_eq!(self.size(), other.size());
        Matrix::from_fn(self.row(), self.column(), |i, j| self[(i, j)].clone() + other[(i, j)].clone())
    }
}

forward_all_binop!(impl Sub, sub);

impl<'a, 'b, Lhs, Rhs> Sub<&'b Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Sub<Rhs> + Clone, Rhs: Clone
{
    type Output = Matrix<<Lhs as Sub<Rhs>>::Output>;

    #[inline]
    fn sub(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Sub<Rhs>>::Output> {
        assert_eq!(self.size(), other.size());
        Matrix::from_fn(self.row(), self.column(), |i, j| self[(i, j)].clone() - other[(i, j)].clone())
    }
}

impl<Lhs, Rhs> Mul<Matrix<Rhs>> for Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: Matrix<Rhs>) -> Matrix<<Lhs as Mul<Rhs>>::Output> {
        (&self).mul(&other)
    }
}

impl<'a, Lhs, Rhs> Mul<Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: Matrix<Rhs>) ->  Matrix<<Lhs as Mul<Rhs>>::Output> {
        self.mul(&other)
    }
}

impl<'a, Lhs, Rhs> Mul<&'a Matrix<Rhs>> for Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Mul<Rhs>>::Output> {
        self.mul(other)
    }
}

impl<'a, 'b, Lhs, Rhs> Mul<&'b Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Mul<Rhs>>::Output> {
        assert_eq!(self.column(), other.row());
        Matrix::from_fn(self.row(), other.column(), |i, j| {
            let mut sum = self[(i, 0)].clone() * other[(0, j)].clone();
            for k in 1 .. self.column() {
                sum = sum + self[(i, k)].clone() * other[(k, j)].clone();
            }
            sum
        })
    }
}

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

    #[test]
    fn from_vec() {
        let mat = Matrix::from_vec(2, 3, vec![(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]);
        for i in 0 .. mat.row() {
            for j in 0 .. mat.column() {
                assert_eq!((i, j), mat[(i, j)]);
            }
        }
    }

    #[test]
    fn index() {
        let mat = Matrix::from_fn(3, 5, |i, j| (i, j));
        for i in 0 .. mat.row() {
            for j in 0 .. mat.column() {
                assert_eq!((i, j), mat[(i, j)]);
            }
        }
    }

    #[test]
    fn mul() {
        let m1 = Matrix::from_vec(1, 3, vec![1.0f64, 2.0, 3.0]);
        let m2 = Matrix::from_vec(3, 1, vec![1.0, 2.0, 3.0]);
        assert_eq!(Matrix::from_vec(1, 1, vec![14.0]), m1 * m2);
        assert_eq!(Matrix::from_vec(3, 1, vec![1.0f64, 4.0, 7.0]),
                   Matrix::from_vec(3, 3, vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]) *
                   Matrix::from_vec(3, 1, vec![1.0, 0.0, 0.0]));
        assert_eq!(Matrix::from_vec(3, 2, vec![1.0f64, 3.0, 4.0, 6.0, 7.0, 9.0]),
                   Matrix::from_vec(3, 3, vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]) *
                   Matrix::from_vec(3, 2, vec![1.0, 0.0, 0.0, 0.0, 0.0, 1.0]));
    }
}

<commit_msg>update to rustc 1.0.0-nightly (ea8b82e90 2015-03-17) (built 2015-03-18)<commit_after>//! Manipulations and data types that represent 2d matrix.

#![warn(bad_style, missing_docs,
        unused, unused_extern_crates, unused_import_braces,
        unused_qualifications, unused_results, unused_typecasts)]

extern crate num;

use std::ops::{Add, Index, Mul, Sub};
use num::{One, Zero};

/// 2D matrix.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Matrix<T> {
    row: usize,
    column: usize,
    data: Vec<T>
}

impl<T> Matrix<T> {
    /// Creates a new `Matrix`.
    #[inline]
    pub fn from_fn<F>(row: usize, column: usize, f: F) -> Matrix<T>
        where F:Fn(usize, usize) -> T
    {
        Matrix {
            row: row,
            column: column,
            data: (0 .. row * column).map(|i| f(i / column, i % column)).collect()
        }
    }

    /// Creates a new `Matrix` from vector.
    #[inline]
    pub fn from_vec(row: usize, column: usize, data: Vec<T>) -> Matrix<T> {
        assert_eq!(row * column, data.len());
        Matrix { row: row, column: column, data: data }
    }

    /// Returns the matrix's row and column.
    #[inline]
    pub fn size(&self) -> (usize, usize) { (self.row(), self.column()) }
    /// Returns the matrix's row.
    #[inline]
    pub fn row(&self) -> usize { self.row }
    /// Returns the matrix's column.
    #[inline]
    pub fn column(&self) -> usize { self.column }
}

impl<T: Zero> Matrix<T> {
    /// Creates a matrix whose elements are all zero.
    #[inline]
    pub fn zero(row: usize, column: usize) -> Matrix<T> {
        Matrix::from_fn(row, column, |_, _| Zero::zero())
    }
}

impl<T: One + Zero> Matrix<T> {
    /// Creates a identity matrix.
    #[inline]
    pub fn one(row: usize, column: usize) -> Matrix<T> {
        Matrix::from_fn(row, column, |i, j| {
            if i == j {
                One::one()
            } else {
                Zero::zero()
            }
        })
    }
}

impl<T: Clone> Matrix<T> {
    #[inline]
    /// Returns transpose of the matrix.
    pub fn trans(&self) -> Matrix<T> {
        Matrix::from_fn(self.column(), self.row(), |i, j| self[(j, i)].clone())
    }
}

impl<T> Index<(usize, usize)> for Matrix<T> {
    type Output = T;

    #[inline]
    fn index(&self, &(i, j): &(usize, usize)) -> &T {
        assert!(i < self.row() && j < self.column());
        &self.data[i * self.column() + j]
    }
}

macro_rules! forward_val_val_binop {
    (impl $imp:ident, $method:ident) => {
        impl<Lhs, Rhs> $imp<Matrix<Rhs>> for Matrix<Lhs>
            where Lhs: $imp<Rhs> + Clone, Rhs: Clone
        {
            type Output = Matrix<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: Matrix<Rhs>) -> Matrix<<Lhs as $imp<Rhs>>::Output> {
                (&self).$method(&other)
            }
        }
    }
}

macro_rules! forward_ref_val_binop {
    (impl $imp:ident, $method:ident) => {
        impl<'a, Lhs, Rhs> $imp<Matrix<Rhs>> for &'a Matrix<Lhs>
            where Lhs: $imp<Rhs> + Clone, Rhs: Clone
        {
            type Output = Matrix<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: Matrix<Rhs>) -> Matrix<<Lhs as $imp<Rhs>>::Output> {
                self.$method(&other)
            }
        }
    }
}

macro_rules! forward_val_ref_binop {
    (impl $imp:ident, $method:ident) => {
        impl<'a, Lhs, Rhs> $imp<&'a Matrix<Rhs>> for Matrix<Lhs>
            where Lhs: $imp<Rhs> + Clone, Rhs: Clone
        {
            type Output = Matrix<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as $imp<Rhs>>::Output> {
                (&self).$method(other)
            }
        }
    }
}

macro_rules! forward_all_binop {
    (impl $imp:ident, $method:ident) => {
        forward_val_val_binop!(impl $imp, $method);
        forward_ref_val_binop!(impl $imp, $method);
        forward_val_ref_binop!(impl $imp, $method);
    };
}

forward_all_binop!(impl Add, add);

impl<'a, 'b, Lhs, Rhs> Add<&'b Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Add<Rhs> + Clone, Rhs: Clone
{
    type Output = Matrix<<Lhs as Add<Rhs>>::Output>;

    #[inline]
    fn add(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Add<Rhs>>::Output> {
        assert_eq!(self.size(), other.size());
        Matrix::from_fn(self.row(), self.column(), |i, j| self[(i, j)].clone() + other[(i, j)].clone())
    }
}

forward_all_binop!(impl Sub, sub);

impl<'a, 'b, Lhs, Rhs> Sub<&'b Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Sub<Rhs> + Clone, Rhs: Clone
{
    type Output = Matrix<<Lhs as Sub<Rhs>>::Output>;

    #[inline]
    fn sub(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Sub<Rhs>>::Output> {
        assert_eq!(self.size(), other.size());
        Matrix::from_fn(self.row(), self.column(), |i, j| self[(i, j)].clone() - other[(i, j)].clone())
    }
}

impl<Lhs, Rhs> Mul<Matrix<Rhs>> for Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: Matrix<Rhs>) -> Matrix<<Lhs as Mul<Rhs>>::Output> {
        (&self).mul(&other)
    }
}

impl<'a, Lhs, Rhs> Mul<Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: Matrix<Rhs>) ->  Matrix<<Lhs as Mul<Rhs>>::Output> {
        self.mul(&other)
    }
}

impl<'a, Lhs, Rhs> Mul<&'a Matrix<Rhs>> for Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Mul<Rhs>>::Output> {
        self.mul(other)
    }
}

impl<'a, 'b, Lhs, Rhs> Mul<&'b Matrix<Rhs>> for &'a Matrix<Lhs>
    where Lhs: Mul<Rhs> + Clone, Rhs: Clone,
          <Lhs as Mul<Rhs>>::Output: Add<Output = <Lhs as Mul<Rhs>>::Output>
{
    type Output = Matrix<<Lhs as Mul<Rhs>>::Output>;

    #[inline]
    fn mul(self, other: &Matrix<Rhs>) -> Matrix<<Lhs as Mul<Rhs>>::Output> {
        assert_eq!(self.column(), other.row());
        Matrix::from_fn(self.row(), other.column(), |i, j| {
            let mut sum = self[(i, 0)].clone() * other[(0, j)].clone();
            for k in 1 .. self.column() {
                sum = sum + self[(i, k)].clone() * other[(k, j)].clone();
            }
            sum
        })
    }
}

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

    #[test]
    fn from_vec() {
        let mat = Matrix::from_vec(2, 3, vec![(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]);
        for i in 0 .. mat.row() {
            for j in 0 .. mat.column() {
                assert_eq!((i, j), mat[(i, j)]);
            }
        }
    }

    #[test]
    fn index() {
        let mat = Matrix::from_fn(3, 5, |i, j| (i, j));
        for i in 0 .. mat.row() {
            for j in 0 .. mat.column() {
                assert_eq!((i, j), mat[(i, j)]);
            }
        }
    }

    #[test]
    fn mul() {
        let m1 = Matrix::from_vec(1, 3, vec![1.0f64, 2.0, 3.0]);
        let m2 = Matrix::from_vec(3, 1, vec![1.0, 2.0, 3.0]);
        assert_eq!(Matrix::from_vec(1, 1, vec![14.0]), m1 * m2);
        assert_eq!(Matrix::from_vec(3, 1, vec![1.0f64, 4.0, 7.0]),
                   Matrix::from_vec(3, 3, vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]) *
                   Matrix::from_vec(3, 1, vec![1.0, 0.0, 0.0]));
        assert_eq!(Matrix::from_vec(3, 2, vec![1.0f64, 3.0, 4.0, 6.0, 7.0, 9.0]),
                   Matrix::from_vec(3, 3, vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]) *
                   Matrix::from_vec(3, 2, vec![1.0, 0.0, 0.0, 0.0, 0.0, 1.0]));
    }
}

<|endoftext|>