<commit_before>use std::collections::HashMap;

#[allow(dead_code)]
#[derive(PartialEq, Debug)]
pub enum Method {
    Get,
    Put,
    Post,
    Delete,
    NoImpl,
}

pub trait FromUri {
    fn from_uri(data: &str) -> Self;
}

impl FromUri for String {
    fn from_uri(data: &str) -> String {
        String::from(data)
    }
}

impl FromUri for i32 {
    fn from_uri(data: &str) -> i32 {
        match data.parse::<i32>() {
            Ok(v)  => v,
            Err(e) => panic!("matched integer can't be parsed: {:?}", e),
        }
    }
}

impl FromUri for f32 {
    fn from_uri(data: &str) -> f32 {
        match data.parse::<f32>() {
            Ok(v)  => v,
            Err(e) => panic!("matched float can't be parsed: {:?}", e),
        }
    }
}

#[derive(Debug)]
pub struct Request {
    pub method: Method,
    pub path:   String,
    pub params: Option<HashMap<String, String>>,
    headers:    HashMap<String, String>,
    payload:    Vec<u8>,
}

impl Request {
    pub fn new() -> Request {
        Request {
            method:  Method::NoImpl,
            path:    String::new(),
            headers: HashMap::new(),
            params:  None,
            payload: Vec::new(),
        }
    }

    fn _get(&self, name: &str) -> Option<&String> {
        let val: Option<&String> = match self.params {
            Some(ref p) => p.get(name),
            None        => None,
        };

        val
    }

    pub fn get<T>(&self, name: &str) -> T where T: FromUri {
        match self._get(&name) {
            Some(item) => FromUri::from_uri(&item),
            None       => panic!("invalid route parameter {:?}", name),
        }
    }

    pub fn from_str(rqstr: &str) -> Request {
        let mut req = Request::new();
        req.parse(rqstr);
        req
    }

    pub fn parse(&mut self, rqstr: &str) {
        let mut buf: Vec<&str> = rqstr.splitn(2, "\r\n").collect();
        let ask: Vec<&str> = buf[0].splitn(3, ' ').collect();

        self.method = match ask[1] {
            "GET"           => Method::Get,
            "PUT" | "PATCH" => Method::Put,
            "POST"          => Method::Post,
            "DELETE"        => Method::Delete,
            _               => Method::NoImpl,
        };
        self.path = String::from(ask[2]);

        loop {
            buf = buf[1].splitn(2, "\r\n").collect();

            if buf[0] == "" {
                if buf[1] == "" {
                    /* no payload */
                    break;
                }

                let tmp: String;
                buf = buf[1].splitn(2, "\r\n").collect();
                tmp = String::from(buf[1]);
                self.payload.extend(tmp.as_bytes());
                break;
            }

            let hdr: Vec<&str> = buf[0].splitn(2, ": ").collect();

            if hdr.len() == 2 {
                self.headers.insert(String::from(hdr[0]), String::from(hdr[1]));
            }
        }
    }

    pub fn has_params(&self) -> bool {
        match self.params {
            Some(ref p) => true,
            None        => false,
        }
    }
}
<commit_msg>Fix a few bugs in the request parser<commit_after>use std::collections::HashMap;

#[allow(dead_code)]
#[derive(PartialEq, Eq, Hash, Debug)]
pub enum Method {
    Get,
    Put,
    Post,
    Delete,
    NoImpl,
}

pub trait FromUri {
    fn from_uri(data: &str) -> Self;
}

impl FromUri for String {
    fn from_uri(data: &str) -> String {
        String::from(data)
    }
}

impl FromUri for i32 {
    fn from_uri(data: &str) -> i32 {
        match data.parse::<i32>() {
            Ok(v)  => v,
            Err(e) => panic!("matched integer can't be parsed: {:?}", e),
        }
    }
}

impl FromUri for f32 {
    fn from_uri(data: &str) -> f32 {
        match data.parse::<f32>() {
            Ok(v)  => v,
            Err(e) => panic!("matched float can't be parsed: {:?}", e),
        }
    }
}

#[derive(Debug)]
pub struct Request {
    pub method: Method,
    pub path:   String,
    pub params: Option<HashMap<String, String>>,
    headers:    HashMap<String, String>,
    payload:    Vec<u8>,
}

impl Request {
    pub fn new() -> Request {
        Request {
            method:  Method::NoImpl,
            path:    String::new(),
            headers: HashMap::new(),
            params:  None,
            payload: Vec::new(),
        }
    }

    fn _get(&self, name: &str) -> Option<&String> {
        let val: Option<&String> = match self.params {
            Some(ref p) => p.get(name),
            None        => None,
        };

        val
    }

    pub fn get<T>(&self, name: &str) -> T where T: FromUri {
        match self._get(&name) {
            Some(item) => FromUri::from_uri(&item),
            None       => panic!("invalid route parameter {:?}", name),
        }
    }

    pub fn from_str(rqstr: &str) -> Request {
        let mut req = Request::new();
        req.parse(rqstr);
        req
    }

    pub fn parse(&mut self, rqstr: &str) {
        let mut buf: Vec<&str> = rqstr.splitn(2, "\r\n").collect();
        let ask: Vec<&str> = buf[0].splitn(3, ' ').collect();

        println!("{:?}", ask);

        self.method = match ask[0] {
            "GET"           => Method::Get,
            "PUT" | "PATCH" => Method::Put,
            "POST"          => Method::Post,
            "DELETE"        => Method::Delete,
            _               => Method::NoImpl,
        };
        self.path = String::from(ask[1]);

        loop {
            buf = buf[1].splitn(2, "\r\n").collect();

            if buf[0] == "" {
                if buf[1] == "" {
                    /* no payload */
                    break;
                }

                let tmp: String;
                buf = buf[1].splitn(2, "\r\n").collect();
                tmp = String::from(buf[1]);
                self.payload.extend(tmp.as_bytes());
                break;
            }

            let hdr: Vec<&str> = buf[0].splitn(2, ": ").collect();

            if hdr.len() == 2 {
                self.headers.insert(String::from(hdr[0]), String::from(hdr[1]));
            }
        }
    }

    pub fn has_params(&self) -> bool {
        match self.params {
            Some(_) => true,
            None    => false,
        }
    }
}
<|endoftext|>


<commit_before>#![allow(clippy::write_with_newline)]

use std::fmt::Write;

// Internal
use clap::*;
use clap_complete::*;

/// Generate fig completion file
pub struct Fig;

impl Generator for Fig {
    fn file_name(&self, name: &str) -> String {
        format!("{}.ts", name)
    }

    fn generate(&self, cmd: &Command, buf: &mut dyn std::io::Write) {
        let command = cmd.get_bin_name().unwrap();
        let mut buffer = String::new();

        write!(
            &mut buffer,
            "const completion: Fig.Spec = {{\n  name: \"{}\",\n",
            command
        )
        .unwrap();

        write!(
            &mut buffer,
            "  description: \"{}\",\n",
            cmd.get_about().unwrap_or_default()
        )
        .unwrap();

        gen_fig_inner(command, &[], 2, cmd, &mut buffer);

        write!(&mut buffer, "}};\n\nexport default completion;\n").unwrap();

        buf.write_all(buffer.as_bytes())
            .expect("Failed to write to generated file");
    }
}

// Escape string inside double quotes
fn escape_string(string: &str) -> String {
    string.replace('\\', "\\\\").replace('\"', "\\\"")
}

fn gen_fig_inner(
    root_command: &str,
    parent_commands: &[&str],
    indent: usize,
    cmd: &Command,
    buffer: &mut String,
) {
    if cmd.has_subcommands() {
        write!(buffer, "{:indent$}subcommands: [\n", "", indent = indent).unwrap();
        // generate subcommands
        for subcommand in cmd.get_subcommands() {
            let mut aliases: Vec<&str> = subcommand.get_all_aliases().collect();
            if !aliases.is_empty() {
                aliases.insert(0, subcommand.get_name());

                write!(
                    buffer,
                    "{:indent$}{{\n{:indent$}  name: [",
                    "",
                    "",
                    indent = indent + 2
                )
                .unwrap();

                buffer.push_str(
                    &aliases
                        .iter()
                        .map(|name| format!("\"{}\"", name))
                        .collect::<Vec<_>>()
                        .join(", "),
                );

                write!(buffer, "],\n").unwrap();
            } else {
                write!(
                    buffer,
                    "{:indent$}{{\n{:indent$}  name: \"{}\",\n",
                    "",
                    "",
                    subcommand.get_name(),
                    indent = indent + 2
                )
                .unwrap();
            }

            if let Some(data) = subcommand.get_about() {
                write!(
                    buffer,
                    "{:indent$}description: \"{}\",\n",
                    "",
                    escape_string(data),
                    indent = indent + 4
                )
                .unwrap();
            }

            if subcommand.is_hide_set() {
                write!(buffer, "{:indent$}hidden: true,\n", "", indent = indent + 4).unwrap();
            }

            let mut parent_commands: Vec<_> = parent_commands.into();
            parent_commands.push(subcommand.get_name());
            gen_fig_inner(
                root_command,
                &parent_commands,
                indent + 4,
                subcommand,
                buffer,
            );

            write!(buffer, "{:indent$}}},\n", "", indent = indent + 2).unwrap();
        }
        write!(buffer, "{:indent$}],\n", "", indent = indent).unwrap();
    }

    buffer.push_str(&gen_options(cmd, indent));

    let args = cmd.get_positionals().collect::<Vec<_>>();

    match args.len() {
        0 => {}
        1 => {
            write!(buffer, "{:indent$}args: ", "", indent = indent).unwrap();

            buffer.push_str(&gen_args(args[0], indent));
        }
        _ => {
            write!(buffer, "{:indent$}args: [\n", "", indent = indent).unwrap();
            for arg in args {
                write!(buffer, "{:indent$}", "", indent = indent + 2).unwrap();
                buffer.push_str(&gen_args(arg, indent + 2));
            }
            write!(buffer, "{:indent$}]\n", "", indent = indent).unwrap();
        }
    };
}

fn gen_options(cmd: &Command, indent: usize) -> String {
    let mut buffer = String::new();

    let flags = generator::utils::flags(cmd);

    if cmd.get_opts().next().is_some() || !flags.is_empty() {
        write!(&mut buffer, "{:indent$}options: [\n", "", indent = indent).unwrap();

        for option in cmd.get_opts() {
            write!(&mut buffer, "{:indent$}{{\n", "", indent = indent + 2).unwrap();

            let mut names = vec![];

            if let Some(shorts) = option.get_short_and_visible_aliases() {
                names.extend(shorts.iter().map(|short| format!("-{}", short)));
            }

            if let Some(longs) = option.get_long_and_visible_aliases() {
                names.extend(longs.iter().map(|long| format!("--{}", long)));
            }

            if names.len() > 1 {
                write!(&mut buffer, "{:indent$}name: [", "", indent = indent + 4).unwrap();

                buffer.push_str(
                    &names
                        .iter()
                        .map(|name| format!("\"{}\"", name))
                        .collect::<Vec<_>>()
                        .join(", "),
                );

                buffer.push_str("],\n");
            } else {
                write!(
                    &mut buffer,
                    "{:indent$}name: \"{}\",\n",
                    "",
                    names[0],
                    indent = indent + 4
                )
                .unwrap();
            }

            if let Some(data) = option.get_help() {
                write!(
                    &mut buffer,
                    "{:indent$}description: \"{}\",\n",
                    "",
                    escape_string(data),
                    indent = indent + 4
                )
                .unwrap();
            }

            if option.is_hide_set() {
                write!(
                    &mut buffer,
                    "{:indent$}hidden: true,\n",
                    "",
                    indent = indent + 4
                )
                .unwrap();
            }

            let conflicts = arg_conflicts(cmd, option);

            if !conflicts.is_empty() {
                write!(
                    &mut buffer,
                    "{:indent$}exclusiveOn: [\n",
                    "",
                    indent = indent + 4
                )
                .unwrap();

                for conflict in conflicts {
                    write!(
                        &mut buffer,
                        "{:indent$}\"{}\",\n",
                        "",
                        conflict,
                        indent = indent + 6
                    )
                    .unwrap();
                }

                write!(&mut buffer, "{:indent$}],\n", "", indent = indent + 4).unwrap();
            }

            if let ArgAction::Set | ArgAction::Append | ArgAction::Count = option.get_action() {
                write!(
                    &mut buffer,
                    "{:indent$}isRepeatable: true,\n",
                    "",
                    indent = indent + 4
                )
                .unwrap();
            }

            if option.is_require_equals_set() {
                write!(
                    &mut buffer,
                    "{:indent$}requiresEquals: true,\n",
                    "",
                    indent = indent + 4
                )
                .unwrap();
            }

            write!(&mut buffer, "{:indent$}args: ", "", indent = indent + 4).unwrap();

            buffer.push_str(&gen_args(option, indent + 4));

            write!(&mut buffer, "{:indent$}}},\n", "", indent = indent + 2).unwrap();
        }

        for flag in generator::utils::flags(cmd) {
            write!(&mut buffer, "{:indent$}{{\n", "", indent = indent + 2).unwrap();

            let mut flags = vec![];

            if let Some(shorts) = flag.get_short_and_visible_aliases() {
                flags.extend(shorts.iter().map(|s| format!("-{}", s)));
            }

            if let Some(longs) = flag.get_long_and_visible_aliases() {
                flags.extend(longs.iter().map(|s| format!("--{}", s)));
            }

            if flags.len() > 1 {
                write!(&mut buffer, "{:indent$}name: [", "", indent = indent + 4).unwrap();

                buffer.push_str(
                    &flags
                        .iter()
                        .map(|name| format!("\"{}\"", name))
                        .collect::<Vec<_>>()
                        .join(", "),
                );

                buffer.push_str("],\n");
            } else {
                write!(
                    &mut buffer,
                    "{:indent$}name: \"{}\",\n",
                    "",
                    flags[0],
                    indent = indent + 4
                )
                .unwrap();
            }

            if let Some(data) = flag.get_help() {
                write!(
                    &mut buffer,
                    "{:indent$}description: \"{}\",\n",
                    "",
                    escape_string(data).as_str(),
                    indent = indent + 4
                )
                .unwrap();
            }

            let conflicts = arg_conflicts(cmd, &flag);

            if !conflicts.is_empty() {
                write!(
                    &mut buffer,
                    "{:indent$}exclusiveOn: [\n",
                    "",
                    indent = indent + 4
                )
                .unwrap();

                for conflict in conflicts {
                    write!(
                        &mut buffer,
                        "{:indent$}\"{}\",\n",
                        "",
                        conflict,
                        indent = indent + 6
                    )
                    .unwrap();
                }

                write!(&mut buffer, "{:indent$}],\n", "", indent = indent + 4).unwrap();
            }

            if let ArgAction::Set | ArgAction::Append | ArgAction::Count = flag.get_action() {
                write!(
                    &mut buffer,
                    "{:indent$}isRepeatable: true,\n",
                    "",
                    indent = indent + 4
                )
                .unwrap();
            }

            write!(&mut buffer, "{:indent$}}},\n", "", indent = indent + 2).unwrap();
        }

        write!(&mut buffer, "{:indent$}],\n", "", indent = indent).unwrap();
    }

    buffer
}

fn gen_args(arg: &Arg, indent: usize) -> String {
    if !arg.get_num_args().expect("built").takes_values() {
        return "".to_string();
    }

    let mut buffer = String::new();

    write!(
        &mut buffer,
        "{{\n{:indent$}  name: \"{}\",\n",
        "",
        arg.get_id(),
        indent = indent
    )
    .unwrap();

    let num_args = arg.get_num_args().expect("built");
    if num_args != builder::ValueRange::EMPTY && num_args != builder::ValueRange::SINGLE {
        write!(
            &mut buffer,
            "{:indent$}isVariadic: true,\n",
            "",
            indent = indent + 2
        )
        .unwrap();
    }

    if !arg.is_required_set() {
        write!(
            &mut buffer,
            "{:indent$}isOptional: true,\n",
            "",
            indent = indent + 2
        )
        .unwrap();
    }

    if let Some(data) = generator::utils::possible_values(arg) {
        write!(
            &mut buffer,
            "{:indent$}suggestions: [\n",
            "",
            indent = indent + 2
        )
        .unwrap();

        for value in data {
            if let Some(help) = value.get_help() {
                write!(
                    &mut buffer,
                    "{:indent$}{{\n{:indent$}  name: \"{}\",\n",
                    "",
                    "",
                    value.get_name(),
                    indent = indent + 4,
                )
                .unwrap();

                write!(
                    &mut buffer,
                    "{:indent$}description: \"{}\",\n",
                    "",
                    escape_string(help),
                    indent = indent + 6
                )
                .unwrap();

                write!(&mut buffer, "{:indent$}}},\n", "", indent = indent + 4).unwrap();
            } else {
                write!(
                    &mut buffer,
                    "{:indent$}\"{}\",\n",
                    "",
                    value.get_name(),
                    indent = indent + 4,
                )
                .unwrap();
            }
        }

        write!(&mut buffer, "{:indent$}],\n", "", indent = indent + 2).unwrap();
    } else {
        match arg.get_value_hint() {
            ValueHint::AnyPath | ValueHint::FilePath | ValueHint::ExecutablePath => {
                write!(
                    &mut buffer,
                    "{:indent$}template: \"filepaths\",\n",
                    "",
                    indent = indent + 2
                )
                .unwrap();
            }
            ValueHint::DirPath => {
                write!(
                    &mut buffer,
                    "{:indent$}template: \"folders\",\n",
                    "",
                    indent = indent + 2
                )
                .unwrap();
            }
            ValueHint::CommandString | ValueHint::CommandName | ValueHint::CommandWithArguments => {
                write!(
                    &mut buffer,
                    "{:indent$}isCommand: true,\n",
                    "",
                    indent = indent + 2
                )
                .unwrap();
            }
            // Disable completion for others
            _ => (),
        };
    };

    write!(&mut buffer, "{:indent$}}},\n", "", indent = indent).unwrap();

    buffer
}

fn arg_conflicts(cmd: &Command, arg: &Arg) -> Vec<String> {
    let mut res = vec![];

    for conflict in cmd.get_arg_conflicts_with(arg) {
        if let Some(s) = conflict.get_short() {
            res.push(format!("-{}", s));
        }

        if let Some(l) = conflict.get_long() {
            res.push(format!("--{}", l));
        }
    }

    res
}
<commit_msg>feat(fig): escape all strings<commit_after>#![allow(clippy::write_with_newline)]

use std::fmt::Write;

// Internal
use clap::*;
use clap_complete::*;

/// Generate fig completion file
pub struct Fig;

impl Generator for Fig {
    fn file_name(&self, name: &str) -> String {
        format!("{}.ts", name)
    }

    fn generate(&self, cmd: &Command, buf: &mut dyn std::io::Write) {
        let command = cmd.get_bin_name().unwrap();
        let mut buffer = String::new();

        write!(
            &mut buffer,
            "const completion: Fig.Spec = {{\n  name: \"{}\",\n",
            escape_string(command)
        )
        .unwrap();

        write!(
            &mut buffer,
            "  description: \"{}\",\n",
            escape_string(cmd.get_about().unwrap_or_default())
        )
        .unwrap();

        gen_fig_inner(command, &[], 2, cmd, &mut buffer);

        write!(&mut buffer, "}};\n\nexport default completion;\n").unwrap();

        buf.write_all(buffer.as_bytes())
            .expect("Failed to write to generated file");
    }
}

// Escape string inside double quotes and convert whitespace
fn escape_string(string: &str) -> String {
    string
        .replace('\\', "\\\\")
        .replace('\"', "\\\"")
        .replace('\t', "    ")
        .replace('\n', " ")
        .replace('\r', "")
}

fn gen_fig_inner(
    root_command: &str,
    parent_commands: &[&str],
    indent: usize,
    cmd: &Command,
    buffer: &mut String,
) {
    if cmd.has_subcommands() {
        write!(buffer, "{:indent$}subcommands: [\n", "", indent = indent).unwrap();
        // generate subcommands
        for subcommand in cmd.get_subcommands() {
            let mut aliases: Vec<&str> = subcommand.get_all_aliases().collect();
            if !aliases.is_empty() {
                aliases.insert(0, subcommand.get_name());

                write!(
                    buffer,
                    "{:indent$}{{\n{:indent$}  name: [",
                    "",
                    "",
                    indent = indent + 2
                )
                .unwrap();

                buffer.push_str(
                    &aliases
                        .iter()
                        .map(|name| format!("\"{}\"", escape_string(name)))
                        .collect::<Vec<_>>()
                        .join(", "),
                );

                write!(buffer, "],\n").unwrap();
            } else {
                write!(
                    buffer,
                    "{:indent$}{{\n{:indent$}  name: \"{}\",\n",
                    "",
                    "",
                    escape_string(subcommand.get_name()),
                    indent = indent + 2
                )
                .unwrap();
            }

            if let Some(data) = subcommand.get_about() {
                write!(
                    buffer,
                    "{:indent$}description: \"{}\",\n",
                    "",
                    escape_string(data),
                    indent = indent + 4
                )
                .unwrap();
            }

            if subcommand.is_hide_set() {
                write!(buffer, "{:indent$}hidden: true,\n", "", indent = indent + 4).unwrap();
            }

            let mut parent_commands: Vec<_> = parent_commands.into();
            parent_commands.push(subcommand.get_name());
            gen_fig_inner(
                root_command,
                &parent_commands,
                indent + 4,
                subcommand,
                buffer,
            );

            write!(buffer, "{:indent$}}},\n", "", indent = indent + 2).unwrap();
        }
        write!(buffer, "{:indent$}],\n", "", indent = indent).unwrap();
    }

    buffer.push_str(&gen_options(cmd, indent));

    let args = cmd.get_positionals().collect::<Vec<_>>();

    match args.len() {
        0 => {}
        1 => {
            write!(buffer, "{:indent$}args: ", "", indent = indent).unwrap();

            buffer.push_str(&gen_args(args[0], indent));
        }
        _ => {
            write!(buffer, "{:indent$}args: [\n", "", indent = indent).unwrap();
            for arg in args {
                write!(buffer, "{:indent$}", "", indent = indent + 2).unwrap();
                buffer.push_str(&gen_args(arg, indent + 2));
            }
            write!(buffer, "{:indent$}]\n", "", indent = indent).unwrap();
        }
    };
}

fn gen_options(cmd: &Command, indent: usize) -> String {
    let mut buffer = String::new();

    let flags = generator::utils::flags(cmd);

    if cmd.get_opts().next().is_some() || !flags.is_empty() {
        write!(&mut buffer, "{:indent$}options: [\n", "", indent = indent).unwrap();

        for option in cmd.get_opts() {
            write!(&mut buffer, "{:indent$}{{\n", "", indent = indent + 2).unwrap();

            let mut names = vec![];

            if let Some(shorts) = option.get_short_and_visible_aliases() {
                names.extend(
                    shorts
                        .iter()
                        .map(|short| format!("-{}", escape_string(&short.to_string()))),
                );
            }

            if let Some(longs) = option.get_long_and_visible_aliases() {
                names.extend(
                    longs
                        .iter()
                        .map(|long| format!("--{}", escape_string(long))),
                );
            }

            if names.len() > 1 {
                write!(&mut buffer, "{:indent$}name: [", "", indent = indent + 4).unwrap();

                buffer.push_str(
                    &names
                        .iter()
                        .map(|name| format!("\"{}\"", escape_string(name)))
                        .collect::<Vec<_>>()
                        .join(", "),
                );

                buffer.push_str("],\n");
            } else {
                write!(
                    &mut buffer,
                    "{:indent$}name: \"{}\",\n",
                    "",
                    escape_string(&names[0]),
                    indent = indent + 4
                )
                .unwrap();
            }

            if let Some(data) = option.get_help() {
                write!(
                    &mut buffer,
                    "{:indent$}description: \"{}\",\n",
                    "",
                    escape_string(data),
                    indent = indent + 4
                )
                .unwrap();
            }

            if option.is_hide_set() {
                write!(
                    &mut buffer,
                    "{:indent$}hidden: true,\n",
                    "",
                    indent = indent + 4
                )
                .unwrap();
            }

            let conflicts = arg_conflicts(cmd, option);

            if !conflicts.is_empty() {
                write!(
                    &mut buffer,
                    "{:indent$}exclusiveOn: [\n",
                    "",
                    indent = indent + 4
                )
                .unwrap();

                for conflict in conflicts {
                    write!(
                        &mut buffer,
                        "{:indent$}\"{}\",\n",
                        "",
                        escape_string(&conflict),
                        indent = indent + 6
                    )
                    .unwrap();
                }

                write!(&mut buffer, "{:indent$}],\n", "", indent = indent + 4).unwrap();
            }

            if let ArgAction::Set | ArgAction::Append | ArgAction::Count = option.get_action() {
                write!(
                    &mut buffer,
                    "{:indent$}isRepeatable: true,\n",
                    "",
                    indent = indent + 4
                )
                .unwrap();
            }

            if option.is_require_equals_set() {
                write!(
                    &mut buffer,
                    "{:indent$}requiresEquals: true,\n",
                    "",
                    indent = indent + 4
                )
                .unwrap();
            }

            write!(&mut buffer, "{:indent$}args: ", "", indent = indent + 4).unwrap();

            buffer.push_str(&gen_args(option, indent + 4));

            write!(&mut buffer, "{:indent$}}},\n", "", indent = indent + 2).unwrap();
        }

        for flag in generator::utils::flags(cmd) {
            write!(&mut buffer, "{:indent$}{{\n", "", indent = indent + 2).unwrap();

            let mut flags = vec![];

            if let Some(shorts) = flag.get_short_and_visible_aliases() {
                flags.extend(shorts.iter().map(|s| format!("-{}", s)));
            }

            if let Some(longs) = flag.get_long_and_visible_aliases() {
                flags.extend(longs.iter().map(|s| format!("--{}", s)));
            }

            if flags.len() > 1 {
                write!(&mut buffer, "{:indent$}name: [", "", indent = indent + 4).unwrap();

                buffer.push_str(
                    &flags
                        .iter()
                        .map(|name| format!("\"{}\"", escape_string(name)))
                        .collect::<Vec<_>>()
                        .join(", "),
                );

                buffer.push_str("],\n");
            } else {
                write!(
                    &mut buffer,
                    "{:indent$}name: \"{}\",\n",
                    "",
                    escape_string(&flags[0]),
                    indent = indent + 4
                )
                .unwrap();
            }

            if let Some(data) = flag.get_help() {
                write!(
                    &mut buffer,
                    "{:indent$}description: \"{}\",\n",
                    "",
                    escape_string(data).as_str(),
                    indent = indent + 4
                )
                .unwrap();
            }

            let conflicts = arg_conflicts(cmd, &flag);

            if !conflicts.is_empty() {
                write!(
                    &mut buffer,
                    "{:indent$}exclusiveOn: [\n",
                    "",
                    indent = indent + 4
                )
                .unwrap();

                for conflict in conflicts {
                    write!(
                        &mut buffer,
                        "{:indent$}\"{}\",\n",
                        "",
                        escape_string(&conflict),
                        indent = indent + 6
                    )
                    .unwrap();
                }

                write!(&mut buffer, "{:indent$}],\n", "", indent = indent + 4).unwrap();
            }

            if let ArgAction::Set | ArgAction::Append | ArgAction::Count = flag.get_action() {
                write!(
                    &mut buffer,
                    "{:indent$}isRepeatable: true,\n",
                    "",
                    indent = indent + 4
                )
                .unwrap();
            }

            write!(&mut buffer, "{:indent$}}},\n", "", indent = indent + 2).unwrap();
        }

        write!(&mut buffer, "{:indent$}],\n", "", indent = indent).unwrap();
    }

    buffer
}

fn gen_args(arg: &Arg, indent: usize) -> String {
    if !arg.get_num_args().expect("built").takes_values() {
        return "".to_string();
    }

    let mut buffer = String::new();

    write!(
        &mut buffer,
        "{{\n{:indent$}  name: \"{}\",\n",
        "",
        escape_string(arg.get_id().as_str()),
        indent = indent
    )
    .unwrap();

    let num_args = arg.get_num_args().expect("built");
    if num_args != builder::ValueRange::EMPTY && num_args != builder::ValueRange::SINGLE {
        write!(
            &mut buffer,
            "{:indent$}isVariadic: true,\n",
            "",
            indent = indent + 2
        )
        .unwrap();
    }

    if !arg.is_required_set() {
        write!(
            &mut buffer,
            "{:indent$}isOptional: true,\n",
            "",
            indent = indent + 2
        )
        .unwrap();
    }

    if let Some(data) = generator::utils::possible_values(arg) {
        write!(
            &mut buffer,
            "{:indent$}suggestions: [\n",
            "",
            indent = indent + 2
        )
        .unwrap();

        for value in data {
            if let Some(help) = value.get_help() {
                write!(
                    &mut buffer,
                    "{:indent$}{{\n{:indent$}  name: \"{}\",\n",
                    "",
                    "",
                    escape_string(value.get_name()),
                    indent = indent + 4,
                )
                .unwrap();

                write!(
                    &mut buffer,
                    "{:indent$}description: \"{}\",\n",
                    "",
                    escape_string(help),
                    indent = indent + 6
                )
                .unwrap();

                write!(&mut buffer, "{:indent$}}},\n", "", indent = indent + 4).unwrap();
            } else {
                write!(
                    &mut buffer,
                    "{:indent$}\"{}\",\n",
                    "",
                    escape_string(value.get_name()),
                    indent = indent + 4,
                )
                .unwrap();
            }
        }

        write!(&mut buffer, "{:indent$}],\n", "", indent = indent + 2).unwrap();
    } else {
        match arg.get_value_hint() {
            ValueHint::AnyPath | ValueHint::FilePath | ValueHint::ExecutablePath => {
                write!(
                    &mut buffer,
                    "{:indent$}template: \"filepaths\",\n",
                    "",
                    indent = indent + 2
                )
                .unwrap();
            }
            ValueHint::DirPath => {
                write!(
                    &mut buffer,
                    "{:indent$}template: \"folders\",\n",
                    "",
                    indent = indent + 2
                )
                .unwrap();
            }
            ValueHint::CommandString | ValueHint::CommandName | ValueHint::CommandWithArguments => {
                write!(
                    &mut buffer,
                    "{:indent$}isCommand: true,\n",
                    "",
                    indent = indent + 2
                )
                .unwrap();
            }
            // Disable completion for others
            _ => (),
        };
    };

    write!(&mut buffer, "{:indent$}}},\n", "", indent = indent).unwrap();

    buffer
}

fn arg_conflicts(cmd: &Command, arg: &Arg) -> Vec<String> {
    let mut res = vec![];

    for conflict in cmd.get_arg_conflicts_with(arg) {
        if let Some(s) = conflict.get_short() {
            res.push(format!("-{}", escape_string(&s.to_string())));
        }

        if let Some(l) = conflict.get_long() {
            res.push(format!("--{}", escape_string(l)));
        }
    }

    res
}
<|endoftext|>


<commit_before>use std::thread;
use std::time::Duration;

fn simulated_expensive_calculation(intensity: u32) -> u32 {
    println!("calculating slowly...");
    thread::sleep(Duration::from_secs(2));
    intensity
}

fn main() {
    let simulated_user_specified_value = 10;
    let simulated_randon_number = 7;

    generate_workout(simulated_user_specified_value, simulated_randon_number);
}

fn generate_workout(intensity: u32, random_number: u32) {
    if intensity < 25 {
        println!(
            "Today, do {} pushups!",
            simulated_expensive_calculation(intensity)
        );
        println!(
            "Next, do {} situps!",
            simulated_expensive_calculation(intensity)
        );
    } else {
        if random_number == 3 {
            println!("Take a break today! Remember to stay hydrated!");
        } else {
            println!(
                "Today, run for {} minutes!",
                simulated_expensive_calculation(intensity)
            );
        }
    }
}
<commit_msg>use closure for calculation<commit_after>use std::thread;
use std::time::Duration;

fn main() {
    let simulated_user_specified_value = 10;
    let simulated_randon_number = 7;

    generate_workout(simulated_user_specified_value, simulated_randon_number);
}

fn generate_workout(intensity: u32, random_number: u32) {

    let expensive_closure = |num| {
    println!("calculating slowly...");
    thread::sleep(Duration::from_secs(2));
    num
    };

    if intensity < 25 {
        println!(
            "Today, do {} pushups!",
            expensive_closure(intensity)
        );
        println!(
            "Next, do {} situps!",
            expensive_closure(intensity)
        );
    } else {
        if random_number == 3 {
            println!("Take a break today! Remember to stay hydrated!");
        } else {
            println!(
                "Today, run for {} minutes!",
                expensive_closure(intensity)
            );
        }
    }
}
<|endoftext|>


<commit_before>#![allow(unused_variables)]
#![allow(unused_constant)]
#![allow(unused_mut)]
fn main() {
    // Constants
    const MAX_POINTS: u32 = 100_000;

    // Mutability
    let mut x = 5;
    println!("The value of x is: {}", x);
    x = 6;
    println!("The value of x is: {}", x);

    // Shadowing
    let x = x + 1;
    let x = x * 2;
    println!("The value of x is: {}", x);

    let spaces = "   ";
    let spaces = spaces.len();
    println!("The value of spaces is: {}", spaces);

    let mut spaces = "      ";
    let spaces = spaces.len();
    println!("The value of spaces is: {}", spaces);
}
<commit_msg>Changed an allow statement<commit_after>#![allow(unused_variables)]
#![allow(unused_mut)]
#![allow(dead_code)]
fn main() {
    // Constants
    const MAX_POINTS: u32 = 100_000;

    // Mutability
    let mut x = 5;
    println!("The value of x is: {}", x);
    x = 6;
    println!("The value of x is: {}", x);

    // Shadowing
    let x = x + 1;
    let x = x * 2;
    println!("The value of x is: {}", x);

    let spaces = "   ";
    let spaces = spaces.len();
    println!("The value of spaces is: {}", spaces);

    let mut spaces = "      ";
    let spaces = spaces.len();
    println!("The value of spaces is: {}", spaces);
}
<|endoftext|>


<commit_before>use std::io::{Error, ErrorKind};
use std::result::Result;
use lua;

fn to_result(status: lua::ThreadStatus) -> Result<(), Error> {
    match status {
        lua::ThreadStatus::Ok => Ok(()),
        lua::ThreadStatus::RuntimeError => Err(Error::new(ErrorKind::Other, "Runtime Error")),
        lua::ThreadStatus::SyntaxError => Err(Error::new(ErrorKind::Other, "Syntax Error")),
        lua::ThreadStatus::MemoryError => Err(Error::new(ErrorKind::Other, "Memory Error")),
        lua::ThreadStatus::GcError => Err(Error::new(ErrorKind::Other, "Gc Error")),
        lua::ThreadStatus::MessageHandlerError => Err(Error::new(ErrorKind::Other, "MessageHandler Error")),
        lua::ThreadStatus::FileError => Err(Error::new(ErrorKind::Other, "File Error")),
        _ => Err(Error::new(ErrorKind::Other, "Unknown Error")),
    }
}

fn load_arms_library(mut state: &mut lua::State) -> Result<(), Error> {
    let library = include_bytes!("../../../rocks/arms/arms.out");

    try!(to_result(state.load_bufferx(library, "arms", "b")));
    try!(to_result(state.pcall(0, 0, 0)));
    Ok(())
}

fn load_prelude(mut state: &mut lua::State) -> Result<(), Error> {
    let prelude = "
        Arms = require 'arms'
        map = Arms.map
        trigger = Arms.trigger
        messages = Arms.messages
        terrain = Arms.terrain
        unit = Arms.unit
        messages = Arms.messages
    ";
    to_result(state.do_string(prelude))
}

fn load_config(mut state: &mut lua::State, seed: u32, num_players: u8) -> Result<(), Error> {
    let config = &format!("
        Arms:_set_random_map_seed({seed})
        Arms:_set_number_of_players({players})
    ", seed = seed, players = num_players);
    to_result(state.do_string(config))
}

// Whelp this function looks like a mess! :D
pub fn run_lua(text: &str) -> Result<String, Error> {
    let mut lua = lua::State::new();
    lua.open_libs(); // TODO don't open os/io/package perhaps

    let result = load_arms_library(&mut lua)
        .and_then(|_| load_prelude(&mut lua))
        .and_then(|_| load_config(&mut lua, 1, 2))
        .and_then(|_| to_result(lua.do_string(text)))
        .and_then(|_| to_result(lua.do_string("return require('arms'):to_string()")))
        .or_else(|err| {
            println!("Error: {}", lua.to_str(1).unwrap());
            Err(err)
        });

    try!(result);

    Ok(String::from(lua.check_string(1)))
}
<commit_msg>Fix running map scripts that return a value<commit_after>use std::io::{Error, ErrorKind};
use std::result::Result;
use lua;

fn to_result(status: lua::ThreadStatus) -> Result<(), Error> {
    match status {
        lua::ThreadStatus::Ok => Ok(()),
        lua::ThreadStatus::RuntimeError => Err(Error::new(ErrorKind::Other, "Runtime Error")),
        lua::ThreadStatus::SyntaxError => Err(Error::new(ErrorKind::Other, "Syntax Error")),
        lua::ThreadStatus::MemoryError => Err(Error::new(ErrorKind::Other, "Memory Error")),
        lua::ThreadStatus::GcError => Err(Error::new(ErrorKind::Other, "Gc Error")),
        lua::ThreadStatus::MessageHandlerError => Err(Error::new(ErrorKind::Other, "MessageHandler Error")),
        lua::ThreadStatus::FileError => Err(Error::new(ErrorKind::Other, "File Error")),
        _ => Err(Error::new(ErrorKind::Other, "Unknown Error")),
    }
}

fn load_arms_library(mut state: &mut lua::State) -> Result<(), Error> {
    let library = include_bytes!("../../../rocks/arms/arms.out");

    try!(to_result(state.load_bufferx(library, "arms", "b")));
    try!(to_result(state.pcall(0, 0, 0)));
    Ok(())
}

fn load_prelude(mut state: &mut lua::State) -> Result<(), Error> {
    let prelude = "
        Arms = require 'arms'
        map = Arms.map
        trigger = Arms.trigger
        messages = Arms.messages
        terrain = Arms.terrain
        unit = Arms.unit
        messages = Arms.messages
    ";
    to_result(state.do_string(prelude))
}

fn load_config(mut state: &mut lua::State, seed: u32, num_players: u8) -> Result<(), Error> {
    let config = &format!("
        Arms:_set_random_map_seed({seed})
        Arms:_set_number_of_players({players})
    ", seed = seed, players = num_players);
    to_result(state.do_string(config))
}

// Validate source code by parsing it.
fn validate_source(mut state: &mut lua::State, source: &str) -> Result<(), Error> {
    // Attempt to load the source.
    try!(to_result(state.load_string(source)));
    // Unload source if it parsed successfully.
    state.pop(1);
    Ok(())
}

fn run_noreturn(mut state: &mut lua::State, text: &str) -> Result<(), Error> {
    try!(validate_source(state, text));
    // Wrap the source in a function so top-level returns don't break us.
    to_result(state.do_string(&format!("
        (function()
            {}
        end)()
    ", text)))
}

// Whelp this function looks like a mess! :D
pub fn run_lua(text: &str) -> Result<String, Error> {
    let mut lua = lua::State::new();
    lua.open_libs(); // TODO don't open os/io/package perhaps

    let result = load_arms_library(&mut lua)
        .and_then(|_| load_prelude(&mut lua))
        .and_then(|_| load_config(&mut lua, 1, 2))
        .and_then(|_| run_noreturn(&mut lua, text))
        .and_then(|_| to_result(lua.do_string("return require('arms'):to_string()")))
        .or_else(|err| {
            println!("Error: {}", lua.to_str(1).unwrap());
            Err(err)
        });

    try!(result);

    Ok(String::from(lua.check_string(1)))
}
<|endoftext|>


<commit_before>extern crate proc_macro;

use proc_macro::TokenStream;
use proc_macro_hack::proc_macro_hack;
use proc_macro2::Span;
use quote::quote;

#[proc_macro_hack]
pub fn media_type(tokens: TokenStream) -> TokenStream {
    let lit_str = syn::parse_macro_input!(tokens as syn::LitStr);

    let mime = match parse_mime_lit(&lit_str.value()) {
        Ok(mime) => mime,
        Err(msg) => {
            let err = syn::Error::new(Span::call_site(), msg);
            return err.to_compile_error().into();
        }
    };

    let slash = mime.slash;
    let plus = match mime.plus {
        Some(i) => quote! { ::std::option::Option::Some(#i) },
        None => quote! { ::std::option::Option::None },
    };
    let params = match mime.params {
        mime_parse::ParamSource::None => quote! { $crate::private::ParamSource::None },
        mime_parse::ParamSource::Utf8(i) => quote! { $crate::private::ParamSource::Utf8(#i) },
        _ => unreachable!("custom params quote"),
    };

    let out = quote! {
        unsafe { $crate::MediaType::private_from_proc_macro(#lit_str, #slash, #plus, #params) }
    };
    out.into()
}

fn parse_mime_lit(value: &str) -> Result<mime_parse::Mime, String> {
    for c in value.chars() {
        if c.is_ascii_uppercase() {
            return Err("uppercase MediaTypes not supported yet".into())
        }
    }

    let mime = mime_parse::parse(
        value,
        mime_parse::CanRange::No,
        |s, _| mime_parse::Source::Dynamic(s.into())
    );

    match mime {
        Ok(mime) => match mime.params {
            mime_parse::ParamSource::None |
            mime_parse::ParamSource::Utf8(_) => Ok(mime),
            _ => Err("MediaType custom parameters not supported yet".into())
        },
        Err(err) => {
            Err(format!("invalid MediaType: {}", err))
        }
    }
}
<commit_msg>fix macro for interning utf8 params<commit_after>extern crate proc_macro;

use proc_macro::TokenStream;
use proc_macro_hack::proc_macro_hack;
use proc_macro2::Span;
use quote::quote;

#[proc_macro_hack]
pub fn media_type(tokens: TokenStream) -> TokenStream {
    let lit_str = syn::parse_macro_input!(tokens as syn::LitStr);

    let mime = match parse_mime_lit(&lit_str.value()) {
        Ok(mime) => mime,
        Err(msg) => {
            let err = syn::Error::new(Span::call_site(), msg);
            return err.to_compile_error().into();
        }
    };

    let slash = mime.slash;
    let plus = match mime.plus {
        Some(i) => quote! { ::std::option::Option::Some(#i) },
        None => quote! { ::std::option::Option::None },
    };
    let params = match mime.params {
        mime_parse::ParamSource::None => quote! { $crate::private::ParamSource::None },
        mime_parse::ParamSource::Utf8(i) => quote! { $crate::private::ParamSource::Utf8(#i) },
        _ => unreachable!("custom params quote"),
    };

    let out = quote! {
        unsafe { $crate::MediaType::private_from_proc_macro(#lit_str, #slash, #plus, #params) }
    };
    out.into()
}

fn parse_mime_lit(value: &str) -> Result<mime_parse::Mime, String> {
    for c in value.chars() {
        if c.is_ascii_uppercase() {
            return Err("uppercase MediaTypes not supported yet".into())
        }
    }

    let mime = mime_parse::parse(
        value,
        mime_parse::CanRange::No,
        |s, _, _| mime_parse::Source::Dynamic(s.into())
    );

    match mime {
        Ok(mime) => match mime.params {
            mime_parse::ParamSource::None |
            mime_parse::ParamSource::Utf8(_) => Ok(mime),
            _ => Err("MediaType custom parameters not supported yet".into())
        },
        Err(err) => {
            Err(format!("invalid MediaType: {}", err))
        }
    }
}
<|endoftext|>


<commit_before>// vim: tw=80

use mockall::*;
use mockall::expectation;
use std::rc::Rc;

#[test]
fn match_eq_ok() {
    expectation!{foo, (), [i32], [&x], [x], [p], [i32]}
    let mut e = foo::Expectation::default();
    e.returning(|_| ());
    e.with(predicate::eq(5));
    e.call(5);
}

#[test]
#[should_panic]
fn match_eq_fail() {
    expectation!{foo, (), [i32], [&x], [x], [p], [i32]}
    let mut e = foo::Expectation::default();
    e.returning(|_| ());
    e.with(predicate::eq(4));
    e.call(5);
}

#[test]
fn match_fn_ok() {
    expectation!{foo, (), [i32], [&x], [x], [p], [i32]}
    let mut e = foo::Expectation::default();
    e.returning(|_| ());
    e.withf(|x: &i32| *x == 5);
    e.call(5);
}

#[test]
#[should_panic]
fn match_fn_fail() {
    expectation!{foo, (), [i32], [&x], [x], [p], [i32]}
    let mut e = foo::Expectation::default();
    e.returning(|_| ());
    e.withf(|x: &i32| *x == 6);
    e.call(5);
}

mod reference_argument {
    use super::*;

    mockall::expectation!{foo, u32,
        [&u32], [&i0], [i0], [p0], [u32]}

    #[test]
    fn t() {
        let mut e = foo::Expectation::default();
        e.with(predicate::eq(42u32))
            .returning(|x| *x);
        let x = 42u32;
        assert_eq!(42u32, e.call(&x));
    }

    #[test]
    fn match_fn() {
        let mut e = foo::Expectation::default();
        e.withf(|x| *x == 42)
            .returning(|x| *x);
        let x = 42u32;
        assert_eq!(42u32, e.call(&x));
    }
}

mod ref_and_nonref_arguments {
    use super::*;

    mockall::expectation!{foo, i32,
        [i32, &u16],
        [&i0, i1],
        [i0, i1],
        [p0, p1],
        [i32, u16]
    }

    #[test]
    fn t() {
        let mut e = foo::Expectation::default();
        e.with(predicate::eq(42), predicate::eq(1))
            .returning(|x, y| x + i32::from(*y));
        let x = 42i32;
        let y = 1u16;
        assert_eq!(43i32, e.call(x, &y));
    }

    #[test]
    fn match_fn() {
        let mut e = foo::Expectation::default();
        e.withf(|x, y| *x == i32::from(*y))
            .returning(|x, y| x + i32::from(*y));
        let x = 42i32;
        let y = 42u16;
        assert_eq!(84i32, e.call(x, &y));
    }
}

mod reference_arguments {
    use super::*;

    mockall::expectation!{foo, u32,
        [&u32, &u16],
        [i0, i1],
        [i0, i1],
        [p0, p1],
        [u32, u16]
    }

    #[test]
    fn t() {
        let mut e = foo::Expectation::default();
        e.with(predicate::eq(42), predicate::eq(1))
            .returning(|x, y| *x + u32::from(*y));
        let x = 42u32;
        let y = 1u16;
        assert_eq!(43u32, e.call(&x, &y));
    }
}

/// A MockObject with a method that takes &mut self like:
/// fn foo(&mut self, x: i32) -> u32
#[test]
fn mutable_self() {
    expectation!{foo, i32, [i32], [&x], [x], [p], [i32]}
    let mut e = foo::Expectation::default();
    let mut count = 0;
    e.returning(move |x| {
            count += x;
            count
        });
    assert_eq!(5, e.call(5));
    assert_eq!(10, e.call(5));
}

///// A mock struct has two different methods with the same name, from different
///// traits.  Neither automock nor mock! can handle this; manual mocking is
///// required.
/////
///// The key is changing the ident names used to store the expectations.  Use
///// "traitname_methodname" as the identifier names, and in the expectation
///// methods' names.
//mod name_conflict {
    //trait Foo {
        //fn meth(&self) -> u32;
    //}
    //trait Bar {
        //fn meth(&self) -> u32;
    //}

    //#[derive(Default)]
    //struct MockA {
        //foo_meth: ::mockall::Expectation<(), u32>,
        //bar_meth: ::mockall::Expectation<(), u32>,
    //}
    //impl MockA {
        //fn expect_foo_meth(&mut self) -> &mut ::mockall::Expectation<(), u32>
        //{
            //self.foo_meth = ::mockall::Expectation::new();
            //&mut self.foo_meth
        //}
        //fn expect_bar_meth(&mut self) -> &mut ::mockall::Expectation<(), u32>
        //{
            //self.bar_meth = ::mockall::Expectation::new();
            //&mut self.bar_meth
        //}
    //}
    //impl Foo for MockA {
        //fn meth(&self) -> u32 {
            //self.foo_meth.call(())
        //}
    //}
    //impl Bar for MockA {
        //fn meth(&self) -> u32 {
            //self.bar_meth.call(())
        //}
    //}

    //#[test]
    //fn t() {
        //let mut mock = MockA::default();
        //mock.expect_foo_meth().returning(|_| 5);
        //mock.expect_bar_meth().returning(|_| 6);
        //assert_eq!(5, Foo::meth(&mock));
        //assert_eq!(6, Bar::meth(&mock));
    //}
//}

#[test]
fn never_ok() {
    expectation!{foo, (), [], [], [], [], []}
    let mut e = foo::Expectation::default();
    e.returning(|| ());
    e.never();
}

#[test]
#[should_panic(expected = "Expectation should not have been called")]
fn never_fail() {
    expectation!{foo, (), [], [], [], [], []}
    let mut e = foo::Expectation::default();
    e.returning(|| ());
    e.never();
    e.call();
}

/// A MockObject with a method that has no arguments or returns
/// fn foo(&self)
#[test]
fn no_args_or_returns() {
    expectation!{foo, (), [], [], [], [], []}
    let mut e = foo::Expectation::default();
    e.returning(|| ());
    e.call();
}

#[test]
fn non_send() {
    expectation!{
        foo, Rc<u32>,
        [Rc<u32>], [&x], [x], [p], [Rc<u32>]
    }
    let mut e = foo::Expectation::default();
    let y = Rc::new(43u32);
    e.returning_st(move |_| y.clone());
    let x = Rc::new(42u32);
    assert_eq!(43, *e.call(x).as_ref());
}

pub struct MyType(Rc<u32>);
#[test]
fn non_send_nor_clone() {
    expectation!{
        foo, MyType,
        [MyType], [&x], [x], [p], [MyType]
    }
    let mut e = foo::Expectation::default();
    let y = MyType(Rc::new(43u32));
    e.return_once_st(move |_| y);
    let x = MyType(Rc::new(42u32));
    assert_eq!(43, *e.call(x).0.as_ref());
}

#[test]
fn return_const() {
    expectation!{ foo, u32, [], [], [], [], [] }
    let mut e = foo::Expectation::default();
    e.return_const(42u32);
    assert_eq!(42, e.call());
}

/// Expectations return O::default() unless otherwise specified
#[test]
#[cfg_attr(not(feature = "nightly"), ignore)]
fn return_default() {
    expectation!{ foo, u32, [], [], [], [], []}
    let e = foo::Expectation::default();
    let r = e.call();
    assert_eq!(u32::default(), r);
}

pub struct NonDefault{}
/// Can't return default for types that aren't Default
#[test]
#[should_panic]
fn return_default_panics_for_non_default_types() {
    expectation!{ foo, NonDefault, [], [], [], [], [] }
    let e = foo::Expectation::default();
    let _: NonDefault = e.call();
}

pub struct NonCopy{}

#[test]
fn return_owned() {
    expectation!{foo, NonCopy, [], [], [], [], []}
    let mut e = foo::Expectation::default();
    let r = NonCopy{};
    e.return_once(|| r);
    e.call();
}

#[test]
#[should_panic(expected = "expected only once")]
fn return_owned_too_many_times() {
    expectation!{foo, NonCopy, [], [], [], [], []}
    let mut e = foo::Expectation::default();
    let r = NonCopy{};
    e.return_once(|| r);
    e.call();
    e.call();
}

#[test]
#[should_panic(expected = "exact call count")]
fn sequence_ambiguous() {
    expectation!{foo, (), [], [], [], [], []}
    let mut seq = Sequence::new();
    let mut e0 = foo::Expectation::default();
    e0.times_range(1..3);
    e0.in_sequence(&mut seq);
    e0.call();
}

#[test]
#[should_panic(expected = "Method sequence violation")]
fn sequence_fail() {
    expectation!{foo, (), [], [], [], [], []}
    let mut seq = Sequence::new();
    let mut e0 = foo::Expectation::default();
    e0.times(1);
    e0.returning(|| ());
    e0.in_sequence(&mut seq);

    let mut e1 = foo::Expectation::default();
    e1.times(1);
    e1.returning(|| ());
    e1.in_sequence(&mut seq);

    e1.call();
    e0.call();
}

#[test]
fn sequence_ok() {
    expectation!{foo, (), [], [], [], [], []}
    let mut seq = Sequence::new();
    let mut e0 = foo::Expectation::default();
    e0.times(1);
    e0.returning(|| ());
    e0.in_sequence(&mut seq);

    let mut e1 = foo::Expectation::default();
    e1.times(1);
    e1.returning(|| ());
    e1.in_sequence(&mut seq);

    e0.call();
    e1.call();
}

/// A MockObject with a simple method like:
/// fn foo(&self, x: i32) -> u32
#[test]
fn simple_method() {
    expectation!{foo, u32, [i32], [&x], [x], [p], [i32]}
    let mut e = foo::Expectation::default();
    e.returning(|_| 42);
    let r = e.call(5);
    assert_eq!(42, r);
}

/////// Mocking static methods requires using globals
////mod static_method {
    ////use std::sync::Mutex;
    ////use super::*;

    ////mockall::lazy_static! {
        ////static ref GLOBAL_EXPECTATIONS: Mutex<Expectations<(i32), u32>> =
            ////Mutex::new(Expectations::new());
    ////}

    /////// The contorted syntax mimics what mockall_derive does.
    ////#[test]
    ////fn t() {
        ////{
            ////let mut eguard = {
                ////let guard = GLOBAL_EXPECTATIONS.lock().unwrap();
                ////ExpectationGuard::new(guard)
            ////};
            ////eguard.returning(|_| 42);
        ////}

        ////assert_eq!(42, GLOBAL_EXPECTATIONS.lock().unwrap().call(5));
    ////}
////}

#[test]
fn times_any() {
    expectation!{foo, (), [], [], [], [], []}
    let mut e = foo::Expectation::default();
    e.returning(|| ());
    e.times(1);
    e.times_any();
    e.call();
    e.call();
}

#[test]
fn times_ok() {
    expectation!{foo, (), [], [], [], [], []}
    let mut e = foo::Expectation::default();
    e.returning(|| ());
    e.times(2);
    e.call();
    e.call();
}

#[test]
#[should_panic(expected = "Expectation called fewer than 2 times")]
fn times_too_few() {
    expectation!{foo, (), [], [], [], [], []}
    let mut e = foo::Expectation::default();
    e.returning(|| ());
    e.times(2);
    e.call();
}

#[test]
#[should_panic(expected = "Expectation called more than 2 times")]
fn times_too_many() {
    expectation!{foo, (), [], [], [], [], []}
    let mut e = foo::Expectation::default();
    e.returning(|| ());
    e.times(2);
    e.call();
    e.call();
    e.call();
    // Verify that we panic quickly and don't reach code below this point.
    panic!("Shouldn't get here!");
}

#[test]
fn times_range_ok() {
    expectation!{foo, (), [], [], [], [], []}
    let mut e0 = foo::Expectation::default();
    e0.returning(|| ());
    e0.times_range(2..4);
    e0.call();
    e0.call();

    let mut e1 = foo::Expectation::default();
    e1.returning(|| ());
    e1.times_range(2..4);
    e1.call();
    e1.call();
    e1.call();
}

#[test]
#[should_panic(expected = "Expectation called fewer than 2 times")]
fn times_range_too_few() {
    expectation!{foo, (), [], [], [], [], []}
    let mut e = foo::Expectation::default();
    e.returning(|| ());
    e.times_range(2..4);
    e.call();
}

#[test]
#[should_panic(expected = "Expectation called more than 3 times")]
fn times_range_too_many() {
    expectation!{foo, (), [], [], [], [], []}
    let mut e = foo::Expectation::default();
    e.returning(|| ());
    e.times_range(2..4);
    e.call();
    e.call();
    e.call();
    e.call();
    // Verify that we panic quickly and don't reach code below this point.
    panic!("Shouldn't get here!");
}
<commit_msg>Add tests for matching slice arguments.<commit_after>// vim: tw=80

use mockall::*;
use mockall::expectation;
use std::rc::Rc;

#[test]
fn match_eq_ok() {
    expectation!{foo, (), [i32], [&x], [x], [p], [i32]}
    let mut e = foo::Expectation::default();
    e.returning(|_| ());
    e.with(predicate::eq(5));
    e.call(5);
}

#[test]
#[should_panic]
fn match_eq_fail() {
    expectation!{foo, (), [i32], [&x], [x], [p], [i32]}
    let mut e = foo::Expectation::default();
    e.returning(|_| ());
    e.with(predicate::eq(4));
    e.call(5);
}

#[test]
fn match_fn_ok() {
    expectation!{foo, (), [i32], [&x], [x], [p], [i32]}
    let mut e = foo::Expectation::default();
    e.returning(|_| ());
    e.withf(|x: &i32| *x == 5);
    e.call(5);
}

#[test]
#[should_panic]
fn match_fn_fail() {
    expectation!{foo, (), [i32], [&x], [x], [p], [i32]}
    let mut e = foo::Expectation::default();
    e.returning(|_| ());
    e.withf(|x: &i32| *x == 6);
    e.call(5);
}

#[test]
fn match_slice_ok() {
    expectation!{foo, (), [&[u8]], [x], [x], [p], [[u8]]}
    let mut e = foo::Expectation::default();
    e.withf(|sl| sl == &[1, 2, 3])
        .returning(|_| ());
    let x = vec![1, 2, 3];
    e.call(&x);
}

#[test]
#[should_panic]
fn match_slice_fail() {
    expectation!{foo, (), [&[u8]], [x], [x], [p], [[u8]]}
    let mut e = foo::Expectation::default();
    e.withf(|sl| sl == &[1, 2, 3])
        .returning(|_| ());
    let x = vec![1, 2, 3, 4];
    e.call(&x);
}

mod reference_argument {
    use super::*;

    mockall::expectation!{foo, u32,
        [&u32], [&i0], [i0], [p0], [u32]}

    #[test]
    fn t() {
        let mut e = foo::Expectation::default();
        e.with(predicate::eq(42u32))
            .returning(|x| *x);
        let x = 42u32;
        assert_eq!(42u32, e.call(&x));
    }

    #[test]
    fn match_fn() {
        let mut e = foo::Expectation::default();
        e.withf(|x| *x == 42)
            .returning(|x| *x);
        let x = 42u32;
        assert_eq!(42u32, e.call(&x));
    }
}

mod ref_and_nonref_arguments {
    use super::*;

    mockall::expectation!{foo, i32,
        [i32, &u16],
        [&i0, i1],
        [i0, i1],
        [p0, p1],
        [i32, u16]
    }

    #[test]
    fn t() {
        let mut e = foo::Expectation::default();
        e.with(predicate::eq(42), predicate::eq(1))
            .returning(|x, y| x + i32::from(*y));
        let x = 42i32;
        let y = 1u16;
        assert_eq!(43i32, e.call(x, &y));
    }

    #[test]
    fn match_fn() {
        let mut e = foo::Expectation::default();
        e.withf(|x, y| *x == i32::from(*y))
            .returning(|x, y| x + i32::from(*y));
        let x = 42i32;
        let y = 42u16;
        assert_eq!(84i32, e.call(x, &y));
    }
}

mod reference_arguments {
    use super::*;

    mockall::expectation!{foo, u32,
        [&u32, &u16],
        [i0, i1],
        [i0, i1],
        [p0, p1],
        [u32, u16]
    }

    #[test]
    fn t() {
        let mut e = foo::Expectation::default();
        e.with(predicate::eq(42), predicate::eq(1))
            .returning(|x, y| *x + u32::from(*y));
        let x = 42u32;
        let y = 1u16;
        assert_eq!(43u32, e.call(&x, &y));
    }
}

/// A MockObject with a method that takes &mut self like:
/// fn foo(&mut self, x: i32) -> u32
#[test]
fn mutable_self() {
    expectation!{foo, i32, [i32], [&x], [x], [p], [i32]}
    let mut e = foo::Expectation::default();
    let mut count = 0;
    e.returning(move |x| {
            count += x;
            count
        });
    assert_eq!(5, e.call(5));
    assert_eq!(10, e.call(5));
}

///// A mock struct has two different methods with the same name, from different
///// traits.  Neither automock nor mock! can handle this; manual mocking is
///// required.
/////
///// The key is changing the ident names used to store the expectations.  Use
///// "traitname_methodname" as the identifier names, and in the expectation
///// methods' names.
//mod name_conflict {
    //trait Foo {
        //fn meth(&self) -> u32;
    //}
    //trait Bar {
        //fn meth(&self) -> u32;
    //}

    //#[derive(Default)]
    //struct MockA {
        //foo_meth: ::mockall::Expectation<(), u32>,
        //bar_meth: ::mockall::Expectation<(), u32>,
    //}
    //impl MockA {
        //fn expect_foo_meth(&mut self) -> &mut ::mockall::Expectation<(), u32>
        //{
            //self.foo_meth = ::mockall::Expectation::new();
            //&mut self.foo_meth
        //}
        //fn expect_bar_meth(&mut self) -> &mut ::mockall::Expectation<(), u32>
        //{
            //self.bar_meth = ::mockall::Expectation::new();
            //&mut self.bar_meth
        //}
    //}
    //impl Foo for MockA {
        //fn meth(&self) -> u32 {
            //self.foo_meth.call(())
        //}
    //}
    //impl Bar for MockA {
        //fn meth(&self) -> u32 {
            //self.bar_meth.call(())
        //}
    //}

    //#[test]
    //fn t() {
        //let mut mock = MockA::default();
        //mock.expect_foo_meth().returning(|_| 5);
        //mock.expect_bar_meth().returning(|_| 6);
        //assert_eq!(5, Foo::meth(&mock));
        //assert_eq!(6, Bar::meth(&mock));
    //}
//}

#[test]
fn never_ok() {
    expectation!{foo, (), [], [], [], [], []}
    let mut e = foo::Expectation::default();
    e.returning(|| ());
    e.never();
}

#[test]
#[should_panic(expected = "Expectation should not have been called")]
fn never_fail() {
    expectation!{foo, (), [], [], [], [], []}
    let mut e = foo::Expectation::default();
    e.returning(|| ());
    e.never();
    e.call();
}

/// A MockObject with a method that has no arguments or returns
/// fn foo(&self)
#[test]
fn no_args_or_returns() {
    expectation!{foo, (), [], [], [], [], []}
    let mut e = foo::Expectation::default();
    e.returning(|| ());
    e.call();
}

#[test]
fn non_send() {
    expectation!{
        foo, Rc<u32>,
        [Rc<u32>], [&x], [x], [p], [Rc<u32>]
    }
    let mut e = foo::Expectation::default();
    let y = Rc::new(43u32);
    e.returning_st(move |_| y.clone());
    let x = Rc::new(42u32);
    assert_eq!(43, *e.call(x).as_ref());
}

pub struct MyType(Rc<u32>);
#[test]
fn non_send_nor_clone() {
    expectation!{
        foo, MyType,
        [MyType], [&x], [x], [p], [MyType]
    }
    let mut e = foo::Expectation::default();
    let y = MyType(Rc::new(43u32));
    e.return_once_st(move |_| y);
    let x = MyType(Rc::new(42u32));
    assert_eq!(43, *e.call(x).0.as_ref());
}

#[test]
fn return_const() {
    expectation!{ foo, u32, [], [], [], [], [] }
    let mut e = foo::Expectation::default();
    e.return_const(42u32);
    assert_eq!(42, e.call());
}

/// Expectations return O::default() unless otherwise specified
#[test]
#[cfg_attr(not(feature = "nightly"), ignore)]
fn return_default() {
    expectation!{ foo, u32, [], [], [], [], []}
    let e = foo::Expectation::default();
    let r = e.call();
    assert_eq!(u32::default(), r);
}

pub struct NonDefault{}
/// Can't return default for types that aren't Default
#[test]
#[should_panic]
fn return_default_panics_for_non_default_types() {
    expectation!{ foo, NonDefault, [], [], [], [], [] }
    let e = foo::Expectation::default();
    let _: NonDefault = e.call();
}

pub struct NonCopy{}

#[test]
fn return_owned() {
    expectation!{foo, NonCopy, [], [], [], [], []}
    let mut e = foo::Expectation::default();
    let r = NonCopy{};
    e.return_once(|| r);
    e.call();
}

#[test]
#[should_panic(expected = "expected only once")]
fn return_owned_too_many_times() {
    expectation!{foo, NonCopy, [], [], [], [], []}
    let mut e = foo::Expectation::default();
    let r = NonCopy{};
    e.return_once(|| r);
    e.call();
    e.call();
}

#[test]
#[should_panic(expected = "exact call count")]
fn sequence_ambiguous() {
    expectation!{foo, (), [], [], [], [], []}
    let mut seq = Sequence::new();
    let mut e0 = foo::Expectation::default();
    e0.times_range(1..3);
    e0.in_sequence(&mut seq);
    e0.call();
}

#[test]
#[should_panic(expected = "Method sequence violation")]
fn sequence_fail() {
    expectation!{foo, (), [], [], [], [], []}
    let mut seq = Sequence::new();
    let mut e0 = foo::Expectation::default();
    e0.times(1);
    e0.returning(|| ());
    e0.in_sequence(&mut seq);

    let mut e1 = foo::Expectation::default();
    e1.times(1);
    e1.returning(|| ());
    e1.in_sequence(&mut seq);

    e1.call();
    e0.call();
}

#[test]
fn sequence_ok() {
    expectation!{foo, (), [], [], [], [], []}
    let mut seq = Sequence::new();
    let mut e0 = foo::Expectation::default();
    e0.times(1);
    e0.returning(|| ());
    e0.in_sequence(&mut seq);

    let mut e1 = foo::Expectation::default();
    e1.times(1);
    e1.returning(|| ());
    e1.in_sequence(&mut seq);

    e0.call();
    e1.call();
}

/// A MockObject with a simple method like:
/// fn foo(&self, x: i32) -> u32
#[test]
fn simple_method() {
    expectation!{foo, u32, [i32], [&x], [x], [p], [i32]}
    let mut e = foo::Expectation::default();
    e.returning(|_| 42);
    let r = e.call(5);
    assert_eq!(42, r);
}

/////// Mocking static methods requires using globals
////mod static_method {
    ////use std::sync::Mutex;
    ////use super::*;

    ////mockall::lazy_static! {
        ////static ref GLOBAL_EXPECTATIONS: Mutex<Expectations<(i32), u32>> =
            ////Mutex::new(Expectations::new());
    ////}

    /////// The contorted syntax mimics what mockall_derive does.
    ////#[test]
    ////fn t() {
        ////{
            ////let mut eguard = {
                ////let guard = GLOBAL_EXPECTATIONS.lock().unwrap();
                ////ExpectationGuard::new(guard)
            ////};
            ////eguard.returning(|_| 42);
        ////}

        ////assert_eq!(42, GLOBAL_EXPECTATIONS.lock().unwrap().call(5));
    ////}
////}

#[test]
fn times_any() {
    expectation!{foo, (), [], [], [], [], []}
    let mut e = foo::Expectation::default();
    e.returning(|| ());
    e.times(1);
    e.times_any();
    e.call();
    e.call();
}

#[test]
fn times_ok() {
    expectation!{foo, (), [], [], [], [], []}
    let mut e = foo::Expectation::default();
    e.returning(|| ());
    e.times(2);
    e.call();
    e.call();
}

#[test]
#[should_panic(expected = "Expectation called fewer than 2 times")]
fn times_too_few() {
    expectation!{foo, (), [], [], [], [], []}
    let mut e = foo::Expectation::default();
    e.returning(|| ());
    e.times(2);
    e.call();
}

#[test]
#[should_panic(expected = "Expectation called more than 2 times")]
fn times_too_many() {
    expectation!{foo, (), [], [], [], [], []}
    let mut e = foo::Expectation::default();
    e.returning(|| ());
    e.times(2);
    e.call();
    e.call();
    e.call();
    // Verify that we panic quickly and don't reach code below this point.
    panic!("Shouldn't get here!");
}

#[test]
fn times_range_ok() {
    expectation!{foo, (), [], [], [], [], []}
    let mut e0 = foo::Expectation::default();
    e0.returning(|| ());
    e0.times_range(2..4);
    e0.call();
    e0.call();

    let mut e1 = foo::Expectation::default();
    e1.returning(|| ());
    e1.times_range(2..4);
    e1.call();
    e1.call();
    e1.call();
}

#[test]
#[should_panic(expected = "Expectation called fewer than 2 times")]
fn times_range_too_few() {
    expectation!{foo, (), [], [], [], [], []}
    let mut e = foo::Expectation::default();
    e.returning(|| ());
    e.times_range(2..4);
    e.call();
}

#[test]
#[should_panic(expected = "Expectation called more than 3 times")]
fn times_range_too_many() {
    expectation!{foo, (), [], [], [], [], []}
    let mut e = foo::Expectation::default();
    e.returning(|| ());
    e.times_range(2..4);
    e.call();
    e.call();
    e.call();
    e.call();
    // Verify that we panic quickly and don't reach code below this point.
    panic!("Shouldn't get here!");
}
<|endoftext|>


<commit_before>use std::num;

pub trait Addressable<ADDR: Int> {
	pub fn get (&self, addr: ADDR) -> u8;
	pub fn set (&mut self, addr: ADDR, data: u8);
}

// FIXME: With default methods, we won't need this anymore
pub trait AddressableUtil<ADDR: Int> {
	pub fn getx (&self, addr:ADDR, offset: int) -> u8;
	pub fn get_be_n (&self, addr: ADDR, nbytes: uint) -> u64;
	pub fn get_be<T: Int> (&self, addr: ADDR) -> T;
	pub fn get_le_n (&self, addr: ADDR, nbytes: uint) -> u64;
	pub fn get_le<T: Int> (&self, addr: ADDR) -> T;

	pub fn setx (&mut self, addr: ADDR, offset: int, data: u8);
	pub fn set_be_n (&mut self, addr: ADDR, nbytes: uint, val: u64);
	pub fn set_be<T: Int> (&mut self, addr: ADDR, val: T);
	pub fn set_le_n (&mut self, addr: ADDR, nbytes: uint, val: u64);
	pub fn set_le<T: Int> (&mut self, addr: ADDR, val: T);
}

impl<ADDR: Int, A: Addressable<ADDR>> AddressableUtil<ADDR> for A {
	pub fn getx (&self, addr:ADDR, offset: int) -> u8 {
		self.get(addr + num::cast(offset))
	}

	pub fn get_be_n (&self, addr: ADDR, nbytes: uint) -> u64 {
		assert!(nbytes > 0 && nbytes < 8);
		let mut val = 0u64;
		let mut i = nbytes;
		while i > 0 {
			i -= 1;
			val |= self.get(addr + num::cast(i)) as u64 << (nbytes-i-1) * 8;
		}
		val
	}

	pub fn get_be<T: Int> (&self, addr: ADDR) -> T {
		num::cast(self.get_be_n(addr, num::Primitive::bytes::<T>()))
	}

	pub fn get_le_n (&self, addr: ADDR, nbytes: uint) -> u64 {
		assert!(nbytes > 0 && nbytes < 8);
		let mut val = 0u64;
		let mut i = nbytes;
		while i > 0 {
			i -= 1;
			val |= self.get(addr + num::cast(i)) as u64 << i * 8;
		}
		val
	}

	pub fn get_le<T: Int> (&self, addr: ADDR) -> T {
		num::cast(self.get_le_n(addr, num::Primitive::bytes::<T>()))
	}

	pub fn setx (&mut self, addr: ADDR, offset: int, data: u8) {
		self.set(addr + num::cast(offset), data);
	}

	pub fn set_be_n (&mut self, addr: ADDR, nbytes: uint, val: u64) {
		assert!(nbytes > 0 && nbytes < 8);
		let mut i = nbytes;
		while i > 0 {
			i -= 1;
			self.set(addr + num::cast(i), (val >> (nbytes-i-1) * 8) as u8);
		}
	}

	pub fn set_be<T: Int> (&mut self, addr: ADDR, val: T) {
		self.set_be_n(addr, num::Primitive::bytes::<T>(), num::cast(val));
	}

	pub fn set_le_n (&mut self, addr: ADDR, nbytes: uint, val: u64) {
		assert!(nbytes > 0 && nbytes < 8);
		let mut i = nbytes;
		while i > 0 {
			i -= 1;
			self.set(addr + num::cast(i), (val >> i * 8) as u8);
		}
	}

	pub fn set_le<T: Int> (&mut self, addr: ADDR, val: T) {
		self.set_le_n(addr, num::Primitive::bytes::<T>(), num::cast(val));
	}
}

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

	struct DummyData;
	impl Addressable<u16> for DummyData {
		pub fn get (&self, addr: u16) -> u8 {
			addr as u8
		}
		pub fn set (&mut self, addr: u16, data: u8) {
			assert_eq!(data, addr as u8);
		}
	}

	#[test]
	fn test_get () {
		let data = DummyData;
		assert_eq!(data.get(0x0012), 0x12);
		assert_eq!(data.get(0x1234), 0x34);
	}

	#[test]
	fn test_getx () {
		let data = DummyData;
		assert_eq!(data.getx(0x0012_u16, 5), 0x17);
		assert_eq!(data.getx(0x1234_u16, 5), 0x39);
	}

	#[test]
	fn test_get_big_endian () {
		let data = DummyData;
		assert_eq!(      0x02_u8 , data.get_be(0x0002_u16));
		assert_eq!(      0x54_u8 , data.get_be(0x0054_u16));
		assert_eq!(    0x0203_u16, data.get_be(0x0002_u16));
		assert_eq!(    0x5455_u16, data.get_be(0x0054_u16));
		assert_eq!(0x02030405_u32, data.get_be(0x0002_u16));
		assert_eq!(0x54555657_u32, data.get_be(0x0054_u16));
	}

	#[test]
	fn test_get_signed_big_endian () {
		let data = DummyData;
		assert_eq!(       0x54_i8 , data.get_be(0x0054_u16));
		assert_eq!(      -0x5b_i8 , data.get_be(0x00a5_u16));
		assert_eq!(     0x5455_i16, data.get_be(0x0054_u16));
		assert_eq!(    -0x5a5a_i16, data.get_be(0x00a5_u16));
		assert_eq!( 0x54555657_i32, data.get_be(0x0054_u16));
		assert_eq!(-0x5a595858_i32, data.get_be(0x00a5_u16));
	}

	#[test]
	fn test_get_little_endian () {
		let data = DummyData;
		assert_eq!(      0x02_u8 , data.get_le(0x0002_u16));
		assert_eq!(      0x54_u8 , data.get_le(0x0054_u16));
		assert_eq!(    0x0302_u16, data.get_le(0x0002_u16));
		assert_eq!(    0x5554_u16, data.get_le(0x0054_u16));
		assert_eq!(0x05040302_u32, data.get_le(0x0002_u16));
		assert_eq!(0x57565554_u32, data.get_le(0x0054_u16));
	}

	#[test]
	fn test_get_signed_little_endian () {
		let data = DummyData;
		assert_eq!(       0x54_i8 , data.get_le(0x0054_u16));
		assert_eq!(      -0x5b_i8 , data.get_le(0x00a5_u16));
		assert_eq!(     0x5554_i16, data.get_le(0x0054_u16));
		assert_eq!(    -0x595b_i16, data.get_le(0x00a5_u16));
		assert_eq!( 0x57565554_i32, data.get_le(0x0054_u16));
		assert_eq!(-0x5758595b_i32, data.get_le(0x00a5_u16));
	}

	#[test]
	fn test_set () {
		let mut data = DummyData;
		data.set(0x0012, 0x12);
		data.set(0x1234, 0x34);
	}

	#[test]
	fn test_setx () {
		let mut data = DummyData;
		data.setx(0x0012_u16, 5, 0x17);
		data.setx(0x1234_u16, 5, 0x39);
	}

	#[test]
	fn test_set_big_endian () {
		let mut data = DummyData;
		data.set_be(0x0002_u16,       0x02_u8 );
		data.set_be(0x0054_u16,       0x54_u8 );
		data.set_be(0x0002_u16,     0x0203_u16);
		data.set_be(0x0054_u16,     0x5455_u16);
		data.set_be(0x0002_u16, 0x02030405_u32);
		data.set_be(0x0054_u16, 0x54555657_u32);
	}

	#[test]
	fn test_set_signed_big_endian () {
		let mut data = DummyData;
		data.set_be(0x0054_u16,        0x54_i8 );
		data.set_be(0x00a5_u16,       -0x5b_i8 );
		data.set_be(0x0054_u16,      0x5455_i16);
		data.set_be(0x00a5_u16,     -0x5a5a_i16);
		data.set_be(0x0054_u16,  0x54555657_i32);
		data.set_be(0x00a5_u16, -0x5a595858_i32);
	}

	#[test]
	fn test_set_little_endian () {
		let mut data = DummyData;
		data.set_le(0x0002_u16,       0x02_u8 );
		data.set_le(0x0054_u16,       0x54_u8 );
		data.set_le(0x0002_u16,     0x0302_u16);
		data.set_le(0x0054_u16,     0x5554_u16);
		data.set_le(0x0002_u16, 0x05040302_u32);
		data.set_le(0x0054_u16, 0x57565554_u32);
	}

	fn test_set_signed_little_endian () {
		let mut data = DummyData;
		data.set_le(0x0054_u16,        0x54_i8 );
		data.set_le(0x00a5_u16,       -0x5b_i8 );
		data.set_le(0x0054_u16,      0x5554_i16);
		data.set_le(0x00a5_u16,     -0x595b_i16);
		data.set_le(0x0054_u16,  0x57565554_i32);
		data.set_le(0x00a5_u16, -0x5758595b_i32);
	}
}
<commit_msg>Formatting<commit_after>use std::num;

pub trait Addressable<ADDR: Int> {
	pub fn get (&self, addr: ADDR) -> u8;
	pub fn set (&mut self, addr: ADDR, data: u8);
}

pub trait AddressableUtil<ADDR: Int> {
	pub fn getx (&self, addr:ADDR, offset: int) -> u8;
	pub fn get_be_n (&self, addr: ADDR, nbytes: uint) -> u64;
	pub fn get_be<T: Int> (&self, addr: ADDR) -> T;
	pub fn get_le_n (&self, addr: ADDR, nbytes: uint) -> u64;
	pub fn get_le<T: Int> (&self, addr: ADDR) -> T;

	pub fn setx (&mut self, addr: ADDR, offset: int, data: u8);
	pub fn set_be_n (&mut self, addr: ADDR, nbytes: uint, val: u64);
	pub fn set_be<T: Int> (&mut self, addr: ADDR, val: T);
	pub fn set_le_n (&mut self, addr: ADDR, nbytes: uint, val: u64);
	pub fn set_le<T: Int> (&mut self, addr: ADDR, val: T);
}

impl<ADDR: Int, A: Addressable<ADDR>> AddressableUtil<ADDR> for A {
	pub fn getx (&self, addr:ADDR, offset: int) -> u8 {
		self.get(addr + num::cast(offset))
	}

	pub fn get_be_n (&self, addr: ADDR, nbytes: uint) -> u64 {
		assert!(nbytes > 0 && nbytes < 8);
		let mut val = 0u64;
		let mut i = nbytes;
		while i > 0 {
			i -= 1;
			val |= self.get(addr + num::cast(i)) as u64 << (nbytes-i-1) * 8;
		}
		val
	}

	pub fn get_be<T: Int> (&self, addr: ADDR) -> T {
		num::cast(self.get_be_n(addr, num::Primitive::bytes::<T>()))
	}

	pub fn get_le_n (&self, addr: ADDR, nbytes: uint) -> u64 {
		assert!(nbytes > 0 && nbytes < 8);
		let mut val = 0u64;
		let mut i = nbytes;
		while i > 0 {
			i -= 1;
			val |= self.get(addr + num::cast(i)) as u64 << i * 8;
		}
		val
	}

	pub fn get_le<T: Int> (&self, addr: ADDR) -> T {
		num::cast(self.get_le_n(addr, num::Primitive::bytes::<T>()))
	}

	pub fn setx (&mut self, addr: ADDR, offset: int, data: u8) {
		self.set(addr + num::cast(offset), data);
	}

	pub fn set_be_n (&mut self, addr: ADDR, nbytes: uint, val: u64) {
		assert!(nbytes > 0 && nbytes < 8);
		let mut i = nbytes;
		while i > 0 {
			i -= 1;
			self.set(addr + num::cast(i), (val >> (nbytes-i-1) * 8) as u8);
		}
	}

	pub fn set_be<T: Int> (&mut self, addr: ADDR, val: T) {
		self.set_be_n(addr, num::Primitive::bytes::<T>(), num::cast(val));
	}

	pub fn set_le_n (&mut self, addr: ADDR, nbytes: uint, val: u64) {
		assert!(nbytes > 0 && nbytes < 8);
		let mut i = nbytes;
		while i > 0 {
			i -= 1;
			self.set(addr + num::cast(i), (val >> i * 8) as u8);
		}
	}

	pub fn set_le<T: Int> (&mut self, addr: ADDR, val: T) {
		self.set_le_n(addr, num::Primitive::bytes::<T>(), num::cast(val));
	}
}

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

	struct DummyData;
	impl Addressable<u16> for DummyData {
		pub fn get (&self, addr: u16) -> u8 {
			addr as u8
		}
		pub fn set (&mut self, addr: u16, data: u8) {
			assert_eq!(data, addr as u8);
		}
	}

	#[test]
	fn test_get () {
		let data = DummyData;
		assert_eq!(data.get(0x0012), 0x12);
		assert_eq!(data.get(0x1234), 0x34);
	}

	#[test]
	fn test_getx () {
		let data = DummyData;
		assert_eq!(data.getx(0x0012_u16, 5), 0x17);
		assert_eq!(data.getx(0x1234_u16, 5), 0x39);
	}

	#[test]
	fn test_get_big_endian () {
		let data = DummyData;
		assert_eq!(      0x02_u8 , data.get_be(0x0002_u16));
		assert_eq!(      0x54_u8 , data.get_be(0x0054_u16));
		assert_eq!(    0x0203_u16, data.get_be(0x0002_u16));
		assert_eq!(    0x5455_u16, data.get_be(0x0054_u16));
		assert_eq!(0x02030405_u32, data.get_be(0x0002_u16));
		assert_eq!(0x54555657_u32, data.get_be(0x0054_u16));
	}

	#[test]
	fn test_get_signed_big_endian () {
		let data = DummyData;
		assert_eq!(       0x54_i8 , data.get_be(0x0054_u16));
		assert_eq!(      -0x5b_i8 , data.get_be(0x00a5_u16));
		assert_eq!(     0x5455_i16, data.get_be(0x0054_u16));
		assert_eq!(    -0x5a5a_i16, data.get_be(0x00a5_u16));
		assert_eq!( 0x54555657_i32, data.get_be(0x0054_u16));
		assert_eq!(-0x5a595858_i32, data.get_be(0x00a5_u16));
	}

	#[test]
	fn test_get_little_endian () {
		let data = DummyData;
		assert_eq!(      0x02_u8 , data.get_le(0x0002_u16));
		assert_eq!(      0x54_u8 , data.get_le(0x0054_u16));
		assert_eq!(    0x0302_u16, data.get_le(0x0002_u16));
		assert_eq!(    0x5554_u16, data.get_le(0x0054_u16));
		assert_eq!(0x05040302_u32, data.get_le(0x0002_u16));
		assert_eq!(0x57565554_u32, data.get_le(0x0054_u16));
	}

	#[test]
	fn test_get_signed_little_endian () {
		let data = DummyData;
		assert_eq!(       0x54_i8 , data.get_le(0x0054_u16));
		assert_eq!(      -0x5b_i8 , data.get_le(0x00a5_u16));
		assert_eq!(     0x5554_i16, data.get_le(0x0054_u16));
		assert_eq!(    -0x595b_i16, data.get_le(0x00a5_u16));
		assert_eq!( 0x57565554_i32, data.get_le(0x0054_u16));
		assert_eq!(-0x5758595b_i32, data.get_le(0x00a5_u16));
	}

	#[test]
	fn test_set () {
		let mut data = DummyData;
		data.set(0x0012, 0x12);
		data.set(0x1234, 0x34);
	}

	#[test]
	fn test_setx () {
		let mut data = DummyData;
		data.setx(0x0012_u16, 5, 0x17);
		data.setx(0x1234_u16, 5, 0x39);
	}

	#[test]
	fn test_set_big_endian () {
		let mut data = DummyData;
		data.set_be(0x0002_u16,       0x02_u8 );
		data.set_be(0x0054_u16,       0x54_u8 );
		data.set_be(0x0002_u16,     0x0203_u16);
		data.set_be(0x0054_u16,     0x5455_u16);
		data.set_be(0x0002_u16, 0x02030405_u32);
		data.set_be(0x0054_u16, 0x54555657_u32);
	}

	#[test]
	fn test_set_signed_big_endian () {
		let mut data = DummyData;
		data.set_be(0x0054_u16,        0x54_i8 );
		data.set_be(0x00a5_u16,       -0x5b_i8 );
		data.set_be(0x0054_u16,      0x5455_i16);
		data.set_be(0x00a5_u16,     -0x5a5a_i16);
		data.set_be(0x0054_u16,  0x54555657_i32);
		data.set_be(0x00a5_u16, -0x5a595858_i32);
	}

	#[test]
	fn test_set_little_endian () {
		let mut data = DummyData;
		data.set_le(0x0002_u16,       0x02_u8 );
		data.set_le(0x0054_u16,       0x54_u8 );
		data.set_le(0x0002_u16,     0x0302_u16);
		data.set_le(0x0054_u16,     0x5554_u16);
		data.set_le(0x0002_u16, 0x05040302_u32);
		data.set_le(0x0054_u16, 0x57565554_u32);
	}

	fn test_set_signed_little_endian () {
		let mut data = DummyData;
		data.set_le(0x0054_u16,        0x54_i8 );
		data.set_le(0x00a5_u16,       -0x5b_i8 );
		data.set_le(0x0054_u16,      0x5554_i16);
		data.set_le(0x00a5_u16,     -0x595b_i16);
		data.set_le(0x0054_u16,  0x57565554_i32);
		data.set_le(0x00a5_u16, -0x5758595b_i32);
	}
}
<|endoftext|>