<commit_before>#![allow(dead_code)]

use parser::ast::*;
use scope::context::*;
use processing::structs::*;

type FormalProp<'a> = (&'a str);
type FormalPropVec<'a> = Vec<FormalProp<'a>>;

type PropKeyRef = (String, String);
type PropKeyRefVec = Vec<PropKeyRef>;

type PropValue<'a> = (&'a str, Option<&'a ExprValue>);
type PropValueVec<'a> = Vec<PropValue<'a>>;

#[derive(Debug, Clone, Default)]
pub struct CompDefProcessorOutput {
    ty: Option<String>,
    ops: Option<OpsVec>
}

impl Into<Component> for CompDefProcessorOutput {
    fn into(self) -> Component {
        Component::new_with_vec(self.ty.unwrap(), self.ops)
    }
}

#[derive(Debug)]
pub struct CompDefProcessor<'out> {
    output: &'out mut CompDefProcessorOutput
}

impl<'out> CompDefProcessor<'out> {
    pub fn with_output(output: &'out mut CompDefProcessorOutput) -> Self {
        CompDefProcessor { output: output }
    }

    fn add_op(&mut self, op: ElementOp) {
        if let Some(ref mut ops) = self.output.ops {
            ops.push(op);
        } else {
            self.output.ops = Some(vec![op]);
        }
    }

    pub fn push_component_definition_scope<'a, I>(&mut self, ctx: &mut Context,component_ty: &str, formals: I)
        where I: IntoIterator<Item = &'a FormalProp<'a>>
    {
        if self.output.ty.is_some() {
            panic!("Already have component defintion in this output.");
        }
        self.output.ty = Some(component_ty.to_owned());

        ctx.push_child_scope();
        for formal in formals {
            ctx.add_unbound_formal_param(formal);
        }
    }

    pub fn push_element_parameter_definition_scope<'a, I>(&mut self, ctx: &mut Context, element_id: &str, element_ty: &str, props: Option<I>)
        where I: IntoIterator<Item = &'a PropKeyRef> + Clone
    {
        // let props = props.map(|props| props.clone().into_iter());
        let element_props = props.as_ref().map(|props| props.clone().into_iter().map(|prop| {
            let key = &prop.0;
            let ref_key = &prop.1;
            let value_sym = ctx.resolve_sym(ref_key);
            if let Some(value_sym) = value_sym {
                return (key.to_owned(), Some(ExprValue::SymbolReference(value_sym)));
            };
            (key.to_owned(), None)
        }).collect());

        let op = ElementOp::ElementVoid(element_ty.to_owned(), Some(element_id.to_owned()), element_props, None, None);
        self.add_op(op);

        let parent_scope_id = ctx.scope().id().to_owned();
        ctx.push_child_scope();
        if let Some(props) = props {
            for prop in props {
                ctx.add_element_prop_ref(&prop.0, &prop.1, Some(&parent_scope_id));
            }
        }
    }

    pub fn push_element_scope(&mut self, ctx: &mut Context, element_id: &str, _element_ty: &str) {
        ctx.push_child_scope();
        ctx.append_path_str(element_id);
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::iter::*;
    use parser::ast::*;
    use scope::context::*;

    trait OpsWriter {
        fn write_op(&mut self, op: &ElementOp);
    }

    #[derive(Debug, Default)]
    struct TestOpsWriter {
    }

    impl OpsWriter for TestOpsWriter {
        fn write_op(&mut self, op: &ElementOp) {

        }
    }

    #[derive(Debug, Default)]
    struct ComponentWriter {
        ctx: Context
    }

    type PropValue<'a> = (&'a str, Option<&'a ExprValue>);

    #[derive(Debug)]
    struct SymbolResolver<'a, I: Iterator<Item = &'a str>> {
        ctx: &'a mut Context,
        iter: I
    }

    // impl<'a, I> SymbolResolver<'a, I>
    // //   where I: Iterator<Item = &'a PropValue<'a>>
    // {
    //     pub fn new(ctx: &'a mut Context, iter: Self::I) -> Self {
    //         SymbolResolver { ctx: ctx, iter: iter }
    //     }
    // }

    // impl<'a, I> Iterator for SymbolResolver<'a, I>
    //   where I: Iterator<Item = &'a PropValue<'a>>
    impl<'a, I: Iterator<Item = &'a str>> Iterator for SymbolResolver<'a, I>
    {
        type Item = Prop;

        fn next(&mut self) -> Option<Self::Item> {
            if let Some(key) = self.iter.next() {
                let resolved_sym = self.ctx.resolve_sym(key);
                if let Some(resolved_sym) = resolved_sym {
                    // let key = prop.0.to_owned();
                    let expr = ExprValue::SymbolReference(resolved_sym);
                    return Some((key.to_owned(), Some(expr)));
                };
                return Some((key.to_owned(), None));
                // return Some((key.to_owned(), prop.1.map(|p| p.to_owned())));
            };
            None

            // self.iter.next().map(|prop| {
            //     let resolved_sym = self.ctx.resolve_sym(&prop.0);
            //     if let Some(resolved_sym) = resolved_sym {
            //         let key = prop.0.to_owned();
            //         let expr = ExprValue::SymbolReference(resolved_sym);
            //         return (key, Some(expr));
            //     }

            //     return (prop.0.to_owned(), prop.1.map(|p| p.to_owned()))
            // })
        }
    }

    // impl<B, I: ExactSizeIterator, F> ExactSizeIterator for SymbolResolver<I>
    // {
    //     fn len(&self) -> usize {
    //         self.iter.len()
    //     }

    //     fn is_empty(&self) -> bool {
    //         self.iter.is_empty()
    //     }
    // }

    impl<'a> ComponentWriter {
        // fn resolve_props<'props, I>(&'a mut self, props: I) -> SymbolResolver<'a, I>
        //   where I: Iterator<Item = PropValue<'props>>
        // {
        //     SymbolResolver::new(&mut self.ctx, props)
        // }

        fn write_op_to<W>(&mut self, ops_writer: &mut W, comp_op: &ElementOp)
          where W: OpsWriter
        {
            match comp_op {
                &ElementOp::ElementVoid(ref element_ty, ref element_id, ref props, ref event_handlers, ref value_bindings) => {
                    if let &Some(ref props) = props {
                        // let v: Vec<PropValue<'a>> = vec![];
                        // let v: PropVec = vec![];
                        // let mut prop_iter = v.iter().map(|prop| (prop.0.as_ref(), prop.1.as_ref()));

                        let mut prop_iter = props.iter().map(|prop| prop.0.as_str());
                        let mut iter = SymbolResolver { ctx: &mut self.ctx, iter: prop_iter };
                        let resolved_props: Vec<Prop> = iter.collect();

                        let op = ElementOp::ElementVoid(element_ty.to_owned(), element_id.to_owned(), Some(resolved_props), event_handlers.to_owned(), value_bindings.to_owned());
                        ops_writer.write_op(&op);
                    };

                    // let resolved_props = props.map(|props| {
                    //     let mut props_iter = props.iter().map(|prop| (prop.0.as_ref(), prop.1.map(|p| &p)));
                    //     let mut iter = SymbolResolver { ctx: &mut self.ctx, iter: props_iter };

                    //     // let mut iter = self.resolve_props(
                    //     //     props.iter().map(|prop| (prop.0.as_ref(), prop.1.map(|p| &p)))
                    //     // );
                    //     let resolved_prop = iter.next().unwrap();
                    //     // let resolved_props: PropVec = iter.collect();

                    //     // resolved_props
                    //     vec![]
                    // });
                    // let op = ElementOp::ElementVoid(element_ty.to_owned(), element_id.to_owned(), resolved_props, event_handlers.to_owned(), value_bindings.to_owned());
                    // ops_writer.write_op(&op);
                },
                _ => { ops_writer.write_op(comp_op); }
            };
        }

        pub fn write_component<W>(&mut self, ops_writer: &mut W, comp: &Component)
          where W: OpsWriter
        {
            if let Some(ops_iter) = comp.ops_iter() {
                for op in ops_iter {
                    ops_writer.write_op(op);
                }
            };
        }
    }

    #[test]
    pub fn test_process_comp_def1() {
        let mut output = CompDefProcessorOutput::default();

        let comp_definition_scope_id: String;
        // let element_param_defs_scope_id: String;
        {
            let mut ctx = Context::default();
            let mut processor = CompDefProcessor::with_output(&mut output);

            // component Component(todo)
            // Create new component context with unbound formal prop (todo)
            {
                let formals: FormalPropVec = vec![("todo")];
                processor.push_component_definition_scope(&mut ctx, "Component", formals.iter());
            }
            comp_definition_scope_id = ctx.scope().id().to_owned();

            // within Component definition
            {
                // The local (todo) should be an unbound formal prop (todo)
                assert_eq!(ctx.resolve_sym("todo"),
                    // Some(Symbol::ref_prop_in_scope("todo", "todo", Some(&lm_element_scope_id)))
                    Some(Symbol::unbound_formal_param("todo", Some(&comp_definition_scope_id)))
                );
            }
            // element_param_defs_scope_id = ctx.scope().id().to_owned();

            // element Pq invocation
            {
                let props: PropKeyRefVec = vec![
                    ("value".into(), "todo".into())
                ];
                processor.push_element_parameter_definition_scope(&mut ctx, "Pq", "input", Some(props.iter()));
            }
            // let element_pq_invocation_scope_id = ctx.scope().id().to_owned();

            // element Pq scope
            {
                processor.push_element_scope(&mut ctx, "Pq", "input");

                // The local (todo) should still be an unbound formal param (todo)
                assert_eq!(ctx.resolve_sym("todo"),
                    Some(Symbol::unbound_formal_param("todo", Some(&comp_definition_scope_id)))
                );
            }
        }

        // Verify output
        let comp: Component = output.into();
        assert_eq!(comp.ty(), "Component");
        assert_eq!(
            comp.ops_iter().map(|v| v.into_iter().cloned().collect()),
            Some(vec![
                ElementOp::ElementVoid("input".into(), Some("Pq".into()), Some(vec![(
                    "value".into(),
                    Some(ExprValue::SymbolReference(Symbol::unbound_formal_param("todo", Some(&comp_definition_scope_id)) ))
                )]), None, None)
            ])
        );

        // Test writer
        let mut ops_writer = TestOpsWriter::default();
        let mut comp_writer = ComponentWriter::default();

        comp_writer.write_component(&mut ops_writer, &comp);
    }
}<commit_msg>Fix SymbolResolver to accept PropValue as input<commit_after>#![allow(dead_code)]

use parser::ast::*;
use scope::context::*;
use processing::structs::*;

type FormalProp<'a> = (&'a str);
type FormalPropVec<'a> = Vec<FormalProp<'a>>;

type PropKeyRef = (String, String);
type PropKeyRefVec = Vec<PropKeyRef>;

type PropValue<'a> = (&'a str, Option<&'a ExprValue>);
type PropValueVec<'a> = Vec<PropValue<'a>>;

#[derive(Debug, Clone, Default)]
pub struct CompDefProcessorOutput {
    ty: Option<String>,
    ops: Option<OpsVec>
}

impl Into<Component> for CompDefProcessorOutput {
    fn into(self) -> Component {
        Component::new_with_vec(self.ty.unwrap(), self.ops)
    }
}

#[derive(Debug)]
pub struct CompDefProcessor<'out> {
    output: &'out mut CompDefProcessorOutput
}

impl<'out> CompDefProcessor<'out> {
    pub fn with_output(output: &'out mut CompDefProcessorOutput) -> Self {
        CompDefProcessor { output: output }
    }

    fn add_op(&mut self, op: ElementOp) {
        if let Some(ref mut ops) = self.output.ops {
            ops.push(op);
        } else {
            self.output.ops = Some(vec![op]);
        }
    }

    pub fn push_component_definition_scope<'a, I>(&mut self, ctx: &mut Context,component_ty: &str, formals: I)
        where I: IntoIterator<Item = &'a FormalProp<'a>>
    {
        if self.output.ty.is_some() {
            panic!("Already have component defintion in this output.");
        }
        self.output.ty = Some(component_ty.to_owned());

        ctx.push_child_scope();
        for formal in formals {
            ctx.add_unbound_formal_param(formal);
        }
    }

    pub fn push_element_parameter_definition_scope<'a, I>(&mut self, ctx: &mut Context, element_id: &str, element_ty: &str, props: Option<I>)
        where I: IntoIterator<Item = &'a PropKeyRef> + Clone
    {
        // let props = props.map(|props| props.clone().into_iter());
        let element_props = props.as_ref().map(|props| props.clone().into_iter().map(|prop| {
            let key = &prop.0;
            let ref_key = &prop.1;
            let value_sym = ctx.resolve_sym(ref_key);
            if let Some(value_sym) = value_sym {
                return (key.to_owned(), Some(ExprValue::SymbolReference(value_sym)));
            };
            (key.to_owned(), None)
        }).collect());

        let op = ElementOp::ElementVoid(element_ty.to_owned(), Some(element_id.to_owned()), element_props, None, None);
        self.add_op(op);

        let parent_scope_id = ctx.scope().id().to_owned();
        ctx.push_child_scope();
        if let Some(props) = props {
            for prop in props {
                ctx.add_element_prop_ref(&prop.0, &prop.1, Some(&parent_scope_id));
            }
        }
    }

    pub fn push_element_scope(&mut self, ctx: &mut Context, element_id: &str, _element_ty: &str) {
        ctx.push_child_scope();
        ctx.append_path_str(element_id);
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::iter::*;
    use parser::ast::*;
    use scope::context::*;

    trait OpsWriter {
        fn write_op(&mut self, op: &ElementOp);
    }

    #[derive(Debug, Default)]
    struct TestOpsWriter {
    }

    impl OpsWriter for TestOpsWriter {
        fn write_op(&mut self, op: &ElementOp) {

        }
    }

    #[derive(Debug, Default)]
    struct ComponentWriter {
        ctx: Context
    }

    type PropValue<'a> = (&'a str, Option<&'a ExprValue>);

    #[derive(Debug)]
    struct SymbolResolver<'a, I: Iterator<Item = PropValue<'a>>> {
        ctx: &'a mut Context,
        iter: I
    }

    // impl<'a, I> SymbolResolver<'a, I>
    // //   where I: Iterator<Item = &'a PropValue<'a>>
    // {
    //     pub fn new(ctx: &'a mut Context, iter: Self::I) -> Self {
    //         SymbolResolver { ctx: ctx, iter: iter }
    //     }
    // }

    // impl<'a, I> Iterator for SymbolResolver<'a, I>
    //   where I: Iterator<Item = &'a PropValue<'a>>
    impl<'a, I: Iterator<Item = PropValue<'a>>> Iterator for SymbolResolver<'a, I>
    {
        type Item = Prop;

        fn next(&mut self) -> Option<Self::Item> {
            if let Some(prop) = self.iter.next() {
                let key = prop.0.to_owned();
                let expr = &prop.1;
                let resolved_sym = self.ctx.resolve_sym(&key);
                if let Some(resolved_sym) = resolved_sym {
                    // let key = prop.0.to_owned();
                    let expr = ExprValue::SymbolReference(resolved_sym);
                    return Some((key, Some(expr)));
                };
                return Some((key, expr.map(|p| p.clone())));
                // return Some((key.to_owned(), prop.1.map(|p| p.to_owned())));
            };
            None

            // self.iter.next().map(|prop| {
            //     let resolved_sym = self.ctx.resolve_sym(&prop.0);
            //     if let Some(resolved_sym) = resolved_sym {
            //         let key = prop.0.to_owned();
            //         let expr = ExprValue::SymbolReference(resolved_sym);
            //         return (key, Some(expr));
            //     }

            //     return (prop.0.to_owned(), prop.1.map(|p| p.to_owned()))
            // })
        }
    }

    // impl<B, I: ExactSizeIterator, F> ExactSizeIterator for SymbolResolver<I>
    // {
    //     fn len(&self) -> usize {
    //         self.iter.len()
    //     }

    //     fn is_empty(&self) -> bool {
    //         self.iter.is_empty()
    //     }
    // }

    impl<'a> ComponentWriter {
        // fn resolve_props<'props, I>(&'a mut self, props: I) -> SymbolResolver<'a, I>
        //   where I: Iterator<Item = PropValue<'props>>
        // {
        //     SymbolResolver::new(&mut self.ctx, props)
        // }

        fn write_op_to<W>(&mut self, ops_writer: &mut W, comp_op: &ElementOp)
          where W: OpsWriter
        {
            match comp_op {
                &ElementOp::ElementVoid(ref element_ty, ref element_id, ref props, ref event_handlers, ref value_bindings) => {
                    if let &Some(ref props) = props {
                        // let v: Vec<PropValue<'a>> = vec![];
                        // let v: PropVec = vec![];
                        // let mut prop_iter = v.iter().map(|prop| (prop.0.as_ref(), prop.1.as_ref()));

                        let mut prop_iter = props.iter().map(|prop| (prop.0.as_str(), prop.1.as_ref()));
                        let mut iter = SymbolResolver { ctx: &mut self.ctx, iter: prop_iter };
                        let resolved_props: Vec<Prop> = iter.collect();

                        let op = ElementOp::ElementVoid(element_ty.to_owned(), element_id.to_owned(), Some(resolved_props), event_handlers.to_owned(), value_bindings.to_owned());
                        ops_writer.write_op(&op);
                    };

                    // let resolved_props = props.map(|props| {
                    //     let mut props_iter = props.iter().map(|prop| (prop.0.as_ref(), prop.1.map(|p| &p)));
                    //     let mut iter = SymbolResolver { ctx: &mut self.ctx, iter: props_iter };

                    //     // let mut iter = self.resolve_props(
                    //     //     props.iter().map(|prop| (prop.0.as_ref(), prop.1.map(|p| &p)))
                    //     // );
                    //     let resolved_prop = iter.next().unwrap();
                    //     // let resolved_props: PropVec = iter.collect();

                    //     // resolved_props
                    //     vec![]
                    // });
                    // let op = ElementOp::ElementVoid(element_ty.to_owned(), element_id.to_owned(), resolved_props, event_handlers.to_owned(), value_bindings.to_owned());
                    // ops_writer.write_op(&op);
                },
                _ => { ops_writer.write_op(comp_op); }
            };
        }

        pub fn write_component<W>(&mut self, ops_writer: &mut W, comp: &Component)
          where W: OpsWriter
        {
            if let Some(ops_iter) = comp.ops_iter() {
                for op in ops_iter {
                    ops_writer.write_op(op);
                }
            };
        }
    }

    #[test]
    pub fn test_process_comp_def1() {
        let mut output = CompDefProcessorOutput::default();

        let comp_definition_scope_id: String;
        // let element_param_defs_scope_id: String;
        {
            let mut ctx = Context::default();
            let mut processor = CompDefProcessor::with_output(&mut output);

            // component Component(todo)
            // Create new component context with unbound formal prop (todo)
            {
                let formals: FormalPropVec = vec![("todo")];
                processor.push_component_definition_scope(&mut ctx, "Component", formals.iter());
            }
            comp_definition_scope_id = ctx.scope().id().to_owned();

            // within Component definition
            {
                // The local (todo) should be an unbound formal prop (todo)
                assert_eq!(ctx.resolve_sym("todo"),
                    // Some(Symbol::ref_prop_in_scope("todo", "todo", Some(&lm_element_scope_id)))
                    Some(Symbol::unbound_formal_param("todo", Some(&comp_definition_scope_id)))
                );
            }
            // element_param_defs_scope_id = ctx.scope().id().to_owned();

            // element Pq invocation
            {
                let props: PropKeyRefVec = vec![
                    ("value".into(), "todo".into())
                ];
                processor.push_element_parameter_definition_scope(&mut ctx, "Pq", "input", Some(props.iter()));
            }
            // let element_pq_invocation_scope_id = ctx.scope().id().to_owned();

            // element Pq scope
            {
                processor.push_element_scope(&mut ctx, "Pq", "input");

                // The local (todo) should still be an unbound formal param (todo)
                assert_eq!(ctx.resolve_sym("todo"),
                    Some(Symbol::unbound_formal_param("todo", Some(&comp_definition_scope_id)))
                );
            }
        }

        // Verify output
        let comp: Component = output.into();
        assert_eq!(comp.ty(), "Component");
        assert_eq!(
            comp.ops_iter().map(|v| v.into_iter().cloned().collect()),
            Some(vec![
                ElementOp::ElementVoid("input".into(), Some("Pq".into()), Some(vec![(
                    "value".into(),
                    Some(ExprValue::SymbolReference(Symbol::unbound_formal_param("todo", Some(&comp_definition_scope_id)) ))
                )]), None, None)
            ])
        );

        // Test writer
        let mut ops_writer = TestOpsWriter::default();
        let mut comp_writer = ComponentWriter::default();

        comp_writer.write_component(&mut ops_writer, &comp);
    }
}<|endoftext|>


<commit_before>use std::io::File;
use std::mem;
use std::os;

// https://stackoverflow.com/questions/24633784/is-there-a-gzip-library-available-for-rust

fn pointer_size() -> uint {
    let tmp = 0u8;
    let boxed = box tmp;
    mem::size_of_val(&boxed)
}

fn main() {
    let args = os::args();
    if args.len() != 2 {
        println!("usage: read_blend_file /path/to/file.blend");
    } else {
        let slice: &str = args[1].as_slice();
        println!("open \"{}\" ...", slice);
        {
            // read 12 bytes from the Blender file
            let path = Path::new(slice);
            let display = path.display();
            let mut file = match File::open(&path) {
                Err(why) => fail!("couldn't open {}: {}", display, why.desc),
                Ok(file) => file,
            };
            let mut buf = [0u8, ..12];
            match file.read(buf) {
                Err(why) => println!("{}", why),
                Ok(_) => (),
            }
            // pack those 12 bytes into a string ...
            let mut header = String::new();
            for n in range(0u, 12) {
                header.push(buf[n] as char);
            }
            // ... to be able to compare them
            let slice = header.as_slice();
            let blender: &str = slice.slice(0, 7); // first 7 chars
            if blender == "BLENDER" {
                println!("INFO: a Blender file.");
                let ptr_size = pointer_size();
                println!("size of pointer in bytes: {}", ptr_size);
                println!("Header (12 chars): {}", header);
                let mut ptr_size_differs = false;
                if buf[7] as char == '_' {
                    // 32-bit pointers expected
                    if ptr_size != 4 {
                        ptr_size_differs = true;
                    }
                    println!("32-bit pointers in file, pointer size differs? {}", ptr_size_differs);
                } else {
                    // 64-bit pointers expected
                    if ptr_size != 8 {
                        ptr_size_differs = true;
                    }
                    println!("64-bit pointers in file, pointer size differs? {}", ptr_size_differs);
                }
                // little endian or big endian?
                let mut l_endian;
                let endian_test = 1u16; // value one stored in two bytes
                if endian_test.to_le() != endian_test {
                    l_endian = false;
                } else {
                    // if we are on a little endian machine to_le() is a no-op
                    l_endian = true;
                }
                println!("l_endian = {}", l_endian);
                let mut switch_endian;
                if buf[8] as char == 'v' {
                    // file stores little endian
                    if !l_endian {
                        switch_endian = true;
                    } else {
                        switch_endian = false;
                    }
                } else {
                    // file stores big endian
                    if l_endian {
                        switch_endian = true;
                    } else {
                        switch_endian = false;
                    }
                }
                println!("switch_endian = {}", switch_endian);
                // get the version number
                let mut num = String::new();
                for n in range(9u, 12) {
                    num.push(buf[n] as char);
                }
                println!("num = {}", num);
                // assumes 64-bit pointers (in file as well as on platform)
                loop {
                    // read_file_dna
                    let mut bhead8 = [0u8, ..24]; // 4 * int + 64-bit pointer
                    match file.read(bhead8) {
                        Err(why) => println!("{}", why),
                        Ok(_) => (),
                    }
                    // pack those 24 bytes into a string ...
                    let mut bhead = String::new();
                    for n in range(0u, 24) {
                        bhead.push(bhead8[n] as char);
                    }
                    let slice = bhead.as_slice();
                    let code: &str = slice.slice(0, 4); // first 4 chars
                    println!("code = {}", code);
                    let mut len: uint = 0;
                    len += (bhead8[4] as uint) <<  0;
                    len += (bhead8[5] as uint) <<  8;
                    len += (bhead8[6] as uint) << 16;
                    len += (bhead8[7] as uint) << 24;
                    println!("len = {}", len);
                    if code == "ENDB" && len == 0 {
                        break;
                    } else if code == "DNA1" {
                        // DNA_sdna_from_data
                        let mut counter = 0u;
                        // SDNA
                        let mut char4 = [0u8, ..4];
                        match file.read(char4) {
                            Err(why) => println!("{}", why),
                            Ok(_) => (),
                        }
                        counter += 4;
                        let mut str4 = String::new();
                        for n in range(0u, 4) {
                            str4.push(char4[n] as char);
                        }
                        let slice = str4.as_slice();
                        let code: &str = slice.slice(0, 4);
                        println!("  code = {}", code);
                        if code == "SDNA" {
                            // NAME
                            let mut char4 = [0u8, ..4];
                            match file.read(char4) {
                                Err(why) => println!("{}", why),
                                Ok(_) => (),
                            }
                            counter += 4;
                            let mut str4 = String::new();
                            for n in range(0u, 4) {
                                str4.push(char4[n] as char);
                            }
                            let slice = str4.as_slice();
                            let code: &str = slice.slice(0, 4);
                            println!("  code = {}", code);
                            if code == "NAME" {
                                // nr_names
                                let io_result = file.read_le_u32();
                                let nr_names: u32 = io_result.unwrap();
                                counter += 4;
                                println!("  nr_names = {}", nr_names);
                                let mut nr = 0u32;
                                loop {
                                    let mut name = String::new();
                                    loop {
                                        // expect strings with '\0' as terminator
                                        let io_result = file.read_byte();
                                        let byte: u8 = io_result.unwrap();
                                        counter += 1;
                                        if byte != 0 {
                                            name.push(byte as char);
                                        } else {
                                            println!("    name = '{}'", name);
                                            nr += 1;
                                            break;
                                        }
                                    } // name loop
                                    if nr >= nr_names {
                                        break;
                                    }
                                } // nr_names loop
                                // assume fill bytes with '\0'
                                let mut last_byte;
                                loop {
                                    let io_result = file.read_byte();
                                    let byte: u8 = io_result.unwrap();
                                    counter += 1;
                                    if byte != 0 {
                                        last_byte = byte;
                                        break;
                                    }
                                } // fill bytes
                                // TYPE
                                let mut char3 = [0u8, ..3];
                                match file.read(char3) {
                                    Err(why) => println!("{}", why),
                                    Ok(_) => (),
                                }
                                counter += 3;
                                let mut str4 = String::new();
                                str4.push(last_byte as char);
                                for n in range(0u, 3) {
                                    str4.push(char3[n] as char);
                                }
                                let slice = str4.as_slice();
                                let code: &str = slice.slice(0, 4);
                                println!("  code = {}", code);
                                if code == "TYPE" {
                                    // nr_types
                                    let io_result = file.read_le_u32();
                                    let nr_types: u32 = io_result.unwrap();
                                    counter += 4;
                                    println!("  nr_types = {}", nr_types);
                                    let mut nr = 0u32;
                                    loop {
                                        let mut name = String::new();
                                        loop {
                                            // expect strings with
                                            // '\0' as terminator
                                            let io_result = file.read_byte();
                                            let byte: u8 = io_result.unwrap();
                                            counter += 1;
                                            if byte != 0 {
                                                name.push(byte as char);
                                            } else {
                                                println!("    type = '{}'",
                                                         name);
                                                nr += 1;
                                                break;
                                            }
                                        } // type loop
                                        if nr >= nr_types {
                                            break;
                                        }
                                    } // nr_types loop
                                    // assume fill bytes with '\0'
                                    let mut last_byte;
                                    loop {
                                        let io_result = file.read_byte();
                                        let byte: u8 = io_result.unwrap();
                                        counter += 1;
                                        if byte != 0 {
                                            last_byte = byte;
                                            break;
                                        }
                                    } // fill bytes
                                    // TLEN
                                    let mut char3 = [0u8, ..3];
                                    match file.read(char3) {
                                        Err(why) => println!("{}", why),
                                        Ok(_) => (),
                                    }
                                    counter += 3;
                                    let mut str4 = String::new();
                                    str4.push(last_byte as char);
                                    for n in range(0u, 3) {
                                        str4.push(char3[n] as char);
                                    }
                                    let slice = str4.as_slice();
                                    let code: &str = slice.slice(0, 4);
                                    println!("  code = {}", code);
                                    if code == "TLEN" {
                                        // typelens
                                        let io_result = file.read_le_u16();
                                        let typelens: u16 = io_result.unwrap();
                                        counter += 2;
                                        println!("    typelens = {}", typelens);
                                        // skip nr_types times u16 values
                                        let _dummy = file.read_exact(2u *
                                                                     nr_types as
                                                                     uint);
                                        counter += 2u * nr_types as uint;
                                        // check next byte
                                        let io_result = file.read_byte();
                                        last_byte = io_result.unwrap();
                                        counter += 1;
                                        if last_byte == 0 {
                                            let io_result = file.read_byte();
                                            last_byte = io_result.unwrap();
                                            counter += 1;
                                        }
                                        // STRC
                                        let mut char3 = [0u8, ..3];
                                        match file.read(char3) {
                                            Err(why) => println!("{}", why),
                                            Ok(_) => (),
                                        }
                                        counter += 3;
                                        let mut str4 = String::new();
                                        str4.push(last_byte as char);
                                        for n in range(0u, 3) {
                                            str4.push(char3[n] as char);
                                        }
                                        let slice = str4.as_slice();
                                        let code: &str = slice.slice(0, 4);
                                        println!("  code = {}", code);
                                        if code == "STRC" {
                                            // nr_structs
                                            let io_result = file.read_le_u32();
                                            let nr_structs: u32 = io_result.unwrap();
                                            counter += 4;
                                            println!("    nr_structs = {}", nr_structs);
                                            nr = 0u32;
                                            loop {
                                                // sp0
                                                let io_result = file.read_le_u16();
                                                let _sp0: u16 = io_result.unwrap();
                                                counter += 2;
                                                // sp1
                                                let io_result = file.read_le_u16();
                                                let sp1: u16 = io_result.unwrap();
                                                counter += 2;
                                                for _n in range(0u16, 2 * sp1) {
                                                    let io_result = file.read_le_u16();
                                                    let _u: u16 = io_result.unwrap();
                                                    counter += 2;
                                                }
                                                nr += 1;
                                                if nr >= nr_structs {
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        // read remaining stuff
                        println!("skip {} bytes", len - counter)
                        let _dummy = file.read_exact(len - counter);
                    } else {
                        let tc: &str = slice.slice(0, 2); // first 2 chars
                        if tc == "CA" {
                            let mut counter = 0u;
                            // struct ID (see DNA_ID.h)
                            let _next = file.read_le_u64();
                            counter += 8;
                            let _prev = file.read_le_u64();
                            counter += 8;
                            let _newid = file.read_le_u64();
                            counter += 8;
                            let _lib = file.read_le_u64();
                            counter += 8;
                            let mut bname = [0u8, ..66];
                            match file.read(bname) {
                                Err(why) => println!("{}", why),
                                Ok(_) => (),
                            }
                            // pack those 66 bytes into a string ...
                            let mut name = String::new();
                            for n in range(0u, 66) {
                                if bname[n] == 0u8 {
                                    // ... but stop as soon as you see '\0'
                                    break;
                                } else {
                                    name.push(bname[n] as char);
                                }
                            }
                            counter += 66;
                            let _flag = file.read_le_u16();
                            counter += 2;
                            let _us = file.read_le_u32();
                            counter += 4;
                            let _icon_id = file.read_le_u32();
                            counter += 4;
                            let _pad2 = file.read_le_u32();
                            counter += 4;
                            let _properties = file.read_le_u64();
                            counter += 8;
                            // struct Camera (see DNA_camera_types.h)
                            let _adt = file.read_le_u64();
                            counter += 8;
                            let io_result = file.read_u8();
                            let cam_type: u8 = io_result.unwrap();
                            counter += 1;
                            let _dtx = file.read_u8();
                            counter += 1;
                            let _flag = file.read_le_u16();
                            counter += 2;
                            let _passepartalpha = file.read_le_f32();
                            counter += 4;
                            let _clipsta = file.read_le_f32();
                            counter += 4;
                            let _clipend = file.read_le_f32();
                            counter += 4;
                            let io_result = file.read_le_f32();
                            let lens: f32 = io_result.unwrap();
                            counter += 4;
                            let _dummy = file.read_exact(len - counter);
                            if cam_type == 0u8 {
                                println!("Camera({}, {}, {})", name, "CAM_PERSP", lens)
                            } else {
                                println!("Camera({}, {}, {})", name, cam_type, lens)
                            }
                        } else {
                            let _dummy = file.read_exact(len);
                        }
                    }
                }
            } else {
                println!("ERROR: not a Blender file.");
            }
        } // file gets closed here
    }
}
<commit_msg>Changes for Rust 1.0 Alpha.<commit_after>use std::io::File;
use std::mem;
use std::num::Int;
use std::os;

// https://stackoverflow.com/questions/24633784/is-there-a-gzip-library-available-for-rust

fn pointer_size() -> usize {
    let tmp = 0u8;
    let boxed = Box::new(tmp);
    mem::size_of_val(&boxed)
}

fn main() {
    let args = os::args();
    if args.len() != 2 {
        println!("usage: read_blend_file /path/to/file.blend");
    } else {
        let slice: &str = args[1].as_slice();
        println!("open \"{}\" ...", slice);
        {
            // read 12 bytes from the Blender file
            let path = Path::new(slice);
            let display = path.display();
            let mut file = match File::open(&path) {
                Err(why) => panic!("couldn't open {}: {}", display, why.desc),
                Ok(file) => file,
            };
            let io_result = file.read_exact(12);
            let buf = io_result.unwrap();
            // pack those 12 bytes into a string ...
            let mut header = String::new();
            for e in buf.iter() {
                header.push(*e as char);
            }
            // ... to be able to compare them
            let slice = header.as_slice();
            let blender: &str = slice.slice(0, 7); // first 7 chars
            if blender == "BLENDER" {
                println!("INFO: a Blender file.");
                let ptr_size = pointer_size();
                println!("size of pointer in bytes: {}", ptr_size);
                println!("Header (12 chars): {}", header);
                let mut ptr_size_differs = false;
                if buf[7] as char == '_' {
                    // 32-bit pointers expected
                    if ptr_size != 4 {
                        ptr_size_differs = true;
                    }
                    println!("32-bit pointers in file, pointer size differs? {}", ptr_size_differs);
                } else {
                    // 64-bit pointers expected
                    if ptr_size != 8 {
                        ptr_size_differs = true;
                    }
                    println!("64-bit pointers in file, pointer size differs? {}", ptr_size_differs);
                }
                // little endian or big endian?
                let mut l_endian;
                let endian_test = 1u16; // value one stored in two bytes
                if endian_test.to_le() != endian_test {
                    l_endian = false;
                } else {
                    // if we are on a little endian machine to_le() is a no-op
                    l_endian = true;
                }
                println!("l_endian = {}", l_endian);
                let mut switch_endian;
                if buf[8] as char == 'v' {
                    // file stores little endian
                    if !l_endian {
                        switch_endian = true;
                    } else {
                        switch_endian = false;
                    }
                } else {
                    // file stores big endian
                    if l_endian {
                        switch_endian = true;
                    } else {
                        switch_endian = false;
                    }
                }
                println!("switch_endian = {}", switch_endian);
                // get the version number
                let num: &str = slice.slice(9, 12); // last 3 chars
                println!("num = {}", num);
                // assumes 64-bit pointers (in file as well as on platform)
                loop {
                    // read_file_dna
                    let io_result = file.read_exact(24); // 4 * int + 64-bit pointer
                    let bhead8 = io_result.unwrap();
                    // pack those 24 bytes into a string ...
                    let mut bhead = String::new();
                    for e in bhead8.iter() {
                        bhead.push(*e as char);
                    }
                    let slice = bhead.as_slice();
                    let code: &str = slice.slice(0, 4); // first 4 chars
                    println!("code = {}", code);
                    let mut len: u32 = 0;
                    len += (bhead8[4] as u32) <<  0;
                    len += (bhead8[5] as u32) <<  8;
                    len += (bhead8[6] as u32) << 16;
                    len += (bhead8[7] as u32) << 24;
                    println!("len = {}", len);
                    if code == "ENDB" && len == 0 {
                        break;
                    } else if code == "DNA1" {
                        // DNA_sdna_from_data
                        let mut counter = 0u32;
                        // SDNA
                        let io_result = file.read_exact(4);
                        let char4 = io_result.unwrap();
                        counter += 4;
                        let mut str4 = String::new();
                        for e in char4.iter() {
                            str4.push(*e as char);
                        }
                        let slice = str4.as_slice();
                        let code: &str = slice.slice(0, 4);
                        println!("  code = {}", code);
                        if code == "SDNA" {
                            // NAME
                            let io_result = file.read_exact(4);
                            let char4 = io_result.unwrap();
                            counter += 4;
                            let mut str4 = String::new();
                            for e in char4.iter() {
                                str4.push(*e as char);
                            }
                            let slice = str4.as_slice();
                            let code: &str = slice.slice(0, 4);
                            println!("  code = {}", code);
                            if code == "NAME" {
                                // nr_names
                                let io_result = file.read_le_u32();
                                let nr_names: u32 = io_result.unwrap();
                                counter += 4;
                                println!("  nr_names = {}", nr_names);
                                let mut nr = 0u32;
                                loop {
                                    let mut name = String::new();
                                    loop {
                                        // expect strings with '\0' as terminator
                                        let io_result = file.read_byte();
                                        let byte: u8 = io_result.unwrap();
                                        counter += 1;
                                        if byte != 0 {
                                            name.push(byte as char);
                                        } else {
                                            println!("    name = '{}'", name);
                                            nr += 1;
                                            break;
                                        }
                                    } // name loop
                                    if nr >= nr_names {
                                        break;
                                    }
                                } // nr_names loop
                                // assume fill bytes with '\0'
                                let mut last_byte;
                                loop {
                                    let io_result = file.read_byte();
                                    let byte: u8 = io_result.unwrap();
                                    counter += 1;
                                    if byte != 0 {
                                        last_byte = byte;
                                        break;
                                    }
                                } // fill bytes
                                // TYPE
                                let io_result = file.read_exact(3);
                                let char3 = io_result.unwrap();
                                counter += 3;
                                let mut str4 = String::new();
                                str4.push(last_byte as char);
                                for e in char3.iter() {
                                    str4.push(*e as char);
                                }
                                let slice = str4.as_slice();
                                let code: &str = slice.slice(0, 4);
                                println!("  code = {}", code);
                                if code == "TYPE" {
                                    // nr_types
                                    let io_result = file.read_le_u32();
                                    let nr_types: u32 = io_result.unwrap();
                                    counter += 4;
                                    println!("  nr_types = {}", nr_types);
                                    let mut nr = 0u32;
                                    loop {
                                        let mut name = String::new();
                                        loop {
                                            // expect strings with
                                            // '\0' as terminator
                                            let io_result = file.read_byte();
                                            let byte: u8 = io_result.unwrap();
                                            counter += 1;
                                            if byte != 0 {
                                                name.push(byte as char);
                                            } else {
                                                println!("    type = '{}'",
                                                         name);
                                                nr += 1;
                                                break;
                                            }
                                        } // type loop
                                        if nr >= nr_types {
                                            break;
                                        }
                                    } // nr_types loop
                                    // assume fill bytes with '\0'
                                    let mut last_byte;
                                    loop {
                                        let io_result = file.read_byte();
                                        let byte: u8 = io_result.unwrap();
                                        counter += 1;
                                        if byte != 0 {
                                            last_byte = byte;
                                            break;
                                        }
                                    } // fill bytes
                                    // TLEN
                                    let io_result = file.read_exact(3);
                                    let char3 = io_result.unwrap();
                                    counter += 3;
                                    let mut str4 = String::new();
                                    str4.push(last_byte as char);
                                    for e in char3.iter() {
                                        str4.push(*e as char);
                                    }
                                    let slice = str4.as_slice();
                                    let code: &str = slice.slice(0, 4);
                                    println!("  code = {}", code);
                                    if code == "TLEN" {
                                        // typelens
                                        let io_result = file.read_le_u16();
                                        let typelens: u16 = io_result.unwrap();
                                        counter += 2;
                                        println!("    typelens = {}", typelens);
                                        // skip nr_types times u16 values
                                        let _dummy = file.read_exact((2u32 *
                                                                     nr_types) as
                                                                     usize);
                                        counter += 2u32 * nr_types as u32;
                                        // check next byte
                                        let io_result = file.read_byte();
                                        last_byte = io_result.unwrap();
                                        counter += 1;
                                        if last_byte == 0 {
                                            let io_result = file.read_byte();
                                            last_byte = io_result.unwrap();
                                            counter += 1;
                                        }
                                        // STRC
                                        let io_result = file.read_exact(3);
                                        let char3 = io_result.unwrap();
                                        counter += 3;
                                        let mut str4 = String::new();
                                        str4.push(last_byte as char);
                                        for e in char3.iter() {
                                            str4.push(*e as char);
                                        }
                                        let slice = str4.as_slice();
                                        let code: &str = slice.slice(0, 4);
                                        println!("  code = {}", code);
                                        if code == "STRC" {
                                            // nr_structs
                                            let io_result = file.read_le_u32();
                                            let nr_structs: u32 = io_result.unwrap();
                                            counter += 4;
                                            println!("    nr_structs = {}", nr_structs);
                                            nr = 0u32;
                                            loop {
                                                // sp0
                                                let io_result = file.read_le_u16();
                                                let _sp0: u16 = io_result.unwrap();
                                                counter += 2;
                                                // sp1
                                                let io_result = file.read_le_u16();
                                                let sp1: u16 = io_result.unwrap();
                                                counter += 2;
                                                for _n in range(0u16, 2 * sp1) {
                                                    let io_result = file.read_le_u16();
                                                    let _u: u16 = io_result.unwrap();
                                                    counter += 2;
                                                }
                                                nr += 1;
                                                if nr >= nr_structs {
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        // read remaining stuff
                        println!("skip {} bytes", len - counter);
                        let _dummy = file.read_exact((len - counter) as usize);
                    } else {
                        let tc: &str = slice.slice(0, 2); // first 2 chars
                        if tc == "CA" {
                            let mut counter = 0u32;
                            // struct ID (see DNA_ID.h)
                            let _next = file.read_le_u64();
                            counter += 8;
                            let _prev = file.read_le_u64();
                            counter += 8;
                            let _newid = file.read_le_u64();
                            counter += 8;
                            let _lib = file.read_le_u64();
                            counter += 8;
                            let io_result = file.read_exact(66);
                            let bname = io_result.unwrap();
                            // pack those 66 bytes into a string ...
                            let mut name = String::new();
                            for e in bname.iter() {
                                if *e == 0u8 {
                                    // ... but stop as soon as you see '\0'
                                    break;
                                } else {
                                    name.push(*e as char);
                                }
                            }
                            counter += 66;
                            let _flag = file.read_le_u16();
                            counter += 2;
                            let _us = file.read_le_u32();
                            counter += 4;
                            let _icon_id = file.read_le_u32();
                            counter += 4;
                            let _pad2 = file.read_le_u32();
                            counter += 4;
                            let _properties = file.read_le_u64();
                            counter += 8;
                            // struct Camera (see DNA_camera_types.h)
                            let _adt = file.read_le_u64();
                            counter += 8;
                            let io_result = file.read_u8();
                            let cam_type: u8 = io_result.unwrap();
                            counter += 1;
                            let _dtx = file.read_u8();
                            counter += 1;
                            let _flag = file.read_le_u16();
                            counter += 2;
                            let _passepartalpha = file.read_le_f32();
                            counter += 4;
                            let _clipsta = file.read_le_f32();
                            counter += 4;
                            let _clipend = file.read_le_f32();
                            counter += 4;
                            let io_result = file.read_le_f32();
                            let lens: f32 = io_result.unwrap();
                            counter += 4;
                            let _dummy = file.read_exact((len - counter) as usize);
                            if cam_type == 0u8 {
                                println!("Camera({}, {}, {})", name, "CAM_PERSP", lens)
                            } else {
                                println!("Camera({}, {}, {})", name, cam_type, lens)
                            }
                        } else {
                            let _dummy = file.read_exact(len as usize);
                        }
                    }
                }
            } else {
                println!("ERROR: not a Blender file.");
            }
        } // file gets closed here
    }
}
<|endoftext|>


<commit_before>use std::result::Result;
pub trait ProgramFragment {
    fn run(&self) -> Result<(), String>;
}

pub trait ConfigurableProgram<T:ProgramFragment> {
    fn set_flag(&mut self, key:String, value:bool) -> &mut Self;
    fn set_arg(&mut self, key:String, value:String) -> &mut Self;
    fn config(&self) -> T;
}
<commit_msg>Added comment to ConfigurableProgram advising Panic for non-recoverable config error<commit_after>use std::result::Result;
pub trait ProgramFragment {
    fn run(&self) -> Result<(), String>;
}

pub trait ConfigurableProgram<T:ProgramFragment> {
    fn set_flag(&mut self, key:String, value:bool) -> &mut Self;
    fn set_arg(&mut self, key:String, value:String) -> &mut Self;
    fn config(&self) -> T; // Should panic on incorrectly defined Programs, User cannot recover
}
<|endoftext|>


<commit_before>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// error-pattern:fail

extern mod std;
use std::map;
use std::map::HashMap;

fn main() {
    let count = @mut 0u;
    let map = map::HashMap();
    let mut arr = ~[];
    for uint::range(0u, 10u) |i| {
        arr += ~[@~"key stuff"];
        map.insert(arr, arr + ~[@~"value stuff"]);
        if arr.len() == 5 {
            fail;
        }
    }
}
<commit_msg>Fix broken tests<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// error-pattern:fail

extern mod std;
use std::map;
use std::map::HashMap;

fn main() {
    let count = @mut 0u;
    let map = map::HashMap();
    let mut arr = ~[];
    for uint::range(0u, 10u) |i| {
        arr += ~[@~"key stuff"];
        map.insert(copy arr, arr + ~[@~"value stuff"]);
        if arr.len() == 5 {
            fail;
        }
    }
}
<|endoftext|>


<commit_before>use error::Error;
use serde::de::Deserialize;
use serde_json;
use std::collections::HashMap;
use chrono::*;

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Level {
    pub ok: bool,
    #[serde(rename="instanceId")]
    pub instance_id: i64,
    pub account: String,
    pub instructions: HashMap<String, String>,
    pub tickers: Vec<String>,
    pub venues: Vec<String>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct HeartBeatResponse {
    pub ok: bool,
    pub error: String,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct VenueHeartBeatResponse {
    pub ok: bool,
    pub venue: String,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct StockListResponse {
    pub ok: bool,
    pub symbols: Vec<StockSymbol>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct StockSymbol {
    pub name: String,
    pub symbol: String,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct OrderbookResponse {
    pub ok: bool,
    pub venue: String,
    pub symbol: String,
    pub bids: Option<Vec<BidAsk>>,
    pub asks: Option<Vec<BidAsk>>,
    pub ts: String,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct BidAsk {
    pub price: u64,
    pub qty: u64,
    #[serde(rename="isBuy")]
    pub is_buy: bool,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct QuoteResponse {
    pub ok: bool,
    pub symbol: String,
    pub venue: String,
    pub bid: Option<u64>,
    pub ask: Option<u64>,
    #[serde(rename="bidSize")]
    pub bid_size: u64,
    #[serde(rename="askSize")]
    pub ask_size: u64,
    #[serde(rename="bidDepth")]
    pub bid_depth: u64,
    #[serde(rename="askDepth")]
    pub ask_depth: u64,
    pub last: Option<u64>,
    #[serde(rename="lastSize")]
    pub last_size: Option<u64>,
    #[serde(rename="lastTrade")]
    pub last_trade: Option<DateTime<UTC>>,
    #[serde(rename="quoteTime")]
    pub quote_time: Option<DateTime<UTC>>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Order {
    pub account: String,
    pub venue: String,
    pub stock: String,
    pub price: u64,
    pub qty: u64,
    // [TODO]: Come back and make this type safe. - 2016-05-20 10:42P
    pub direction: String,
    #[serde(rename="orderType")]
    pub order_type: String,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct OrderResponse {
    pub ok: bool,
    pub symbol: String,
    pub venue: String,
    pub direction: Option<String>,
    #[serde(rename="originalQty")]
    pub original_qty: u64,
    pub qty: u64,
    pub price: u64,
    #[serde(rename="orderType")]
    pub order_type: String,
    pub id: u64,
    pub account: String,
    pub ts: DateTime<UTC>,
    pub fills: Vec<Fill>,
    #[serde(rename="totalFilled")]
    pub total_filled: u64,
    pub open: bool,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Fill {
    pub price: u64,
    pub qty: u64,
    pub ts: DateTime<UTC>,
}

pub fn parse_response<T: Deserialize>(buf: &str) -> Result<T, Error> {
    let l: T = try!(serde_json::from_str(&buf));
    Ok(l)
}

#[cfg(test)]
mod tests {
    use super::*;
    use chrono::*;
    use serde_json;
    use std::collections::HashMap;

    #[test]
    fn test_encode_order() {
        let o = Order {
            account: "tstacc".to_string(),
            venue: "testven".to_string(),
            stock: "BOOK".to_string(),
            price: 1000,
            qty: 5000,
            direction: "buy".to_string(),
            order_type: "immediate-or-cancel".to_string(),
        };
        let res = serde_json::to_string(&o).unwrap();
        assert!(res.len() > 0);
    }

    #[test]
    fn test_encode_level_field_names() {
        let l = Level {
            ok: true,
            instance_id: 998,
            account: "tacc".to_string(),
            instructions: HashMap::new(),
            tickers: vec![],
            venues: vec![],
        };
        let res_string = serde_json::to_string(&l).unwrap();
        assert!(res_string.contains("instanceId"));
    }

    #[test]
    fn test_bid_ask_encode_field_name() {
        let ba = BidAsk {
            price: 1009,
            qty: 100,
            is_buy: true,
        };
        let res_string = serde_json::to_string(&ba).unwrap();
        assert!(res_string.contains("isBuy"));
    }

    #[test]
    fn test_quote_response_fieled_name() {
        let qr = QuoteResponse {
            ok: true,
            symbol: "BOOK".to_string(),
            venue: "MYEX".to_string(),
            bid: Some(101),
            ask: Some(105),
            bid_size: 50,
            ask_size: 1,
            bid_depth: 9,
            ask_depth: 9,
            last: Some(102),
            last_size: Some(3),
            last_trade: Some("2015-12-04T09:02:16.680986205Z".parse().unwrap()),
            quote_time: Some("2015-12-04T09:02:16.680986205Z".parse().unwrap()),
        };
        let res_string = serde_json::to_string(&qr).unwrap();
        assert!(res_string.contains("bidSize"));
        assert!(res_string.contains("askSize"));
        assert!(res_string.contains("bidDepth"));
        assert!(res_string.contains("askDepth"));
        assert!(res_string.contains("lastSize"));
        assert!(res_string.contains("lastTrade"));
        assert!(res_string.contains("quoteTime"));
    }

    #[test]
    fn test_order_response_field_name() {
        let or = OrderResponse {
            ok: true,
            direction: None,
            symbol: "BOOK".to_string(),
            venue: "MYEX".to_string(),
            original_qty: 10,
            qty: 9,
            price: 1045,
            order_type: "limit".to_string(),
            id: 99803,
            account: "MYACC".to_string(),
            ts: "2015-12-04T09:02:16.680986205Z".parse().unwrap(),
            fills: vec![],
            total_filled: 1,
            open: true,
        };
        let res_string = serde_json::to_string(&or).unwrap();
        println!("{:?}", res_string);
        assert!(res_string.contains("originalQty"));
        assert!(res_string.contains("orderType"));
        assert!(res_string.contains("totalFilled"));
    }

    #[test]
    fn test_decode_date_time() {
        let dt_one: DateTime<UTC> = "2015-12-04T09:02:16.680986205Z".parse().unwrap();
        println!("dt = {:?}", dt_one);
        let dt_two: DateTime<UTC> = "2015-07-05T22:16:18+00:00".parse().unwrap();
        println!("dt = {:?}", dt_two);
    }

    #[test]
    fn test_decode_order_response() {
        let o_json = "{\"account\": \"testacc\", \"price\": 26382757, \"id\": 2138, \"open\": \
                      false, \"venue\": \"TESTEX\", \"orderType\": \"limit\", \"qty\": 0, \
                      \"direction\": \"buy\", \"fills\": [{\"qty\": 5000, \"ts\": \
                      \"2016-06-02T16:20:53.024563Z\", \"price\": 26382747}], \"totalFilled\": \
                      5000, \"originalQty\": 5000, \"symbol\": \"FOOBAR\", \"ts\": \
                      \"2016-06-02T16:20:53.024542Z\", \"ok\": true}";

        let o: OrderResponse = parse_response(&o_json).unwrap();
        assert!(o.ok);
    }
}
<commit_msg>Make order type and order direction type safe.<commit_after>use error::Error;
use serde::de::Deserialize;
use serde_json;
use std::collections::HashMap;
use chrono::*;
use std::fmt;
use serde;

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Level {
    pub ok: bool,
    #[serde(rename="instanceId")]
    pub instance_id: i64,
    pub account: String,
    pub instructions: HashMap<String, String>,
    pub tickers: Vec<String>,
    pub venues: Vec<String>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct HeartBeatResponse {
    pub ok: bool,
    pub error: String,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct VenueHeartBeatResponse {
    pub ok: bool,
    pub venue: String,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct StockListResponse {
    pub ok: bool,
    pub symbols: Vec<StockSymbol>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct StockSymbol {
    pub name: String,
    pub symbol: String,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct OrderbookResponse {
    pub ok: bool,
    pub venue: String,
    pub symbol: String,
    pub bids: Option<Vec<BidAsk>>,
    pub asks: Option<Vec<BidAsk>>,
    pub ts: String,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct BidAsk {
    pub price: u64,
    pub qty: u64,
    #[serde(rename="isBuy")]
    pub is_buy: bool,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct QuoteResponse {
    pub ok: bool,
    pub symbol: String,
    pub venue: String,
    pub bid: Option<u64>,
    pub ask: Option<u64>,
    #[serde(rename="bidSize")]
    pub bid_size: u64,
    #[serde(rename="askSize")]
    pub ask_size: u64,
    #[serde(rename="bidDepth")]
    pub bid_depth: u64,
    #[serde(rename="askDepth")]
    pub ask_depth: u64,
    pub last: Option<u64>,
    #[serde(rename="lastSize")]
    pub last_size: Option<u64>,
    #[serde(rename="lastTrade")]
    pub last_trade: Option<DateTime<UTC>>,
    #[serde(rename="quoteTime")]
    pub quote_time: Option<DateTime<UTC>>,
}

#[derive(Debug, Clone)]
pub enum OrderDirection {
    Buy,
    Sell,
}

impl fmt::Display for OrderDirection {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let s = match self {
            &OrderDirection::Buy => "buy",
            &OrderDirection::Sell => "sell",
        };
        write!(f, "{}", s)
    }
}

impl serde::Serialize for OrderDirection {
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: serde::Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl serde::Deserialize for OrderDirection {
    fn deserialize<D>(deserializer: &mut D) -> Result<OrderDirection, D::Error>
        where D: serde::de::Deserializer
    {
        struct OrderDirectionVisitor;

        impl serde::de::Visitor for OrderDirectionVisitor {
            type Value = OrderDirection;

            fn visit_str<E>(&mut self, value: &str) -> Result<OrderDirection, E>
                where E: serde::de::Error
            {
                match value {
                    "buy" => Ok(OrderDirection::Buy),
                    "sell" => Ok(OrderDirection::Sell),
                    _ => Err(serde::de::Error::custom("expected Buy or Sell")),
                }
            }
        }

        deserializer.deserialize(OrderDirectionVisitor)
    }
}

#[derive(Debug, Clone)]
pub enum OrderType {
    Limit,
    Market,
    FillOrKill,
    ImmediateOrCancel,
}

impl fmt::Display for OrderType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let s = match self {
            &OrderType::Market => "market",
            &OrderType::Limit => "limit",
            &OrderType::FillOrKill => "fill-or-kill",
            &OrderType::ImmediateOrCancel => "immediate-or-cancel",

        };
        write!(f, "{}", s)
    }
}

impl serde::Serialize for OrderType {
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: serde::Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl serde::Deserialize for OrderType {
    fn deserialize<D>(deserializer: &mut D) -> Result<OrderType, D::Error>
        where D: serde::de::Deserializer
    {
        struct OrderTypeVisitor;

        impl serde::de::Visitor for OrderTypeVisitor {
            type Value = OrderType;

            fn visit_str<E>(&mut self, value: &str) -> Result<OrderType, E>
                where E: serde::de::Error
            {
                match value {
                    "limit" => Ok(OrderType::Limit),
                    "market" => Ok(OrderType::Market),
                    "fill-or-kill" => Ok(OrderType::FillOrKill),
                    "immediate-or-cancel" => Ok(OrderType::ImmediateOrCancel),
                    _ => Err(serde::de::Error::custom("expected known order type")),
                }
            }
        }

        deserializer.deserialize(OrderTypeVisitor)
    }
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Order {
    pub account: String,
    pub venue: String,
    pub stock: String,
    pub price: u64,
    pub qty: u64,
    pub direction: OrderDirection,
    #[serde(rename="orderType")]
    pub order_type: OrderType,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct OrderResponse {
    pub ok: bool,
    pub symbol: String,
    pub venue: String,
    pub direction: Option<OrderDirection>,
    #[serde(rename="originalQty")]
    pub original_qty: u64,
    pub qty: u64,
    pub price: u64,
    #[serde(rename="orderType")]
    pub order_type: OrderType,
    pub id: u64,
    pub account: String,
    pub ts: DateTime<UTC>,
    pub fills: Vec<Fill>,
    #[serde(rename="totalFilled")]
    pub total_filled: u64,
    pub open: bool,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Fill {
    pub price: u64,
    pub qty: u64,
    pub ts: DateTime<UTC>,
}

pub fn parse_response<T: Deserialize>(buf: &str) -> Result<T, Error> {
    let l: T = try!(serde_json::from_str(&buf));
    Ok(l)
}

#[cfg(test)]
mod tests {
    use super::*;
    use chrono::*;
    use serde_json;
    use std::collections::HashMap;

    #[test]
    fn test_encode_order() {
        let o = Order {
            account: "tstacc".to_string(),
            venue: "testven".to_string(),
            stock: "BOOK".to_string(),
            price: 1000,
            qty: 5000,
            direction: OrderDirection::Buy,
            order_type: OrderType::ImmediateOrCancel,
        };
        let res = serde_json::to_string(&o).unwrap();
        assert!(res.len() > 0);
    }

    #[test]
    fn test_encode_level_field_names() {
        let l = Level {
            ok: true,
            instance_id: 998,
            account: "tacc".to_string(),
            instructions: HashMap::new(),
            tickers: vec![],
            venues: vec![],
        };
        let res_string = serde_json::to_string(&l).unwrap();
        assert!(res_string.contains("instanceId"));
    }

    #[test]
    fn test_bid_ask_encode_field_name() {
        let ba = BidAsk {
            price: 1009,
            qty: 100,
            is_buy: true,
        };
        let res_string = serde_json::to_string(&ba).unwrap();
        assert!(res_string.contains("isBuy"));
    }

    #[test]
    fn test_quote_response_fieled_name() {
        let qr = QuoteResponse {
            ok: true,
            symbol: "BOOK".to_string(),
            venue: "MYEX".to_string(),
            bid: Some(101),
            ask: Some(105),
            bid_size: 50,
            ask_size: 1,
            bid_depth: 9,
            ask_depth: 9,
            last: Some(102),
            last_size: Some(3),
            last_trade: Some("2015-12-04T09:02:16.680986205Z".parse().unwrap()),
            quote_time: Some("2015-12-04T09:02:16.680986205Z".parse().unwrap()),
        };
        let res_string = serde_json::to_string(&qr).unwrap();
        assert!(res_string.contains("bidSize"));
        assert!(res_string.contains("askSize"));
        assert!(res_string.contains("bidDepth"));
        assert!(res_string.contains("askDepth"));
        assert!(res_string.contains("lastSize"));
        assert!(res_string.contains("lastTrade"));
        assert!(res_string.contains("quoteTime"));
    }

    #[test]
    fn test_order_response_field_name() {
        let or = OrderResponse {
            ok: true,
            direction: None,
            symbol: "BOOK".to_string(),
            venue: "MYEX".to_string(),
            original_qty: 10,
            qty: 9,
            price: 1045,
            order_type: OrderType::Limit,
            id: 99803,
            account: "MYACC".to_string(),
            ts: "2015-12-04T09:02:16.680986205Z".parse().unwrap(),
            fills: vec![],
            total_filled: 1,
            open: true,
        };
        let res_string = serde_json::to_string(&or).unwrap();
        println!("{:?}", res_string);
        assert!(res_string.contains("originalQty"));
        assert!(res_string.contains("orderType"));
        assert!(res_string.contains("totalFilled"));
    }

    #[test]
    fn test_decode_date_time() {
        let dt_one: DateTime<UTC> = "2015-12-04T09:02:16.680986205Z".parse().unwrap();
        println!("dt = {:?}", dt_one);
        let dt_two: DateTime<UTC> = "2015-07-05T22:16:18+00:00".parse().unwrap();
        println!("dt = {:?}", dt_two);
    }

    #[test]
    fn test_decode_order_response() {
        let o_json = "{\"account\": \"testacc\", \"price\": 26382757, \"id\": 2138, \"open\": \
                      false, \"venue\": \"TESTEX\", \"orderType\": \"limit\", \"qty\": 0, \
                      \"direction\": \"buy\", \"fills\": [{\"qty\": 5000, \"ts\": \
                      \"2016-06-02T16:20:53.024563Z\", \"price\": 26382747}], \"totalFilled\": \
                      5000, \"originalQty\": 5000, \"symbol\": \"FOOBAR\", \"ts\": \
                      \"2016-06-02T16:20:53.024542Z\", \"ok\": true}";

        let o: OrderResponse = parse_response(&o_json).unwrap();
        assert!(o.ok);
    }
}
<|endoftext|>


<commit_before>use std::fmt::{Display, Formatter, Error};

#[derive(Debug, PartialEq)]
pub struct PerElem {
    pub name: String,
    pub coef: u32,
    pub pos: usize,
    pub len: usize,
}

pub type Molecule = Vec<PerElem>;

/// Sorts the PerElems and groups those with the same name field.
///
/// Grouping of two (or more) PerElems means adding the coef field of the
/// duplicate to the one already found, and then throwing away the duplicate.
/// E.g. CH3CH3 would turn into C2H6.
pub fn group_elems(mut molecule: Molecule) -> Molecule {
    let mut out = Vec::<PerElem>::new();
    molecule.as_mut_slice().sort_by(|a, b| a.name.cmp(&b.name));
    // since the elements are now sorted, if the current elem does not match the
    // last element in out (i.e. what we previously pushed), then it won't match
    // anything in out
    for elem in molecule.into_iter() {
        if out.last().and_then(|e| Some(e.name == elem.name)).unwrap_or(false) {
            out.last_mut().unwrap().coef += elem.coef;
        } else {
            out.push(elem);
        }
    }
    out
}

impl Display for Molecule {
    fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
        for elem in self.iter() {
            fmt.write_str(elem.name.as_slice());
            // TODO: Use a proper conversion function -- if it exists
            fmt.write_str(format!("{}", elem.coef).as_slice());
        }
        Ok(())
    }
}

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

    macro_rules! dummy_elem(
        ($name:expr) => (
            PerElem { name: $name.to_string(), coef: 1, pos: 0, len: 1 }
        );
        ($name:expr, $coef:expr) => (
            PerElem { name: $name.to_string(), coef: $coef, pos: 0, len: 1 }
        );
    );

    #[test]
    fn group() {
        let result = group_elems(vec!(dummy_elem!("C"), dummy_elem!("H"), dummy_elem!("C")));
        let expected = vec!(dummy_elem!("C", 2), dummy_elem!("H", 1));
        assert_eq!(result, expected);
    }

    #[test]
    fn molecule_display() {
        let molecule = vec!(dummy_elem!("C", 2), dummy_elem!("H", 3));
        let result = format!("{}", molecule);
        let expected = "C2H3";
        assert_eq!(result, expected);
    }
}<commit_msg>Small change in Molecule pretty printing<commit_after>use std::fmt::{Display, Formatter, Error};

#[derive(Debug, PartialEq)]
pub struct PerElem {
    pub name: String,
    pub coef: u32,
    pub pos: usize,
    pub len: usize,
}

pub type Molecule = Vec<PerElem>;

/// Sorts the PerElems and groups those with the same name field.
///
/// Grouping of two (or more) PerElems means adding the coef field of the
/// duplicate to the one already found, and then throwing away the duplicate.
/// E.g. CH3CH3 would turn into C2H6.
pub fn group_elems(mut molecule: Molecule) -> Molecule {
    let mut out = Vec::<PerElem>::new();
    molecule.as_mut_slice().sort_by(|a, b| a.name.cmp(&b.name));
    // since the elements are now sorted, if the current elem does not match the
    // last element in out (i.e. what we previously pushed), then it won't match
    // anything in out
    for elem in molecule.into_iter() {
        if out.last().and_then(|e| Some(e.name == elem.name)).unwrap_or(false) {
            out.last_mut().unwrap().coef += elem.coef;
        } else {
            out.push(elem);
        }
    }
    out
}

impl Display for Molecule {
    fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
        for elem in self.iter() {
            fmt.write_str(elem.name.as_slice());
            // TODO: Use a proper conversion function -- if it exists
            if elem.coef > 1 {
                fmt.write_str(format!("{}", elem.coef).as_slice());
            }
        }
        Ok(())
    }
}

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

    macro_rules! dummy_elem(
        ($name:expr) => (
            PerElem { name: $name.to_string(), coef: 1, pos: 0, len: 1 }
        );
        ($name:expr, $coef:expr) => (
            PerElem { name: $name.to_string(), coef: $coef, pos: 0, len: 1 }
        );
    );

    #[test]
    fn group() {
        let result = group_elems(vec!(dummy_elem!("C"), dummy_elem!("H"), dummy_elem!("C")));
        let expected = vec!(dummy_elem!("C", 2), dummy_elem!("H", 1));
        assert_eq!(result, expected);
    }

    #[test]
    fn molecule_display() {
        let molecule = vec!(dummy_elem!("C", 2), dummy_elem!("H", 3));
        let result = format!("{}", molecule);
        let expected = "C2H3";
        assert_eq!(result, expected);
    }
}<|endoftext|>


<commit_before>//! Two-step verfication of HOTP algorithm.
//!
//! # Example
//!
//! ```
//! extern crate otpauth;
//!
//! fn main() {
//!     let auth = otpauth::HOTP::new("python");
//!     let code = auth.generate(4);
//!     assert_eq!(true, auth.verify(code, 0, 100));
//! }
//! ```
//!
use std::io::Cursor;

use crypto::digest::Digest;
use crypto::mac::Mac;
use crypto::hmac::Hmac;
use crypto::sha1::Sha1;
use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};

pub struct HOTP {
    /// A secret token for the authentication
    pub secret: String,
}

impl HOTP {
    /// Constructs a new `HOTP`
    pub fn new(secret: &str) -> HOTP {
        HOTP {
            secret: secret.to_string(),
        }
    }

    /// Generate a HOTP code.
    ///
    /// ``counter``: HOTP is a counter based algorithm.
    pub fn generate(&self, counter: usize) -> u32 {
        // Init Hmac
        let key = self.secret.clone().into_bytes();
        let mut hmac = Hmac::new(Sha1::new(), &key[..]);
        // Calc msg
        let mut wtr = vec![];
        // supress warning about unused_must_use
        let _ = wtr.write_u64::<BigEndian>(counter as u64);
        hmac.input(&wtr[..]);
        // Get digest
        let result = hmac.result();
        let digest = result.code();
        let ob = digest[19];
        let pos: usize = (ob & 15) as usize;
        let mut rdr = Cursor::new(digest[pos..pos+4].to_vec());
        let base = rdr.read_u32::<BigEndian>().unwrap() & 0x7fffffff;
        base % 1000000
    }

    /// Valid a HOTP code.
    ///
    /// ``code``: A number that is less than 6 characters.
    ///
    /// ``last``: Guess HOTP code from ``last + 1`` range.
    ///
    /// ``trials``: Guest HOTP code end at ``last + trials + 1``.
    pub fn verify(&self, code: u32, last: usize, trials: usize) -> bool {
        let code_str = code.to_string();
        let code_bytes = code_str.as_bytes();
        if code_bytes.len() > 6 {
            return false;
        }
        for i in last+1..last+trials+1 {
            let valid_code = self.generate(i).to_string();
            let valid_bytes = valid_code.as_bytes();
            if code_bytes.len() != valid_code.len() {
                continue;
            }
            let mut rv = 0;
            for (a, b) in code_bytes.iter().zip(valid_bytes.iter()) {
                rv |= a ^ b;
            }
            if rv == 0 {
                return true;
            }
        }
        false
    }

    /// Generate the otpauth protocal string.
    ///
    /// ``label``: Label of the identifier.
    ///
    /// ``issuer``: The company, the organization or something else.
    ///
    /// ``counter``: Counter of the HOTP algorithm.
    pub fn to_uri(&self, label: &str, issuer: &str, counter: usize) -> String {
        use base32::encode;
        use base32::Alphabet::RFC4648;

        let encoded_secret = encode(RFC4648 { padding: false }, self.secret.as_bytes());
        format!("otpauth://hotp/{}?secret={}&issuer={}&counter={}", label, encoded_secret, issuer, counter)
    }
}
<commit_msg>Typo fix.<commit_after>//! Two-step verfication of HOTP algorithm.
//!
//! # Example
//!
//! ```
//! extern crate otpauth;
//!
//! fn main() {
//!     let auth = otpauth::HOTP::new("python");
//!     let code = auth.generate(4);
//!     assert_eq!(true, auth.verify(code, 0, 100));
//! }
//! ```
//!
use std::io::Cursor;

use crypto::digest::Digest;
use crypto::mac::Mac;
use crypto::hmac::Hmac;
use crypto::sha1::Sha1;
use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};

pub struct HOTP {
    /// A secret token for the authentication
    pub secret: String,
}

impl HOTP {
    /// Constructs a new `HOTP`
    pub fn new(secret: &str) -> HOTP {
        HOTP {
            secret: secret.to_string(),
        }
    }

    /// Generate a HOTP code.
    ///
    /// ``counter``: HOTP is a counter based algorithm.
    pub fn generate(&self, counter: usize) -> u32 {
        // Init Hmac
        let key = self.secret.clone().into_bytes();
        let mut hmac = Hmac::new(Sha1::new(), &key[..]);
        // Calc msg
        let mut wtr = vec![];
        // supress warning about unused_must_use
        let _ = wtr.write_u64::<BigEndian>(counter as u64);
        hmac.input(&wtr[..]);
        // Get digest
        let result = hmac.result();
        let digest = result.code();
        let ob = digest[19];
        let pos: usize = (ob & 15) as usize;
        let mut rdr = Cursor::new(digest[pos..pos+4].to_vec());
        let base = rdr.read_u32::<BigEndian>().unwrap() & 0x7fffffff;
        base % 1000000
    }

    /// Valid a HOTP code.
    ///
    /// ``code``: A number that is less than 6 characters.
    ///
    /// ``last``: Guess HOTP code from ``last + 1`` range.
    ///
    /// ``trials``: Guess HOTP code end at ``last + trials + 1``.
    pub fn verify(&self, code: u32, last: usize, trials: usize) -> bool {
        let code_str = code.to_string();
        let code_bytes = code_str.as_bytes();
        if code_bytes.len() > 6 {
            return false;
        }
        for i in last+1..last+trials+1 {
            let valid_code = self.generate(i).to_string();
            let valid_bytes = valid_code.as_bytes();
            if code_bytes.len() != valid_code.len() {
                continue;
            }
            let mut rv = 0;
            for (a, b) in code_bytes.iter().zip(valid_bytes.iter()) {
                rv |= a ^ b;
            }
            if rv == 0 {
                return true;
            }
        }
        false
    }

    /// Generate the otpauth protocal string.
    ///
    /// ``label``: Label of the identifier.
    ///
    /// ``issuer``: The company, the organization or something else.
    ///
    /// ``counter``: Counter of the HOTP algorithm.
    pub fn to_uri(&self, label: &str, issuer: &str, counter: usize) -> String {
        use base32::encode;
        use base32::Alphabet::RFC4648;

        let encoded_secret = encode(RFC4648 { padding: false }, self.secret.as_bytes());
        format!("otpauth://hotp/{}?secret={}&issuer={}&counter={}", label, encoded_secret, issuer, counter)
    }
}
<|endoftext|>


<commit_before><commit_msg>Use fmt::Write trait instead of fmt::Formatter<commit_after><|endoftext|>


<commit_before>//!
//!	Temporary experimental code.
//!
extern crate rust_htslib as htslib;
use self::htslib::bam;
use self::htslib::bam::Read;
use self::htslib::bam::Reader;
use self::htslib::bam::Records;
use std::collections::BTreeMap;
use std::iter::Peekable;

#[derive(Debug)]
struct SequencePileUp {
    chrom: String,
    counts: BTreeMap<u32, (f64, f64)>
}

impl SequencePileUp {
    // some constructor that takes CountsTable, SeqTable data and BAM files
    // processes the data corresponding to a single sequence and returns a
    // new fully built pileUp

    // op to write pile up into BED file
}

//#[derive(Debug)]
struct BAMSource<'a> {
    bam_set: Vec<Peekable<Records<'a, Reader>>>,
    index: usize,
    id: i32,         // sequence ID inside BAM files ... this may not work ...
    map: Vec<usize>, // map from BAM IDs to SeqTable IDs
}

// The idea of BAMSource is to create a global iterator over Records<Reader>
// that will read all BAM records from a sequence from all input BAM files,
// before moving to the next sequence.
// Want a sort of iterator of iterators

// Basic assumption is that sequences are in order...??

// issues: what happens if not all BAM files have data on all sequences ?
//         do BAM file sequence IDs match across BAM files? probably not!
//         need to create a unified ID table ???

// given a list of input chromosomes:
// - scan BAM headers to map the tid of each one to the chromosome map
// - start with the smallest global id
<commit_msg>Remove incorrectly uploaded temporary file<commit_after><|endoftext|>