<commit_before>use std::string;
use std::str::MaybeOwned;
use std::collections::TreeMap;

#[deriving(Show, PartialEq, Eq)]
pub enum FormatParseError {
    EmptyFormat,
    InvalidAtom(MaybeOwned<'static>)
}
pub type FormatResult<T> = Result<T, FormatParseError>;

#[deriving(Show, PartialEq, Eq)]
pub enum ValueParseError {
    BadFormat,
}
pub type ValueResult<T> = Result<T, ValueParseError>;

#[deriving(Show, PartialEq, Eq, Clone, Copy)]
pub enum FormatKind {
    Unspecified,
    String,
    WholeNumeric
}

#[deriving(Show, PartialEq, Eq, Clone)]
pub enum Atom {
    // LiteralAtom(value)
    LiteralAtom(string::String),
    // FormattedAtom(name, kind)
    FormattedAtom(string::String, FormatKind),
    // RestAtom(name)
    RestAtom(string::String),
}

#[deriving(Show, PartialEq, Eq, Clone)]
pub enum Value {
    StringValue(string::String),
    WholeNumericValue(u64)
}

impl Value {
    fn parse(kind: FormatKind, input: &str) -> ValueResult<Value> {
        match kind {
            Unspecified => Ok(StringValue(input.to_string())),
            String => Ok(StringValue(input.to_string())),
            WholeNumeric => match from_str(input) {
                Some(val) => Ok(WholeNumericValue(val)),
                None => Err(BadFormat)
            }
        }
    }
}

impl Atom {
    pub fn get_name<'a>(&'a self) -> Option<&'a str> {
        match *self {
            LiteralAtom(_) => None,
            FormattedAtom(ref name, _) => Some(name[]),
            RestAtom(ref name) => Some(name[]),
        }
    }

    fn parse(&self, input: &str) -> FormatResult<Option<Value>> {
        let value_res = match *self {
            LiteralAtom(_) => None,
            FormattedAtom(_, kind) => Some(Value::parse(kind, input)),
            RestAtom(_) => Some(Value::parse(String, input)),
        };
        match (self.get_name(), value_res) {
            (Some(_), Some(Ok(value))) => {
                Ok(Some(value))
            },
            (Some(name), Some(Err(val_err))) => {
                Err(InvalidAtom(format!(
                    "atom {} invalid: {}",
                    name[], val_err
                ).into_maybe_owned()))
            },
            (Some(_), None) => unreachable!(),
            (None, _) => Ok(None)
        }
    }
}

#[deriving(Show)]
pub struct Format {
    atoms: Vec<Atom>
}

impl Format {
    pub fn get_command<'a>(&'a self) -> &'a str {
        match self.atoms[0] {
            LiteralAtom(ref literal) => literal[],
            _ => fail!("Malformed Format")
        }
    }
}

#[deriving(Show, Clone)]
pub struct CommandPhrase {
    pub command: string::String,
    pub original_command: string::String,
    pub args: TreeMap<string::String, Value>
}

#[inline]
fn get_token<'a>(input: &'a str) -> (&'a str, &'a str) {
    match input.find(' ') {
        Some(idx) => {
            let mut rest = input[idx+1..];
            while rest.starts_with(" ") {
                rest = rest[1..];
            }
            (input[..idx], rest)
        },
        None => (input, input[input.len()..])
    }
}

impl Format {
    // If true, this Format may (or may not) match the given input.
    // If false, this Format definitely does not match the given input.
    pub fn matches_maybe(&self, input: &str) -> bool {
        let (command, _) = get_token(input);
        command == self.get_command()
    }

    pub fn from_str(definition: &str) -> FormatResult<Format> {
        if definition == "" {
            return Err(EmptyFormat)
        }
        let mut format = Format { atoms: vec![] };
        for node in definition.split(' ') {
            match parse_atom(node) {
                Ok(atom) => format.atoms.push(atom),
                Err(err) => return Err(err)
            };
        }
        match format.atoms[0] {
            LiteralAtom(ref literal) => {
                literal.to_string()
            },
            _ => return Err(InvalidAtom(
                "first atom must be literal".into_maybe_owned()))
        };
        Ok(format)
    }

    pub fn parse(&self, input: &str) -> FormatResult<Option<CommandPhrase>> {
        let original_input = input[];
        let mut input = input[];
        let mut args_map: TreeMap<string::String, Value> = TreeMap::new();

        let command = match self.atoms[0] {
            LiteralAtom(ref literal) => {
                literal.to_string()
            },
            _ => fail!("Malformed Format")
        };

        for atom in self.atoms.iter() {
            match atom {
                &RestAtom(ref name) => {
                    args_map.insert(
                        name.to_string(),
                        StringValue(input.to_string()));
                },
                &LiteralAtom(ref value) => {
                    let (part, input_tmp) = get_token(input);
                    if part != value[] {
                        return Ok(None);
                    }
                    input = input_tmp;
                },
                _ => {
                    let (part, input_tmp) = get_token(input);
                    match (atom.get_name(), atom.parse(part)) {
                        (Some(name), Ok(Some(value))) => {
                            args_map.insert(name.to_string(), value);
                        },
                        (Some(name), Ok(None)) => fail!("named atom with Ok(None) value"),
                        (None, Ok(_)) => (),
                        (_, Err(err)) => return Err(err)
                    };
                    input = input_tmp;
                }
            }

        }
        Ok(Some(CommandPhrase {
            command: command,
            original_command: original_input.to_string(),
            args: args_map,
        }))
    }
}

fn parse_atom(atom: &str) -> FormatResult<Atom> {
    if atom.starts_with("{") {
        if !atom.ends_with("}") {
            return Err(InvalidAtom(
                "atom begins with { but doesn't end with }".into_maybe_owned()));
        }
        let atom = atom[1..atom.len()-1];

        let (name, format_spec) = match atom.find(':') {
            Some(idx) => (atom[..idx], Some(atom[1 + idx ..])),
            None => (atom, None)
        };
        let format_kind = match format_spec {
            Some("") => return Err(
                InvalidAtom("atom has empty format specifier".into_maybe_owned())),
            Some("s") => String,
            Some("d") => WholeNumeric,
            Some(spec) => return Err(InvalidAtom(
                format!("atom has unknown format specifier `{}'", spec).into_maybe_owned())),
            None => Unspecified
        };
        if name.starts_with("*") {
            if format_kind != Unspecified {
                return Err(InvalidAtom(
                    "format specifier not allowed on *atom".into_maybe_owned()));
            }
            return Ok(RestAtom(name[1..].to_string()));
        }
        return Ok(FormattedAtom(name.to_string(), format_kind));
    }
    Ok(LiteralAtom(atom.to_string()))
}

#[test]
fn cons_the_basics() {
    {
        let fmt_str = "articles {foo} {category:s} {id:d}";
        let fmt = match Format::from_str(fmt_str) {
            Ok(fmt) => fmt,
            Err(err) => fail!("parse failure: {}", err)
        };

        assert_eq!(fmt.atoms.len(), 4);
        assert_eq!(
            fmt.atoms[0],
            LiteralAtom("articles".to_string()));
        assert_eq!(
            fmt.atoms[1],
            FormattedAtom("foo".to_string(), Unspecified));
        assert_eq!(
            fmt.atoms[2],
            FormattedAtom("category".to_string(), String));
        assert_eq!(
            fmt.atoms[3],
            FormattedAtom("id".to_string(), WholeNumeric));
    }

    match Format::from_str("") {
        Ok(_) => fail!("empty string must not succeed"),
        Err(EmptyFormat) => (),
        Err(err) => fail!("wrong error for empty: {}", err),
    };

    match Format::from_str("{category:s} articles") {
        Ok(_) => fail!("first atom must be literal"),
        Err(_) => ()
    };

    {
        let fmt_str = "articles {foo} {*rest}";
        let fmt = match Format::from_str(fmt_str) {
            Ok(fmt) => fmt,
            Err(err) => fail!("parse failure: {}", err)
        };
        let cmdlet = match fmt.parse("articles bar test article argument") {
            Ok(cmdlet) => cmdlet,
            Err(err) => fail!("parse failure: {}", err)
        };
        assert_eq!(cmdlet.command[], "articles");
        assert_eq!(
            cmdlet.args["foo".to_string()],
            StringValue("bar".to_string()));
        assert_eq!(
            cmdlet.args["rest".to_string()],
            StringValue("test article argument".to_string()));
    }

}

#[test]
fn parse_the_basics() {
    {
        let cmd_str = "articles my_bar my_category 01234";
        let fmt_str = "articles {foo} {category:s} {id:d}";

        let fmt = match Format::from_str(fmt_str) {
            Ok(fmt) => fmt,
            Err(err) => fail!("parse failure: {}", err)
        };

        assert!(fmt.matches_maybe(cmd_str));

        let cmdlet = match fmt.parse(cmd_str) {
            Ok(cmdlet) => cmdlet,
            Err(err) => fail!("parse failure: {}", err)
        };
        assert_eq!(cmdlet.command[], "articles");
        assert!(cmdlet.args.contains_key(&"foo".to_string()));
        assert!(cmdlet.args.contains_key(&"foo".to_string()));

        assert_eq!(
            cmdlet.args["foo".to_string()],
            StringValue("my_bar".to_string()));

        assert_eq!(
            cmdlet.args["category".to_string()],
            StringValue("my_category".to_string()));
    }
    {
        match Format::from_str("") {
            Ok(_) => fail!("empty string must not succeed"),
            Err(EmptyFormat) => (),
            Err(err) => fail!("wrong error for empty: {}", err),
        };
    }
}<commit_msg>Fix tests<commit_after>use std::string;
use std::str::MaybeOwned;
use std::collections::TreeMap;

#[deriving(Show, PartialEq, Eq)]
pub enum FormatParseError {
    EmptyFormat,
    InvalidAtom(MaybeOwned<'static>)
}
pub type FormatResult<T> = Result<T, FormatParseError>;

#[deriving(Show, PartialEq, Eq)]
pub enum ValueParseError {
    BadFormat,
}
pub type ValueResult<T> = Result<T, ValueParseError>;

#[deriving(Show, PartialEq, Eq, Clone, Copy)]
pub enum FormatKind {
    Unspecified,
    String,
    WholeNumeric
}

#[deriving(Show, PartialEq, Eq, Clone)]
pub enum Atom {
    // LiteralAtom(value)
    LiteralAtom(string::String),
    // FormattedAtom(name, kind)
    FormattedAtom(string::String, FormatKind),
    // RestAtom(name)
    RestAtom(string::String),
}

#[deriving(Show, PartialEq, Eq, Clone)]
pub enum Value {
    StringValue(string::String),
    WholeNumericValue(u64)
}

impl Value {
    fn parse(kind: FormatKind, input: &str) -> ValueResult<Value> {
        match kind {
            Unspecified => Ok(StringValue(input.to_string())),
            String => Ok(StringValue(input.to_string())),
            WholeNumeric => match from_str(input) {
                Some(val) => Ok(WholeNumericValue(val)),
                None => Err(BadFormat)
            }
        }
    }
}

impl Atom {
    pub fn get_name<'a>(&'a self) -> Option<&'a str> {
        match *self {
            LiteralAtom(_) => None,
            FormattedAtom(ref name, _) => Some(name[]),
            RestAtom(ref name) => Some(name[]),
        }
    }

    fn parse(&self, input: &str) -> FormatResult<Option<Value>> {
        let value_res = match *self {
            LiteralAtom(_) => None,
            FormattedAtom(_, kind) => Some(Value::parse(kind, input)),
            RestAtom(_) => Some(Value::parse(String, input)),
        };
        match (self.get_name(), value_res) {
            (Some(_), Some(Ok(value))) => {
                Ok(Some(value))
            },
            (Some(name), Some(Err(val_err))) => {
                Err(InvalidAtom(format!(
                    "atom {} invalid: {}",
                    name[], val_err
                ).into_maybe_owned()))
            },
            (Some(_), None) => unreachable!(),
            (None, _) => Ok(None)
        }
    }
}

#[deriving(Show)]
pub struct Format {
    atoms: Vec<Atom>
}

impl Format {
    pub fn get_command<'a>(&'a self) -> &'a str {
        match self.atoms[0] {
            LiteralAtom(ref literal) => literal[],
            _ => fail!("Malformed Format")
        }
    }
}

#[deriving(Show, Clone)]
pub struct CommandPhrase {
    pub command: string::String,
    pub original_command: string::String,
    pub args: TreeMap<string::String, Value>
}

#[inline]
fn get_token<'a>(input: &'a str) -> (&'a str, &'a str) {
    match input.find(' ') {
        Some(idx) => {
            let mut rest = input[idx+1..];
            while rest.starts_with(" ") {
                rest = rest[1..];
            }
            (input[..idx], rest)
        },
        None => (input, input[input.len()..])
    }
}

impl Format {
    // If true, this Format may (or may not) match the given input.
    // If false, this Format definitely does not match the given input.
    pub fn matches_maybe(&self, input: &str) -> bool {
        let (command, _) = get_token(input);
        command == self.get_command()
    }

    pub fn from_str(definition: &str) -> FormatResult<Format> {
        if definition == "" {
            return Err(EmptyFormat)
        }
        let mut format = Format { atoms: vec![] };
        for node in definition.split(' ') {
            match parse_atom(node) {
                Ok(atom) => format.atoms.push(atom),
                Err(err) => return Err(err)
            };
        }
        match format.atoms[0] {
            LiteralAtom(ref literal) => {
                literal.to_string()
            },
            _ => return Err(InvalidAtom(
                "first atom must be literal".into_maybe_owned()))
        };
        Ok(format)
    }

    pub fn parse(&self, input: &str) -> FormatResult<Option<CommandPhrase>> {
        let original_input = input[];
        let mut input = input[];
        let mut args_map: TreeMap<string::String, Value> = TreeMap::new();

        let command = match self.atoms[0] {
            LiteralAtom(ref literal) => {
                literal.to_string()
            },
            _ => fail!("Malformed Format")
        };

        for atom in self.atoms.iter() {
            match atom {
                &RestAtom(ref name) => {
                    args_map.insert(
                        name.to_string(),
                        StringValue(input.to_string()));
                },
                &LiteralAtom(ref value) => {
                    let (part, input_tmp) = get_token(input);
                    if part != value[] {
                        return Ok(None);
                    }
                    input = input_tmp;
                },
                _ => {
                    let (part, input_tmp) = get_token(input);
                    match (atom.get_name(), atom.parse(part)) {
                        (Some(name), Ok(Some(value))) => {
                            args_map.insert(name.to_string(), value);
                        },
                        (Some(name), Ok(None)) => fail!("named atom with Ok(None) value"),
                        (None, Ok(_)) => (),
                        (_, Err(err)) => return Err(err)
                    };
                    input = input_tmp;
                }
            }

        }
        Ok(Some(CommandPhrase {
            command: command,
            original_command: original_input.to_string(),
            args: args_map,
        }))
    }
}

fn parse_atom(atom: &str) -> FormatResult<Atom> {
    if atom.starts_with("{") {
        if !atom.ends_with("}") {
            return Err(InvalidAtom(
                "atom begins with { but doesn't end with }".into_maybe_owned()));
        }
        let atom = atom[1..atom.len()-1];

        let (name, format_spec) = match atom.find(':') {
            Some(idx) => (atom[..idx], Some(atom[1 + idx ..])),
            None => (atom, None)
        };
        let format_kind = match format_spec {
            Some("") => return Err(
                InvalidAtom("atom has empty format specifier".into_maybe_owned())),
            Some("s") => String,
            Some("d") => WholeNumeric,
            Some(spec) => return Err(InvalidAtom(
                format!("atom has unknown format specifier `{}'", spec).into_maybe_owned())),
            None => Unspecified
        };
        if name.starts_with("*") {
            if format_kind != Unspecified {
                return Err(InvalidAtom(
                    "format specifier not allowed on *atom".into_maybe_owned()));
            }
            return Ok(RestAtom(name[1..].to_string()));
        }
        return Ok(FormattedAtom(name.to_string(), format_kind));
    }
    Ok(LiteralAtom(atom.to_string()))
}

#[test]
fn cons_the_basics() {
    {
        let fmt_str = "articles {foo} {category:s} {id:d}";
        let fmt = match Format::from_str(fmt_str) {
            Ok(fmt) => fmt,
            Err(err) => fail!("parse failure: {}", err)
        };

        assert_eq!(fmt.atoms.len(), 4);
        assert_eq!(
            fmt.atoms[0],
            LiteralAtom("articles".to_string()));
        assert_eq!(
            fmt.atoms[1],
            FormattedAtom("foo".to_string(), Unspecified));
        assert_eq!(
            fmt.atoms[2],
            FormattedAtom("category".to_string(), String));
        assert_eq!(
            fmt.atoms[3],
            FormattedAtom("id".to_string(), WholeNumeric));
    }

    match Format::from_str("") {
        Ok(_) => fail!("empty string must not succeed"),
        Err(EmptyFormat) => (),
        Err(err) => fail!("wrong error for empty: {}", err),
    };

    match Format::from_str("{category:s} articles") {
        Ok(_) => fail!("first atom must be literal"),
        Err(_) => ()
    };

    {
        let fmt_str = "articles {foo} {*rest}";
        let fmt = match Format::from_str(fmt_str) {
            Ok(fmt) => fmt,
            Err(err) => fail!("parse failure: {}", err)
        };
        let cmdlet = match fmt.parse("articles bar test article argument") {
            Ok(Some(cmdlet)) => cmdlet,
            Ok(None) => fail!("doesn't match when it should"),
            Err(err) => fail!("parse failure: {}", err)
        };
        assert_eq!(cmdlet.command[], "articles");
        assert_eq!(
            cmdlet.args["foo".to_string()],
            StringValue("bar".to_string()));
        assert_eq!(
            cmdlet.args["rest".to_string()],
            StringValue("test article argument".to_string()));
    }

}

#[test]
fn parse_the_basics() {
    {
        let cmd_str = "articles my_bar my_category 01234";
        let fmt_str = "articles {foo} {category:s} {id:d}";

        let fmt = match Format::from_str(fmt_str) {
            Ok(fmt) => fmt,
            Err(err) => fail!("parse failure: {}", err)
        };

        assert!(fmt.matches_maybe(cmd_str));

        let cmdlet = match fmt.parse(cmd_str) {
            Ok(Some(cmdlet)) => cmdlet,
            Ok(None) => fail!("doesn't match when it should"),
            Err(err) => fail!("parse failure: {}", err)
        };
        assert_eq!(cmdlet.command[], "articles");
        assert!(cmdlet.args.contains_key(&"foo".to_string()));
        assert!(cmdlet.args.contains_key(&"foo".to_string()));

        assert_eq!(
            cmdlet.args["foo".to_string()],
            StringValue("my_bar".to_string()));

        assert_eq!(
            cmdlet.args["category".to_string()],
            StringValue("my_category".to_string()));
    }
    {
        match Format::from_str("") {
            Ok(_) => fail!("empty string must not succeed"),
            Err(EmptyFormat) => (),
            Err(err) => fail!("wrong error for empty: {}", err),
        };
    }
}<|endoftext|>


<commit_before>extern crate server;
extern crate bincode;
extern crate log;

use server::storage::*;
use bincode::rustc_serialize::{encode_into};
use bincode::SizeLimit;
use server::logger;
use server::parse::ast::DataSrc;

fn main() {

    logger::with_loglevel(::log::LogLevelFilter::Trace)
        .with_logfile(std::path::Path::new("log.txt"))
        .enable().unwrap();

    let ty = SqlType::Int;
    let mut v = Vec::new();
    let _ = encode_into(&ty, &mut v, SizeLimit::Infinite);

    //let db = Database::create("storage_team").unwrap();
    let db = Database::load("storage_team").unwrap();

    let mut cols = Vec::new();
    cols.push(Column {
        name: "Heiner".into(),
        sql_type: SqlType::Int,
        allow_null: false,
        description: "Heiner".to_string(),
        is_primary_key: false,
    });
    cols.push(Column {
        name: "Mathias".into(),
        sql_type: SqlType::Bool,
        allow_null: false,
        description: "Mathias".to_string(),
        is_primary_key: false,
    });
    cols.push(Column {
        name: "Dennis".into(),
        sql_type: SqlType::Char(6),
        allow_null: false,
        description: "Dennis".to_string(),
        is_primary_key: true,
    });

    let mut my_data: Vec<Option<DataSrc>> = Vec::new();
    my_data.push(Some(DataSrc::Int(10)));
    my_data.push(Some(DataSrc::Bool(1)));
    my_data.push(Some(DataSrc::String("sechs".to_string())));
    my_data.push(
        Some(DataSrc::String("i am a very long string, at least i think i am".to_string()))
    );

    let _storage_team = db.create_table("storage_team", cols, 1).unwrap();

    let t = db.load_table("storage_team").unwrap();

    //_type_test();
}

fn _type_test(){
    let my_int: [u8; 4] = [20, 30, 40, 50]; //0001:0100:0001:1110:0010:1000:0011:0010 -> 337520690
    let my_other_int: [u8; 4] = [10, 5, 0, 2];//0000:1010:0000:0101:0000:0000:0000:0010 -> 168099842

    let my_bool: [u8; 3] = [0, 0, 0];
    let my_other_bool: [u8; 3] = [0, 0, 0];

    let my_strin: [u8; 2] = [0, 41];
    let my_other_strin: [u8; 2] = [0, 41];

    let my_sqltype_int = SqlType::Int;
    let my_sqltype_bool = SqlType::Bool;
    let my_sqltype_char = SqlType::Char(7);
    println!("check for int:");

    println!("is equal: {:?}",my_sqltype_int.cmp(&my_int[0..4], &my_other_int[0..4], CompType::Equ).unwrap());
    println!("is not equal: {:?}",my_sqltype_int.cmp(&my_int[0..4], &my_other_int[0..4], CompType::NEqu).unwrap());
    println!("is greater: {:?}",my_sqltype_int.cmp(&my_int[0..4], &my_other_int[0..4], CompType::GThan).unwrap());
    println!("is lesser: {:?}",my_sqltype_int.cmp(&my_int[0..4], &my_other_int[0..4], CompType::SThan).unwrap());
    println!("is greater equal: {:?}",my_sqltype_int.cmp(&my_int[0..4], &my_other_int[0..4], CompType::GEThan).unwrap());
    println!("is lesser equal: {:?}",my_sqltype_int.cmp(&my_int[0..4], &my_other_int[0..4], CompType::SEThan).unwrap());

    println!("check for bool:");
    println!("is equal: {:?}",my_sqltype_bool.cmp(&my_bool[0..3], &my_other_bool[0..3], CompType::Equ).unwrap());
    println!("is not equal: {:?}",my_sqltype_bool.cmp(&my_bool[0..3], &my_other_bool[0..3], CompType::NEqu).unwrap());

    println!("check for string:");
    println!("is equal: {:?}",my_sqltype_char.cmp(&my_strin[0..2], &my_other_strin[0..2], CompType::Equ).unwrap());
    println!("is not equal: {:?}",my_sqltype_char.cmp(&my_strin[0..2], &my_other_strin[0..2], CompType::NEqu).unwrap());
}
<commit_msg>style check<commit_after>extern crate server;
extern crate bincode;
extern crate log;

use server::storage::*;
use bincode::rustc_serialize::{encode_into};
use bincode::SizeLimit;
use server::logger;
use server::parse::ast::DataSrc;

fn main() {

    logger::with_loglevel(::log::LogLevelFilter::Trace)
        .with_logfile(std::path::Path::new("log.txt"))
        .enable().unwrap();

    let ty = SqlType::Int;
    let mut v = Vec::new();
    let _ = encode_into(&ty, &mut v, SizeLimit::Infinite);

    //let db = Database::create("storage_team").unwrap();
    let db = Database::load("storage_team").unwrap();

    let mut cols = Vec::new();
    cols.push(Column {
        name: "Heiner".into(),
        sql_type: SqlType::Int,
        allow_null: false,
        description: "Heiner".to_string(),
        is_primary_key: false,
    });
    cols.push(Column {
        name: "Mathias".into(),
        sql_type: SqlType::Bool,
        allow_null: false,
        description: "Mathias".to_string(),
        is_primary_key: false,
    });
    cols.push(Column {
        name: "Dennis".into(),
        sql_type: SqlType::Char(6),
        allow_null: false,
        description: "Dennis".to_string(),
        is_primary_key: true,
    });

    let mut my_data: Vec<Option<DataSrc>> = Vec::new();
    my_data.push(Some(DataSrc::Int(10)));
    my_data.push(Some(DataSrc::Bool(1)));
    my_data.push(Some(DataSrc::String("sechs".to_string())));
    my_data.push(
        Some(DataSrc::String("i am a very long string, at least i think i am".to_string()))
    );

    let _storage_team = db.create_table("storage_team", cols, 1).unwrap();

    let t = db.load_table("storage_team").unwrap();

    //_type_test();
}

fn _type_test(){
    let my_int: [u8; 4] = [20, 30, 40, 50]; //0001:0100:0001:1110:0010:1000:0011:0010 -> 337520690
    let my_other_int: [u8; 4] = [10, 5, 0, 2];//0000:1010:0000:0101:0000:0000:0000:0010 -> 168099842

    let my_bool: [u8; 3] = [0, 0, 0];
    let my_other_bool: [u8; 3] = [0, 0, 0];

    let my_strin: [u8; 2] = [0, 41];
    let my_other_strin: [u8; 2] = [0, 41];

    let my_sqltype_int = SqlType::Int;
    let my_sqltype_bool = SqlType::Bool;
    let my_sqltype_char = SqlType::Char(7);
    println!("check for int:");

    println!("is equal: {:?}",my_sqltype_int.cmp(
        &my_int[0..4], &my_other_int[0..4], CompType::Equ).unwrap()
    );
    println!("is not equal: {:?}",my_sqltype_int.cmp(
        &my_int[0..4], &my_other_int[0..4], CompType::NEqu).unwrap()
    );
    println!("is greater: {:?}",my_sqltype_int.cmp(
        &my_int[0..4], &my_other_int[0..4], CompType::GThan).unwrap()
    );
    println!("is lesser: {:?}",my_sqltype_int.cmp(
        &my_int[0..4], &my_other_int[0..4], CompType::SThan).unwrap()
    );
    println!("is greater equal: {:?}",my_sqltype_int.cmp(
        &my_int[0..4], &my_other_int[0..4], CompType::GEThan).unwrap()
    );
    println!("is lesser equal: {:?}",my_sqltype_int.cmp(
        &my_int[0..4], &my_other_int[0..4], CompType::SEThan).unwrap()
    );

    println!("check for bool:");
    println!("is equal: {:?}",my_sqltype_bool.cmp(
        &my_bool[0..3], &my_other_bool[0..3], CompType::Equ).unwrap()
    );
    println!("is not equal: {:?}",my_sqltype_bool.cmp(
        &my_bool[0..3], &my_other_bool[0..3], CompType::NEqu).unwrap()
    );

    println!("check for string:");
    println!("is equal: {:?}",my_sqltype_char.cmp(
        &my_strin[0..2], &my_other_strin[0..2], CompType::Equ).unwrap()
    );
    println!("is not equal: {:?}",my_sqltype_char.cmp(
        &my_strin[0..2], &my_other_strin[0..2], CompType::NEqu).unwrap()
    );
}
<|endoftext|>


<commit_before>// Copyright 2017, Igor Shaula
// Licensed under the MIT License <LICENSE or
// http://opensource.org/licenses/MIT>. This file
// may not be copied, modified, or distributed
// except according to those terms.
use std::mem;
use std::fmt;
use serde::de::*;
use super::{DecoderError, DecodeResult, DecoderReadingState, DecoderEnumerationState, Decoder, DECODER_SAM};
use super::super::FromRegValue;

impl Error for DecoderError {
    fn custom<T: fmt::Display>(msg: T) -> Self {
        DecoderError::DeserializerError(format!("{}", msg))
    }
}

impl<'de, 'a> Deserializer<'de> for &'a mut Decoder {
    type Error = DecoderError;
    fn deserialize_any<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        use self::DecoderEnumerationState::*;
        match self.enumeration_state {
            EnumeratingKeys(..) => no_impl!("deserialize_any for keys"),
            EnumeratingValues(..) => {
                match self.f_name {
                    Some(ref s) => {
                        let v = self.key.get_raw_value(s)?;
                        use RegType::*;
                        match v.vtype {
                            REG_SZ | REG_EXPAND_SZ | REG_MULTI_SZ => visitor.visit_string(String::from_reg_value(&v)?),
                            REG_DWORD => visitor.visit_u32(u32::from_reg_value(&v)?),
                            REG_QWORD => visitor.visit_u64(u64::from_reg_value(&v)?),
                            _ => Err(DecoderError::DecodeNotImplemented("value type deserialization not implemented".to_owned()))
                        }
                    },
                    None => Err(DecoderError::NoFieldName)
                }
            }
        }
    }

    fn deserialize_bool<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        visitor.visit_bool(read_value!(self).map(|v: u32| v > 0)?)
    }

    fn deserialize_u8<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        self.deserialize_u32(visitor)
    }

    fn deserialize_u16<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        self.deserialize_u32(visitor)
    }

    fn deserialize_u32<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        visitor.visit_u32(read_value!(self)?)
    }

    fn deserialize_u64<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        visitor.visit_u64(read_value!(self)?)
    }

    fn deserialize_i8<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        visitor.visit_i8(parse_string!(self)?)
    }

    fn deserialize_i16<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        visitor.visit_i16(parse_string!(self)?)
    }

    fn deserialize_i32<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        visitor.visit_i32(parse_string!(self)?)
    }

    fn deserialize_i64<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        visitor.visit_i64(parse_string!(self)?)
    }

    fn deserialize_f32<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_f32")
    }

    fn deserialize_f64<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_f64")
    }

    fn deserialize_char<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_char")
    }

    fn deserialize_str<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_str")
    }

    fn deserialize_string<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        use self::DecoderReadingState::*;
        match self.reading_state {
            WaitingForKey => {
                let s = self.f_name.as_ref().ok_or(DecoderError::NoFieldName)?;
                visitor.visit_string(s.clone())
            }
            WaitingForValue => visitor.visit_string(read_value!(self)?)
        }
    }

    fn deserialize_bytes<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_bytes")
    }

    fn deserialize_byte_buf<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_byte_buf")
    }

    fn deserialize_option<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        let v = {
            let s = self.f_name.as_ref().ok_or(DecoderError::NoFieldName)?;
            self.key.get_raw_value(s)
        };
        match v {
            Ok(..) => visitor.visit_some(&mut *self),
            Err(..) => visitor.visit_none()
        }
    }

    fn deserialize_unit<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_unit")
    }

    fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_unit_struct")
    }

    fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_newtype_struct")
    }

    fn deserialize_seq<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_seq")
    }

    fn deserialize_tuple<V>(self, len: usize, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_tuple")
    }

    fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_tuple_struct")
    }

    fn deserialize_map<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        visitor.visit_map(self)
    }

    fn deserialize_struct<V>(self, name: &'static str, fields: &'static [&'static str], visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        visitor.visit_map(self)
    }

    fn deserialize_identifier<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        self.deserialize_string(visitor)
    }

    fn deserialize_enum<V>(self, name: &'static str, variants: &'static [&'static str], visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_enum")
    }

    fn deserialize_ignored_any<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        self.deserialize_any(visitor)
    }
}

impl<'de, 'a> MapAccess<'de> for Decoder {
    type Error = DecoderError;
    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
        where K: DeserializeSeed<'de>
    {
        self.reading_state = DecoderReadingState::WaitingForKey;
        use self::DecoderEnumerationState::*;
        match self.enumeration_state {
            EnumeratingKeys(index) => {
                match self.key.enum_key(index) {
                    Some(res) => {
                        self.f_name = Some(res?);
                        self.enumeration_state = EnumeratingKeys(index + 1);
                        seed.deserialize(&mut *self).map(Some)
                    }
                    None => {
                        self.enumeration_state = EnumeratingValues(0);
                        self.next_key_seed(seed)
                    }
                }
            }
            EnumeratingValues(index) => {
                let next_value = self.key.enum_value(index);
                match next_value {
                    Some(res) => {
                        self.f_name = Some(res?.0);
                        self.enumeration_state = EnumeratingValues(index + 1);
                        seed.deserialize(&mut *self).map(Some)
                    }
                    None => Ok(None),
                }
            }
        }
    }

    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
        where V: DeserializeSeed<'de>
    {
        self.reading_state = DecoderReadingState::WaitingForValue;
        use self::DecoderEnumerationState::*;
        match self.enumeration_state {
            EnumeratingKeys(..) => {
                let f_name = self.f_name.as_ref().ok_or(DecoderError::NoFieldName)?;
                match self.key.open_subkey_with_flags(f_name, DECODER_SAM) {
                    Ok(subkey) => {
                        let mut nested = Decoder::new(subkey);
                        seed.deserialize(&mut nested)
                    }
                    Err(err) => Err(DecoderError::IoError(err)),
                }
            },
            EnumeratingValues(..) => {
                seed.deserialize(&mut *self)
            }
        }
    }
}
<commit_msg>Refactor deserialize_any method<commit_after>// Copyright 2017, Igor Shaula
// Licensed under the MIT License <LICENSE or
// http://opensource.org/licenses/MIT>. This file
// may not be copied, modified, or distributed
// except according to those terms.
use std::mem;
use std::fmt;
use serde::de::*;
use super::{DecoderError, DecodeResult, DecoderReadingState, DecoderEnumerationState, Decoder, DECODER_SAM};
use super::super::FromRegValue;

impl Error for DecoderError {
    fn custom<T: fmt::Display>(msg: T) -> Self {
        DecoderError::DeserializerError(format!("{}", msg))
    }
}

impl<'de, 'a> Deserializer<'de> for &'a mut Decoder {
    type Error = DecoderError;
    fn deserialize_any<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        use self::DecoderEnumerationState::*;
        match self.enumeration_state {
            EnumeratingKeys(..) => no_impl!("deserialize_any for keys"),
            EnumeratingValues(..) => {
                let s = self.f_name.as_ref().ok_or(DecoderError::NoFieldName)?;
                let v = self.key.get_raw_value(s)?;
                use RegType::*;
                match v.vtype {
                    REG_SZ | REG_EXPAND_SZ | REG_MULTI_SZ => visitor.visit_string(String::from_reg_value(&v)?),
                    REG_DWORD => visitor.visit_u32(u32::from_reg_value(&v)?),
                    REG_QWORD => visitor.visit_u64(u64::from_reg_value(&v)?),
                    _ => Err(DecoderError::DecodeNotImplemented("value type deserialization not implemented".to_owned()))
                }
            }
        }
    }

    fn deserialize_bool<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        visitor.visit_bool(read_value!(self).map(|v: u32| v > 0)?)
    }

    fn deserialize_u8<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        self.deserialize_u32(visitor)
    }

    fn deserialize_u16<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        self.deserialize_u32(visitor)
    }

    fn deserialize_u32<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        visitor.visit_u32(read_value!(self)?)
    }

    fn deserialize_u64<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        visitor.visit_u64(read_value!(self)?)
    }

    fn deserialize_i8<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        visitor.visit_i8(parse_string!(self)?)
    }

    fn deserialize_i16<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        visitor.visit_i16(parse_string!(self)?)
    }

    fn deserialize_i32<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        visitor.visit_i32(parse_string!(self)?)
    }

    fn deserialize_i64<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        visitor.visit_i64(parse_string!(self)?)
    }

    fn deserialize_f32<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_f32")
    }

    fn deserialize_f64<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_f64")
    }

    fn deserialize_char<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_char")
    }

    fn deserialize_str<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_str")
    }

    fn deserialize_string<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        use self::DecoderReadingState::*;
        match self.reading_state {
            WaitingForKey => {
                let s = self.f_name.as_ref().ok_or(DecoderError::NoFieldName)?;
                visitor.visit_string(s.clone())
            }
            WaitingForValue => visitor.visit_string(read_value!(self)?)
        }
    }

    fn deserialize_bytes<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_bytes")
    }

    fn deserialize_byte_buf<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_byte_buf")
    }

    fn deserialize_option<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        let v = {
            let s = self.f_name.as_ref().ok_or(DecoderError::NoFieldName)?;
            self.key.get_raw_value(s)
        };
        match v {
            Ok(..) => visitor.visit_some(&mut *self),
            Err(..) => visitor.visit_none()
        }
    }

    fn deserialize_unit<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_unit")
    }

    fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_unit_struct")
    }

    fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_newtype_struct")
    }

    fn deserialize_seq<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_seq")
    }

    fn deserialize_tuple<V>(self, len: usize, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_tuple")
    }

    fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_tuple_struct")
    }

    fn deserialize_map<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        visitor.visit_map(self)
    }

    fn deserialize_struct<V>(self, name: &'static str, fields: &'static [&'static str], visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        visitor.visit_map(self)
    }

    fn deserialize_identifier<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        self.deserialize_string(visitor)
    }

    fn deserialize_enum<V>(self, name: &'static str, variants: &'static [&'static str], visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        no_impl!("deserialize_enum")
    }

    fn deserialize_ignored_any<V>(self, visitor: V) -> DecodeResult<V::Value> where V: Visitor<'de> {
        self.deserialize_any(visitor)
    }
}

impl<'de, 'a> MapAccess<'de> for Decoder {
    type Error = DecoderError;
    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
        where K: DeserializeSeed<'de>
    {
        self.reading_state = DecoderReadingState::WaitingForKey;
        use self::DecoderEnumerationState::*;
        match self.enumeration_state {
            EnumeratingKeys(index) => {
                match self.key.enum_key(index) {
                    Some(res) => {
                        self.f_name = Some(res?);
                        self.enumeration_state = EnumeratingKeys(index + 1);
                        seed.deserialize(&mut *self).map(Some)
                    }
                    None => {
                        self.enumeration_state = EnumeratingValues(0);
                        self.next_key_seed(seed)
                    }
                }
            }
            EnumeratingValues(index) => {
                let next_value = self.key.enum_value(index);
                match next_value {
                    Some(res) => {
                        self.f_name = Some(res?.0);
                        self.enumeration_state = EnumeratingValues(index + 1);
                        seed.deserialize(&mut *self).map(Some)
                    }
                    None => Ok(None),
                }
            }
        }
    }

    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
        where V: DeserializeSeed<'de>
    {
        self.reading_state = DecoderReadingState::WaitingForValue;
        use self::DecoderEnumerationState::*;
        match self.enumeration_state {
            EnumeratingKeys(..) => {
                let f_name = self.f_name.as_ref().ok_or(DecoderError::NoFieldName)?;
                match self.key.open_subkey_with_flags(f_name, DECODER_SAM) {
                    Ok(subkey) => {
                        let mut nested = Decoder::new(subkey);
                        seed.deserialize(&mut nested)
                    }
                    Err(err) => Err(DecoderError::IoError(err)),
                }
            },
            EnumeratingValues(..) => {
                seed.deserialize(&mut *self)
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate alga;
extern crate clap;
extern crate env_logger;
extern crate glfw;
extern crate kiss3d;
extern crate nalgebra as na;
extern crate nkinematics as nk;
extern crate nkinematics_urdf as nk_urdf;
extern crate urdf_rs;
extern crate urdf_vis;

use clap::{Arg, App};
use glfw::{Action, WindowEvent, Key};
use kiss3d::camera::ArcBall;
use kiss3d::light::Light;
use kiss3d::window::Window;
use std::collections::HashMap;
use std::path::Path;

#[cfg(target_os = "macos")]
static NATIVE_MOD: glfw::Modifiers = glfw::Super;

#[cfg(not(target_os = "macos"))]
static NATIVE_MOD: glfw::Modifiers = glfw::Control;

fn move_ang(index: usize, rot: f32, angles_vec: &mut Vec<f32>) {
    if index == 0 {
        for ang in angles_vec.iter_mut() {
            *ang += rot;
        }
    } else {
        let dof = angles_vec.len();
        angles_vec[index % dof] += rot;
    }
}

fn main() {
    env_logger::init().unwrap();
    let matches = App::new("urdf_viewer")
        .author("Takashi Ogura <t.ogura@gmail.com>")
        .about("Show and move urdf robot model for debuging")
        .arg(Arg::with_name("input")
                 .help("input urdf or xacro file")
                 .required(true))
        .arg(Arg::with_name("assimp")
                 .short("a")
                 .long("assimp")
                 .help("Use assimp instead of meshlab to convert .dae to .obj for visualization"))
        .get_matches();
    let mesh_convert = if matches.is_present("assimp") {
        urdf_vis::MeshConvert::Assimp
    } else {
        urdf_vis::MeshConvert::Meshlab
    };

    let mut window = Window::new("urdf_viewer");
    window.set_light(Light::StickToCamera);
    let eye = na::Point3::new(0.5f32, 1.0, -3.0);
    let at = na::Point3::new(0.0f32, 0.25, 0.0);
    let mut arc_ball = ArcBall::new(eye, at);

    let arg_input = matches.value_of("input").unwrap();
    let urdf_file_path;
    let urdf_path;
    let input_path = Path::new(&arg_input);
    if input_path.extension().unwrap() == "xacro" {
        urdf_file_path = format!("/tmp/urdf_vis/{}",
                                 &input_path.with_extension("urdf").to_str().unwrap());
        urdf_path = Path::new(&urdf_file_path);
        urdf_vis::convert_xacro_to_urdf(&input_path, &urdf_path).unwrap();
    } else {
        urdf_path = input_path;
    }

    let urdf_robo = urdf_rs::read_file(&urdf_path).unwrap();
    let robot = nk_urdf::create_tree::<f32>(&urdf_robo);
    let base_transform =
        na::Isometry3::from_parts(na::Translation3::new(0.0, 0.0, 0.0),
                                  na::UnitQuaternion::from_euler_angles(0.0, 1.57, 1.57));
    robot.root_link.borrow_mut().data.transform = base_transform;

    let mut scenes = HashMap::new();
    for l in urdf_robo.links {
        scenes.insert(l.name,
                      urdf_vis::add_geometry(&l.visual, &mesh_convert, &mut window).unwrap());
    }

    let dof = robot
        .map(&|ljn_ref| ljn_ref.borrow().data.get_joint_angle())
        .len();

    let mut angles_vec = vec![0.0f32; dof];
    let mut j = 0;
    let mut is_drag = false;
    let mut last_cur_pos_y = 0f64;
    while window.render_with_camera(&mut arc_ball) {
        for mut event in window.events().iter() {
            match event.value {
                WindowEvent::MouseButton(_, Action::Press, mods) => {
                    if mods.contains(NATIVE_MOD) {
                        is_drag = true;
                        event.inhibited = true;
                    }
                }
                WindowEvent::CursorPos(_, y) => {
                    if is_drag {
                        event.inhibited = true;
                        move_ang(j, ((y - last_cur_pos_y) / 100.0) as f32, &mut angles_vec);
                    }
                    last_cur_pos_y = y;
                }
                WindowEvent::MouseButton(_, Action::Release, _) => {
                    if is_drag {
                        is_drag = false;
                        event.inhibited = true;
                    }
                }
                WindowEvent::Key(code, _, Action::Press, _) => {
                    match code {
                        Key::Num0 => j = 0,
                        Key::Num1 => j = 1,
                        Key::Num2 => j = 2,
                        Key::Num3 => j = 3,
                        Key::Num4 => j = 4,
                        Key::Num5 => j = 5,
                        Key::Num6 => j = 6,
                        Key::Num7 => j = 7,
                        Key::Num8 => j = 8,
                        Key::Num9 => j = 9,
                        Key::A => j = 10,
                        Key::B => j = 11,
                        Key::C => j = 12,
                        Key::D => j = 13,
                        Key::E => j = 14,
                        Key::F => j = 15,
                        Key::G => j = 16,
                        Key::H => j = 17,
                        Key::I => j = 18,
                        Key::J => j = 19,
                        Key::K => j = 20,
                        Key::L => j = 21,
                        Key::M => j = 22,
                        Key::N => j = 23,
                        Key::O => j = 24,
                        Key::Up => move_ang(j, 0.1, &mut angles_vec),
                        Key::Down => move_ang(j, -0.1, &mut angles_vec),
                        _ => {}
                    };
                    event.inhibited = true; // override the default keyboard handler
                }
                _ => {}
            }
        }
        for (lj, angle) in robot
                .map(&|ljn_ref| ljn_ref.clone())
                .iter()
                .zip(angles_vec.iter()) {
            let _ = lj.borrow_mut().data.set_joint_angle(*angle);
        }

        for (trans, link_name) in
            robot
                .calc_link_transforms()
                .iter()
                .zip(robot.map(&|ljn_ref| ljn_ref.borrow().data.name.clone())) {
            match scenes.get_mut(&link_name) {
                Some(obj) => obj.set_local_transformation(trans.clone()),
                None => {
                    println!("{} not found", link_name);
                }
            }
        }
    }
}
<commit_msg>Add IK for urdf_viewer<commit_after>extern crate alga;
extern crate clap;
extern crate env_logger;
extern crate glfw;
extern crate kiss3d;
extern crate nalgebra as na;
extern crate nkinematics as nk;
extern crate nkinematics_urdf as nk_urdf;
extern crate urdf_rs;
extern crate urdf_vis;

use clap::{Arg, App};
use glfw::{Action, WindowEvent, Key};
use kiss3d::camera::ArcBall;
use kiss3d::light::Light;
use kiss3d::window::Window;
use nk::InverseKinematicsSolver;
use nk::KinematicChain;
use std::collections::HashMap;
use std::path::Path;

#[cfg(target_os = "macos")]
static NATIVE_MOD: glfw::Modifiers = glfw::Super;

#[cfg(not(target_os = "macos"))]
static NATIVE_MOD: glfw::Modifiers = glfw::Control;

fn move_ang(index: usize, rot: f32, angles_vec: &mut Vec<f32>, robot: &mut nk::LinkedJointTree<f32>) {
    if index == 0 {
        for ang in angles_vec.iter_mut() {
            *ang += rot;
        }
    } else {
        let dof = angles_vec.len();
        angles_vec[index % dof] += rot;
    }
    for (lj, angle) in
        robot.map(&|ljn_ref| ljn_ref.clone())
        .iter()
        .zip(angles_vec.iter()) {
            let _ = lj.borrow_mut().data.set_joint_angle(*angle);
        }
}

fn main() {
    env_logger::init().unwrap();
    let matches = App::new("urdf_viewer")
        .author("Takashi Ogura <t.ogura@gmail.com>")
        .about("Show and move urdf robot model for debuging")
        .arg(Arg::with_name("input")
                 .help("input urdf or xacro file")
                 .required(true))
        .arg(Arg::with_name("assimp")
                 .short("a")
                 .long("assimp")
                 .help("Use assimp instead of meshlab to convert .dae to .obj for visualization"))
        .get_matches();
    let mesh_convert = if matches.is_present("assimp") {
        urdf_vis::MeshConvert::Assimp
    } else {
        urdf_vis::MeshConvert::Meshlab
    };

    let mut window = Window::new("urdf_viewer");
    window.set_light(Light::StickToCamera);
    let eye = na::Point3::new(0.5f32, 1.0, -3.0);
    let at = na::Point3::new(0.0f32, 0.25, 0.0);
    let mut arc_ball = ArcBall::new(eye, at);

    let arg_input = matches.value_of("input").unwrap();
    let urdf_file_path;
    let urdf_path;
    let input_path = Path::new(&arg_input);
    if input_path.extension().unwrap() == "xacro" {
        urdf_file_path = format!("/tmp/urdf_vis/{}",
                                 &input_path.with_extension("urdf").to_str().unwrap());
        urdf_path = Path::new(&urdf_file_path);
        urdf_vis::convert_xacro_to_urdf(&input_path, &urdf_path).unwrap();
    } else {
        urdf_path = input_path;
    }

    let urdf_robo = urdf_rs::read_file(&urdf_path).unwrap();
    let mut robot = nk_urdf::create_tree::<f32>(&urdf_robo);
    let base_transform =
        na::Isometry3::from_parts(na::Translation3::new(0.0, 0.0, 0.0),
                                  na::UnitQuaternion::from_euler_angles(0.0, 1.57, 1.57));
    robot.root_link.borrow_mut().data.transform = base_transform;

    let mut scenes = HashMap::new();
    for l in urdf_robo.links {
        scenes.insert(l.name,
                      urdf_vis::add_geometry(&l.visual, &mesh_convert, &mut window).unwrap());
    }

    let optional_ends = robot.map(&|ljn_ref|
                                  if ljn_ref.borrow().children.is_empty() {
                                      Some(ljn_ref.clone())
                                  } else {
                                      None
                                  });
    let mut arms = optional_ends
        .iter()
        .filter_map(|ljn_ref_opt|
                    match *ljn_ref_opt {
                        Some(ref ljn_ref) => {
                            let kc = nk::RefKinematicChain::new(&ljn_ref.borrow().data.name, ljn_ref);
                            if kc.get_joint_angles().len() >= 6 {
                                Some(kc)
                            } else {
                                None
                            }
                        }
                        None => None,
                    })
        .collect::<Vec<_>>();
    let num_arms = arms.len();
    println!("num_arms = {}", num_arms);
    let solver = nk::JacobianIKSolverBuilder::new().finalize();

    let dof = robot
        .map(&|ljn_ref| ljn_ref.borrow().data.get_joint_angle())
        .len();

    let mut angles_vec = vec![0.0f32; dof];
    let mut j = 0;
    let mut is_drag = false;
    let mut is_shift = false;
    let mut last_cur_pos_y = 0f64;
    let mut last_cur_pos_x = 0f64;
    while window.render_with_camera(&mut arc_ball) {
        for mut event in window.events().iter() {
            match event.value {
                WindowEvent::MouseButton(_, Action::Press, mods) => {
                    if mods.contains(NATIVE_MOD) {
                        is_drag = true;
                        event.inhibited = true;
                    } else if mods.contains(glfw::Shift) {
                        is_shift = true;
                        event.inhibited = true;
                    }
                }
                WindowEvent::CursorPos(x, y) => {
                    if is_drag {
                        event.inhibited = true;
                        move_ang(j, ((y - last_cur_pos_y) / 100.0) as f32, &mut angles_vec, &mut robot);
                    }
                    if is_shift {
                        event.inhibited = true;
                        let mut target = arms[j % num_arms].calc_end_transform();
                        target.translation.vector[2] +=
                            ((x - last_cur_pos_x) / 100.0) as f32;
                        target.translation.vector[1] +=
                            ((y - last_cur_pos_y) / 100.0) as f32;
                        solver.solve(&mut arms[j % num_arms], &target)
                            .unwrap_or_else(|err| {
                                println!("Err: {}", err);
                                0.0f32
                            });
                    }
                    last_cur_pos_x = x;
                    last_cur_pos_y = y;
                }
                WindowEvent::MouseButton(_, Action::Release, _) => {
                    if is_drag {
                        is_drag = false;
                        event.inhibited = true;
                    } else if is_shift {
                        is_shift = false;
                        event.inhibited = true;
                    }
                }
                WindowEvent::Key(code, _, Action::Press, _) => {
                    match code {
                        Key::Num0 => j = 0,
                        Key::Num1 => j = 1,
                        Key::Num2 => j = 2,
                        Key::Num3 => j = 3,
                        Key::Num4 => j = 4,
                        Key::Num5 => j = 5,
                        Key::Num6 => j = 6,
                        Key::Num7 => j = 7,
                        Key::Num8 => j = 8,
                        Key::Num9 => j = 9,
                        Key::A => j = 10,
                        Key::B => j = 11,
                        Key::C => j = 12,
                        Key::D => j = 13,
                        Key::E => j = 14,
                        Key::F => j = 15,
                        Key::G => j = 16,
                        Key::H => j = 17,
                        Key::I => j = 18,
                        Key::J => j = 19,
                        Key::K => j = 20,
                        Key::L => j = 21,
                        Key::M => j = 22,
                        Key::N => j = 23,
                        Key::O => j = 24,
                        Key::Up => move_ang(j, 0.1, &mut angles_vec, &mut robot),
                        Key::Down => move_ang(j, -0.1, &mut angles_vec, &mut robot),
                        _ => {}
                    };
                    event.inhibited = true;
                }
                _ => {}
            }
        }

        for (trans, link_name) in
            robot
                .calc_link_transforms()
                .iter()
                .zip(robot.map(&|ljn_ref| ljn_ref.borrow().data.name.clone())) {
            match scenes.get_mut(&link_name) {
                Some(obj) => obj.set_local_transformation(trans.clone()),
                None => {
                    println!("{} not found", link_name);
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>use super::{contains_return, BIND_INSTEAD_OF_MAP};
use clippy_utils::diagnostics::{multispan_sugg_with_applicability, span_lint_and_sugg, span_lint_and_then};
use clippy_utils::source::{snippet, snippet_with_macro_callsite};
use clippy_utils::ty::match_type;
use clippy_utils::{in_macro, match_qpath, method_calls, paths, remove_blocks, visitors::find_all_ret_expressions};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
use rustc_span::Span;

pub(crate) struct OptionAndThenSome;

impl BindInsteadOfMap for OptionAndThenSome {
    const TYPE_NAME: &'static str = "Option";
    const TYPE_QPATH: &'static [&'static str] = &paths::OPTION;

    const BAD_METHOD_NAME: &'static str = "and_then";
    const BAD_VARIANT_NAME: &'static str = "Some";
    const BAD_VARIANT_QPATH: &'static [&'static str] = &paths::OPTION_SOME;

    const GOOD_METHOD_NAME: &'static str = "map";
}

pub(crate) struct ResultAndThenOk;

impl BindInsteadOfMap for ResultAndThenOk {
    const TYPE_NAME: &'static str = "Result";
    const TYPE_QPATH: &'static [&'static str] = &paths::RESULT;

    const BAD_METHOD_NAME: &'static str = "and_then";
    const BAD_VARIANT_NAME: &'static str = "Ok";
    const BAD_VARIANT_QPATH: &'static [&'static str] = &paths::RESULT_OK;

    const GOOD_METHOD_NAME: &'static str = "map";
}

pub(crate) struct ResultOrElseErrInfo;

impl BindInsteadOfMap for ResultOrElseErrInfo {
    const TYPE_NAME: &'static str = "Result";
    const TYPE_QPATH: &'static [&'static str] = &paths::RESULT;

    const BAD_METHOD_NAME: &'static str = "or_else";
    const BAD_VARIANT_NAME: &'static str = "Err";
    const BAD_VARIANT_QPATH: &'static [&'static str] = &paths::RESULT_ERR;

    const GOOD_METHOD_NAME: &'static str = "map_err";
}

pub(crate) trait BindInsteadOfMap {
    const TYPE_NAME: &'static str;
    const TYPE_QPATH: &'static [&'static str];

    const BAD_METHOD_NAME: &'static str;
    const BAD_VARIANT_NAME: &'static str;
    const BAD_VARIANT_QPATH: &'static [&'static str];

    const GOOD_METHOD_NAME: &'static str;

    fn no_op_msg() -> String {
        format!(
            "using `{}.{}({})`, which is a no-op",
            Self::TYPE_NAME,
            Self::BAD_METHOD_NAME,
            Self::BAD_VARIANT_NAME
        )
    }

    fn lint_msg() -> String {
        format!(
            "using `{}.{}(|x| {}(y))`, which is more succinctly expressed as `{}(|x| y)`",
            Self::TYPE_NAME,
            Self::BAD_METHOD_NAME,
            Self::BAD_VARIANT_NAME,
            Self::GOOD_METHOD_NAME
        )
    }

    fn lint_closure_autofixable(
        cx: &LateContext<'_>,
        expr: &hir::Expr<'_>,
        recv: &hir::Expr<'_>,
        closure_expr: &hir::Expr<'_>,
        closure_args_span: Span,
    ) -> bool {
        if_chain! {
            if let hir::ExprKind::Call(ref some_expr, ref some_args) = closure_expr.kind;
            if let hir::ExprKind::Path(ref qpath) = some_expr.kind;
            if match_qpath(qpath, Self::BAD_VARIANT_QPATH);
            if some_args.len() == 1;
            then {
                let inner_expr = &some_args[0];

                if contains_return(inner_expr) {
                    return false;
                }

                let some_inner_snip = if inner_expr.span.from_expansion() {
                    snippet_with_macro_callsite(cx, inner_expr.span, "_")
                } else {
                    snippet(cx, inner_expr.span, "_")
                };

                let closure_args_snip = snippet(cx, closure_args_span, "..");
                let option_snip = snippet(cx, recv.span, "..");
                let note = format!("{}.{}({} {})", option_snip, Self::GOOD_METHOD_NAME, closure_args_snip, some_inner_snip);
                span_lint_and_sugg(
                    cx,
                    BIND_INSTEAD_OF_MAP,
                    expr.span,
                    Self::lint_msg().as_ref(),
                    "try this",
                    note,
                    Applicability::MachineApplicable,
                );
                true
            } else {
                false
            }
        }
    }

    fn lint_closure(cx: &LateContext<'_>, expr: &hir::Expr<'_>, closure_expr: &hir::Expr<'_>) -> bool {
        let mut suggs = Vec::new();
        let can_sugg: bool = find_all_ret_expressions(cx, closure_expr, |ret_expr| {
            if_chain! {
                if !in_macro(ret_expr.span);
                if let hir::ExprKind::Call(ref func_path, ref args) = ret_expr.kind;
                if let hir::ExprKind::Path(ref qpath) = func_path.kind;
                if match_qpath(qpath, Self::BAD_VARIANT_QPATH);
                if args.len() == 1;
                if !contains_return(&args[0]);
                then {
                    suggs.push((ret_expr.span, args[0].span.source_callsite()));
                    true
                } else {
                    false
                }
            }
        });

        if can_sugg {
            span_lint_and_then(cx, BIND_INSTEAD_OF_MAP, expr.span, Self::lint_msg().as_ref(), |diag| {
                multispan_sugg_with_applicability(
                    diag,
                    "try this",
                    Applicability::MachineApplicable,
                    std::iter::once((*method_calls(expr, 1).2.get(0).unwrap(), Self::GOOD_METHOD_NAME.into())).chain(
                        suggs
                            .into_iter()
                            .map(|(span1, span2)| (span1, snippet(cx, span2, "_").into())),
                    ),
                )
            });
        }
        can_sugg
    }

    /// Lint use of `_.and_then(|x| Some(y))` for `Option`s
    fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) -> bool {
        if !match_type(cx, cx.typeck_results().expr_ty(recv), Self::TYPE_QPATH) {
            return false;
        }

        match arg.kind {
            hir::ExprKind::Closure(_, _, body_id, closure_args_span, _) => {
                let closure_body = cx.tcx.hir().body(body_id);
                let closure_expr = remove_blocks(&closure_body.value);

                if Self::lint_closure_autofixable(cx, expr, recv, closure_expr, closure_args_span) {
                    true
                } else {
                    Self::lint_closure(cx, expr, closure_expr)
                }
            },
            // `_.and_then(Some)` case, which is no-op.
            hir::ExprKind::Path(ref qpath) if match_qpath(qpath, Self::BAD_VARIANT_QPATH) => {
                span_lint_and_sugg(
                    cx,
                    BIND_INSTEAD_OF_MAP,
                    expr.span,
                    Self::no_op_msg().as_ref(),
                    "use the expression directly",
                    snippet(cx, recv.span, "..").into(),
                    Applicability::MachineApplicable,
                );
                true
            },
            _ => false,
        }
    }
}
<commit_msg>Remove paths from bind_instead_of_map<commit_after>use super::{contains_return, BIND_INSTEAD_OF_MAP};
use clippy_utils::diagnostics::{multispan_sugg_with_applicability, span_lint_and_sugg, span_lint_and_then};
use clippy_utils::source::{snippet, snippet_with_macro_callsite};
use clippy_utils::{in_macro, remove_blocks, visitors::find_all_ret_expressions};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
use rustc_hir::{LangItem, QPath};
use rustc_lint::LateContext;
use rustc_middle::ty::DefIdTree;
use rustc_span::Span;

pub(crate) struct OptionAndThenSome;

impl BindInsteadOfMap for OptionAndThenSome {
    const VARIANT_LANG_ITEM: LangItem = LangItem::OptionSome;
    const BAD_METHOD_NAME: &'static str = "and_then";
    const GOOD_METHOD_NAME: &'static str = "map";
}

pub(crate) struct ResultAndThenOk;

impl BindInsteadOfMap for ResultAndThenOk {
    const VARIANT_LANG_ITEM: LangItem = LangItem::ResultOk;
    const BAD_METHOD_NAME: &'static str = "and_then";
    const GOOD_METHOD_NAME: &'static str = "map";
}

pub(crate) struct ResultOrElseErrInfo;

impl BindInsteadOfMap for ResultOrElseErrInfo {
    const VARIANT_LANG_ITEM: LangItem = LangItem::ResultErr;
    const BAD_METHOD_NAME: &'static str = "or_else";
    const GOOD_METHOD_NAME: &'static str = "map_err";
}

pub(crate) trait BindInsteadOfMap {
    const VARIANT_LANG_ITEM: LangItem;
    const BAD_METHOD_NAME: &'static str;
    const GOOD_METHOD_NAME: &'static str;

    fn no_op_msg(cx: &LateContext<'_>) -> Option<String> {
        let variant_id = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM).ok()?;
        let item_id = cx.tcx.parent(variant_id)?;
        Some(format!(
            "using `{}.{}({})`, which is a no-op",
            cx.tcx.item_name(item_id),
            Self::BAD_METHOD_NAME,
            cx.tcx.item_name(variant_id),
        ))
    }

    fn lint_msg(cx: &LateContext<'_>) -> Option<String> {
        let variant_id = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM).ok()?;
        let item_id = cx.tcx.parent(variant_id)?;
        Some(format!(
            "using `{}.{}(|x| {}(y))`, which is more succinctly expressed as `{}(|x| y)`",
            cx.tcx.item_name(item_id),
            Self::BAD_METHOD_NAME,
            cx.tcx.item_name(variant_id),
            Self::GOOD_METHOD_NAME
        ))
    }

    fn lint_closure_autofixable(
        cx: &LateContext<'_>,
        expr: &hir::Expr<'_>,
        recv: &hir::Expr<'_>,
        closure_expr: &hir::Expr<'_>,
        closure_args_span: Span,
    ) -> bool {
        if_chain! {
            if let hir::ExprKind::Call(ref some_expr, [inner_expr]) = closure_expr.kind;
            if let hir::ExprKind::Path(QPath::Resolved(_, path)) = some_expr.kind;
            if Self::is_variant(cx, path.res);
            if !contains_return(inner_expr);
            if let Some(msg) = Self::lint_msg(cx);
            then {
                let some_inner_snip = if inner_expr.span.from_expansion() {
                    snippet_with_macro_callsite(cx, inner_expr.span, "_")
                } else {
                    snippet(cx, inner_expr.span, "_")
                };

                let closure_args_snip = snippet(cx, closure_args_span, "..");
                let option_snip = snippet(cx, recv.span, "..");
                let note = format!("{}.{}({} {})", option_snip, Self::GOOD_METHOD_NAME, closure_args_snip, some_inner_snip);
                span_lint_and_sugg(
                    cx,
                    BIND_INSTEAD_OF_MAP,
                    expr.span,
                    &msg,
                    "try this",
                    note,
                    Applicability::MachineApplicable,
                );
                true
            } else {
                false
            }
        }
    }

    fn lint_closure(cx: &LateContext<'_>, expr: &hir::Expr<'_>, closure_expr: &hir::Expr<'_>) -> bool {
        let mut suggs = Vec::new();
        let can_sugg: bool = find_all_ret_expressions(cx, closure_expr, |ret_expr| {
            if_chain! {
                if !in_macro(ret_expr.span);
                if let hir::ExprKind::Call(ref func_path, [arg]) = ret_expr.kind;
                if let hir::ExprKind::Path(QPath::Resolved(_, path)) = func_path.kind;
                if Self::is_variant(cx, path.res);
                if !contains_return(arg);
                then {
                    suggs.push((ret_expr.span, arg.span.source_callsite()));
                    true
                } else {
                    false
                }
            }
        });
        let (span, msg) = if_chain! {
            if can_sugg;
            if let hir::ExprKind::MethodCall(_, span, ..) = expr.kind;
            if let Some(msg) = Self::lint_msg(cx);
            then { (span, msg) } else { return false; }
        };
        span_lint_and_then(cx, BIND_INSTEAD_OF_MAP, expr.span, &msg, |diag| {
            multispan_sugg_with_applicability(
                diag,
                "try this",
                Applicability::MachineApplicable,
                std::iter::once((span, Self::GOOD_METHOD_NAME.into())).chain(
                    suggs
                        .into_iter()
                        .map(|(span1, span2)| (span1, snippet(cx, span2, "_").into())),
                ),
            )
        });
        true
    }

    /// Lint use of `_.and_then(|x| Some(y))` for `Option`s
    fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) -> bool {
        if_chain! {
            if let Some(adt) = cx.typeck_results().expr_ty(recv).ty_adt_def();
            if let Ok(vid) = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM);
            if Some(adt.did) == cx.tcx.parent(vid);
            then {} else { return false; }
        }

        match arg.kind {
            hir::ExprKind::Closure(_, _, body_id, closure_args_span, _) => {
                let closure_body = cx.tcx.hir().body(body_id);
                let closure_expr = remove_blocks(&closure_body.value);

                if Self::lint_closure_autofixable(cx, expr, recv, closure_expr, closure_args_span) {
                    true
                } else {
                    Self::lint_closure(cx, expr, closure_expr)
                }
            },
            // `_.and_then(Some)` case, which is no-op.
            hir::ExprKind::Path(QPath::Resolved(_, path)) if Self::is_variant(cx, path.res) => {
                if let Some(msg) = Self::no_op_msg(cx) {
                    span_lint_and_sugg(
                        cx,
                        BIND_INSTEAD_OF_MAP,
                        expr.span,
                        &msg,
                        "use the expression directly",
                        snippet(cx, recv.span, "..").into(),
                        Applicability::MachineApplicable,
                    );
                }
                true
            },
            _ => false,
        }
    }

    fn is_variant(cx: &LateContext<'_>, res: Res) -> bool {
        if let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), id) = res {
            if let Ok(variant_id) = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM) {
                return cx.tcx.parent(id) == Some(variant_id);
            }
        }
        false
    }
}
<|endoftext|>


<commit_before>use html::HtmlRenderer;
use book::Book;
use parser::Parser;
use token::Token;
use super::test_eq;

fn ast_to_html(v: &[Token]) -> String {
    let mut book = Book::new(&[]);
    book.options.set("numbering", "0").unwrap();
    let mut html = HtmlRenderer::new(&book);
    html.render_vec(v)
}

#[test]
fn html_combination() {
    let doc = "
Foo
===

```rust
fn min(x: &u32, y: u32) -> &u32 {
    if x < y { x } else { y }
}
```

Bar
---

Some paragraph

* a list
    * inside a list
* another item

3. three
4. four
5. five

[& some link](http://foo/bar?baz=42&coin=plop)
";
    let expected = r#"
Foo

fn min(x: &u32, y: u32) -> &u32 {
    if x < y { x } else { y }
}

Bar

Some paragraph

a list

inside a list

another item

three

four

five

& some link

"#;
    let actual = ast_to_html(&Parser::new().parse(doc).unwrap());
    println!("ecpected:\n {}", expected);
    println!("actual:\n {}", actual);
    test_eq(&actual, &expected);
}
<commit_msg>Update tests/html.rs<commit_after>use html::HtmlRenderer;
use book::Book;
use parser::Parser;
use token::Token;
use super::test_eq;

fn ast_to_html(v: &[Token]) -> String {
    let mut book = Book::new(&[]);
    book.options.set("numbering", "0").unwrap();
    let mut html = HtmlRenderer::new(&book);
    html.render_vec(v).unwrap()
}

#[test]
fn html_combination() {
    let doc = "
Foo
===

```rust
fn min(x: &u32, y: u32) -> &u32 {
    if x < y { x } else { y }
}
```

Bar
---

Some paragraph

* a list
    * inside a list
* another item

3. three
4. four
5. five

[& some link](http://foo/bar?baz=42&coin=plop)
";
    let expected = r#"
Foo

fn min(x: &u32, y: u32) -> &u32 {
    if x < y { x } else { y }
}

Bar

Some paragraph

a list

inside a list

another item

three

four

five

& some link

"#;
    let actual = ast_to_html(&Parser::new().parse(doc).unwrap());
    println!("ecpected:\n {}", expected);
    println!("actual:\n {}", actual);
    test_eq(&actual, &expected);
}
<|endoftext|>


<commit_before>// Copyright 2014 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.

#![allow(missing_copy_implementations)]

use prelude::v1::*;

use io::{self, Read, Write, ErrorKind, BufRead};

/// Copies the entire contents of a reader into a writer.
///
/// This function will continuously read data from `r` and then write it into
/// `w` in a streaming fashion until `r` returns EOF.
///
/// On success the total number of bytes that were copied from `r` to `w` is
/// returned.
///
/// # Errors
///
/// This function will return an error immediately if any call to `read` or
/// `write` returns an error. All instances of `ErrorKind::Interrupted` are
/// handled by this function and the underlying operation is retried.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn copy<R: Read, W: Write>(r: &mut R, w: &mut W) -> io::Result<u64> {
    let mut buf = [0; super::DEFAULT_BUF_SIZE];
    let mut written = 0;
    loop {
        let len = match r.read(&mut buf) {
            Ok(0) => return Ok(written),
            Ok(len) => len,
            Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
            Err(e) => return Err(e),
        };
        try!(w.write_all(&buf[..len]));
        written += len as u64;
    }
}

/// A reader which is always at EOF.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Empty { _priv: () }

/// Creates an instance of an empty reader.
///
/// All reads from the returned reader will return `Ok(0)`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn empty() -> Empty { Empty { _priv: () } }

#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Empty {
    fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { Ok(0) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl BufRead for Empty {
    fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(&[]) }
    fn consume(&mut self, _n: usize) {}
}

/// A reader which infinitely yields one byte.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Repeat { byte: u8 }

/// Creates an instance of a reader that infinitely repeats one byte.
///
/// All reads from this reader will succeed by filling the specified buffer with
/// the given byte.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn repeat(byte: u8) -> Repeat { Repeat { byte: byte } }

#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Repeat {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        for slot in buf.iter_mut() {
            *slot = self.byte;
        }
        Ok(buf.len())
    }
}

/// A writer which will move data into the void.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Sink { _priv: () }

/// Creates an instance of a writer which will successfully consume all data.
///
/// All calls to `write` on the returned instance will return `Ok(buf.len())`
/// and the contents of the buffer will not be inspected.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn sink() -> Sink { Sink { _priv: () } }

#[stable(feature = "rust1", since = "1.0.0")]
impl Write for Sink {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) }
    fn flush(&mut self) -> io::Result<()> { Ok(()) }
}

#[cfg(test)]
mod tests {
    use prelude::v1::*;

    use io::prelude::*;
    use io::{sink, empty, repeat};

    #[test]
    fn sink_sinks() {
        let mut s = sink();
        assert_eq!(s.write(&[]).unwrap(), 0);
        assert_eq!(s.write(&[0]).unwrap(), 1);
        assert_eq!(s.write(&[0; 1024]).unwrap(), 1024);
        assert_eq!(s.by_ref().write(&[0; 1024]).unwrap(), 1024);
    }

    #[test]
    fn empty_reads() {
        let mut e = empty();
        assert_eq!(e.read(&mut []).unwrap(), 0);
        assert_eq!(e.read(&mut [0]).unwrap(), 0);
        assert_eq!(e.read(&mut [0; 1024]).unwrap(), 0);
        assert_eq!(e.by_ref().read(&mut [0; 1024]).unwrap(), 0);
    }

    #[test]
    fn repeat_repeats() {
        let mut r = repeat(4);
        let mut b = [0; 1024];
        assert_eq!(r.read(&mut b).unwrap(), 1024);
        assert!(b.iter().all(|b| *b == 4));
    }

    #[test]
    fn take_some_bytes() {
        assert_eq!(repeat(4).take(100).bytes().count(), 100);
        assert_eq!(repeat(4).take(100).bytes().next().unwrap().unwrap(), 4);
        assert_eq!(repeat(1).take(10).chain(repeat(2).take(10)).bytes().count(), 20);
    }

    #[test]
    fn tee() {
        let mut buf = [0; 10];
        {
            let mut ptr: &mut [u8] = &mut buf;
            assert_eq!(repeat(4).tee(&mut ptr).take(5).read(&mut [0; 10]).unwrap(), 5);
        }
        assert_eq!(buf, [4, 4, 4, 4, 4, 0, 0, 0, 0, 0]);
    }

    #[test]
    fn broadcast() {
        let mut buf1 = [0; 10];
        let mut buf2 = [0; 10];
        {
            let mut ptr1: &mut [u8] = &mut buf1;
            let mut ptr2: &mut [u8] = &mut buf2;

            assert_eq!((&mut ptr1).broadcast(&mut ptr2)
                                  .write(&[1, 2, 3]).unwrap(), 3);
        }
        assert_eq!(buf1, buf2);
        assert_eq!(buf1, [1, 2, 3, 0, 0, 0, 0, 0, 0, 0]);
    }
}
<commit_msg>Auto merge of #25656 - tshepang:spell-em-out, r=brson<commit_after>// Copyright 2014 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.

#![allow(missing_copy_implementations)]

use prelude::v1::*;

use io::{self, Read, Write, ErrorKind, BufRead};

/// Copies the entire contents of a reader into a writer.
///
/// This function will continuously read data from `reader` and then
/// write it into `writer` in a streaming fashion until `reader`
/// returns EOF.
///
/// On success, the total number of bytes that were copied from
/// `reader` to `writer` is returned.
///
/// # Errors
///
/// This function will return an error immediately if any call to `read` or
/// `write` returns an error. All instances of `ErrorKind::Interrupted` are
/// handled by this function and the underlying operation is retried.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn copy<R: Read, W: Write>(reader: &mut R, writer: &mut W) -> io::Result<u64> {
    let mut buf = [0; super::DEFAULT_BUF_SIZE];
    let mut written = 0;
    loop {
        let len = match reader.read(&mut buf) {
            Ok(0) => return Ok(written),
            Ok(len) => len,
            Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
            Err(e) => return Err(e),
        };
        try!(writer.write_all(&buf[..len]));
        written += len as u64;
    }
}

/// A reader which is always at EOF.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Empty { _priv: () }

/// Creates an instance of an empty reader.
///
/// All reads from the returned reader will return `Ok(0)`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn empty() -> Empty { Empty { _priv: () } }

#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Empty {
    fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { Ok(0) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl BufRead for Empty {
    fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(&[]) }
    fn consume(&mut self, _n: usize) {}
}

/// A reader which infinitely yields one byte.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Repeat { byte: u8 }

/// Creates an instance of a reader that infinitely repeats one byte.
///
/// All reads from this reader will succeed by filling the specified buffer with
/// the given byte.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn repeat(byte: u8) -> Repeat { Repeat { byte: byte } }

#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Repeat {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        for slot in buf.iter_mut() {
            *slot = self.byte;
        }
        Ok(buf.len())
    }
}

/// A writer which will move data into the void.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Sink { _priv: () }

/// Creates an instance of a writer which will successfully consume all data.
///
/// All calls to `write` on the returned instance will return `Ok(buf.len())`
/// and the contents of the buffer will not be inspected.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn sink() -> Sink { Sink { _priv: () } }

#[stable(feature = "rust1", since = "1.0.0")]
impl Write for Sink {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) }
    fn flush(&mut self) -> io::Result<()> { Ok(()) }
}

#[cfg(test)]
mod tests {
    use prelude::v1::*;

    use io::prelude::*;
    use io::{sink, empty, repeat};

    #[test]
    fn sink_sinks() {
        let mut s = sink();
        assert_eq!(s.write(&[]).unwrap(), 0);
        assert_eq!(s.write(&[0]).unwrap(), 1);
        assert_eq!(s.write(&[0; 1024]).unwrap(), 1024);
        assert_eq!(s.by_ref().write(&[0; 1024]).unwrap(), 1024);
    }

    #[test]
    fn empty_reads() {
        let mut e = empty();
        assert_eq!(e.read(&mut []).unwrap(), 0);
        assert_eq!(e.read(&mut [0]).unwrap(), 0);
        assert_eq!(e.read(&mut [0; 1024]).unwrap(), 0);
        assert_eq!(e.by_ref().read(&mut [0; 1024]).unwrap(), 0);
    }

    #[test]
    fn repeat_repeats() {
        let mut r = repeat(4);
        let mut b = [0; 1024];
        assert_eq!(r.read(&mut b).unwrap(), 1024);
        assert!(b.iter().all(|b| *b == 4));
    }

    #[test]
    fn take_some_bytes() {
        assert_eq!(repeat(4).take(100).bytes().count(), 100);
        assert_eq!(repeat(4).take(100).bytes().next().unwrap().unwrap(), 4);
        assert_eq!(repeat(1).take(10).chain(repeat(2).take(10)).bytes().count(), 20);
    }

    #[test]
    fn tee() {
        let mut buf = [0; 10];
        {
            let mut ptr: &mut [u8] = &mut buf;
            assert_eq!(repeat(4).tee(&mut ptr).take(5).read(&mut [0; 10]).unwrap(), 5);
        }
        assert_eq!(buf, [4, 4, 4, 4, 4, 0, 0, 0, 0, 0]);
    }

    #[test]
    fn broadcast() {
        let mut buf1 = [0; 10];
        let mut buf2 = [0; 10];
        {
            let mut ptr1: &mut [u8] = &mut buf1;
            let mut ptr2: &mut [u8] = &mut buf2;

            assert_eq!((&mut ptr1).broadcast(&mut ptr2)
                                  .write(&[1, 2, 3]).unwrap(), 3);
        }
        assert_eq!(buf1, buf2);
        assert_eq!(buf1, [1, 2, 3, 0, 0, 0, 0, 0, 0, 0]);
    }
}
<|endoftext|>