<commit_before>use std::fmt::Debug;
use std::collections::HashMap;
use test::Bencher;

use rustc_serialize::{Decoder, Decodable};

use serde;
use serde::de::{Deserializer, Deserialize};

//////////////////////////////////////////////////////////////////////////////

#[derive(PartialEq, Debug)]
pub enum Error {
    EndOfStream,
    SyntaxError,
    MissingField,
}

impl serde::de::Error for Error {
    fn syntax(_: &str) -> Error { Error::SyntaxError }

    fn end_of_stream() -> Error { Error::EndOfStream }

    fn unknown_field(_: &str) -> Error { Error::SyntaxError }

    fn missing_field(_: &'static str) -> Error {
        Error::MissingField
    }
}

//////////////////////////////////////////////////////////////////////////////

mod decoder {
    use std::collections::HashMap;
    use std::collections::hash_map::IntoIter;
    use rustc_serialize;

    use super::Error;
    use self::Value::{StringValue, IsizeValue};

    enum Value {
        StringValue(String),
        IsizeValue(isize),
    }

    pub struct IsizeDecoder {
        len: usize,
        iter: IntoIter<String, isize>,
        stack: Vec<Value>,
    }

    impl IsizeDecoder {
        #[inline]
        pub fn new(values: HashMap<String, isize>) -> IsizeDecoder {
            IsizeDecoder {
                len: values.len(),
                iter: values.into_iter(),
                stack: vec!(),
            }
        }
    }

    impl rustc_serialize::Decoder for IsizeDecoder {
        type Error = Error;

        fn error(&mut self, _msg: &str) -> Error {
            Error::SyntaxError
        }

        // Primitive types:
        fn read_nil(&mut self) -> Result<(), Error> { Err(Error::SyntaxError) }
        fn read_usize(&mut self) -> Result<usize, Error> { Err(Error::SyntaxError) }
        fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::SyntaxError) }
        fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::SyntaxError) }
        fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::SyntaxError) }
        fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::SyntaxError) }
        #[inline]
        fn read_isize(&mut self) -> Result<isize, Error> {
            match self.stack.pop() {
                Some(IsizeValue(x)) => Ok(x),
                Some(_) => Err(Error::SyntaxError),
                None => Err(Error::EndOfStream),
            }
        }
        fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::SyntaxError) }
        fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::SyntaxError) }
        fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::SyntaxError) }
        fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::SyntaxError) }
        fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::SyntaxError) }
        fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::SyntaxError) }
        fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::SyntaxError) }
        fn read_char(&mut self) -> Result<char, Error> { Err(Error::SyntaxError) }
        #[inline]
        fn read_str(&mut self) -> Result<String, Error> {
            match self.stack.pop() {
                Some(StringValue(x)) => Ok(x),
                Some(_) => Err(Error::SyntaxError),
                None => Err(Error::EndOfStream),
            }
        }

        // Compound types:
        fn read_enum<T, F>(&mut self, _name: &str, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_enum_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_struct_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        // Specialized types:
        fn read_option<T, F>(&mut self, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder, bool) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_seq<T, F>(&mut self, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_seq_elt<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        #[inline]
        fn read_map<T, F>(&mut self, f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>,
        {
            let len = self.len;
            f(self, len)
        }
        #[inline]
        fn read_map_elt_key<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            match self.iter.next() {
                Some((key, value)) => {
                    self.stack.push(IsizeValue(value));
                    self.stack.push(StringValue(key));
                    f(self)
                }
                None => {
                    Err(Error::SyntaxError)
                }
            }
        }

        #[inline]
        fn read_map_elt_val<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            f(self)
        }
    }
}

//////////////////////////////////////////////////////////////////////////////

mod deserializer {
    use std::collections::HashMap;
    use std::collections::hash_map;

    use super::Error;

    use serde::de;

    #[derive(PartialEq, Debug)]
    enum State {
        StartState,
        KeyState(String),
        ValueState(isize),
    }

    pub struct IsizeDeserializer {
        stack: Vec<State>,
        iter: hash_map::IntoIter<String, isize>,
    }

    impl IsizeDeserializer {
        #[inline]
        pub fn new(values: HashMap<String, isize>) -> IsizeDeserializer {
            IsizeDeserializer {
                stack: vec!(State::StartState),
                iter: values.into_iter(),
            }
        }
    }

    impl de::Deserializer for IsizeDeserializer {
        type Error = Error;

        fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
            where V: de::Visitor,
        {
            match self.stack.pop() {
                Some(State::StartState) => {
                    visitor.visit_map(self)
                }
                Some(State::KeyState(key)) => {
                    visitor.visit_string(key)
                }
                Some(State::ValueState(value)) => {
                    visitor.visit_isize(value)
                }
                None => {
                    Err(Error::EndOfStream)
                }
            }
        }
    }

    impl de::MapVisitor for IsizeDeserializer {
        type Error = Error;

        fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
            where K: de::Deserialize,
        {
            match self.iter.next() {
                Some((key, value)) => {
                    self.stack.push(State::ValueState(value));
                    self.stack.push(State::KeyState(key));
                    Ok(Some(try!(de::Deserialize::deserialize(self))))
                }
                None => {
                    Ok(None)
                }
            }
        }

        fn visit_value<V>(&mut self) -> Result<V, Error>
            where V: de::Deserialize,
        {
            de::Deserialize::deserialize(self)
        }

        fn end(&mut self) -> Result<(), Error> {
            match self.iter.next() {
                Some(_) => Err(Error::SyntaxError),
                None => Ok(()),
            }
        }

        fn size_hint(&self) -> (usize, Option<usize>) {
            self.iter.size_hint()
        }
    }

/*
    impl Iterator for IsizeDeserializer {
        type Item = Result<de::Token, Error>;

        #[inline]
        fn next(&mut self) -> Option<Result<de::Token, Error>> {
            match self.stack.pop() {
                Some(StartState) => {
                    self.stack.push(KeyOrEndState);
                    Some(Ok(de::Token::MapStart(self.len)))
                }
                Some(KeyOrEndState) => {
                    match self.iter.next() {
                        Some((key, value)) => {
                            self.stack.push(ValueState(value));
                            Some(Ok(de::Token::String(key)))
                        }
                        None => {
                            self.stack.push(EndState);
                            Some(Ok(de::Token::End))
                        }
                    }
                }
                Some(ValueState(x)) => {
                    self.stack.push(KeyOrEndState);
                    Some(Ok(de::Token::Isize(x)))
                }
                Some(EndState) => {
                    None
                }
                None => {
                    None
                }
            }
        }
    }

    impl de::Deserializer<Error> for IsizeDeserializer {
        #[inline]
        fn end_of_stream(&mut self) -> Error {
            EndOfStream
        }

        #[inline]
        fn syntax(&mut self, _token: de::Token, _expected: &[de::TokenKind]) -> Error {
            SyntaxError
        }

        #[inline]
        fn unexpected_name(&mut self, _token: de::Token) -> Error {
            SyntaxError
        }

        #[inline]
        fn conversion_error(&mut self, _token: de::Token) -> Error {
            SyntaxError
        }

        #[inline]
        fn missing_field<
            T: de::Deserialize<IsizeDeserializer, Error>
        >(&mut self, _field: &'static str) -> Result<T, Error> {
            Err(Error::SyntaxError)
        }
    }
*/
}

//////////////////////////////////////////////////////////////////////////////

fn run_decoder<
    D: Decoder<Error=Error>,
    T: Clone + PartialEq + Debug + Decodable
>(mut d: D, value: T) {
    let v = Decodable::decode(&mut d);

    assert_eq!(Ok(value), v);
}

#[bench]
fn bench_decoder_000(b: &mut Bencher) {
    b.iter(|| {
        let m: HashMap<String, isize> = HashMap::new();
        run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
    })
}

#[bench]
fn bench_decoder_003(b: &mut Bencher) {
    b.iter(|| {
        let mut m: HashMap<String, isize> = HashMap::new();
        for i in (0 .. 3) {
            m.insert(i.to_string(), i);
        }
        run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
    })
}

#[bench]
fn bench_decoder_100(b: &mut Bencher) {
    b.iter(|| {
        let mut m: HashMap<String, isize> = HashMap::new();
        for i in (0 .. 100) {
            m.insert(i.to_string(), i);
        }
        run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
    })
}

fn run_deserializer<D, T>(mut d: D, value: T)
    where D: Deserializer,
          D::Error: Debug + PartialEq,
          T: Clone + PartialEq + Debug + Deserialize
{
    let v = T::deserialize(&mut d);

    assert_eq!(Ok(value), v);
}

#[bench]
fn bench_deserializer_000(b: &mut Bencher) {
    b.iter(|| {
        let m: HashMap<String, isize> = HashMap::new();
        run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
    })
}

#[bench]
fn bench_deserializer_003(b: &mut Bencher) {
    b.iter(|| {
        let mut m: HashMap<String, isize> = HashMap::new();
        for i in (0 .. 3) {
            m.insert(i.to_string(), i);
        }
        run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
    })
}

#[bench]
fn bench_deserializer_100(b: &mut Bencher) {
    b.iter(|| {
        let mut m: HashMap<String, isize> = HashMap::new();
        for i in (0 .. 100) {
            m.insert(i.to_string(), i);
        }
        run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
    })
}
<commit_msg>chore(cleanup): Fix some warnings<commit_after>use std::fmt::Debug;
use std::collections::HashMap;
use test::Bencher;

use rustc_serialize::{Decoder, Decodable};

use serde;
use serde::de::{Deserializer, Deserialize};

//////////////////////////////////////////////////////////////////////////////

#[derive(PartialEq, Debug)]
pub enum Error {
    EndOfStream,
    SyntaxError,
    MissingField,
}

impl serde::de::Error for Error {
    fn syntax(_: &str) -> Error { Error::SyntaxError }

    fn end_of_stream() -> Error { Error::EndOfStream }

    fn unknown_field(_: &str) -> Error { Error::SyntaxError }

    fn missing_field(_: &'static str) -> Error {
        Error::MissingField
    }
}

//////////////////////////////////////////////////////////////////////////////

mod decoder {
    use std::collections::HashMap;
    use std::collections::hash_map::IntoIter;
    use rustc_serialize;

    use super::Error;
    use self::Value::{StringValue, IsizeValue};

    enum Value {
        StringValue(String),
        IsizeValue(isize),
    }

    pub struct IsizeDecoder {
        len: usize,
        iter: IntoIter<String, isize>,
        stack: Vec<Value>,
    }

    impl IsizeDecoder {
        #[inline]
        pub fn new(values: HashMap<String, isize>) -> IsizeDecoder {
            IsizeDecoder {
                len: values.len(),
                iter: values.into_iter(),
                stack: vec!(),
            }
        }
    }

    impl rustc_serialize::Decoder for IsizeDecoder {
        type Error = Error;

        fn error(&mut self, _msg: &str) -> Error {
            Error::SyntaxError
        }

        // Primitive types:
        fn read_nil(&mut self) -> Result<(), Error> { Err(Error::SyntaxError) }
        fn read_usize(&mut self) -> Result<usize, Error> { Err(Error::SyntaxError) }
        fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::SyntaxError) }
        fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::SyntaxError) }
        fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::SyntaxError) }
        fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::SyntaxError) }
        #[inline]
        fn read_isize(&mut self) -> Result<isize, Error> {
            match self.stack.pop() {
                Some(IsizeValue(x)) => Ok(x),
                Some(_) => Err(Error::SyntaxError),
                None => Err(Error::EndOfStream),
            }
        }
        fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::SyntaxError) }
        fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::SyntaxError) }
        fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::SyntaxError) }
        fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::SyntaxError) }
        fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::SyntaxError) }
        fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::SyntaxError) }
        fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::SyntaxError) }
        fn read_char(&mut self) -> Result<char, Error> { Err(Error::SyntaxError) }
        #[inline]
        fn read_str(&mut self) -> Result<String, Error> {
            match self.stack.pop() {
                Some(StringValue(x)) => Ok(x),
                Some(_) => Err(Error::SyntaxError),
                None => Err(Error::EndOfStream),
            }
        }

        // Compound types:
        fn read_enum<T, F>(&mut self, _name: &str, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_enum_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_struct_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        // Specialized types:
        fn read_option<T, F>(&mut self, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder, bool) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_seq<T, F>(&mut self, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        fn read_seq_elt<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            Err(Error::SyntaxError)
        }

        #[inline]
        fn read_map<T, F>(&mut self, f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>,
        {
            let len = self.len;
            f(self, len)
        }
        #[inline]
        fn read_map_elt_key<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            match self.iter.next() {
                Some((key, value)) => {
                    self.stack.push(IsizeValue(value));
                    self.stack.push(StringValue(key));
                    f(self)
                }
                None => {
                    Err(Error::SyntaxError)
                }
            }
        }

        #[inline]
        fn read_map_elt_val<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Error> where
            F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
        {
            f(self)
        }
    }
}

//////////////////////////////////////////////////////////////////////////////

mod deserializer {
    use std::collections::HashMap;
    use std::collections::hash_map;

    use super::Error;

    use serde::de;

    #[derive(PartialEq, Debug)]
    enum State {
        StartState,
        KeyState(String),
        ValueState(isize),
    }

    pub struct IsizeDeserializer {
        stack: Vec<State>,
        iter: hash_map::IntoIter<String, isize>,
    }

    impl IsizeDeserializer {
        #[inline]
        pub fn new(values: HashMap<String, isize>) -> IsizeDeserializer {
            IsizeDeserializer {
                stack: vec!(State::StartState),
                iter: values.into_iter(),
            }
        }
    }

    impl de::Deserializer for IsizeDeserializer {
        type Error = Error;

        fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
            where V: de::Visitor,
        {
            match self.stack.pop() {
                Some(State::StartState) => {
                    visitor.visit_map(self)
                }
                Some(State::KeyState(key)) => {
                    visitor.visit_string(key)
                }
                Some(State::ValueState(value)) => {
                    visitor.visit_isize(value)
                }
                None => {
                    Err(Error::EndOfStream)
                }
            }
        }
    }

    impl de::MapVisitor for IsizeDeserializer {
        type Error = Error;

        fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
            where K: de::Deserialize,
        {
            match self.iter.next() {
                Some((key, value)) => {
                    self.stack.push(State::ValueState(value));
                    self.stack.push(State::KeyState(key));
                    Ok(Some(try!(de::Deserialize::deserialize(self))))
                }
                None => {
                    Ok(None)
                }
            }
        }

        fn visit_value<V>(&mut self) -> Result<V, Error>
            where V: de::Deserialize,
        {
            de::Deserialize::deserialize(self)
        }

        fn end(&mut self) -> Result<(), Error> {
            match self.iter.next() {
                Some(_) => Err(Error::SyntaxError),
                None => Ok(()),
            }
        }

        fn size_hint(&self) -> (usize, Option<usize>) {
            self.iter.size_hint()
        }
    }

/*
    impl Iterator for IsizeDeserializer {
        type Item = Result<de::Token, Error>;

        #[inline]
        fn next(&mut self) -> Option<Result<de::Token, Error>> {
            match self.stack.pop() {
                Some(StartState) => {
                    self.stack.push(KeyOrEndState);
                    Some(Ok(de::Token::MapStart(self.len)))
                }
                Some(KeyOrEndState) => {
                    match self.iter.next() {
                        Some((key, value)) => {
                            self.stack.push(ValueState(value));
                            Some(Ok(de::Token::String(key)))
                        }
                        None => {
                            self.stack.push(EndState);
                            Some(Ok(de::Token::End))
                        }
                    }
                }
                Some(ValueState(x)) => {
                    self.stack.push(KeyOrEndState);
                    Some(Ok(de::Token::Isize(x)))
                }
                Some(EndState) => {
                    None
                }
                None => {
                    None
                }
            }
        }
    }

    impl de::Deserializer<Error> for IsizeDeserializer {
        #[inline]
        fn end_of_stream(&mut self) -> Error {
            EndOfStream
        }

        #[inline]
        fn syntax(&mut self, _token: de::Token, _expected: &[de::TokenKind]) -> Error {
            SyntaxError
        }

        #[inline]
        fn unexpected_name(&mut self, _token: de::Token) -> Error {
            SyntaxError
        }

        #[inline]
        fn conversion_error(&mut self, _token: de::Token) -> Error {
            SyntaxError
        }

        #[inline]
        fn missing_field<
            T: de::Deserialize<IsizeDeserializer, Error>
        >(&mut self, _field: &'static str) -> Result<T, Error> {
            Err(Error::SyntaxError)
        }
    }
*/
}

//////////////////////////////////////////////////////////////////////////////

fn run_decoder<
    D: Decoder<Error=Error>,
    T: Clone + PartialEq + Debug + Decodable
>(mut d: D, value: T) {
    let v = Decodable::decode(&mut d);

    assert_eq!(Ok(value), v);
}

#[bench]
fn bench_decoder_000(b: &mut Bencher) {
    b.iter(|| {
        let m: HashMap<String, isize> = HashMap::new();
        run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
    })
}

#[bench]
fn bench_decoder_003(b: &mut Bencher) {
    b.iter(|| {
        let mut m: HashMap<String, isize> = HashMap::new();
        for i in 0 .. 3 {
            m.insert(i.to_string(), i);
        }
        run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
    })
}

#[bench]
fn bench_decoder_100(b: &mut Bencher) {
    b.iter(|| {
        let mut m: HashMap<String, isize> = HashMap::new();
        for i in 0 .. 100 {
            m.insert(i.to_string(), i);
        }
        run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
    })
}

fn run_deserializer<D, T>(mut d: D, value: T)
    where D: Deserializer,
          D::Error: Debug + PartialEq,
          T: Clone + PartialEq + Debug + Deserialize
{
    let v = T::deserialize(&mut d);

    assert_eq!(Ok(value), v);
}

#[bench]
fn bench_deserializer_000(b: &mut Bencher) {
    b.iter(|| {
        let m: HashMap<String, isize> = HashMap::new();
        run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
    })
}

#[bench]
fn bench_deserializer_003(b: &mut Bencher) {
    b.iter(|| {
        let mut m: HashMap<String, isize> = HashMap::new();
        for i in 0 .. 3 {
            m.insert(i.to_string(), i);
        }
        run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
    })
}

#[bench]
fn bench_deserializer_100(b: &mut Bencher) {
    b.iter(|| {
        let mut m: HashMap<String, isize> = HashMap::new();
        for i in 0 .. 100 {
            m.insert(i.to_string(), i);
        }
        run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
    })
}
<|endoftext|>


<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

#![deny(
    non_camel_case_types,
    non_snake_case,
    path_statements,
    trivial_numeric_casts,
    unstable_features,
    unused_allocation,
    unused_import_braces,
    unused_imports,
    unused_mut,
    unused_qualifications,
    while_true,
)]

extern crate toml;
extern crate toml_query;
#[macro_use] extern crate log;
#[macro_use] extern crate semver;

#[macro_use] extern crate libimagstore;
#[macro_use] extern crate libimagerror;

module_entry_path_mod!("counter");

pub mod counter;
pub mod error;
pub mod result;

<commit_msg>Remove unneeded macro import<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

#![deny(
    non_camel_case_types,
    non_snake_case,
    path_statements,
    trivial_numeric_casts,
    unstable_features,
    unused_allocation,
    unused_import_braces,
    unused_imports,
    unused_mut,
    unused_qualifications,
    while_true,
)]

extern crate toml;
extern crate toml_query;
#[macro_use] extern crate log;
extern crate semver;

#[macro_use] extern crate libimagstore;
#[macro_use] extern crate libimagerror;

module_entry_path_mod!("counter");

pub mod counter;
pub mod error;
pub mod result;

<|endoftext|>


<commit_before>use std::io;
use std::mem;
use std::os::windows::io::{RawHandle, AsRawHandle};

use winapi::{HANDLE, STD_OUTPUT_HANDLE,
             CONSOLE_SCREEN_BUFFER_INFO, COORD, SMALL_RECT};
use kernel32::{GetStdHandle, GetConsoleScreenBufferInfo,
               GetConsoleMode, SetConsoleCursorPosition};

use term::Term;

pub const DEFAULT_WIDTH: u16 = 79;

pub fn is_a_terminal() -> bool {
    unsafe {
        let handle = GetStdHandle(STD_OUTPUT_HANDLE);
        let mut out = 0;
        GetConsoleMode(handle, &mut out) != 0
    }
}

pub fn terminal_size() -> Option<(u16, u16)> {
    let hand = STD_OUTPUT_HANDLE as RawHandle;
    if let Some((_, csbi)) = get_console_screen_buffer_info(hand) {
        Some(((csbi.srWindow.Right - csbi.srWindow.Left) as u16,
              (csbi.srWindow.Bottom - csbi.srWindow.Top) as u16))
    } else {
        None
    }
}

pub fn move_cursor_up(out: &Term, n: usize) -> io::Result<()> {
    if let Some((hand, csbi)) = get_console_screen_buffer_info(out.as_raw_handle()) {
        unsafe {
            SetConsoleCursorPosition(hand, COORD {
                X: 0,
                Y: csbi.dwCursorPosition.Y - n as i16,
            });
        }
    }
    Ok(())
}

pub fn move_cursor_down(out: &Term, n: usize) -> io::Result<()> {
    if let Some((hand, csbi)) = get_console_screen_buffer_info(out.as_raw_handle()) {
        unsafe {
            SetConsoleCursorPosition(hand, COORD {
                X: 0,
                Y: csbi.dwCursorPosition.Y + n as i16,
            });
        }
    }
    Ok(())
}

pub fn clear_line(out: &Term) -> io::Result<()> {
    if let Some((hand, csbi)) = get_console_screen_buffer_info(out.as_raw_handle()) {
        out.write_str(&format!("\r{0:width$}\r", "", width=
            (csbi.srWindow.Right - csbi.srWindow.Left) as usize))?;
    }
    Ok(())
}

fn get_console_screen_buffer_info(hand: HANDLE)
    -> Option<(HANDLE, CONSOLE_SCREEN_BUFFER_INFO)>
{
    let mut csbi: CONSOLE_SCREEN_BUFFER_INFO = unsafe { mem::zeroed() };
    match unsafe { GetConsoleScreenBufferInfo(hand, &mut csbi) } {
        0 => None,
        _ => Some((hand, csbi)),
    }
}
<commit_msg>Fix some warnings<commit_after>use std::io;
use std::mem;
use std::os::windows::io::{RawHandle, AsRawHandle};

use winapi::{HANDLE, STD_OUTPUT_HANDLE,
             CONSOLE_SCREEN_BUFFER_INFO, COORD};
use kernel32::{GetStdHandle, GetConsoleScreenBufferInfo,
               GetConsoleMode, SetConsoleCursorPosition};

use term::Term;

pub const DEFAULT_WIDTH: u16 = 79;

pub fn is_a_terminal() -> bool {
    unsafe {
        let handle = GetStdHandle(STD_OUTPUT_HANDLE);
        let mut out = 0;
        GetConsoleMode(handle, &mut out) != 0
    }
}

pub fn terminal_size() -> Option<(u16, u16)> {
    let hand = STD_OUTPUT_HANDLE as RawHandle;
    if let Some((_, csbi)) = get_console_screen_buffer_info(hand) {
        Some(((csbi.srWindow.Right - csbi.srWindow.Left) as u16,
              (csbi.srWindow.Bottom - csbi.srWindow.Top) as u16))
    } else {
        None
    }
}

pub fn move_cursor_up(out: &Term, n: usize) -> io::Result<()> {
    if let Some((hand, csbi)) = get_console_screen_buffer_info(out.as_raw_handle()) {
        unsafe {
            SetConsoleCursorPosition(hand, COORD {
                X: 0,
                Y: csbi.dwCursorPosition.Y - n as i16,
            });
        }
    }
    Ok(())
}

pub fn move_cursor_down(out: &Term, n: usize) -> io::Result<()> {
    if let Some((hand, csbi)) = get_console_screen_buffer_info(out.as_raw_handle()) {
        unsafe {
            SetConsoleCursorPosition(hand, COORD {
                X: 0,
                Y: csbi.dwCursorPosition.Y + n as i16,
            });
        }
    }
    Ok(())
}

pub fn clear_line(out: &Term) -> io::Result<()> {
    if let Some((_, csbi)) = get_console_screen_buffer_info(out.as_raw_handle()) {
        out.write_str(&format!("\r{0:width$}\r", "", width=
            (csbi.srWindow.Right - csbi.srWindow.Left) as usize))?;
    }
    Ok(())
}

fn get_console_screen_buffer_info(hand: HANDLE)
    -> Option<(HANDLE, CONSOLE_SCREEN_BUFFER_INFO)>
{
    let mut csbi: CONSOLE_SCREEN_BUFFER_INFO = unsafe { mem::zeroed() };
    match unsafe { GetConsoleScreenBufferInfo(hand, &mut csbi) } {
        0 => None,
        _ => Some((hand, csbi)),
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014, David Renshaw (dwrenshaw@gmail.com)
 *
 * See the LICENSE file in the capnproto-rust root directory.
 */

use capnp::capability::{FromServer};
use capnp_rpc::ez_rpc::EzRpcClient;
use capnp_rpc::capability::{InitRequest, LocalClient, WaitForContent};
use calculator_capnp::calculator;

pub struct PowerFunction;

impl calculator::function::Server for PowerFunction {
    fn call(&mut self, mut context : calculator::function::CallContext) {
        let (params, results) = context.get();
        let params = params.get_params();
        if params.size() != 2 {
            //"Wrong number of parameters"
            return context.fail();
        };
        results.set_value(params.get(0).powf(params.get(1)));
        context.done();
    }
}

pub fn main() {
    let args = ::std::os::args();
    if args.len() != 3 {
        println!("usage: {} client HOST:PORT", args[0]);
        return;
    }

    let mut rpc_client = EzRpcClient::new(args[2].as_slice()).unwrap();

    let calculator : calculator::Client = rpc_client.import_cap("calculator");

    {
        //# Make a request that just evaluates the literal value 123.
        //#
        //# What's interesting here is that evaluate() returns a "Value", which is
        //# another interface and therefore points back to an object living on the
        //# server.  We then have to call read() on that object to read it.
        //# However, even though we are making two RPC's, this block executes in
        //# *one* network round trip because of promise pipelining:  we do not wait
        //# for the first call to complete before we send the second call to the
        //# server.

        println!("Evaluating a literal... ");

        let mut request = calculator.evaluate_request();
        request.init().get_expression().set_literal(123.0);

        let eval_promise = request.send();

        let mut read_promise = eval_promise.pipeline.get_value().read_request().send();

        let response = read_promise.wait().unwrap();
        assert_eq!(response.get_value(), 123.0);

        println!("PASS")
    }

    {
        //# Make a request to evaluate 123 + 45 - 67.
        //#
        //# The Calculator interface requires that we first call getOperator() to
        //# get the addition and subtraction functions, then call evaluate() to use
        //# them.  But, once again, we can get both functions, call evaluate(), and
        //# then read() the result -- four RPCs -- in the time of *one* network
        //# round trip, because of promise pipelining.

        println!("Using add and subtract... ");

        let add = {
            let mut request = calculator.get_operator_request();
            request.init().set_op(calculator::operator::Add);
            request.send().pipeline.get_func()
        };

        let subtract = {
            let mut request = calculator.get_operator_request();
            request.init().set_op(calculator::operator::Subtract);
            request.send().pipeline.get_func()
        };

        let mut request = calculator.evaluate_request();

        let subtract_call = request.init().get_expression().init_call();
        subtract_call.set_function(subtract);
        let subtract_params = subtract_call.init_params(2);
        subtract_params.get(1).set_literal(67.0);

        let add_call = subtract_params.get(0).init_call();
        add_call.set_function(add);
        let add_params = add_call.init_params(2);
        add_params.get(0).set_literal(123.0);
        add_params.get(1).set_literal(45.0);

        let eval_promise = request.send();
        let mut read_promise = eval_promise.pipeline.get_value().read_request().send();
        let response = read_promise.wait().unwrap();
        assert_eq!(response.get_value(), 101.0);

        println!("PASS");
    }

    {
        //# Make a request to evaluate 4 * 6, then use the result in two more
        //# requests that add 3 and 5.
        //#
        //# Since evaluate() returns its result wrapped in a `Value`, we can pass
        //# that `Value` back to the server in subsequent requests before the first
        //# `evaluate()` has actually returned.  Thus, this example again does only
        //# one network round trip.

        println!("Pipelining eval() calls... ");

        let add = {
            let mut request = calculator.get_operator_request();
            request.init().set_op(calculator::operator::Add);
            request.send().pipeline.get_func()
        };

        let multiply = {
            let mut request = calculator.get_operator_request();
            request.init().set_op(calculator::operator::Multiply);
            request.send().pipeline.get_func()
        };

        //# Build the request to evaluate 4 * 6
        let mut request = calculator.evaluate_request();

        let multiply_call = request.init().get_expression().init_call();
        multiply_call.set_function(multiply);
        let multiply_params = multiply_call.init_params(2);
        multiply_params.get(0).set_literal(4.0);
        multiply_params.get(1).set_literal(6.0);

        let multiply_result = request.send().pipeline.get_value();

        //# Use the result in two calls that add 3 and 5.

        let mut add3_request = calculator.evaluate_request();
        let add3_call = add3_request.init().get_expression().init_call();
        add3_call.set_function(add.clone());
        let add3_params = add3_call.init_params(2);
        add3_params.get(0).set_previous_result(multiply_result.clone());
        add3_params.get(1).set_literal(3.0);
        let mut add3_promise = add3_request.send().pipeline.get_value().read_request().send();

        let mut add5_request = calculator.evaluate_request();
        let add5_call = add5_request.init().get_expression().init_call();
        add5_call.set_function(add);
        let add5_params = add5_call.init_params(2);
        add5_params.get(0).set_previous_result(multiply_result);
        add5_params.get(1).set_literal(5.0);
        let mut add5_promise = add5_request.send().pipeline.get_value().read_request().send();

        assert!(add3_promise.wait().unwrap().get_value() == 27.0);
        assert!(add5_promise.wait().unwrap().get_value() == 29.0);

        println!("PASS");
    }

    {
        //# Our calculator interface supports defining functions.  Here we use it
        //# to define two functions and then make calls to them as follows:
        //#
        //#   f(x, y) = x * 100 + y
        //#   g(x) = f(x, x + 1) * 2;
        //#   f(12, 34)
        //#   g(21)
        //#
        //# Once again, the whole thing takes only one network round trip.

        println!("Defining functions... ");

        let add = {
            let mut request = calculator.get_operator_request();
            request.init().set_op(calculator::operator::Add);
            request.send().pipeline.get_func()
        };

        let multiply = {
            let mut request = calculator.get_operator_request();
            request.init().set_op(calculator::operator::Multiply);
            request.send().pipeline.get_func()
        };

        let f = {
            let mut request = calculator.def_function_request();
            let def_function_params = request.init();
            def_function_params.set_param_count(2);
            {
                let add_call = def_function_params.get_body().init_call();
                add_call.set_function(add.clone());
                let add_params = add_call.init_params(2);
                add_params.get(1).set_parameter(1);

                let multiply_call = add_params.get(0).init_call();
                multiply_call.set_function(multiply.clone());
                let multiply_params = multiply_call.init_params(2);
                multiply_params.get(0).set_parameter(0);
                multiply_params.get(1).set_literal(100.0);
            }
            request.send().pipeline.get_func()
        };

        let g = {
            let mut request = calculator.def_function_request();
            let def_function_params = request.init();
            def_function_params.set_param_count(1);
            {
                let multiply_call = def_function_params.get_body().init_call();
                multiply_call.set_function(multiply);
                let multiply_params = multiply_call.init_params(2);
                multiply_params.get(1).set_literal(2.0);

                let f_call = multiply_params.get(0).init_call();
                f_call.set_function(f.clone());
                let f_params = f_call.init_params(2);
                f_params.get(0).set_parameter(0);

                let add_call = f_params.get(1).init_call();
                add_call.set_function(add);
                let add_params = add_call.init_params(2);
                add_params.get(0).set_parameter(0);
                add_params.get(1).set_literal(1.0);
            }
            request.send().pipeline.get_func()
        };

        let mut f_eval_request = calculator.evaluate_request();
        let f_call = f_eval_request.init().init_expression().init_call();
        f_call.set_function(f);
        let f_params = f_call.init_params(2);
        f_params.get(0).set_literal(12.0);
        f_params.get(1).set_literal(34.0);
        let mut f_eval_promise = f_eval_request.send().pipeline.get_value().read_request().send();

        let mut g_eval_request = calculator.evaluate_request();
        let g_call = g_eval_request.init().init_expression().init_call();
        g_call.set_function(g);
        g_call.init_params(1).get(0).set_literal(21.0);
        let mut g_eval_promise = g_eval_request.send().pipeline.get_value().read_request().send();

        assert!(f_eval_promise.wait().unwrap().get_value() == 1234.0);
        assert!(g_eval_promise.wait().unwrap().get_value() == 4244.0);

        println!("PASS")
    }

    {
        //# Make a request that will call back to a function defined locally.
        //#
        //# Specifically, we will compute 2^(4 + 5).  However, exponent is not
        //# defined by the Calculator server.  So, we'll implement the Function
        //# interface locally and pass it to the server for it to use when
        //# evaluating the expression.
        //#
        //# This example requires two network round trips to complete, because the
        //# server calls back to the client once before finishing.  In this
        //# particular case, this could potentially be optimized by using a tail
        //# call on the server side -- see CallContext::tailCall().  However, to
        //# keep the example simpler, we haven't implemented this optimization in
        //# the sample server.

        println!("Using a callback... ");

        let add = {
            let mut request = calculator.get_operator_request();
            request.init().set_op(calculator::operator::Add);
            request.send().pipeline.get_func()
        };

        let mut request = calculator.evaluate_request();
        {
            let pow_call = request.init().get_expression().init_call();
            pow_call.set_function(FromServer::new(None::<LocalClient>, box PowerFunction));
            let pow_params = pow_call.init_params(2);
            pow_params.get(0).set_literal(2.0);

            let add_call = pow_params.get(1).init_call();
            add_call.set_function(add);
            let add_params = add_call.init_params(2);
            add_params.get(0).set_literal(4.0);
            add_params.get(1).set_literal(5.0);
        }

        let mut response_promise = request.send().pipeline.get_value().read_request().send();
        let response = response_promise.wait().unwrap();

        assert!(response.get_value() == 512.0);

        println!("PASS");
    }
}
<commit_msg>now need to import Float to use powf<commit_after>/*
 * Copyright (c) 2014, David Renshaw (dwrenshaw@gmail.com)
 *
 * See the LICENSE file in the capnproto-rust root directory.
 */

use capnp::capability::{FromServer};
use capnp_rpc::ez_rpc::EzRpcClient;
use capnp_rpc::capability::{InitRequest, LocalClient, WaitForContent};
use calculator_capnp::calculator;

pub struct PowerFunction;

impl calculator::function::Server for PowerFunction {
    fn call(&mut self, mut context : calculator::function::CallContext) {
        use std::num::Float;

        let (params, results) = context.get();
        let params = params.get_params();
        if params.size() != 2 {
            //"Wrong number of parameters"
            return context.fail();
        };
        results.set_value(params.get(0).powf(params.get(1)));
        context.done();
    }
}

pub fn main() {
    let args = ::std::os::args();
    if args.len() != 3 {
        println!("usage: {} client HOST:PORT", args[0]);
        return;
    }

    let mut rpc_client = EzRpcClient::new(args[2].as_slice()).unwrap();

    let calculator : calculator::Client = rpc_client.import_cap("calculator");

    {
        //# Make a request that just evaluates the literal value 123.
        //#
        //# What's interesting here is that evaluate() returns a "Value", which is
        //# another interface and therefore points back to an object living on the
        //# server.  We then have to call read() on that object to read it.
        //# However, even though we are making two RPC's, this block executes in
        //# *one* network round trip because of promise pipelining:  we do not wait
        //# for the first call to complete before we send the second call to the
        //# server.

        println!("Evaluating a literal... ");

        let mut request = calculator.evaluate_request();
        request.init().get_expression().set_literal(123.0);

        let eval_promise = request.send();

        let mut read_promise = eval_promise.pipeline.get_value().read_request().send();

        let response = read_promise.wait().unwrap();
        assert_eq!(response.get_value(), 123.0);

        println!("PASS")
    }

    {
        //# Make a request to evaluate 123 + 45 - 67.
        //#
        //# The Calculator interface requires that we first call getOperator() to
        //# get the addition and subtraction functions, then call evaluate() to use
        //# them.  But, once again, we can get both functions, call evaluate(), and
        //# then read() the result -- four RPCs -- in the time of *one* network
        //# round trip, because of promise pipelining.

        println!("Using add and subtract... ");

        let add = {
            let mut request = calculator.get_operator_request();
            request.init().set_op(calculator::operator::Add);
            request.send().pipeline.get_func()
        };

        let subtract = {
            let mut request = calculator.get_operator_request();
            request.init().set_op(calculator::operator::Subtract);
            request.send().pipeline.get_func()
        };

        let mut request = calculator.evaluate_request();

        let subtract_call = request.init().get_expression().init_call();
        subtract_call.set_function(subtract);
        let subtract_params = subtract_call.init_params(2);
        subtract_params.get(1).set_literal(67.0);

        let add_call = subtract_params.get(0).init_call();
        add_call.set_function(add);
        let add_params = add_call.init_params(2);
        add_params.get(0).set_literal(123.0);
        add_params.get(1).set_literal(45.0);

        let eval_promise = request.send();
        let mut read_promise = eval_promise.pipeline.get_value().read_request().send();
        let response = read_promise.wait().unwrap();
        assert_eq!(response.get_value(), 101.0);

        println!("PASS");
    }

    {
        //# Make a request to evaluate 4 * 6, then use the result in two more
        //# requests that add 3 and 5.
        //#
        //# Since evaluate() returns its result wrapped in a `Value`, we can pass
        //# that `Value` back to the server in subsequent requests before the first
        //# `evaluate()` has actually returned.  Thus, this example again does only
        //# one network round trip.

        println!("Pipelining eval() calls... ");

        let add = {
            let mut request = calculator.get_operator_request();
            request.init().set_op(calculator::operator::Add);
            request.send().pipeline.get_func()
        };

        let multiply = {
            let mut request = calculator.get_operator_request();
            request.init().set_op(calculator::operator::Multiply);
            request.send().pipeline.get_func()
        };

        //# Build the request to evaluate 4 * 6
        let mut request = calculator.evaluate_request();

        let multiply_call = request.init().get_expression().init_call();
        multiply_call.set_function(multiply);
        let multiply_params = multiply_call.init_params(2);
        multiply_params.get(0).set_literal(4.0);
        multiply_params.get(1).set_literal(6.0);

        let multiply_result = request.send().pipeline.get_value();

        //# Use the result in two calls that add 3 and 5.

        let mut add3_request = calculator.evaluate_request();
        let add3_call = add3_request.init().get_expression().init_call();
        add3_call.set_function(add.clone());
        let add3_params = add3_call.init_params(2);
        add3_params.get(0).set_previous_result(multiply_result.clone());
        add3_params.get(1).set_literal(3.0);
        let mut add3_promise = add3_request.send().pipeline.get_value().read_request().send();

        let mut add5_request = calculator.evaluate_request();
        let add5_call = add5_request.init().get_expression().init_call();
        add5_call.set_function(add);
        let add5_params = add5_call.init_params(2);
        add5_params.get(0).set_previous_result(multiply_result);
        add5_params.get(1).set_literal(5.0);
        let mut add5_promise = add5_request.send().pipeline.get_value().read_request().send();

        assert!(add3_promise.wait().unwrap().get_value() == 27.0);
        assert!(add5_promise.wait().unwrap().get_value() == 29.0);

        println!("PASS");
    }

    {
        //# Our calculator interface supports defining functions.  Here we use it
        //# to define two functions and then make calls to them as follows:
        //#
        //#   f(x, y) = x * 100 + y
        //#   g(x) = f(x, x + 1) * 2;
        //#   f(12, 34)
        //#   g(21)
        //#
        //# Once again, the whole thing takes only one network round trip.

        println!("Defining functions... ");

        let add = {
            let mut request = calculator.get_operator_request();
            request.init().set_op(calculator::operator::Add);
            request.send().pipeline.get_func()
        };

        let multiply = {
            let mut request = calculator.get_operator_request();
            request.init().set_op(calculator::operator::Multiply);
            request.send().pipeline.get_func()
        };

        let f = {
            let mut request = calculator.def_function_request();
            let def_function_params = request.init();
            def_function_params.set_param_count(2);
            {
                let add_call = def_function_params.get_body().init_call();
                add_call.set_function(add.clone());
                let add_params = add_call.init_params(2);
                add_params.get(1).set_parameter(1);

                let multiply_call = add_params.get(0).init_call();
                multiply_call.set_function(multiply.clone());
                let multiply_params = multiply_call.init_params(2);
                multiply_params.get(0).set_parameter(0);
                multiply_params.get(1).set_literal(100.0);
            }
            request.send().pipeline.get_func()
        };

        let g = {
            let mut request = calculator.def_function_request();
            let def_function_params = request.init();
            def_function_params.set_param_count(1);
            {
                let multiply_call = def_function_params.get_body().init_call();
                multiply_call.set_function(multiply);
                let multiply_params = multiply_call.init_params(2);
                multiply_params.get(1).set_literal(2.0);

                let f_call = multiply_params.get(0).init_call();
                f_call.set_function(f.clone());
                let f_params = f_call.init_params(2);
                f_params.get(0).set_parameter(0);

                let add_call = f_params.get(1).init_call();
                add_call.set_function(add);
                let add_params = add_call.init_params(2);
                add_params.get(0).set_parameter(0);
                add_params.get(1).set_literal(1.0);
            }
            request.send().pipeline.get_func()
        };

        let mut f_eval_request = calculator.evaluate_request();
        let f_call = f_eval_request.init().init_expression().init_call();
        f_call.set_function(f);
        let f_params = f_call.init_params(2);
        f_params.get(0).set_literal(12.0);
        f_params.get(1).set_literal(34.0);
        let mut f_eval_promise = f_eval_request.send().pipeline.get_value().read_request().send();

        let mut g_eval_request = calculator.evaluate_request();
        let g_call = g_eval_request.init().init_expression().init_call();
        g_call.set_function(g);
        g_call.init_params(1).get(0).set_literal(21.0);
        let mut g_eval_promise = g_eval_request.send().pipeline.get_value().read_request().send();

        assert!(f_eval_promise.wait().unwrap().get_value() == 1234.0);
        assert!(g_eval_promise.wait().unwrap().get_value() == 4244.0);

        println!("PASS")
    }

    {
        //# Make a request that will call back to a function defined locally.
        //#
        //# Specifically, we will compute 2^(4 + 5).  However, exponent is not
        //# defined by the Calculator server.  So, we'll implement the Function
        //# interface locally and pass it to the server for it to use when
        //# evaluating the expression.
        //#
        //# This example requires two network round trips to complete, because the
        //# server calls back to the client once before finishing.  In this
        //# particular case, this could potentially be optimized by using a tail
        //# call on the server side -- see CallContext::tailCall().  However, to
        //# keep the example simpler, we haven't implemented this optimization in
        //# the sample server.

        println!("Using a callback... ");

        let add = {
            let mut request = calculator.get_operator_request();
            request.init().set_op(calculator::operator::Add);
            request.send().pipeline.get_func()
        };

        let mut request = calculator.evaluate_request();
        {
            let pow_call = request.init().get_expression().init_call();
            pow_call.set_function(FromServer::new(None::<LocalClient>, box PowerFunction));
            let pow_params = pow_call.init_params(2);
            pow_params.get(0).set_literal(2.0);

            let add_call = pow_params.get(1).init_call();
            add_call.set_function(add);
            let add_params = add_call.init_params(2);
            add_params.get(0).set_literal(4.0);
            add_params.get(1).set_literal(5.0);
        }

        let mut response_promise = request.send().pipeline.get_value().read_request().send();
        let response = response_promise.wait().unwrap();

        assert!(response.get_value() == 512.0);

        println!("PASS");
    }
}
<|endoftext|>


<commit_before>use std::rc::*;

use super::treenode::*;

///
/// Represents the address of a node relative to another node
///
#[derive(Clone)]
pub enum TreeAddress {
    /// Selects this node
    Here,

    /// Selects a child of this node by index, then selects a new address from there
    ChildAtIndex(usize, Box<TreeAddress>),

    /// Selects a child of this node by tag name, then selects a new address from there
    ChildWithTag(String, Box<TreeAddress>),

    /// Selects a child of this node by looking up the 'nth' child with the specified tag, then selects a new address from there
    ChildWithIndexedTag(String, usize, Box<TreeAddress>)
}

impl TreeNodeIndex for TreeAddress {
    fn lookup_index(&self, parent_node: &Rc<TreeNode>) -> Option<Rc<TreeNode>> {
        match *self {
            TreeAddress::Here => Some(parent_node.to_owned()),

            TreeAddress::ChildAtIndex(ref pos, ref next) => {
                (*pos).lookup_index(parent_node).and_then(|new_parent| {
                    (*next).lookup_index(&new_parent)
                })
            },

            TreeAddress::ChildWithTag(ref name, ref next) => {
                (&**name).lookup_index(parent_node).and_then(|new_parent| {
                    (*next).lookup_index(&new_parent)
                })
            },

            TreeAddress::ChildWithIndexedTag(ref name, ref pos, ref next) => {
                let mut current = parent_node.get_child_ref();
                let mut remaining = *pos;

                loop {
                    match current.to_owned() {
                        Some(ref current_ref) => {
                            if current_ref.get_tag() == name {
                                if remaining == 0 {
                                    return (*next).lookup_index(current_ref);
                                }

                                remaining = remaining-1;
                            }

                            current = current_ref.get_sibling_ref();
                        },

                        None => {
                            return None;
                        }
                    }
                }
            }
        }
    }
}

///
/// Structure representing a tag with an index
///
pub struct TagIndex<'a>(&'a str, usize);

///
/// Structure representing a shorthand address
///
/// This has `TreeNodeIndex` implemented on it, so `treenode.get_child_ref_at(Addr(0, ()))` will work
///
pub struct Addr<TFirst: ToTreeAddress, TSecond: ToTreeAddress>(TFirst, TSecond);

///
/// Trait that is implemented by types that can be converted to tree addresses
///
pub trait ToTreeAddress {
    fn to_tree_address(&self) -> TreeAddress;
    fn to_tree_address_then(&self, then: TreeAddress) -> TreeAddress;
}

impl ToTreeAddress for () {
    #[inline]
    fn to_tree_address(&self) -> TreeAddress {
        TreeAddress::Here
    }

    #[inline]
    fn to_tree_address_then(&self, then: TreeAddress) -> TreeAddress {
        then
    }
}

impl ToTreeAddress for usize {
    #[inline]
    fn to_tree_address(&self) -> TreeAddress {
        TreeAddress::ChildAtIndex(*self, Box::new(TreeAddress::Here))
    }

    #[inline]
    fn to_tree_address_then(&self, then: TreeAddress) -> TreeAddress {
        TreeAddress::ChildAtIndex(*self, Box::new(then))
    }
}

impl<'a> ToTreeAddress for TagIndex<'a> {
    #[inline]
    fn to_tree_address(&self) -> TreeAddress {
        let TagIndex(ref tag, ref pos) = *self;
        TreeAddress::ChildWithIndexedTag((*tag).to_string(), *pos, Box::new(TreeAddress::Here))
    }

    #[inline]
    fn to_tree_address_then(&self, then: TreeAddress) -> TreeAddress {
        let TagIndex(ref tag, ref pos) = *self;
        TreeAddress::ChildWithIndexedTag((*tag).to_string(), *pos, Box::new(then))
    }
}

impl<'a> ToTreeAddress for &'a str {
    #[inline]
    fn to_tree_address(&self) -> TreeAddress {
        TreeAddress::ChildWithTag((*self).to_string(), Box::new(TreeAddress::Here))
    }

    #[inline]
    fn to_tree_address_then(&self, then: TreeAddress) -> TreeAddress {
        TreeAddress::ChildWithTag((*self).to_string(), Box::new(then))
    }
}

impl ToTreeAddress for TreeAddress {
    #[inline]
    fn to_tree_address(&self) -> TreeAddress {
        (*self).to_owned()
    }

    fn to_tree_address_then(&self, then: TreeAddress) -> TreeAddress {
        match *self {
            TreeAddress::Here                                                   => then,
            TreeAddress::ChildAtIndex(ref index, ref old_then)                  => TreeAddress::ChildAtIndex(*index, Box::new((*old_then).to_tree_address_then(then))),
            TreeAddress::ChildWithTag(ref tag, ref old_then)                    => TreeAddress::ChildWithTag((*tag).to_owned(), Box::new((*old_then).to_tree_address_then(then))),
            TreeAddress::ChildWithIndexedTag(ref tag, ref index, ref old_then)  => TreeAddress::ChildWithIndexedTag((*tag).to_owned(), *index, Box::new((*old_then).to_tree_address_then(then)))
        }
    }
}

impl<TFirst: ToTreeAddress, TSecond: ToTreeAddress> ToTreeAddress for (TFirst, TSecond) {
    #[inline]
    fn to_tree_address(&self) -> TreeAddress {
        let (ref first, ref second) = *self;

        first.to_tree_address_then(second.to_tree_address())
    }

    #[inline]
    fn to_tree_address_then(&self, then: TreeAddress) -> TreeAddress {
        self.to_tree_address().to_tree_address_then(then)
    }
}

impl<TFirst: ToTreeAddress, TSecond: ToTreeAddress> ToTreeAddress for Addr<TFirst, TSecond> {
    #[inline]
    fn to_tree_address(&self) -> TreeAddress {
        let Addr(ref first, ref second) = *self;

        first.to_tree_address_then(second.to_tree_address())
    }

    #[inline]
    fn to_tree_address_then(&self, then: TreeAddress) -> TreeAddress {
        self.to_tree_address().to_tree_address_then(then)
    }
}

impl<TFirst: ToTreeAddress, TSecond: ToTreeAddress> TreeNodeIndex for Addr<TFirst, TSecond> {
    #[inline]
    fn lookup_index(&self, parent_node: &Rc<TreeNode>) -> Option<Rc<TreeNode>> {
        let Addr(ref first, ref second) = *self;

        first.to_tree_address_then(second.to_tree_address()).lookup_index(parent_node)
    }
}

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

    #[test]
    fn lookup_here() {
        let some_tree = tree!("Here", "There", "Everywhere");

        assert!(some_tree.get_child_ref_at(TreeAddress::Here).unwrap().get_tag() == "Here");
    }

    #[test]
    fn lookup_child() {
        let some_tree = tree!("Here", "There", "Everywhere");

        assert!(some_tree.get_child_ref_at(Addr(0, ())).unwrap().get_tag() == "There");
        assert!(some_tree.get_child_ref_at(Addr(1, ())).unwrap().get_tag() == "Everywhere");
    }

    #[test]
    fn lookup_tag() {
        let some_tree = tree!("Here", "There", "Everywhere");

        assert!(some_tree.get_child_ref_at(Addr("There", ())).unwrap().get_tag() == "There");
        assert!(some_tree.get_child_ref_at(Addr("Everywhere", ())).unwrap().get_tag() == "Everywhere");
    }

    #[test]
    fn lookup_indexed_tag() {
        let some_tree = tree!("Here", ("Tag", "First"), ("Tag", "Second"));

        assert!(some_tree.get_child_ref_at(Addr(TagIndex("Tag", 0), ())).unwrap().get_value().to_str("") == "First");
        assert!(some_tree.get_child_ref_at(Addr(TagIndex("Tag", 1), ())).unwrap().get_value().to_str("") == "Second");
    }

    #[test]
    fn lookup_grandchild() {
        let some_tree = tree!("Here", tree!("There", "Everywhere"));

        assert!(some_tree.get_child_ref_at(Addr("There", (0, ()))).unwrap().get_tag() == "Everywhere");
    }

    #[test]
    fn address_after_address() {
        let some_tree = tree!("Here", tree!("There", tree!("Everywhere", "Also here")));

        // Address formed of a complicated address with an extra address appended
        let everywhere_address = Addr("There", ("Everywhere", ()));
        assert!(some_tree.get_child_ref_at(Addr(everywhere_address, (0, ()))).unwrap().get_tag() == "Also here");
    }
}
<commit_msg>In order to deal with subscriptions, we need to be able to determine the relation between two tree addresses<commit_after>use std::rc::*;

use super::treenode::*;

///
/// Represents the address of a node relative to another node
///
#[derive(Clone)]
pub enum TreeAddress {
    /// Selects this node
    Here,

    /// Selects a child of this node by index, then selects a new address from there
    ChildAtIndex(usize, Box<TreeAddress>),

    /// Selects a child of this node by tag name, then selects a new address from there
    ChildWithTag(String, Box<TreeAddress>),

    /// Selects a child of this node by looking up the 'nth' child with the specified tag, then selects a new address from there
    ChildWithIndexedTag(String, usize, Box<TreeAddress>)
}

impl TreeNodeIndex for TreeAddress {
    fn lookup_index(&self, parent_node: &Rc<TreeNode>) -> Option<Rc<TreeNode>> {
        match *self {
            TreeAddress::Here => Some(parent_node.to_owned()),

            TreeAddress::ChildAtIndex(ref pos, ref next) => {
                (*pos).lookup_index(parent_node).and_then(|new_parent| {
                    (*next).lookup_index(&new_parent)
                })
            },

            TreeAddress::ChildWithTag(ref name, ref next) => {
                (&**name).lookup_index(parent_node).and_then(|new_parent| {
                    (*next).lookup_index(&new_parent)
                })
            },

            TreeAddress::ChildWithIndexedTag(ref name, ref pos, ref next) => {
                let mut current = parent_node.get_child_ref();
                let mut remaining = *pos;

                loop {
                    match current.to_owned() {
                        Some(ref current_ref) => {
                            if current_ref.get_tag() == name {
                                if remaining == 0 {
                                    return (*next).lookup_index(current_ref);
                                }

                                remaining = remaining-1;
                            }

                            current = current_ref.get_sibling_ref();
                        },

                        None => {
                            return None;
                        }
                    }
                }
            }
        }
    }
}

impl TreeAddress {
    ///
    /// Returns whether or not address is a parent of this address, or the same address
    ///
    /// Will return None if the two addresses are in incompatible formats (eg, if a tag needs to match up against an indexed address)
    ///
    pub fn is_parent_of(&self, address: &TreeAddress) -> Option<bool> {
        match *self {
            TreeAddress::Here => Some(true),

            TreeAddress::ChildAtIndex(self_index, ref self_child) => {
                match *address {
                    TreeAddress::ChildAtIndex(address_index, ref address_child) => {
                        if self_index == address_index {
                            self_child.is_parent_of(address_child)
                        } else {
                            Some(false)
                        }
                    },

                    TreeAddress::Here   => Some(false),
                    _                   => None
                }
            },

            TreeAddress::ChildWithTag(ref self_tag, ref self_child) => {
                match *address {
                    TreeAddress::ChildWithTag(ref address_tag, ref address_child) => {
                        if *self_tag == *address_tag {
                            self_child.is_parent_of(address_child)
                        } else {
                            Some(false)
                        }
                    },

                    TreeAddress::Here   => Some(false),
                    _                   => None
                }
            },

            TreeAddress::ChildWithIndexedTag(ref self_tag, self_index, ref self_child) => {
                match *address {
                    TreeAddress::ChildWithIndexedTag(ref address_tag, address_index, ref address_child) => {
                        if self_index == address_index && *self_tag == *address_tag {
                            self_child.is_parent_of(address_child)
                        } else {
                            Some(false)
                        }
                    },

                    TreeAddress::Here   => Some(false),
                    _                   => None
                }
            },
        }
    }

    ///
    /// Returns whether or not address is a child of this address or the same address
    ///
    #[inline]
    pub fn is_child_of(&self, address: &TreeAddress) -> Option<bool> {
        address.is_parent_of(self)
    }
}

///
/// Structure representing a tag with an index
///
pub struct TagIndex<'a>(&'a str, usize);

///
/// Structure representing a shorthand address
///
/// This has `TreeNodeIndex` implemented on it, so `treenode.get_child_ref_at(Addr(0, ()))` will work
///
pub struct Addr<TFirst: ToTreeAddress, TSecond: ToTreeAddress>(TFirst, TSecond);

///
/// Trait that is implemented by types that can be converted to tree addresses
///
pub trait ToTreeAddress {
    fn to_tree_address(&self) -> TreeAddress;
    fn to_tree_address_then(&self, then: TreeAddress) -> TreeAddress;
}

impl ToTreeAddress for () {
    #[inline]
    fn to_tree_address(&self) -> TreeAddress {
        TreeAddress::Here
    }

    #[inline]
    fn to_tree_address_then(&self, then: TreeAddress) -> TreeAddress {
        then
    }
}

impl ToTreeAddress for usize {
    #[inline]
    fn to_tree_address(&self) -> TreeAddress {
        TreeAddress::ChildAtIndex(*self, Box::new(TreeAddress::Here))
    }

    #[inline]
    fn to_tree_address_then(&self, then: TreeAddress) -> TreeAddress {
        TreeAddress::ChildAtIndex(*self, Box::new(then))
    }
}

impl<'a> ToTreeAddress for TagIndex<'a> {
    #[inline]
    fn to_tree_address(&self) -> TreeAddress {
        let TagIndex(ref tag, ref pos) = *self;
        TreeAddress::ChildWithIndexedTag((*tag).to_string(), *pos, Box::new(TreeAddress::Here))
    }

    #[inline]
    fn to_tree_address_then(&self, then: TreeAddress) -> TreeAddress {
        let TagIndex(ref tag, ref pos) = *self;
        TreeAddress::ChildWithIndexedTag((*tag).to_string(), *pos, Box::new(then))
    }
}

impl<'a> ToTreeAddress for &'a str {
    #[inline]
    fn to_tree_address(&self) -> TreeAddress {
        TreeAddress::ChildWithTag((*self).to_string(), Box::new(TreeAddress::Here))
    }

    #[inline]
    fn to_tree_address_then(&self, then: TreeAddress) -> TreeAddress {
        TreeAddress::ChildWithTag((*self).to_string(), Box::new(then))
    }
}

impl ToTreeAddress for TreeAddress {
    #[inline]
    fn to_tree_address(&self) -> TreeAddress {
        (*self).to_owned()
    }

    fn to_tree_address_then(&self, then: TreeAddress) -> TreeAddress {
        match *self {
            TreeAddress::Here                                                   => then,
            TreeAddress::ChildAtIndex(ref index, ref old_then)                  => TreeAddress::ChildAtIndex(*index, Box::new((*old_then).to_tree_address_then(then))),
            TreeAddress::ChildWithTag(ref tag, ref old_then)                    => TreeAddress::ChildWithTag((*tag).to_owned(), Box::new((*old_then).to_tree_address_then(then))),
            TreeAddress::ChildWithIndexedTag(ref tag, ref index, ref old_then)  => TreeAddress::ChildWithIndexedTag((*tag).to_owned(), *index, Box::new((*old_then).to_tree_address_then(then)))
        }
    }
}

impl<TFirst: ToTreeAddress, TSecond: ToTreeAddress> ToTreeAddress for (TFirst, TSecond) {
    #[inline]
    fn to_tree_address(&self) -> TreeAddress {
        let (ref first, ref second) = *self;

        first.to_tree_address_then(second.to_tree_address())
    }

    #[inline]
    fn to_tree_address_then(&self, then: TreeAddress) -> TreeAddress {
        self.to_tree_address().to_tree_address_then(then)
    }
}

impl<TFirst: ToTreeAddress, TSecond: ToTreeAddress> ToTreeAddress for Addr<TFirst, TSecond> {
    #[inline]
    fn to_tree_address(&self) -> TreeAddress {
        let Addr(ref first, ref second) = *self;

        first.to_tree_address_then(second.to_tree_address())
    }

    #[inline]
    fn to_tree_address_then(&self, then: TreeAddress) -> TreeAddress {
        self.to_tree_address().to_tree_address_then(then)
    }
}

impl<TFirst: ToTreeAddress, TSecond: ToTreeAddress> TreeNodeIndex for Addr<TFirst, TSecond> {
    #[inline]
    fn lookup_index(&self, parent_node: &Rc<TreeNode>) -> Option<Rc<TreeNode>> {
        let Addr(ref first, ref second) = *self;

        first.to_tree_address_then(second.to_tree_address()).lookup_index(parent_node)
    }
}

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

    #[test]
    fn lookup_here() {
        let some_tree = tree!("Here", "There", "Everywhere");

        assert!(some_tree.get_child_ref_at(TreeAddress::Here).unwrap().get_tag() == "Here");
    }

    #[test]
    fn lookup_child() {
        let some_tree = tree!("Here", "There", "Everywhere");

        assert!(some_tree.get_child_ref_at(Addr(0, ())).unwrap().get_tag() == "There");
        assert!(some_tree.get_child_ref_at(Addr(1, ())).unwrap().get_tag() == "Everywhere");
    }

    #[test]
    fn lookup_tag() {
        let some_tree = tree!("Here", "There", "Everywhere");

        assert!(some_tree.get_child_ref_at(Addr("There", ())).unwrap().get_tag() == "There");
        assert!(some_tree.get_child_ref_at(Addr("Everywhere", ())).unwrap().get_tag() == "Everywhere");
    }

    #[test]
    fn lookup_indexed_tag() {
        let some_tree = tree!("Here", ("Tag", "First"), ("Tag", "Second"));

        assert!(some_tree.get_child_ref_at(Addr(TagIndex("Tag", 0), ())).unwrap().get_value().to_str("") == "First");
        assert!(some_tree.get_child_ref_at(Addr(TagIndex("Tag", 1), ())).unwrap().get_value().to_str("") == "Second");
    }

    #[test]
    fn lookup_grandchild() {
        let some_tree = tree!("Here", tree!("There", "Everywhere"));

        assert!(some_tree.get_child_ref_at(Addr("There", (0, ()))).unwrap().get_tag() == "Everywhere");
    }

    #[test]
    fn address_after_address() {
        let some_tree = tree!("Here", tree!("There", tree!("Everywhere", "Also here")));

        // Address formed of a complicated address with an extra address appended
        let everywhere_address = Addr("There", ("Everywhere", ()));
        assert!(some_tree.get_child_ref_at(Addr(everywhere_address, (0, ()))).unwrap().get_tag() == "Also here");
    }

    #[test]
    fn here_is_parent_of_here() {
        let here        = ().to_tree_address();
        let is_parent   = here.is_parent_of(&here);
        let is_child    = here.is_child_of(&here);

        assert!(is_parent.unwrap());
        assert!(is_child.unwrap());
    }

    #[test]
    fn here_is_parent_of_anything() {
        let here        = ().to_tree_address();
        let there       = (0, (1, 2)).to_tree_address();
        let is_parent   = here.is_parent_of(&there);
        let is_child    = here.is_child_of(&there);

        assert!(is_parent.unwrap());
        assert!(!is_child.unwrap());
    }

    #[test]
    fn nothing_is_parent_of_here() {
        let here        = ().to_tree_address();
        let there       = (0, (1, 2)).to_tree_address();
        let is_parent   = there.is_parent_of(&here);
        let is_child    = there.is_child_of(&here);

        assert!(!is_parent.unwrap());
        assert!(is_child.unwrap());
    }

    #[test]
    fn same_address_is_parent() {
        let here        = (0, (1, 2)).to_tree_address();
        let there       = (0, (1, 2)).to_tree_address();
        let is_parent   = here.is_parent_of(&there);
        let is_child    = here.is_child_of(&there);

        assert!(is_parent.unwrap());
        assert!(is_child.unwrap());
    }

    #[test]
    fn indexed_parent() {
        let here        = (0, 1).to_tree_address();
        let there       = (0, (1, 2)).to_tree_address();
        let is_parent   = here.is_parent_of(&there);
        let is_child    = here.is_child_of(&there);

        assert!(is_parent.unwrap());
        assert!(!is_child.unwrap());
    }

    #[test]
    fn bad_indexed_parent() {
        let here        = (1, 0).to_tree_address();
        let there       = (0, (1, 2)).to_tree_address();
        let is_parent   = here.is_parent_of(&there);
        let is_child    = here.is_child_of(&there);

        assert!(!is_parent.unwrap());
        assert!(!is_child.unwrap());
    }

    #[test]
    fn tagged_parent() {
        let here        = ("first", "second").to_tree_address();
        let there       = ("first", ("second", "third")).to_tree_address();
        let is_parent   = here.is_parent_of(&there);
        let is_child    = here.is_child_of(&there);

        assert!(is_parent.unwrap());
        assert!(!is_child.unwrap());
    }

    #[test]
    fn bad_tagged_parent() {
        let here        = ("other tag", "second").to_tree_address();
        let there       = ("first", ("second", "third")).to_tree_address();
        let is_parent   = here.is_parent_of(&there);
        let is_child    = here.is_child_of(&there);

        assert!(!is_parent.unwrap());
        assert!(!is_child.unwrap());
    }

    #[test]
    fn tagged_indexed_parent() {
        let here        = (TagIndex("first", 1), TagIndex("second", 2)).to_tree_address();
        let there       = (TagIndex("first", 1), (TagIndex("second", 2), TagIndex("third", 3))).to_tree_address();
        let is_parent   = here.is_parent_of(&there);
        let is_child    = here.is_child_of(&there);

        assert!(is_parent.unwrap());
        assert!(!is_child.unwrap());
    }

    #[test]
    fn bad_tagged_indexed_parent() {
        let here        = (TagIndex("other tag", 1), TagIndex("second", 2)).to_tree_address();
        let there       = (TagIndex("first", 1), (TagIndex("second", 2), TagIndex("third", 3))).to_tree_address();
        let is_parent   = here.is_parent_of(&there);
        let is_child    = here.is_child_of(&there);

        assert!(!is_parent.unwrap());
        assert!(!is_child.unwrap());
    }

    #[test]
    fn tagged_bad_indexed_parent() {
        let here        = (TagIndex("first", 2), TagIndex("second", 2)).to_tree_address();
        let there       = (TagIndex("first", 1), (TagIndex("second", 2), TagIndex("third", 3))).to_tree_address();
        let is_parent   = here.is_parent_of(&there);
        let is_child    = here.is_child_of(&there);

        assert!(!is_parent.unwrap());
        assert!(!is_child.unwrap());
    }

    #[test]
    fn different_address_types_cant_be_checked() {
        let indexed         = 1.to_tree_address();
        let tagged          = "tag".to_tree_address();
        let index_tagged    = TagIndex("tag", 0).to_tree_address();

        assert!(indexed.is_parent_of(&tagged).is_none());
        assert!(indexed.is_parent_of(&index_tagged).is_none());
        assert!(tagged.is_parent_of(&indexed).is_none());
        assert!(tagged.is_parent_of(&index_tagged).is_none());
        assert!(index_tagged.is_parent_of(&indexed).is_none());
        assert!(index_tagged.is_parent_of(&tagged).is_none());
    }
}
<|endoftext|>


<commit_before>extern crate chrono;

use std::error;
use std::io::prelude::*;
use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian};
use self::chrono::{Duration, NaiveDate, NaiveTime, NaiveDateTime, DateTime, UTC};

use Result;
use error::Error;
use types::{FromSql, ToSql, IsNull, Type, SessionInfo};

fn base() -> NaiveDateTime {
    NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0)
}

impl FromSql for NaiveDateTime {
    fn from_sql<R: Read>(_: &Type, raw: &mut R, _: &SessionInfo) -> Result<NaiveDateTime> {
        let t = try!(raw.read_i64::<BigEndian>());
        Ok(base() + Duration::microseconds(t))
    }

    accepts!(Type::Timestamp);
}

impl ToSql for NaiveDateTime {
    fn to_sql<W: Write+?Sized>(&self, _: &Type, mut w: &mut W, _: &SessionInfo) -> Result<IsNull> {
        let t = (*self - base()).num_microseconds().unwrap();
        try!(w.write_i64::<BigEndian>(t));
        Ok(IsNull::No)
    }

    accepts!(Type::Timestamp);
    to_sql_checked!();
}

impl FromSql for DateTime<UTC> {
    fn from_sql<R: Read>(type_: &Type, raw: &mut R, info: &SessionInfo) -> Result<DateTime<UTC>> {
        let naive = try!(NaiveDateTime::from_sql(type_, raw, info));
        Ok(DateTime::from_utc(naive, UTC))
    }

    accepts!(Type::TimestampTZ);
}

impl ToSql for DateTime<UTC> {
    fn to_sql<W: Write+?Sized>(&self, type_: &Type, mut w: &mut W, info: &SessionInfo)
                               -> Result<IsNull> {
        self.naive_utc().to_sql(type_, w, info)
    }

    accepts!(Type::TimestampTZ);
    to_sql_checked!();
}

impl FromSql for NaiveDate {
    fn from_sql<R: Read>(_: &Type, raw: &mut R, _: &SessionInfo) -> Result<NaiveDate> {
        let jd = try!(raw.read_i32::<BigEndian>());
        Ok(base().date() + Duration::days(jd as i64))
    }

    accepts!(Type::Date);
}

impl ToSql for NaiveDate {
    fn to_sql<W: Write+?Sized>(&self, _: &Type, mut w: &mut W, _: &SessionInfo) -> Result<IsNull> {
        let jd = (*self - base().date()).num_days();
        if jd > i32::max_value() as i64 || jd < i32::min_value() as i64 {
            let err: Box<error::Error+Sync+Send> = "value too large to transmit".into();
            return Err(Error::Conversion(err));
        }

        try!(w.write_i32::<BigEndian>(jd as i32));
        Ok(IsNull::No)
    }

    accepts!(Type::Date);
    to_sql_checked!();
}

impl FromSql for NaiveTime {
    fn from_sql<R: Read>(_: &Type, raw: &mut R, _: &SessionInfo) -> Result<NaiveTime> {
        let usec = try!(raw.read_i64::<BigEndian>());
        Ok(NaiveTime::from_hms(0, 0, 0) + Duration::microseconds(usec))
    }

    accepts!(Type::Time);
}

impl ToSql for NaiveTime {
    fn to_sql<W: Write+?Sized>(&self, _: &Type, mut w: &mut W, _: &SessionInfo) -> Result<IsNull> {
        let delta = *self - NaiveTime::from_hms(0, 0, 0);
        try!(w.write_i64::<BigEndian>(delta.num_microseconds().unwrap()));
        Ok(IsNull::No)
    }

    accepts!(Type::Time);
    to_sql_checked!();
}
<commit_msg>Implement ToSql and FromSql for DateTime<{Local,FixedOffset}><commit_after>extern crate chrono;

use std::error;
use std::io::prelude::*;
use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian};
use self::chrono::{Duration, NaiveDate, NaiveTime, NaiveDateTime, DateTime, UTC, Local, FixedOffset};

use Result;
use error::Error;
use types::{FromSql, ToSql, IsNull, Type, SessionInfo};

fn base() -> NaiveDateTime {
    NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0)
}

impl FromSql for NaiveDateTime {
    fn from_sql<R: Read>(_: &Type, raw: &mut R, _: &SessionInfo) -> Result<NaiveDateTime> {
        let t = try!(raw.read_i64::<BigEndian>());
        Ok(base() + Duration::microseconds(t))
    }

    accepts!(Type::Timestamp);
}

impl ToSql for NaiveDateTime {
    fn to_sql<W: Write+?Sized>(&self, _: &Type, mut w: &mut W, _: &SessionInfo) -> Result<IsNull> {
        let t = (*self - base()).num_microseconds().unwrap();
        try!(w.write_i64::<BigEndian>(t));
        Ok(IsNull::No)
    }

    accepts!(Type::Timestamp);
    to_sql_checked!();
}

impl FromSql for DateTime<UTC> {
    fn from_sql<R: Read>(type_: &Type, raw: &mut R, info: &SessionInfo) -> Result<DateTime<UTC>> {
        let naive = try!(NaiveDateTime::from_sql(type_, raw, info));
        Ok(DateTime::from_utc(naive, UTC))
    }

    accepts!(Type::TimestampTZ);
}

impl ToSql for DateTime<UTC> {
    fn to_sql<W: Write+?Sized>(&self, type_: &Type, mut w: &mut W, info: &SessionInfo)
                               -> Result<IsNull> {
        self.naive_utc().to_sql(type_, w, info)
    }

    accepts!(Type::TimestampTZ);
    to_sql_checked!();
}

impl FromSql for DateTime<Local> {
    fn from_sql<R: Read>(type_: &Type, raw: &mut R, info: &SessionInfo) -> Result<DateTime<Local>> {
        let utc = try!(DateTime::<UTC>::from_sql(type_, raw, info));
        Ok(utc.with_timezone(&Local))
    }

    accepts!(Type::TimestampTZ);
}

impl ToSql for DateTime<Local> {
    fn to_sql<W: Write+?Sized>(&self, type_: &Type, mut w: &mut W, info: &SessionInfo)
                               -> Result<IsNull> {
        self.with_timezone(&UTC).to_sql(type_, w, info)
    }

    accepts!(Type::TimestampTZ);
    to_sql_checked!();
}

impl FromSql for DateTime<FixedOffset> {
    fn from_sql<R: Read>(type_: &Type, raw: &mut R, info: &SessionInfo)
                         -> Result<DateTime<FixedOffset>> {
        let utc = try!(DateTime::<UTC>::from_sql(type_, raw, info));
        Ok(utc.with_timezone(&FixedOffset::east(0)))
    }

    accepts!(Type::TimestampTZ);
}

impl ToSql for DateTime<FixedOffset> {
    fn to_sql<W: Write+?Sized>(&self, type_: &Type, mut w: &mut W, info: &SessionInfo)
                               -> Result<IsNull> {
        self.with_timezone(&UTC).to_sql(type_, w, info)
    }

    accepts!(Type::TimestampTZ);
    to_sql_checked!();
}

impl FromSql for NaiveDate {
    fn from_sql<R: Read>(_: &Type, raw: &mut R, _: &SessionInfo) -> Result<NaiveDate> {
        let jd = try!(raw.read_i32::<BigEndian>());
        Ok(base().date() + Duration::days(jd as i64))
    }

    accepts!(Type::Date);
}

impl ToSql for NaiveDate {
    fn to_sql<W: Write+?Sized>(&self, _: &Type, mut w: &mut W, _: &SessionInfo) -> Result<IsNull> {
        let jd = (*self - base().date()).num_days();
        if jd > i32::max_value() as i64 || jd < i32::min_value() as i64 {
            let err: Box<error::Error+Sync+Send> = "value too large to transmit".into();
            return Err(Error::Conversion(err));
        }

        try!(w.write_i32::<BigEndian>(jd as i32));
        Ok(IsNull::No)
    }

    accepts!(Type::Date);
    to_sql_checked!();
}

impl FromSql for NaiveTime {
    fn from_sql<R: Read>(_: &Type, raw: &mut R, _: &SessionInfo) -> Result<NaiveTime> {
        let usec = try!(raw.read_i64::<BigEndian>());
        Ok(NaiveTime::from_hms(0, 0, 0) + Duration::microseconds(usec))
    }

    accepts!(Type::Time);
}

impl ToSql for NaiveTime {
    fn to_sql<W: Write+?Sized>(&self, _: &Type, mut w: &mut W, _: &SessionInfo) -> Result<IsNull> {
        let delta = *self - NaiveTime::from_hms(0, 0, 0);
        try!(w.write_i64::<BigEndian>(delta.num_microseconds().unwrap()));
        Ok(IsNull::No)
    }

    accepts!(Type::Time);
    to_sql_checked!();
}
<|endoftext|>


<commit_before>use bytes::BufMut;
use ruma_api::{
    error::{FromHttpResponseError, IntoHttpError, MatrixError},
    ruma_api, IncomingResponse, OutgoingResponse,
};
use ruma_serde::Outgoing;

ruma_api! {
    metadata: {
        description: "Does something.",
        method: POST, // An `http::Method` constant. No imports required.
        name: "some_endpoint",
        path: "/_matrix/some/endpoint/:foo",
        rate_limited: false,
        authentication: None,
    }

    #[derive(PartialEq)] // Make sure attributes work
    request: {
        // With no attribute on the field, it will be put into the body of the request.
        #[ruma_api(path)]
        pub foo: String,
    }
}

#[derive(Outgoing)]
pub struct Response;

impl IncomingResponse for Response {
    type EndpointError = MatrixError;

    fn try_from_http_response<T: AsRef<[u8]>>(
        _: http::Response<T>,
    ) -> Result<Self, FromHttpResponseError<MatrixError>> {
        todo!()
    }
}

impl OutgoingResponse for Response {
    fn try_into_http_response<T: Default + BufMut>(
        self,
    ) -> Result<http::Response<T>, IntoHttpError> {
        todo!()
    }
}

fn main() {
    let req1 = Request { foo: "foo".into() };
    let req2 = req1.clone();

    assert_eq!(req1, req2);
}
<commit_msg>api: Remove incorrect attribute on compile test<commit_after>use bytes::BufMut;
use ruma_api::{
    error::{FromHttpResponseError, IntoHttpError, MatrixError},
    ruma_api, IncomingResponse, OutgoingResponse,
};
use ruma_serde::Outgoing;

ruma_api! {
    metadata: {
        description: "Does something.",
        method: POST, // An `http::Method` constant. No imports required.
        name: "some_endpoint",
        path: "/_matrix/some/endpoint",
        rate_limited: false,
        authentication: None,
    }

    #[derive(PartialEq)] // Make sure attributes work
    request: {
        // With no attribute on the field, it will be put into the body of the request.
        pub foo: String,
    }
}

#[derive(Outgoing)]
pub struct Response;

impl IncomingResponse for Response {
    type EndpointError = MatrixError;

    fn try_from_http_response<T: AsRef<[u8]>>(
        _: http::Response<T>,
    ) -> Result<Self, FromHttpResponseError<MatrixError>> {
        todo!()
    }
}

impl OutgoingResponse for Response {
    fn try_into_http_response<T: Default + BufMut>(
        self,
    ) -> Result<http::Response<T>, IntoHttpError> {
        todo!()
    }
}

fn main() {
    let req1 = Request { foo: "foo".into() };
    let req2 = req1.clone();

    assert_eq!(req1, req2);
}
<|endoftext|>