<commit_before>#![allow(non_snake_case, non_upper_case_globals)]
extern crate time;

use time::precise_time_s;
use std::mem;

///////////////////////////////////////////////////////////////////////////////
// 1. Calibration
///////////////////////////////////////////////////////////////////////////////
const aalpha:f64 = 0.33333333333;  // Elasticity of output w.r.t. capital
const bbeta:f64 = 0.95;           // Discount factor

// Productivity values
const vProductivity:[f64; 5] = [0.9792, 0.9896, 1.0000, 1.0106, 1.0212];

// Transition matrix
const mTransition:[[f64; 5]; 5] = [[0.9727, 0.0273, 0.0000, 0.0000, 0.0000],
                                   [0.0041, 0.9806, 0.0153, 0.0000, 0.0000],
                                   [0.0000, 0.0082, 0.9837, 0.0082, 0.0000],
                                   [0.0000, 0.0000, 0.0153, 0.9806, 0.0041],
                                   [0.0000, 0.0000, 0.0000, 0.0273, 0.9727]];

// Dimensions to generate the grid of capital
const nGridCapital: usize = 17820;
const nGridProductivity: usize = 5;

fn main() {

    let cpu0 = precise_time_s();

  /////////////////////////////////////////////////////////////////////////////
  // 2. Steady State
  /////////////////////////////////////////////////////////////////////////////

    let capitalSteadyState: f64 = (aalpha * bbeta).powf(1_f64 / (1_f64 - aalpha));
    let outputSteadyState: f64 = capitalSteadyState.powf(aalpha);
    let consumptionSteadyState: f64 = outputSteadyState - capitalSteadyState;

    println!("\
    Output = {}, Capital = {}, Consumption = {}",
    outputSteadyState, capitalSteadyState, consumptionSteadyState);

    let vGridCapital = (0..nGridCapital)
                           .map(|nCapital| 0.5 * capitalSteadyState + 0.00001 * (nCapital as f64))
                           .collect::<Vec<f64>>();

  // 3. Required matrices and vectors
  // One could use: vec![vec![0_f64; nGridProductivity]; nGridCapital];
  // but for some reasons this is faster.

    #[inline]
    fn row() -> Vec<f64> {
        (0..nGridProductivity).map(|_| 0_f64).collect::<Vec<f64>>()
    }

    let mut mValueFunction = (0..nGridCapital).map(|_| row()).collect::<Vec<Vec<f64>>>();
    let mut mValueFunctionNew = (0..nGridCapital).map(|_| row()).collect::<Vec<Vec<f64>>>();
    let mut mPolicyFunction = (0..nGridCapital).map(|_| row()).collect::<Vec<Vec<f64>>>();
    let mut expectedValueFunction = (0..nGridCapital).map(|_| row()).collect::<Vec<Vec<f64>>>();

  // 4. We pre-build output for each point in the grid
    let mOutput = (0..nGridCapital)
                      .map(|nCapital| {
                          (0..nGridProductivity).map(|nProductivity|
        vProductivity[nProductivity]*vGridCapital[nCapital].powf(aalpha)
      ).collect::<Vec<f64>>()
                      })
                      .collect::<Vec<Vec<f64>>>();

  // 5. Main iteration
  // TODO: one could implement a macro for the multiple declarations
    let mut maxDifference = 10_f64;
    const tolerance: f64 = 0.0000001; // compiler warn: variable does not need to be mutable
    let mut capitalChoice: f64;

    let mut iteration = 0;

    while maxDifference > tolerance {

        for nProductivity in 0..nGridProductivity {
            for nCapital in 0..nGridCapital {
                expectedValueFunction[nCapital][nProductivity] = 0.0;
                for nProductivityNextPeriod in 0..nGridProductivity {
                    expectedValueFunction[nCapital][nProductivity] +=
                        mTransition[nProductivity][nProductivityNextPeriod] *
                        mValueFunction[nCapital][nProductivityNextPeriod];
                }
            }
        }

        for nProductivity in 0..nGridProductivity {

        // We start from previous choice (monotonicity of policy function)
            let mut gridCapitalNextPeriod = 0;

            for nCapital in 0..nGridCapital {

                let mut valueHighSoFar = -100000.0;

                for nCapitalNextPeriod in gridCapitalNextPeriod..nGridCapital {

                    let consumption = mOutput[nCapital][nProductivity] -
                                  vGridCapital[nCapitalNextPeriod];
                    let valueProvisional = (1_f64 - bbeta) * (consumption.ln()) +
                                       bbeta *
                                       expectedValueFunction[nCapitalNextPeriod][nProductivity];

                    if valueProvisional > valueHighSoFar {
                        valueHighSoFar = valueProvisional;
                        capitalChoice = vGridCapital[nCapitalNextPeriod];
                        gridCapitalNextPeriod = nCapitalNextPeriod;
                    } else {
                        break; // We break when we have achieved the max
                    }

                    mValueFunctionNew[nCapital][nProductivity] = valueHighSoFar;
                    mPolicyFunction[nCapital][nProductivity] = capitalChoice;
                }

            }

        }

        let mut diffHighSoFar = -100000.0;
        for nProductivity in 0..nGridProductivity {
            for nCapital in 0..nGridCapital {
                let diff = (mValueFunction[nCapital][nProductivity] -
                        mValueFunctionNew[nCapital][nProductivity])
                           .abs();
                if diff > diffHighSoFar {
                    diffHighSoFar = diff;
                }
            }
        }

        // swap buffers after the loop
        mem::swap(&mut mValueFunction, &mut mValueFunctionNew);

        maxDifference = diffHighSoFar;

        iteration += 1;
        if iteration % 10 == 0 || iteration == 1 {
            println!("Iteration = {}, Sup Diff = {}", iteration, maxDifference);
        }
    }

    println!("Iteration = {}, Sup Diff = {}\n", iteration, maxDifference);
    println!("My check = {}\n", mPolicyFunction[999][2]);

    let cpu1 = precise_time_s();

    println!("Elapsed time is   = {}", cpu1  - cpu0);
}
<commit_msg>Simplify initialization<commit_after>#![allow(non_snake_case, non_upper_case_globals)]
extern crate time;

use time::precise_time_s;
use std::mem;

///////////////////////////////////////////////////////////////////////////////
// 1. Calibration
///////////////////////////////////////////////////////////////////////////////
const aalpha:f64 = 0.33333333333;  // Elasticity of output w.r.t. capital
const bbeta:f64 = 0.95;           // Discount factor

// Productivity values
const vProductivity:[f64; 5] = [0.9792, 0.9896, 1.0000, 1.0106, 1.0212];

// Transition matrix
const mTransition:[[f64; 5]; 5] = [[0.9727, 0.0273, 0.0000, 0.0000, 0.0000],
                                   [0.0041, 0.9806, 0.0153, 0.0000, 0.0000],
                                   [0.0000, 0.0082, 0.9837, 0.0082, 0.0000],
                                   [0.0000, 0.0000, 0.0153, 0.9806, 0.0041],
                                   [0.0000, 0.0000, 0.0000, 0.0273, 0.9727]];

// Dimensions to generate the grid of capital
const nGridCapital: usize = 17820;
const nGridProductivity: usize = 5;

fn main() {

    let cpu0 = precise_time_s();

  /////////////////////////////////////////////////////////////////////////////
  // 2. Steady State
  /////////////////////////////////////////////////////////////////////////////

    let capitalSteadyState: f64 = (aalpha * bbeta).powf(1_f64 / (1_f64 - aalpha));
    let outputSteadyState: f64 = capitalSteadyState.powf(aalpha);
    let consumptionSteadyState: f64 = outputSteadyState - capitalSteadyState;

    println!("\
    Output = {}, Capital = {}, Consumption = {}",
    outputSteadyState, capitalSteadyState, consumptionSteadyState);

    let vGridCapital = (0..nGridCapital)
                           .map(|nCapital| 0.5 * capitalSteadyState + 0.00001 * (nCapital as f64))
                           .collect::<Vec<f64>>();

    // 3. Required matrices and vectors
    let mut mValueFunction = vec![vec![0f64; nGridProductivity]; nGridCapital];
    let mut mValueFunctionNew = mValueFunction.clone();
    let mut mPolicyFunction = mValueFunction.clone();
    let mut expectedValueFunction = mValueFunction.clone();

    // 4. We pre-build output for each point in the grid
    let mOutput = (0..nGridCapital)
                      .map(|nCapital| {
                          (0..nGridProductivity).map(|nProductivity|
        vProductivity[nProductivity]*vGridCapital[nCapital].powf(aalpha)
      ).collect::<Vec<f64>>()
                      })
                      .collect::<Vec<Vec<f64>>>();

  // 5. Main iteration
  // TODO: one could implement a macro for the multiple declarations
    let mut maxDifference = 10_f64;
    const tolerance: f64 = 0.0000001; // compiler warn: variable does not need to be mutable
    let mut capitalChoice: f64;

    let mut iteration = 0;

    while maxDifference > tolerance {
        for nProductivity in 0..nGridProductivity {
            for nCapital in 0..nGridCapital {
                expectedValueFunction[nCapital][nProductivity] = 0.0;
                for nProductivityNextPeriod in 0..nGridProductivity {
                    expectedValueFunction[nCapital][nProductivity] +=
                        mTransition[nProductivity][nProductivityNextPeriod] *
                        mValueFunction[nCapital][nProductivityNextPeriod];
                }
            }
        }

        for nProductivity in 0..nGridProductivity {

        // We start from previous choice (monotonicity of policy function)
            let mut gridCapitalNextPeriod = 0;

            for nCapital in 0..nGridCapital {

                let mut valueHighSoFar = -100000.0;

                for nCapitalNextPeriod in gridCapitalNextPeriod..nGridCapital {

                    let consumption = mOutput[nCapital][nProductivity] -
                                  vGridCapital[nCapitalNextPeriod];
                    let valueProvisional = (1_f64 - bbeta) * (consumption.ln()) +
                                       bbeta *
                                       expectedValueFunction[nCapitalNextPeriod][nProductivity];

                    if valueProvisional > valueHighSoFar {
                        valueHighSoFar = valueProvisional;
                        capitalChoice = vGridCapital[nCapitalNextPeriod];
                        gridCapitalNextPeriod = nCapitalNextPeriod;
                    } else {
                        break; // We break when we have achieved the max
                    }

                    mValueFunctionNew[nCapital][nProductivity] = valueHighSoFar;
                    mPolicyFunction[nCapital][nProductivity] = capitalChoice;
                }

            }

        }

        let mut diffHighSoFar = -100000.0;
        for nProductivity in 0..nGridProductivity {
            for nCapital in 0..nGridCapital {
                let diff = (mValueFunction[nCapital][nProductivity] -
                        mValueFunctionNew[nCapital][nProductivity])
                           .abs();
                if diff > diffHighSoFar {
                    diffHighSoFar = diff;
                }
            }
        }

        // swap buffers after the loop
        mem::swap(&mut mValueFunction, &mut mValueFunctionNew);

        maxDifference = diffHighSoFar;

        iteration += 1;
        if iteration % 10 == 0 || iteration == 1 {
            println!("Iteration = {}, Sup Diff = {}", iteration, maxDifference);
        }
    }

    println!("Iteration = {}, Sup Diff = {}\n", iteration, maxDifference);
    println!("My check = {}\n", mPolicyFunction[999][2]);

    let cpu1 = precise_time_s();

    println!("Elapsed time is   = {}", cpu1  - cpu0);
}
<|endoftext|>


<commit_before>//! Contains Value and ValueRef structs and its conversion traits.

use std::convert::From;

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Integer {
    /// Every non-negative integer is treated as u64, even if it fits in i64.
    U64(u64),
    /// Every negative integer is treated as i64.
    I64(i64),
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Float {
    F32(f32),
    F64(f64),
}

#[derive(Clone, Debug, PartialEq)]
pub enum Value {
    /// Nil represents nil.
    Nil,
    /// Boolean represents true or false.
    Boolean(bool),
    /// Integer represents an integer.
    Integer(Integer),
    /// Float represents a floating point number.
    Float(Float),
    /// String extending Raw type represents a UTF-8 string.
    String(String),
    /// Binary extending Raw type represents a byte array.
    Binary(Vec<u8>),
    /// Array represents a sequence of objects.
    Array(Vec<Value>),
    /// Map represents key-value pairs of objects.
    Map(Vec<(Value, Value)>),
    /// Extended implements Extension interface: represents a tuple of type information and a byte
    /// array where type information is an integer whose meaning is defined by applications.
    Ext(i8, Vec<u8>),
}

impl Value {
    /// Returns true if the `Value` is a Null. Returns false otherwise.
    pub fn is_nil(&self) -> bool {
        if let Value::Nil = *self {
            true
        } else {
            false
        }
    }

    /// If the `Value` is a Boolean, returns the associated bool.
    /// Returns None otherwise.
    ///
    /// # Examples
    ///
    /// ```
    /// use rmp::Value;
    ///
    /// assert_eq!(Some(true), Value::Boolean(true).as_bool());
    /// assert_eq!(None, Value::Nil.as_bool());
    /// ```
    pub fn as_bool(&self) -> Option<bool> {
        if let Value::Boolean(val) = *self {
            Some(val)
        } else {
            None
        }
    }

    /// If the `Value` is an integer, return or cast it to a i64.
    /// Returns None otherwise.
    ///
    /// # Examples
    ///
    /// ```
    /// use rmp::Value;
    /// use rmp::value::{Float, Integer};
    ///
    /// assert_eq!(Some(42i64), Value::Integer(Integer::I64(42)).as_i64());
    /// assert_eq!(Some(42i64), Value::Integer(Integer::U64(42)).as_i64());
    ///
    /// assert_eq!(None, Value::Float(Float::F64(42.0)).as_i64());
    /// ```
    pub fn as_i64(&self) -> Option<i64> {
        match *self {
            Value::Integer(Integer::I64(n)) => Some(n),
            Value::Integer(Integer::U64(n)) if n <= i64::max_value() as u64 => Some(n as i64),
            _ => None,
        }
    }

    /// If the `Value` is an integer, return or cast it to a u64.
    /// Returns None otherwise.
    ///
    /// # Examples
    ///
    /// ```
    /// use rmp::Value;
    /// use rmp::value::{Float, Integer};
    ///
    /// assert_eq!(Some(42u64), Value::Integer(Integer::I64(42)).as_u64());
    /// assert_eq!(Some(42u64), Value::Integer(Integer::U64(42)).as_u64());
    ///
    /// assert_eq!(None, Value::Integer(Integer::I64(-42)).as_u64());
    /// assert_eq!(None, Value::Float(Float::F64(42.0)).as_u64());
    /// ```
    pub fn as_u64(&self) -> Option<u64> {
        match *self {
            Value::Integer(Integer::I64(n)) if 0 <= n => Some(n as u64),
            Value::Integer(Integer::U64(n)) => Some(n),
            _ => None,
        }
    }

    /// If the `Value` is a number, return or cast it to a f64.
    /// Returns None otherwise.
    ///
    /// # Examples
    ///
    /// ```
    /// use rmp::Value;
    /// use rmp::value::{Float, Integer};
    ///
    /// assert_eq!(Some(42.0), Value::Integer(Integer::I64(42)).as_f64());
    /// assert_eq!(Some(42.0), Value::Integer(Integer::U64(42)).as_f64());
    /// assert_eq!(Some(42.0), Value::Float(Float::F32(42.0f32)).as_f64());
    /// assert_eq!(Some(42.0), Value::Float(Float::F64(42.0f64)).as_f64());
    ///
    /// assert_eq!(Some(2147483647.0), Value::Integer(Integer::I64(i32::max_value() as i64)).as_f64());
    ///
    /// assert_eq!(None, Value::Nil.as_f64());
    ///
    /// assert_eq!(None, Value::Integer(Integer::I64(i32::max_value() as i64 + 1)).as_f64());
    /// ```
    pub fn as_f64(&self) -> Option<f64> {
        match *self {
            Value::Integer(Integer::I64(n)) if (i32::min_value() as i64 <= n) && (n <= i32::max_value() as i64) => {
                Some(From::from(n as i32))
            }
            Value::Integer(Integer::U64(n)) if n <= u32::max_value() as u64 => {
                Some(From::from(n as u32))
            }
            Value::Float(Float::F32(n)) => Some(From::from(n)),
            Value::Float(Float::F64(n)) => Some(n),
            _ => None,
        }
    }

    /// If the `Value` is a String, returns the associated str.
    /// Returns None otherwise.
    ///
    /// # Examples
    ///
    /// ```
    /// use rmp::Value;
    ///
    /// assert_eq!(Some("le message"), Value::String("le message".into()).as_str());
    ///
    /// assert_eq!(None, Value::Boolean(true).as_str());
    /// ```
    pub fn as_str(&self) -> Option<&str> {
        if let Value::String(ref val) = *self {
            Some(val)
        } else {
            None
        }
    }

    /// If the `Value` is an Array, returns the associated vector.
    /// Returns None otherwise.
    ///
    /// # Examples
    ///
    /// ```
    /// use rmp::Value;
    ///
    /// let val = Value::Array(vec![Value::Nil, Value::Boolean(true)]);
    ///
    /// assert_eq!(Some(&vec![Value::Nil, Value::Boolean(true)]), val.as_array());
    ///
    /// assert_eq!(None, Value::Nil.as_array());
    /// ```
    pub fn as_array(&self) -> Option<&Vec<Value>> {
        if let Value::Array(ref array) = *self {
            Some(&*array)
        } else {
            None
        }
    }
}

impl From<bool> for Value {
    fn from(v: bool) -> Value {
        Value::Boolean(v)
    }
}

impl From<u8> for Value {
    fn from(v: u8) -> Value {
        Value::Integer(Integer::U64(From::from(v)))
    }
}

impl From<u16> for Value {
    fn from(v: u16) -> Value {
        Value::Integer(Integer::U64(From::from(v)))
    }
}

impl From<u32> for Value {
    fn from(v: u32) -> Value {
        Value::Integer(Integer::U64(From::from(v)))
    }
}

impl From<u64> for Value {
    fn from(v: u64) -> Value {
        Value::Integer(Integer::U64(From::from(v)))
    }
}

impl From<usize> for Value {
    fn from(v: usize) -> Value {
        Value::Integer(Integer::U64(v as u64))
    }
}

impl From<i8> for Value {
    fn from(v: i8) -> Value {
        Value::Integer(Integer::I64(From::from(v)))
    }
}

impl From<i16> for Value {
    fn from(v: i16) -> Value {
        Value::Integer(Integer::I64(From::from(v)))
    }
}

impl From<i32> for Value {
    fn from(v: i32) -> Value {
        Value::Integer(Integer::I64(From::from(v)))
    }
}

impl From<i64> for Value {
    fn from(v: i64) -> Value {
        Value::Integer(Integer::I64(From::from(v)))
    }
}

impl From<isize> for Value {
    fn from(v: isize) -> Value {
        Value::Integer(Integer::I64(v as i64))
    }
}

impl From<f32> for Value {
    fn from(v: f32) -> Value {
        Value::Float(Float::F32(v))
    }
}

impl From<f64> for Value {
    fn from(v: f64) -> Value {
        Value::Float(Float::F64(v))
    }
}

/// Implements human-readable value formatting.
impl ::std::fmt::Display for Value {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        match *self {
            Value::Nil => write!(f, "nil"),
            Value::Boolean(val) => write!(f, "{}", val),
            Value::Integer(Integer::U64(val)) => write!(f, "{}", val),
            Value::Integer(Integer::I64(val)) => write!(f, "{}", val),
            Value::Float(Float::F32(val)) => write!(f, "{}", val),
            Value::Float(Float::F64(val)) => write!(f, "{}", val),
            Value::String(ref val) => write!(f, "\"{}\"", val),
            Value::Binary(ref val) => write!(f, "{:?}", val),
            Value::Array(ref vec) => {
                // TODO: This can be slower than naive implementation. Need benchmarks for more
                // information.
                let res = vec.iter()
                    .map(|val| format!("{}", val))
                    .collect::<Vec<String>>()
                    .join(", ");

                write!(f, "[{}]", res)
            }
            Value::Map(ref vec) => {
                try!(write!(f, "{{"));

                match vec.iter().take(1).next() {
                    Some(&(ref k, ref v)) => {
                        try!(write!(f, "{}: {}", k, v));
                    }
                    None => {
                        try!(write!(f, ""));
                    }
                }

                for &(ref k, ref v) in vec.iter().skip(1) {
                    try!(write!(f, ", {}: {}", k, v));
                }

                write!(f, "}}")
            }
            Value::Ext(ty, ref data) => {
                write!(f, "[{}, {:?}]", ty, data)
            }
        }
    }
}

#[derive(Clone, Debug, PartialEq)]
pub enum ValueRef<'a> {
    /// Nil represents nil.
    Nil,
    /// Boolean represents true or false.
    Boolean(bool),
    /// Integer represents an integer.
    Integer(Integer),
    /// Float represents a floating point number.
    Float(Float),
    /// String extending Raw type represents a UTF-8 string.
    String(&'a str),
    /// Binary extending Raw type represents a byte array.
    Binary(&'a [u8]),
    /// Array represents a sequence of objects.
    Array(Vec<ValueRef<'a>>),
    /// Map represents key-value pairs of objects.
    Map(Vec<(ValueRef<'a>, ValueRef<'a>)>),
    /// Extended implements Extension interface: represents a tuple of type information and a byte
    /// array where type information is an integer whose meaning is defined by applications.
    Ext(i8, &'a [u8]),
}

impl<'a> ValueRef<'a> {
    /// Converts the current non-owning value to an owned Value.
    ///
    /// This is achieved by deep copying all underlying structures and borrowed buffers.
    ///
    /// # Panics
    ///
    /// Panics in unable to allocate memory to keep all internal structures and buffers.
    ///
    /// # Examples
    /// ```
    /// use rmp::{Value, ValueRef};
    /// use rmp::value::Integer;
    ///
    /// let val = ValueRef::Array(vec![
    ///    ValueRef::Nil,
    ///    ValueRef::Integer(Integer::U64(42)),
    ///    ValueRef::Array(vec![
    ///        ValueRef::String("le message"),
    ///    ])
    /// ]);
    ///
    /// let expected = Value::Array(vec![
    ///     Value::Nil,
    ///     Value::Integer(Integer::U64(42)),
    ///     Value::Array(vec![
    ///         Value::String("le message".to_string())
    ///     ])
    /// ]);
    ///
    /// assert_eq!(expected, val.to_owned());
    /// ```
    pub fn to_owned(&self) -> Value {
        match self {
            &ValueRef::Nil => Value::Nil,
            &ValueRef::Boolean(val) => Value::Boolean(val),
            &ValueRef::Integer(val) => Value::Integer(val),
            &ValueRef::Float(val) => Value::Float(val),
            &ValueRef::String(val) => Value::String(val.to_owned()),
            &ValueRef::Binary(val) => Value::Binary(val.to_vec()),
            &ValueRef::Array(ref val) => {
                Value::Array(val.iter().map(|v| v.to_owned()).collect())
            }
            &ValueRef::Map(ref val) => {
                Value::Map(val.iter().map(|&(ref k, ref v)| (k.to_owned(), v.to_owned())).collect())
            }
            &ValueRef::Ext(ty, buf) => Value::Ext(ty, buf.to_vec()),
        }
    }
}

// For some weird reasons I can't implement it manually.
// It gives: conflicting implementations for trait `collections::borrow::ToOwned`
// impl<'a> ToOwned for ValueRef<'a> {
//     type Owned = Value;
// }
<commit_msg>feat: add map view for value<commit_after>//! Contains Value and ValueRef structs and its conversion traits.

use std::convert::From;

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Integer {
    /// Every non-negative integer is treated as u64, even if it fits in i64.
    U64(u64),
    /// Every negative integer is treated as i64.
    I64(i64),
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Float {
    F32(f32),
    F64(f64),
}

#[derive(Clone, Debug, PartialEq)]
pub enum Value {
    /// Nil represents nil.
    Nil,
    /// Boolean represents true or false.
    Boolean(bool),
    /// Integer represents an integer.
    Integer(Integer),
    /// Float represents a floating point number.
    Float(Float),
    /// String extending Raw type represents a UTF-8 string.
    String(String),
    /// Binary extending Raw type represents a byte array.
    Binary(Vec<u8>),
    /// Array represents a sequence of objects.
    Array(Vec<Value>),
    /// Map represents key-value pairs of objects.
    Map(Vec<(Value, Value)>),
    /// Extended implements Extension interface: represents a tuple of type information and a byte
    /// array where type information is an integer whose meaning is defined by applications.
    Ext(i8, Vec<u8>),
}

impl Value {
    /// Returns true if the `Value` is a Null. Returns false otherwise.
    pub fn is_nil(&self) -> bool {
        if let Value::Nil = *self {
            true
        } else {
            false
        }
    }

    /// If the `Value` is a Boolean, returns the associated bool.
    /// Returns None otherwise.
    ///
    /// # Examples
    ///
    /// ```
    /// use rmp::Value;
    ///
    /// assert_eq!(Some(true), Value::Boolean(true).as_bool());
    /// assert_eq!(None, Value::Nil.as_bool());
    /// ```
    pub fn as_bool(&self) -> Option<bool> {
        if let Value::Boolean(val) = *self {
            Some(val)
        } else {
            None
        }
    }

    /// If the `Value` is an integer, return or cast it to a i64.
    /// Returns None otherwise.
    ///
    /// # Examples
    ///
    /// ```
    /// use rmp::Value;
    /// use rmp::value::{Float, Integer};
    ///
    /// assert_eq!(Some(42i64), Value::Integer(Integer::I64(42)).as_i64());
    /// assert_eq!(Some(42i64), Value::Integer(Integer::U64(42)).as_i64());
    ///
    /// assert_eq!(None, Value::Float(Float::F64(42.0)).as_i64());
    /// ```
    pub fn as_i64(&self) -> Option<i64> {
        match *self {
            Value::Integer(Integer::I64(n)) => Some(n),
            Value::Integer(Integer::U64(n)) if n <= i64::max_value() as u64 => Some(n as i64),
            _ => None,
        }
    }

    /// If the `Value` is an integer, return or cast it to a u64.
    /// Returns None otherwise.
    ///
    /// # Examples
    ///
    /// ```
    /// use rmp::Value;
    /// use rmp::value::{Float, Integer};
    ///
    /// assert_eq!(Some(42u64), Value::Integer(Integer::I64(42)).as_u64());
    /// assert_eq!(Some(42u64), Value::Integer(Integer::U64(42)).as_u64());
    ///
    /// assert_eq!(None, Value::Integer(Integer::I64(-42)).as_u64());
    /// assert_eq!(None, Value::Float(Float::F64(42.0)).as_u64());
    /// ```
    pub fn as_u64(&self) -> Option<u64> {
        match *self {
            Value::Integer(Integer::I64(n)) if 0 <= n => Some(n as u64),
            Value::Integer(Integer::U64(n)) => Some(n),
            _ => None,
        }
    }

    /// If the `Value` is a number, return or cast it to a f64.
    /// Returns None otherwise.
    ///
    /// # Examples
    ///
    /// ```
    /// use rmp::Value;
    /// use rmp::value::{Float, Integer};
    ///
    /// assert_eq!(Some(42.0), Value::Integer(Integer::I64(42)).as_f64());
    /// assert_eq!(Some(42.0), Value::Integer(Integer::U64(42)).as_f64());
    /// assert_eq!(Some(42.0), Value::Float(Float::F32(42.0f32)).as_f64());
    /// assert_eq!(Some(42.0), Value::Float(Float::F64(42.0f64)).as_f64());
    ///
    /// assert_eq!(Some(2147483647.0), Value::Integer(Integer::I64(i32::max_value() as i64)).as_f64());
    ///
    /// assert_eq!(None, Value::Nil.as_f64());
    ///
    /// assert_eq!(None, Value::Integer(Integer::I64(i32::max_value() as i64 + 1)).as_f64());
    /// ```
    pub fn as_f64(&self) -> Option<f64> {
        match *self {
            Value::Integer(Integer::I64(n)) if (i32::min_value() as i64 <= n) && (n <= i32::max_value() as i64) => {
                Some(From::from(n as i32))
            }
            Value::Integer(Integer::U64(n)) if n <= u32::max_value() as u64 => {
                Some(From::from(n as u32))
            }
            Value::Float(Float::F32(n)) => Some(From::from(n)),
            Value::Float(Float::F64(n)) => Some(n),
            _ => None,
        }
    }

    /// If the `Value` is a String, returns the associated str.
    /// Returns None otherwise.
    ///
    /// # Examples
    ///
    /// ```
    /// use rmp::Value;
    ///
    /// assert_eq!(Some("le message"), Value::String("le message".into()).as_str());
    ///
    /// assert_eq!(None, Value::Boolean(true).as_str());
    /// ```
    pub fn as_str(&self) -> Option<&str> {
        if let Value::String(ref val) = *self {
            Some(val)
        } else {
            None
        }
    }

    /// If the `Value` is an Array, returns the associated vector.
    /// Returns None otherwise.
    ///
    /// # Examples
    ///
    /// ```
    /// use rmp::Value;
    ///
    /// let val = Value::Array(vec![Value::Nil, Value::Boolean(true)]);
    ///
    /// assert_eq!(Some(&vec![Value::Nil, Value::Boolean(true)]), val.as_array());
    ///
    /// assert_eq!(None, Value::Nil.as_array());
    /// ```
    pub fn as_array(&self) -> Option<&Vec<Value>> {
        if let Value::Array(ref array) = *self {
            Some(&*array)
        } else {
            None
        }
    }

    /// If the `Value` is a Map, returns the associated vector of key-value tuples.
    /// Returns None otherwise.
    ///
    /// # Note
    ///
    /// MessagePack represents map as a vector of key-value tuples.
    ///
    /// # Examples
    ///
    /// ```
    /// use rmp::Value;
    ///
    /// let val = Value::Map(vec![(Value::Nil, Value::Boolean(true))]);
    ///
    /// assert_eq!(Some(&vec![(Value::Nil, Value::Boolean(true))]), val.as_map());
    ///
    /// assert_eq!(None, Value::Nil.as_map());
    /// ```
    pub fn as_map(&self) -> Option<&Vec<(Value, Value)>> {
        if let Value::Map(ref map) = *self {
            Some(map)
        } else {
            None
        }
    }
}

impl From<bool> for Value {
    fn from(v: bool) -> Value {
        Value::Boolean(v)
    }
}

impl From<u8> for Value {
    fn from(v: u8) -> Value {
        Value::Integer(Integer::U64(From::from(v)))
    }
}

impl From<u16> for Value {
    fn from(v: u16) -> Value {
        Value::Integer(Integer::U64(From::from(v)))
    }
}

impl From<u32> for Value {
    fn from(v: u32) -> Value {
        Value::Integer(Integer::U64(From::from(v)))
    }
}

impl From<u64> for Value {
    fn from(v: u64) -> Value {
        Value::Integer(Integer::U64(From::from(v)))
    }
}

impl From<usize> for Value {
    fn from(v: usize) -> Value {
        Value::Integer(Integer::U64(v as u64))
    }
}

impl From<i8> for Value {
    fn from(v: i8) -> Value {
        Value::Integer(Integer::I64(From::from(v)))
    }
}

impl From<i16> for Value {
    fn from(v: i16) -> Value {
        Value::Integer(Integer::I64(From::from(v)))
    }
}

impl From<i32> for Value {
    fn from(v: i32) -> Value {
        Value::Integer(Integer::I64(From::from(v)))
    }
}

impl From<i64> for Value {
    fn from(v: i64) -> Value {
        Value::Integer(Integer::I64(From::from(v)))
    }
}

impl From<isize> for Value {
    fn from(v: isize) -> Value {
        Value::Integer(Integer::I64(v as i64))
    }
}

impl From<f32> for Value {
    fn from(v: f32) -> Value {
        Value::Float(Float::F32(v))
    }
}

impl From<f64> for Value {
    fn from(v: f64) -> Value {
        Value::Float(Float::F64(v))
    }
}

/// Implements human-readable value formatting.
impl ::std::fmt::Display for Value {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        match *self {
            Value::Nil => write!(f, "nil"),
            Value::Boolean(val) => write!(f, "{}", val),
            Value::Integer(Integer::U64(val)) => write!(f, "{}", val),
            Value::Integer(Integer::I64(val)) => write!(f, "{}", val),
            Value::Float(Float::F32(val)) => write!(f, "{}", val),
            Value::Float(Float::F64(val)) => write!(f, "{}", val),
            Value::String(ref val) => write!(f, "\"{}\"", val),
            Value::Binary(ref val) => write!(f, "{:?}", val),
            Value::Array(ref vec) => {
                // TODO: This can be slower than naive implementation. Need benchmarks for more
                // information.
                let res = vec.iter()
                    .map(|val| format!("{}", val))
                    .collect::<Vec<String>>()
                    .join(", ");

                write!(f, "[{}]", res)
            }
            Value::Map(ref vec) => {
                try!(write!(f, "{{"));

                match vec.iter().take(1).next() {
                    Some(&(ref k, ref v)) => {
                        try!(write!(f, "{}: {}", k, v));
                    }
                    None => {
                        try!(write!(f, ""));
                    }
                }

                for &(ref k, ref v) in vec.iter().skip(1) {
                    try!(write!(f, ", {}: {}", k, v));
                }

                write!(f, "}}")
            }
            Value::Ext(ty, ref data) => {
                write!(f, "[{}, {:?}]", ty, data)
            }
        }
    }
}

#[derive(Clone, Debug, PartialEq)]
pub enum ValueRef<'a> {
    /// Nil represents nil.
    Nil,
    /// Boolean represents true or false.
    Boolean(bool),
    /// Integer represents an integer.
    Integer(Integer),
    /// Float represents a floating point number.
    Float(Float),
    /// String extending Raw type represents a UTF-8 string.
    String(&'a str),
    /// Binary extending Raw type represents a byte array.
    Binary(&'a [u8]),
    /// Array represents a sequence of objects.
    Array(Vec<ValueRef<'a>>),
    /// Map represents key-value pairs of objects.
    Map(Vec<(ValueRef<'a>, ValueRef<'a>)>),
    /// Extended implements Extension interface: represents a tuple of type information and a byte
    /// array where type information is an integer whose meaning is defined by applications.
    Ext(i8, &'a [u8]),
}

impl<'a> ValueRef<'a> {
    /// Converts the current non-owning value to an owned Value.
    ///
    /// This is achieved by deep copying all underlying structures and borrowed buffers.
    ///
    /// # Panics
    ///
    /// Panics in unable to allocate memory to keep all internal structures and buffers.
    ///
    /// # Examples
    /// ```
    /// use rmp::{Value, ValueRef};
    /// use rmp::value::Integer;
    ///
    /// let val = ValueRef::Array(vec![
    ///    ValueRef::Nil,
    ///    ValueRef::Integer(Integer::U64(42)),
    ///    ValueRef::Array(vec![
    ///        ValueRef::String("le message"),
    ///    ])
    /// ]);
    ///
    /// let expected = Value::Array(vec![
    ///     Value::Nil,
    ///     Value::Integer(Integer::U64(42)),
    ///     Value::Array(vec![
    ///         Value::String("le message".to_string())
    ///     ])
    /// ]);
    ///
    /// assert_eq!(expected, val.to_owned());
    /// ```
    pub fn to_owned(&self) -> Value {
        match self {
            &ValueRef::Nil => Value::Nil,
            &ValueRef::Boolean(val) => Value::Boolean(val),
            &ValueRef::Integer(val) => Value::Integer(val),
            &ValueRef::Float(val) => Value::Float(val),
            &ValueRef::String(val) => Value::String(val.to_owned()),
            &ValueRef::Binary(val) => Value::Binary(val.to_vec()),
            &ValueRef::Array(ref val) => {
                Value::Array(val.iter().map(|v| v.to_owned()).collect())
            }
            &ValueRef::Map(ref val) => {
                Value::Map(val.iter().map(|&(ref k, ref v)| (k.to_owned(), v.to_owned())).collect())
            }
            &ValueRef::Ext(ty, buf) => Value::Ext(ty, buf.to_vec()),
        }
    }
}

// For some weird reasons I can't implement it manually.
// It gives: conflicting implementations for trait `collections::borrow::ToOwned`
// impl<'a> ToOwned for ValueRef<'a> {
//     type Owned = Value;
// }
<|endoftext|>


<commit_before>extern crate fuse;
extern crate libc;
extern crate time;
extern crate argparse;

use std::string::String;
use std::fmt;
use std::env;
use std::path::Path;
use std::collections::HashMap;
use std::ffi::OsStr;

use libc::ENOENT;
use time::Timespec;
use argparse::{ArgumentParser, StoreTrue, Store};
use fuse::{FileType, FileAttr, Filesystem, Request, ReplyData, ReplyEntry, ReplyAttr, ReplyDirectory};

const TTL: Timespec = Timespec { sec: 1, nsec: 0 };                 // 1 second

const CREATE_TIME: Timespec = Timespec { sec: 1381237736, nsec: 0 };    // 2013-10-08 08:56

const HELLO_DIR_ATTR: FileAttr = FileAttr {
    ino: 1,
    size: 0,
    blocks: 0,
    atime: CREATE_TIME,
    mtime: CREATE_TIME,
    ctime: CREATE_TIME,
    crtime: CREATE_TIME,
    kind: FileType::Directory,
    perm: 0o755,
    nlink: 2,
    uid: 501,
    gid: 20,
    rdev: 0,
    flags: 0,
};

const HELLO_TXT_CONTENT: &'static str = "Hello World!\n";

const HELLO_TXT_ATTR: FileAttr = FileAttr {
    ino: 2,
    size: 13,
    blocks: 1,
    atime: CREATE_TIME,
    mtime: CREATE_TIME,
    ctime: CREATE_TIME,
    crtime: CREATE_TIME,
    kind: FileType::RegularFile,
    perm: 0o644,
    nlink: 1,
    uid: 501,
    gid: 20,
    rdev: 0,
    flags: 0,
};

struct UrchinFS;

impl Filesystem for UrchinFS {
    fn lookup (&mut self, _req: &Request, parent: u64, name: &Path, reply: ReplyEntry) {
        if parent == 1 && name.to_str() == Some("hello.txt") {
            reply.entry(&TTL, &HELLO_TXT_ATTR, 0);
        } else {
            reply.error(ENOENT);
        }
    }

    fn getattr (&mut self, _req: &Request, ino: u64, reply: ReplyAttr) {
        match ino {
            1 => reply.attr(&TTL, &HELLO_DIR_ATTR),
            2 => reply.attr(&TTL, &HELLO_TXT_ATTR),
            _ => reply.error(ENOENT),
        }
    }

    fn read (&mut self, _req: &Request, ino: u64, _fh: u64, offset: u64, _size: u32, reply: ReplyData) {
        if ino == 2 {
            reply.data(&HELLO_TXT_CONTENT.as_bytes()[offset as usize..]);
        } else {
            reply.error(ENOENT);
        }
    }

    fn readdir (&mut self, _req: &Request, ino: u64, _fh: u64, offset: u64, mut reply: ReplyDirectory) {
        if ino == 1 {
            if offset == 0 {
                reply.add(1, 0, FileType::Directory, ".");
                reply.add(1, 1, FileType::Directory, "..");
                reply.add(2, 2, FileType::RegularFile, "hello.txt");
            }
            reply.ok();
        } else {
            reply.error(ENOENT);
        }
    }
}

fn main () {
    let mut mountpoint = String::new();
    let mut optstr = String::new();
    {
        let mut ap = ArgumentParser::new();
        ap.set_description("faceted-search FUSE filesystem");
        ap.refer(&mut optstr).add_option(&["-o", "--options"], Store, "comma-separated mount options");
        ap.refer(&mut mountpoint).add_argument("mountpoint", Store, "the mountpoint").required();
        ap.parse_args_or_exit();
    }

    // FIXME seems weird to have to have two variable refs
    let vec;
    let mut options : &[&OsStr] = &[];
    if optstr!= "" {
        vec = optstr.split(",").map(|s| OsStr::new(s)).collect::<Vec<_>>();
        options = &vec;
    }
    fuse::mount(UrchinFS, &mountpoint, options);
}
<commit_msg>stub out entries<commit_after>extern crate fuse;
extern crate libc;
extern crate time;
extern crate argparse;

use std::string::String;
use std::fmt;
use std::env;
use std::path::Path;
use std::collections::{HashMap, HashSet};
use std::ffi::OsStr;

use libc::{ENOSYS,c_int,ENOENT};
use time::Timespec;
use argparse::{ArgumentParser, StoreTrue, Store};
use fuse::{FileType, FileAttr, Filesystem, Request, ReplyData, ReplyEntry, ReplyAttr, ReplyDirectory};

// FIXME these are ugly as fuck and it seems like a BAD DECISION to have these kind of macros in rust.
// FIXME in any case, clean up our usage of these later.
// from: http://stackoverflow.com/questions/28392008/more-concise-hashmap-initialization
// auto-converts to String
macro_rules! hashmap {
    ($( $key: expr => $val: expr ),*) => {{
         let mut map = ::std::collections::HashMap::new();
         $( map.insert($key.to_string(), $val); )*
         map
    }}
}
// similar to above, jesus christ this is terrible
macro_rules! hashset {
    ($( $x: expr ),* ) => {{
            let mut set = HashSet::new();
            $( set.insert($x.to_string()); )*
            set
    }}
}

const TTL: Timespec = Timespec { sec: 1, nsec: 0 };                 // 1 second

const CREATE_TIME: Timespec = Timespec { sec: 1381237736, nsec: 0 };    // 2013-10-08 08:56

const HELLO_DIR_ATTR: FileAttr = FileAttr {
    ino: 1,
    size: 0,
    blocks: 0,
    atime: CREATE_TIME,
    mtime: CREATE_TIME,
    ctime: CREATE_TIME,
    crtime: CREATE_TIME,
    kind: FileType::Directory,
    perm: 0o755,
    nlink: 2,
    uid: 501,
    gid: 20,
    rdev: 0,
    flags: 0,
};

const HELLO_TXT_CONTENT: &'static str = "Hello World!\n";

const HELLO_TXT_ATTR: FileAttr = FileAttr {
    ino: 2,
    size: 13,
    blocks: 1,
    atime: CREATE_TIME,
    mtime: CREATE_TIME,
    ctime: CREATE_TIME,
    crtime: CREATE_TIME,
    kind: FileType::RegularFile,
    perm: 0o644,
    nlink: 1,
    uid: 501,
    gid: 20,
    rdev: 0,
    flags: 0,
};

struct UrchinFSEntry {
    display_name: String,
    destination: String,
    metadata: HashMap<String, HashSet<String>>
}

struct UrchinFS {
    entries: Vec<UrchinFSEntry>
}

impl Filesystem for UrchinFS {
    fn lookup (&mut self, _req: &Request, parent: u64, name: &Path, reply: ReplyEntry) {
        if parent == 1 && name.to_str() == Some("hello.txt") {
            reply.entry(&TTL, &HELLO_TXT_ATTR, 0);
        } else {
            reply.error(ENOENT);
        }
    }

    fn getattr (&mut self, _req: &Request, ino: u64, reply: ReplyAttr) {
        match ino {
            1 => reply.attr(&TTL, &HELLO_DIR_ATTR),
            2 => reply.attr(&TTL, &HELLO_TXT_ATTR),
            _ => reply.error(ENOENT),
        }
    }

    fn read (&mut self, _req: &Request, ino: u64, _fh: u64, offset: u64, _size: u32, reply: ReplyData) {
        if ino == 2 {
            reply.data(&HELLO_TXT_CONTENT.as_bytes()[offset as usize..]);
        } else {
            reply.error(ENOENT);
        }
    }

    fn readdir (&mut self, _req: &Request, ino: u64, _fh: u64, offset: u64, mut reply: ReplyDirectory) {
        if ino == 1 {
            if offset == 0 {
                reply.add(1, 0, FileType::Directory, ".");
                reply.add(1, 1, FileType::Directory, "..");
                reply.add(2, 2, FileType::RegularFile, "hello.txt");
            }
            reply.ok();
        } else {
            reply.error(ENOENT);
        }
    }
}

fn main () {
    let mut mountpoint = String::new();
    let mut optstr = String::new();
    {
        let mut ap = ArgumentParser::new();
        ap.set_description("faceted-search FUSE filesystem");
        ap.refer(&mut optstr).add_option(&["-o", "--options"], Store, "comma-separated mount options");
        ap.refer(&mut mountpoint).add_argument("mountpoint", Store, "the mountpoint").required();
        ap.parse_args_or_exit();
    }

    // FIXME seems weird to have to have two variable refs
    let vec;
    let mut options : &[&OsStr] = &[];
    if optstr!= "" {
        vec = optstr.split(",").map(|s| OsStr::new(s)).collect::<Vec<_>>();
        options = &vec;
    }

    // FIMXE do this better
    let easter = UrchinFSEntry {
        display_name: "Easter Parade (1948) color".to_string(),
        destination: "/home/kellen/test".to_string(),
        metadata: hashmap!["year" => hashset!["1948"], "color" => hashset!["color"]]
    };

    let entries = vec![easter];

    //
    fuse::mount(UrchinFS {entries: entries}, &mountpoint, options);
}
<|endoftext|>


<commit_before>// -----------------------------------------------
// Framework <https://github.com/vain0x/procon>
//
// See the bottom of file for solution.
// -----------------------------------------------

#![allow(unused_imports)]
#![allow(non_snake_case)]

use std::cell::RefCell;
use std::cmp::{max, min, Ordering};
use std::collections::*;
use std::fmt::{Debug, Display, Formatter, Write as FmtWrite};
use std::io::{stderr, stdin, BufRead, Write};
use std::mem::{replace, swap};
use std::ops::*;
use std::rc::Rc;

#[allow(unused_macros)]
macro_rules! debug {
    ($($e:expr),*) => {
        #[cfg(debug_assertions)]
        $({
            let (e, mut err) = (stringify!($e), stderr());
            writeln!(err, "\x1B[33m{}\x1B[0m = {:?}", e, $e).unwrap()
        })*
    };
}

#[allow(unused_macros)]
macro_rules! read {
    ([$t:ty] ; $n:expr) =>
        ((0..$n).map(|_| read!([$t])).collect::<Vec<_>>());
    ($($t:ty),+ ; $n:expr) =>
        ((0..$n).map(|_| read!($($t),+)).collect::<Vec<_>>());
    ([$t:ty]) =>
        (rl().split_whitespace().map(|w| w.parse().unwrap()).collect::<Vec<$t>>());
    ($($t:ty),*) => {{
        let buf = rl();
        let mut w = buf.split_whitespace();
        ($(w.next().unwrap().parse::<$t>().unwrap()),*)
    }};
}

#[allow(dead_code)]
fn rl() -> String {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    buf.trim_right().to_owned()
}

// -----------------------------------------------
// Solution
// -----------------------------------------------

fn main() {
    println!("{}", 0)
}
<commit_msg>refactor: Add comments to Rust solver<commit_after>// -----------------------------------------------
// Framework <https://github.com/vain0x/procon>
//
// See the bottom of file for solution.
// -----------------------------------------------

#![allow(unused_imports)]
#![allow(non_snake_case)]

use std::cell::RefCell;
use std::cmp::{max, min, Ordering};
use std::collections::*;
use std::fmt::{Debug, Display, Formatter, Write as FmtWrite};
use std::io::{stderr, stdin, BufRead, Write};
use std::mem::{replace, swap};
use std::ops::*;
use std::rc::Rc;

/// Print values to standard error if debug mode.
#[allow(unused_macros)]
macro_rules! debug {
    ($($e:expr),*) => {
        #[cfg(debug_assertions)]
        $({
            let (e, mut err) = (stringify!($e), stderr());
            writeln!(err, "\x1B[33m{}\x1B[0m = {:?}", e, $e).unwrap()
        })*
    };
}

/// Read from standard input and parse each word.
/// - `read!(T, U, ..)` parses a line as a tuple of words.
/// - `read![[T]]` parses a line as an array of words.
/// - `read![..; N]` parses `N` lines, using `read!(..)` repeatedly.
#[allow(unused_macros)]
macro_rules! read {
    ([$t:ty] ; $n:expr) =>
        ((0..$n).map(|_| read!([$t])).collect::<Vec<_>>());
    ($($t:ty),+ ; $n:expr) =>
        ((0..$n).map(|_| read!($($t),+)).collect::<Vec<_>>());
    ([$t:ty]) =>
        (rl().split_whitespace().map(|w| w.parse().unwrap()).collect::<Vec<$t>>());
    ($($t:ty),*) => {{
        let buf = rl();
        let mut w = buf.split_whitespace();
        ($(w.next().unwrap().parse::<$t>().unwrap()),*)
    }};
}

/// Read a line from standard input.
#[allow(dead_code)]
fn rl() -> String {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    buf.trim_right().to_owned()
}

// -----------------------------------------------
// Solution
// -----------------------------------------------

fn main() {
    println!("{}", 0)
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Chef Software Inc. and/or applicable contributors
//
// 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.

pub fn get_uid_by_name(owner: &str) -> Option<u32> {
    unimplemented!();
}

pub fn get_gid_by_name(group: &str) -> Option<u32> {
    unimplemented!();
}

pub fn get_effective_uid() -> u32 {
    unimplemented!();
}
<commit_msg>stub out response for get_effective_uid<commit_after>// Copyright (c) 2016 Chef Software Inc. and/or applicable contributors
//
// 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.

pub fn get_uid_by_name(owner: &str) -> Option<u32> {
    unimplemented!();
}

pub fn get_gid_by_name(group: &str) -> Option<u32> {
    unimplemented!();
}

pub fn get_effective_uid() -> u32 {
    0u32
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use cssparser::ToCss;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::Bindings::EventListenerBinding::EventListener;
use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
use dom::bindings::codegen::Bindings::MediaQueryListBinding::{self, MediaQueryListMethods};
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, Root};
use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString;
use dom::bindings::trace::JSTraceable;
use dom::bindings::weakref::{WeakRef, WeakRefVec};
use dom::document::Document;
use dom::eventtarget::EventTarget;
use euclid::scale_factor::ScaleFactor;
use js::jsapi::JSTracer;
use std::cell::Cell;
use std::rc::Rc;
use style;
use style::media_queries::{Device, MediaType};
use style_traits::{PagePx, ViewportPx};

pub enum MediaQueryListMatchState {
    Same(bool),
    Changed(bool),
}

#[dom_struct]
pub struct MediaQueryList {
    eventtarget: EventTarget,
    document: JS<Document>,
    media_query_list: style::media_queries::MediaQueryList,
    last_match_state: Cell<Option<bool>>
}

impl MediaQueryList {
    fn new_inherited(document: &Document,
                     media_query_list: style::media_queries::MediaQueryList) -> MediaQueryList {
        MediaQueryList {
            eventtarget: EventTarget::new_inherited(),
            document: JS::from_ref(document),
            media_query_list: media_query_list,
            last_match_state: Cell::new(None),
        }
    }

    pub fn new(document: &Document,
               media_query_list: style::media_queries::MediaQueryList) -> Root<MediaQueryList> {
        reflect_dom_object(box MediaQueryList::new_inherited(document, media_query_list),
                           document.window(),
                           MediaQueryListBinding::Wrap)
    }
}

impl MediaQueryList {
    fn evaluate_changes(&self) -> MediaQueryListMatchState {
        let matches = self.evaluate();

        let result = if let Some(old_matches) = self.last_match_state.get() {
            if old_matches == matches {
                MediaQueryListMatchState::Same(matches)
            } else {
                MediaQueryListMatchState::Changed(matches)
            }
        } else {
            MediaQueryListMatchState::Changed(matches)
        };

        self.last_match_state.set(Some(matches));
        result
    }

    pub fn evaluate(&self) -> bool {
        if let Some(window_size) = self.document.window().window_size() {
            let viewport_size = window_size.visible_viewport;
            // TODO: support real ViewportPx, including zoom level
            // This information seems not to be tracked currently, so we assume
            // ViewportPx == PagePx
            let page_to_viewport: ScaleFactor<f32, PagePx, ViewportPx> = ScaleFactor::new(1.0);
            let device = Device::new(MediaType::Screen, viewport_size * page_to_viewport);
            self.media_query_list.evaluate(&device)
        } else {
            false
        }
    }
}

impl MediaQueryListMethods for MediaQueryList {
    // https://drafts.csswg.org/cssom-view/#dom-mediaquerylist-media
    fn Media(&self) -> DOMString {
        let mut s = String::new();
        self.media_query_list.to_css(&mut s).unwrap();
        DOMString::from_string(s)
    }

    // https://drafts.csswg.org/cssom-view/#dom-mediaquerylist-matches
    fn Matches(&self) -> bool {
        match self.last_match_state.get() {
            None => self.evaluate(),
            Some(state) => state,
        }
    }

    // https://drafts.csswg.org/cssom-view/#dom-mediaquerylist-addlistener
    fn AddListener(&self, listener: Option<Rc<EventListener>>) {
        self.upcast::<EventTarget>().AddEventListener(DOMString::from_string("change".to_owned()),
                                                      listener, false);
    }

    // https://drafts.csswg.org/cssom-view/#dom-mediaquerylist-removelistener
    fn RemoveListener(&self, listener: Option<Rc<EventListener>>) {
        self.upcast::<EventTarget>().RemoveEventListener(DOMString::from_string("change".to_owned()),
                                                         listener, false);
    }

    // https://drafts.csswg.org/cssom-view/#dom-mediaquerylist-onchange
    event_handler!(change, GetOnchange, SetOnchange);
}

#[derive(HeapSizeOf)]
pub struct WeakMediaQueryListVec {
    cell: DOMRefCell<WeakRefVec<MediaQueryList>>,
}

#[allow(unsafe_code)]
impl WeakMediaQueryListVec {
    /// Create a new vector of weak references to MediaQueryList
    pub fn new() -> Self {
        WeakMediaQueryListVec { cell: DOMRefCell::new(WeakRefVec::new()) }
    }

    pub fn push(&self, mql: &MediaQueryList) {
        self.cell.borrow_mut().push(WeakRef::new(mql));
    }

    /// Evaluate media query lists and report changes
    /// https://drafts.csswg.org/cssom-view/#evaluate-media-queries-and-report-changes
    pub fn evaluate_and_report_changes(&self) {
        for mql in self.cell.borrow().iter() {
            if let MediaQueryListMatchState::Changed(_) = mql.root().unwrap().evaluate_changes() {
                mql.root().unwrap().upcast::<EventTarget>().fire_event(atom!("change"));
            }
        }
    }
}

#[allow(unsafe_code)]
impl JSTraceable for WeakMediaQueryListVec {
    fn trace(&self, _: *mut JSTracer) {
        self.cell.borrow_mut().retain_alive()
    }
}
<commit_msg>Auto merge of #14082 - dns2utf8:cleanup_14065, r=jdm<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use cssparser::ToCss;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::Bindings::EventListenerBinding::EventListener;
use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
use dom::bindings::codegen::Bindings::MediaQueryListBinding::{self, MediaQueryListMethods};
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, Root};
use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString;
use dom::bindings::trace::JSTraceable;
use dom::bindings::weakref::{WeakRef, WeakRefVec};
use dom::document::Document;
use dom::eventtarget::EventTarget;
use euclid::scale_factor::ScaleFactor;
use js::jsapi::JSTracer;
use std::cell::Cell;
use std::rc::Rc;
use style;
use style::media_queries::{Device, MediaType};
use style_traits::{PagePx, ViewportPx};

pub enum MediaQueryListMatchState {
    Same(bool),
    Changed(bool),
}

#[dom_struct]
pub struct MediaQueryList {
    eventtarget: EventTarget,
    document: JS<Document>,
    media_query_list: style::media_queries::MediaQueryList,
    last_match_state: Cell<Option<bool>>
}

impl MediaQueryList {
    fn new_inherited(document: &Document,
                     media_query_list: style::media_queries::MediaQueryList) -> MediaQueryList {
        MediaQueryList {
            eventtarget: EventTarget::new_inherited(),
            document: JS::from_ref(document),
            media_query_list: media_query_list,
            last_match_state: Cell::new(None),
        }
    }

    pub fn new(document: &Document,
               media_query_list: style::media_queries::MediaQueryList) -> Root<MediaQueryList> {
        reflect_dom_object(box MediaQueryList::new_inherited(document, media_query_list),
                           document.window(),
                           MediaQueryListBinding::Wrap)
    }
}

impl MediaQueryList {
    fn evaluate_changes(&self) -> MediaQueryListMatchState {
        let matches = self.evaluate();

        let result = if let Some(old_matches) = self.last_match_state.get() {
            if old_matches == matches {
                MediaQueryListMatchState::Same(matches)
            } else {
                MediaQueryListMatchState::Changed(matches)
            }
        } else {
            MediaQueryListMatchState::Changed(matches)
        };

        self.last_match_state.set(Some(matches));
        result
    }

    pub fn evaluate(&self) -> bool {
        if let Some(window_size) = self.document.window().window_size() {
            let viewport_size = window_size.visible_viewport;
            // TODO: support real ViewportPx, including zoom level
            // This information seems not to be tracked currently, so we assume
            // ViewportPx == PagePx
            let page_to_viewport: ScaleFactor<f32, PagePx, ViewportPx> = ScaleFactor::new(1.0);
            let device = Device::new(MediaType::Screen, viewport_size * page_to_viewport);
            self.media_query_list.evaluate(&device)
        } else {
            false
        }
    }
}

impl MediaQueryListMethods for MediaQueryList {
    // https://drafts.csswg.org/cssom-view/#dom-mediaquerylist-media
    fn Media(&self) -> DOMString {
        let mut s = String::new();
        self.media_query_list.to_css(&mut s).unwrap();
        DOMString::from_string(s)
    }

    // https://drafts.csswg.org/cssom-view/#dom-mediaquerylist-matches
    fn Matches(&self) -> bool {
        match self.last_match_state.get() {
            None => self.evaluate(),
            Some(state) => state,
        }
    }

    // https://drafts.csswg.org/cssom-view/#dom-mediaquerylist-addlistener
    fn AddListener(&self, listener: Option<Rc<EventListener>>) {
        self.upcast::<EventTarget>().AddEventListener(DOMString::from_string("change".to_owned()),
                                                      listener, false);
    }

    // https://drafts.csswg.org/cssom-view/#dom-mediaquerylist-removelistener
    fn RemoveListener(&self, listener: Option<Rc<EventListener>>) {
        self.upcast::<EventTarget>().RemoveEventListener(DOMString::from_string("change".to_owned()),
                                                         listener, false);
    }

    // https://drafts.csswg.org/cssom-view/#dom-mediaquerylist-onchange
    event_handler!(change, GetOnchange, SetOnchange);
}

#[derive(HeapSizeOf)]
pub struct WeakMediaQueryListVec {
    cell: DOMRefCell<WeakRefVec<MediaQueryList>>,
}

impl WeakMediaQueryListVec {
    /// Create a new vector of weak references to MediaQueryList
    pub fn new() -> Self {
        WeakMediaQueryListVec { cell: DOMRefCell::new(WeakRefVec::new()) }
    }

    pub fn push(&self, mql: &MediaQueryList) {
        self.cell.borrow_mut().push(WeakRef::new(mql));
    }

    /// Evaluate media query lists and report changes
    /// https://drafts.csswg.org/cssom-view/#evaluate-media-queries-and-report-changes
    pub fn evaluate_and_report_changes(&self) {
        for mql in self.cell.borrow().iter() {
            if let MediaQueryListMatchState::Changed(_) = mql.root().unwrap().evaluate_changes() {
                mql.root().unwrap().upcast::<EventTarget>().fire_event(atom!("change"));
            }
        }
    }
}

impl JSTraceable for WeakMediaQueryListVec {
    fn trace(&self, _: *mut JSTracer) {
        self.cell.borrow_mut().retain_alive()
    }
}
<|endoftext|>


<commit_before>use bifrost::rpc::*;
use bifrost::raft::*;
use bifrost::membership::server::Membership;
use bifrost::membership::member::MemberService;
use bifrost::membership::client::Client;
use bifrost::raft::client::RaftClient;
use bifrost::raft::state_machine::callback::client::SubscriptionService;

use std::mem::forget;

use raft::wait;

#[test]
fn primary() {
    let addr = String::from("127.0.0.1:2100");
    let raft_service = RaftService::new(Options {
        storage: Storage::Default(),
        address: addr.clone(),
        service_id: 0,
    });
    let server = Server::new(vec!((0, raft_service.clone())));
    let heartbeat_service = Membership::new(&server, &raft_service);
    Server::listen_and_resume(&server, &addr);
    RaftService::start(&raft_service);
    raft_service.bootstrap();

    let group_1 = String::from("test_group_1");
    let group_2 = String::from("test_group_2");
    let group_3 = String::from("test_group_3");

    let wild_raft_client = RaftClient::new(vec!(addr.clone()), 0).unwrap();
    let client = Client::new(&wild_raft_client);

    let subs_service = SubscriptionService::initialize(&server);
    wild_raft_client.set_subscription(&subs_service);

    client.new_group(&group_1).unwrap().unwrap();
    client.new_group(&group_2).unwrap().unwrap();
    client.new_group(&group_3).unwrap().unwrap();

    client.on_any_member_joined(|res| {
        println!("NEW MEMBER: {:?}", res.unwrap().address);
    }).unwrap().unwrap();

    client.on_any_member_left(|res| {
        println!("MEMBER LEFT: {:?}", res.unwrap().address);
    }).unwrap().unwrap();

    client.on_any_member_offline(|res| {
        println!("MEMBER OFFLINE: {:?}", res.unwrap().address);
    }).unwrap().unwrap();

    client.on_any_member_online(|res| {
        println!("MEMBER ONLINE: {:?}", res.unwrap().address);
    }).unwrap().unwrap();

    client.on_group_leader_changed(|res| {
        println!("GROUP LEADER CHANGED");
    }, &group_1).unwrap().unwrap();

    client.on_group_member_joined(|res| {
        println!("GROUP MEMBER JOINED: {:?}", res.unwrap().address);
    }, &group_1).unwrap().unwrap();

    client.on_group_member_left(|res| {
        println!("GROUP MEMBER LEFT: {:?}", res.unwrap().address);
    }, &group_1).unwrap().unwrap();

    client.on_group_member_online(|res| {
        println!("GROUP MEMBER ONLINE: {:?}", res.unwrap().address);
    }, &group_1).unwrap().unwrap();

    client.on_group_member_offline(|res| {
        println!("GROUP MEMBER OFFLINE: {:?}", res.unwrap().address);
    }, &group_1).unwrap().unwrap();

    let member1_raft_client = RaftClient::new(vec!(addr.clone()), 0).unwrap();
    let member1_addr = String::from("server1");
    let member1_svr = MemberService::new(&member1_addr, &member1_raft_client);

    let member2_raft_client = RaftClient::new(vec!(addr.clone()), 0).unwrap();
    let member2_addr = String::from("server2");
    let member2_svr = MemberService::new(&member2_addr, &member2_raft_client);

    let member3_raft_client = RaftClient::new(vec!(addr.clone()), 0).unwrap();
    let member3_addr = String::from("server3");
    let member3_svr = MemberService::new(&member3_addr, &member3_raft_client);

    member1_svr.join_group(&group_1).unwrap().unwrap();
    member2_svr.join_group(&group_1).unwrap().unwrap();
    member3_svr.join_group(&group_1).unwrap().unwrap();

    member1_svr.join_group(&group_2).unwrap().unwrap();
    member2_svr.join_group(&group_2).unwrap().unwrap();

    member1_svr.join_group(&group_3).unwrap().unwrap();

    assert_eq!(member1_svr.client().all_members(false).unwrap().unwrap().len(), 3);
    assert_eq!(member1_svr.client().all_members(true).unwrap().unwrap().len(), 3);

    assert_eq!(member1_svr.client().group_members(&group_1, false).unwrap().unwrap().len(), 3);
    assert_eq!(member1_svr.client().group_members(&group_1, true).unwrap().unwrap().len(), 3);

    assert_eq!(member1_svr.client().group_members(&group_2, false).unwrap().unwrap().len(), 2);
    assert_eq!(member1_svr.client().group_members(&group_2, true).unwrap().unwrap().len(), 2);

    assert_eq!(member1_svr.client().group_members(&group_3, false).unwrap().unwrap().len(), 1);
    assert_eq!(member1_svr.client().group_members(&group_3, true).unwrap().unwrap().len(), 1);

    member1_svr.close(); // close only end the heartbeat thread
    wait();
    wait();
    assert_eq!(member1_svr.client().all_members(false).unwrap().unwrap().len(), 3);
    assert_eq!(member1_svr.client().all_members(true).unwrap().unwrap().len(), 2);

    assert_eq!(member1_svr.client().group_members(&group_1, false).unwrap().unwrap().len(), 3);
    assert_eq!(member1_svr.client().group_members(&group_1, true).unwrap().unwrap().len(), 2);

    assert_eq!(member1_svr.client().group_members(&group_2, false).unwrap().unwrap().len(), 2);
    assert_eq!(member1_svr.client().group_members(&group_2, true).unwrap().unwrap().len(), 1);

    assert_eq!(member1_svr.client().group_members(&group_3, false).unwrap().unwrap().len(), 1);
    assert_eq!(member1_svr.client().group_members(&group_3, true).unwrap().unwrap().len(), 0);

    member2_svr.leave().unwrap().unwrap();// leave will report to the raft servers to remove it from the list
    assert_eq!(member1_svr.client().all_members(false).unwrap().unwrap().len(), 2);
    assert_eq!(member1_svr.client().all_members(true).unwrap().unwrap().len(), 1);

    assert_eq!(member1_svr.client().group_members(&group_1, false).unwrap().unwrap().len(), 2);
    assert_eq!(member1_svr.client().group_members(&group_1, true).unwrap().unwrap().len(), 1);

    assert_eq!(member1_svr.client().group_members(&group_2, false).unwrap().unwrap().len(), 1);
    assert_eq!(member1_svr.client().group_members(&group_2, true).unwrap().unwrap().len(), 0);

    assert_eq!(member1_svr.client().group_members(&group_3, false).unwrap().unwrap().len(), 1);
    assert_eq!(member1_svr.client().group_members(&group_3, true).unwrap().unwrap().len(), 0);

    wait();
}<commit_msg>membership changes callback check<commit_after>use bifrost::rpc::*;
use bifrost::raft::*;
use bifrost::membership::server::Membership;
use bifrost::membership::member::MemberService;
use bifrost::membership::client::Client;
use bifrost::raft::client::RaftClient;
use bifrost::raft::state_machine::callback::client::SubscriptionService;

use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};

use raft::wait;

#[test]
fn primary() {
    let addr = String::from("127.0.0.1:2100");
    let raft_service = RaftService::new(Options {
        storage: Storage::Default(),
        address: addr.clone(),
        service_id: 0,
    });
    let server = Server::new(vec!((0, raft_service.clone())));
    let heartbeat_service = Membership::new(&server, &raft_service);
    Server::listen_and_resume(&server, &addr);
    RaftService::start(&raft_service);
    raft_service.bootstrap();

    let group_1 = String::from("test_group_1");
    let group_2 = String::from("test_group_2");
    let group_3 = String::from("test_group_3");

    let wild_raft_client = RaftClient::new(vec!(addr.clone()), 0).unwrap();
    let client = Client::new(&wild_raft_client);

    let subs_service = SubscriptionService::initialize(&server);
    wild_raft_client.set_subscription(&subs_service);

    client.new_group(&group_1).unwrap().unwrap();
    client.new_group(&group_2).unwrap().unwrap();
    client.new_group(&group_3).unwrap().unwrap();

    let any_member_joined_count = Arc::new(AtomicUsize::new(0));
    let any_member_left_count = Arc::new(AtomicUsize::new(0));
    let any_member_offline_count = Arc::new(AtomicUsize::new(0));
    let any_member_online_count = Arc::new(AtomicUsize::new(0));
    let group_leader_changed_count = Arc::new(AtomicUsize::new(0));
    let group_member_joined_count = Arc::new(AtomicUsize::new(0));
    let group_member_left_count = Arc::new(AtomicUsize::new(0));
    let group_member_online_count = Arc::new(AtomicUsize::new(0));
    let group_member_offline_count = Arc::new(AtomicUsize::new(0));

    let any_member_joined_count_clone = any_member_joined_count.clone();
    let any_member_left_count_clone = any_member_left_count.clone();
    let any_member_offline_count_clone = any_member_offline_count.clone();
    let any_member_online_count_clone = any_member_online_count.clone();
    let group_leader_changed_count_clone = group_leader_changed_count.clone();
    let group_member_joined_count_clone = group_member_joined_count.clone();
    let group_member_left_count_clone = group_member_left_count.clone();
    let group_member_online_count_clone = group_member_online_count.clone();
    let group_member_offline_count_clone = group_member_offline_count.clone();

    client.on_any_member_joined(move |res| {
        any_member_joined_count_clone.fetch_add(1, Ordering::Relaxed);
        println!("NEW MEMBER: {:?}", res.unwrap().address);
    }).unwrap().unwrap();

    client.on_any_member_left(move |res| {
        any_member_left_count_clone.fetch_add(1, Ordering::Relaxed);
        println!("MEMBER LEFT: {:?}", res.unwrap().address);
    }).unwrap().unwrap();

    client.on_any_member_offline(move |res| {
        any_member_offline_count_clone.fetch_add(1, Ordering::Relaxed);
        println!("MEMBER OFFLINE: {:?}", res.unwrap().address);
    }).unwrap().unwrap();

    client.on_any_member_online(move |res| {
        any_member_online_count_clone.fetch_add(1, Ordering::Relaxed);
        println!("MEMBER ONLINE: {:?}", res.unwrap().address);
    }).unwrap().unwrap();

    client.on_group_leader_changed(move |res| {
        group_leader_changed_count_clone.fetch_add(1, Ordering::Relaxed);
        println!("GROUP LEADER CHANGED");
    }, &group_1).unwrap().unwrap();

    client.on_group_member_joined(move |res| {
        group_member_joined_count_clone.fetch_add(1, Ordering::Relaxed);
        println!("GROUP MEMBER JOINED: {:?}", res.unwrap().address);
    }, &group_1).unwrap().unwrap();

    client.on_group_member_left(move |res| {
        group_member_left_count_clone.fetch_add(1, Ordering::Relaxed);
        println!("GROUP MEMBER LEFT: {:?}", res.unwrap().address);
    }, &group_1).unwrap().unwrap();

    client.on_group_member_online(move |res| {
        group_member_online_count_clone.fetch_add(1, Ordering::Relaxed);
        println!("GROUP MEMBER ONLINE: {:?}", res.unwrap().address);
    }, &group_1).unwrap().unwrap();

    client.on_group_member_offline(move |res| {
        group_member_offline_count_clone.fetch_add(1, Ordering::Relaxed);
        println!("GROUP MEMBER OFFLINE: {:?}", res.unwrap().address);
    }, &group_1).unwrap().unwrap();

    let member1_raft_client = RaftClient::new(vec!(addr.clone()), 0).unwrap();
    let member1_addr = String::from("server1");
    let member1_svr = MemberService::new(&member1_addr, &member1_raft_client);

    let member2_raft_client = RaftClient::new(vec!(addr.clone()), 0).unwrap();
    let member2_addr = String::from("server2");
    let member2_svr = MemberService::new(&member2_addr, &member2_raft_client);

    let member3_raft_client = RaftClient::new(vec!(addr.clone()), 0).unwrap();
    let member3_addr = String::from("server3");
    let member3_svr = MemberService::new(&member3_addr, &member3_raft_client);

    member1_svr.join_group(&group_1).unwrap().unwrap();
    member2_svr.join_group(&group_1).unwrap().unwrap();
    member3_svr.join_group(&group_1).unwrap().unwrap();

    member1_svr.join_group(&group_2).unwrap().unwrap();
    member2_svr.join_group(&group_2).unwrap().unwrap();

    member1_svr.join_group(&group_3).unwrap().unwrap();

    assert_eq!(member1_svr.client().all_members(false).unwrap().unwrap().len(), 3);
    assert_eq!(member1_svr.client().all_members(true).unwrap().unwrap().len(), 3);

    assert_eq!(member1_svr.client().group_members(&group_1, false).unwrap().unwrap().len(), 3);
    assert_eq!(member1_svr.client().group_members(&group_1, true).unwrap().unwrap().len(), 3);

    assert_eq!(member1_svr.client().group_members(&group_2, false).unwrap().unwrap().len(), 2);
    assert_eq!(member1_svr.client().group_members(&group_2, true).unwrap().unwrap().len(), 2);

    assert_eq!(member1_svr.client().group_members(&group_3, false).unwrap().unwrap().len(), 1);
    assert_eq!(member1_svr.client().group_members(&group_3, true).unwrap().unwrap().len(), 1);

    member1_svr.close(); // close only end the heartbeat thread
    wait();
    wait();
    assert_eq!(member1_svr.client().all_members(false).unwrap().unwrap().len(), 3);
    assert_eq!(member1_svr.client().all_members(true).unwrap().unwrap().len(), 2);

    assert_eq!(member1_svr.client().group_members(&group_1, false).unwrap().unwrap().len(), 3);
    assert_eq!(member1_svr.client().group_members(&group_1, true).unwrap().unwrap().len(), 2);

    assert_eq!(member1_svr.client().group_members(&group_2, false).unwrap().unwrap().len(), 2);
    assert_eq!(member1_svr.client().group_members(&group_2, true).unwrap().unwrap().len(), 1);

    assert_eq!(member1_svr.client().group_members(&group_3, false).unwrap().unwrap().len(), 1);
    assert_eq!(member1_svr.client().group_members(&group_3, true).unwrap().unwrap().len(), 0);

    member2_svr.leave().unwrap().unwrap();// leave will report to the raft servers to remove it from the list
    assert_eq!(member1_svr.client().all_members(false).unwrap().unwrap().len(), 2);
    assert_eq!(member1_svr.client().all_members(true).unwrap().unwrap().len(), 1);

    assert_eq!(member1_svr.client().group_members(&group_1, false).unwrap().unwrap().len(), 2);
    assert_eq!(member1_svr.client().group_members(&group_1, true).unwrap().unwrap().len(), 1);

    assert_eq!(member1_svr.client().group_members(&group_2, false).unwrap().unwrap().len(), 1);
    assert_eq!(member1_svr.client().group_members(&group_2, true).unwrap().unwrap().len(), 0);

    assert_eq!(member1_svr.client().group_members(&group_3, false).unwrap().unwrap().len(), 1);
    assert_eq!(member1_svr.client().group_members(&group_3, true).unwrap().unwrap().len(), 0);

    wait();

    assert_eq!(any_member_joined_count.load(Ordering::Relaxed), 3);
    assert_eq!(any_member_left_count.load(Ordering::Relaxed), 1);
    assert_eq!(any_member_offline_count.load(Ordering::Relaxed), 1);
    assert_eq!(any_member_online_count.load(Ordering::Relaxed), 0); // no server online from offline
    assert_eq!(group_leader_changed_count.load(Ordering::Relaxed), 3); // 1 for None -> server1, 2 for server 1 -> server 2, 3 for server 2 -> server 3
    assert_eq!(group_member_joined_count.load(Ordering::Relaxed), 3);
    assert_eq!(group_member_left_count.load(Ordering::Relaxed), 1);
    assert_eq!(group_member_online_count.load(Ordering::Relaxed), 0);
    assert_eq!(group_member_offline_count.load(Ordering::Relaxed), 1);
}<|endoftext|>


<commit_before>//! Defines types for operating with floating point and 8 bit RGB colors

use std::num::Float;
use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut};
use linalg;

/// Colorf is a floating point RGBA color type
/// `a` is typically used to store the weight of a color eg. in the
/// render target for multisampling we need to track the weight to
/// normalize in the end and is always initialized to 0
#[derive(Show, Copy, Clone, PartialEq)]
pub struct Colorf {
    pub r: f32,
    pub g: f32,
    pub b: f32,
    pub a: f32,
}

impl Colorf {
    /// Create an RGB color
    pub fn new(r: f32, g: f32, b: f32) -> Colorf {
        Colorf { r: r, g: g, b: b, a: 0f32 }
    }
    /// Create an RGB color using the same value for all channels
    pub fn broadcast(r: f32) -> Colorf {
        Colorf { r: r, g: r, b: r, a: 0f32 }
    }
    /// Clamp the color values between [0, 1]
    pub fn clamp(&self) -> Colorf {
        Colorf { r: linalg::clamp(self.r, 0.0, 1.0),
                 g: linalg::clamp(self.g, 0.0, 1.0),
                 b: linalg::clamp(self.b, 0.0, 1.0),
                 a: linalg::clamp(self.a, 0.0, 1.0) }
    }
    /// Compute the luminance of the color
    pub fn luminance(&self) -> f32 {
        0.2126 * self.r + 0.7152 * self.g + 0.0722 * self.b
    }
    /// Check if the color is black
    pub fn is_black(&self) -> bool {
        self.r == 0f32 && self.g == 0f32 && self.b == 0f32
    }
    /// Convert the linear RGB color to sRGB
    pub fn to_srgb(&self) -> Colorf {
        let a = 0.055f32;
        let b = 1f32 / 2.4;
        let mut srgb = Colorf::broadcast(0.0);
        for i in 0..3us {
            if self[i] <= 0.0031308 {
                srgb[i] = 12.92 * self[i];
            } else {
                srgb[i] = (1.0 + a) * Float::powf(self[i], b) - a;
            }
        }
        srgb
    }
    /// Return the color with values { e^r, e^g, e^b }
    pub fn exp(&self) -> Colorf {
        Colorf { r: Float::exp(self.r), g: Float::exp(self.g),
                 b: Float::exp(self.b), a: Float::exp(self.a) }
    }
}

impl Add for Colorf {
    type Output = Colorf;
    /// Add two colors together
    fn add(self, rhs: Colorf) -> Colorf {
        Colorf { r: self.r + rhs.r, g: self.g + rhs.g, b: self.b + rhs.b, a: self.a + rhs.a }
    }
}

impl Sub for Colorf {
    type Output = Colorf;
    /// Subtract the two colors
    fn sub(self, rhs: Colorf) -> Colorf {
        Colorf { r: self.r - rhs.r, g: self.g - rhs.g, b: self.b - rhs.b, a: self.a - rhs.a }
    }
}

impl Mul for Colorf {
    type Output = Colorf;
    /// Multiply the two colors
    fn mul(self, rhs: Colorf) -> Colorf {
        Colorf { r: self.r * rhs.r, g: self.g * rhs.g, b: self.b * rhs.b, a: self.a * rhs.a }
    }
}

impl Mul<f32> for Colorf {
    type Output = Colorf;
    /// Scale the color by the float
    fn mul(self, rhs: f32) -> Colorf {
        Colorf { r: self.r * rhs, g: self.g * rhs, b: self.b * rhs, a: self.a * rhs }
    }
}

impl Div for Colorf {
    type Output = Colorf;
    /// Divide the channels of one color by another
    fn div(self, rhs: Colorf) -> Colorf {
        Colorf { r: self.r / rhs.r, g: self.g / rhs.g, b: self.b / rhs.b, a: self.a / rhs.a }
    }
}

impl Div<f32> for Colorf {
    type Output = Colorf;
    /// Divide the channels of the color by the float
    fn div(self, rhs: f32) -> Colorf {
        Colorf { r: self.r / rhs, g: self.g / rhs, b: self.b / rhs, a: self.a / rhs }
    }
}

impl Neg for Colorf {
    type Output = Colorf;
    /// Negate the color channels
    fn neg(self) -> Colorf {
        Colorf { r: -self.r, g: -self.g, b: -self.b, a: -self.a }
    }
}

impl Index<usize> for Colorf {
    type Output = f32;
    /// Access the channels by index
    ///
    /// - 0 = r
    /// - 1 = g
    /// - 2 = b
    /// - 3 = a
    fn index(&self, i: &usize) -> &f32 {
        match *i {
            0 => &self.r,
            1 => &self.g,
            2 => &self.b,
            3 => &self.a,
            _ => panic!("Invalid index into color"),
        }
    }
}

impl IndexMut<usize> for Colorf {
    type Output = f32;
    /// Access the channels by index
    ///
    /// - 0 = r
    /// - 1 = g
    /// - 2 = b
    /// - 3 = a
    fn index_mut(&mut self, i: &usize) -> &mut f32 {
        match *i {
            0 => &mut self.r,
            1 => &mut self.g,
            2 => &mut self.b,
            3 => &mut self.a,
            _ => panic!("Invalid index into color"),
        }
    }
}

<commit_msg>Should set alpha to one when making an RGB color<commit_after>//! Defines types for operating with floating point and 8 bit RGB colors

use std::num::Float;
use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut};
use linalg;

/// Colorf is a floating point RGBA color type
/// `a` is typically used to store the weight of a color eg. in the
/// render target for multisampling we need to track the weight to
/// normalize in the end and is always initialized to 0
#[derive(Show, Copy, Clone, PartialEq)]
pub struct Colorf {
    pub r: f32,
    pub g: f32,
    pub b: f32,
    pub a: f32,
}

impl Colorf {
    /// Create an RGB color
    pub fn new(r: f32, g: f32, b: f32) -> Colorf {
        Colorf { r: r, g: g, b: b, a: 1.0 }
    }
    /// Create an RGB color using the same value for all channels
    pub fn broadcast(r: f32) -> Colorf {
        Colorf { r: r, g: r, b: r, a: r }
    }
    /// Clamp the color values between [0, 1]
    pub fn clamp(&self) -> Colorf {
        Colorf { r: linalg::clamp(self.r, 0.0, 1.0),
                 g: linalg::clamp(self.g, 0.0, 1.0),
                 b: linalg::clamp(self.b, 0.0, 1.0),
                 a: linalg::clamp(self.a, 0.0, 1.0) }
    }
    /// Compute the luminance of the color
    pub fn luminance(&self) -> f32 {
        0.2126 * self.r + 0.7152 * self.g + 0.0722 * self.b
    }
    /// Check if the color is black
    pub fn is_black(&self) -> bool {
        self.r == 0f32 && self.g == 0f32 && self.b == 0f32
    }
    /// Convert the linear RGB color to sRGB
    pub fn to_srgb(&self) -> Colorf {
        let a = 0.055f32;
        let b = 1f32 / 2.4;
        let mut srgb = Colorf::broadcast(0.0);
        for i in 0..3us {
            if self[i] <= 0.0031308 {
                srgb[i] = 12.92 * self[i];
            } else {
                srgb[i] = (1.0 + a) * Float::powf(self[i], b) - a;
            }
        }
        srgb
    }
    /// Return the color with values { e^r, e^g, e^b }
    pub fn exp(&self) -> Colorf {
        Colorf { r: Float::exp(self.r), g: Float::exp(self.g),
                 b: Float::exp(self.b), a: Float::exp(self.a) }
    }
}

impl Add for Colorf {
    type Output = Colorf;
    /// Add two colors together
    fn add(self, rhs: Colorf) -> Colorf {
        Colorf { r: self.r + rhs.r, g: self.g + rhs.g, b: self.b + rhs.b, a: self.a + rhs.a }
    }
}

impl Sub for Colorf {
    type Output = Colorf;
    /// Subtract the two colors
    fn sub(self, rhs: Colorf) -> Colorf {
        Colorf { r: self.r - rhs.r, g: self.g - rhs.g, b: self.b - rhs.b, a: self.a - rhs.a }
    }
}

impl Mul for Colorf {
    type Output = Colorf;
    /// Multiply the two colors
    fn mul(self, rhs: Colorf) -> Colorf {
        Colorf { r: self.r * rhs.r, g: self.g * rhs.g, b: self.b * rhs.b, a: self.a * rhs.a }
    }
}

impl Mul<f32> for Colorf {
    type Output = Colorf;
    /// Scale the color by the float
    fn mul(self, rhs: f32) -> Colorf {
        Colorf { r: self.r * rhs, g: self.g * rhs, b: self.b * rhs, a: self.a * rhs }
    }
}

impl Div for Colorf {
    type Output = Colorf;
    /// Divide the channels of one color by another
    fn div(self, rhs: Colorf) -> Colorf {
        Colorf { r: self.r / rhs.r, g: self.g / rhs.g, b: self.b / rhs.b, a: self.a / rhs.a }
    }
}

impl Div<f32> for Colorf {
    type Output = Colorf;
    /// Divide the channels of the color by the float
    fn div(self, rhs: f32) -> Colorf {
        Colorf { r: self.r / rhs, g: self.g / rhs, b: self.b / rhs, a: self.a / rhs }
    }
}

impl Neg for Colorf {
    type Output = Colorf;
    /// Negate the color channels
    fn neg(self) -> Colorf {
        Colorf { r: -self.r, g: -self.g, b: -self.b, a: -self.a }
    }
}

impl Index<usize> for Colorf {
    type Output = f32;
    /// Access the channels by index
    ///
    /// - 0 = r
    /// - 1 = g
    /// - 2 = b
    /// - 3 = a
    fn index(&self, i: &usize) -> &f32 {
        match *i {
            0 => &self.r,
            1 => &self.g,
            2 => &self.b,
            3 => &self.a,
            _ => panic!("Invalid index into color"),
        }
    }
}

impl IndexMut<usize> for Colorf {
    type Output = f32;
    /// Access the channels by index
    ///
    /// - 0 = r
    /// - 1 = g
    /// - 2 = b
    /// - 3 = a
    fn index_mut(&mut self, i: &usize) -> &mut f32 {
        match *i {
            0 => &mut self.r,
            1 => &mut self.g,
            2 => &mut self.b,
            3 => &mut self.a,
            _ => panic!("Invalid index into color"),
        }
    }
}

<|endoftext|>