<commit_before>use std::fmt;
use std::ops;
use std::num::{Zero, One};
use std::cmp::{PartialEq, PartialOrd};
use asexp::Sexp;

pub trait NumType: fmt::Debug+Copy+Clone+Zero+One+ops::Add<Output=Self>+ops::Sub<Output=Self>+ops::Mul<Output=Self>+ops::Div<Output=Self>+PartialEq+PartialOrd+Default+Into<Sexp> {}
impl NumType for f32 {}
impl NumType for f64 {}
impl NumType for u32 {}
impl NumType for u64 {}

#[derive(Debug, Eq, PartialEq)]
pub enum ExprError {
    /// In case of division by zero.
    DivByZero,
    /// When the argument position `n` in Arg(n) is out of bounds.
    InvalidArg,
    /// In case of an invalid operation.
    InvalidOperation,
}

/// An expression evaluates to a numeric value of `NumType`.
#[derive(Clone, PartialEq, Eq)]
pub enum Expr<T: NumType> {
    Const(T),
    // References an actual Argument by position
    Arg(usize),
    Add(Box<Expr<T>>, Box<Expr<T>>),
    Sub(Box<Expr<T>>, Box<Expr<T>>),
    Mul(Box<Expr<T>>, Box<Expr<T>>),
    Div(Box<Expr<T>>, Box<Expr<T>>),

    // Safe division with x/0 = 0.0
    Divz(Box<Expr<T>>, Box<Expr<T>>),

    // Reciprocal (1 / x).
    Recip(Box<Expr<T>>),

    // Reciprocal using safe division
    Recipz(Box<Expr<T>>),
}

impl<'a, T: NumType> Into<Sexp> for &'a Expr<T> {
    fn into(self) -> Sexp {
        match self {
            &Expr::Const(n) => n.into(),
            &Expr::Arg(n) => Sexp::from(("@", n)),
            &Expr::Add(ref a, ref b) => {
                Sexp::from(("+",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
            &Expr::Sub(ref a, ref b) => {
                Sexp::from(("-",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
            &Expr::Mul(ref a, ref b) => {
                Sexp::from(("*",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
            &Expr::Div(ref a, ref b) => {
                Sexp::from(("/",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
            &Expr::Divz(ref a, ref b) => {
                Sexp::from(("divz",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
            &Expr::Recip(ref a) => Sexp::from(("recip", Into::<Sexp>::into(a.as_ref()))),
            &Expr::Recipz(ref a) => Sexp::from(("recipz", Into::<Sexp>::into(a.as_ref()))),
        }
    }
}

impl<T: NumType> fmt::Debug for Expr<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Expr::Const(ref c) => write!(f, "{:?}", c),
            &Expr::Arg(num) => write!(f, "a{}", num),
            &Expr::Add(ref op1, ref op2) => write!(f, "({:?}+{:?})", op1, op2),
            &Expr::Sub(ref op1, ref op2) => write!(f, "({:?}-{:?})", op1, op2),
            &Expr::Mul(ref op1, ref op2) => write!(f, "{:?}*{:?}", op1, op2),
            &Expr::Div(ref op1, ref op2) => write!(f, "{:?}/{:?}", op1, op2),
            &Expr::Divz(ref op1, ref op2) => write!(f, "{:?}\\{:?}", op1, op2),
            &Expr::Recip(ref op) => write!(f, "{:?}/{:?}", T::one(), op),
            &Expr::Recipz(ref op) => write!(f, "{:?}\\{:?}", T::one(), op),
        }
    }
}

impl<T: NumType> Expr<T> {
    pub fn value(&self) -> Result<T, ExprError> {
        if let &Expr::Const(ref c) = self {
            Ok(c.clone())
        } else {
            Err(ExprError::InvalidArg)
        }
    }

    pub fn evaluate(&self, args: &[Expr<T>]) -> Result<T, ExprError> {
        Ok(match *self {
            Expr::Arg(n) => try!(try!(args.get(n).ok_or(ExprError::InvalidArg)).value()),
            Expr::Const(ref c) => c.clone(),
            Expr::Add(ref e1, ref e2) => try!(e1.evaluate(args)) + try!(e2.evaluate(args)),
            Expr::Sub(ref e1, ref e2) => try!(e1.evaluate(args)) - try!(e2.evaluate(args)),
            Expr::Mul(ref e1, ref e2) => try!(e1.evaluate(args)) * try!(e2.evaluate(args)),
            Expr::Div(ref e1, ref e2) => {
                let a = try!(e1.evaluate(args));
                let div = try!(e2.evaluate(args));
                if div == T::zero() {
                    return Err(ExprError::DivByZero);
                }
                a / div
            }
            Expr::Divz(ref e1, ref e2) => {
                let a = try!(e1.evaluate(args));
                let div = try!(e2.evaluate(args));
                if div == T::zero() {
                    div
                } else {
                    a / div
                }
            }
            Expr::Recip(ref e1) => {
                let div = try!(e1.evaluate(args));
                if div == T::zero() {
                    return Err(ExprError::DivByZero);
                } else {
                    T::one() / div
                }
            }
            Expr::Recipz(ref e1) => {
                let div = try!(e1.evaluate(args));
                if div == T::zero() {
                    div
                } else {
                    T::one() / div
                }
            }
        })
    }
}

/// A condition evaluates to either `true` or `false`.
#[derive(Debug, Clone)]
pub enum Condition<T: NumType> {
    True,
    False,
    Not(Box<Condition<T>>),
    And(Box<Condition<T>>, Box<Condition<T>>),
    Or(Box<Condition<T>>, Box<Condition<T>>),

    /// If two expressions are equal
    Equal(Box<Expr<T>>, Box<Expr<T>>),

    Less(Box<Expr<T>>, Box<Expr<T>>),
    Greater(Box<Expr<T>>, Box<Expr<T>>),

    LessEqual(Box<Expr<T>>, Box<Expr<T>>),
    GreaterEqual(Box<Expr<T>>, Box<Expr<T>>),
}

impl<'a, T: NumType> Into<Sexp> for &'a Condition<T> {
    fn into(self) -> Sexp {
        match self {
            &Condition::True => Sexp::from("true"),
            &Condition::False => Sexp::from("false"),
            &Condition::Not(ref a) => Sexp::from(("not", Into::<Sexp>::into(a.as_ref()))),
            &Condition::And(ref a, ref b) => {
                Sexp::from(("and",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
            &Condition::Or(ref a, ref b) => {
                Sexp::from(("or",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
            &Condition::Equal(ref a, ref b) => {
                Sexp::from(("==",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
            &Condition::Less(ref a, ref b) => {
                Sexp::from(("<",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
            &Condition::Greater(ref a, ref b) => {
                Sexp::from((">",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
            &Condition::LessEqual(ref a, ref b) => {
                Sexp::from(("<=",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
            &Condition::GreaterEqual(ref a, ref b) => {
                Sexp::from((">=",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
        }
    }
}

impl<T: NumType> Condition<T> {
    pub fn evaluate(&self, args: &[Expr<T>]) -> Result<bool, ExprError> {
        Ok(match *self {
            Condition::True => true,
            Condition::False => false,
            Condition::Not(ref c) => !try!(c.evaluate(args)),
            Condition::And(ref c1, ref c2) => try!(c1.evaluate(args)) && try!(c2.evaluate(args)),
            Condition::Or(ref c1, ref c2) => try!(c1.evaluate(args)) || try!(c2.evaluate(args)),
            Condition::Equal(ref e1, ref e2) => try!(e1.evaluate(args)) == try!(e2.evaluate(args)),
            Condition::Less(ref e1, ref e2) => try!(e1.evaluate(args)) < try!(e2.evaluate(args)),
            Condition::Greater(ref e1, ref e2) => try!(e1.evaluate(args)) > try!(e2.evaluate(args)),
            Condition::LessEqual(ref e1, ref e2) => {
                try!(e1.evaluate(args)) <= try!(e2.evaluate(args))
            }
            Condition::GreaterEqual(ref e1, ref e2) => {
                try!(e1.evaluate(args)) >= try!(e2.evaluate(args))
            }
        })
    }
}

#[test]
fn test_expr_divz() {
    let expr = Expr::Divz(box Expr::Const(1.0), box Expr::Const(0.0));
    assert_eq!(Ok(0.0), expr.evaluate(&[]));
}

#[test]
fn test_expr_recipz() {
    let expr = Expr::Recipz(box Expr::Const(0.0));
    assert_eq!(Ok(0.0), expr.evaluate(&[]));

    let expr = Expr::Recipz(box Expr::Const(1.0));
    assert_eq!(Ok(1.0), expr.evaluate(&[]));

    let expr = Expr::Recipz(box Expr::Const(0.5));
    assert_eq!(Ok(2.0), expr.evaluate(&[]));
}

#[test]
fn test_expr() {
    let expr = Expr::Sub(box Expr::Const(0.0),
                         box Expr::Div(box Expr::Mul(box Expr::Add(box Expr::Const(1.0),
                                                                   box Expr::Arg(0)),
                                                     box Expr::Arg(1)),
                                       box Expr::Const(2.0)));

    fn fun(a: f32, b: f32) -> f32 {
        0.0 - ((1.0 + a) * b) / 2.0
    }

    fn check(expr: &Expr<f32>, a: f32, b: f32) {
        assert_eq!(Ok(fun(a, b)),
                   expr.evaluate(&[Expr::Const(a), Expr::Const(b)]))
    }

    check(&expr, 123.0, 4444.0);
    check(&expr, 0.0, -12.0);
}

#[test]
fn test_condition() {
    let cond = Condition::Greater(box Expr::Arg(0), box Expr::Const(0.0));

    fn fun(a: f32) -> bool {
        a > 0.0
    }

    fn check(cond: &Condition<f32>, a: f32) {
        assert_eq!(Ok(fun(a)), cond.evaluate(&[Expr::Const(a)]))
    }

    check(&cond, 123.0);
    check(&cond, 0.0);
    check(&cond, -1.4);

    assert_eq!(Ok(true), (Condition::True::<f32>).evaluate(&[]));
}
<commit_msg>Format Expr::Arg as $n<commit_after>use std::fmt;
use std::ops;
use std::num::{Zero, One};
use std::cmp::{PartialEq, PartialOrd};
use asexp::Sexp;

pub trait NumType: fmt::Debug+Copy+Clone+Zero+One+ops::Add<Output=Self>+ops::Sub<Output=Self>+ops::Mul<Output=Self>+ops::Div<Output=Self>+PartialEq+PartialOrd+Default+Into<Sexp> {}
impl NumType for f32 {}
impl NumType for f64 {}
impl NumType for u32 {}
impl NumType for u64 {}

#[derive(Debug, Eq, PartialEq)]
pub enum ExprError {
    /// In case of division by zero.
    DivByZero,
    /// When the argument position `n` in Arg(n) is out of bounds.
    InvalidArg,
    /// In case of an invalid operation.
    InvalidOperation,
}

/// An expression evaluates to a numeric value of `NumType`.
#[derive(Clone, PartialEq, Eq)]
pub enum Expr<T: NumType> {
    Const(T),
    // References an actual Argument by position
    Arg(usize),
    Add(Box<Expr<T>>, Box<Expr<T>>),
    Sub(Box<Expr<T>>, Box<Expr<T>>),
    Mul(Box<Expr<T>>, Box<Expr<T>>),
    Div(Box<Expr<T>>, Box<Expr<T>>),

    // Safe division with x/0 = 0.0
    Divz(Box<Expr<T>>, Box<Expr<T>>),

    // Reciprocal (1 / x).
    Recip(Box<Expr<T>>),

    // Reciprocal using safe division
    Recipz(Box<Expr<T>>),
}

impl<'a, T: NumType> Into<Sexp> for &'a Expr<T> {
    fn into(self) -> Sexp {
        match self {
            &Expr::Const(n) => n.into(),
            &Expr::Arg(n) => Sexp::from(format!("${}", n)),
            &Expr::Add(ref a, ref b) => {
                Sexp::from(("+",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
            &Expr::Sub(ref a, ref b) => {
                Sexp::from(("-",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
            &Expr::Mul(ref a, ref b) => {
                Sexp::from(("*",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
            &Expr::Div(ref a, ref b) => {
                Sexp::from(("/",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
            &Expr::Divz(ref a, ref b) => {
                Sexp::from(("divz",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
            &Expr::Recip(ref a) => Sexp::from(("recip", Into::<Sexp>::into(a.as_ref()))),
            &Expr::Recipz(ref a) => Sexp::from(("recipz", Into::<Sexp>::into(a.as_ref()))),
        }
    }
}

impl<T: NumType> fmt::Debug for Expr<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Expr::Const(ref c) => write!(f, "{:?}", c),
            &Expr::Arg(num) => write!(f, "${}", num),
            &Expr::Add(ref op1, ref op2) => write!(f, "({:?}+{:?})", op1, op2),
            &Expr::Sub(ref op1, ref op2) => write!(f, "({:?}-{:?})", op1, op2),
            &Expr::Mul(ref op1, ref op2) => write!(f, "{:?}*{:?}", op1, op2),
            &Expr::Div(ref op1, ref op2) => write!(f, "{:?}/{:?}", op1, op2),
            &Expr::Divz(ref op1, ref op2) => write!(f, "{:?}\\{:?}", op1, op2),
            &Expr::Recip(ref op) => write!(f, "{:?}/{:?}", T::one(), op),
            &Expr::Recipz(ref op) => write!(f, "{:?}\\{:?}", T::one(), op),
        }
    }
}

impl<T: NumType> Expr<T> {
    pub fn value(&self) -> Result<T, ExprError> {
        if let &Expr::Const(ref c) = self {
            Ok(c.clone())
        } else {
            Err(ExprError::InvalidArg)
        }
    }

    pub fn evaluate(&self, args: &[Expr<T>]) -> Result<T, ExprError> {
        Ok(match *self {
            Expr::Arg(n) => try!(try!(args.get(n).ok_or(ExprError::InvalidArg)).value()),
            Expr::Const(ref c) => c.clone(),
            Expr::Add(ref e1, ref e2) => try!(e1.evaluate(args)) + try!(e2.evaluate(args)),
            Expr::Sub(ref e1, ref e2) => try!(e1.evaluate(args)) - try!(e2.evaluate(args)),
            Expr::Mul(ref e1, ref e2) => try!(e1.evaluate(args)) * try!(e2.evaluate(args)),
            Expr::Div(ref e1, ref e2) => {
                let a = try!(e1.evaluate(args));
                let div = try!(e2.evaluate(args));
                if div == T::zero() {
                    return Err(ExprError::DivByZero);
                }
                a / div
            }
            Expr::Divz(ref e1, ref e2) => {
                let a = try!(e1.evaluate(args));
                let div = try!(e2.evaluate(args));
                if div == T::zero() {
                    div
                } else {
                    a / div
                }
            }
            Expr::Recip(ref e1) => {
                let div = try!(e1.evaluate(args));
                if div == T::zero() {
                    return Err(ExprError::DivByZero);
                } else {
                    T::one() / div
                }
            }
            Expr::Recipz(ref e1) => {
                let div = try!(e1.evaluate(args));
                if div == T::zero() {
                    div
                } else {
                    T::one() / div
                }
            }
        })
    }
}

/// A condition evaluates to either `true` or `false`.
#[derive(Debug, Clone)]
pub enum Condition<T: NumType> {
    True,
    False,
    Not(Box<Condition<T>>),
    And(Box<Condition<T>>, Box<Condition<T>>),
    Or(Box<Condition<T>>, Box<Condition<T>>),

    /// If two expressions are equal
    Equal(Box<Expr<T>>, Box<Expr<T>>),

    Less(Box<Expr<T>>, Box<Expr<T>>),
    Greater(Box<Expr<T>>, Box<Expr<T>>),

    LessEqual(Box<Expr<T>>, Box<Expr<T>>),
    GreaterEqual(Box<Expr<T>>, Box<Expr<T>>),
}

impl<'a, T: NumType> Into<Sexp> for &'a Condition<T> {
    fn into(self) -> Sexp {
        match self {
            &Condition::True => Sexp::from("true"),
            &Condition::False => Sexp::from("false"),
            &Condition::Not(ref a) => Sexp::from(("not", Into::<Sexp>::into(a.as_ref()))),
            &Condition::And(ref a, ref b) => {
                Sexp::from(("and",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
            &Condition::Or(ref a, ref b) => {
                Sexp::from(("or",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
            &Condition::Equal(ref a, ref b) => {
                Sexp::from(("==",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
            &Condition::Less(ref a, ref b) => {
                Sexp::from(("<",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
            &Condition::Greater(ref a, ref b) => {
                Sexp::from((">",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
            &Condition::LessEqual(ref a, ref b) => {
                Sexp::from(("<=",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
            &Condition::GreaterEqual(ref a, ref b) => {
                Sexp::from((">=",
                            Into::<Sexp>::into(a.as_ref()),
                            Into::<Sexp>::into(b.as_ref())))
            }
        }
    }
}

impl<T: NumType> Condition<T> {
    pub fn evaluate(&self, args: &[Expr<T>]) -> Result<bool, ExprError> {
        Ok(match *self {
            Condition::True => true,
            Condition::False => false,
            Condition::Not(ref c) => !try!(c.evaluate(args)),
            Condition::And(ref c1, ref c2) => try!(c1.evaluate(args)) && try!(c2.evaluate(args)),
            Condition::Or(ref c1, ref c2) => try!(c1.evaluate(args)) || try!(c2.evaluate(args)),
            Condition::Equal(ref e1, ref e2) => try!(e1.evaluate(args)) == try!(e2.evaluate(args)),
            Condition::Less(ref e1, ref e2) => try!(e1.evaluate(args)) < try!(e2.evaluate(args)),
            Condition::Greater(ref e1, ref e2) => try!(e1.evaluate(args)) > try!(e2.evaluate(args)),
            Condition::LessEqual(ref e1, ref e2) => {
                try!(e1.evaluate(args)) <= try!(e2.evaluate(args))
            }
            Condition::GreaterEqual(ref e1, ref e2) => {
                try!(e1.evaluate(args)) >= try!(e2.evaluate(args))
            }
        })
    }
}

#[test]
fn test_expr_divz() {
    let expr = Expr::Divz(box Expr::Const(1.0), box Expr::Const(0.0));
    assert_eq!(Ok(0.0), expr.evaluate(&[]));
}

#[test]
fn test_expr_recipz() {
    let expr = Expr::Recipz(box Expr::Const(0.0));
    assert_eq!(Ok(0.0), expr.evaluate(&[]));

    let expr = Expr::Recipz(box Expr::Const(1.0));
    assert_eq!(Ok(1.0), expr.evaluate(&[]));

    let expr = Expr::Recipz(box Expr::Const(0.5));
    assert_eq!(Ok(2.0), expr.evaluate(&[]));
}

#[test]
fn test_expr() {
    let expr = Expr::Sub(box Expr::Const(0.0),
                         box Expr::Div(box Expr::Mul(box Expr::Add(box Expr::Const(1.0),
                                                                   box Expr::Arg(0)),
                                                     box Expr::Arg(1)),
                                       box Expr::Const(2.0)));

    fn fun(a: f32, b: f32) -> f32 {
        0.0 - ((1.0 + a) * b) / 2.0
    }

    fn check(expr: &Expr<f32>, a: f32, b: f32) {
        assert_eq!(Ok(fun(a, b)),
                   expr.evaluate(&[Expr::Const(a), Expr::Const(b)]))
    }

    check(&expr, 123.0, 4444.0);
    check(&expr, 0.0, -12.0);
}

#[test]
fn test_condition() {
    let cond = Condition::Greater(box Expr::Arg(0), box Expr::Const(0.0));

    fn fun(a: f32) -> bool {
        a > 0.0
    }

    fn check(cond: &Condition<f32>, a: f32) {
        assert_eq!(Ok(fun(a)), cond.evaluate(&[Expr::Const(a)]))
    }

    check(&cond, 123.0);
    check(&cond, 0.0);
    check(&cond, -1.4);

    assert_eq!(Ok(true), (Condition::True::<f32>).evaluate(&[]));
}
<|endoftext|>


<commit_before>//! ReQL Error Messages
//!
//! These are the error messages returned by the driver. See their [documentation] for details.
//!
//! [documentation]: https://www.rethinkdb.com/docs/error-types/

/// The most generic error message in ReQL
#[derive(Debug)]
pub enum ReqlError {
    Compile(ReqlCompileError),
    Runtime(ReqlRuntimeError),
    Driver(ReqlDriverError),
}

/// The query cannot be compiled by the server
///
/// This may be due to a syntax error, such as an unrecognized optional argument, or specifying the
/// wrong number of arguments to a command.
#[derive(Debug)]
pub enum ReqlCompileError {}

/// The parent class of all runtime errors
///
/// All errors on the server unrelated to compilation. Programs may use this to catch any runtime
/// error, but the server will always return a more specific error class.
#[derive(Debug)]
pub enum ReqlRuntimeError {
    QueryLogic(ReqlQueryLogicError),
    ResourceLimit(ReqlResourceLimitError),
    User(ReqlUserError),
    Internal(ReqlInternalError),
    Timeout(ReqlTimeoutError),
    Availability(ReqlAvailabilityError),
    Permissions(ReqlPermissionsError),
}

/// The query contains a logical impossibility, such as adding a number to a string.
#[derive(Debug)]
pub enum ReqlQueryLogicError {
    NonExistence(ReqlNonExistenceError),
}

/// A `ReqlQueryLogicError` that results from accessing a non-existent field or something else that
/// can be handled with the default command.
#[derive(Debug)]
pub enum ReqlNonExistenceError {}

/// Query execution caused a resource limit (for example, the array size limit) to be exceeded.
#[derive(Debug)]
pub enum ReqlResourceLimitError {}

/// An error produced by the error command.
#[derive(Debug)]
pub enum ReqlUserError {}

/// Query execution stopped due to an internal error, i.e., a server bug.
#[derive(Debug)]
pub enum ReqlInternalError {}

/// The query has timed out
///
/// This error happens on the client, not the server. Depending on driver implementation it may
/// derive from a native error class rather than `ReqlError`.
#[derive(Debug)]
pub enum ReqlTimeoutError {}

/// A server in the cluster is unavailable
///
/// The parent class of `ReqlOpFailedError` and `ReqlOpIndeterminateError`. Programs may use this
/// to catch any availability error, but the server will always return one of this class’s
/// children.
#[derive(Debug)]
pub enum ReqlAvailabilityError {
    OpFailed(ReqlOpFailedError),
    OpIndeterminate(ReqlOpIndeterminateError),
}

/// The operation has failed due to cluster state, configuration or table availability.
#[derive(Debug)]
pub enum ReqlOpFailedError {}

/// The status of the operation cannot be verified due to cluster state, configuration or table
/// availability.
#[derive(Debug)]
pub enum ReqlOpIndeterminateError {}

/// The user account does not have the permissions necessary to execute the query.
#[derive(Debug)]
pub enum ReqlPermissionsError {}

/// An error has occurred within the driver
///
/// This may be a driver bug, or it may be an unfulfillable command, such as an unserializable
/// query.
#[derive(Debug)]
pub enum ReqlDriverError {
    Auth(ReqlAuthError),
}

/// The client failed authentication with the server.
#[derive(Debug)]
pub enum ReqlAuthError {}
<commit_msg>Implement From for ReqlError<commit_after>//! ReQL Error Messages
//!
//! These are the error messages returned by the driver. See their [documentation] for details.
//!
//! [documentation]: https://www.rethinkdb.com/docs/error-types/

/// The most generic error message in ReQL
#[derive(Debug)]
pub enum ReqlError {
    Compile(ReqlCompileError),
    Runtime(ReqlRuntimeError),
    Driver(ReqlDriverError),
}

impl From<ReqlCompileError> for ReqlError {
    fn from(err: ReqlCompileError) -> ReqlError {
        ReqlError::Compile(err)
    }
}

impl From<ReqlRuntimeError> for ReqlError {
    fn from(err: ReqlRuntimeError) -> ReqlError {
        ReqlError::Runtime(err)
    }
}

impl From<ReqlDriverError> for ReqlError {
    fn from(err: ReqlDriverError) -> ReqlError {
        ReqlError::Driver(err)
    }
}

/// The query cannot be compiled by the server
///
/// This may be due to a syntax error, such as an unrecognized optional argument, or specifying the
/// wrong number of arguments to a command.
#[derive(Debug)]
pub enum ReqlCompileError {}

/// The parent class of all runtime errors
///
/// All errors on the server unrelated to compilation. Programs may use this to catch any runtime
/// error, but the server will always return a more specific error class.
#[derive(Debug)]
pub enum ReqlRuntimeError {
    QueryLogic(ReqlQueryLogicError),
    ResourceLimit(ReqlResourceLimitError),
    User(ReqlUserError),
    Internal(ReqlInternalError),
    Timeout(ReqlTimeoutError),
    Availability(ReqlAvailabilityError),
    Permissions(ReqlPermissionsError),
}

/// The query contains a logical impossibility, such as adding a number to a string.
#[derive(Debug)]
pub enum ReqlQueryLogicError {
    NonExistence(ReqlNonExistenceError),
}

/// A `ReqlQueryLogicError` that results from accessing a non-existent field or something else that
/// can be handled with the default command.
#[derive(Debug)]
pub enum ReqlNonExistenceError {}

/// Query execution caused a resource limit (for example, the array size limit) to be exceeded.
#[derive(Debug)]
pub enum ReqlResourceLimitError {}

/// An error produced by the error command.
#[derive(Debug)]
pub enum ReqlUserError {}

/// Query execution stopped due to an internal error, i.e., a server bug.
#[derive(Debug)]
pub enum ReqlInternalError {}

/// The query has timed out
///
/// This error happens on the client, not the server. Depending on driver implementation it may
/// derive from a native error class rather than `ReqlError`.
#[derive(Debug)]
pub enum ReqlTimeoutError {}

/// A server in the cluster is unavailable
///
/// The parent class of `ReqlOpFailedError` and `ReqlOpIndeterminateError`. Programs may use this
/// to catch any availability error, but the server will always return one of this class’s
/// children.
#[derive(Debug)]
pub enum ReqlAvailabilityError {
    OpFailed(ReqlOpFailedError),
    OpIndeterminate(ReqlOpIndeterminateError),
}

/// The operation has failed due to cluster state, configuration or table availability.
#[derive(Debug)]
pub enum ReqlOpFailedError {}

/// The status of the operation cannot be verified due to cluster state, configuration or table
/// availability.
#[derive(Debug)]
pub enum ReqlOpIndeterminateError {}

/// The user account does not have the permissions necessary to execute the query.
#[derive(Debug)]
pub enum ReqlPermissionsError {}

/// An error has occurred within the driver
///
/// This may be a driver bug, or it may be an unfulfillable command, such as an unserializable
/// query.
#[derive(Debug)]
pub enum ReqlDriverError {
    Auth(ReqlAuthError),
}

/// The client failed authentication with the server.
#[derive(Debug)]
pub enum ReqlAuthError {}
<|endoftext|>


<commit_before>use rusqlite::Connection;
use std::env;
use std::fs::create_dir_all;

pub fn db_exists() -> bool {
    false
}

pub fn create_database() {
    let tmp = env::home_dir();
    let mut path_buf = tmp.unwrap();
    path_buf.push("Film-O-Mat");

    // creates path if not existing
    create_dir_all(&path_buf);

    path_buf.push("database");
    path_buf.set_extension("db");

    let conn = Connection::open(path_buf).unwrap();

    // Example of SQL-Statement
    conn.execute("CREATE TABLE IF NOT EXISTS person (
                  id              INTEGER PRIMARY KEY,
                  name            TEXT NOT NULL,
                  time_created    TEXT NOT NULL,
                  data            BLOB
                  )",
                 &[])
        .unwrap();
}
<commit_msg>implemented check whether the database already exists<commit_after>use rusqlite::Connection;
use std::env;
use std::fs::create_dir_all;

pub fn db_exists() -> bool {
    let tmp = env::home_dir();
    let mut path_buf = tmp.unwrap();
    path_buf.push("Film-O-Mat");
    path_buf.push("database");
    path_buf.set_extension("db");
    path_buf.as_path().exists()
}

pub fn create_database() {
    let tmp = env::home_dir();
    let mut path_buf = tmp.unwrap();
    path_buf.push("Film-O-Mat");

    // creates path if not existing
    create_dir_all(&path_buf);

    path_buf.push("database");
    path_buf.set_extension("db");

    let conn = Connection::open(path_buf).unwrap();

    // Example of SQL-Statement
    conn.execute("CREATE TABLE IF NOT EXISTS person (
                  id              INTEGER PRIMARY KEY,
                  name            TEXT NOT NULL,
                  time_created    TEXT NOT NULL,
                  data            BLOB
                  )",
                 &[])
        .unwrap();
}
<|endoftext|>


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

#[macro_use]
extern crate log;
extern crate chrono;
extern crate fern;

extern crate dirs;

extern crate xi_core_lib;
extern crate xi_rpc;

use std::collections::HashMap;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};

use xi_core_lib::XiCore;
use xi_rpc::RpcLoop;

const XI_LOG_DIR: &str = "xi-core";
const XI_LOG_FILE: &str = "xi-core.log";

fn get_logging_directory_path<P: AsRef<Path>>(directory: P) -> Result<PathBuf, io::Error> {
    match dirs::data_local_dir() {
        Some(mut log_dir) => {
            log_dir.push(directory);
            Ok(log_dir)
        }
        None => Err(
            io::Error::new(
                io::ErrorKind::NotFound,
                "No standard logging directory known for this platform",
            )
        ),
    }
}

fn path_for_log_file<P: AsRef<Path>>(filename: P) -> Result<PathBuf, io::Error> {
    let mut logging_directory = get_logging_directory_path(get_logfile_directory_name())?;
    // Create the logging directory
    fs::create_dir_all(&logging_directory)?;
    // Pushing the filename to the end
    logging_directory.push(filename.as_ref());
    Ok(logging_directory)
}

fn setup_logging() -> Result<(), fern::InitError> {
    let level_filter = match std::env::var("XI_LOG") {
        Ok(level) => match level.to_lowercase().as_ref() {
            "trace" => log::LevelFilter::Trace,
            "debug" => log::LevelFilter::Debug,
            _ => log::LevelFilter::Info,
        },
        // Default to info
        Err(_) => log::LevelFilter::Info,
    };

    let mut fern_dispatch = fern::Dispatch::new()
        .format(|out, message, record| {
            out.finish(format_args!(
                "{}[{}][{}] {}",
                chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"),
                record.target(),
                record.level(),
                message,
            ))
        }).level(level_filter)
        .chain(io::stderr());

    let path_result = path_for_log_file(get_logfile_file_name());
    // If the logging_file_path returned successfully, add the logfile capability to fern
    if let Ok(logging_file_path) = &path_result {
        fern_dispatch = fern_dispatch.chain(fern::log_file(logging_file_path)?);
    }

    // Start fern
    fern_dispatch.apply()?;

    // Log details of the fern setup using fern/log
    match &path_result {
        Err(e) => {
            let message = "There was an issue getting the path for the log file";
            warn!("{}: {:?}, falling back to stderr.", message, e);
        }
        Ok(logging_file_path) => info!("Logging to the following file: {:?}", logging_file_path),
    }

    info!("Logging with fern is setup");
    Ok(())
}

fn get_flags() -> HashMap<String, Option<String>> {
    let mut flags: HashMap<String, Option<String>> = HashMap::new();

    let flag_prefix = "-";
    let mut args_itterator = std::env::args().peekable();
    while let Some(arg) = args_itterator.next() {
        if arg.starts_with(flag_prefix) {
            let key = arg.trim_left_matches(flag_prefix).to_string();

            // Check the next argument doesn't start with the flag prefix
            // map_or accounts for peek returning an Option
            let next_arg_not_a_flag: bool = args_itterator.peek().map_or(false, |val| !val.starts_with(flag_prefix));
            if next_arg_not_a_flag {
                flags.insert(key, args_itterator.next());
            }
        }
    }
    flags
}

fn main() {
    let mut state = XiCore::new();
    let stdin = io::stdin();
    let stdout = io::stdout();
    let mut rpc_looper = RpcLoop::new(stdout);

    if let Err(e) = setup_logging() {
        eprintln!(
            "[ERROR] setup_logging returned error, logging disabled: {:?}",
            e
        );
    }

    match rpc_looper.mainloop(|| stdin.lock(), &mut state) {
        Ok(_) => (),
        Err(err) => error!("xi-core exited with error:\n{:?}", err),
    }
}
<commit_msg>Added a function to take a config and generate a path. This will end up replacing path_for_log_file and be clearer. The creation of the logging dir will move to the log setup.<commit_after>// Copyright 2016 The xi-editor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[macro_use]
extern crate log;
extern crate chrono;
extern crate fern;

extern crate dirs;

extern crate xi_core_lib;
extern crate xi_rpc;

use std::collections::HashMap;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};

use xi_core_lib::XiCore;
use xi_rpc::RpcLoop;

const XI_LOG_DIR: &str = "xi-core";
const XI_LOG_FILE: &str = "xi-core.log";

fn get_logging_directory_path<P: AsRef<Path>>(directory: P) -> Result<PathBuf, io::Error> {
    match dirs::data_local_dir() {
        Some(mut log_dir) => {
            log_dir.push(directory);
            Ok(log_dir)
        }
        None => Err(
            io::Error::new(
                io::ErrorKind::NotFound,
                "No standard logging directory known for this platform",
            )
        ),
    }
}

fn path_for_log_file<P: AsRef<Path>>(filename: P) -> Result<PathBuf, io::Error> {
    let mut logging_directory = get_logging_directory_path(get_logfile_directory_name())?;
    // Create the logging directory
    fs::create_dir_all(&logging_directory)?;
    // Pushing the filename to the end
    logging_directory.push(filename.as_ref());
    Ok(logging_directory)
}

fn setup_logging() -> Result<(), fern::InitError> {
    let level_filter = match std::env::var("XI_LOG") {
        Ok(level) => match level.to_lowercase().as_ref() {
            "trace" => log::LevelFilter::Trace,
            "debug" => log::LevelFilter::Debug,
            _ => log::LevelFilter::Info,
        },
        // Default to info
        Err(_) => log::LevelFilter::Info,
    };

    let mut fern_dispatch = fern::Dispatch::new()
        .format(|out, message, record| {
            out.finish(format_args!(
                "{}[{}][{}] {}",
                chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"),
                record.target(),
                record.level(),
                message,
            ))
        }).level(level_filter)
        .chain(io::stderr());

    let path_result = path_for_log_file(get_logfile_file_name());
    // If the logging_file_path returned successfully, add the logfile capability to fern
    if let Ok(logging_file_path) = &path_result {
        fern_dispatch = fern_dispatch.chain(fern::log_file(logging_file_path)?);
    }

    // Start fern
    fern_dispatch.apply()?;

    // Log details of the fern setup using fern/log
    match &path_result {
        Err(e) => {
            let message = "There was an issue getting the path for the log file";
            warn!("{}: {:?}, falling back to stderr.", message, e);
        }
        Ok(logging_file_path) => info!("Logging to the following file: {:?}", logging_file_path),
    }

    info!("Logging with fern is setup");
    Ok(())
}

fn prepare_logging_path(logfile_config: LogfileConfig) -> Result<PathBuf, io::Error> {
    // Use the file name set in logfile_config or fallback to the default
    let logfile_file_name = match logfile_config.file {
        Some(file_name) => file_name,
        None => XI_LOG_FILE.to_string(),
    };
    // Use the directory name set in logfile_config or fallback to the default
    let logfile_directory_name = match logfile_config.directory {
        Some(dir) => dir,
        None => XI_LOG_DIR.to_string(),
    };

    let mut logging_directory_path = get_logging_directory_path(logfile_directory_name)?;

    // Add the file name & return the full path
    logging_directory_path.push(logfile_file_name);
    Ok(logging_directory_path)
}

struct LogfileConfig {
    directory: Option<String>,
    file: Option<String>,
}

fn get_flags() -> HashMap<String, Option<String>> {
    let mut flags: HashMap<String, Option<String>> = HashMap::new();

    let flag_prefix = "-";
    let mut args_itterator = std::env::args().peekable();
    while let Some(arg) = args_itterator.next() {
        if arg.starts_with(flag_prefix) {
            let key = arg.trim_left_matches(flag_prefix).to_string();

            // Check the next argument doesn't start with the flag prefix
            // map_or accounts for peek returning an Option
            let next_arg_not_a_flag: bool = args_itterator.peek().map_or(false, |val| !val.starts_with(flag_prefix));
            if next_arg_not_a_flag {
                flags.insert(key, args_itterator.next());
            }
        }
    }
    flags
}

fn main() {
    let mut state = XiCore::new();
    let stdin = io::stdin();
    let stdout = io::stdout();
    let mut rpc_looper = RpcLoop::new(stdout);

    if let Err(e) = setup_logging() {
        eprintln!(
            "[ERROR] setup_logging returned error, logging disabled: {:?}",
            e
        );
    }

    match rpc_looper.mainloop(|| stdin.lock(), &mut state) {
        Ok(_) => (),
        Err(err) => error!("xi-core exited with error:\n{:?}", err),
    }
}
<|endoftext|>


<commit_before>extern crate rand;

use glium::{self, DrawParameters, LinearBlendingFactor, Program, VertexBuffer};
use glium::draw_parameters::{BlendingFunction, DepthTest};
use super::camera::Camera;
use util::ToArr;
use base::math::*;
use base::world::PillarIndex;
use GameContext;
use std::rc::Rc;

const BOX_SIZE: f32 = 20.0;

#[derive(Copy, Clone)]
pub struct Vertex {
    point: [f32; 3],
}
implement_vertex!(Vertex, point);

#[derive(Debug, Copy, Clone)]
pub enum Form {
    #[allow(dead_code)]
    None = 0,
    #[allow(dead_code)]
    Rain = 1,
    #[allow(dead_code)]
    Snow = 2,
    #[allow(dead_code)]
    Pollen = 3,
}

#[derive(Debug, Copy, Clone)]
pub enum Strength {
    #[allow(dead_code)]
    Weak = 1,
    #[allow(dead_code)]
    Medium = 2,
    #[allow(dead_code)]
    Heavy = 3,
}

#[derive(Copy, Clone)]
pub struct Particle {
    vertices: [Vertex; 4],
    position: Point3<f32>,
    velocity: f32,
    trans_x: f32,
    trans_y: f32,
    trans_z: f32,
}

#[derive(Copy, Clone)]
pub struct Instance {
    position: [f32; 3],
}
implement_vertex!(Instance, position);

impl Particle {
    pub fn new(cam_pos: Point3<f32>) -> Particle {
        let mut radius: f32 = 0.0;
        let mut spawn = false;

        // loop provides better distribution of particles, by rolling a dice
        // which equalizes the chance for every radius inside the circle
        while !spawn {
            radius = rand::random::<f32>();

            let dice = rand::random::<f32>();

            spawn = dice < radius;
        }

        radius = radius * BOX_SIZE;

        let angle = Rad::new(rand::random::<f32>() * 6.28);

        let mut velocity = rand::random::<f32>();
        if velocity < 0.25 {
            velocity = velocity + 0.25;
        }
        if velocity > 0.75 {
            velocity = velocity - 0.25;
        }

        Particle {
            vertices: [Vertex { point: [1.0, 1.0, 0.0] },
                       Vertex { point: [-1.0, 1.0, 0.0] },
                       Vertex { point: [1.0, -1.0, 0.0] },
                       Vertex { point: [-1.0, -1.0, 0.0] }],
            position: Point3::new(cam_pos.x + radius * Rad::sin(angle),
                                  cam_pos.y + radius * Rad::cos(angle),
                                  cam_pos.z + BOX_SIZE),
            velocity: velocity,
            trans_x: rand::random::<f32>() * 6.28,
            trans_y: rand::random::<f32>() * 6.28,
            trans_z: rand::random::<f32>() * 6.28,
        }
    }
}

pub struct Weather {
    particles: Vec<Particle>,
    program: Program,
    indices: glium::index::NoIndices,
    context: Rc<GameContext>,
    camera: Camera,
    particle_buf: VertexBuffer<Instance>,
    actual_buf: VertexBuffer<Instance>,
    form: Form,
    strength: Strength,
    time: f32,
}

impl Weather {
    pub fn new(context: Rc<GameContext>) -> Weather {
        let vec: Vec<Particle> = Vec::new();
        let index_buffer = glium::index::NoIndices(glium::index::PrimitiveType::TriangleStrip);
        let weather_program = context.load_program("weather").unwrap();
        let camera = Camera::default();
        let sections = glium::VertexBuffer::new(context.get_facade(), &[]).unwrap();
        let sections2 = glium::VertexBuffer::new(context.get_facade(), &[]).unwrap();
        Weather {
            particles: vec,
            program: weather_program,
            indices: index_buffer,
            context: context,
            camera: camera,
            particle_buf: sections,
            actual_buf: sections2,
            form: Form::None,
            strength: Strength::Weak,
            time: 0.0,
        }
    }

    pub fn draw<S: glium::Surface>(&mut self, surface: &mut S, camera: &Camera) {
        if self.form as u8 == 0 {
            return;
        }

        let params = DrawParameters {
            depth: glium::Depth {
                write: true,
                test: DepthTest::IfLess,
                ..Default::default()
            },
            blend: glium::Blend {
                color: BlendingFunction::Addition {
                    source: LinearBlendingFactor::SourceAlpha,
                    destination: LinearBlendingFactor::OneMinusSourceAlpha,
                },
                ..Default::default()
            },
            ..Default::default()
        };

        let buffer = vec![Vertex { point: [1.0, 1.0, 0.0] },
                          Vertex { point: [-1.0, 1.0, 0.0] },
                          Vertex { point: [1.0, -1.0, 0.0] },
                          Vertex { point: [-1.0, -1.0, 0.0] }];
        let vertex_buffer = glium::VertexBuffer::new(self.context.get_facade(), &buffer).unwrap();
        let mut scaling = Matrix4::from_cols(Vector4f::new(1.0, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 1.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 1.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
        let view = camera.view_matrix();
        let mut color = Vector4f::new(0.0, 0.0, 0.0, 0.0);
        match self.form {
            Form::Snow => {
                color = Vector4f::new(0.7, 0.7, 0.7, 1.0);

                scaling = Matrix4::from_cols(Vector4f::new(0.05, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.05, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.05, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
            }
            Form::Rain => {
                color = Vector4f::new(0.35, 0.43, 0.47, 1.0);

                scaling = Matrix4::from_cols(Vector4f::new(0.01, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.05, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.5, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
            }
            Form::Pollen => {
                color = Vector4f::new(0.5, 0.5, 0.5, 1.0);

                scaling = Matrix4::from_cols(Vector4f::new(0.05, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.05, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.05, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
            }
            _ => (),
        };

        let uniforms = uniform!{
                form: self.form as i32,
                view_matrix: view.to_arr(),
                proj_matrix: camera.proj_matrix().to_arr(),
                scaling_matrix: scaling.to_arr(),
                color: color.to_arr(),
            };

        surface.draw((&vertex_buffer, self.actual_buf.per_instance().unwrap()),
                  &self.indices,
                  &self.program,
                  &uniforms,
                  &params)
            .unwrap();

    }

    pub fn update(&mut self, camera: &Camera, time: f32, world_manager: &super::WorldManager) {
        if self.time == time {
            return;
        } else {
            self.time += 1.0;
        }
        if self.form as u8 == 0 {
            return;
        }
        self.camera = *camera;
        let max_count: usize;
        match self.form {
            Form::Pollen => max_count = 25 * self.strength as usize,
            _ => max_count = 750 * self.strength as usize,
        }
        if self.particles.len() < max_count {
            let count = max_count / 10;
            for _ in 0..count {
                self.particles.push(Particle::new(camera.position));
            }
            let mut tmp = Vec::new();
            for particle in self.particles.iter() {
                tmp.push(Instance {
                    position: [particle.position.x, particle.position.y, particle.position.z],
                })
            }
            let vertex_buffer = glium::VertexBuffer::new(self.context.get_facade(), &tmp).unwrap();
            self.particle_buf = vertex_buffer;
        }

        let mut mapping = self.particle_buf.map();
        let mut tmp2 = Vec::new();
        for (particle, instance) in &mut self.particles.iter_mut().zip(mapping.iter_mut()) {
            match self.form {
                Form::Snow => {
                    instance.position[2] = instance.position[2] - (particle.velocity * 0.1);
                    instance.position[0] += particle.trans_x.sin() * 0.05;
                    instance.position[1] += particle.trans_y.cos() * 0.05;
                    particle.trans_y += 3.14 * 0.005 * (rand::random::<f32>() - 0.5);
                    particle.trans_x += 3.14 * 0.005 * (rand::random::<f32>() - 0.5);
                }

                Form::Rain => {
                    instance.position[2] = instance.position[2] - ((particle.velocity + 0.5) * 1.0)
                }
                Form::Pollen => {
                    instance.position[0] += particle.trans_x.sin() * 0.025;
                    instance.position[1] += particle.trans_y.cos() * 0.025;
                    instance.position[2] += (particle.trans_z.sin() - 0.7) * 0.01;
                    particle.trans_y += 3.14 * 0.005 * (rand::random::<f32>() - 0.5);
                    particle.trans_x += 3.14 * 0.005 * (rand::random::<f32>() - 0.5);
                    particle.trans_z += 3.14 * 0.005 * (rand::random::<f32>() - 0.1);
                }
                _ => (),

            }

            let pix_vec = Point2::new(instance.position[0], instance.position[1]);
            let cam_vec = Point2::new(camera.position.x, camera.position.y);
            let tmp = pix_vec - cam_vec;
            let len = ((tmp.x * tmp.x) + (tmp.y * tmp.y)).sqrt();

            let size = match self.form {
                Form::Pollen => BOX_SIZE / 4.0,
                _ => 1.0,
            };

            if len > BOX_SIZE - size || len < -BOX_SIZE - size {
                instance.position[0] = instance.position[0] - (1.95 * tmp.x);
                instance.position[1] = instance.position[1] - (1.95 * tmp.y);
            }
            if instance.position[2] < self.camera.position.z - BOX_SIZE / size {
                instance.position[2] += 1.9 * (BOX_SIZE / size);
            }
            if instance.position[2] > self.camera.position.z + BOX_SIZE / size {
                instance.position[2] -= 1.9 * (BOX_SIZE / size);
            }
            let tmp_point = Point3::new(instance.position[0],
                                        instance.position[1],
                                        instance.position[2]);
            let mut height = 0.0;

            let world = world_manager.get_world();
            let relevant_pos = Point2f::new(instance.position[0], instance.position[1]);
            let pillar_index = PillarIndex(AxialPoint::from_real(relevant_pos));
            let vec_len = world.pillar_at(pillar_index)
                .map(|pillar| pillar.sections().len())
                .unwrap_or(0);
            let pillar_vec = world.pillar_at(pillar_index).map(|pillar| pillar.sections());
            if pillar_vec.is_some() {
                let new_pillar_vec = pillar_vec.unwrap();

                if vec_len == 1 {
                    height = new_pillar_vec[0].top.to_real();
                } else {
                    for i in 0..vec_len {
                        if i != vec_len - 1 {
                            if new_pillar_vec[i].top.to_real() < instance.position[2] &&
                               instance.position[2] < new_pillar_vec[i + 1].bottom.to_real() {
                                height = new_pillar_vec[i].top.to_real();
                                break;
                            } else {
                                continue;
                            }
                        } else {
                            height = new_pillar_vec[i].top.to_real();
                            break;
                        }
                    }
                }
            }
            // let vec = world.pillar_at(pillar_index);
            if ((tmp_point - camera.position).dot(camera.get_look_at_vector())) > 0.0 &&
               instance.position[2] > height {
                tmp2.push(Instance {
                    position: [instance.position[0], instance.position[1], instance.position[2]],
                })
            }
        }
        let vertex_buffer = glium::VertexBuffer::new(self.context.get_facade(), &tmp2).unwrap();

        self.actual_buf = vertex_buffer;
    }

    pub fn set_weather(&mut self, form: Form, strength: Strength) {
        self.form = form;
        self.strength = strength;
    }
}
<commit_msg>deleted dead code annotations<commit_after>extern crate rand;

use glium::{self, DrawParameters, LinearBlendingFactor, Program, VertexBuffer};
use glium::draw_parameters::{BlendingFunction, DepthTest};
use super::camera::Camera;
use util::ToArr;
use base::math::*;
use base::world::PillarIndex;
use GameContext;
use std::rc::Rc;

const BOX_SIZE: f32 = 20.0;

#[derive(Copy, Clone)]
pub struct Vertex {
    point: [f32; 3],
}
implement_vertex!(Vertex, point);

#[derive(Debug, Copy, Clone)]
pub enum Form {
    None = 0,
    Rain = 1,
    Snow = 2,
    Pollen = 3,
}

#[derive(Debug, Copy, Clone)]
pub enum Strength {
    Weak = 1,
    Medium = 2,
    Heavy = 3,
}

#[derive(Copy, Clone)]
pub struct Particle {
    vertices: [Vertex; 4],
    position: Point3<f32>,
    velocity: f32,
    trans_x: f32,
    trans_y: f32,
    trans_z: f32,
}

#[derive(Copy, Clone)]
pub struct Instance {
    position: [f32; 3],
}
implement_vertex!(Instance, position);

impl Particle {
    pub fn new(cam_pos: Point3<f32>) -> Particle {
        let mut radius: f32 = 0.0;
        let mut spawn = false;

        // loop provides better distribution of particles, by rolling a dice
        // which equalizes the chance for every radius inside the circle
        while !spawn {
            radius = rand::random::<f32>();

            let dice = rand::random::<f32>();

            spawn = dice < radius;
        }

        radius = radius * BOX_SIZE;

        let angle = Rad::new(rand::random::<f32>() * 6.28);

        let mut velocity = rand::random::<f32>();
        if velocity < 0.25 {
            velocity = velocity + 0.25;
        }
        if velocity > 0.75 {
            velocity = velocity - 0.25;
        }

        Particle {
            vertices: [Vertex { point: [1.0, 1.0, 0.0] },
                       Vertex { point: [-1.0, 1.0, 0.0] },
                       Vertex { point: [1.0, -1.0, 0.0] },
                       Vertex { point: [-1.0, -1.0, 0.0] }],
            position: Point3::new(cam_pos.x + radius * Rad::sin(angle),
                                  cam_pos.y + radius * Rad::cos(angle),
                                  cam_pos.z + BOX_SIZE),
            velocity: velocity,
            trans_x: rand::random::<f32>() * 6.28,
            trans_y: rand::random::<f32>() * 6.28,
            trans_z: rand::random::<f32>() * 6.28,
        }
    }
}

pub struct Weather {
    particles: Vec<Particle>,
    program: Program,
    indices: glium::index::NoIndices,
    context: Rc<GameContext>,
    camera: Camera,
    particle_buf: VertexBuffer<Instance>,
    actual_buf: VertexBuffer<Instance>,
    form: Form,
    strength: Strength,
    time: f32,
}

impl Weather {
    pub fn new(context: Rc<GameContext>) -> Weather {
        let vec: Vec<Particle> = Vec::new();
        let index_buffer = glium::index::NoIndices(glium::index::PrimitiveType::TriangleStrip);
        let weather_program = context.load_program("weather").unwrap();
        let camera = Camera::default();
        let sections = glium::VertexBuffer::new(context.get_facade(), &[]).unwrap();
        let sections2 = glium::VertexBuffer::new(context.get_facade(), &[]).unwrap();
        Weather {
            particles: vec,
            program: weather_program,
            indices: index_buffer,
            context: context,
            camera: camera,
            particle_buf: sections,
            actual_buf: sections2,
            form: Form::None,
            strength: Strength::Weak,
            time: 0.0,
        }
    }

    pub fn draw<S: glium::Surface>(&mut self, surface: &mut S, camera: &Camera) {
        if self.form as u8 == 0 {
            return;
        }

        let params = DrawParameters {
            depth: glium::Depth {
                write: true,
                test: DepthTest::IfLess,
                ..Default::default()
            },
            blend: glium::Blend {
                color: BlendingFunction::Addition {
                    source: LinearBlendingFactor::SourceAlpha,
                    destination: LinearBlendingFactor::OneMinusSourceAlpha,
                },
                ..Default::default()
            },
            ..Default::default()
        };

        let buffer = vec![Vertex { point: [1.0, 1.0, 0.0] },
                          Vertex { point: [-1.0, 1.0, 0.0] },
                          Vertex { point: [1.0, -1.0, 0.0] },
                          Vertex { point: [-1.0, -1.0, 0.0] }];
        let vertex_buffer = glium::VertexBuffer::new(self.context.get_facade(), &buffer).unwrap();
        let mut scaling = Matrix4::from_cols(Vector4f::new(1.0, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 1.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 1.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
        let view = camera.view_matrix();
        let mut color = Vector4f::new(0.0, 0.0, 0.0, 0.0);
        match self.form {
            Form::Snow => {
                color = Vector4f::new(0.7, 0.7, 0.7, 1.0);

                scaling = Matrix4::from_cols(Vector4f::new(0.05, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.05, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.05, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
            }
            Form::Rain => {
                color = Vector4f::new(0.35, 0.43, 0.47, 1.0);

                scaling = Matrix4::from_cols(Vector4f::new(0.01, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.05, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.5, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
            }
            Form::Pollen => {
                color = Vector4f::new(0.5, 0.5, 0.5, 1.0);

                scaling = Matrix4::from_cols(Vector4f::new(0.05, 0.0, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.05, 0.0, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.05, 0.0),
                                             Vector4f::new(0.0, 0.0, 0.0, 1.0));
            }
            _ => (),
        };

        let uniforms = uniform!{
                form: self.form as i32,
                view_matrix: view.to_arr(),
                proj_matrix: camera.proj_matrix().to_arr(),
                scaling_matrix: scaling.to_arr(),
                color: color.to_arr(),
            };

        surface.draw((&vertex_buffer, self.actual_buf.per_instance().unwrap()),
                  &self.indices,
                  &self.program,
                  &uniforms,
                  &params)
            .unwrap();

    }

    pub fn update(&mut self, camera: &Camera, time: f32, world_manager: &super::WorldManager) {
        if self.time == time {
            return;
        } else {
            self.time += 1.0;
        }
        if self.form as u8 == 0 {
            return;
        }
        self.camera = *camera;
        let max_count: usize;
        match self.form {
            Form::Pollen => max_count = 25 * self.strength as usize,
            _ => max_count = 750 * self.strength as usize,
        }
        if self.particles.len() < max_count {
            let count = max_count / 10;
            for _ in 0..count {
                self.particles.push(Particle::new(camera.position));
            }
            let mut tmp = Vec::new();
            for particle in self.particles.iter() {
                tmp.push(Instance {
                    position: [particle.position.x, particle.position.y, particle.position.z],
                })
            }
            let vertex_buffer = glium::VertexBuffer::new(self.context.get_facade(), &tmp).unwrap();
            self.particle_buf = vertex_buffer;
        }

        let mut mapping = self.particle_buf.map();
        let mut tmp2 = Vec::new();
        for (particle, instance) in &mut self.particles.iter_mut().zip(mapping.iter_mut()) {
            match self.form {
                Form::Snow => {
                    instance.position[2] = instance.position[2] - (particle.velocity * 0.1);
                    instance.position[0] += particle.trans_x.sin() * 0.05;
                    instance.position[1] += particle.trans_y.cos() * 0.05;
                    particle.trans_y += 3.14 * 0.005 * (rand::random::<f32>() - 0.5);
                    particle.trans_x += 3.14 * 0.005 * (rand::random::<f32>() - 0.5);
                }

                Form::Rain => {
                    instance.position[2] = instance.position[2] - ((particle.velocity + 0.5) * 1.0)
                }
                Form::Pollen => {
                    instance.position[0] += particle.trans_x.sin() * 0.025;
                    instance.position[1] += particle.trans_y.cos() * 0.025;
                    instance.position[2] += (particle.trans_z.sin() - 0.7) * 0.01;
                    particle.trans_y += 3.14 * 0.005 * (rand::random::<f32>() - 0.5);
                    particle.trans_x += 3.14 * 0.005 * (rand::random::<f32>() - 0.5);
                    particle.trans_z += 3.14 * 0.005 * (rand::random::<f32>() - 0.1);
                }
                _ => (),

            }

            let pix_vec = Point2::new(instance.position[0], instance.position[1]);
            let cam_vec = Point2::new(camera.position.x, camera.position.y);
            let tmp = pix_vec - cam_vec;
            let len = ((tmp.x * tmp.x) + (tmp.y * tmp.y)).sqrt();

            let size = match self.form {
                Form::Pollen => BOX_SIZE / 4.0,
                _ => 1.0,
            };

            if len > BOX_SIZE - size || len < -BOX_SIZE - size {
                instance.position[0] = instance.position[0] - (1.95 * tmp.x);
                instance.position[1] = instance.position[1] - (1.95 * tmp.y);
            }
            if instance.position[2] < self.camera.position.z - BOX_SIZE / size {
                instance.position[2] += 1.9 * (BOX_SIZE / size);
            }
            if instance.position[2] > self.camera.position.z + BOX_SIZE / size {
                instance.position[2] -= 1.9 * (BOX_SIZE / size);
            }
            let tmp_point = Point3::new(instance.position[0],
                                        instance.position[1],
                                        instance.position[2]);
            let mut height = 0.0;

            let world = world_manager.get_world();
            let relevant_pos = Point2f::new(instance.position[0], instance.position[1]);
            let pillar_index = PillarIndex(AxialPoint::from_real(relevant_pos));
            let vec_len = world.pillar_at(pillar_index)
                .map(|pillar| pillar.sections().len())
                .unwrap_or(0);
            let pillar_vec = world.pillar_at(pillar_index).map(|pillar| pillar.sections());
            if pillar_vec.is_some() {
                let new_pillar_vec = pillar_vec.unwrap();

                if vec_len == 1 {
                    height = new_pillar_vec[0].top.to_real();
                } else {
                    for i in 0..vec_len {
                        if i != vec_len - 1 {
                            if new_pillar_vec[i].top.to_real() < instance.position[2] &&
                               instance.position[2] < new_pillar_vec[i + 1].bottom.to_real() {
                                height = new_pillar_vec[i].top.to_real();
                                break;
                            } else {
                                continue;
                            }
                        } else {
                            height = new_pillar_vec[i].top.to_real();
                            break;
                        }
                    }
                }
            }
            // let vec = world.pillar_at(pillar_index);
            if ((tmp_point - camera.position).dot(camera.get_look_at_vector())) > 0.0 &&
               instance.position[2] > height {
                tmp2.push(Instance {
                    position: [instance.position[0], instance.position[1], instance.position[2]],
                })
            }
        }
        let vertex_buffer = glium::VertexBuffer::new(self.context.get_facade(), &tmp2).unwrap();

        self.actual_buf = vertex_buffer;
    }

    pub fn set_weather(&mut self, form: Form, strength: Strength) {
        self.form = form;
        self.strength = strength;
    }
}
<|endoftext|>


<commit_before>use byteorder::{BigEndian, ByteOrder};

pub(crate) fn ghash(key: &[u8; 16], data: &[u8], ciphertext: &[u8]) -> [u8; 16] {
    let mut tag = [0; 16];
    let mut mac = GHash::new(key, data);
    mac.update(ciphertext);
    mac.write_tag(&mut tag);
    tag
}

const R0: u128 = 0xe1 << 120;

struct GHash {
    function: PolyFunction,
    data_len: u64,
    ciphertext_len: u64,
}

impl GHash {
    fn new(key: &[u8; 16], data: &[u8]) -> Self {
        let mut ghash = Self {
            function: PolyFunction::new(key),
            data_len: data.len() as u64,
            ciphertext_len: 0,
        };
        ghash.process(data);
        ghash
    }

    fn update(&mut self, input: &[u8]) {
        self.ciphertext_len += input.len() as u64;
        self.process(input);
    }

    fn write_tag(mut self, output: &mut [u8; 16]) {
        BigEndian::write_u64(&mut output[..8], 8 * self.data_len);
        BigEndian::write_u64(&mut output[8..], 8 * self.ciphertext_len);
        self.function.process(output);
        self.function.write_value(output);
    }

    fn process(&mut self, input: &[u8]) {
        for chunk in input.chunks(16) {
            if chunk.len() < 16 {
                let buffer = &mut [0; 16];
                buffer[..chunk.len()].copy_from_slice(chunk);
                self.function.process(buffer);
            } else {
                self.function.process(chunk);
            }
        }
    }
}

type GFBlock = u128;

struct PolyFunction {
    key_block: GFBlock,
    state: GFBlock,
}

impl PolyFunction {
    fn new(key: &[u8; 16]) -> Self {
        Self {
            key_block: BigEndian::read_u128(key),
            state: 0,
        }
    }

    fn process(&mut self, input: &[u8]) {
        self.state ^= BigEndian::read_u128(input);

        let mut x = self.state;
        let mut v = self.key_block;
        self.state = 0;
        for _ in 0..128 {
            let mut h = x & (1 << 127);
            let mut m = (h as i128 >> 127) as u128;
            self.state ^= v & m;
            h = v << 127;
            m = (h as i128 >> 127) as u128;
            v >>= 1;
            v ^= R0 & m;
            x <<= 1;
        }
    }

    fn write_value(self, output: &mut [u8; 16]) {
        BigEndian::write_u128(output, self.state);
    }
}

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

    fn check(expected: &str, h: &str, a: &str, c: &str) {
        let h_vec = &h2b(h);
        let h = &mut [0; 16];
        h.copy_from_slice(h_vec);
        let a = &h2b(a);
        let c = &h2b(c);
        let expected = h2b(expected);
        assert_eq!(expected, ghash(h, a, c));
    }

    #[test]
    fn test_case_1_2() {
        let h = "66e94bd4ef8a2c3b884cfa59ca342b2e";
        let a = "";
        let c = "";
        let expected = "00000000000000000000000000000000";
        check(expected, h, a, c);

        let c = "0388dace60b6a392f328c2b971b2fe78";
        let expected = "f38cbb1ad69223dcc3457ae5b6b0f885";
        check(expected, h, a, c);
    }

    #[test]
    fn test_case_3_4_5_6() {
        let h = "b83b533708bf535d0aa6e52980d53b78";
        let a = "";
        let c = "42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e\
                 21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985";
        let expected = "7f1b32b81b820d02614f8895ac1d4eac";
        check(expected, h, a, c);

        let a = "feedfacedeadbeeffeedfacedeadbeefabaddad2";
        let c = &c[..120];
        let expected = "698e57f70e6ecc7fd9463b7260a9ae5f";
        check(expected, h, a, c);

        let c = "61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c7423\
                 73806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598";
        let expected = "df586bb4c249b92cb6922877e444d37b";
        check(expected, h, a, c);

        let c = "8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca7\
                 01e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5";
        let expected = "1c5afe9760d3932f3c9a878aac3dc3de";
        check(expected, h, a, c);
    }

    #[test]
    fn test_case_7_8() {
        let h = "aae06992acbf52a3e8f4a96ec9300bd7";
        let a = "";
        let c = "";
        let expected = "00000000000000000000000000000000";
        check(expected, h, a, c);

        let c = "98e7247c07f0fe411c267e4384b0f600";
        let expected = "e2c63f0ac44ad0e02efa05ab6743d4ce";
        check(expected, h, a, c);
    }

    #[test]
    fn test_case_9_10_11_12() {
        let h = "466923ec9ae682214f2c082badb39249";
        let a = "";
        let c = "3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c\
                 7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710acade256";
        let expected = "51110d40f6c8fff0eb1ae33445a889f0";
        check(expected, h, a, c);

        let a = "feedfacedeadbeeffeedfacedeadbeefabaddad2";
        let c = &c[..120];
        let expected = "ed2ce3062e4a8ec06db8b4c490e8a268";
        check(expected, h, a, c);

        let c = "0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057\
                 fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f7";
        let expected = "1e6a133806607858ee80eaf237064089";
        check(expected, h, a, c);

        let c = "d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e45\
                 81e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373b";
        let expected = "82567fb0b4cc371801eadec005968e94";
        check(expected, h, a, c);
    }

    #[test]
    fn test_case_13_14() {
        let h = "dc95c078a2408989ad48a21492842087";
        let a = "";
        let c = "";
        let expected = "00000000000000000000000000000000";
        check(expected, h, a, c);

        let c = "cea7403d4d606b6e074ec5d3baf39d18";
        let expected = "83de425c5edc5d498f382c441041ca92";
        check(expected, h, a, c);
    }

    #[test]
    fn test_case_15_16_17_18() {
        let h = "acbef20579b4b8ebce889bac8732dad7";
        let a = "";
        let c = "522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa\
                 8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad";
        let expected = "4db870d37cb75fcb46097c36230d1612";
        check(expected, h, a, c);

        let a = "feedfacedeadbeeffeedfacedeadbeefabaddad2";
        let c = &c[..120];
        let expected = "8bd0c4d8aacd391e67cca447e8c38f65";
        check(expected, h, a, c);

        let c = "c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0\
                 feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f";
        let expected = "75a34288b8c68f811c52b2e9a2f97f63";
        check(expected, h, a, c);

        let c = "5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf4\
                 0fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f";
        let expected = "d5ffcf6fc5ac4d69722187421a7f170b";
        check(expected, h, a, c);
    }
}
<commit_msg>u128: use be builtin<commit_after>use byteorder::{BigEndian, ByteOrder};

pub(crate) fn ghash(key: &[u8; 16], data: &[u8], ciphertext: &[u8]) -> [u8; 16] {
    let mut tag = [0; 16];
    let mut mac = GHash::new(key, data);
    mac.update(ciphertext);
    mac.write_tag(&mut tag);
    tag
}

const R0: u128 = 0xe1 << 120;

struct GHash {
    function: PolyFunction,
    data_len: u64,
    ciphertext_len: u64,
}

impl GHash {
    fn new(key: &[u8; 16], data: &[u8]) -> Self {
        let mut ghash = Self {
            function: PolyFunction::new(key),
            data_len: data.len() as u64,
            ciphertext_len: 0,
        };
        ghash.process(data);
        ghash
    }

    fn update(&mut self, input: &[u8]) {
        self.ciphertext_len += input.len() as u64;
        self.process(input);
    }

    fn write_tag(mut self, output: &mut [u8; 16]) {
        BigEndian::write_u64(&mut output[..8], 8 * self.data_len);
        BigEndian::write_u64(&mut output[8..], 8 * self.ciphertext_len);
        self.function.process(output);
        self.function.write_value(output);
    }

    fn process(&mut self, input: &[u8]) {
        for chunk in input.chunks(16) {
            if chunk.len() < 16 {
                let buffer = &mut [0; 16];
                buffer[..chunk.len()].copy_from_slice(chunk);
                self.function.process(buffer);
            } else {
                self.function.process(chunk);
            }
        }
    }
}

type GFBlock = u128;

struct PolyFunction {
    key_block: GFBlock,
    state: GFBlock,
}

impl PolyFunction {
    fn new(key: &[u8; 16]) -> Self {
        Self {
            key_block: u128::from_be_bytes(*key),
            state: 0,
        }
    }

    fn process(&mut self, input: &[u8]) {
        self.state ^= BigEndian::read_u128(input);

        let mut x = self.state;
        let mut v = self.key_block;
        self.state = 0;
        for _ in 0..128 {
            let mut h = x & (1 << 127);
            let mut m = (h as i128 >> 127) as u128;
            self.state ^= v & m;
            h = v << 127;
            m = (h as i128 >> 127) as u128;
            v >>= 1;
            v ^= R0 & m;
            x <<= 1;
        }
    }

    fn write_value(self, output: &mut [u8; 16]) {
        BigEndian::write_u128(output, self.state);
    }
}

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

    fn check(expected: &str, h: &str, a: &str, c: &str) {
        let h_vec = &h2b(h);
        let h = &mut [0; 16];
        h.copy_from_slice(h_vec);
        let a = &h2b(a);
        let c = &h2b(c);
        let expected = h2b(expected);
        assert_eq!(expected, ghash(h, a, c));
    }

    #[test]
    fn test_case_1_2() {
        let h = "66e94bd4ef8a2c3b884cfa59ca342b2e";
        let a = "";
        let c = "";
        let expected = "00000000000000000000000000000000";
        check(expected, h, a, c);

        let c = "0388dace60b6a392f328c2b971b2fe78";
        let expected = "f38cbb1ad69223dcc3457ae5b6b0f885";
        check(expected, h, a, c);
    }

    #[test]
    fn test_case_3_4_5_6() {
        let h = "b83b533708bf535d0aa6e52980d53b78";
        let a = "";
        let c = "42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e\
                 21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985";
        let expected = "7f1b32b81b820d02614f8895ac1d4eac";
        check(expected, h, a, c);

        let a = "feedfacedeadbeeffeedfacedeadbeefabaddad2";
        let c = &c[..120];
        let expected = "698e57f70e6ecc7fd9463b7260a9ae5f";
        check(expected, h, a, c);

        let c = "61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c7423\
                 73806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598";
        let expected = "df586bb4c249b92cb6922877e444d37b";
        check(expected, h, a, c);

        let c = "8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca7\
                 01e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5";
        let expected = "1c5afe9760d3932f3c9a878aac3dc3de";
        check(expected, h, a, c);
    }

    #[test]
    fn test_case_7_8() {
        let h = "aae06992acbf52a3e8f4a96ec9300bd7";
        let a = "";
        let c = "";
        let expected = "00000000000000000000000000000000";
        check(expected, h, a, c);

        let c = "98e7247c07f0fe411c267e4384b0f600";
        let expected = "e2c63f0ac44ad0e02efa05ab6743d4ce";
        check(expected, h, a, c);
    }

    #[test]
    fn test_case_9_10_11_12() {
        let h = "466923ec9ae682214f2c082badb39249";
        let a = "";
        let c = "3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c\
                 7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710acade256";
        let expected = "51110d40f6c8fff0eb1ae33445a889f0";
        check(expected, h, a, c);

        let a = "feedfacedeadbeeffeedfacedeadbeefabaddad2";
        let c = &c[..120];
        let expected = "ed2ce3062e4a8ec06db8b4c490e8a268";
        check(expected, h, a, c);

        let c = "0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057\
                 fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f7";
        let expected = "1e6a133806607858ee80eaf237064089";
        check(expected, h, a, c);

        let c = "d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e45\
                 81e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373b";
        let expected = "82567fb0b4cc371801eadec005968e94";
        check(expected, h, a, c);
    }

    #[test]
    fn test_case_13_14() {
        let h = "dc95c078a2408989ad48a21492842087";
        let a = "";
        let c = "";
        let expected = "00000000000000000000000000000000";
        check(expected, h, a, c);

        let c = "cea7403d4d606b6e074ec5d3baf39d18";
        let expected = "83de425c5edc5d498f382c441041ca92";
        check(expected, h, a, c);
    }

    #[test]
    fn test_case_15_16_17_18() {
        let h = "acbef20579b4b8ebce889bac8732dad7";
        let a = "";
        let c = "522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa\
                 8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad";
        let expected = "4db870d37cb75fcb46097c36230d1612";
        check(expected, h, a, c);

        let a = "feedfacedeadbeeffeedfacedeadbeefabaddad2";
        let c = &c[..120];
        let expected = "8bd0c4d8aacd391e67cca447e8c38f65";
        check(expected, h, a, c);

        let c = "c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0\
                 feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f";
        let expected = "75a34288b8c68f811c52b2e9a2f97f63";
        check(expected, h, a, c);

        let c = "5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf4\
                 0fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f";
        let expected = "d5ffcf6fc5ac4d69722187421a7f170b";
        check(expected, h, a, c);
    }
}
<|endoftext|>


<commit_before>use std::fmt;

pub struct DeviceToken {
    pub token: String,
}

impl DeviceToken {
    pub fn new<S>(token: S) -> DeviceToken
        where S: Into<String>
    {
        DeviceToken { token: token.into() }
    }
}

impl fmt::Display for DeviceToken {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.token)
    }
}
<commit_msg>Simple changes in DeviceToken<commit_after>use std::fmt;
use std::borrow::Cow;

/// Specify the hexadecimal bytes of the device token for the target device.
pub struct DeviceToken<'a> {
    pub token: Cow<'a, str>,
}

impl<'a> DeviceToken<'a> {
    pub fn new<S>(token: S) -> DeviceToken<'a>
        where S: Into<Cow<'a, str>>
    {
        DeviceToken { token: token.into() }
    }
}

impl<'a> fmt::Display for DeviceToken<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.token)
    }
}
<|endoftext|>


<commit_before>// See LICENSE file for copyright and license details.

use std::collections::{HashMap, VecDeque};
use common::types::{ZInt, ZFloat, MapPos};
use zgl::zgl::{Zgl};
use zgl::mesh::{Mesh};
use zgl::camera::Camera;
use zgl::shader::{Shader};
use zgl::font_stash::{FontStash};
use zgl::types::{Time};
use geom;
use move_helper::{MoveHelper};

struct ShowTextCommand {
    pos: MapPos,
    text: String,
}

struct MapText {
    move_helper: MoveHelper,
    mesh: Mesh,
    pos: MapPos,
}

pub struct MapTextManager {
    commands: VecDeque<ShowTextCommand>,
    meshes: HashMap<ZInt, MapText>, // TODO: rename
    scale: ZFloat,
    i: ZInt, // TODO: rename
}

impl MapTextManager {
    pub fn new(font_stash: &mut FontStash) -> Self {
        MapTextManager {
            commands: VecDeque::new(),
            meshes: HashMap::new(),
            scale: 0.5 / font_stash.get_size(),
            i: 0,
        }
    }

    pub fn add_text(&mut self, pos: &MapPos, text: &str) {
        self.commands.push_back(ShowTextCommand {
            pos: pos.clone(),
            text: text.to_string(),
        });
    }

    fn can_show_text_here(&self, pos: &MapPos) -> bool {
        let min_progress = 0.3;
        for (_, map_text) in &self.meshes {
            let progress = map_text.move_helper.progress();
            if map_text.pos == *pos && progress < min_progress {
                return false;
            }
        }
        true
    }

    pub fn do_commands(&mut self, zgl: &Zgl, font_stash: &mut FontStash) {
        let mut postponed_commands = Vec::new();
        while !self.commands.is_empty() {
            let command = self.commands.pop_front()
                .expect("MapTextManager: Can`t get next command");
            if !self.can_show_text_here(&command.pos) {
                postponed_commands.push(command);
                continue;
            }
            let from = geom::map_pos_to_world_pos(&command.pos);
            let mut to = from.clone();
            to.v.z += 2.0;
            let mesh = font_stash.get_mesh(zgl, &command.text, 1.0, true);
            self.meshes.insert(self.i, MapText {
                pos: command.pos.clone(),
                mesh: mesh,
                move_helper: MoveHelper::new(&from, &to, 1.0),
            });
            self.i += 1;
        }
        self.commands.extend(postponed_commands);
    }

    fn delete_old(&mut self) {
        let mut bad_keys = Vec::new();
        for (key, map_text) in &self.meshes {
            if map_text.move_helper.is_finished() {
                bad_keys.push(*key);
            }
        }
        for key in &bad_keys {
            self.meshes.remove(key);
        }
    }

    pub fn draw(
        &mut self,
        zgl: &Zgl,
        camera: &Camera,
        shader: &Shader,
        dtime: &Time,
        font_stash: &mut FontStash,
    ) {
        self.do_commands(zgl, font_stash);
        // TODO: I'm not sure that disabling depth test is correct solution
        zgl.set_depth_test(false);
        for (_, map_text) in self.meshes.iter_mut() {
            let pos = map_text.move_helper.step(dtime);
            let m = camera.mat(zgl);
            let m = zgl.tr(m, &pos.v);
            let m = zgl.scale(m, self.scale);
            let m = zgl.rot_z(m, camera.get_z_angle());
            let m = zgl.rot_x(m, camera.get_x_angle());
            shader.set_uniform_mat4f(zgl, shader.get_mvp_mat(), &m);
            map_text.mesh.draw(zgl, shader);
        }
        zgl.set_depth_test(true);
        self.delete_old();
    }
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<commit_msg>MapTextManager: Fixed field names<commit_after>// See LICENSE file for copyright and license details.

use std::collections::{HashMap, VecDeque};
use common::types::{ZInt, ZFloat, MapPos};
use zgl::zgl::{Zgl};
use zgl::mesh::{Mesh};
use zgl::camera::Camera;
use zgl::shader::{Shader};
use zgl::font_stash::{FontStash};
use zgl::types::{Time};
use geom;
use move_helper::{MoveHelper};

struct ShowTextCommand {
    pos: MapPos,
    text: String,
}

struct MapText {
    move_helper: MoveHelper,
    mesh: Mesh,
    pos: MapPos,
}

pub struct MapTextManager {
    commands: VecDeque<ShowTextCommand>,
    visible_labels_list: HashMap<ZInt, MapText>,
    scale: ZFloat,
    last_label_id: ZInt, // TODO: think about better way of deleting old labels
}

impl MapTextManager {
    pub fn new(font_stash: &mut FontStash) -> Self {
        MapTextManager {
            commands: VecDeque::new(),
            visible_labels_list: HashMap::new(),
            scale: 0.5 / font_stash.get_size(),
            last_label_id: 0,
        }
    }

    pub fn add_text(&mut self, pos: &MapPos, text: &str) {
        self.commands.push_back(ShowTextCommand {
            pos: pos.clone(),
            text: text.to_string(),
        });
    }

    fn can_show_text_here(&self, pos: &MapPos) -> bool {
        let min_progress = 0.3;
        for (_, map_text) in &self.visible_labels_list {
            let progress = map_text.move_helper.progress();
            if map_text.pos == *pos && progress < min_progress {
                return false;
            }
        }
        true
    }

    pub fn do_commands(&mut self, zgl: &Zgl, font_stash: &mut FontStash) {
        let mut postponed_commands = Vec::new();
        while !self.commands.is_empty() {
            let command = self.commands.pop_front()
                .expect("MapTextManager: Can`t get next command");
            if !self.can_show_text_here(&command.pos) {
                postponed_commands.push(command);
                continue;
            }
            let from = geom::map_pos_to_world_pos(&command.pos);
            let mut to = from.clone();
            to.v.z += 2.0;
            let mesh = font_stash.get_mesh(zgl, &command.text, 1.0, true);
            self.visible_labels_list.insert(self.last_label_id, MapText {
                pos: command.pos.clone(),
                mesh: mesh,
                move_helper: MoveHelper::new(&from, &to, 1.0),
            });
            self.last_label_id += 1;
        }
        self.commands.extend(postponed_commands);
    }

    fn delete_old(&mut self) {
        let mut bad_keys = Vec::new();
        for (key, map_text) in &self.visible_labels_list {
            if map_text.move_helper.is_finished() {
                bad_keys.push(*key);
            }
        }
        for key in &bad_keys {
            self.visible_labels_list.remove(key);
        }
    }

    pub fn draw(
        &mut self,
        zgl: &Zgl,
        camera: &Camera,
        shader: &Shader,
        dtime: &Time,
        font_stash: &mut FontStash,
    ) {
        self.do_commands(zgl, font_stash);
        // TODO: I'm not sure that disabling depth test is correct solution
        zgl.set_depth_test(false);
        for (_, map_text) in self.visible_labels_list.iter_mut() {
            let pos = map_text.move_helper.step(dtime);
            let m = camera.mat(zgl);
            let m = zgl.tr(m, &pos.v);
            let m = zgl.scale(m, self.scale);
            let m = zgl.rot_z(m, camera.get_z_angle());
            let m = zgl.rot_x(m, camera.get_x_angle());
            shader.set_uniform_mat4f(zgl, shader.get_mvp_mat(), &m);
            map_text.mesh.draw(zgl, shader);
        }
        zgl.set_depth_test(true);
        self.delete_old();
    }
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<|endoftext|>


<commit_before>extern crate clap;

use std::any::Any;
use std::env;
use std::ffi::OsString;

use catfs::flags::DiskSpace;

pub struct Flag<'a, 'b> {
    pub arg: clap::Arg<'a, 'a>,
    pub value: &'b mut Any,
}

pub fn parse_options<'a, 'b>(mut app: clap::App<'a, 'a>, flags: &'b mut [Flag<'a, 'b>]) {
    for f in flags.iter() {
        app = app.arg(f.arg.clone());
    }
    let mut argv = env::args_os().collect::<Vec<OsString>>();
    if argv.len() == 5 && argv[3] == OsString::from("-o") {
	// looks like it's coming from fstab!
        // [0]: catfs, [1] = src_dir#cache_dir, [2] = mnt
        // [3]: -o, [4] = opt1,opt2
        // XXX str has split but OsString doesn't

        // XXX2 this is more convoluted than necessary because paths
        // immutably borrows from argv and we can't modify elements of
        // argv again because that requires another mutable borrow

        // XXX3 need to initialize src/cache because the compiler is
        // not smart enough
        let mut src: OsString = Default::default();
        let mut cache: OsString = Default::default();
        let mut is_fstab = false;

        {
            let paths = argv[1].to_str().unwrap().splitn(2, '#').collect::<Vec<&str>>();
            if paths.len() == 2 {
                src = OsString::from(paths[0]);
                cache = OsString::from(paths[1]);
                is_fstab = true;
            }
        }

        if is_fstab {
            argv[1] = src;
            argv.insert(2, cache);
        }
    }

    let matches = app.get_matches_from(argv);

    for f in flags.iter_mut() {
        let name = f.arg.b.name;

        if matches.is_present(name) {
            // cannot use else if here or rust would claim double mutable borrow
            if let Some(v) = f.value.downcast_mut::<String>() {
                let s = matches.value_of(name).unwrap();
                *v = String::from(s);
            }
            if let Some(v) = f.value.downcast_mut::<OsString>() {
                let s = matches.value_of_os(name).unwrap();
                *v = s.to_os_string();
            }
            if let Some(v) = f.value.downcast_mut::<bool>() {
                *v = true;
            }
            if let Some(v) = f.value.downcast_mut::<Vec<OsString>>() {
                let options = matches.values_of(name).unwrap();
                for s in options {
                    for s in s.split(',') {
                        v.push(OsString::from("-o"));
                        v.push(OsString::from(s));
                    }
                }
            }
            if let Some(v) = f.value.downcast_mut::<DiskSpace>() {
                let s = matches.value_of(name).unwrap();
                *v = s.parse().unwrap();
            }
        }
    }
}
<commit_msg>better runtime typechecking for missing types<commit_after>extern crate clap;
extern crate libc;

use std::any::Any;
use std::env;
use std::ffi::OsString;

use catfs::flags::DiskSpace;

pub struct Flag<'a, 'b> {
    pub arg: clap::Arg<'a, 'a>,
    pub value: &'b mut Any,
}

pub fn parse_options<'a, 'b>(mut app: clap::App<'a, 'a>, flags: &'b mut [Flag<'a, 'b>]) {
    for f in flags.iter() {
        app = app.arg(f.arg.clone());
    }
    let mut argv = env::args_os().collect::<Vec<OsString>>();
    if argv.len() == 5 && argv[3] == OsString::from("-o") {
	// looks like it's coming from fstab!
        // [0]: catfs, [1] = src_dir#cache_dir, [2] = mnt
        // [3]: -o, [4] = opt1,opt2
        // XXX str has split but OsString doesn't

        // XXX2 this is more convoluted than necessary because paths
        // immutably borrows from argv and we can't modify elements of
        // argv again because that requires another mutable borrow

        // XXX3 need to initialize src/cache because the compiler is
        // not smart enough
        let mut src: OsString = Default::default();
        let mut cache: OsString = Default::default();
        let mut is_fstab = false;

        {
            let paths = argv[1].to_str().unwrap().splitn(2, '#').collect::<Vec<&str>>();
            if paths.len() == 2 {
                src = OsString::from(paths[0]);
                cache = OsString::from(paths[1]);
                is_fstab = true;
            }
        }

        if is_fstab {
            argv[1] = src;
            argv.insert(2, cache);
        }
    }

    let matches = app.get_matches_from(argv);

    for f in flags.iter_mut() {
        let name = f.arg.b.name;

        if matches.is_present(name) {
            // cannot use else if here or rust would claim double
            // mutable borrow because apparently a borrow sends with
            // the last else if
            if let Some(v) = f.value.downcast_mut::<String>() {
                let s = matches.value_of(name).unwrap();
                *v = String::from(s);
                continue;
            }
            if let Some(v) = f.value.downcast_mut::<OsString>() {
                let s = matches.value_of_os(name).unwrap();
                *v = s.to_os_string();
                continue;
            }
            if let Some(v) = f.value.downcast_mut::<bool>() {
                *v = true;
                continue;
            }
            if let Some(v) = f.value.downcast_mut::<Vec<OsString>>() {
                let options = matches.values_of(name).unwrap();
                for s in options {
                    for s in s.split(',') {
                        v.push(OsString::from("-o"));
                        v.push(OsString::from(s));
                    }
                }
                continue;
            }
            if let Some(v) = f.value.downcast_mut::<DiskSpace>() {
                let s = matches.value_of(name).unwrap();
                *v = s.parse().unwrap();
                continue;
            }
            if let Some(v) = f.value.downcast_mut::<libc::uid_t>() {
                let s = matches.value_of(name).unwrap();
                *v = s.parse().unwrap();
                continue;
            }
            if let Some(v) = f.value.downcast_mut::<libc::gid_t>() {
                let s = matches.value_of(name).unwrap();
                *v = s.parse().unwrap();
                continue;
            }

            panic!("unknown type for {}", name);
        }
    }
}
<|endoftext|>