<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::str::FromStr;

use bindgen::items::Enum;

/// The type of identifier to be renamed.
#[derive(Debug, Clone, Copy)]
pub enum IdentifierType<'a> {
    StructMember,
    EnumVariant(&'a Enum),
    FunctionArg,
    Enum,
}
impl<'a> IdentifierType<'a> {
    fn to_str(&'a self) -> &'static str {
        match *self {
            IdentifierType::StructMember => "m",
            IdentifierType::EnumVariant(..) => "",
            IdentifierType::FunctionArg => "a",
            IdentifierType::Enum => "",
        }
    }
}

/// A rule to apply to an identifier when generating bindings.
#[derive(Debug, Clone, Copy)]
pub enum RenameRule {
    /// Do not apply any renaming. The default.
    None,
    /// Converts the identifier to PascalCase and adds a prefix based on where the identifier is used.
    GeckoCase,
    /// Converts the identifier to lower case.
    LowerCase,
    /// Converts the identifier to upper case.
    UpperCase,
    /// Converts the identifier to PascalCase.
    PascalCase,
    /// Converts the identifier to camelCase.
    CamelCase,
    /// Converts the identifier to snake_case.
    SnakeCase,
    /// Converts the identifier to SCREAMING_SNAKE_CASE.
    ScreamingSnakeCase,
    /// Converts the identifier to SCREAMING_SNAKE_CASE and prefixes enum variants
    /// with the enum name.
    QualifiedScreamingSnakeCase,
}

impl RenameRule {
    /// Applies the rename rule to a string that is formatted in PascalCase.
    pub fn apply_to_pascal_case(&self, text: &str, context: IdentifierType) -> String {
        if text.len() == 0 {
            return String::new();
        }

        match *self {
            RenameRule::None => String::from(text),
            RenameRule::GeckoCase => context.to_str().to_owned() + text,
            RenameRule::LowerCase => text.to_lowercase(),
            RenameRule::UpperCase => text.to_uppercase(),
            RenameRule::PascalCase => text.to_owned(),
            RenameRule::CamelCase => {
                text[..1].to_lowercase() + &text[1..]
            }
            RenameRule::SnakeCase => {
                let mut result = String::new();
                for (i, c) in text.char_indices() {
                    if c.is_uppercase() && i != 0 {
                        result.push_str("_");
                    }
                    for x in c.to_lowercase() {
                        result.push(x);
                    }
                }
                result
            }
            RenameRule::ScreamingSnakeCase => {
                // Same as SnakeCase code above, but uses to_uppercase
                let mut result = String::new();
                for (i, c) in text.char_indices() {
                    if c.is_uppercase() && i != 0 {
                        result.push_str("_");
                    }
                    for x in c.to_uppercase() {
                        result.push(x);
                    }
                }
                result
            }
            RenameRule::QualifiedScreamingSnakeCase => {
                let mut result = String::new();

                if let IdentifierType::EnumVariant(e) = context {
                    if let &RenameRule::QualifiedScreamingSnakeCase = self {
                        result.push_str(&RenameRule::ScreamingSnakeCase.apply_to_pascal_case(
                            &e.name, IdentifierType::Enum));
                        result.push_str("_");
                    }
                }

                result.push_str(&RenameRule::SnakeCase.apply_to_pascal_case(
                    &text, context));
                result
            }
        }
    }

    /// Applies the rename rule to a string that is formatted in snake_case.
    pub fn apply_to_snake_case(&self, mut text: &str, context: IdentifierType) -> String {
        if text.len() == 0 {
            return String::new();
        }

        match *self {
            RenameRule::None => String::from(text),
            RenameRule::GeckoCase => {
                if &text[..1] == "_" {
                    text = &text[1..];
                }

                context.to_str().to_owned() +
                    &RenameRule::PascalCase.apply_to_snake_case(text, context)
            }
            RenameRule::LowerCase => text.to_lowercase(),
            RenameRule::UpperCase => text.to_uppercase(),
            RenameRule::PascalCase => {
                let mut result = String::new();
                let mut is_uppercase = true;
                for c in text.chars() {
                    if c == '_' {
                        is_uppercase = true;
                        continue;
                    }

                    if is_uppercase {
                        for x in c.to_uppercase() {
                            result.push(x);
                        }
                        is_uppercase = false;
                    } else {
                        result.push(c);
                    }
                }
                result
            }
            RenameRule::CamelCase => {
                // Same as PascalCase code above, but is_uppercase = false to start
                let mut result = String::new();
                let mut is_uppercase = false;
                for c in text.chars() {
                    if c == '_' {
                        is_uppercase = true;
                        continue;
                    }

                    if is_uppercase {
                        for x in c.to_uppercase() {
                            result.push(x);
                        }
                        is_uppercase = false;
                    } else {
                        result.push(c);
                    }
                }
                result
            }
            RenameRule::SnakeCase => text.to_owned(),
            RenameRule::ScreamingSnakeCase => text.to_owned().to_uppercase(),
            RenameRule::QualifiedScreamingSnakeCase => {
                let mut result = String::new();

                if let IdentifierType::EnumVariant(e) = context {
                    if let &RenameRule::QualifiedScreamingSnakeCase = self {
                        result.push_str(&RenameRule::ScreamingSnakeCase.apply_to_snake_case(
                            &e.name, IdentifierType::Enum));
                        result.push_str("_");
                    }
                }

                result.push_str(&RenameRule::SnakeCase.apply_to_snake_case(
                    &text, context));
                result
            }
        }
    }
}

impl Default for RenameRule {
    fn default() -> RenameRule {
        RenameRule::None
    }
}

impl FromStr for RenameRule {
    type Err = String;

    fn from_str(s: &str) -> Result<RenameRule, Self::Err> {
        match s {
            "none" => Ok(RenameRule::None),
            "None" => Ok(RenameRule::None),

            "mGeckoCase" => Ok(RenameRule::GeckoCase),
            "GeckoCase" => Ok(RenameRule::GeckoCase),
            "gecko_case" => Ok(RenameRule::GeckoCase),

            "lowercase" => Ok(RenameRule::LowerCase),
            "LowerCase" => Ok(RenameRule::LowerCase),
            "lower_case" => Ok(RenameRule::LowerCase),

            "UPPERCASE" => Ok(RenameRule::UpperCase),
            "UpperCase" => Ok(RenameRule::UpperCase),
            "upper_case" => Ok(RenameRule::UpperCase),

            "PascalCase" => Ok(RenameRule::PascalCase),
            "pascal_case" => Ok(RenameRule::PascalCase),

            "camelCase" => Ok(RenameRule::CamelCase),
            "CamelCase" => Ok(RenameRule::CamelCase),
            "camel_case" => Ok(RenameRule::CamelCase),

            "snake_case" => Ok(RenameRule::SnakeCase),
            "SnakeCase" => Ok(RenameRule::SnakeCase),

            "SCREAMING_SNAKE_CASE" => Ok(RenameRule::ScreamingSnakeCase),
            "ScreamingSnakeCase" => Ok(RenameRule::ScreamingSnakeCase),
            "screaming_snake_case" => Ok(RenameRule::ScreamingSnakeCase),

            "QUALIFIED_SCREAMING_SNAKE_CASE" => Ok(RenameRule::QualifiedScreamingSnakeCase),
            "QualifiedScreamingSnakeCase" => Ok(RenameRule::QualifiedScreamingSnakeCase),
            "qualified_screaming_snake_case" => Ok(RenameRule::QualifiedScreamingSnakeCase),

            _ => Err(format!("unrecognized RenameRule: '{}'", s)),
        }
    }
}
deserialize_enum_str!(RenameRule);
<commit_msg>Add some spaces in rename.rs<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::str::FromStr;

use bindgen::items::Enum;

/// The type of identifier to be renamed.
#[derive(Debug, Clone, Copy)]
pub enum IdentifierType<'a> {
    StructMember,
    EnumVariant(&'a Enum),
    FunctionArg,
    Enum,
}

impl<'a> IdentifierType<'a> {
    fn to_str(&'a self) -> &'static str {
        match *self {
            IdentifierType::StructMember => "m",
            IdentifierType::EnumVariant(..) => "",
            IdentifierType::FunctionArg => "a",
            IdentifierType::Enum => "",
        }
    }
}

/// A rule to apply to an identifier when generating bindings.
#[derive(Debug, Clone, Copy)]
pub enum RenameRule {
    /// Do not apply any renaming. The default.
    None,
    /// Converts the identifier to PascalCase and adds a prefix based on where the identifier is used.
    GeckoCase,
    /// Converts the identifier to lower case.
    LowerCase,
    /// Converts the identifier to upper case.
    UpperCase,
    /// Converts the identifier to PascalCase.
    PascalCase,
    /// Converts the identifier to camelCase.
    CamelCase,
    /// Converts the identifier to snake_case.
    SnakeCase,
    /// Converts the identifier to SCREAMING_SNAKE_CASE.
    ScreamingSnakeCase,
    /// Converts the identifier to SCREAMING_SNAKE_CASE and prefixes enum variants
    /// with the enum name.
    QualifiedScreamingSnakeCase,
}

impl RenameRule {
    /// Applies the rename rule to a string that is formatted in PascalCase.
    pub fn apply_to_pascal_case(&self, text: &str, context: IdentifierType) -> String {
        if text.len() == 0 {
            return String::new();
        }

        match *self {
            RenameRule::None => String::from(text),
            RenameRule::GeckoCase => context.to_str().to_owned() + text,
            RenameRule::LowerCase => text.to_lowercase(),
            RenameRule::UpperCase => text.to_uppercase(),
            RenameRule::PascalCase => text.to_owned(),
            RenameRule::CamelCase => {
                text[..1].to_lowercase() + &text[1..]
            }
            RenameRule::SnakeCase => {
                let mut result = String::new();
                for (i, c) in text.char_indices() {
                    if c.is_uppercase() && i != 0 {
                        result.push_str("_");
                    }
                    for x in c.to_lowercase() {
                        result.push(x);
                    }
                }
                result
            }
            RenameRule::ScreamingSnakeCase => {
                // Same as SnakeCase code above, but uses to_uppercase
                let mut result = String::new();
                for (i, c) in text.char_indices() {
                    if c.is_uppercase() && i != 0 {
                        result.push_str("_");
                    }
                    for x in c.to_uppercase() {
                        result.push(x);
                    }
                }
                result
            }
            RenameRule::QualifiedScreamingSnakeCase => {
                let mut result = String::new();

                if let IdentifierType::EnumVariant(e) = context {
                    if let &RenameRule::QualifiedScreamingSnakeCase = self {
                        result.push_str(&RenameRule::ScreamingSnakeCase.apply_to_pascal_case(
                            &e.name, IdentifierType::Enum));
                        result.push_str("_");
                    }
                }

                result.push_str(&RenameRule::SnakeCase.apply_to_pascal_case(
                    &text, context));
                result
            }
        }
    }

    /// Applies the rename rule to a string that is formatted in snake_case.
    pub fn apply_to_snake_case(&self, mut text: &str, context: IdentifierType) -> String {
        if text.len() == 0 {
            return String::new();
        }

        match *self {
            RenameRule::None => String::from(text),
            RenameRule::GeckoCase => {
                if &text[..1] == "_" {
                    text = &text[1..];
                }

                context.to_str().to_owned() +
                    &RenameRule::PascalCase.apply_to_snake_case(text, context)
            }
            RenameRule::LowerCase => text.to_lowercase(),
            RenameRule::UpperCase => text.to_uppercase(),
            RenameRule::PascalCase => {
                let mut result = String::new();
                let mut is_uppercase = true;
                for c in text.chars() {
                    if c == '_' {
                        is_uppercase = true;
                        continue;
                    }

                    if is_uppercase {
                        for x in c.to_uppercase() {
                            result.push(x);
                        }
                        is_uppercase = false;
                    } else {
                        result.push(c);
                    }
                }
                result
            }
            RenameRule::CamelCase => {
                // Same as PascalCase code above, but is_uppercase = false to start
                let mut result = String::new();
                let mut is_uppercase = false;
                for c in text.chars() {
                    if c == '_' {
                        is_uppercase = true;
                        continue;
                    }

                    if is_uppercase {
                        for x in c.to_uppercase() {
                            result.push(x);
                        }
                        is_uppercase = false;
                    } else {
                        result.push(c);
                    }
                }
                result
            }
            RenameRule::SnakeCase => text.to_owned(),
            RenameRule::ScreamingSnakeCase => text.to_owned().to_uppercase(),
            RenameRule::QualifiedScreamingSnakeCase => {
                let mut result = String::new();

                if let IdentifierType::EnumVariant(e) = context {
                    if let &RenameRule::QualifiedScreamingSnakeCase = self {
                        result.push_str(&RenameRule::ScreamingSnakeCase.apply_to_snake_case(
                            &e.name, IdentifierType::Enum));
                        result.push_str("_");
                    }
                }

                result.push_str(&RenameRule::SnakeCase.apply_to_snake_case(
                    &text, context));
                result
            }
        }
    }
}

impl Default for RenameRule {
    fn default() -> RenameRule {
        RenameRule::None
    }
}

impl FromStr for RenameRule {
    type Err = String;

    fn from_str(s: &str) -> Result<RenameRule, Self::Err> {
        match s {
            "none" => Ok(RenameRule::None),
            "None" => Ok(RenameRule::None),

            "mGeckoCase" => Ok(RenameRule::GeckoCase),
            "GeckoCase" => Ok(RenameRule::GeckoCase),
            "gecko_case" => Ok(RenameRule::GeckoCase),

            "lowercase" => Ok(RenameRule::LowerCase),
            "LowerCase" => Ok(RenameRule::LowerCase),
            "lower_case" => Ok(RenameRule::LowerCase),

            "UPPERCASE" => Ok(RenameRule::UpperCase),
            "UpperCase" => Ok(RenameRule::UpperCase),
            "upper_case" => Ok(RenameRule::UpperCase),

            "PascalCase" => Ok(RenameRule::PascalCase),
            "pascal_case" => Ok(RenameRule::PascalCase),

            "camelCase" => Ok(RenameRule::CamelCase),
            "CamelCase" => Ok(RenameRule::CamelCase),
            "camel_case" => Ok(RenameRule::CamelCase),

            "snake_case" => Ok(RenameRule::SnakeCase),
            "SnakeCase" => Ok(RenameRule::SnakeCase),

            "SCREAMING_SNAKE_CASE" => Ok(RenameRule::ScreamingSnakeCase),
            "ScreamingSnakeCase" => Ok(RenameRule::ScreamingSnakeCase),
            "screaming_snake_case" => Ok(RenameRule::ScreamingSnakeCase),

            "QUALIFIED_SCREAMING_SNAKE_CASE" => Ok(RenameRule::QualifiedScreamingSnakeCase),
            "QualifiedScreamingSnakeCase" => Ok(RenameRule::QualifiedScreamingSnakeCase),
            "qualified_screaming_snake_case" => Ok(RenameRule::QualifiedScreamingSnakeCase),

            _ => Err(format!("unrecognized RenameRule: '{}'", s)),
        }
    }
}

deserialize_enum_str!(RenameRule);
<|endoftext|>


<commit_before>#![macro_escape]

use std::str::Chars;
use std::vec::Vec;
use std::io::IoResult;

#[deriving(Clone)]
pub struct ParseBranch {
    matches: Vec<u8>,
    result: Option<String>,
    children: Vec<ParseBranch>,
}

impl ParseBranch {
    fn new() -> ParseBranch {
        ParseBranch {
            matches: Vec::new(),
            result: None,
            children: Vec::new()
        }
    }
}

pub fn branchify(options: &[(&str, &str)], case_sensitive: bool) -> Vec<ParseBranch> {
    let mut root = ParseBranch::new();

    fn go_down_moses(branch: &mut ParseBranch, mut chariter: Chars, result: &str, case_sensitive: bool) {
        match chariter.next() {
            Some(c) => {
                let first_case = if case_sensitive { c as u8 } else { c.to_ascii().to_uppercase().to_byte() };
                for next_branch in branch.children.iter_mut() {
                    if next_branch.matches[0] == first_case {
                        go_down_moses(next_branch, chariter, result, case_sensitive);
                        return;
                    }
                }
                let mut subbranch = ParseBranch::new();
                subbranch.matches.push(first_case);
                if !case_sensitive {
                    let second_case = c.to_ascii().to_lowercase().to_byte();
                    if first_case != second_case {
                        subbranch.matches.push(second_case);
                    }
                }
                branch.children.push(subbranch);
                let i = branch.children.len() - 1;
                go_down_moses(branch.children.get_mut(i), chariter, result, case_sensitive);
            },
            None => {
                assert!(branch.result.is_none());
                branch.result = Some(String::from_str(result));
            },
        }
    };

    for &(key, result) in options.iter() {
        go_down_moses(&mut root, key.chars(), result, case_sensitive);
    }

    root.children
}

macro_rules! branchify(
    (case sensitive, $($key:expr => $value:ident),*) => (
        ::branchify::branchify([$(($key, stringify!($value))),*], true)
    );
    (case insensitive, $($key:expr => $value:ident),*) => (
        ::branchify::branchify([$(($key, stringify!($value))),*], false)
    );
)

/// Prints the contents to stdout.
///
/// :param branches: the branches to search through
/// :param indent: the level of indentation (each level representing four leading spaces)
/// :param read_call: the function call to read a byte
/// :param end: the byte which marks the end of the sequence
/// :param max_len: the maximum length a value may be before giving up and returning ``None``
/// :param valid: the function call to if a byte ``b`` is valid
/// :param unknown: the expression to call for an unknown value; in this string, ``{}`` will be
///         replaced with an expression (literal or non-literal) evaluating to a ``String`` (it is
///         ``{}`` only, not arbitrary format strings)
pub fn generate_branchified_method(
        writer: &mut Writer,
        branches: Vec<ParseBranch>,
        indent: uint,
        read_call: &str,
        end: &str,
        max_len: &str,
        valid: &str,
        unknown: &str) -> IoResult<()> {

    fn r(writer: &mut Writer, branch: &ParseBranch, prefix: &str, indent: uint, read_call: &str,
            end: &str, max_len: &str, valid: &str, unknown: &str) -> IoResult<()> {
        let indentstr = " ".repeat(indent * 4);
        macro_rules! w (
            ($s:expr) => {
                try!(write!(writer, "{}{}\n", indentstr, $s))
            }
        )
        for &c in branch.matches.iter() {
            let next_prefix = format!("{}{}", prefix, c as char);
            w!(format!("Ok(b'{}') => match {} {{", c as char, read_call));
            for b in branch.children.iter() {
                try!(r(writer, b, next_prefix[], indent + 1, read_call, end, max_len, valid, unknown));
            }
            match branch.result {
                Some(ref result) =>
                    w!(format!("    Ok(b' ') => return Ok({}),", *result)),
                None => w!(format!("    Ok(b' ') => return Ok({}),",
                                  unknown.replace("{}", format!("String::from_str(\"{}\")", next_prefix)[]))),
            }
            w!(format!("    Ok(b) if {} => (\"{}\", b),", valid, next_prefix));
            w!("    Ok(_) => return Err(::std::io::IoError { kind: ::std::io::OtherIoError, desc: \"bad value\", detail: None }),");
            w!("    Err(err) => return Err(err),");
            w!("},");
        }
        Ok(())
    }
    let indentstr = " ".repeat(indent * 4);
    macro_rules! w (
        ($s:expr) => {
            try!(write!(writer, "{}{}\n", indentstr, $s))
        }
    )

    w!(format!("let (s, next_byte) = match {} {{", read_call));
    for b in branches.iter() {
        try!(r(writer, b, "", indent + 1, read_call, end, max_len, valid, unknown));
    }
    w!(format!("    Ok(b) if {} => (\"\", b),", valid));
    w!(       ("    Ok(_) => return Err(::std::io::IoError { kind: ::std::io::OtherIoError, desc: \"bad value\", detail: None }),"));
    w!(       ("    Err(err) => return Err(err),"));
    w!(       ("};"));
    w!(       ("// OK, that didn't pan out. Let's read the rest and see what we get."));
    w!(       ("let mut s = String::from_str(s);"));
    w!(       ("s.push(next_byte as char);"));
    w!(       ("loop {"));
    w!(format!("    match {} {{", read_call));
    w!(format!("        Ok(b) if b == {} => return Ok({}),", end, unknown.replace("{}", "s")));
    w!(format!("        Ok(b) if {} => {{", valid));
    w!(format!("            if s.len() == {} {{", max_len));
    w!(       ("                // Too long; bad request"));
    w!(       ("                return Err(::std::io::IoError { kind: ::std::io::OtherIoError, desc: \"too long, bad request\", detail: None });"));
    w!(       ("            }"));
    w!(       ("            s.push(b as char);"));
    w!(       ("        },"));
    w!(       ("        Ok(_) => return Err(::std::io::IoError { kind: ::std::io::OtherIoError, desc: \"bad value\", detail: None }),"));
    w!(       ("        Err(err) => return Err(err),"));
    w!(       ("    }"));
    w!(       ("}"));
    Ok(())
}
<commit_msg>Use indexing instead of get_mut since it now returns an Option<commit_after>#![macro_escape]

use std::str::Chars;
use std::vec::Vec;
use std::io::IoResult;

#[deriving(Clone)]
pub struct ParseBranch {
    matches: Vec<u8>,
    result: Option<String>,
    children: Vec<ParseBranch>,
}

impl ParseBranch {
    fn new() -> ParseBranch {
        ParseBranch {
            matches: Vec::new(),
            result: None,
            children: Vec::new()
        }
    }
}

pub fn branchify(options: &[(&str, &str)], case_sensitive: bool) -> Vec<ParseBranch> {
    let mut root = ParseBranch::new();

    fn go_down_moses(branch: &mut ParseBranch, mut chariter: Chars, result: &str, case_sensitive: bool) {
        match chariter.next() {
            Some(c) => {
                let first_case = if case_sensitive { c as u8 } else { c.to_ascii().to_uppercase().to_byte() };
                for next_branch in branch.children.iter_mut() {
                    if next_branch.matches[0] == first_case {
                        go_down_moses(next_branch, chariter, result, case_sensitive);
                        return;
                    }
                }
                let mut subbranch = ParseBranch::new();
                subbranch.matches.push(first_case);
                if !case_sensitive {
                    let second_case = c.to_ascii().to_lowercase().to_byte();
                    if first_case != second_case {
                        subbranch.matches.push(second_case);
                    }
                }
                branch.children.push(subbranch);
                let i = branch.children.len() - 1;
                go_down_moses(&mut branch.children[i], chariter, result, case_sensitive);
            },
            None => {
                assert!(branch.result.is_none());
                branch.result = Some(String::from_str(result));
            },
        }
    };

    for &(key, result) in options.iter() {
        go_down_moses(&mut root, key.chars(), result, case_sensitive);
    }

    root.children
}

macro_rules! branchify(
    (case sensitive, $($key:expr => $value:ident),*) => (
        ::branchify::branchify([$(($key, stringify!($value))),*], true)
    );
    (case insensitive, $($key:expr => $value:ident),*) => (
        ::branchify::branchify([$(($key, stringify!($value))),*], false)
    );
)

/// Prints the contents to stdout.
///
/// :param branches: the branches to search through
/// :param indent: the level of indentation (each level representing four leading spaces)
/// :param read_call: the function call to read a byte
/// :param end: the byte which marks the end of the sequence
/// :param max_len: the maximum length a value may be before giving up and returning ``None``
/// :param valid: the function call to if a byte ``b`` is valid
/// :param unknown: the expression to call for an unknown value; in this string, ``{}`` will be
///         replaced with an expression (literal or non-literal) evaluating to a ``String`` (it is
///         ``{}`` only, not arbitrary format strings)
pub fn generate_branchified_method(
        writer: &mut Writer,
        branches: Vec<ParseBranch>,
        indent: uint,
        read_call: &str,
        end: &str,
        max_len: &str,
        valid: &str,
        unknown: &str) -> IoResult<()> {

    fn r(writer: &mut Writer, branch: &ParseBranch, prefix: &str, indent: uint, read_call: &str,
            end: &str, max_len: &str, valid: &str, unknown: &str) -> IoResult<()> {
        let indentstr = " ".repeat(indent * 4);
        macro_rules! w (
            ($s:expr) => {
                try!(write!(writer, "{}{}\n", indentstr, $s))
            }
        )
        for &c in branch.matches.iter() {
            let next_prefix = format!("{}{}", prefix, c as char);
            w!(format!("Ok(b'{}') => match {} {{", c as char, read_call));
            for b in branch.children.iter() {
                try!(r(writer, b, next_prefix[], indent + 1, read_call, end, max_len, valid, unknown));
            }
            match branch.result {
                Some(ref result) =>
                    w!(format!("    Ok(b' ') => return Ok({}),", *result)),
                None => w!(format!("    Ok(b' ') => return Ok({}),",
                                  unknown.replace("{}", format!("String::from_str(\"{}\")", next_prefix)[]))),
            }
            w!(format!("    Ok(b) if {} => (\"{}\", b),", valid, next_prefix));
            w!("    Ok(_) => return Err(::std::io::IoError { kind: ::std::io::OtherIoError, desc: \"bad value\", detail: None }),");
            w!("    Err(err) => return Err(err),");
            w!("},");
        }
        Ok(())
    }
    let indentstr = " ".repeat(indent * 4);
    macro_rules! w (
        ($s:expr) => {
            try!(write!(writer, "{}{}\n", indentstr, $s))
        }
    )

    w!(format!("let (s, next_byte) = match {} {{", read_call));
    for b in branches.iter() {
        try!(r(writer, b, "", indent + 1, read_call, end, max_len, valid, unknown));
    }
    w!(format!("    Ok(b) if {} => (\"\", b),", valid));
    w!(       ("    Ok(_) => return Err(::std::io::IoError { kind: ::std::io::OtherIoError, desc: \"bad value\", detail: None }),"));
    w!(       ("    Err(err) => return Err(err),"));
    w!(       ("};"));
    w!(       ("// OK, that didn't pan out. Let's read the rest and see what we get."));
    w!(       ("let mut s = String::from_str(s);"));
    w!(       ("s.push(next_byte as char);"));
    w!(       ("loop {"));
    w!(format!("    match {} {{", read_call));
    w!(format!("        Ok(b) if b == {} => return Ok({}),", end, unknown.replace("{}", "s")));
    w!(format!("        Ok(b) if {} => {{", valid));
    w!(format!("            if s.len() == {} {{", max_len));
    w!(       ("                // Too long; bad request"));
    w!(       ("                return Err(::std::io::IoError { kind: ::std::io::OtherIoError, desc: \"too long, bad request\", detail: None });"));
    w!(       ("            }"));
    w!(       ("            s.push(b as char);"));
    w!(       ("        },"));
    w!(       ("        Ok(_) => return Err(::std::io::IoError { kind: ::std::io::OtherIoError, desc: \"bad value\", detail: None }),"));
    w!(       ("        Err(err) => return Err(err),"));
    w!(       ("    }"));
    w!(       ("}"));
    Ok(())
}
<|endoftext|>


<commit_before>use rand::Rng;
use Packing;

pub mod kyber;

pub trait KeyExchange {
    type PrivateKey: Packing;
    type PublicKey: Packing;
    type Message: Packing;

    const SHARED_LENGTH: usize;

    fn keypair<R: Rng>(r: R) -> (Self::PrivateKey, Self::PublicKey);

    /// TODO should be `sharedkey: &mut [u8; Self::SHARED_LENGTH]`
    fn exchange_to<R: Rng>(r: R, sharedkey: &mut [u8], pk: &Self::PublicKey) -> Self::Message;

    /// TODO should be `sharedkey: &mut [u8; Self::SHARED_LENGTH]`
    fn exchange_from(sharedkey: &mut [u8], sk: &Self::PrivateKey, m: &Self::Message);
}

pub trait DeterministicExchange: KeyExchange {
    fn exchange_to(sharedkey: &mut [u8], pk: &Self::PublicKey) -> Self::Message;
}

pub trait CheckedExchange: KeyExchange {
    fn exchange_from(sharedkey: &mut [u8], sk: &Self::PrivateKey, m: &Self::Message) -> bool;
}
<commit_msg>change: remove  DeterministicExchange trait<commit_after>use rand::Rng;
use Packing;

pub mod kyber;

pub trait KeyExchange {
    type PrivateKey: Packing;
    type PublicKey: Packing;
    type Message: Packing;

    const SHARED_LENGTH: usize;

    fn keypair<R: Rng>(r: R) -> (Self::PrivateKey, Self::PublicKey);

    /// TODO should be `sharedkey: &mut [u8; Self::SHARED_LENGTH]`
    fn exchange_to<R: Rng>(r: R, sharedkey: &mut [u8], pk: &Self::PublicKey) -> Self::Message;

    /// TODO should be `sharedkey: &mut [u8; Self::SHARED_LENGTH]`
    fn exchange_from(sharedkey: &mut [u8], sk: &Self::PrivateKey, m: &Self::Message);
}

pub trait CheckedExchange: KeyExchange {
    fn exchange_from(sharedkey: &mut [u8], sk: &Self::PrivateKey, m: &Self::Message) -> bool;
}
<|endoftext|>


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

// This test case tests the incremental compilation hash (ICH) implementation
// for match expressions.

// The general pattern followed here is: Change one thing between rev1 and rev2
// and make sure that the hash has changed, then change nothing between rev2 and
// rev3 and make sure that the hash has not changed.

// must-compile-successfully
// revisions: cfail1 cfail2 cfail3
// compile-flags: -Z query-dep-graph

#![allow(warnings)]
#![feature(rustc_attrs)]
#![crate_type="rlib"]

// Add Arm ---------------------------------------------------------------------
#[cfg(cfail1)]
pub fn add_arm(x: u32) -> u32 {
    match x {
        0 => 0,
        1 => 1,
        _ => 100,
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_arm(x: u32) -> u32 {
    match x {
        0 => 0,
        1 => 1,
        2 => 2,
        _ => 100,
    }
}

// Change Order Of Arms --------------------------------------------------------
#[cfg(cfail1)]
pub fn change_order_of_arms(x: u32) -> u32 {
    match x {
        0 => 0,
        1 => 1,
        _ => 100,
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_order_of_arms(x: u32) -> u32 {
    match x {
        1 => 1,
        0 => 0,
        _ => 100,
    }
}

// Add Guard Clause ------------------------------------------------------------
#[cfg(cfail1)]
pub fn add_guard_clause(x: u32, y: bool) -> u32 {
    match x {
        0 => 0,
        1 => 1,
        _ => 100,
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_guard_clause(x: u32, y: bool) -> u32 {
    match x {
        0 => 0,
        1 if y => 1,
        _ => 100,
    }
}

// Change Guard Clause ------------------------------------------------------------
#[cfg(cfail1)]
pub fn change_guard_clause(x: u32, y: bool) -> u32 {
    match x {
        0 => 0,
        1 if y => 1,
        _ => 100,
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_guard_clause(x: u32, y: bool) -> u32 {
    match x {
        0 => 0,
        1 if !y => 1,
        _ => 100,
    }
}

// Add @-Binding ---------------------------------------------------------------
#[cfg(cfail1)]
pub fn add_at_binding(x: u32) -> u32 {
    match x {
        0 => 0,
        1 => 1,
        _ => x,
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_at_binding(x: u32) -> u32 {
    match x {
        0 => 0,
        1 => 1,
        x @ _ => x,
    }
}

// Change Name of @-Binding ----------------------------------------------------
#[cfg(cfail1)]
pub fn change_name_of_at_binding(x: u32) -> u32 {
    match x {
        0 => 0,
        1 => 1,
        x @ _ => 7,
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_name_of_at_binding(x: u32) -> u32 {
    match x {
        0 => 0,
        1 => 1,
        y @ _ => 7,
    }
}

// Change Simple Binding To Pattern --------------------------------------------
#[cfg(cfail1)]
pub fn change_simple_name_to_pattern(x: u32) -> u32 {
    match (x, x & 1) {
        (0, 0) => 0,
        a      => 1
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_simple_name_to_pattern(x: u32) -> u32 {
    match (x, x & 1) {
        (0, 0) => 0,
        (x, y) => 1
    }
}

// Change Name In Pattern ------------------------------------------------------
#[cfg(cfail1)]
pub fn change_name_in_pattern(x: u32) -> u32 {
    match (x, x & 1) {
        (a, 0) => 0,
        (a, 1) => a,
        _ => 100,
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_name_in_pattern(x: u32) -> u32 {
    match (x, x & 1) {
        (b, 0) => 0,
        (a, 1) => a,
        _ => 100,
    }
}

// Change Mutability Of Binding In Pattern -------------------------------------
#[cfg(cfail1)]
pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 {
    match (x, x & 1) {
        (a, 0) => 0,
        _      => 1
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 {
    match (x, x & 1) {
        (mut a, 0) => 0,
        _      => 1
    }
}

// Add `ref` To Binding In Pattern -------------------------------------
#[cfg(cfail1)]
pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 {
    match (x, x & 1) {
        (a, 0) => 0,
        _      => 1
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 {
    match (x, x & 1) {
        (ref a, 0) => 0,
        _      => 1,
    }
}

// Add `&` To Binding In Pattern -------------------------------------
#[cfg(cfail1)]
pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 {
    match (&x, x & 1) {
        (a, 0) => 0,
        _      => 1
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 {
    match (&x, x & 1) {
        (&a, 0) => 0,
        _      => 1,
    }
}

// Change RHS Of Arm -----------------------------------------------------------
#[cfg(cfail1)]
pub fn change_rhs_of_arm(x: u32) -> u32 {
    match x {
        0 => 0,
        1 => 1,
        _ => 2,
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_rhs_of_arm(x: u32) -> u32 {
    match x {
        0 => 0,
        1 => 3,
        _ => 2,
    }
}

// Add Alternative To Arm ------------------------------------------------------
#[cfg(cfail1)]
pub fn add_alternative_to_arm(x: u32) -> u32 {
    match x {
        0 => 0,
        1 => 1,
        _ => 2,
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_alternative_to_arm(x: u32) -> u32 {
    match x {
        0 | 7 => 0,
        1 => 3,
        _ => 2,
    }
}
<commit_msg>Rollup merge of #45941 - gaurikholkar:master, r=nikomatsakis<commit_after>// Copyright 2016 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.

// This test case tests the incremental compilation hash (ICH) implementation
// for match expressions.

// The general pattern followed here is: Change one thing between rev1 and rev2
// and make sure that the hash has changed, then change nothing between rev2 and
// rev3 and make sure that the hash has not changed.

// must-compile-successfully
// revisions: cfail1 cfail2 cfail3
// compile-flags: -Z query-dep-graph

#![allow(warnings)]
#![feature(rustc_attrs)]
#![crate_type="rlib"]

// Add Arm ---------------------------------------------------------------------
#[cfg(cfail1)]
pub fn add_arm(x: u32) -> u32 {
    match x {
        0 => 0,
        1 => 1,
        _ => 100,
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2",
    except="HirBody,MirValidated,MirOptimized,TypeckTables")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_arm(x: u32) -> u32 {
    match x {
        0 => 0,
        1 => 1,
        2 => 2,
        _ => 100,
    }
}

// Change Order Of Arms --------------------------------------------------------
#[cfg(cfail1)]
pub fn change_order_of_arms(x: u32) -> u32 {
    match x {
        0 => 0,
        1 => 1,
        _ => 100,
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2",
    except="HirBody,MirValidated,MirOptimized")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_order_of_arms(x: u32) -> u32 {
    match x {
        1 => 1,
        0 => 0,
        _ => 100,
    }
}

// Add Guard Clause ------------------------------------------------------------
#[cfg(cfail1)]
pub fn add_guard_clause(x: u32, y: bool) -> u32 {
    match x {
        0 => 0,
        1 => 1,
        _ => 100,
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2",
    except="HirBody,MirValidated,MirOptimized,TypeckTables")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_guard_clause(x: u32, y: bool) -> u32 {
    match x {
        0 => 0,
        1 if y => 1,
        _ => 100,
    }
}

// Change Guard Clause ------------------------------------------------------------
#[cfg(cfail1)]
pub fn change_guard_clause(x: u32, y: bool) -> u32 {
    match x {
        0 => 0,
        1 if y => 1,
        _ => 100,
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2",
    except="HirBody,MirValidated,MirOptimized,TypeckTables")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_guard_clause(x: u32, y: bool) -> u32 {
    match x {
        0 => 0,
        1 if !y => 1,
        _ => 100,
    }
}

// Add @-Binding ---------------------------------------------------------------
#[cfg(cfail1)]
pub fn add_at_binding(x: u32) -> u32 {
    match x {
        0 => 0,
        1 => 1,
        _ => x,
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2",
    except="HirBody,MirValidated,MirOptimized,TypeckTables")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_at_binding(x: u32) -> u32 {
    match x {
        0 => 0,
        1 => 1,
        x @ _ => x,
    }
}

// Change Name of @-Binding ----------------------------------------------------
#[cfg(cfail1)]
pub fn change_name_of_at_binding(x: u32) -> u32 {
    match x {
        0 => 0,
        1 => 1,
        x @ _ => 7,
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2",
    except="HirBody,MirValidated,MirOptimized")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_name_of_at_binding(x: u32) -> u32 {
    match x {
        0 => 0,
        1 => 1,
        y @ _ => 7,
    }
}

// Change Simple Binding To Pattern --------------------------------------------
#[cfg(cfail1)]
pub fn change_simple_name_to_pattern(x: u32) -> u32 {
    match (x, x & 1) {
        (0, 0) => 0,
        a => 1,
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2",
    except="HirBody,MirValidated,MirOptimized,TypeckTables")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_simple_name_to_pattern(x: u32) -> u32 {
    match (x, x & 1) {
        (0, 0) => 0,
        (x, y) => 1,
    }
}

// Change Name In Pattern ------------------------------------------------------
#[cfg(cfail1)]
pub fn change_name_in_pattern(x: u32) -> u32 {
    match (x, x & 1) {
        (a, 0) => 0,
        (a, 1) => a,
        _ => 100,
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2",
    except="HirBody,MirValidated,MirOptimized")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_name_in_pattern(x: u32) -> u32 {
    match (x, x & 1) {
        (b, 0) => 0,
        (a, 1) => a,
        _ => 100,
    }
}

// Change Mutability Of Binding In Pattern -------------------------------------
#[cfg(cfail1)]
pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 {
    match (x, x & 1) {
        (a, 0) => 0,
        _ => 1,
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2",
    except="HirBody,MirValidated,MirOptimized,TypeckTables")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 {
    match (x, x & 1) {
        (mut a, 0) => 0,
        _ => 1,
    }
}

// Add `ref` To Binding In Pattern -------------------------------------
#[cfg(cfail1)]
pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 {
    match (x, x & 1) {
        (a, 0) => 0,
        _ => 1,
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2",
    except="HirBody,MirValidated,MirOptimized,TypeckTables")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 {
    match (x, x & 1) {
        (ref a, 0) => 0,
        _ => 1,
    }
}

// Add `&` To Binding In Pattern -------------------------------------
#[cfg(cfail1)]
pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 {
    match (&x, x & 1) {
        (a, 0) => 0,
        _ => 1,
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2",
except="HirBody,MirValidated,MirOptimized,TypeckTables")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 {
    match (&x, x & 1) {
        (&a, 0) => 0,
        _ => 1,
    }
}

// Change RHS Of Arm -----------------------------------------------------------
#[cfg(cfail1)]
pub fn change_rhs_of_arm(x: u32) -> u32 {
    match x {
        0 => 0,
        1 => 1,
        _ => 2,
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2",
    except="HirBody,MirValidated,MirOptimized")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_rhs_of_arm(x: u32) -> u32 {
    match x {
        0 => 0,
        1 => 3,
        _ => 2,
    }
}

// Add Alternative To Arm ------------------------------------------------------
#[cfg(cfail1)]
pub fn add_alternative_to_arm(x: u32) -> u32 {
    match x {
        0 => 0,
        1 => 1,
        _ => 2,
    }
}

#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2",
    except="HirBody,MirValidated,MirOptimized,TypeckTables")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_alternative_to_arm(x: u32) -> u32 {
    match x {
        0 | 7 => 0,
        1 => 3,
        _ => 2,
    }
}
<|endoftext|>


<commit_before>use crate::mir::operand::OperandRef;
use crate::traits::*;
use rustc::mir;
use rustc::mir::interpret::{ConstValue, ErrorHandled};
use rustc::ty::layout::{self, HasTyCtxt};
use rustc::ty::{self, Ty};
use rustc_index::vec::Idx;
use rustc_span::source_map::Span;

use super::FunctionCx;

impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
    pub fn eval_mir_constant_to_operand(
        &mut self,
        bx: &mut Bx,
        constant: &mir::Constant<'tcx>,
    ) -> Result<OperandRef<'tcx, Bx::Value>, ErrorHandled> {
        match constant.literal.val {
            // Special case unevaluated statics, because statics have an identity and thus should
            // use `get_static` to get at their id.
            // FIXME(oli-obk): can we unify this somehow, maybe by making const eval of statics
            // always produce `&STATIC`. This may also simplify how const eval works with statics.
            ty::ConstKind::Unevaluated(def_id, substs, None) if self.cx.tcx().is_static(def_id) => {
                assert!(substs.is_empty(), "we don't support generic statics yet");
                let static_ = bx.get_static(def_id);
                // we treat operands referring to statics as if they were `&STATIC` instead
                let ptr_ty = self.cx.tcx().mk_mut_ptr(self.monomorphize(&constant.literal.ty));
                let layout = bx.layout_of(ptr_ty);
                Ok(OperandRef::from_immediate_or_packed_pair(bx, static_, layout))
            }
            _ => {
                let val = self.eval_mir_constant(constant)?;
                Ok(OperandRef::from_const(bx, val.clone(), constant.literal.ty))
            }
        }
    }

    pub fn eval_mir_constant(
        &mut self,
        constant: &mir::Constant<'tcx>,
    ) -> Result<ConstValue<'tcx>, ErrorHandled> {
        match constant.literal.val {
            ty::ConstKind::Unevaluated(def_id, substs, promoted) => {
                let substs = self.monomorphize(&substs);
                self.cx
                    .tcx()
                    .const_eval_resolve(ty::ParamEnv::reveal_all(), def_id, substs, promoted, None)
                    .map_err(|err| {
                        if promoted.is_none() {
                            self.cx
                                .tcx()
                                .sess
                                .span_err(constant.span, "erroneous constant encountered");
                        }
                        err
                    })
            }
            ty::ConstKind::Value(value) => Ok(value),
            _ => {
                let const_ = self.monomorphize(&constant.literal);
                if let ty::ConstKind::Value(value) = const_.val {
                    Ok(value)
                } else {
                    bug!("encountered bad ConstKind in codegen");
                }
            }
        }
    }

    /// process constant containing SIMD shuffle indices
    pub fn simd_shuffle_indices(
        &mut self,
        bx: &Bx,
        span: Span,
        ty: Ty<'tcx>,
        constant: Result<ConstValue<'tcx>, ErrorHandled>,
    ) -> (Bx::Value, Ty<'tcx>) {
        constant
            .map(|val| {
                let field_ty = ty.builtin_index().unwrap();
                let fields = match ty.kind {
                    ty::Array(_, n) => n.eval_usize(bx.tcx(), ty::ParamEnv::reveal_all()),
                    _ => bug!("invalid simd shuffle type: {}", ty),
                };
                let c = bx.tcx().mk_const(ty::Const { val: ty::ConstKind::Value(val), ty });
                let values: Vec<_> = (0..fields)
                    .map(|field| {
                        let field = bx.tcx().const_field(
                            ty::ParamEnv::reveal_all().and((&c, mir::Field::new(field as usize))),
                        );
                        if let Some(prim) = field.try_to_scalar() {
                            let layout = bx.layout_of(field_ty);
                            let scalar = match layout.abi {
                                layout::Abi::Scalar(ref x) => x,
                                _ => bug!("from_const: invalid ByVal layout: {:#?}", layout),
                            };
                            bx.scalar_to_backend(prim, scalar, bx.immediate_backend_type(layout))
                        } else {
                            bug!("simd shuffle field {:?}", field)
                        }
                    })
                    .collect();
                let llval = bx.const_struct(&values, false);
                (llval, c.ty)
            })
            .unwrap_or_else(|_| {
                bx.tcx().sess.span_err(span, "could not evaluate shuffle_indices at compile time");
                // We've errored, so we don't have to produce working code.
                let ty = self.monomorphize(&ty);
                let llty = bx.backend_type(bx.layout_of(ty));
                (bx.const_undef(llty), ty)
            })
    }
}
<commit_msg>Monomorphize const type during codegen.<commit_after>use crate::mir::operand::OperandRef;
use crate::traits::*;
use rustc::mir;
use rustc::mir::interpret::{ConstValue, ErrorHandled};
use rustc::ty::layout::{self, HasTyCtxt};
use rustc::ty::{self, Ty};
use rustc_index::vec::Idx;
use rustc_span::source_map::Span;

use super::FunctionCx;

impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
    pub fn eval_mir_constant_to_operand(
        &mut self,
        bx: &mut Bx,
        constant: &mir::Constant<'tcx>,
    ) -> Result<OperandRef<'tcx, Bx::Value>, ErrorHandled> {
        match constant.literal.val {
            // Special case unevaluated statics, because statics have an identity and thus should
            // use `get_static` to get at their id.
            // FIXME(oli-obk): can we unify this somehow, maybe by making const eval of statics
            // always produce `&STATIC`. This may also simplify how const eval works with statics.
            ty::ConstKind::Unevaluated(def_id, substs, None) if self.cx.tcx().is_static(def_id) => {
                assert!(substs.is_empty(), "we don't support generic statics yet");
                let static_ = bx.get_static(def_id);
                // we treat operands referring to statics as if they were `&STATIC` instead
                let ptr_ty = self.cx.tcx().mk_mut_ptr(self.monomorphize(&constant.literal.ty));
                let layout = bx.layout_of(ptr_ty);
                Ok(OperandRef::from_immediate_or_packed_pair(bx, static_, layout))
            }
            _ => {
                let val = self.eval_mir_constant(constant)?;
                let ty = self.monomorphize(&constant.literal.ty);
                Ok(OperandRef::from_const(bx, val.clone(), ty))
            }
        }
    }

    pub fn eval_mir_constant(
        &mut self,
        constant: &mir::Constant<'tcx>,
    ) -> Result<ConstValue<'tcx>, ErrorHandled> {
        match constant.literal.val {
            ty::ConstKind::Unevaluated(def_id, substs, promoted) => {
                let substs = self.monomorphize(&substs);
                self.cx
                    .tcx()
                    .const_eval_resolve(ty::ParamEnv::reveal_all(), def_id, substs, promoted, None)
                    .map_err(|err| {
                        if promoted.is_none() {
                            self.cx
                                .tcx()
                                .sess
                                .span_err(constant.span, "erroneous constant encountered");
                        }
                        err
                    })
            }
            ty::ConstKind::Value(value) => Ok(value),
            _ => {
                let const_ = self.monomorphize(&constant.literal);
                if let ty::ConstKind::Value(value) = const_.val {
                    Ok(value)
                } else {
                    bug!("encountered bad ConstKind in codegen");
                }
            }
        }
    }

    /// process constant containing SIMD shuffle indices
    pub fn simd_shuffle_indices(
        &mut self,
        bx: &Bx,
        span: Span,
        ty: Ty<'tcx>,
        constant: Result<ConstValue<'tcx>, ErrorHandled>,
    ) -> (Bx::Value, Ty<'tcx>) {
        constant
            .map(|val| {
                let field_ty = ty.builtin_index().unwrap();
                let fields = match ty.kind {
                    ty::Array(_, n) => n.eval_usize(bx.tcx(), ty::ParamEnv::reveal_all()),
                    _ => bug!("invalid simd shuffle type: {}", ty),
                };
                let c = bx.tcx().mk_const(ty::Const { val: ty::ConstKind::Value(val), ty });
                let values: Vec<_> = (0..fields)
                    .map(|field| {
                        let field = bx.tcx().const_field(
                            ty::ParamEnv::reveal_all().and((&c, mir::Field::new(field as usize))),
                        );
                        if let Some(prim) = field.try_to_scalar() {
                            let layout = bx.layout_of(field_ty);
                            let scalar = match layout.abi {
                                layout::Abi::Scalar(ref x) => x,
                                _ => bug!("from_const: invalid ByVal layout: {:#?}", layout),
                            };
                            bx.scalar_to_backend(prim, scalar, bx.immediate_backend_type(layout))
                        } else {
                            bug!("simd shuffle field {:?}", field)
                        }
                    })
                    .collect();
                let llval = bx.const_struct(&values, false);
                (llval, c.ty)
            })
            .unwrap_or_else(|_| {
                bx.tcx().sess.span_err(span, "could not evaluate shuffle_indices at compile time");
                // We've errored, so we don't have to produce working code.
                let ty = self.monomorphize(&ty);
                let llty = bx.backend_type(bx.layout_of(ty));
                (bx.const_undef(llty), ty)
            })
    }
}
<|endoftext|>


<commit_before>use rustc_serialize::Encodable;
use rustc_serialize::json::{mod, PrettyEncoder};
use std::io::{File, IoResult};
use std::io::fs::PathExtensions;
use PrivateIdentity;

#[derive(RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Config {
	pub privateKey: String,
	pub tunDevice: String,
	pub udpBind: String
}

impl Config {
	pub fn get_default(identity: &PrivateIdentity) -> Config {
		Config {
			privateKey: identity.private_key.as_string(),
			tunDevice: "tun%d".to_string(),
			udpBind: "0.0.0.0:3300".to_string()
		}
	}

	pub fn write(&self, path: &Path) -> IoResult<()> {
		if path.exists() {
			panic!("Config file '{}' exists already.", path.display());
		}

		let mut file = match File::create(path) {
			Ok(file) => file,
			Err(why) => panic!("Couldn't open config file '{}': {}", path.display(), why),
		};

		let mut encoder = PrettyEncoder::new(&mut file);
		self.encode(&mut encoder)
	}

	pub fn load(path: &Path) -> Config {
		let mut file = match File::open(path) {
			Ok(file) => file,
			Err(why) => panic!("Couldn't open config file '{}': {}", path.display(), why),
		};

		let content = match file.read_to_string() {
			Ok(string) => string,
			Err(why) => panic!("Couldn't read config file '{}': {}", path.display(), why),
		};

		json::decode(content.as_slice()).unwrap()
	}
}
<commit_msg>mod -> self fallout<commit_after>use rustc_serialize::Encodable;
use rustc_serialize::json::{self, PrettyEncoder};
use std::io::{File, IoResult};
use std::io::fs::PathExtensions;
use PrivateIdentity;

#[derive(RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Config {
	pub privateKey: String,
	pub tunDevice: String,
	pub udpBind: String
}

impl Config {
	pub fn get_default(identity: &PrivateIdentity) -> Config {
		Config {
			privateKey: identity.private_key.as_string(),
			tunDevice: "tun%d".to_string(),
			udpBind: "0.0.0.0:3300".to_string()
		}
	}

	pub fn write(&self, path: &Path) -> IoResult<()> {
		if path.exists() {
			panic!("Config file '{}' exists already.", path.display());
		}

		let mut file = match File::create(path) {
			Ok(file) => file,
			Err(why) => panic!("Couldn't open config file '{}': {}", path.display(), why),
		};

		let mut encoder = PrettyEncoder::new(&mut file);
		self.encode(&mut encoder)
	}

	pub fn load(path: &Path) -> Config {
		let mut file = match File::open(path) {
			Ok(file) => file,
			Err(why) => panic!("Couldn't open config file '{}': {}", path.display(), why),
		};

		let content = match file.read_to_string() {
			Ok(string) => string,
			Err(why) => panic!("Couldn't read config file '{}': {}", path.display(), why),
		};

		json::decode(content.as_slice()).unwrap()
	}
}
<|endoftext|>


<commit_before>use byteorder::{ReadBytesExt, LittleEndian};
use std::io::prelude::*;
use std::io::BufReader;
use std::io::SeekFrom;
use std::fs::File;
use std::cmp::Ordering;
use utils;
use errors::Word2VecError;

/// Representation of a word vector space
///
/// Each word of a vocabulary is represented by a vector. All words span a vector space. This data
/// structure manages this vector space of words.
pub struct WordVector {
    vocabulary: Vec<(String, Vec<f32>)>,
    vector_size: usize,
}

impl WordVector {
    /// Load a word vector space from file
    ///
    /// Word2vec is able to store the word vectors in a binary file. This function parses the file
    /// and loads the vectors into RAM.
    pub fn load_from_binary(file_name: &str) -> Result<WordVector, Word2VecError> {
        let file = try!(File::open(file_name));
        let mut reader = BufReader::new(file);
        let mut header = String::new();
        try!(reader.read_line(&mut header));
        let header_info = header.split_whitespace()
            .filter_map(|x| x.parse::<usize>().ok())
            .take(2)
            .collect::<Vec<usize>>();
        if header_info.len() != 2 {
            return Err(Word2VecError::WrongHeader);
        }
        let vocabulary_size = header_info[0];
        let vector_size = header_info[1];
        let mut vocabulary: Vec<(String, Vec<f32>)> = Vec::with_capacity(vocabulary_size);
        for _ in 0..vocabulary_size {
            let mut word_bytes: Vec<u8> = Vec::new();
            try!(reader.read_until(b' ', &mut word_bytes));
            word_bytes.pop();
            let word = try!(String::from_utf8(word_bytes));
            let mut current_vector: Vec<f32> = Vec::with_capacity(vector_size);
            for _ in 0..vector_size {
                let val = try!(reader.read_f32::<LittleEndian>());
                current_vector.push(val);
            }
            utils::vector_norm(&mut current_vector);
            vocabulary.push((word, current_vector));
            try!(reader.seek(SeekFrom::Current(1)));
        }
        Ok(WordVector {
            vocabulary: vocabulary,
            vector_size: vector_size,
        })
    }

    fn get_index(&self, word: &str) -> Option<usize> {
        self.vocabulary.iter().position(|x| x.0 == word)
    }

    /// Get word vector for the given word.
    pub fn get_vector(&self, word: &str) -> Option<&Vec<f32>> {
        let index = self.get_index(word);
        match index {
            Some(val) => Some(&self.vocabulary[val].1),
            None => None,
        }
    }

    /// Compute consine distance to similar words.
    ///
    /// The words in the vector space are characterized through the position and angle to each
    /// other. This method calculates the `n` closest words via the cosine of the requested word to
    /// all other words.
    pub fn cosine(&self, word: &str, n: usize) -> Option<Vec<(String, f32)>> {
        let word_vector = self.get_vector(word);
        match word_vector {
            Some(val) => { // save index and cosine distance to current word
                let mut metrics: Vec<(usize, f32)> = Vec::with_capacity(self.vocabulary.len());
                metrics.extend(self.vocabulary.iter().enumerate().
                        map(|(i, other_val)|
                    (i, utils::dot_product(&other_val.1, val))));
                metrics.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(Ordering::Equal));
                Some(metrics[1..n+1].iter().map(|&(idx, dist)|
                         (self.vocabulary[idx].clone().0, dist)).collect())
            }
            None => None,
        }
    }

    pub fn analogy(&self, pos: Vec<&str>, neg: Vec<&str>, n: usize) -> Option<Vec<(String, f32)>> {
        let mut vectors: Vec<Vec<f32>> = Vec::new();
        let mut exclude: Vec<String> = Vec::new();
        for word in pos {
            exclude.push(word.to_string());
            match self.get_vector(word) {
                Some(val) => vectors.push(val.clone()),
                None => {}
            }
        }
        for word in neg.iter() {
            exclude.push(word.to_string());
            match self.get_vector(word) {
                Some(val) => vectors.push(val.iter().map(|x| -x).collect::<Vec<f32>>()),
                None => {}
            }
        }
        if exclude.is_empty() {
            return None;
        }
        let mut mean: Vec<f32> = Vec::with_capacity(self.vector_size);
        for i in 0..self.vector_size {
            mean.push(utils::mean(vectors.iter().map(|v| v[i])));
        }
        let mut metrics: Vec<(String, f32)> = Vec::new();
        for word in self.vocabulary.iter() {
            metrics.push((word.0.clone(), utils::dot_product(&word.1, &mean)));
        }
        metrics.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(Ordering::Equal));
        metrics.retain(|x| exclude.contains(&x.0) == false);
        metrics.truncate(n);
        Some(metrics)
    }

    /// Get the number of all known words from the vocabulary.
    pub fn word_count(&self) -> usize {
        self.vocabulary.len()
    }

    /// Return the number of columns of the word vector.
    pub fn get_col_count(&self) -> usize {
        self.vector_size // size == column count
    }

    /// Get all known words from the vocabulary.
    pub fn get_words<'a>(&'a self) -> Words<'a> {
        Words::new(&self.vocabulary)
    }
}

pub struct Words<'parent> {
    words: &'parent Vec<(String, Vec<f32>)>,
    index: usize,
}

impl<'a> Words<'a> {
    fn new(x: &'a Vec<(String, Vec<f32>)>) -> Words<'a> {
        Words {
            words: x,
            index: 0,
        }
    }
}

impl<'a> Iterator for Words<'a> {
    type Item = String;

    fn next(&mut self) -> Option<Self::Item> {
        if self.index >= self.words.len() {
            return None;
        }
        self.index += 1;
        Some(self.words[self.index - 1].0.clone())
    }
}
<commit_msg>WordVector::analogy: performance improvements<commit_after>use byteorder::{ReadBytesExt, LittleEndian};
use std::io::prelude::*;
use std::io::BufReader;
use std::io::SeekFrom;
use std::fs::File;
use std::cmp::Ordering;
use utils;
use errors::Word2VecError;

/// Representation of a word vector space
///
/// Each word of a vocabulary is represented by a vector. All words span a vector space. This data
/// structure manages this vector space of words.
pub struct WordVector {
    vocabulary: Vec<(String, Vec<f32>)>,
    vector_size: usize,
}

impl WordVector {
    /// Load a word vector space from file
    ///
    /// Word2vec is able to store the word vectors in a binary file. This function parses the file
    /// and loads the vectors into RAM.
    pub fn load_from_binary(file_name: &str) -> Result<WordVector, Word2VecError> {
        let file = try!(File::open(file_name));
        let mut reader = BufReader::new(file);
        let mut header = String::new();
        try!(reader.read_line(&mut header));
        let header_info = header.split_whitespace()
            .filter_map(|x| x.parse::<usize>().ok())
            .take(2)
            .collect::<Vec<usize>>();
        if header_info.len() != 2 {
            return Err(Word2VecError::WrongHeader);
        }
        let vocabulary_size = header_info[0];
        let vector_size = header_info[1];
        let mut vocabulary: Vec<(String, Vec<f32>)> = Vec::with_capacity(vocabulary_size);
        for _ in 0..vocabulary_size {
            let mut word_bytes: Vec<u8> = Vec::new();
            try!(reader.read_until(b' ', &mut word_bytes));
            word_bytes.pop();
            let word = try!(String::from_utf8(word_bytes));
            let mut current_vector: Vec<f32> = Vec::with_capacity(vector_size);
            for _ in 0..vector_size {
                let val = try!(reader.read_f32::<LittleEndian>());
                current_vector.push(val);
            }
            utils::vector_norm(&mut current_vector);
            vocabulary.push((word, current_vector));
            try!(reader.seek(SeekFrom::Current(1)));
        }
        Ok(WordVector {
            vocabulary: vocabulary,
            vector_size: vector_size,
        })
    }

    fn get_index(&self, word: &str) -> Option<usize> {
        self.vocabulary.iter().position(|x| x.0 == word)
    }

    /// Get word vector for the given word.
    pub fn get_vector(&self, word: &str) -> Option<&Vec<f32>> {
        let index = self.get_index(word);
        match index {
            Some(val) => Some(&self.vocabulary[val].1),
            None => None,
        }
    }

    /// Compute consine distance to similar words.
    ///
    /// The words in the vector space are characterized through the position and angle to each
    /// other. This method calculates the `n` closest words via the cosine of the requested word to
    /// all other words.
    pub fn cosine(&self, word: &str, n: usize) -> Option<Vec<(String, f32)>> {
        let word_vector = self.get_vector(word);
        match word_vector {
            Some(val) => { // save index and cosine distance to current word
                let mut metrics: Vec<(usize, f32)> = Vec::with_capacity(self.vocabulary.len());
                metrics.extend(self.vocabulary.iter().enumerate().
                        map(|(i, other_val)|
                    (i, utils::dot_product(&other_val.1, val))));
                metrics.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(Ordering::Equal));
                Some(metrics[1..n+1].iter().map(|&(idx, dist)|
                         (self.vocabulary[idx].clone().0, dist)).collect())
            }
            None => None,
        }
    }

    pub fn analogy(&self, pos: Vec<&str>, neg: Vec<&str>, n: usize) -> Option<Vec<(String, f32)>> {
        let mut vectors: Vec<Vec<f32>> = Vec::new();
        let mut exclude: Vec<String> = Vec::new();
        for word in pos {
            exclude.push(word.to_string());
            match self.get_vector(word) {
                Some(val) => vectors.push(val.clone()),
                None => {}
            }
        }
        for word in neg.iter() {
            exclude.push(word.to_string());
            match self.get_vector(word) {
                Some(val) => vectors.push(val.iter().map(|x| -x).collect::<Vec<f32>>()),
                None => {}
            }
        }
        if exclude.is_empty() {
            return None;
        }
        let mut mean: Vec<f32> = Vec::with_capacity(self.vector_size);
        for i in 0..self.vector_size {
            mean.push(utils::mean(vectors.iter().map(|v| v[i])));
        }
        let mut metrics: Vec<(&String, f32)> = Vec::new();
        for word in self.vocabulary.iter() {
            metrics.push((&word.0, utils::dot_product(&word.1, &mean)));
        }
        metrics.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(Ordering::Equal));
        metrics.retain(|x| !exclude.contains(&x.0));
        Some(metrics.iter().take(n).map(|&(x,y)| (x.clone(), y)).collect())
    }

    /// Get the number of all known words from the vocabulary.
    pub fn word_count(&self) -> usize {
        self.vocabulary.len()
    }

    /// Return the number of columns of the word vector.
    pub fn get_col_count(&self) -> usize {
        self.vector_size // size == column count
    }

    /// Get all known words from the vocabulary.
    pub fn get_words<'a>(&'a self) -> Words<'a> {
        Words::new(&self.vocabulary)
    }
}

pub struct Words<'parent> {
    words: &'parent Vec<(String, Vec<f32>)>,
    index: usize,
}

impl<'a> Words<'a> {
    fn new(x: &'a Vec<(String, Vec<f32>)>) -> Words<'a> {
        Words {
            words: x,
            index: 0,
        }
    }
}

impl<'a> Iterator for Words<'a> {
    type Item = String;

    fn next(&mut self) -> Option<Self::Item> {
        if self.index >= self.words.len() {
            return None;
        }
        self.index += 1;
        Some(self.words[self.index - 1].0.clone())
    }
}
<|endoftext|>