<commit_before>use std::collections::{HashMap, TreeMap};
use std::hash::Hash;

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

pub trait Deserialize<D, E> {
    fn deserialize(d: &mut D) -> Result<Self, E>;
}

pub trait Deserializer<E> {
    fn visit<
        R,
        V: Visitor<Self, R, E>,
    >(&mut self, visitor: &mut V) -> Result<R, E>;

    fn visit_option<
        R,
        V: Visitor<Self, R, E>,
    >(&mut self, visitor: &mut V) -> Result<R, E> {
        self.visit(visitor)
    }

    fn syntax_error(&mut self) -> E;

    fn end_of_stream_error(&mut self) -> E;
}

pub trait Visitor<D: Deserializer<E>, R, E> {
    fn visit_null(&mut self, d: &mut D) -> Result<R, E> {
        Err(d.syntax_error())
    }

    fn visit_int(&mut self, d: &mut D, _v: int) -> Result<R, E> {
        Err(d.syntax_error())
    }

    fn visit_str(&mut self, d: &mut D, v: &str) -> Result<R, E> {
        self.visit_string(d, v.to_string())
    }

    fn visit_string(&mut self, d: &mut D, _v: String) -> Result<R, E> {
        Err(d.syntax_error())
    }

    fn visit_option<
        V: OptionVisitor<D, E>,
    >(&mut self, d: &mut D, _visitor: V) -> Result<R, E> {
        Err(d.syntax_error())
    }

    fn visit_seq<
        V: SeqVisitor<D, E>,
    >(&mut self, d: &mut D, _visitor: V) -> Result<R, E> {
        Err(d.syntax_error())
    }

    fn visit_map<
        V: MapVisitor<D, E>,
    >(&mut self, d: &mut D, _visitor: V) -> Result<R, E> {
        Err(d.syntax_error())
    }
}

pub trait OptionVisitor<D, E> {
    fn visit<
        T: Deserialize<D, E>,
    >(&mut self, d: &mut D) -> Result<Option<T>, E>;
}

pub trait SeqVisitor<D, E> {
    fn visit<
        T: Deserialize<D, E>,
    >(&mut self, d: &mut D) -> Result<Option<T>, E>;

    fn end(&mut self, d: &mut D) -> Result<(), E>;

    #[inline]
    fn size_hint(&self, _d: &mut D) -> (uint, Option<uint>) {
        (0, None)
    }
}

pub trait MapVisitor<D, E> {
    fn visit<
        K: Deserialize<D, E>,
        V: Deserialize<D, E>,
    >(&mut self, d: &mut D) -> Result<Option<(K, V)>, E>;

    fn end(&mut self, d: &mut D) -> Result<(), E>;

    #[inline]
    fn size_hint(&self, _d: &mut D) -> (uint, Option<uint>) {
        (0, None)
    }
}

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

impl<
    D: Deserializer<E>,
    E,
> Deserialize<D, E> for () {
    fn deserialize(d: &mut D) -> Result<(), E> {
        struct Visitor;

        impl<D: Deserializer<E>, E> self::Visitor<D, (), E> for Visitor {
            fn visit_null(&mut self, _d: &mut D) -> Result<(), E> {
                Ok(())
            }
        }

        d.visit(&mut Visitor)
    }
}

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

impl<
    D: Deserializer<E>,
    E,
> Deserialize<D, E> for int {
    fn deserialize(d: &mut D) -> Result<int, E> {
        struct Visitor;

        impl<D: Deserializer<E>, E> self::Visitor<D, int, E> for Visitor {
            fn visit_int(&mut self, _d: &mut D, v: int) -> Result<int, E> {
                Ok(v)
            }
        }

        d.visit(&mut Visitor)
    }
}

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

impl<
    D: Deserializer<E>,
    E,
> Deserialize<D, E> for String {
    fn deserialize(d: &mut D) -> Result<String, E> {
        struct Visitor;

        impl<D: Deserializer<E>, E> self::Visitor<D, String, E> for Visitor {
            fn visit_string(&mut self, _d: &mut D, v: String) -> Result<String, E> {
                Ok(v)
            }
        }

        d.visit(&mut Visitor)
    }
}

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

impl<
    T: Deserialize<D, E>,
    D: Deserializer<E>,
    E,
> Deserialize<D, E> for Option<T> {
    fn deserialize(d: &mut D) -> Result<Option<T>, E> {
        struct Visitor;

        impl<
            T: Deserialize<D, E>,
            D: Deserializer<E>,
            E,
        > self::Visitor<D, Option<T>, E> for Visitor {
            fn visit_option<
                V: OptionVisitor<D, E>,
            >(&mut self, d: &mut D, mut visitor: V) -> Result<Option<T>, E> {
                visitor.visit(d)
            }
        }

        d.visit_option(&mut Visitor)
    }
}

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

impl<
    T: Deserialize<D, E>,
    D: Deserializer<E>,
    E,
> Deserialize<D, E> for Vec<T> {
    fn deserialize(d: &mut D) -> Result<Vec<T>, E> {
        struct Visitor;

        impl<
            T: Deserialize<D, E>,
            D: Deserializer<E>,
            E,
        > self::Visitor<D, Vec<T>, E> for Visitor {
            fn visit_seq<
                V: SeqVisitor<D, E>,
            >(&mut self, d: &mut D, mut visitor: V) -> Result<Vec<T>, E> {
                let (len, _) = visitor.size_hint(d);
                let mut values = Vec::with_capacity(len);

                loop {
                    match try!(visitor.visit(d)) {
                        Some(value) => {
                            values.push(value);
                        }
                        None => {
                            break;
                        }
                    }
                }

                Ok(values)
            }
        }

        d.visit(&mut Visitor)
    }
}

impl<
    T0: Deserialize<D, E>,
    T1: Deserialize<D, E>,
    D: Deserializer<E>,
    E,
> Deserialize<D, E> for (T0, T1) {
    fn deserialize(d: &mut D) -> Result<(T0, T1), E> {
        struct Visitor;

        impl<
            T0: Deserialize<D, E>,
            T1: Deserialize<D, E>,
            D: Deserializer<E>,
            E,
        > self::Visitor<D, (T0, T1), E> for Visitor {
            fn visit_seq<
                V: SeqVisitor<D, E>,
            >(&mut self, d: &mut D, mut visitor: V) -> Result<(T0, T1), E> {
                let mut state = 0u;
                let mut t0 = None;
                let mut t1 = None;

                loop {
                    match state {
                        0 => {
                            state += 1;
                            match try!(visitor.visit(d)) {
                                Some(value) => {
                                    t0 = Some(value);
                                }
                                None => {
                                    return Err(d.end_of_stream_error());
                                }
                            }
                        }
                        1 => {
                            state += 1;
                            match try!(visitor.visit(d)) {
                                Some(value) => {
                                    t1 = Some(value);
                                }
                                None => {
                                    return Err(d.end_of_stream_error());
                                }
                            }
                        }
                        _ => {
                            try!(visitor.end(d));

                            return Ok((t0.unwrap(), t1.unwrap()));
                        }
                    }
                }
            }
        }

        d.visit(&mut Visitor)
    }
}

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

impl<
    K: Deserialize<D, E> + Eq + Hash,
    V: Deserialize<D, E>,
    D: Deserializer<E>,
    E,
> Deserialize<D, E> for HashMap<K, V> {
    fn deserialize(d: &mut D) -> Result<HashMap<K, V>, E> {
        struct Visitor;

        impl<
            K: Deserialize<D, E> + Eq + Hash,
            V: Deserialize<D, E>,
            D: Deserializer<E>,
            E,
        > self::Visitor<D, HashMap<K, V>, E> for Visitor {
            fn visit_map<
                Visitor: MapVisitor<D, E>,
            >(&mut self, d: &mut D, mut visitor: Visitor) -> Result<HashMap<K, V>, E> {
                let (len, _) = visitor.size_hint(d);
                let mut values = HashMap::with_capacity(len);

                loop {
                    match try!(visitor.visit(d)) {
                        Some((key, value)) => {
                            values.insert(key, value);
                        }
                        None => {
                            break;
                        }
                    }
                }

                Ok(values)
            }
        }

        d.visit(&mut Visitor)
    }
}

impl<
    K: Deserialize<D, E> + Eq + Ord,
    V: Deserialize<D, E>,
    D: Deserializer<E>,
    E,
> Deserialize<D, E> for TreeMap<K, V> {
    fn deserialize(d: &mut D) -> Result<TreeMap<K, V>, E> {
        struct Visitor;

        impl<
            K: Deserialize<D, E> + Eq + Ord,
            V: Deserialize<D, E>,
            D: Deserializer<E>,
            E,
        > self::Visitor<D, TreeMap<K, V>, E> for Visitor {
            fn visit_map<
                Visitor: MapVisitor<D, E>,
            >(&mut self, d: &mut D, mut visitor: Visitor) -> Result<TreeMap<K, V>, E> {
                let mut values = TreeMap::new();

                loop {
                    match try!(visitor.visit(d)) {
                        Some((key, value)) => {
                            values.insert(key, value);
                        }
                        None => {
                            break;
                        }
                    }
                }

                Ok(values)
            }
        }

        d.visit(&mut Visitor)
    }
}

/*
trait Deserialize<S, E> {
    fn deserialize(state: &mut S) -> Result<Self, E>;
}

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

trait Deserializer<S, E> {
    fn visit<R>(&mut self, state: &mut S) -> Result<(), E>;

    fn syntax_error(&mut self) -> E;
}

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

/*
trait DeserializerState<E> {
    fn syntax_error(&mut self) -> E;

    fn visit<
        V: VisitorState<T, Self, E>,
        T: Deserialize<Self, E>,
    >(&mut self, visitor: &mut V) -> Result<T, E>;
}

trait Visitor<R, E> {
    fn visit<S>(&mut self, state: &mut S) -> Result<(), E>;

    fn size_hint(&self) -> (uint, Option<uint>);
}
*/

trait VisitorState<
    D: Deserializer<Self, E>,
    //R,
    E,
> {
    /*
    fn visit_null(&mut self) -> R;
    */

    fn visit_int(&mut self, d: &mut D, v: int) -> Result<int, E> {
        Err(d.syntax_error())
        //self.visit_i64(d, v as i64)
    }

    /*
    fn visit_i8(&mut self, d: &mut D, v: i8) -> Result<(), E> {
        self.visit_i64(d, v as i64)
    }

    fn visit_i16(&mut self, d: &mut D, v: i16) -> Result<(), E> {
        self.visit_i64(d, v as i64)
    }

    fn visit_i32(&mut self, d: &mut D, v: i32) -> Result<(), E> {
        self.visit_i64(d, v as i64)
    }

    fn visit_i64(&mut self, d: &mut D, v: i64) -> Result<(), E> {
        Err(d.syntax_error())
    }

    fn visit_uint(&mut self, d: &mut D, v: int) -> Result<(), E> {
        self.visit_u64(d, v as u64)
    }

    fn visit_u8(&mut self, d: &mut D, v: u8) -> Result<(), E> {
        self.visit_u64(d, v as u64)
    }

    fn visit_u16(&mut self, d: &mut D, v: u16) -> Result<(), E> {
        self.visit_u64(d, v as u64)
    }

    fn visit_u32(&mut self, d: &mut D, v: u32) -> Result<(), E> {
        self.visit_u64(d, v as u64)
    }

    fn visit_u64(&mut self, d: &mut D, _v: u64) -> Result<(), E> {
        Err(d.syntax_error())
    }

    fn visit_string(&mut self, d: &mut D, _v: String) -> Result<(), E> {
        Err(d.syntax_error())
    }
    */

    fn visit_seq<
        R,
        V: SeqVisitor<D, E>,
    >(&mut self, d: &mut D, _visitor: V) -> Result<(), E> {
        Err(d.syntax_error())
    }

    /*
    /*
    #[inline]
    fn visit_named_seq<
        Elt: Deserialize<D, E>,
        V: SeqVisitor<D, Result<Elt, E>>,
    >(&mut self, d: &mut D, _name: &str, visitor: V) -> Result<T, E> {
        self.visit_seq(d, visitor)
    }
    */

    fn visit_seq_elt<
        T: Deserialize<Self, R>,
    >(&mut self, first: bool, value: T) -> R;
    */

    /*
    #[inline]
    fn visit_map<
        K: Deserialize<D, E>,
        V: Deserialize<D, E>,
        V: Visitor<D, Result<T, E>>,
    >(&mut self, d: &mut D, _visitor: V) -> Result<T, E> {
        Err(d.syntax_error())
    }

    #[inline]
    fn visit_named_map<
        V: Visitor<D, E>,
    >(&mut self, d: &mut D, _name: &str, visitor: V) -> Result<T, E> {
        self.visit_map(d, visitor)
    }

    fn visit_map_elt<
        K: Deserialize<D, E>,
        V: Deserialize<D, E>,
    >(&mut self, first: bool, value: T) -> Result<(K, V), E>;
    */
}

trait SeqVisitor<D, E> {
    fn next<
        T: Deserialize<D, E>,
    >(&mut self, d: &mut D) -> Option<Result<T, E>>;

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        (0, None)
    }
}

/*
trait MapVisitor<D, E> {
    fn next<
        K: Deserialize<D, E>,
        V: Deserialize<D, E>,
    >(&mut self, d: &mut D) -> Option<Result<(K, V), E>>;

    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        (0, None)
    }
}
*/

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

/*
macro_rules! impl_deserialize {
    ($ty:ty, $method:ident) => {
        impl<
            S: Deserializer<E>,
            E,
        > Deserialize<S, E> for $ty {
            #[inline]
            fn deserialize(state: &mut S) -> Result<$ty, E> {
                struct Visitor;

                impl<
                    D: Deserializer<$ty, E>,
                    E,
                > VisitorState<S, $ty, E> for Visitor {
                    fn visit_int(&mut self, _d: &mut D, v: int) -> Result<$ty, E> {
                        Ok(v)
                    }
                }

                state.visit(&mut Visitor)

                d.$method(token)
            }
        }
    }
}
*/

impl<
    D: Deserializer<int, E>,
    E,
> Deserialize<D, E> for int {
    fn deserialize(state: &mut D) -> Result<int, E> {
        struct Visitor;

        impl<
            D: Deserializer<Visitor, E>,
            E,
        > VisitorState<D, E> for Visitor {
            fn visit_int(&mut self, _state: &mut D, v: int) -> Result<int, E> {
                Ok(v)
            }
        }

        state.visit(&mut Visitor)
    }
}

/*
impl<
    S: Deserializer<String, E>,
    E,
> Deserialize<S, E> for String {
    fn deserialize(state: &mut S) -> Result<String, E> {
        struct Visitor;

        impl<
            D: Deserializer<String, E>,
            E,
        > VisitorState<S, String, E> for Visitor {
            fn visit_string(&mut self, _d: &mut D, v: String) -> Result<String, E> {
                Ok(v)
            }
        }

        state.visit(&mut Visitor)
    }
}
*/

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

/*
impl<
    T: Deserialize<D, E>,
    D: Deserializer<Vec<T>, E>,
    E,
> Deserialize<D, E> for Vec<T> {
    fn deserialize(d: &mut D) -> Result<Vec<T>, E> {
        struct Visitor;

        impl<
            D: Deserializer<Visitor, E>,
            T: Deserialize<D, E>,
            E,
        > VisitorState<D, E> for Visitor {
            fn visit_seq<
                V: SeqVisitor<D, E>,
            >(&mut self, state: &mut D, mut visitor: V) -> Result<Vec<T>, E> {
                let (len, _) = visitor.size_hint();
                let mut values = Vec::with_capacity(len);

                loop {
                    match visitor.next(state) {
                        Some(Ok(value)) => {
                            values.push(value);
                        }
                        Some(Err(err)) => {
                            return Err(err);
                        }
                        None => {
                            break;
                        }
                    }
                }

                Ok(values)
            }
        }

        d.visit(&mut Visitor)
    }
}
*/

/*
///////////////////////////////////////////////////////////////////////////////

impl<
    D: DeserializerState<E>,
    E
> Deserialize<D, E> for () {
    fn deserialize(d: &mut D) -> Result<(), E> {
        struct Visitor;

        impl<
            D: DeserializerState<E>,
            E,
        > ::VisitorState<(), D, E> for Visitor {
            fn visit_null(&mut self, _d: &mut D) -> Result<(), E> {
                Ok(())
            }
        }

        d.visit(&mut Visitor)
    }
}

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

impl<
    T0: Deserialize<D, E>,
    T1: Deserialize<D, E>,
    D: DeserializerState<E>,
    E
> Deserialize<D, E> for (T0, T1) {
    fn deserialize(d: &mut D) -> Result<(T0, T1), E> {
        struct Visitor;

        impl<
            T0: Deserialize<D, E>,
            T1: Deserialize<D, E>,
            D: DeserializerState<E>,
            E
        > ::VisitorState<(T0, T1), D, E> for Visitor {
            fn visit_seq<
                Visitor: ::SeqVisitor<D, E>,
            >(&mut self, d: &mut D, mut visitor: Visitor) -> Result<(T0, T1), E> {
                let mut state = 0u;
                let mut t0 = None;
                let mut t1 = None;

                loop {
                    match state {
                        0 => {
                            t0 = match visitor.next(d) {
                                Some(Ok(v)) => Some(v),
                                Some(Err(err)) => { return Err(err); }
                                None => { return Err(d.syntax_error()); }
                            };
                            state += 1;
                        }
                        1 => {
                            t1 = match visitor.next(d) {
                                Some(Ok(v)) => Some(v),
                                Some(Err(err)) => { return Err(err); }
                                None => { return Err(d.syntax_error()); }
                            };
                            state += 1;
                        }
                        _ => {
                            match visitor.next(d) {
                                Some(Ok(())) => { return Err(d.syntax_error()); }
                                Some(Err(err)) => { return Err(err); }
                                None => { break; }
                            }
                        }
                    }
                }

                match (t0, t1) {
                    (Some(t0), Some(t1)) => Ok((t0, t1)),
                    _ => Err(d.syntax_error()),
                }
            }
        }

        d.visit(&mut Visitor)
    }
}

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

impl<
    K: Deserialize<D, E> + Eq + Hash,
    V: Deserialize<D, E>,
    D: DeserializerState<E>,
    E
> Deserialize<D, E> for HashMap<K, V> {
    fn deserialize(d: &mut D) -> Result<HashMap<K, V>, E> {
        struct Visitor;

        impl<
            K: Deserialize<D, E> + Eq + Hash,
            V: Deserialize<D, E>,
            D: DeserializerState<E>,
            E,
        > ::VisitorState<HashMap<K, V>, D, E> for Visitor {
            fn visit_map<
                Visitor: ::MapVisitor<D, E>,
            >(&mut self, d: &mut D, mut visitor: Visitor) -> Result<HashMap<K, V>, E> {
                let (len, _) = visitor.size_hint();
                let mut values = HashMap::with_capacity(len);

                loop {
                    let kv: Option<Result<(K, V), E>> = visitor.next(d);
                    match kv {
                        Some(Ok((key, value))) => {
                            values.insert(key, value);
                        }
                        Some(Err(err)) => {
                            return Err(err);
                        }
                        None => {
                            break;
                        }
                    }
                }

                Ok(values)
            }
        }

        d.visit(&mut Visitor)
    }
}

impl<
    K: Deserialize<D, E> + Eq + Ord,
    V: Deserialize<D, E>,
    D: DeserializerState<E>,
    E
> Deserialize<D, E> for TreeMap<K, V> {
    fn deserialize(d: &mut D) -> Result<TreeMap<K, V>, E> {
        struct Visitor;

        impl<
            K: Deserialize<D, E> + Eq + Ord,
            V: Deserialize<D, E>,
            D: DeserializerState<E>,
            E,
        > ::VisitorState<TreeMap<K, V>, D, E> for Visitor {
            fn visit_map<
                Visitor: ::MapVisitor<D, E>,
            >(&mut self, d: &mut D, mut visitor: Visitor) -> Result<TreeMap<K, V>, E> {
                let mut values = TreeMap::new();

                loop {
                    let kv: Option<Result<(K, V), E>> = visitor.next(d);
                    match kv {
                        Some(Ok((key, value))) => {
                            values.insert(key, value);
                        }
                        Some(Err(err)) => {
                            return Err(err);
                        }
                        None => {
                            break;
                        }
                    }
                }

                Ok(values)
            }
        }

        d.visit(&mut Visitor)
    }
}

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

*/
*/
<commit_msg>Remove commented out code<commit_after>use std::collections::{HashMap, TreeMap};
use std::hash::Hash;

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

pub trait Deserialize<D, E> {
    fn deserialize(d: &mut D) -> Result<Self, E>;
}

pub trait Deserializer<E> {
    fn visit<
        R,
        V: Visitor<Self, R, E>,
    >(&mut self, visitor: &mut V) -> Result<R, E>;

    fn visit_option<
        R,
        V: Visitor<Self, R, E>,
    >(&mut self, visitor: &mut V) -> Result<R, E> {
        self.visit(visitor)
    }

    fn syntax_error(&mut self) -> E;

    fn end_of_stream_error(&mut self) -> E;
}

pub trait Visitor<D: Deserializer<E>, R, E> {
    fn visit_null(&mut self, d: &mut D) -> Result<R, E> {
        Err(d.syntax_error())
    }

    fn visit_int(&mut self, d: &mut D, _v: int) -> Result<R, E> {
        Err(d.syntax_error())
    }

    fn visit_str(&mut self, d: &mut D, v: &str) -> Result<R, E> {
        self.visit_string(d, v.to_string())
    }

    fn visit_string(&mut self, d: &mut D, _v: String) -> Result<R, E> {
        Err(d.syntax_error())
    }

    fn visit_option<
        V: OptionVisitor<D, E>,
    >(&mut self, d: &mut D, _visitor: V) -> Result<R, E> {
        Err(d.syntax_error())
    }

    fn visit_seq<
        V: SeqVisitor<D, E>,
    >(&mut self, d: &mut D, _visitor: V) -> Result<R, E> {
        Err(d.syntax_error())
    }

    fn visit_map<
        V: MapVisitor<D, E>,
    >(&mut self, d: &mut D, _visitor: V) -> Result<R, E> {
        Err(d.syntax_error())
    }
}

pub trait OptionVisitor<D, E> {
    fn visit<
        T: Deserialize<D, E>,
    >(&mut self, d: &mut D) -> Result<Option<T>, E>;
}

pub trait SeqVisitor<D, E> {
    fn visit<
        T: Deserialize<D, E>,
    >(&mut self, d: &mut D) -> Result<Option<T>, E>;

    fn end(&mut self, d: &mut D) -> Result<(), E>;

    #[inline]
    fn size_hint(&self, _d: &mut D) -> (uint, Option<uint>) {
        (0, None)
    }
}

pub trait MapVisitor<D, E> {
    fn visit<
        K: Deserialize<D, E>,
        V: Deserialize<D, E>,
    >(&mut self, d: &mut D) -> Result<Option<(K, V)>, E>;

    fn end(&mut self, d: &mut D) -> Result<(), E>;

    #[inline]
    fn size_hint(&self, _d: &mut D) -> (uint, Option<uint>) {
        (0, None)
    }
}

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

impl<
    D: Deserializer<E>,
    E,
> Deserialize<D, E> for () {
    fn deserialize(d: &mut D) -> Result<(), E> {
        struct Visitor;

        impl<D: Deserializer<E>, E> self::Visitor<D, (), E> for Visitor {
            fn visit_null(&mut self, _d: &mut D) -> Result<(), E> {
                Ok(())
            }
        }

        d.visit(&mut Visitor)
    }
}

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

impl<
    D: Deserializer<E>,
    E,
> Deserialize<D, E> for int {
    fn deserialize(d: &mut D) -> Result<int, E> {
        struct Visitor;

        impl<D: Deserializer<E>, E> self::Visitor<D, int, E> for Visitor {
            fn visit_int(&mut self, _d: &mut D, v: int) -> Result<int, E> {
                Ok(v)
            }
        }

        d.visit(&mut Visitor)
    }
}

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

impl<
    D: Deserializer<E>,
    E,
> Deserialize<D, E> for String {
    fn deserialize(d: &mut D) -> Result<String, E> {
        struct Visitor;

        impl<D: Deserializer<E>, E> self::Visitor<D, String, E> for Visitor {
            fn visit_string(&mut self, _d: &mut D, v: String) -> Result<String, E> {
                Ok(v)
            }
        }

        d.visit(&mut Visitor)
    }
}

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

impl<
    T: Deserialize<D, E>,
    D: Deserializer<E>,
    E,
> Deserialize<D, E> for Option<T> {
    fn deserialize(d: &mut D) -> Result<Option<T>, E> {
        struct Visitor;

        impl<
            T: Deserialize<D, E>,
            D: Deserializer<E>,
            E,
        > self::Visitor<D, Option<T>, E> for Visitor {
            fn visit_option<
                V: OptionVisitor<D, E>,
            >(&mut self, d: &mut D, mut visitor: V) -> Result<Option<T>, E> {
                visitor.visit(d)
            }
        }

        d.visit_option(&mut Visitor)
    }
}

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

impl<
    T: Deserialize<D, E>,
    D: Deserializer<E>,
    E,
> Deserialize<D, E> for Vec<T> {
    fn deserialize(d: &mut D) -> Result<Vec<T>, E> {
        struct Visitor;

        impl<
            T: Deserialize<D, E>,
            D: Deserializer<E>,
            E,
        > self::Visitor<D, Vec<T>, E> for Visitor {
            fn visit_seq<
                V: SeqVisitor<D, E>,
            >(&mut self, d: &mut D, mut visitor: V) -> Result<Vec<T>, E> {
                let (len, _) = visitor.size_hint(d);
                let mut values = Vec::with_capacity(len);

                loop {
                    match try!(visitor.visit(d)) {
                        Some(value) => {
                            values.push(value);
                        }
                        None => {
                            break;
                        }
                    }
                }

                Ok(values)
            }
        }

        d.visit(&mut Visitor)
    }
}

impl<
    T0: Deserialize<D, E>,
    T1: Deserialize<D, E>,
    D: Deserializer<E>,
    E,
> Deserialize<D, E> for (T0, T1) {
    fn deserialize(d: &mut D) -> Result<(T0, T1), E> {
        struct Visitor;

        impl<
            T0: Deserialize<D, E>,
            T1: Deserialize<D, E>,
            D: Deserializer<E>,
            E,
        > self::Visitor<D, (T0, T1), E> for Visitor {
            fn visit_seq<
                V: SeqVisitor<D, E>,
            >(&mut self, d: &mut D, mut visitor: V) -> Result<(T0, T1), E> {
                let mut state = 0u;
                let mut t0 = None;
                let mut t1 = None;

                loop {
                    match state {
                        0 => {
                            state += 1;
                            match try!(visitor.visit(d)) {
                                Some(value) => {
                                    t0 = Some(value);
                                }
                                None => {
                                    return Err(d.end_of_stream_error());
                                }
                            }
                        }
                        1 => {
                            state += 1;
                            match try!(visitor.visit(d)) {
                                Some(value) => {
                                    t1 = Some(value);
                                }
                                None => {
                                    return Err(d.end_of_stream_error());
                                }
                            }
                        }
                        _ => {
                            try!(visitor.end(d));

                            return Ok((t0.unwrap(), t1.unwrap()));
                        }
                    }
                }
            }
        }

        d.visit(&mut Visitor)
    }
}

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

impl<
    K: Deserialize<D, E> + Eq + Hash,
    V: Deserialize<D, E>,
    D: Deserializer<E>,
    E,
> Deserialize<D, E> for HashMap<K, V> {
    fn deserialize(d: &mut D) -> Result<HashMap<K, V>, E> {
        struct Visitor;

        impl<
            K: Deserialize<D, E> + Eq + Hash,
            V: Deserialize<D, E>,
            D: Deserializer<E>,
            E,
        > self::Visitor<D, HashMap<K, V>, E> for Visitor {
            fn visit_map<
                Visitor: MapVisitor<D, E>,
            >(&mut self, d: &mut D, mut visitor: Visitor) -> Result<HashMap<K, V>, E> {
                let (len, _) = visitor.size_hint(d);
                let mut values = HashMap::with_capacity(len);

                loop {
                    match try!(visitor.visit(d)) {
                        Some((key, value)) => {
                            values.insert(key, value);
                        }
                        None => {
                            break;
                        }
                    }
                }

                Ok(values)
            }
        }

        d.visit(&mut Visitor)
    }
}

impl<
    K: Deserialize<D, E> + Eq + Ord,
    V: Deserialize<D, E>,
    D: Deserializer<E>,
    E,
> Deserialize<D, E> for TreeMap<K, V> {
    fn deserialize(d: &mut D) -> Result<TreeMap<K, V>, E> {
        struct Visitor;

        impl<
            K: Deserialize<D, E> + Eq + Ord,
            V: Deserialize<D, E>,
            D: Deserializer<E>,
            E,
        > self::Visitor<D, TreeMap<K, V>, E> for Visitor {
            fn visit_map<
                Visitor: MapVisitor<D, E>,
            >(&mut self, d: &mut D, mut visitor: Visitor) -> Result<TreeMap<K, V>, E> {
                let mut values = TreeMap::new();

                loop {
                    match try!(visitor.visit(d)) {
                        Some((key, value)) => {
                            values.insert(key, value);
                        }
                        None => {
                            break;
                        }
                    }
                }

                Ok(values)
            }
        }

        d.visit(&mut Visitor)
    }
}
<|endoftext|>


<commit_before>//! Helper module to compute a CRC32 checksum

use std::io;
use std::io::prelude::*;

use crc32fast::Hasher;

/// Reader that validates the CRC32 when it reaches the EOF.
pub struct Crc32Reader<R>
{
    inner: R,
    hasher: Hasher,
    check: u32,
}

impl<R> Crc32Reader<R>
{
    /// Get a new Crc32Reader which check the inner reader against checksum.
    pub fn new(inner: R, checksum: u32) -> Crc32Reader<R>
    {
        Crc32Reader
        {
            inner: inner,
            hasher: Hasher::new(),
            check: checksum,
        }
    }

    fn check_matches(&self) -> bool
    {
        self.check == self.hasher.clone().finalize()
    }

    pub fn into_inner(self) -> R {
        self.inner
    }
}

impl<R: Read> Read for Crc32Reader<R>
{
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>
    {
        let count = match self.inner.read(buf)
        {
            Ok(0) if !buf.is_empty() && !self.check_matches() => { return Err(io::Error::new(io::ErrorKind::Other, "Invalid checksum")) },
            Ok(n) => n,
            Err(e) => return Err(e),
        };
        self.hasher.update(&buf[0..count]);
        Ok(count)
    }
}

#[cfg(test)]
mod test
{
    use super::*;
    use std::io::Read;
    use std::io::Cursor;

    #[test]
    fn test_empty_reader()
    {
        let data: &[u8] = b"";
        let mut buf = [0; 1];

        let mut reader = Crc32Reader::new(data, 0);
        assert_eq!(reader.read(&mut buf).unwrap(), 0);

        let mut reader = Crc32Reader::new(data, 1);
        assert!(reader.read(&mut buf).unwrap_err().to_string().contains("Invalid checksum"));
    }

    #[test]
    fn test_byte_by_byte()
    {
        let data: &[u8] = b"1234";
        let mut buf = [0; 1];

        let mut reader = Crc32Reader::new(data, 0x9be3e0a3);
        assert_eq!(reader.read(&mut buf).unwrap(), 1);
        assert_eq!(reader.read(&mut buf).unwrap(), 1);
        assert_eq!(reader.read(&mut buf).unwrap(), 1);
        assert_eq!(reader.read(&mut buf).unwrap(), 1);
        assert_eq!(reader.read(&mut buf).unwrap(), 0);
        // Can keep reading 0 bytes after the end
        assert_eq!(reader.read(&mut buf).unwrap(), 0);
    }

    #[test]
    fn test_zero_read()
    {
        let data: &[u8] = b"1234";
        let mut buf = [0; 5];

        let mut reader = Crc32Reader::new(data, 0x9be3e0a3);
        assert_eq!(reader.read(&mut buf[..0]).unwrap(), 0);
        assert_eq!(reader.read(&mut buf).unwrap(), 4);
    }
}
<commit_msg>Remove unused import<commit_after>//! Helper module to compute a CRC32 checksum

use std::io;
use std::io::prelude::*;

use crc32fast::Hasher;

/// Reader that validates the CRC32 when it reaches the EOF.
pub struct Crc32Reader<R>
{
    inner: R,
    hasher: Hasher,
    check: u32,
}

impl<R> Crc32Reader<R>
{
    /// Get a new Crc32Reader which check the inner reader against checksum.
    pub fn new(inner: R, checksum: u32) -> Crc32Reader<R>
    {
        Crc32Reader
        {
            inner: inner,
            hasher: Hasher::new(),
            check: checksum,
        }
    }

    fn check_matches(&self) -> bool
    {
        self.check == self.hasher.clone().finalize()
    }

    pub fn into_inner(self) -> R {
        self.inner
    }
}

impl<R: Read> Read for Crc32Reader<R>
{
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>
    {
        let count = match self.inner.read(buf)
        {
            Ok(0) if !buf.is_empty() && !self.check_matches() => { return Err(io::Error::new(io::ErrorKind::Other, "Invalid checksum")) },
            Ok(n) => n,
            Err(e) => return Err(e),
        };
        self.hasher.update(&buf[0..count]);
        Ok(count)
    }
}

#[cfg(test)]
mod test
{
    use super::*;
    use std::io::Read;

    #[test]
    fn test_empty_reader()
    {
        let data: &[u8] = b"";
        let mut buf = [0; 1];

        let mut reader = Crc32Reader::new(data, 0);
        assert_eq!(reader.read(&mut buf).unwrap(), 0);

        let mut reader = Crc32Reader::new(data, 1);
        assert!(reader.read(&mut buf).unwrap_err().to_string().contains("Invalid checksum"));
    }

    #[test]
    fn test_byte_by_byte()
    {
        let data: &[u8] = b"1234";
        let mut buf = [0; 1];

        let mut reader = Crc32Reader::new(data, 0x9be3e0a3);
        assert_eq!(reader.read(&mut buf).unwrap(), 1);
        assert_eq!(reader.read(&mut buf).unwrap(), 1);
        assert_eq!(reader.read(&mut buf).unwrap(), 1);
        assert_eq!(reader.read(&mut buf).unwrap(), 1);
        assert_eq!(reader.read(&mut buf).unwrap(), 0);
        // Can keep reading 0 bytes after the end
        assert_eq!(reader.read(&mut buf).unwrap(), 0);
    }

    #[test]
    fn test_zero_read()
    {
        let data: &[u8] = b"1234";
        let mut buf = [0; 5];

        let mut reader = Crc32Reader::new(data, 0x9be3e0a3);
        assert_eq!(reader.read(&mut buf[..0]).unwrap(), 0);
        assert_eq!(reader.read(&mut buf).unwrap(), 4);
    }
}
<|endoftext|>


<commit_before>use std::fmt;
use ansi_term::Colour;

#[derive(Debug)]
pub enum ErrorLevel {
    Info,
    Warning,
    Error,
}

#[derive(Debug)]
pub struct Error(pub (ErrorLevel, String));

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let colour_level = match (self.0).0 {
            ErrorLevel::Info => Colour::Yellow.paint("Info"),

            // ansi_term does not have orange for some reason
            ErrorLevel::Warning => Colour::RGB(255, 210, 0).paint("Warning"),
            ErrorLevel::Error => Colour::Red.paint("Error"),
        };

        write!(f, "[{}] {}", colour_level, (self.0).1)
    }
}

#[derive(Debug)]
pub struct ErrorStack(pub Vec<Error>);

impl fmt::Display for ErrorStack {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for error in &self.0 {
            // TODO: Remove this unwrap
            write!(f, "{}", error).unwrap();
        }

        write!(f, "")
    }
}
<commit_msg>Add error enum<commit_after>use std::fmt;
use ansi_term::Colour;

#[derive(Debug, Copy, Clone, PartialEq)]
pub enum ErrorKind {
    UndefinedVar = 0,
}

#[derive(Debug, PartialEq)]
pub enum ErrorLevel {
    Info,
    Warning,
    Error,
}

#[derive(Debug, PartialEq)]
pub struct Error(pub ErrorKind, pub ErrorLevel, pub &'static str);

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let colour_level = match self.1 {
            ErrorLevel::Info => Colour::Yellow.paint("Info"),

            // ansi_term does not have orange for some reason
            ErrorLevel::Warning => Colour::RGB(255, 210, 0).paint("Warning"),
            ErrorLevel::Error => Colour::Red.paint("Error"),
        };

        // TODO: Remove clone
        write!(f, "[{}] (E{}) {}", colour_level, self.0 as i32, self.2)
    }
}

#[derive(Debug)]
pub struct ErrorStack(pub Vec<Error>);

impl fmt::Display for ErrorStack {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for error in &self.0 {
            // TODO: Remove this unwrap
            write!(f, "{}", error).unwrap();
        }

        write!(f, "")
    }
}
<|endoftext|>


<commit_before>use crate::deserialize::*;
use crate::errors::*;

use std::path::Path;

/// sort <link> and <joint> to avoid the [issue](https://github.com/RReverser/serde-xml-rs/issues/5)
fn sort_link_joint(string: &str) -> Result<String> {
    let e: xml::Element = string.parse().map_err(UrdfError::new)?;
    let mut links = Vec::new();
    let mut joints = Vec::new();
    let mut materials = Vec::new();
    for c in &e.children {
        if let xml::Xml::ElementNode(ref xml_elm) = *c {
            if xml_elm.name == "link" {
                links.push(xml::Xml::ElementNode(xml_elm.clone()));
            } else if xml_elm.name == "joint" {
                joints.push(xml::Xml::ElementNode(xml_elm.clone()));
            } else if xml_elm.name == "material" {
                materials.push(xml::Xml::ElementNode(xml_elm.clone()));
            }
        };
    }
    let mut new_elm = e;
    links.extend(joints);
    links.extend(materials);
    new_elm.children = links;
    Ok(format!("{}", new_elm))
}

/// Read urdf file and create Robot instance
///
/// # Examples
///
/// ```
/// let urdf_robo = urdf_rs::read_file("sample.urdf").unwrap();
/// let links = urdf_robo.links;
/// println!("{:?}", links[0].visual[0].origin.xyz);
/// ```
pub fn read_file<P: AsRef<Path>>(path: P) -> Result<Robot> {
    read_from_string(&std::fs::read_to_string(path)?)
}

/// Read from string instead of file.
///
///
/// # Examples
///
/// ```
/// let s = r##"
///     <robot name="robo">
///         <link name="shoulder1">
///             <inertial>
///                 <origin xyz="0 0 0.5" rpy="0 0 0"/>
///                 <mass value="1"/>
///                 <inertia ixx="100"  ixy="0"  ixz="0" iyy="100" iyz="0" izz="100" />
///             </inertial>
///             <visual>
///                 <origin xyz="0.1 0.2 0.3" rpy="-0.1 -0.2  -0.3" />
///                 <geometry>
///                     <box size="1.0 2.0 3.0" />
///                 </geometry>
///                 <material name="Cyan">
///                     <color rgba="0 1.0 1.0 1.0"/>
///                 </material>
///             </visual>
///             <collision>
///                 <origin xyz="0 0 0" rpy="0 0 0"/>
///                 <geometry>
///                     <cylinder radius="1" length="0.5"/>
///                 </geometry>
///             </collision>
///         </link>
///         <link name="elbow1" />
///         <link name="wrist1" />
///         <joint name="shoulder_pitch" type="revolute">
///             <origin xyz="0.0 0.0 0.1" />
///             <parent link="shoulder1" />
///             <child link="elbow1" />
///             <axis xyz="0 1 -1" />
///             <limit lower="-1" upper="1.0" effort="0" velocity="1.0"/>
///         </joint>
///         <joint name="shoulder_pitch" type="revolute">
///             <origin xyz="0.0 0.0 0.0" />
///             <parent link="elbow1" />
///             <child link="wrist1" />
///             <axis xyz="0 1 0" />
///             <limit lower="-2" upper="1.0" effort="0" velocity="1.0"/>
///         </joint>
///     </robot>
///    "##;
/// let urdf_robo = urdf_rs::read_from_string(s).unwrap();
/// println!("{:?}", urdf_robo.links[0].visual[0].origin.xyz);
/// ```

pub fn read_from_string(string: &str) -> Result<Robot> {
    let sorted_string = sort_link_joint(string)?;
    serde_xml_rs::from_str(&sorted_string).map_err(UrdfError::new)
}

#[test]
fn it_works() {
    let s = r##"
        <robot name="robo">
            <material name="blue">
              <color rgba="0.0 0.0 0.8 1.0"/>
            </material>

            <link name="shoulder1">
                <inertial>
                    <origin xyz="0 0 0.5" rpy="0 0 0"/>
                    <mass value="1"/>
                    <inertia ixx="100"  ixy="0"  ixz="0" iyy="100" iyz="0" izz="100" />
                </inertial>
                <visual>
                    <origin xyz="0.1 0.2 0.3" rpy="-0.1 -0.2  -0.3" />
                    <geometry>
                        <box size="1.0 2.0 3.0" />
                    </geometry>
                    <material name="Cyan">
                        <color rgba="0 1.0 1.0 1.0"/>
                    </material>
                </visual>
                <visual>
                    <origin xyz="0.1 0.2 0.3" rpy="-0.1 -0.2  -0.3" />
                    <geometry>
                        <mesh filename="aa.dae" />
                    </geometry>
                </visual>
                <visual>
                    <origin xyz="0.1 0.2 0.3" rpy="-0.1 -0.2  -0.3" />
                    <geometry>
                        <mesh filename="bbb.dae" scale="2.0 3.0 4.0" />
                    </geometry>
                </visual>
                <collision>
                    <origin xyz="0 0 0" rpy="0 0 0"/>
                    <geometry>
                        <cylinder radius="1" length="0.5"/>
                    </geometry>
                </collision>
            </link>
            <joint name="shoulder_pitch" type="revolute">
                <origin xyz="0.0 0.0 0.1" />
                <parent link="shoulder1" />
                <child link="elbow1" />
                <axis xyz="0 1 -1" />
                <limit lower="-1" upper="1.0" effort="0" velocity="1.0"/>
            </joint>
            <link name="elbow1" />
            <link name="wrist1" />
            <joint name="shoulder_pitch" type="revolute">
                <origin xyz="0.0 0.0 0.0" />
                <parent link="elbow1" />
                <child link="wrist1" />
                <axis xyz="0 1 0" />
                <limit lower="-2" upper="1.0" effort="0" velocity="1.0"/>
            </joint>
        </robot>
    "##;
    let robo = read_from_string(s).unwrap();

    assert_eq!(robo.name, "robo");
    assert_eq!(robo.links.len(), 3);
    assert_eq!(robo.joints.len(), 2);
    assert_eq!(robo.links[0].visual.len(), 3);
    let xyz = robo.links[0].visual[0].origin.xyz;
    assert_eq!(xyz[0], 0.1);
    assert_eq!(xyz[1], 0.2);
    assert_eq!(xyz[2], 0.3);
    let rpy = robo.links[0].visual[0].origin.rpy;
    assert_eq!(rpy[0], -0.1);
    assert_eq!(rpy[1], -0.2);
    assert_eq!(rpy[2], -0.3);

    match robo.links[0].visual[0].geometry {
        Geometry::Box { size } => {
            assert_eq!(size[0], 1.0f64);
            assert_eq!(size[1], 2.0f64);
            assert_eq!(size[2], 3.0f64);
        }
        _ => panic!("geometry error"),
    }
    match robo.links[0].visual[1].geometry {
        Geometry::Mesh { ref filename, scale } => {
            assert_eq!(filename, "aa.dae");
            assert_eq!(scale, None);
        }
        _ => panic!("geometry error"),
    }
    match robo.links[0].visual[2].geometry {
        Geometry::Mesh { ref filename, scale } => {
            assert_eq!(filename, "bbb.dae");
            assert!(scale.is_some());
        }
        _ => panic!("geometry error"),
    }

    assert_eq!(robo.materials.len(), 1);

    assert_eq!(robo.joints[0].name, "shoulder_pitch");
    let xyz = robo.joints[0].axis.xyz;
    assert_eq!(xyz[0], 0.0f64);
    assert_eq!(xyz[1], 1.0f64);
    assert_eq!(xyz[2], -1.0f64);
    let xyz = robo.joints[0].axis.xyz;
    //"0 1 -1"
    assert_eq!(xyz[0], 0.0);
    assert_eq!(xyz[1], 1.0);
    assert_eq!(xyz[2], -1.0);
}
<commit_msg>Apply cargo fmt<commit_after>use crate::deserialize::*;
use crate::errors::*;

use std::path::Path;

/// sort <link> and <joint> to avoid the [issue](https://github.com/RReverser/serde-xml-rs/issues/5)
fn sort_link_joint(string: &str) -> Result<String> {
    let e: xml::Element = string.parse().map_err(UrdfError::new)?;
    let mut links = Vec::new();
    let mut joints = Vec::new();
    let mut materials = Vec::new();
    for c in &e.children {
        if let xml::Xml::ElementNode(ref xml_elm) = *c {
            if xml_elm.name == "link" {
                links.push(xml::Xml::ElementNode(xml_elm.clone()));
            } else if xml_elm.name == "joint" {
                joints.push(xml::Xml::ElementNode(xml_elm.clone()));
            } else if xml_elm.name == "material" {
                materials.push(xml::Xml::ElementNode(xml_elm.clone()));
            }
        };
    }
    let mut new_elm = e;
    links.extend(joints);
    links.extend(materials);
    new_elm.children = links;
    Ok(format!("{}", new_elm))
}

/// Read urdf file and create Robot instance
///
/// # Examples
///
/// ```
/// let urdf_robo = urdf_rs::read_file("sample.urdf").unwrap();
/// let links = urdf_robo.links;
/// println!("{:?}", links[0].visual[0].origin.xyz);
/// ```
pub fn read_file<P: AsRef<Path>>(path: P) -> Result<Robot> {
    read_from_string(&std::fs::read_to_string(path)?)
}

/// Read from string instead of file.
///
///
/// # Examples
///
/// ```
/// let s = r##"
///     <robot name="robo">
///         <link name="shoulder1">
///             <inertial>
///                 <origin xyz="0 0 0.5" rpy="0 0 0"/>
///                 <mass value="1"/>
///                 <inertia ixx="100"  ixy="0"  ixz="0" iyy="100" iyz="0" izz="100" />
///             </inertial>
///             <visual>
///                 <origin xyz="0.1 0.2 0.3" rpy="-0.1 -0.2  -0.3" />
///                 <geometry>
///                     <box size="1.0 2.0 3.0" />
///                 </geometry>
///                 <material name="Cyan">
///                     <color rgba="0 1.0 1.0 1.0"/>
///                 </material>
///             </visual>
///             <collision>
///                 <origin xyz="0 0 0" rpy="0 0 0"/>
///                 <geometry>
///                     <cylinder radius="1" length="0.5"/>
///                 </geometry>
///             </collision>
///         </link>
///         <link name="elbow1" />
///         <link name="wrist1" />
///         <joint name="shoulder_pitch" type="revolute">
///             <origin xyz="0.0 0.0 0.1" />
///             <parent link="shoulder1" />
///             <child link="elbow1" />
///             <axis xyz="0 1 -1" />
///             <limit lower="-1" upper="1.0" effort="0" velocity="1.0"/>
///         </joint>
///         <joint name="shoulder_pitch" type="revolute">
///             <origin xyz="0.0 0.0 0.0" />
///             <parent link="elbow1" />
///             <child link="wrist1" />
///             <axis xyz="0 1 0" />
///             <limit lower="-2" upper="1.0" effort="0" velocity="1.0"/>
///         </joint>
///     </robot>
///    "##;
/// let urdf_robo = urdf_rs::read_from_string(s).unwrap();
/// println!("{:?}", urdf_robo.links[0].visual[0].origin.xyz);
/// ```

pub fn read_from_string(string: &str) -> Result<Robot> {
    let sorted_string = sort_link_joint(string)?;
    serde_xml_rs::from_str(&sorted_string).map_err(UrdfError::new)
}

#[test]
fn it_works() {
    let s = r##"
        <robot name="robo">
            <material name="blue">
              <color rgba="0.0 0.0 0.8 1.0"/>
            </material>

            <link name="shoulder1">
                <inertial>
                    <origin xyz="0 0 0.5" rpy="0 0 0"/>
                    <mass value="1"/>
                    <inertia ixx="100"  ixy="0"  ixz="0" iyy="100" iyz="0" izz="100" />
                </inertial>
                <visual>
                    <origin xyz="0.1 0.2 0.3" rpy="-0.1 -0.2  -0.3" />
                    <geometry>
                        <box size="1.0 2.0 3.0" />
                    </geometry>
                    <material name="Cyan">
                        <color rgba="0 1.0 1.0 1.0"/>
                    </material>
                </visual>
                <visual>
                    <origin xyz="0.1 0.2 0.3" rpy="-0.1 -0.2  -0.3" />
                    <geometry>
                        <mesh filename="aa.dae" />
                    </geometry>
                </visual>
                <visual>
                    <origin xyz="0.1 0.2 0.3" rpy="-0.1 -0.2  -0.3" />
                    <geometry>
                        <mesh filename="bbb.dae" scale="2.0 3.0 4.0" />
                    </geometry>
                </visual>
                <collision>
                    <origin xyz="0 0 0" rpy="0 0 0"/>
                    <geometry>
                        <cylinder radius="1" length="0.5"/>
                    </geometry>
                </collision>
            </link>
            <joint name="shoulder_pitch" type="revolute">
                <origin xyz="0.0 0.0 0.1" />
                <parent link="shoulder1" />
                <child link="elbow1" />
                <axis xyz="0 1 -1" />
                <limit lower="-1" upper="1.0" effort="0" velocity="1.0"/>
            </joint>
            <link name="elbow1" />
            <link name="wrist1" />
            <joint name="shoulder_pitch" type="revolute">
                <origin xyz="0.0 0.0 0.0" />
                <parent link="elbow1" />
                <child link="wrist1" />
                <axis xyz="0 1 0" />
                <limit lower="-2" upper="1.0" effort="0" velocity="1.0"/>
            </joint>
        </robot>
    "##;
    let robo = read_from_string(s).unwrap();

    assert_eq!(robo.name, "robo");
    assert_eq!(robo.links.len(), 3);
    assert_eq!(robo.joints.len(), 2);
    assert_eq!(robo.links[0].visual.len(), 3);
    let xyz = robo.links[0].visual[0].origin.xyz;
    assert_eq!(xyz[0], 0.1);
    assert_eq!(xyz[1], 0.2);
    assert_eq!(xyz[2], 0.3);
    let rpy = robo.links[0].visual[0].origin.rpy;
    assert_eq!(rpy[0], -0.1);
    assert_eq!(rpy[1], -0.2);
    assert_eq!(rpy[2], -0.3);

    match robo.links[0].visual[0].geometry {
        Geometry::Box { size } => {
            assert_eq!(size[0], 1.0f64);
            assert_eq!(size[1], 2.0f64);
            assert_eq!(size[2], 3.0f64);
        }
        _ => panic!("geometry error"),
    }
    match robo.links[0].visual[1].geometry {
        Geometry::Mesh {
            ref filename,
            scale,
        } => {
            assert_eq!(filename, "aa.dae");
            assert_eq!(scale, None);
        }
        _ => panic!("geometry error"),
    }
    match robo.links[0].visual[2].geometry {
        Geometry::Mesh {
            ref filename,
            scale,
        } => {
            assert_eq!(filename, "bbb.dae");
            assert!(scale.is_some());
        }
        _ => panic!("geometry error"),
    }

    assert_eq!(robo.materials.len(), 1);

    assert_eq!(robo.joints[0].name, "shoulder_pitch");
    let xyz = robo.joints[0].axis.xyz;
    assert_eq!(xyz[0], 0.0f64);
    assert_eq!(xyz[1], 1.0f64);
    assert_eq!(xyz[2], -1.0f64);
    let xyz = robo.joints[0].axis.xyz;
    //"0 1 -1"
    assert_eq!(xyz[0], 0.0);
    assert_eq!(xyz[1], 1.0);
    assert_eq!(xyz[2], -1.0);
}
<|endoftext|>


<commit_before>use std::collections::{HashSet, RingBuf, Deque};
use std::collections::hashmap::SetItems;

trait Graph<T> {
    /// Insert a new node, returning its index
    fn add_node(&mut self, val: T) -> NodeIndex;

    /// Insert a new edge, returning an error if one of the indices is invalid
    /// and a result otherwise
    fn add_edge(&mut self, i: NodeIndex, j: NodeIndex) -> GraphResult<bool>;

    fn adj<'a>(&'a self, i: NodeIndex) -> NodeIndices<'a>;

    /// Return the number of nodes in the graph
    fn num_nodes(&self) -> uint;

    /// Do a breadth-first search of the graph, returning the resulting breadth-
    /// first tree.
    fn bfs(&self) -> Digraph<NodeIndex> {
        let mut tree = Digraph::new();

        if self.num_nodes() == 0 {
            return tree;
        }

        let mut visited = HashSet::new();
        let mut discovered = RingBuf::new();

        discovered.push_back((0, None));
        loop {
            match discovered.pop_front() {
                None => break,
                Some((ind, parent)) => {
                    tree.add_node(ind);
                    if parent.is_some() {
                        tree.add_edge(parent.unwrap(), ind);
                    }
                    visited.insert(ind);

                    for i in self.adj(ind) {
                        if !visited.contains(i) {
                            discovered.push_back((*i, Some(ind)));
                        }
                    }
                }
            }
        }
        return tree;
    }
}

struct GraphError {
    error_type: GraphErrorType,
}

impl GraphError {
    fn invalid_index(ind: NodeIndex) -> GraphError {
        GraphError { error_type: InvalidNodeIndex(ind) }
    }
}

type GraphResult<T> = Result<T, GraphError>;

enum GraphErrorType {
    InvalidNodeIndex(NodeIndex),
}

type NodeIndex = uint;

#[deriving(Show)]
struct Node<T> {
    data: T,
    index: NodeIndex,
}

/// Undirected graph. Allows loops.
#[deriving(Show)]
struct UnGraph<T> {
    nodes: Vec<Node<T>>,
    adj: Vec<HashSet<NodeIndex>>,
    num_nodes: uint,
}

/// Directed graph. Allows loops.
#[deriving(Show)]
struct Digraph<T> {
    nodes: Vec<Node<T>>,
    in_adj: Vec<HashSet<NodeIndex>>,
    out_adj: Vec<HashSet<NodeIndex>>,
    num_nodes: uint,
}

impl<T> UnGraph<T> {
    pub fn new() -> UnGraph<T> {
        UnGraph { nodes: vec!(), adj: vec!(), num_nodes: 0 }
    }

    pub fn degree(&mut self, ind: NodeIndex) -> Result<uint, GraphError> {
        if ind >= self.num_nodes {
            Err(GraphError::invalid_index(ind))
        } else {
            Ok(self.adj[ind].len())
        }
    }
}

impl<T> Graph<T> for UnGraph<T> {
    fn add_node(&mut self, val: T) -> NodeIndex {
        let ind = self.num_nodes;
        self.nodes.push(Node { data: val, index: ind });
        self.adj.push(HashSet::new());
        self.num_nodes += 1;
        ind
    }

    fn add_edge(&mut self, i: NodeIndex, j: NodeIndex) -> GraphResult<bool> {
        if i >= self.num_nodes {
            Err(GraphError::invalid_index(i))
        } else if j >= self.num_nodes {
            Err(GraphError::invalid_index(j))
        } else {
            if self.adj[i].contains(&j) {
                Ok(false)
            } else {
                self.adj.get_mut(i).insert(j);
                self.adj.get_mut(j).insert(i);
                Ok(true)
            }
        }
    }

    fn adj<'a>(&'a self, i: NodeIndex) -> NodeIndices<'a> {
        NodeIndices::from_set(&self.adj[i])
    }

    fn num_nodes(&self) -> uint {
        self.num_nodes
    }
}

impl<T> Digraph<T> {
    pub fn new() -> Digraph<T> {
        Digraph { nodes: vec!(), in_adj: vec!(), out_adj: vec!(), num_nodes: 0 }
    }

    pub fn out_degree(&mut self, ind: NodeIndex) -> Result<uint, GraphError> {
        if ind >= self.num_nodes {
            Err(GraphError::invalid_index(ind))
        } else {
            Ok(self.out_adj[ind].len())
        }
    }

    pub fn in_degree(&mut self, ind: NodeIndex) -> Result<uint, GraphError> {
        if ind >= self.num_nodes {
            Err(GraphError::invalid_index(ind))
        } else {
            Ok(self.in_adj[ind].len())
        }
    }
}

impl<T> Graph<T> for Digraph<T> {
    fn add_node(&mut self, val: T) -> NodeIndex {
        let ind = self.num_nodes;
        self.nodes.push(Node { data: val, index: ind });
        self.in_adj.push(HashSet::new());
        self.out_adj.push(HashSet::new());
        self.num_nodes += 1;
        ind
    }

    fn add_edge(&mut self, i: NodeIndex, j: NodeIndex) -> GraphResult<bool> {
        if i >= self.num_nodes {
            Err(GraphError::invalid_index(i))
        } else if j >= self.num_nodes {
            Err(GraphError::invalid_index(j))
        } else {
            if self.out_adj[i].contains(&j) {
                Ok(false)
            } else {
                self.out_adj.get_mut(i).insert(j);
                self.in_adj.get_mut(j).insert(i);
                Ok(true)
            }
        }
    }

    fn adj<'a>(&'a self, i: NodeIndex) -> NodeIndices<'a> {
        NodeIndices::from_set(&self.out_adj[i])
    }

    fn num_nodes(&self) -> uint {
        self.num_nodes
    }
}

struct NodeIndices<'a> {
    indices: SetItems<'a, NodeIndex>,
}

impl<'a> Iterator<&'a NodeIndex> for NodeIndices<'a> {
    fn next(&mut self) -> Option<&'a NodeIndex> {
        self.indices.next()
    }
}

impl<'a> NodeIndices<'a> {
    fn from_set(set: &'a HashSet<NodeIndex>) -> NodeIndices<'a> {
        NodeIndices { indices: set.iter() }
    }
}
<commit_msg>implement dfs<commit_after>use std::collections::{HashSet, RingBuf, Deque};
use std::collections::hashmap::SetItems;

trait Graph<T> {
    /// Insert a new node, returning its index
    fn add_node(&mut self, val: T) -> NodeIndex;

    /// Insert a new edge, returning an error if one of the indices is invalid
    /// and a result otherwise
    fn add_edge(&mut self, i: NodeIndex, j: NodeIndex) -> GraphResult<bool>;

    fn adj<'a>(&'a self, i: NodeIndex) -> NodeIndices<'a>;

    /// Return the number of nodes in the graph
    fn num_nodes(&self) -> uint;

    /// Do a breadth-first search of the graph, returning the resulting breadth-
    /// first tree.
    fn bfs(&self) -> Digraph<NodeIndex> {
        let mut tree = Digraph::new();

        if self.num_nodes() == 0 {
            return tree;
        }

        let mut visited = HashSet::new();
        let mut discovered = RingBuf::new();

        discovered.push_back((0, None));
        loop {
            match discovered.pop_front() {
                None => break,
                Some((ind, parent)) => {
                    tree.add_node(ind);
                    if parent.is_some() {
                        tree.add_edge(parent.unwrap(), ind);
                    }
                    visited.insert(ind);

                    for i in self.adj(ind) {
                        if !visited.contains(i) {
                            discovered.push_back((*i, Some(ind)));
                        }
                    }
                }
            }
        }
        return tree;
    }

    fn dfs(&self) -> Digraph<NodeIndex> {
        let mut tree = Digraph::new();

        if self.num_nodes() == 0 {
            return tree;
        }

        let mut visited = HashSet::new();
        let mut discovered = vec!();

        discovered.push((0, None));
        loop {
            match discovered.pop() {
                None => break,
                Some((ind, parent)) => {
                    tree.add_node(ind);
                    if parent.is_some() {
                        tree.add_edge(parent.unwrap(), ind);
                    }
                    visited.insert(ind);

                    for i in self.adj(ind) {
                        if !visited.contains(i) {
                            discovered.push((*i, Some(ind)));
                        }
                    }
                }
            }
        }
        return tree;

    }
}

struct GraphError {
    error_type: GraphErrorType,
}

impl GraphError {
    fn invalid_index(ind: NodeIndex) -> GraphError {
        GraphError { error_type: InvalidNodeIndex(ind) }
    }
}

type GraphResult<T> = Result<T, GraphError>;

enum GraphErrorType {
    InvalidNodeIndex(NodeIndex),
}

type NodeIndex = uint;

#[deriving(Show)]
struct Node<T> {
    data: T,
    index: NodeIndex,
}

/// Undirected graph. Allows loops.
#[deriving(Show)]
struct UnGraph<T> {
    nodes: Vec<Node<T>>,
    adj: Vec<HashSet<NodeIndex>>,
    num_nodes: uint,
}

/// Directed graph. Allows loops.
#[deriving(Show)]
struct Digraph<T> {
    nodes: Vec<Node<T>>,
    in_adj: Vec<HashSet<NodeIndex>>,
    out_adj: Vec<HashSet<NodeIndex>>,
    num_nodes: uint,
}

impl<T> UnGraph<T> {
    pub fn new() -> UnGraph<T> {
        UnGraph { nodes: vec!(), adj: vec!(), num_nodes: 0 }
    }

    pub fn degree(&mut self, ind: NodeIndex) -> Result<uint, GraphError> {
        if ind >= self.num_nodes {
            Err(GraphError::invalid_index(ind))
        } else {
            Ok(self.adj[ind].len())
        }
    }
}

impl<T> Graph<T> for UnGraph<T> {
    fn add_node(&mut self, val: T) -> NodeIndex {
        let ind = self.num_nodes;
        self.nodes.push(Node { data: val, index: ind });
        self.adj.push(HashSet::new());
        self.num_nodes += 1;
        ind
    }

    fn add_edge(&mut self, i: NodeIndex, j: NodeIndex) -> GraphResult<bool> {
        if i >= self.num_nodes {
            Err(GraphError::invalid_index(i))
        } else if j >= self.num_nodes {
            Err(GraphError::invalid_index(j))
        } else {
            if self.adj[i].contains(&j) {
                Ok(false)
            } else {
                self.adj.get_mut(i).insert(j);
                self.adj.get_mut(j).insert(i);
                Ok(true)
            }
        }
    }

    fn adj<'a>(&'a self, i: NodeIndex) -> NodeIndices<'a> {
        NodeIndices::from_set(&self.adj[i])
    }

    fn num_nodes(&self) -> uint {
        self.num_nodes
    }
}

impl<T> Digraph<T> {
    pub fn new() -> Digraph<T> {
        Digraph { nodes: vec!(), in_adj: vec!(), out_adj: vec!(), num_nodes: 0 }
    }

    pub fn out_degree(&mut self, ind: NodeIndex) -> Result<uint, GraphError> {
        if ind >= self.num_nodes {
            Err(GraphError::invalid_index(ind))
        } else {
            Ok(self.out_adj[ind].len())
        }
    }

    pub fn in_degree(&mut self, ind: NodeIndex) -> Result<uint, GraphError> {
        if ind >= self.num_nodes {
            Err(GraphError::invalid_index(ind))
        } else {
            Ok(self.in_adj[ind].len())
        }
    }
}

impl<T> Graph<T> for Digraph<T> {
    fn add_node(&mut self, val: T) -> NodeIndex {
        let ind = self.num_nodes;
        self.nodes.push(Node { data: val, index: ind });
        self.in_adj.push(HashSet::new());
        self.out_adj.push(HashSet::new());
        self.num_nodes += 1;
        ind
    }

    fn add_edge(&mut self, i: NodeIndex, j: NodeIndex) -> GraphResult<bool> {
        if i >= self.num_nodes {
            Err(GraphError::invalid_index(i))
        } else if j >= self.num_nodes {
            Err(GraphError::invalid_index(j))
        } else {
            if self.out_adj[i].contains(&j) {
                Ok(false)
            } else {
                self.out_adj.get_mut(i).insert(j);
                self.in_adj.get_mut(j).insert(i);
                Ok(true)
            }
        }
    }

    fn adj<'a>(&'a self, i: NodeIndex) -> NodeIndices<'a> {
        NodeIndices::from_set(&self.out_adj[i])
    }

    fn num_nodes(&self) -> uint {
        self.num_nodes
    }
}

struct NodeIndices<'a> {
    indices: SetItems<'a, NodeIndex>,
}

impl<'a> Iterator<&'a NodeIndex> for NodeIndices<'a> {
    fn next(&mut self) -> Option<&'a NodeIndex> {
        self.indices.next()
    }
}

impl<'a> NodeIndices<'a> {
    fn from_set(set: &'a HashSet<NodeIndex>) -> NodeIndices<'a> {
        NodeIndices { indices: set.iter() }
    }
}
<|endoftext|>


<commit_before>// This is a part of rust-encoding.
// Copyright (c) 2013, Kang Seonghoon.
// See README.md and LICENSE.txt for details.

//! An interface for retrieving an encoding (or a set of encodings) from a string label.

use std::ascii::StrAsciiExt;
use all;
use types;

/// Returns an encoding from given label, defined in the WHATWG Encoding standard, if any.
/// Implements "get an encoding" algorithm: http://encoding.spec.whatwg.org/#decode
pub fn encoding_from_whatwg_label(label: &str) -> Option<&'static types::Encoding> {
    match label.trim_chars(& &[' ', '\n', '\r', '\t', '\x0C']).to_ascii_lower().as_slice() {
        "unicode-1-1-utf-8" |
        "utf-8" |
        "utf8" =>
            Some(all::UTF_8 as &'static types::Encoding),
        "866" |
        "cp866" |
        "csibm866" |
        "ibm866" =>
            Some(all::IBM866 as &'static types::Encoding),
        "csisolatin2" |
        "iso-8859-2" |
        "iso-ir-101" |
        "iso8859-2" |
        "iso88592" |
        "iso_8859-2" |
        "iso_8859-2:1987" |
        "l2" |
        "latin2" =>
            Some(all::ISO_8859_2 as &'static types::Encoding),
        "csisolatin3" |
        "iso-8859-3" |
        "iso-ir-109" |
        "iso8859-3" |
        "iso88593" |
        "iso_8859-3" |
        "iso_8859-3:1988" |
        "l3" |
        "latin3" =>
            Some(all::ISO_8859_3 as &'static types::Encoding),
        "csisolatin4" |
        "iso-8859-4" |
        "iso-ir-110" |
        "iso8859-4" |
        "iso88594" |
        "iso_8859-4" |
        "iso_8859-4:1988" |
        "l4" |
        "latin4" =>
            Some(all::ISO_8859_4 as &'static types::Encoding),
        "csisolatincyrillic" |
        "cyrillic" |
        "iso-8859-5" |
        "iso-ir-144" |
        "iso8859-5" |
        "iso88595" |
        "iso_8859-5" |
        "iso_8859-5:1988" =>
            Some(all::ISO_8859_5 as &'static types::Encoding),
        "arabic" |
        "asmo-708" |
        "csiso88596e" |
        "csiso88596i" |
        "csisolatinarabic" |
        "ecma-114" |
        "iso-8859-6" |
        "iso-8859-6-e" |
        "iso-8859-6-i" |
        "iso-ir-127" |
        "iso8859-6" |
        "iso88596" |
        "iso_8859-6" |
        "iso_8859-6:1987" =>
            Some(all::ISO_8859_6 as &'static types::Encoding),
        "csisolatingreek" |
        "ecma-118" |
        "elot_928" |
        "greek" |
        "greek8" |
        "iso-8859-7" |
        "iso-ir-126" |
        "iso8859-7" |
        "iso88597" |
        "iso_8859-7" |
        "iso_8859-7:1987" |
        "sun_eu_greek" =>
            Some(all::ISO_8859_7 as &'static types::Encoding),
        "csiso88598e" |
        "csisolatinhebrew" |
        "hebrew" |
        "iso-8859-8" |
        "iso-8859-8-e" |
        "iso-ir-138" |
        "iso8859-8" |
        "iso88598" |
        "iso_8859-8" |
        "iso_8859-8:1988" |
        "visual" =>
            Some(all::ISO_8859_8 as &'static types::Encoding),
        "csiso88598i" |
        "iso-8859-8-i" |
        "logical" =>
            Some(all::whatwg::ISO_8859_8_I as &'static types::Encoding),
        "csisolatin6" |
        "iso-8859-10" |
        "iso-ir-157" |
        "iso8859-10" |
        "iso885910" |
        "l6" |
        "latin6" =>
            Some(all::ISO_8859_10 as &'static types::Encoding),
        "iso-8859-13" |
        "iso8859-13" |
        "iso885913" =>
            Some(all::ISO_8859_13 as &'static types::Encoding),
        "iso-8859-14" |
        "iso8859-14" |
        "iso885914" =>
            Some(all::ISO_8859_14 as &'static types::Encoding),
        "csisolatin9" |
        "iso-8859-15" |
        "iso8859-15" |
        "iso885915" |
        "iso_8859-15" |
        "l9" =>
            Some(all::ISO_8859_15 as &'static types::Encoding),
        "iso-8859-16" =>
            Some(all::ISO_8859_16 as &'static types::Encoding),
        "cskoi8r" |
        "koi" |
        "koi8" |
        "koi8-r" |
        "koi8_r" =>
            Some(all::KOI8_R as &'static types::Encoding),
        "koi8-u" =>
            Some(all::KOI8_U as &'static types::Encoding),
        "csmacintosh" |
        "mac" |
        "macintosh" |
        "x-mac-roman" =>
            Some(all::MACINTOSH as &'static types::Encoding),
        "dos-874" |
        "iso-8859-11" |
        "iso8859-11" |
        "iso885911" |
        "tis-620" |
        "windows-874" =>
            Some(all::WINDOWS_874 as &'static types::Encoding),
        "cp1250" |
        "windows-1250" |
        "x-cp1250" =>
            Some(all::WINDOWS_1250 as &'static types::Encoding),
        "cp1251" |
        "windows-1251" |
        "x-cp1251" =>
            Some(all::WINDOWS_1251 as &'static types::Encoding),
        "ansi_x3.4-1968" |
        "ascii" |
        "cp1252" |
        "cp819" |
        "csisolatin1" |
        "ibm819" |
        "iso-8859-1" |
        "iso-ir-100" |
        "iso8859-1" |
        "iso88591" |
        "iso_8859-1" |
        "iso_8859-1:1987" |
        "l1" |
        "latin1" |
        "us-ascii" |
        "windows-1252" |
        "x-cp1252" =>
            Some(all::WINDOWS_1252 as &'static types::Encoding),
        "cp1253" |
        "windows-1253" |
        "x-cp1253" =>
            Some(all::WINDOWS_1253 as &'static types::Encoding),
        "cp1254" |
        "csisolatin5" |
        "iso-8859-9" |
        "iso-ir-148" |
        "iso8859-9" |
        "iso88599" |
        "iso_8859-9" |
        "iso_8859-9:1989" |
        "l5" |
        "latin5" |
        "windows-1254" |
        "x-cp1254" =>
            Some(all::WINDOWS_1254 as &'static types::Encoding),
        "cp1255" |
        "windows-1255" |
        "x-cp1255" =>
            Some(all::WINDOWS_1255 as &'static types::Encoding),
        "cp1256" |
        "windows-1256" |
        "x-cp1256" =>
            Some(all::WINDOWS_1256 as &'static types::Encoding),
        "cp1257" |
        "windows-1257" |
        "x-cp1257" =>
            Some(all::WINDOWS_1257 as &'static types::Encoding),
        "cp1258" |
        "windows-1258" |
        "x-cp1258" =>
            Some(all::WINDOWS_1258 as &'static types::Encoding),
        "x-mac-cyrillic" |
        "x-mac-ukrainian" =>
            Some(all::X_MAC_CYRILLIC as &'static types::Encoding),
        "chinese" |
        "csgb2312" |
        "csiso58gb231280" |
        "gb2312" |
        "gb_2312" |
        "gb_2312-80" |
        "gbk" |
        "iso-ir-58" |
        "x-gbk" =>
            Some(all::GBK18030 as &'static types::Encoding),
        "gb18030" =>
            Some(all::GB18030 as &'static types::Encoding),
        /*
        "hz-gb-2312" =>
            Some(all::HZ_GB_2312 as &'static types::Encoding),
        */
        "big5" |
        "big5-hkscs" |
        "cn-big5" |
        "csbig5" |
        "x-x-big5" =>
            Some(all::BIG5_2003 as &'static types::Encoding),
        "cseucpkdfmtjapanese" |
        "euc-jp" |
        "x-euc-jp" =>
            Some(all::EUC_JP as &'static types::Encoding),
        /*
        "csiso2022jp" |
        "iso-2022-jp" =>
            Some(all::ISO_2022_JP as &'static types::Encoding),
        */
        "csshiftjis" |
        "ms_kanji" |
        "shift-jis" |
        "shift_jis" |
        "sjis" |
        "windows-31j" |
        "x-sjis" =>
            Some(all::WINDOWS_31J as &'static types::Encoding),
        "cseuckr" |
        "csksc56011987" |
        "euc-kr" |
        "iso-ir-149" |
        "korean" |
        "ks_c_5601-1987" |
        "ks_c_5601-1989" |
        "ksc5601" |
        "ksc_5601" |
        "windows-949" =>
            Some(all::WINDOWS_949 as &'static types::Encoding),
        "csiso2022kr" |
        "iso-2022-kr" |
        "iso-2022-cn" |
        "iso-2022-cn-ext" =>
            Some(all::whatwg::REPLACEMENT as &'static types::Encoding),
        "utf-16be" =>
            Some(all::UTF_16BE as &'static types::Encoding),
        "utf-16" |
        "utf-16le" =>
            Some(all::UTF_16LE as &'static types::Encoding),
        "x-user-defined" =>
            Some(all::whatwg::X_USER_DEFINED as &'static types::Encoding),
        _ => None
    }
}

#[cfg(test)]
mod tests {
    extern mod extra;
    use super::encoding_from_whatwg_label;

    #[test]
    fn test_encoding_from_whatwg_label() {
        assert!(encoding_from_whatwg_label("utf-8").is_some())
        assert!(encoding_from_whatwg_label("UTF-8").is_some())
        assert!(encoding_from_whatwg_label("\t\n\x0C\r utf-8\t\n\x0C\r ").is_some())
        assert!(encoding_from_whatwg_label("\u00A0utf-8").is_none(),
                "Non-ASCII whitespace should not be trimmed")
        assert!(encoding_from_whatwg_label("greek").is_some())
        assert!(encoding_from_whatwg_label("gree\u212A").is_none(),
                "Case-insensitive matching should be ASCII only. Kelvin sign does not match k.")
    }

    #[bench]
    fn bench_encoding_from_whatwg_label(harness: &mut extra::test::BenchHarness) {
        do harness.iter() {
            encoding_from_whatwg_label("iso-8859-bazinga");
        }
    }
}

<commit_msg>added label::encoding_from_windows_code_page. (duh!)<commit_after>// This is a part of rust-encoding.
// Copyright (c) 2013, Kang Seonghoon.
// See README.md and LICENSE.txt for details.

//! An interface for retrieving an encoding (or a set of encodings) from a string/numeric label.

use std::ascii::StrAsciiExt;
use all;
use types;

/// Returns an encoding from given label, defined in the WHATWG Encoding standard, if any.
/// Implements "get an encoding" algorithm: http://encoding.spec.whatwg.org/#decode
pub fn encoding_from_whatwg_label(label: &str) -> Option<&'static types::Encoding> {
    match label.trim_chars(& &[' ', '\n', '\r', '\t', '\x0C']).to_ascii_lower().as_slice() {
        "unicode-1-1-utf-8" |
        "utf-8" |
        "utf8" =>
            Some(all::UTF_8 as &'static types::Encoding),
        "866" |
        "cp866" |
        "csibm866" |
        "ibm866" =>
            Some(all::IBM866 as &'static types::Encoding),
        "csisolatin2" |
        "iso-8859-2" |
        "iso-ir-101" |
        "iso8859-2" |
        "iso88592" |
        "iso_8859-2" |
        "iso_8859-2:1987" |
        "l2" |
        "latin2" =>
            Some(all::ISO_8859_2 as &'static types::Encoding),
        "csisolatin3" |
        "iso-8859-3" |
        "iso-ir-109" |
        "iso8859-3" |
        "iso88593" |
        "iso_8859-3" |
        "iso_8859-3:1988" |
        "l3" |
        "latin3" =>
            Some(all::ISO_8859_3 as &'static types::Encoding),
        "csisolatin4" |
        "iso-8859-4" |
        "iso-ir-110" |
        "iso8859-4" |
        "iso88594" |
        "iso_8859-4" |
        "iso_8859-4:1988" |
        "l4" |
        "latin4" =>
            Some(all::ISO_8859_4 as &'static types::Encoding),
        "csisolatincyrillic" |
        "cyrillic" |
        "iso-8859-5" |
        "iso-ir-144" |
        "iso8859-5" |
        "iso88595" |
        "iso_8859-5" |
        "iso_8859-5:1988" =>
            Some(all::ISO_8859_5 as &'static types::Encoding),
        "arabic" |
        "asmo-708" |
        "csiso88596e" |
        "csiso88596i" |
        "csisolatinarabic" |
        "ecma-114" |
        "iso-8859-6" |
        "iso-8859-6-e" |
        "iso-8859-6-i" |
        "iso-ir-127" |
        "iso8859-6" |
        "iso88596" |
        "iso_8859-6" |
        "iso_8859-6:1987" =>
            Some(all::ISO_8859_6 as &'static types::Encoding),
        "csisolatingreek" |
        "ecma-118" |
        "elot_928" |
        "greek" |
        "greek8" |
        "iso-8859-7" |
        "iso-ir-126" |
        "iso8859-7" |
        "iso88597" |
        "iso_8859-7" |
        "iso_8859-7:1987" |
        "sun_eu_greek" =>
            Some(all::ISO_8859_7 as &'static types::Encoding),
        "csiso88598e" |
        "csisolatinhebrew" |
        "hebrew" |
        "iso-8859-8" |
        "iso-8859-8-e" |
        "iso-ir-138" |
        "iso8859-8" |
        "iso88598" |
        "iso_8859-8" |
        "iso_8859-8:1988" |
        "visual" =>
            Some(all::ISO_8859_8 as &'static types::Encoding),
        "csiso88598i" |
        "iso-8859-8-i" |
        "logical" =>
            Some(all::whatwg::ISO_8859_8_I as &'static types::Encoding),
        "csisolatin6" |
        "iso-8859-10" |
        "iso-ir-157" |
        "iso8859-10" |
        "iso885910" |
        "l6" |
        "latin6" =>
            Some(all::ISO_8859_10 as &'static types::Encoding),
        "iso-8859-13" |
        "iso8859-13" |
        "iso885913" =>
            Some(all::ISO_8859_13 as &'static types::Encoding),
        "iso-8859-14" |
        "iso8859-14" |
        "iso885914" =>
            Some(all::ISO_8859_14 as &'static types::Encoding),
        "csisolatin9" |
        "iso-8859-15" |
        "iso8859-15" |
        "iso885915" |
        "iso_8859-15" |
        "l9" =>
            Some(all::ISO_8859_15 as &'static types::Encoding),
        "iso-8859-16" =>
            Some(all::ISO_8859_16 as &'static types::Encoding),
        "cskoi8r" |
        "koi" |
        "koi8" |
        "koi8-r" |
        "koi8_r" =>
            Some(all::KOI8_R as &'static types::Encoding),
        "koi8-u" =>
            Some(all::KOI8_U as &'static types::Encoding),
        "csmacintosh" |
        "mac" |
        "macintosh" |
        "x-mac-roman" =>
            Some(all::MACINTOSH as &'static types::Encoding),
        "dos-874" |
        "iso-8859-11" |
        "iso8859-11" |
        "iso885911" |
        "tis-620" |
        "windows-874" =>
            Some(all::WINDOWS_874 as &'static types::Encoding),
        "cp1250" |
        "windows-1250" |
        "x-cp1250" =>
            Some(all::WINDOWS_1250 as &'static types::Encoding),
        "cp1251" |
        "windows-1251" |
        "x-cp1251" =>
            Some(all::WINDOWS_1251 as &'static types::Encoding),
        "ansi_x3.4-1968" |
        "ascii" |
        "cp1252" |
        "cp819" |
        "csisolatin1" |
        "ibm819" |
        "iso-8859-1" |
        "iso-ir-100" |
        "iso8859-1" |
        "iso88591" |
        "iso_8859-1" |
        "iso_8859-1:1987" |
        "l1" |
        "latin1" |
        "us-ascii" |
        "windows-1252" |
        "x-cp1252" =>
            Some(all::WINDOWS_1252 as &'static types::Encoding),
        "cp1253" |
        "windows-1253" |
        "x-cp1253" =>
            Some(all::WINDOWS_1253 as &'static types::Encoding),
        "cp1254" |
        "csisolatin5" |
        "iso-8859-9" |
        "iso-ir-148" |
        "iso8859-9" |
        "iso88599" |
        "iso_8859-9" |
        "iso_8859-9:1989" |
        "l5" |
        "latin5" |
        "windows-1254" |
        "x-cp1254" =>
            Some(all::WINDOWS_1254 as &'static types::Encoding),
        "cp1255" |
        "windows-1255" |
        "x-cp1255" =>
            Some(all::WINDOWS_1255 as &'static types::Encoding),
        "cp1256" |
        "windows-1256" |
        "x-cp1256" =>
            Some(all::WINDOWS_1256 as &'static types::Encoding),
        "cp1257" |
        "windows-1257" |
        "x-cp1257" =>
            Some(all::WINDOWS_1257 as &'static types::Encoding),
        "cp1258" |
        "windows-1258" |
        "x-cp1258" =>
            Some(all::WINDOWS_1258 as &'static types::Encoding),
        "x-mac-cyrillic" |
        "x-mac-ukrainian" =>
            Some(all::X_MAC_CYRILLIC as &'static types::Encoding),
        "chinese" |
        "csgb2312" |
        "csiso58gb231280" |
        "gb2312" |
        "gb_2312" |
        "gb_2312-80" |
        "gbk" |
        "iso-ir-58" |
        "x-gbk" =>
            Some(all::GBK18030 as &'static types::Encoding),
        "gb18030" =>
            Some(all::GB18030 as &'static types::Encoding),
        /*
        "hz-gb-2312" =>
            Some(all::HZ_GB_2312 as &'static types::Encoding),
        */
        "big5" |
        "big5-hkscs" |
        "cn-big5" |
        "csbig5" |
        "x-x-big5" =>
            Some(all::BIG5_2003 as &'static types::Encoding),
        "cseucpkdfmtjapanese" |
        "euc-jp" |
        "x-euc-jp" =>
            Some(all::EUC_JP as &'static types::Encoding),
        /*
        "csiso2022jp" |
        "iso-2022-jp" =>
            Some(all::ISO_2022_JP as &'static types::Encoding),
        */
        "csshiftjis" |
        "ms_kanji" |
        "shift-jis" |
        "shift_jis" |
        "sjis" |
        "windows-31j" |
        "x-sjis" =>
            Some(all::WINDOWS_31J as &'static types::Encoding),
        "cseuckr" |
        "csksc56011987" |
        "euc-kr" |
        "iso-ir-149" |
        "korean" |
        "ks_c_5601-1987" |
        "ks_c_5601-1989" |
        "ksc5601" |
        "ksc_5601" |
        "windows-949" =>
            Some(all::WINDOWS_949 as &'static types::Encoding),
        "csiso2022kr" |
        "iso-2022-kr" |
        "iso-2022-cn" |
        "iso-2022-cn-ext" =>
            Some(all::whatwg::REPLACEMENT as &'static types::Encoding),
        "utf-16be" =>
            Some(all::UTF_16BE as &'static types::Encoding),
        "utf-16" |
        "utf-16le" =>
            Some(all::UTF_16LE as &'static types::Encoding),
        "x-user-defined" =>
            Some(all::whatwg::X_USER_DEFINED as &'static types::Encoding),
        _ => None
    }
}

/// Returns an encoding from Windows code page number.
/// http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756%28v=vs.85%29.aspx
/// Sometimes it can return a *superset* of the requested encoding, e.g. for several CJK encodings.
pub fn encoding_from_windows_code_page(cp: uint) -> Option<&'static types::Encoding> {
    match cp {
        65001 => Some(all::UTF_8 as &'static types::Encoding),
        866 => Some(all::IBM866 as &'static types::Encoding),
        28591 => Some(all::ISO_8859_1 as &'static types::Encoding),
        28592 => Some(all::ISO_8859_2 as &'static types::Encoding),
        28593 => Some(all::ISO_8859_3 as &'static types::Encoding),
        28594 => Some(all::ISO_8859_4 as &'static types::Encoding),
        28595 => Some(all::ISO_8859_5 as &'static types::Encoding),
        28596 => Some(all::ISO_8859_6 as &'static types::Encoding),
        28597 => Some(all::ISO_8859_7 as &'static types::Encoding),
        28598 => Some(all::ISO_8859_8 as &'static types::Encoding),
        38598 => Some(all::whatwg::ISO_8859_8_I as &'static types::Encoding),
        28603 => Some(all::ISO_8859_13 as &'static types::Encoding),
        28605 => Some(all::ISO_8859_15 as &'static types::Encoding),
        20866 => Some(all::KOI8_R as &'static types::Encoding),
        21866 => Some(all::KOI8_U as &'static types::Encoding),
        10000 => Some(all::MACINTOSH as &'static types::Encoding),
        874 => Some(all::WINDOWS_874 as &'static types::Encoding),
        1250 => Some(all::WINDOWS_1250 as &'static types::Encoding),
        1251 => Some(all::WINDOWS_1251 as &'static types::Encoding),
        1252 => Some(all::WINDOWS_1252 as &'static types::Encoding),
        1253 => Some(all::WINDOWS_1253 as &'static types::Encoding),
        1254 => Some(all::WINDOWS_1254 as &'static types::Encoding),
        1255 => Some(all::WINDOWS_1255 as &'static types::Encoding),
        1256 => Some(all::WINDOWS_1256 as &'static types::Encoding),
        1257 => Some(all::WINDOWS_1257 as &'static types::Encoding),
        1258 => Some(all::WINDOWS_1258 as &'static types::Encoding),
        1259 => Some(all::X_MAC_CYRILLIC as &'static types::Encoding),
        936 => Some(all::GBK18030 as &'static types::Encoding),
        54936 => Some(all::GB18030 as &'static types::Encoding),
        /*
        52936 => Some(all::HZ_GB_2312 as &'static types::Encoding),
        */
        950 => Some(all::BIG5_2003 as &'static types::Encoding),
        20932 => Some(all::EUC_JP as &'static types::Encoding),
        /*
        50220 => Some(all::ISO_2022_JP as &'static types::Encoding),
        */
        932 => Some(all::WINDOWS_31J as &'static types::Encoding),
        949 => Some(all::WINDOWS_949 as &'static types::Encoding),
        1201 => Some(all::UTF_16BE as &'static types::Encoding),
        1200 => Some(all::UTF_16LE as &'static types::Encoding),
        _ => None
    }
}

#[cfg(test)]
mod tests {
    extern mod extra;
    use super::encoding_from_whatwg_label;

    #[test]
    fn test_encoding_from_whatwg_label() {
        assert!(encoding_from_whatwg_label("utf-8").is_some())
        assert!(encoding_from_whatwg_label("UTF-8").is_some())
        assert!(encoding_from_whatwg_label("\t\n\x0C\r utf-8\t\n\x0C\r ").is_some())
        assert!(encoding_from_whatwg_label("\u00A0utf-8").is_none(),
                "Non-ASCII whitespace should not be trimmed")
        assert!(encoding_from_whatwg_label("greek").is_some())
        assert!(encoding_from_whatwg_label("gree\u212A").is_none(),
                "Case-insensitive matching should be ASCII only. Kelvin sign does not match k.")
    }

    #[bench]
    fn bench_encoding_from_whatwg_label(harness: &mut extra::test::BenchHarness) {
        do harness.iter() {
            encoding_from_whatwg_label("iso-8859-bazinga");
        }
    }
}

<|endoftext|>


<commit_before>use std::str::Chars;
use std::iter::Peekable;
use errors::{CalcrResult, CalcrError};
use token::Token;
use token::TokVal::*;
use token::KeywordKind::*;
use ast::OpKind::*;

pub fn lex_equation(eq: &String) -> CalcrResult<Vec<Token>> {
    let mut lexer = Lexer {
        pos: 0,
        iter: eq.chars().peekable(),
    };
    lexer.lex_expression()
}

pub struct Lexer<'a> {
    pos: usize,
    iter: Peekable<Chars<'a>>,
}

impl<'a> Lexer<'a> {
    pub fn lex_expression(&mut self) -> CalcrResult<Vec<Token>> {
        let mut out = Vec::new();
        loop {
            self.consume_whitespace();
            let tok = match self.peek_char() {
                Some(ch) if ch.is_numeric() => try!(self.lex_number()),
                Some(ch) if ch.is_alphabetic() => try!(self.lex_name_or_keyword()),
                Some(_) => try!(self.lex_single_char()),
                None => break,
            };
            out.push(tok);
        }
        Ok(out)
    }

    fn lex_number(&mut self) -> CalcrResult<Token> {
        let num_str = self.consume_while(|ch| ch.is_numeric() || ch == '.');
        if let Ok(num) = num_str.parse::<f64>() {
            Ok(Token {
                val: Num(num),
                span: (self.pos - num_str.len(), self.pos),
            })
        } else {
            Err(CalcrError {
                desc: format!("Invalid number: {}", num_str),
                span: Some((self.pos - num_str.len(), self.pos)),
            })
        }
    }

    fn lex_name_or_keyword(&mut self) -> CalcrResult<Token> {
        let name_str = self.consume_while(|ch| ch.is_alphabetic() || ch.is_numeric());
        let len = name_str.chars().count();
        let val = match name_str.as_ref() {
            "let" => Keyword(Let),
            _ => Name(name_str),
        };
        Ok(Token {
            val: val,
            span: (self.pos - len, self.pos),
        })
    }

    fn lex_single_char(&mut self) -> CalcrResult<Token> {
        let val = match self.consume_char() {
            '+' => Op(Plus),
            '-' => Op(Minus),
            '*' => Op(Mult),
            '/' => Op(Div),
            '^' => Op(Pow),
            '!' => Op(Fact),
            '=' => Op(Assign),
            '√' => Name("sqrt".to_string()),
            '(' => ParenOpen,
            ')' => ParenClose,
            '|' => AbsDelim,
            ch => return Err(CalcrError {
                desc: format!("Invalid char: {}", ch),
                span: Some((self.pos - 1, self.pos)),
            }),
        };
        Ok(Token {
            val: val,
            span: (self.pos - 1, self.pos),
        })
    }

    /// Peeks at the next `char` and returns `Some` if one was found, or `None` if none are left
    fn peek_char(&mut self) -> Option<char> {
        self.iter.peek().map(|ch| *ch)
    }

    /// Consumes a `char` - thereby advanding `pos` - and returns it
    ///
    /// # Panics
    /// This function panics if there are no more chars to consume
    fn consume_char(&mut self) -> char {
        let ch = self.iter.next();
        self.pos += 1;
        ch.unwrap().to_lowercase().next().unwrap()
    }

    /// Consumes `char`s long as `pred` returns true and we are not eof
    ///
    /// The `char`s are returned as a `String`. Note that unlike `consume_char` this function will
    /// not panic.
    fn consume_while<F>(&mut self, pred: F) -> String where F: Fn(char) -> bool {
        let mut out = String::new();
        loop {
            match self.peek_char() {
                Some(ch) if pred(ch) => out.push(self.consume_char()),
                _ => break,
            }
        }
        out
    }

    /// Consumes any current whitespace
    fn consume_whitespace(&mut self) {
        self.consume_while(|ch| ch.is_whitespace());
    }
}

#[cfg(test)]
mod tests {
    use super::lex_equation;
    use token::Token;
    use token::TokVal::*;
    use ast::OpKind::*;

    #[test]
    fn empty() {
        let eq = "".to_string();
        let toks = lex_equation(&eq);
        assert_eq!(toks, Ok(vec!()));
    }

    #[test]
    fn single_char() {
        let eq = "2".to_string();
        let toks = lex_equation(&eq);
        assert_eq!(toks, Ok(vec!(Token { val: Num(2.0), span: (0, 1) })));
    }

    #[test]
    fn utf8() {
        let eq = "π𐍈".to_string();
        let toks = lex_equation(&eq);
        assert_eq!(toks, Ok(vec!(Token { val: Name(eq), span: (0, 2) })));
    }

    #[test]
    fn ops() {
        let eq = "+-*/!^".to_string();
        let toks = lex_equation(&eq);
        assert_eq!(toks, Ok(vec!(Token { val: Op(Plus), span: (0,1) },
                                 Token { val: Op(Minus), span: (1,2) },
                                 Token { val: Op(Mult), span: (2,3) },
                                 Token { val: Op(Div), span: (3,4) },
                                 Token { val: Op(Fact), span: (4,5) },
                                 Token { val: Op(Pow), span: (5,6) })));
    }

    #[test]
    fn delims() {
        let eq = "|()".to_string();
        let toks = lex_equation(&eq);
        assert_eq!(toks, Ok(vec!(Token { val: AbsDelim, span: (0,1) },
                                 Token { val: ParenOpen, span: (1,2) },
                                 Token { val: ParenClose, span: (2,3) })));
    }

    #[test]
    fn sqrt_single_char() {
        let eq = "√".to_string();
        let toks = lex_equation(&eq);
        assert_eq!(toks, Ok(vec!(Token { val: Name("sqrt".to_string()), span: (0,1) })));
    }

    #[test]
    fn invalid_char() {
        let eq = "?".to_string();
        let err = lex_equation(&eq);
        assert!(err.is_err());
    }
}<commit_msg>Allow '[' and ']' to be used as parentheses<commit_after>use std::str::Chars;
use std::iter::Peekable;
use errors::{CalcrResult, CalcrError};
use token::Token;
use token::TokVal::*;
use token::KeywordKind::*;
use ast::OpKind::*;

pub fn lex_equation(eq: &String) -> CalcrResult<Vec<Token>> {
    let mut lexer = Lexer {
        pos: 0,
        iter: eq.chars().peekable(),
    };
    lexer.lex_expression()
}

pub struct Lexer<'a> {
    pos: usize,
    iter: Peekable<Chars<'a>>,
}

impl<'a> Lexer<'a> {
    pub fn lex_expression(&mut self) -> CalcrResult<Vec<Token>> {
        let mut out = Vec::new();
        loop {
            self.consume_whitespace();
            let tok = match self.peek_char() {
                Some(ch) if ch.is_numeric() => try!(self.lex_number()),
                Some(ch) if ch.is_alphabetic() => try!(self.lex_name_or_keyword()),
                Some(_) => try!(self.lex_single_char()),
                None => break,
            };
            out.push(tok);
        }
        Ok(out)
    }

    fn lex_number(&mut self) -> CalcrResult<Token> {
        let num_str = self.consume_while(|ch| ch.is_numeric() || ch == '.');
        if let Ok(num) = num_str.parse::<f64>() {
            Ok(Token {
                val: Num(num),
                span: (self.pos - num_str.len(), self.pos),
            })
        } else {
            Err(CalcrError {
                desc: format!("Invalid number: {}", num_str),
                span: Some((self.pos - num_str.len(), self.pos)),
            })
        }
    }

    fn lex_name_or_keyword(&mut self) -> CalcrResult<Token> {
        let name_str = self.consume_while(|ch| ch.is_alphabetic() || ch.is_numeric());
        let len = name_str.chars().count();
        let val = match name_str.as_ref() {
            "let" => Keyword(Let),
            _ => Name(name_str),
        };
        Ok(Token {
            val: val,
            span: (self.pos - len, self.pos),
        })
    }

    fn lex_single_char(&mut self) -> CalcrResult<Token> {
        let val = match self.consume_char() {
            '+' => Op(Plus),
            '-' => Op(Minus),
            '*' => Op(Mult),
            '/' => Op(Div),
            '^' => Op(Pow),
            '!' => Op(Fact),
            '=' => Op(Assign),
            '√' => Name("sqrt".to_string()),
            '(' | '[' => ParenOpen,
            ')' | ']' => ParenClose,
            '|' => AbsDelim,
            ch => return Err(CalcrError {
                desc: format!("Invalid char: {}", ch),
                span: Some((self.pos - 1, self.pos)),
            }),
        };
        Ok(Token {
            val: val,
            span: (self.pos - 1, self.pos),
        })
    }

    /// Peeks at the next `char` and returns `Some` if one was found, or `None` if none are left
    fn peek_char(&mut self) -> Option<char> {
        self.iter.peek().map(|ch| *ch)
    }

    /// Consumes a `char` - thereby advanding `pos` - and returns it
    ///
    /// # Panics
    /// This function panics if there are no more chars to consume
    fn consume_char(&mut self) -> char {
        let ch = self.iter.next();
        self.pos += 1;
        ch.unwrap().to_lowercase().next().unwrap()
    }

    /// Consumes `char`s long as `pred` returns true and we are not eof
    ///
    /// The `char`s are returned as a `String`. Note that unlike `consume_char` this function will
    /// not panic.
    fn consume_while<F>(&mut self, pred: F) -> String where F: Fn(char) -> bool {
        let mut out = String::new();
        loop {
            match self.peek_char() {
                Some(ch) if pred(ch) => out.push(self.consume_char()),
                _ => break,
            }
        }
        out
    }

    /// Consumes any current whitespace
    fn consume_whitespace(&mut self) {
        self.consume_while(|ch| ch.is_whitespace());
    }
}

#[cfg(test)]
mod tests {
    use super::lex_equation;
    use token::Token;
    use token::TokVal::*;
    use ast::OpKind::*;

    #[test]
    fn empty() {
        let eq = "".to_string();
        let toks = lex_equation(&eq);
        assert_eq!(toks, Ok(vec!()));
    }

    #[test]
    fn single_char() {
        let eq = "2".to_string();
        let toks = lex_equation(&eq);
        assert_eq!(toks, Ok(vec!(Token { val: Num(2.0), span: (0, 1) })));
    }

    #[test]
    fn utf8() {
        let eq = "π𐍈".to_string();
        let toks = lex_equation(&eq);
        assert_eq!(toks, Ok(vec!(Token { val: Name(eq), span: (0, 2) })));
    }

    #[test]
    fn ops() {
        let eq = "+-*/!^".to_string();
        let toks = lex_equation(&eq);
        assert_eq!(toks, Ok(vec!(Token { val: Op(Plus), span: (0,1) },
                                 Token { val: Op(Minus), span: (1,2) },
                                 Token { val: Op(Mult), span: (2,3) },
                                 Token { val: Op(Div), span: (3,4) },
                                 Token { val: Op(Fact), span: (4,5) },
                                 Token { val: Op(Pow), span: (5,6) })));
    }

    #[test]
    fn delims() {
        let eq = "|()".to_string();
        let toks = lex_equation(&eq);
        assert_eq!(toks, Ok(vec!(Token { val: AbsDelim, span: (0,1) },
                                 Token { val: ParenOpen, span: (1,2) },
                                 Token { val: ParenClose, span: (2,3) })));
    }

    #[test]
    fn sqrt_single_char() {
        let eq = "√".to_string();
        let toks = lex_equation(&eq);
        assert_eq!(toks, Ok(vec!(Token { val: Name("sqrt".to_string()), span: (0,1) })));
    }

    #[test]
    fn invalid_char() {
        let eq = "?".to_string();
        let err = lex_equation(&eq);
        assert!(err.is_err());
    }
}<|endoftext|>