<commit_before>use std::convert::From;
use std::error::Error;
use std::fmt;
use std::num::ParseIntError;

use ansi_term::{ANSIString, Color, Style};

use util::Shell;

/// Representation of config options that all modules have
#[derive(Clone)]
pub struct ModuleOptions<'a> {
    /// String to display to the left of the content
    pub padding_left: &'a str,
    /// String to display to the right of the content
    pub padding_right: &'a str,
    /// String to print out after the content and right padding
    pub separator: &'a str,
    /// Background color, foreground color, etc.
    pub style: ModuleStyle,
}

/// Representation of how to style a module
#[derive(Clone)]
pub struct ModuleStyle {
    /// Color behind the text
    pub background: Option<Color>,
    /// Color of the text
    pub foreground: Option<Color>,
    /// Combination of attributes like bold, italicized, etc.
    pub text_properties: Option<Style>,
}

/// Formats a string with the given `ModuleOptions` for a specific
/// `Shell`.
///
/// # Parameters
///
/// - `s` - the contents of the module to be formatted
/// - `options` - the background, foreground, padding, etc. to apply
/// - `next_bg` - the background color, if any, of the next visible module
/// - `shell` - the type of shell to format the string for
pub fn format_for_module(s: &str,
                         options: &ModuleOptions,
                         next_bg: Option<Color>,
                         shell: Shell)
                         -> ANSIString<'static> {

    let style = style_from_modulestyle(&options.style);

    // Each shell keeps track of the number of characters that make up
    // the prompt. The ANSI escape-sequences that color the text will
    // be accidentally included in this length *unless* we prefix and
    // suffix them with these shell-specific escape-sequences. We
    // don't want the shell to mistakenly think there's fewer
    // characters remaining on the current line than there actually
    // are.
    let (len_esc_prefix, len_esc_suffix) = match shell {
        Shell::Bash => ("\\[", "\\]"),
        Shell::Zsh => ("%{", "%}"),
    };

    // Every time there is a color escape-sequence, it must be
    // surrounded by the length escape-codes. We also include the
    // padding before and after the content.
    let content = format!("{}{}{}{}{}{}{}{}{}",
                    len_esc_prefix,
                    style.prefix(),
                    len_esc_suffix,
                    options.padding_left,
                    s,
                    options.padding_right,
                    len_esc_prefix,
                    style.suffix(),
                    len_esc_suffix,
    );

    // We must format the separator differently depending on whether
    // there exists a visible module after this one or not.
    let separator_style = ModuleStyle {
        foreground: options.style.background,
        background: next_bg,
        text_properties: options.style.text_properties,
    };
    let separator_style = style_from_modulestyle(&separator_style);
    let separator = format!("{}{}{}{}{}{}{}",
                            len_esc_prefix,
                            separator_style.prefix(),
                            len_esc_suffix,
                            options.separator,
                            len_esc_prefix,
                            separator_style.suffix(),
                            len_esc_suffix);

    ANSIString::from(format!("{}{}", content, separator))
}

/// Converts a `ModuleStyle` into an `ansi_term::Style`.
fn style_from_modulestyle(s: &ModuleStyle) -> Style {
    let mut style = s.text_properties.unwrap_or_default();
    if let Some(bg) = s.background {
        style = style.on(bg);
    }
    if let Some(fg) = s.foreground {
        style = style.fg(fg);
    }
    style
}

// We use methods of the form "try_*_from_*" because the user should
// just be able to specify (in their config) what color/style they
// want, and we have to be able to parse what they say into a
// meaningful type.

/// Attempts to convert a string into an `ansi_term::Color`.
///
/// Returns a `ConvertError::NoSuchMatch` if the provided string
/// doesn't match any of the colors defined in crate `ansi_term`.
///
/// # Examples
/// ```
/// assert_eq!(try_color_from_str("black"), Ok(Color::Black));
/// assert_eq!(try_color_from_str("green"), Ok(Color::Green));
/// assert_eq!(try_color_from_str("turquoise"), Err(ConvertError::NoSuchMatch));
/// ```
pub fn try_color_from_str(s: &str) -> Result<Color, ConvertError> {
    match s.to_lowercase().as_ref() {
        "black" => Ok(Color::Black),
        "red" => Ok(Color::Red),
        "green" => Ok(Color::Green),
        "yellow" => Ok(Color::Yellow),
        "blue" => Ok(Color::Blue),
        "purple" => Ok(Color::Purple),
        "cyan" => Ok(Color::Cyan),
        "white" => Ok(Color::White),
        _ => Err(ConvertError::NoSuchMatch),
    }
}

/// Attempts to convert a string into an `ansi_term::Color::RGB`.
///
/// Returns a `ConvertError::InvalidForm` if the provided string is
/// not a sequence of 3 `u8`s, separated by commas.
///
/// # Examples
/// ```
/// assert_eq!(try_rgb_from_str("(14, 76, 1)"), Ok(Color::RGB(14, 76, 1)));
/// assert_eq!(try_rgb_from_str("0, 100, 0"), Ok(Color::RGB(0, 100, 0)));
/// assert_eq!(try_rgb_from_str("1000, b, c, -1"), Err(ConvertError::InvalidForm));
/// ```
pub fn try_rgb_from_str(s: &str) -> Result<Color, ConvertError> {
    // Strip out non-integer characters
    let cleaned: Vec<String> =
        s.split(',').map(|i| i.replace(|j| j == '(' || j == ')' || j == ' ', "")).collect();

    // We want to immediately return an Error if a conversion fails
    let mut ints: Vec<u8> = Vec::new();
    for i in &cleaned {
        ints.push(i.parse::<u8>()?);
    }

    // Note: somewhat-malformed input, like "()()(0, 0, 0)" can still
    // get through, but we can still make "sense" of it so it's good
    // to go.
    if ints.len() != 3 {
        Err(ConvertError::InvalidForm)
    } else {
        Ok(Color::RGB(ints[0], ints[1], ints[2]))
    }
}

// NOTE: We do not need a try_color_from_u8 OR a try_rgb_from_vec.
// The implementation would just look like:
// pub fn try_color_from_u8(i: u8) -> Color { Color::u8(i) }
// It would always succeed due to Rust's type system.

#[derive(Debug, PartialEq)]
/// Error type for when a conversion due to parsing fails
pub enum ConvertError {
    /// Input doesn't correspond to a valid result
    NoSuchMatch,
    /// Input is malformed and cannot be parsed
    InvalidForm,
}

impl fmt::Display for ConvertError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl Error for ConvertError {
    fn description(&self) -> &str {
        match *self {
            ConvertError::NoSuchMatch => "no match was found for the provided input",
            ConvertError::InvalidForm => "provided input was malformed and could not be parsed",
        }
    }
}

// So that we can use try!() and ? to return early if we encounter a
// ParseIntError
impl From<ParseIntError> for ConvertError {
    fn from(_: ParseIntError) -> ConvertError {
        ConvertError::InvalidForm
    }
}

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

    #[test]
    fn test_format_for_module() {
        const CONTENT: &'static str = "Hello";
        const PADDING: &'static str = " ";
        const SEPARATOR: &'static str = ">";

        let options = ModuleOptions {
            padding_left: PADDING,
            padding_right: PADDING,
            separator: SEPARATOR,
            style: ModuleStyle {
                background: Some(Color::Blue),
                foreground: Some(Color::White),
                text_properties: Some(Style::default().bold()),
            },
        };

        let formatted_string = format_for_module(CONTENT, &options, None, Shell::Bash);
        assert_eq!(format!("\\[\x1B[1;44;37m\\]{}{}{}\\[\x1B[0m\\]\\[\x1B[1;34m\\]{}\\[\x1B[0m\\]",
                           PADDING,
                           CONTENT,
                           PADDING,
                           SEPARATOR),
                   format!("{}", formatted_string))
    }

    #[test]
    fn test_style_from_modulestyle() {
        const CONTENT: &'static str = "Hello";

        struct Test {
            style: ModuleStyle,
            expected: String,
        }

        let tests = [// Normal text, no bg, custom fg
                     Test {
                         style: ModuleStyle {
                             background: None,
                             foreground: Some(Color::White),
                             text_properties: None,
                         },
                         expected: format!("\x1B[37m{}\x1B[0m", CONTENT),
                     },
                     // Bold text, no fg, custom bg
                     Test {
                         style: ModuleStyle {
                             background: Some(Color::Blue),
                             foreground: None,
                             text_properties: Some(Style::default().bold()),
                         },
                         expected: format!("\x1B[1;44m{}\x1B[0m", CONTENT),
                     },
                     // Underlined text, custom bg and fg
                     Test {
                         style: ModuleStyle {
                             background: Some(Color::Blue),
                             foreground: Some(Color::White),
                             text_properties: Some(Style::default().underline()),
                         },
                         expected: format!("\x1B[4;44;37m{}\x1B[0m", CONTENT),
                     },
                     // Normal text, no bg nor fg
                     Test {
                         style: ModuleStyle {
                             background: None,
                             foreground: None,
                             text_properties: None,
                         },
                         expected: format!("{}", CONTENT),
                     }];

        for test in &tests {
            let result = format!("{}", style_from_modulestyle(&test.style).paint(CONTENT));
            assert_eq!(result, test.expected);
        }
    }

    #[test]
    fn test_color_try_from_str() {
        assert_eq!(try_color_from_str("blue"), Ok(Color::Blue));
        assert_eq!(try_color_from_str("teal"), Err(ConvertError::NoSuchMatch));
    }

    #[test]
    fn test_rgb_try_from_str() {
        // Valid inputs
        assert_eq!(try_rgb_from_str("(0, 0, 0)"), Ok(Color::RGB(0, 0, 0)));
        assert_eq!(try_rgb_from_str("(255, 255, 255)"),
                   Ok(Color::RGB(255, 255, 255)));

        // Questionable inputs (should still work)
        assert_eq!(try_rgb_from_str("(0, 0, 0))"), Ok(Color::RGB(0, 0, 0)));

        // Improperly formed ("too many" inputs)
        assert_eq!(try_rgb_from_str("(0, 0, 0,)"),
                   Err(ConvertError::InvalidForm));

        // Too few inputs
        assert_eq!(try_rgb_from_str("(0, 0)"), Err(ConvertError::InvalidForm));

        // Inputs aren't u8's
        assert_eq!(try_rgb_from_str("(1000, 0, 0)"),
                   Err(ConvertError::InvalidForm));
        assert_eq!(try_rgb_from_str("(0, 0, -1)"),
                   Err(ConvertError::InvalidForm));
    }
}
<commit_msg>feat: implement try_fixed_from_str<commit_after>use std::convert::From;
use std::error::Error;
use std::fmt;
use std::num::ParseIntError;

use ansi_term::{ANSIString, Color, Style};

use util::Shell;

/// Representation of config options that all modules have
#[derive(Clone)]
pub struct ModuleOptions<'a> {
    /// String to display to the left of the content
    pub padding_left: &'a str,
    /// String to display to the right of the content
    pub padding_right: &'a str,
    /// String to print out after the content and right padding
    pub separator: &'a str,
    /// Background color, foreground color, etc.
    pub style: ModuleStyle,
}

/// Representation of how to style a module
#[derive(Clone)]
pub struct ModuleStyle {
    /// Color behind the text
    pub background: Option<Color>,
    /// Color of the text
    pub foreground: Option<Color>,
    /// Combination of attributes like bold, italicized, etc.
    pub text_properties: Option<Style>,
}

/// Formats a string with the given `ModuleOptions` for a specific
/// `Shell`.
///
/// # Parameters
///
/// - `s` - the contents of the module to be formatted
/// - `options` - the background, foreground, padding, etc. to apply
/// - `next_bg` - the background color, if any, of the next visible module
/// - `shell` - the type of shell to format the string for
pub fn format_for_module(s: &str,
                         options: &ModuleOptions,
                         next_bg: Option<Color>,
                         shell: Shell)
                         -> ANSIString<'static> {

    let style = style_from_modulestyle(&options.style);

    // Each shell keeps track of the number of characters that make up
    // the prompt. The ANSI escape-sequences that color the text will
    // be accidentally included in this length *unless* we prefix and
    // suffix them with these shell-specific escape-sequences. We
    // don't want the shell to mistakenly think there's fewer
    // characters remaining on the current line than there actually
    // are.
    let (len_esc_prefix, len_esc_suffix) = match shell {
        Shell::Bash => ("\\[", "\\]"),
        Shell::Zsh => ("%{", "%}"),
    };

    // Every time there is a color escape-sequence, it must be
    // surrounded by the length escape-codes. We also include the
    // padding before and after the content.
    let content = format!("{}{}{}{}{}{}{}{}{}",
                    len_esc_prefix,
                    style.prefix(),
                    len_esc_suffix,
                    options.padding_left,
                    s,
                    options.padding_right,
                    len_esc_prefix,
                    style.suffix(),
                    len_esc_suffix,
    );

    // We must format the separator differently depending on whether
    // there exists a visible module after this one or not.
    let separator_style = ModuleStyle {
        foreground: options.style.background,
        background: next_bg,
        text_properties: options.style.text_properties,
    };
    let separator_style = style_from_modulestyle(&separator_style);
    let separator = format!("{}{}{}{}{}{}{}",
                            len_esc_prefix,
                            separator_style.prefix(),
                            len_esc_suffix,
                            options.separator,
                            len_esc_prefix,
                            separator_style.suffix(),
                            len_esc_suffix);

    ANSIString::from(format!("{}{}", content, separator))
}

/// Converts a `ModuleStyle` into an `ansi_term::Style`.
fn style_from_modulestyle(s: &ModuleStyle) -> Style {
    let mut style = s.text_properties.unwrap_or_default();
    if let Some(bg) = s.background {
        style = style.on(bg);
    }
    if let Some(fg) = s.foreground {
        style = style.fg(fg);
    }
    style
}

// We use methods of the form "try_*_from_*" because the user should
// just be able to specify (in their config) what color/style they
// want, and we have to be able to parse what they say into a
// meaningful type.

/// Attempts to convert a string into an `ansi_term::Color`.
///
/// Returns a `ConvertError::NoSuchMatch` if the provided string
/// doesn't match any of the colors defined in crate `ansi_term`.
///
/// # Examples
///
/// ```
/// assert_eq!(try_color_from_str("black"), Ok(Color::Black));
/// assert_eq!(try_color_from_str("green"), Ok(Color::Green));
/// assert_eq!(try_color_from_str("turquoise"), Err(ConvertError::NoSuchMatch));
/// ```
pub fn try_color_from_str(s: &str) -> Result<Color, ConvertError> {
    match s.to_lowercase().as_ref() {
        "black" => Ok(Color::Black),
        "red" => Ok(Color::Red),
        "green" => Ok(Color::Green),
        "yellow" => Ok(Color::Yellow),
        "blue" => Ok(Color::Blue),
        "purple" => Ok(Color::Purple),
        "cyan" => Ok(Color::Cyan),
        "white" => Ok(Color::White),
        _ => Err(ConvertError::NoSuchMatch),
    }
}

/// Attempts to convert a string into an `ansi_term::Color::RGB`.
///
/// Returns a `ConvertError::InvalidForm` if the provided string is
/// not a sequence of 3 `u8`s, separated by commas.
///
/// # Examples
///
/// ```
/// assert_eq!(try_rgb_from_str("(14, 76, 1)"), Ok(Color::RGB(14, 76, 1)));
/// assert_eq!(try_rgb_from_str("0, 100, 0"), Ok(Color::RGB(0, 100, 0)));
/// assert_eq!(try_rgb_from_str("1000, b, c, -1"), Err(ConvertError::InvalidForm));
/// ```
pub fn try_rgb_from_str(s: &str) -> Result<Color, ConvertError> {
    // Strip out non-integer characters
    let cleaned: Vec<String> =
        s.split(',').map(|i| i.replace(|j| j == '(' || j == ')' || j == ' ', "")).collect();

    // We want to immediately return an Error if a conversion fails
    let mut ints: Vec<u8> = Vec::new();
    for i in &cleaned {
        ints.push(i.parse::<u8>()?);
    }

    // Note: somewhat-malformed input, like "()()(0, 0, 0)" can still
    // get through, but we can still make "sense" of it so it's good
    // to go.
    if ints.len() != 3 {
        Err(ConvertError::InvalidForm)
    } else {
        Ok(Color::RGB(ints[0], ints[1], ints[2]))
    }
}

/// Attempts to convert a string into an `ansi_term::Color::Fixed`.
///
/// Returns a `ConvertError::InvalidForm` if the provided string fails
/// to coerce into a `u8`.
///
/// # Examples
///
/// ```
/// assert_eq!(try_fixed_from_str("63"), Ok(Color::Fixed(63)));
/// assert_eq!(try_fixed_from_str("257"), Err(ConvertError::InvalidForm));
/// ```
pub fn try_fixed_from_str(s: &str) -> Result<Color, ConvertError> {
    Ok(Color::Fixed(s.parse::<u8>()?))
}

// NOTE: We do not need a try_color_from_u8 OR a try_rgb_from_vec.
// The implementation would just look like:
// pub fn try_color_from_u8(i: u8) -> Color { Color::u8(i) }
// It would always succeed due to Rust's type system.

#[derive(Debug, PartialEq)]
/// Error type for when a conversion due to parsing fails
pub enum ConvertError {
    /// Input doesn't correspond to a valid result
    NoSuchMatch,
    /// Input is malformed and cannot be parsed
    InvalidForm,
}

impl fmt::Display for ConvertError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl Error for ConvertError {
    fn description(&self) -> &str {
        match *self {
            ConvertError::NoSuchMatch => "no match was found for the provided input",
            ConvertError::InvalidForm => "provided input was malformed and could not be parsed",
        }
    }
}

// So that we can use try!() and ? to return early if we encounter a
// ParseIntError
impl From<ParseIntError> for ConvertError {
    fn from(_: ParseIntError) -> ConvertError {
        ConvertError::InvalidForm
    }
}

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

    #[test]
    fn test_format_for_module() {
        const CONTENT: &'static str = "Hello";
        const PADDING: &'static str = " ";
        const SEPARATOR: &'static str = ">";

        let options = ModuleOptions {
            padding_left: PADDING,
            padding_right: PADDING,
            separator: SEPARATOR,
            style: ModuleStyle {
                background: Some(Color::Blue),
                foreground: Some(Color::White),
                text_properties: Some(Style::default().bold()),
            },
        };

        let formatted_string = format_for_module(CONTENT, &options, None, Shell::Bash);
        assert_eq!(format!("\\[\x1B[1;44;37m\\]{}{}{}\\[\x1B[0m\\]\\[\x1B[1;34m\\]{}\\[\x1B[0m\\]",
                           PADDING,
                           CONTENT,
                           PADDING,
                           SEPARATOR),
                   format!("{}", formatted_string))
    }

    #[test]
    fn test_style_from_modulestyle() {
        const CONTENT: &'static str = "Hello";

        struct Test {
            style: ModuleStyle,
            expected: String,
        }

        let tests = [// Normal text, no bg, custom fg
                     Test {
                         style: ModuleStyle {
                             background: None,
                             foreground: Some(Color::White),
                             text_properties: None,
                         },
                         expected: format!("\x1B[37m{}\x1B[0m", CONTENT),
                     },
                     // Bold text, no fg, custom bg
                     Test {
                         style: ModuleStyle {
                             background: Some(Color::Blue),
                             foreground: None,
                             text_properties: Some(Style::default().bold()),
                         },
                         expected: format!("\x1B[1;44m{}\x1B[0m", CONTENT),
                     },
                     // Underlined text, custom bg and fg
                     Test {
                         style: ModuleStyle {
                             background: Some(Color::Blue),
                             foreground: Some(Color::White),
                             text_properties: Some(Style::default().underline()),
                         },
                         expected: format!("\x1B[4;44;37m{}\x1B[0m", CONTENT),
                     },
                     // Normal text, no bg nor fg
                     Test {
                         style: ModuleStyle {
                             background: None,
                             foreground: None,
                             text_properties: None,
                         },
                         expected: format!("{}", CONTENT),
                     }];

        for test in &tests {
            let result = format!("{}", style_from_modulestyle(&test.style).paint(CONTENT));
            assert_eq!(result, test.expected);
        }
    }

    #[test]
    fn test_try_color_from_str() {
        // Corresponds to one of the colors defined in `ansi_term`
        assert_eq!(try_color_from_str("blue"), Ok(Color::Blue));

        // Not part of the `ansi_term::Color` enum
        assert_eq!(try_color_from_str("teal"), Err(ConvertError::NoSuchMatch));
    }

    #[test]
    fn test_try_fixed_from_str() {
        // Valid inputs
        assert_eq!(try_fixed_from_str("0"), Ok(Color::Fixed(0)));
        assert_eq!(try_fixed_from_str("100"), Ok(Color::Fixed(100)));

        // Inputs that can't be parsed to u8
        assert_eq!(try_fixed_from_str("256"), Err(ConvertError::InvalidForm));
        assert_eq!(try_fixed_from_str("-1"), Err(ConvertError::InvalidForm));
    }

    #[test]
    fn test_try_rgb_from_str() {
        // Valid inputs
        assert_eq!(try_rgb_from_str("(0, 0, 0)"), Ok(Color::RGB(0, 0, 0)));
        assert_eq!(try_rgb_from_str("(255, 255, 255)"),
                   Ok(Color::RGB(255, 255, 255)));

        // Questionable inputs (should still work)
        assert_eq!(try_rgb_from_str("(0, 0, 0))"), Ok(Color::RGB(0, 0, 0)));

        // Improperly formed ("too many" inputs)
        assert_eq!(try_rgb_from_str("(0, 0, 0,)"),
                   Err(ConvertError::InvalidForm));

        // Too few inputs
        assert_eq!(try_rgb_from_str("(0, 0)"), Err(ConvertError::InvalidForm));

        // Inputs aren't u8's
        assert_eq!(try_rgb_from_str("(1000, 0, 0)"),
                   Err(ConvertError::InvalidForm));
        assert_eq!(try_rgb_from_str("(0, 0, -1)"),
                   Err(ConvertError::InvalidForm));
    }
}
<|endoftext|>


<commit_before>// rust-xmpp
// Copyright (c) 2015 Florian Zeitz
//
// This project is MIT licensed.
// Please see the COPYING file for more information.

use std::fmt;
use ns;
use xmpp_send::XmppSend;

#[derive(Debug)]
pub struct StreamStart<'a> {
    pub to: &'a str
}

impl<'a> fmt::Display for StreamStart<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "<?xml version='1.0'?>\n\
               <stream:stream xmlns:stream='{}' xmlns='{}' version='1.0' to='{}'>",
               ns::STREAMS, ns::JABBER_CLIENT, self.to)
    }
}

impl<'a> XmppSend for StreamStart<'a> {}

#[derive(Debug)]
pub struct StreamEnd;

impl fmt::Display for StreamEnd {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "</stream:stream>")
    }
}

impl XmppSend for StreamEnd {}

#[derive(Debug)]
pub struct StartTls;

impl fmt::Display for StartTls {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "<starttls xmlns='{}'/>", ns::FEATURE_TLS)
    }
}

impl XmppSend for StartTls {}

#[derive(Debug)]
pub struct AuthStart<'a> {
    pub mech: &'a str,
    pub data: &'a str
}

impl<'a> fmt::Display for AuthStart<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.data.len() == 0 {
            write!(f, "<auth mechanism='{}' xmlns='{}'/>",
                   self.mech, ns::FEATURE_SASL)
        } else {
            write!(f, "<auth mechanism='{}' xmlns='{}'>{}</auth>",
                   self.mech, ns::FEATURE_SASL, self.data)
        }
    }
}

impl<'a> XmppSend for AuthStart<'a> {}

#[derive(Debug)]
pub struct AuthResponse<'a> {
    pub data: &'a str
}

impl<'a> fmt::Display for AuthResponse<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "<response xmlns='{}'>{}</response>", ns::FEATURE_SASL, self.data)
    }
}

impl<'a> XmppSend for AuthResponse<'a> {}

#[allow(dead_code)]
#[derive(Debug)]
pub enum DefinedCondition {
    BadFormat,
    BadNamespacePrefix,
    Conflict,
    ConnectionTimeout,
    HostGone,
    HostUnknown,
    ImproperAddressing,
    InternalServerError,
    InvalidFrom,
    InvalidId,
    InvalidNamespace,
    InvalidXml,
    NotAuthorized,
    NotWellFormed,
    PolicyViolation,
    RemoteConnectionFailed,
    Reset,
    ResourceConstraint,
    RestrictedXml,
    SeeOtherHost(String),
    SystemShutdown,
    UndefinedCondition,
    UnsupportedEncoding,
    UnsupportedStanzaType,
    UnsupportedVersion,
}

impl fmt::Display for DefinedCondition {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let name = match *self {
            DefinedCondition::BadFormat => "bad-format",
            DefinedCondition::BadNamespacePrefix => "bad-namespace-prefix",
            DefinedCondition::Conflict => "conflict",
            DefinedCondition::ConnectionTimeout => "connection-timeout",
            DefinedCondition::HostGone => "host-gone",
            DefinedCondition::HostUnknown => "host-unknown",
            DefinedCondition::ImproperAddressing => "improper-addressing",
            DefinedCondition::InternalServerError => "internal-server-error",
            DefinedCondition::InvalidFrom => "invalid-from",
            DefinedCondition::InvalidId => "invalid-id",
            DefinedCondition::InvalidNamespace => "invalid-namespace",
            DefinedCondition::InvalidXml => "invalid-xml",
            DefinedCondition::NotAuthorized => "not-authorized",
            DefinedCondition::NotWellFormed => "not-well-formed",
            DefinedCondition::PolicyViolation => "policy-violation",
            DefinedCondition::RemoteConnectionFailed => "remote-connection-failed",
            DefinedCondition::Reset => "reset",
            DefinedCondition::ResourceConstraint => "resource-constraint",
            DefinedCondition::RestrictedXml => "restricted-xml",
            DefinedCondition::SeeOtherHost(ref host) => {
                return write!(f, "<see-other-host xmlns='{}'>{}</see-other-host>",
                              ns::STREAM_ERRORS, host);
            }
            DefinedCondition::SystemShutdown => "system-shutdown",
            DefinedCondition::UndefinedCondition => "undefined-condition",
            DefinedCondition::UnsupportedEncoding => "unsupported-encoding",
            DefinedCondition::UnsupportedStanzaType => "unsupported-stanza-type",
            DefinedCondition::UnsupportedVersion => "unsupported-version"
        };
        write!(f, "<{} xmlns='{}'/>", name, ns::STREAM_ERRORS)
    }
}

#[derive(Debug)]
pub struct StreamError<'a> {
    pub cond: DefinedCondition,
    pub text: Option<&'a str>
}

impl<'a> fmt::Display for StreamError<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(write!(f, "<stream:error>{}", self.cond));
        if let Some(text) = self.text {
            try!(write!(f, "<text xmlns='{}'>{}</text>", ns::STREAM_ERRORS, text));
        }
        write!(f, "</stream:error>")
    }
}

impl<'a> XmppSend for StreamError<'a> {}
<commit_msg>non_stanzas AuthStart: fmt empty data as =<commit_after>// rust-xmpp
// Copyright (c) 2015 Florian Zeitz
//
// This project is MIT licensed.
// Please see the COPYING file for more information.

use std::fmt;
use ns;
use xmpp_send::XmppSend;

#[derive(Debug)]
pub struct StreamStart<'a> {
    pub to: &'a str
}

impl<'a> fmt::Display for StreamStart<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "<?xml version='1.0'?>\n\
               <stream:stream xmlns:stream='{}' xmlns='{}' version='1.0' to='{}'>",
               ns::STREAMS, ns::JABBER_CLIENT, self.to)
    }
}

impl<'a> XmppSend for StreamStart<'a> {}

#[derive(Debug)]
pub struct StreamEnd;

impl fmt::Display for StreamEnd {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "</stream:stream>")
    }
}

impl XmppSend for StreamEnd {}

#[derive(Debug)]
pub struct StartTls;

impl fmt::Display for StartTls {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "<starttls xmlns='{}'/>", ns::FEATURE_TLS)
    }
}

impl XmppSend for StartTls {}

#[derive(Debug)]
pub struct AuthStart<'a> {
    pub mech: &'a str,
    pub data: &'a str
}

impl<'a> fmt::Display for AuthStart<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let data = if self.data.len() > 0 {
            self.data
        } else {
            "="
        };
        write!(f, "<auth mechanism='{}' xmlns='{}'>{}</auth>",
               self.mech, ns::FEATURE_SASL, data)
    }
}

impl<'a> XmppSend for AuthStart<'a> {}

#[derive(Debug)]
pub struct AuthResponse<'a> {
    pub data: &'a str
}

impl<'a> fmt::Display for AuthResponse<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "<response xmlns='{}'>{}</response>", ns::FEATURE_SASL, self.data)
    }
}

impl<'a> XmppSend for AuthResponse<'a> {}

#[allow(dead_code)]
#[derive(Debug)]
pub enum DefinedCondition {
    BadFormat,
    BadNamespacePrefix,
    Conflict,
    ConnectionTimeout,
    HostGone,
    HostUnknown,
    ImproperAddressing,
    InternalServerError,
    InvalidFrom,
    InvalidId,
    InvalidNamespace,
    InvalidXml,
    NotAuthorized,
    NotWellFormed,
    PolicyViolation,
    RemoteConnectionFailed,
    Reset,
    ResourceConstraint,
    RestrictedXml,
    SeeOtherHost(String),
    SystemShutdown,
    UndefinedCondition,
    UnsupportedEncoding,
    UnsupportedStanzaType,
    UnsupportedVersion,
}

impl fmt::Display for DefinedCondition {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let name = match *self {
            DefinedCondition::BadFormat => "bad-format",
            DefinedCondition::BadNamespacePrefix => "bad-namespace-prefix",
            DefinedCondition::Conflict => "conflict",
            DefinedCondition::ConnectionTimeout => "connection-timeout",
            DefinedCondition::HostGone => "host-gone",
            DefinedCondition::HostUnknown => "host-unknown",
            DefinedCondition::ImproperAddressing => "improper-addressing",
            DefinedCondition::InternalServerError => "internal-server-error",
            DefinedCondition::InvalidFrom => "invalid-from",
            DefinedCondition::InvalidId => "invalid-id",
            DefinedCondition::InvalidNamespace => "invalid-namespace",
            DefinedCondition::InvalidXml => "invalid-xml",
            DefinedCondition::NotAuthorized => "not-authorized",
            DefinedCondition::NotWellFormed => "not-well-formed",
            DefinedCondition::PolicyViolation => "policy-violation",
            DefinedCondition::RemoteConnectionFailed => "remote-connection-failed",
            DefinedCondition::Reset => "reset",
            DefinedCondition::ResourceConstraint => "resource-constraint",
            DefinedCondition::RestrictedXml => "restricted-xml",
            DefinedCondition::SeeOtherHost(ref host) => {
                return write!(f, "<see-other-host xmlns='{}'>{}</see-other-host>",
                              ns::STREAM_ERRORS, host);
            }
            DefinedCondition::SystemShutdown => "system-shutdown",
            DefinedCondition::UndefinedCondition => "undefined-condition",
            DefinedCondition::UnsupportedEncoding => "unsupported-encoding",
            DefinedCondition::UnsupportedStanzaType => "unsupported-stanza-type",
            DefinedCondition::UnsupportedVersion => "unsupported-version"
        };
        write!(f, "<{} xmlns='{}'/>", name, ns::STREAM_ERRORS)
    }
}

#[derive(Debug)]
pub struct StreamError<'a> {
    pub cond: DefinedCondition,
    pub text: Option<&'a str>
}

impl<'a> fmt::Display for StreamError<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(write!(f, "<stream:error>{}", self.cond));
        if let Some(text) = self.text {
            try!(write!(f, "<text xmlns='{}'>{}</text>", ns::STREAM_ERRORS, text));
        }
        write!(f, "</stream:error>")
    }
}

impl<'a> XmppSend for StreamError<'a> {}
<|endoftext|>


<commit_before>// Copyright (c) 2016-2017 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

pub mod archive;
pub mod ident;
pub mod install;
pub mod metadata;
pub mod plan;
pub mod target;

mod list;

pub use self::archive::{FromArchive, PackageArchive};
pub use self::ident::{Identifiable, PackageIdent};
pub use self::install::PackageInstall;
pub use self::list::all_packages;
pub use self::plan::Plan;
pub use self::target::PackageTarget;

#[cfg(test)]
pub mod test_support {
    use super::metadata::MetaFile;
    use super::*;
    use fs;
    use std::fs::{create_dir_all, File};
    use std::io::Write;
    use std::path::{Path, PathBuf};
    use std::str::FromStr;
    use time;

    pub fn fixture_path(name: &str) -> PathBuf {
        let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
            .join("tests")
            .join("fixtures")
            .join(name);
        path
    }

    /// Creates a minimal installed package under an fs_root and return a corresponding loaded
    /// `PackageInstall` suitable for testing against. The `IDENT` and `TARGET` metafiles are
    /// created and for the target system the tests are running on. Further subdirectories, files,
    /// and metafile can be created under this path.
    pub fn testing_package_install(ident: &str, fs_root: &Path) -> PackageInstall {
        fn write_file(path: &Path, content: &str) {
            let mut f = File::create(path).unwrap();
            f.write_all(content.as_bytes()).unwrap()
        }

        let mut pkg_ident = PackageIdent::from_str(ident).unwrap();
        if !pkg_ident.fully_qualified() {
            if let None = pkg_ident.version {
                pkg_ident.version = Some(String::from("1.0.0"));
            }
            if let None = pkg_ident.release {
                pkg_ident.release = Some(
                    time::now_utc()
                        .strftime("%Y%m%d%H%M%S")
                        .unwrap()
                        .to_string(),
                );
            }
        }
        let pkg_install_path = fs::pkg_install_path(&pkg_ident, Some(fs_root));

        create_dir_all(&pkg_install_path).unwrap();
        write_file(
            &pkg_install_path.join(MetaFile::Ident.to_string()),
            &pkg_ident.to_string(),
        );
        write_file(
            &pkg_install_path.join(MetaFile::Target.to_string()),
            PackageTarget::active_target(),
        );

        PackageInstall::load(&pkg_ident, Some(fs_root))
            .expect(&format!("PackageInstall should load for {}", &pkg_ident))
    }
}
<commit_msg>make package list module public tro fix habitat dep code<commit_after>// Copyright (c) 2016-2017 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

pub mod archive;
pub mod ident;
pub mod install;
pub mod list;
pub mod metadata;
pub mod plan;
pub mod target;

pub use self::archive::{FromArchive, PackageArchive};
pub use self::ident::{Identifiable, PackageIdent};
pub use self::install::PackageInstall;
pub use self::list::all_packages;
pub use self::plan::Plan;
pub use self::target::PackageTarget;

#[cfg(test)]
pub mod test_support {
    use super::metadata::MetaFile;
    use super::*;
    use fs;
    use std::fs::{create_dir_all, File};
    use std::io::Write;
    use std::path::{Path, PathBuf};
    use std::str::FromStr;
    use time;

    pub fn fixture_path(name: &str) -> PathBuf {
        let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
            .join("tests")
            .join("fixtures")
            .join(name);
        path
    }

    /// Creates a minimal installed package under an fs_root and return a corresponding loaded
    /// `PackageInstall` suitable for testing against. The `IDENT` and `TARGET` metafiles are
    /// created and for the target system the tests are running on. Further subdirectories, files,
    /// and metafile can be created under this path.
    pub fn testing_package_install(ident: &str, fs_root: &Path) -> PackageInstall {
        fn write_file(path: &Path, content: &str) {
            let mut f = File::create(path).unwrap();
            f.write_all(content.as_bytes()).unwrap()
        }

        let mut pkg_ident = PackageIdent::from_str(ident).unwrap();
        if !pkg_ident.fully_qualified() {
            if let None = pkg_ident.version {
                pkg_ident.version = Some(String::from("1.0.0"));
            }
            if let None = pkg_ident.release {
                pkg_ident.release = Some(
                    time::now_utc()
                        .strftime("%Y%m%d%H%M%S")
                        .unwrap()
                        .to_string(),
                );
            }
        }
        let pkg_install_path = fs::pkg_install_path(&pkg_ident, Some(fs_root));

        create_dir_all(&pkg_install_path).unwrap();
        write_file(
            &pkg_install_path.join(MetaFile::Ident.to_string()),
            &pkg_ident.to_string(),
        );
        write_file(
            &pkg_install_path.join(MetaFile::Target.to_string()),
            PackageTarget::active_target(),
        );

        PackageInstall::load(&pkg_ident, Some(fs_root))
            .expect(&format!("PackageInstall should load for {}", &pkg_ident))
    }
}
<|endoftext|>


<commit_before>use regex::Regex;
use parser::{Span, Text, Emphasis, Strong, Code, Link, Image};

static SPANS : Regex = regex!(r"(!?\[.*\]\([^\(\)]*\))|(\*[^\*].+?\*)|(\*\*.+?\*\*)|(_[^_].+?_)|(__.+?__)|(`[^`].+?`)|(``.+?``)");
static LINK  : Regex = regex!("\\[(?P<text>.*)\\]\\((?P<url>.*?)(?:\\s\"(?P<title>.*?)\")?\\)");
static EMPHASIS_UNDERSCORE  : Regex = regex!(r"^_(?P<text>[^_].+?)_");
static EMPHASIS_STAR  : Regex = regex!(r"^\*(?P<text>[^\*].+?)\*");

pub fn parse_spans(text : &str) -> Vec<Span>{
    let mut tokens = vec![];
    let mut current = 0;
    for (begin, end) in SPANS.find_iter(text) {
        tokens.push(Text(text.slice(current, begin)));
        tokens.push(parse_span(text.slice(begin, end)));
        current = end;
    }
    tokens.push(Text(text.slice(current, text.len())));
    tokens
}

fn parse_span(text : &str) -> Span{
    if LINK.is_match(text){
        let caps = LINK.captures(text).unwrap();
        return Link(
            caps.name("text"),
            caps.name("url"),
            caps.name("title")
            );
    }else if EMPHASIS_UNDERSCORE.is_match(text){
        let caps = EMPHASIS_UNDERSCORE.captures(text).unwrap();
        return Emphasis(caps.name("text"));
    }else if EMPHASIS_STAR.is_match(text){
        let caps = EMPHASIS_STAR.captures(text).unwrap();
        return Emphasis(caps.name("text"));
    }
    return Text(text);
}

#[test]
fn parse_emphasis_test() {
    match parse_span("_whatever_"){
      Emphasis("whatever") => {},
      _ => fail!()
    }
    match parse_span("__whatever__"){
      Emphasis("whatever") => fail!(),
      _ => {}
    }
    match parse_span("*whatever*"){
      Emphasis("whatever") => {},
      _ => fail!()
    }
    match parse_span("**whatever**"){
      Emphasis("whatever") => fail!(),
      _ => {}
    }
}

#[test]
fn parse_strong_test() {
    match parse_span("__whatever__"){
      Strong("whatever") => {},
      _ => fail!()
    }
    match parse_span("_whatever_"){
      Strong("whatever") => fail!(),
      _ => {}
    }
    match parse_span("**whatever**"){
      Strong("whatever") => {},
      _ => fail!()
    }
    match parse_span("*whatever*"){
      Strong("whatever") => fail!(),
      _ => {}
    }
}

#[test]
fn parse_link_test() {
    match parse_span("[an example](example.com)"){
      Link("an example", "example.com", "") => {},
      _ => fail!()
    }
    match parse_span("[an example](example.com \"Title\")"){
      Link("an example", "example.com", "Title") => {},
      _ => fail!()
    }
}

#[test]
fn parse_image_test() {
    match parse_span("![an example](example.com)"){
      Image("an example", "example.com", "") => {},
      _ => fail!()
    }
    match parse_span("[an example](example.com \"Title\")"){
      Image("an example", "example.com", "Title") => {},
      _ => fail!()
    }
}

<commit_msg>parse images, more tests<commit_after>use regex::Regex;
use parser::{Span, Text, Emphasis, Strong, Code, Link, Image};

static SPANS : Regex = regex!(r"(!?\[.*\]\([^\(\)]*\))|(\*[^\*].+?\*)|(\*\*.+?\*\*)|(_[^_].+?_)|(__.+?__)|(`[^`].+?`)|(``.+?``)");
static LINK  : Regex = regex!("\\[(?P<text>.*)\\]\\((?P<url>.*?)(?:\\s\"(?P<title>.*?)\")?\\)");
static IMAGE  : Regex = regex!("!\\[(?P<text>.*)\\]\\((?P<url>.*?)(?:\\s\"(?P<title>.*?)\")?\\)");
static EMPHASIS_UNDERSCORE  : Regex = regex!(r"^_(?P<text>[^_].+?)_");
static EMPHASIS_STAR  : Regex = regex!(r"^\*(?P<text>[^\*].+?)\*");

pub fn parse_spans(text : &str) -> Vec<Span>{
    let mut tokens = vec![];
    let mut current = 0;
    for (begin, end) in SPANS.find_iter(text) {
        tokens.push(Text(text.slice(current, begin)));
        tokens.push(parse_span(text.slice(begin, end)));
        current = end;
    }
    tokens.push(Text(text.slice(current, text.len())));
    tokens
}

fn parse_span(text : &str) -> Span{
    if IMAGE.is_match(text){
        let caps = IMAGE.captures(text).unwrap();
        return Image(
            caps.name("text"),
            caps.name("url"),
            caps.name("title")
            );
    }else if LINK.is_match(text){
        let caps = LINK.captures(text).unwrap();
        return Link(
            caps.name("text"),
            caps.name("url"),
            caps.name("title")
            );
    }else if EMPHASIS_UNDERSCORE.is_match(text){
        let caps = EMPHASIS_UNDERSCORE.captures(text).unwrap();
        return Emphasis(caps.name("text"));
    }else if EMPHASIS_STAR.is_match(text){
        let caps = EMPHASIS_STAR.captures(text).unwrap();
        return Emphasis(caps.name("text"));
    }
    return Text(text);
}

#[test]
fn parse_emphasis_test() {
    match parse_span("_whatever_"){
      Emphasis("whatever") => {},
      _ => fail!()
    }
    match parse_span("__whatever__"){
      Emphasis("whatever") => fail!(),
      _ => {}
    }
    match parse_span("*whatever*"){
      Emphasis("whatever") => {},
      _ => fail!()
    }
    match parse_span("**whatever**"){
      Emphasis("whatever") => fail!(),
      _ => {}
    }
}

#[test]
fn parse_strong_test() {
    match parse_span("__whatever__"){
      Strong("whatever") => {},
      _ => fail!()
    }
    match parse_span("__what_ever__"){
      Strong("what_ever") => {},
      _ => fail!()
    }
    match parse_span("_whatever_"){
      Strong("whatever") => fail!(),
      _ => {}
    }
    match parse_span("**whatever**"){
      Strong("whatever") => {},
      _ => fail!()
    }
    match parse_span("**what*ever**"){
      Strong("what*ever") => {},
      _ => fail!()
    }
    match parse_span("*whatever*"){
      Strong("whatever") => fail!(),
      _ => {}
    }
}

#[test]
fn parse_link_test() {
    match parse_span("[an example](example.com)"){
      Link("an example", "example.com", "") => {},
      _ => fail!()
    }
    match parse_span("[an example](example.com \"Title\")"){
      Link("an example", "example.com", "Title") => {},
      _ => fail!()
    }
}

#[test]
fn parse_image_test() {
    match parse_span("![an example](example.com)"){
      Image("an example", "example.com", "") => {},
      _ => fail!()
    }
    match parse_span("![an example](example.com \"Title\")"){
      Image("an example", "example.com", "Title") => {},
      _ => fail!()
    }
}

<|endoftext|>


<commit_before>use crate::intrinsics;
use crate::iter::{
    DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator, TrustedRandomAccess,
};
use crate::ops::Try;

/// An iterator that yields `None` forever after the underlying iterator
/// yields `None` once.
///
/// This `struct` is created by the [`fuse`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`fuse`]: trait.Iterator.html#method.fuse
/// [`Iterator`]: trait.Iterator.html
#[derive(Clone, Debug)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Fuse<I> {
    // NOTE: for `I: FusedIterator`, this is always assumed `Some`!
    iter: Option<I>,
}
impl<I> Fuse<I> {
    pub(in crate::iter) fn new(iter: I) -> Fuse<I> {
        Fuse { iter: Some(iter) }
    }
}

#[stable(feature = "fused", since = "1.26.0")]
impl<I> FusedIterator for Fuse<I> where I: Iterator {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I> Iterator for Fuse<I>
where
    I: Iterator,
{
    type Item = <I as Iterator>::Item;

    #[inline]
    default fn next(&mut self) -> Option<<I as Iterator>::Item> {
        let next = self.iter.as_mut()?.next();
        if next.is_none() {
            self.iter = None;
        }
        next
    }

    #[inline]
    default fn nth(&mut self, n: usize) -> Option<I::Item> {
        let nth = self.iter.as_mut()?.nth(n);
        if nth.is_none() {
            self.iter = None;
        }
        nth
    }

    #[inline]
    default fn last(self) -> Option<I::Item> {
        self.iter?.last()
    }

    #[inline]
    default fn count(self) -> usize {
        self.iter.map_or(0, I::count)
    }

    #[inline]
    default fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.as_ref().map_or((0, Some(0)), I::size_hint)
    }

    #[inline]
    default fn try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        if let Some(ref mut iter) = self.iter {
            acc = iter.try_fold(acc, fold)?;
            self.iter = None;
        }
        Try::from_ok(acc)
    }

    #[inline]
    default fn fold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        if let Some(iter) = self.iter {
            acc = iter.fold(acc, fold);
        }
        acc
    }

    #[inline]
    default fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
    where
        P: FnMut(&Self::Item) -> bool,
    {
        let found = self.iter.as_mut()?.find(predicate);
        if found.is_none() {
            self.iter = None;
        }
        found
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I> DoubleEndedIterator for Fuse<I>
where
    I: DoubleEndedIterator,
{
    #[inline]
    default fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
        let next = self.iter.as_mut()?.next_back();
        if next.is_none() {
            self.iter = None;
        }
        next
    }

    #[inline]
    default fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
        let nth = self.iter.as_mut()?.nth_back(n);
        if nth.is_none() {
            self.iter = None;
        }
        nth
    }

    #[inline]
    default fn try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        if let Some(ref mut iter) = self.iter {
            acc = iter.try_rfold(acc, fold)?;
            self.iter = None;
        }
        Try::from_ok(acc)
    }

    #[inline]
    default fn rfold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        if let Some(iter) = self.iter {
            acc = iter.rfold(acc, fold);
        }
        acc
    }

    #[inline]
    default fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
    where
        P: FnMut(&Self::Item) -> bool,
    {
        let found = self.iter.as_mut()?.rfind(predicate);
        if found.is_none() {
            self.iter = None;
        }
        found
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I> ExactSizeIterator for Fuse<I>
where
    I: ExactSizeIterator,
{
    default fn len(&self) -> usize {
        self.iter.as_ref().map_or(0, I::len)
    }

    default fn is_empty(&self) -> bool {
        self.iter.as_ref().map_or(true, I::is_empty)
    }
}

// NOTE: for `I: FusedIterator`, we assume that the iterator is always `Some`
impl<I: FusedIterator> Fuse<I> {
    #[inline(always)]
    fn as_inner(&self) -> &I {
        match self.iter {
            Some(ref iter) => iter,
            // SAFETY: the specialized iterator never sets `None`
            None => unsafe { intrinsics::unreachable() },
        }
    }

    #[inline(always)]
    fn as_inner_mut(&mut self) -> &mut I {
        match self.iter {
            Some(ref mut iter) => iter,
            // SAFETY: the specialized iterator never sets `None`
            None => unsafe { intrinsics::unreachable() },
        }
    }

    #[inline(always)]
    fn into_inner(self) -> I {
        match self.iter {
            Some(iter) => iter,
            // SAFETY: the specialized iterator never sets `None`
            None => unsafe { intrinsics::unreachable() },
        }
    }
}

#[stable(feature = "fused", since = "1.26.0")]
impl<I> Iterator for Fuse<I>
where
    I: FusedIterator,
{
    #[inline]
    fn next(&mut self) -> Option<<I as Iterator>::Item> {
        self.as_inner_mut().next()
    }

    #[inline]
    fn nth(&mut self, n: usize) -> Option<I::Item> {
        self.as_inner_mut().nth(n)
    }

    #[inline]
    fn last(self) -> Option<I::Item> {
        self.into_inner().last()
    }

    #[inline]
    fn count(self) -> usize {
        self.into_inner().count()
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.as_inner().size_hint()
    }

    #[inline]
    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        self.as_inner_mut().try_fold(init, fold)
    }

    #[inline]
    fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        self.into_inner().fold(init, fold)
    }

    #[inline]
    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
    where
        P: FnMut(&Self::Item) -> bool,
    {
        self.as_inner_mut().find(predicate)
    }
}

#[stable(feature = "fused", since = "1.26.0")]
impl<I> DoubleEndedIterator for Fuse<I>
where
    I: DoubleEndedIterator + FusedIterator,
{
    #[inline]
    fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
        self.as_inner_mut().next_back()
    }

    #[inline]
    fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
        self.as_inner_mut().nth_back(n)
    }

    #[inline]
    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        self.as_inner_mut().try_rfold(init, fold)
    }

    #[inline]
    fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        self.into_inner().rfold(init, fold)
    }

    #[inline]
    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
    where
        P: FnMut(&Self::Item) -> bool,
    {
        self.as_inner_mut().rfind(predicate)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I> ExactSizeIterator for Fuse<I>
where
    I: ExactSizeIterator + FusedIterator,
{
    fn len(&self) -> usize {
        self.as_inner().len()
    }

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

unsafe impl<I> TrustedRandomAccess for Fuse<I>
where
    I: TrustedRandomAccess,
{
    unsafe fn get_unchecked(&mut self, i: usize) -> I::Item {
        match self.iter {
            Some(ref mut iter) => iter.get_unchecked(i),
            // SAFETY: the caller asserts there is an item at `i`, so we're not exhausted.
            None => intrinsics::unreachable(),
        }
    }

    fn may_have_side_effect() -> bool {
        I::may_have_side_effect()
    }
}
<commit_msg>Open-code Fuse's Option matches<commit_after>use crate::intrinsics;
use crate::iter::{
    DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator, TrustedRandomAccess,
};
use crate::ops::Try;

/// An iterator that yields `None` forever after the underlying iterator
/// yields `None` once.
///
/// This `struct` is created by the [`fuse`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`fuse`]: trait.Iterator.html#method.fuse
/// [`Iterator`]: trait.Iterator.html
#[derive(Clone, Debug)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Fuse<I> {
    // NOTE: for `I: FusedIterator`, this is always assumed `Some`!
    iter: Option<I>,
}
impl<I> Fuse<I> {
    pub(in crate::iter) fn new(iter: I) -> Fuse<I> {
        Fuse { iter: Some(iter) }
    }
}

#[stable(feature = "fused", since = "1.26.0")]
impl<I> FusedIterator for Fuse<I> where I: Iterator {}

/// Fuse the iterator if the expression is `None`.
macro_rules! fuse {
    ($self:ident . iter . $($call:tt)+) => {
        match $self.iter {
            Some(ref mut iter) => match iter.$($call)+ {
                None => {
                    $self.iter = None;
                    None
                }
                item => item,
            },
            None => None,
        }
    };
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I> Iterator for Fuse<I>
where
    I: Iterator,
{
    type Item = <I as Iterator>::Item;

    #[inline]
    default fn next(&mut self) -> Option<<I as Iterator>::Item> {
        fuse!(self.iter.next())
    }

    #[inline]
    default fn nth(&mut self, n: usize) -> Option<I::Item> {
        fuse!(self.iter.nth(n))
    }

    #[inline]
    default fn last(self) -> Option<I::Item> {
        match self.iter {
            Some(iter) => iter.last(),
            None => None,
        }
    }

    #[inline]
    default fn count(self) -> usize {
        match self.iter {
            Some(iter) => iter.count(),
            None => 0,
        }
    }

    #[inline]
    default fn size_hint(&self) -> (usize, Option<usize>) {
        match self.iter {
            Some(ref iter) => iter.size_hint(),
            None => (0, Some(0)),
        }
    }

    #[inline]
    default fn try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        if let Some(ref mut iter) = self.iter {
            acc = iter.try_fold(acc, fold)?;
            self.iter = None;
        }
        Try::from_ok(acc)
    }

    #[inline]
    default fn fold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        if let Some(iter) = self.iter {
            acc = iter.fold(acc, fold);
        }
        acc
    }

    #[inline]
    default fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
    where
        P: FnMut(&Self::Item) -> bool,
    {
        fuse!(self.iter.find(predicate))
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I> DoubleEndedIterator for Fuse<I>
where
    I: DoubleEndedIterator,
{
    #[inline]
    default fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
        fuse!(self.iter.next_back())
    }

    #[inline]
    default fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
        fuse!(self.iter.nth_back(n))
    }

    #[inline]
    default fn try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        if let Some(ref mut iter) = self.iter {
            acc = iter.try_rfold(acc, fold)?;
            self.iter = None;
        }
        Try::from_ok(acc)
    }

    #[inline]
    default fn rfold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        if let Some(iter) = self.iter {
            acc = iter.rfold(acc, fold);
        }
        acc
    }

    #[inline]
    default fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
    where
        P: FnMut(&Self::Item) -> bool,
    {
        fuse!(self.iter.rfind(predicate))
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I> ExactSizeIterator for Fuse<I>
where
    I: ExactSizeIterator,
{
    default fn len(&self) -> usize {
        match self.iter {
            Some(ref iter) => iter.len(),
            None => 0,
        }
    }

    default fn is_empty(&self) -> bool {
        match self.iter {
            Some(ref iter) => iter.is_empty(),
            None => true,
        }
    }
}

// NOTE: for `I: FusedIterator`, we assume that the iterator is always `Some`
impl<I: FusedIterator> Fuse<I> {
    #[inline(always)]
    fn as_inner(&self) -> &I {
        match self.iter {
            Some(ref iter) => iter,
            // SAFETY: the specialized iterator never sets `None`
            None => unsafe { intrinsics::unreachable() },
        }
    }

    #[inline(always)]
    fn as_inner_mut(&mut self) -> &mut I {
        match self.iter {
            Some(ref mut iter) => iter,
            // SAFETY: the specialized iterator never sets `None`
            None => unsafe { intrinsics::unreachable() },
        }
    }

    #[inline(always)]
    fn into_inner(self) -> I {
        match self.iter {
            Some(iter) => iter,
            // SAFETY: the specialized iterator never sets `None`
            None => unsafe { intrinsics::unreachable() },
        }
    }
}

#[stable(feature = "fused", since = "1.26.0")]
impl<I> Iterator for Fuse<I>
where
    I: FusedIterator,
{
    #[inline]
    fn next(&mut self) -> Option<<I as Iterator>::Item> {
        self.as_inner_mut().next()
    }

    #[inline]
    fn nth(&mut self, n: usize) -> Option<I::Item> {
        self.as_inner_mut().nth(n)
    }

    #[inline]
    fn last(self) -> Option<I::Item> {
        self.into_inner().last()
    }

    #[inline]
    fn count(self) -> usize {
        self.into_inner().count()
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.as_inner().size_hint()
    }

    #[inline]
    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        self.as_inner_mut().try_fold(init, fold)
    }

    #[inline]
    fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        self.into_inner().fold(init, fold)
    }

    #[inline]
    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
    where
        P: FnMut(&Self::Item) -> bool,
    {
        self.as_inner_mut().find(predicate)
    }
}

#[stable(feature = "fused", since = "1.26.0")]
impl<I> DoubleEndedIterator for Fuse<I>
where
    I: DoubleEndedIterator + FusedIterator,
{
    #[inline]
    fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
        self.as_inner_mut().next_back()
    }

    #[inline]
    fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
        self.as_inner_mut().nth_back(n)
    }

    #[inline]
    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        self.as_inner_mut().try_rfold(init, fold)
    }

    #[inline]
    fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        self.into_inner().rfold(init, fold)
    }

    #[inline]
    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
    where
        P: FnMut(&Self::Item) -> bool,
    {
        self.as_inner_mut().rfind(predicate)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I> ExactSizeIterator for Fuse<I>
where
    I: ExactSizeIterator + FusedIterator,
{
    fn len(&self) -> usize {
        self.as_inner().len()
    }

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

unsafe impl<I> TrustedRandomAccess for Fuse<I>
where
    I: TrustedRandomAccess,
{
    unsafe fn get_unchecked(&mut self, i: usize) -> I::Item {
        match self.iter {
            Some(ref mut iter) => iter.get_unchecked(i),
            // SAFETY: the caller asserts there is an item at `i`, so we're not exhausted.
            None => intrinsics::unreachable(),
        }
    }

    fn may_have_side_effect() -> bool {
        I::may_have_side_effect()
    }
}
<|endoftext|>


<commit_before>/// Owner information for the object
#[derive(Deserialize, Debug)]
pub struct Owner {
    #[serde(rename = "DisplayName")]
    /// Object owner's name.
    pub display_name: String,
    #[serde(rename = "ID")]
    /// Object owner's ID.
    pub id: String,
}

/// An individual object in a ListBucketResult
#[derive(Deserialize, Debug)]
pub struct Object {
    #[serde(rename = "LastModified")]
    /// Date and time the object was last modified.
    pub last_modified: String,
    #[serde(rename = "ETag")]
    /// The entity tag is an MD5 hash of the object. The ETag only reflects changes to the
    /// contents of an object, not its metadata.
    pub e_tag: String,
    #[serde(rename = "StorageClass")]
    /// STANDARD | STANDARD_IA | REDUCED_REDUNDANCY | GLACIER
    pub storage_class: String,
    #[serde(rename = "Key")]
    /// The object's key
    pub key: String,
    #[serde(rename = "Owner")]
    /// Bucket owner
    pub owner: Option<Owner>,
    #[serde(rename = "Size")]
    /// Size in bytes of the object.
    pub size: i32,
}

/// The parsed result of a s3 bucket listing
#[derive(Deserialize, Debug)]
pub struct ListBucketResult {
    #[serde(rename = "Name")]
    /// Name of the bucket.
    pub name: String,
    #[serde(rename = "NextMarker")]
    /// When the response is truncated (that is, the IsTruncated element value in the response
    /// is true), you can use the key name in this field as a marker in the subsequent request
    /// to get next set of objects. Amazon S3 lists objects in UTF-8 character encoding in
    /// lexicographical order.
    pub next_marker: Option<String>,
    #[serde(rename = "Delimiter")]
    /// A delimiter is a character you use to group keys.
    pub delimiter: Option<String>,
    #[serde(rename = "MaxKeys")]
    /// Sets the maximum number of keys returned in the response body.
    pub max_keys: i32,
    #[serde(rename = "Prefix")]
    /// Limits the response to keys that begin with the specified prefix.
    pub prefix: String,
    #[serde(rename = "Marker")]
    /// Indicates where in the bucket listing begins. Marker is included in the response if
    /// it was sent with the request.
    pub marker: Option<String>,
    #[serde(rename = "EncodingType")]
    /// Specifies the encoding method to used
    pub encoding_type: Option<String>,
    #[serde(rename = "IsTruncated")]
    ///  Specifies whether (true) or not (false) all of the results were returned.
    ///  If the number of results exceeds that specified by MaxKeys, all of the results
    ///  might not be returned.
    pub is_truncated: bool,
    #[serde(rename = "Contents")]
    /// Metadata about each object returned.
    pub contents: Vec<Object>,
    #[serde(rename = "CommonPrefixs")]
    /// All of the keys rolled up into a common prefix count as a single return when
    /// calculating the number of returns.
    pub common_prefixes: Option<Vec<CommonPrefix>>,
}

/// CommonPrefix is used to group keys
#[derive(Deserialize, Debug)]
pub struct CommonPrefix {
    #[serde(rename = "Prefix")]
    /// Keys that begin with the indicated prefix.
    pub prefix: String,
}
<commit_msg>Change type of size for larger files<commit_after>/// Owner information for the object
#[derive(Deserialize, Debug)]
pub struct Owner {
    #[serde(rename = "DisplayName")]
    /// Object owner's name.
    pub display_name: String,
    #[serde(rename = "ID")]
    /// Object owner's ID.
    pub id: String,
}

/// An individual object in a ListBucketResult
#[derive(Deserialize, Debug)]
pub struct Object {
    #[serde(rename = "LastModified")]
    /// Date and time the object was last modified.
    pub last_modified: String,
    #[serde(rename = "ETag")]
    /// The entity tag is an MD5 hash of the object. The ETag only reflects changes to the
    /// contents of an object, not its metadata.
    pub e_tag: String,
    #[serde(rename = "StorageClass")]
    /// STANDARD | STANDARD_IA | REDUCED_REDUNDANCY | GLACIER
    pub storage_class: String,
    #[serde(rename = "Key")]
    /// The object's key
    pub key: String,
    #[serde(rename = "Owner")]
    /// Bucket owner
    pub owner: Option<Owner>,
    #[serde(rename = "Size")]
    /// Size in bytes of the object.
    pub size: u64,
}

/// The parsed result of a s3 bucket listing
#[derive(Deserialize, Debug)]
pub struct ListBucketResult {
    #[serde(rename = "Name")]
    /// Name of the bucket.
    pub name: String,
    #[serde(rename = "NextMarker")]
    /// When the response is truncated (that is, the IsTruncated element value in the response
    /// is true), you can use the key name in this field as a marker in the subsequent request
    /// to get next set of objects. Amazon S3 lists objects in UTF-8 character encoding in
    /// lexicographical order.
    pub next_marker: Option<String>,
    #[serde(rename = "Delimiter")]
    /// A delimiter is a character you use to group keys.
    pub delimiter: Option<String>,
    #[serde(rename = "MaxKeys")]
    /// Sets the maximum number of keys returned in the response body.
    pub max_keys: i32,
    #[serde(rename = "Prefix")]
    /// Limits the response to keys that begin with the specified prefix.
    pub prefix: String,
    #[serde(rename = "Marker")]
    /// Indicates where in the bucket listing begins. Marker is included in the response if
    /// it was sent with the request.
    pub marker: Option<String>,
    #[serde(rename = "EncodingType")]
    /// Specifies the encoding method to used
    pub encoding_type: Option<String>,
    #[serde(rename = "IsTruncated")]
    ///  Specifies whether (true) or not (false) all of the results were returned.
    ///  If the number of results exceeds that specified by MaxKeys, all of the results
    ///  might not be returned.
    pub is_truncated: bool,
    #[serde(rename = "Contents")]
    /// Metadata about each object returned.
    pub contents: Vec<Object>,
    #[serde(rename = "CommonPrefixs")]
    /// All of the keys rolled up into a common prefix count as a single return when
    /// calculating the number of returns.
    pub common_prefixes: Option<Vec<CommonPrefix>>,
}

/// CommonPrefix is used to group keys
#[derive(Deserialize, Debug)]
pub struct CommonPrefix {
    #[serde(rename = "Prefix")]
    /// Keys that begin with the indicated prefix.
    pub prefix: String,
}
<|endoftext|>


<commit_before>//! Contains all packets that can be sent by an ozelot client
//!
//! See the Serverbound sections on http://wiki.vg/Protocol for information
//! about each of the packets.

use read::*;
use write::*;
use connection::Packet;
use {ClientState, u128, yggdrasil};

use std::fmt;
use std::io::Read;
use std::io;

use openssl::rsa::Rsa;

/* See packets.clj for information about this include */
include!("./.serverbound-enum.generated.rs");
include!("./.serverbound-packets.generated.rs");

/* Now come to the manual definitions of packets that don't fit into the
 * code generation */

impl Handshake {
    /// Get the next state as a ClientState, if the value is valid
    pub fn get_next_clientstate(&self) -> Option<ClientState> {
        match self.next_state {
            1 => Some(ClientState::Status),
            2 => Some(ClientState::Login),
            _ => None,
        }
    }
}

impl EncryptionResponse {
    pub fn get_decrypted_shared_secret(&self,
                                       key: &Rsa)
                                       -> io::Result<Vec<u8>> {
        yggdrasil::rsa_decrypt(key, &self.shared_secret)
    }
    pub fn get_decrypted_verify_token(&self, key: &Rsa) -> io::Result<Vec<u8>> {
        yggdrasil::rsa_decrypt(key, &self.verify_token)
    }
}

impl StatusRequest {
    fn to_u8(&self) -> io::Result<Vec<u8>> {
        let mut ret = Vec::new();
        write_varint(&StatusRequest::get_packet_id(), &mut ret)?;
        Ok(ret)
    }
    fn deserialize<R: Read>(_: &mut R) -> io::Result<ServerboundPacket> {
        Ok(ServerboundPacket::StatusRequest(StatusRequest {}))
    }
}

impl TabComplete {
    fn to_u8(&self) -> io::Result<Vec<u8>> {
        let mut ret = Vec::new();
        write_varint(&TabComplete::get_packet_id(), &mut ret)?;
        write_String(&self.text, &mut ret)?;
        write_bool(&self.assume_command, &mut ret)?;
        match self.looked_at_block {
            Some(x) => {
                write_bool(&true, &mut ret)?;
                write_position(&x, &mut ret)?;
            },
            None => {
                write_bool(&false, &mut ret)?;
            },
        }
        Ok(ret)
    }
    fn deserialize<R: Read>(r: &mut R) -> io::Result<ServerboundPacket> {
        let text = read_String(r)?;
        let assume_command = read_bool(r)?;
        let has_position = read_bool(r)?;
        let looked_at_block = if has_position {
            Some(read_position(r)?)
        } else {
            None
        };

        Ok(ServerboundPacket::TabComplete(TabComplete {
                                              text: text,
                                              assume_command: assume_command,
                                              looked_at_block: looked_at_block,
                                          }))
    }
}

impl UseEntity {
    fn to_u8(&self) -> io::Result<Vec<u8>> {
        let mut ret = Vec::new();
        write_varint(&UseEntity::get_packet_id(), &mut ret)?;
        write_varint(&self.target, &mut ret)?;
        write_varint(&self.action, &mut ret)?;
        match self.action {
            2 => {
                if let Some((x, y, z)) = self.location {
                    write_f32(&x, &mut ret)?;
                    write_f32(&y, &mut ret)?;
                    write_f32(&z, &mut ret)?;
                } else {
                    return io_error!("UseEntity had invalid values. Location was None even though action was 2.");
                }
            },
            _ => (),
        }

        match self.action {
            0 | 1 => {
                if let Some(x) = self.hand {
                    write_varint(&x, &mut ret)?;
                } else {
                    return io_error!("UseEntity had invalid values. Hand was none even though action was {}",
                                     self.action);
                }
            },
            _ => (),
        }
        Ok(ret)
    }
    fn deserialize<R: Read>(r: &mut R) -> io::Result<ServerboundPacket> {
        let target = read_varint(r)?;
        let action = read_varint(r)?;

        let location = if action == 2 {
            Some((read_f32(r)?, read_f32(r)?, read_f32(r)?))
        } else {
            None
        };

        let hand = if action == 0 || action == 1 {
            Some(read_varint(r)?)
        } else {
            None
        };
        Ok(ServerboundPacket::UseEntity(UseEntity {
                                            target: target,
                                            action: action,
                                            location: location,
                                            hand: hand,
                                        }))
    }
}

impl EncryptionResponse {
    /// Create the EncryptionResponse packet from the unencrypted shared secret
    /// and verify token, and the server's public key in DER format.
    pub fn new_unencrypted(key: &[u8],
                           shared_secret: &[u8],
                           verify_token: &[u8])
                           -> io::Result<ServerboundPacket> {
        let ss_encrypted = yggdrasil::rsa_encrypt(key, shared_secret)?;
        let verify_encrypted = yggdrasil::rsa_encrypt(key, verify_token)?;

        Ok(EncryptionResponse::new(ss_encrypted, verify_encrypted))
    }
}
<commit_msg>documentation: Minor rewording<commit_after>//! Contains all serverbound packets
//!
//! See the Serverbound sections on http://wiki.vg/Protocol for information
//! about each of the packets.

use read::*;
use write::*;
use connection::Packet;
use {ClientState, u128, yggdrasil};

use std::fmt;
use std::io::Read;
use std::io;

use openssl::rsa::Rsa;

/* See packets.clj for information about this include */
include!("./.serverbound-enum.generated.rs");
include!("./.serverbound-packets.generated.rs");

/* Now come to the manual definitions of packets that don't fit into the
 * code generation */

impl Handshake {
    /// Get the next state as a ClientState, if the value is valid
    pub fn get_next_clientstate(&self) -> Option<ClientState> {
        match self.next_state {
            1 => Some(ClientState::Status),
            2 => Some(ClientState::Login),
            _ => None,
        }
    }
}

impl EncryptionResponse {
    pub fn get_decrypted_shared_secret(&self,
                                       key: &Rsa)
                                       -> io::Result<Vec<u8>> {
        yggdrasil::rsa_decrypt(key, &self.shared_secret)
    }
    pub fn get_decrypted_verify_token(&self, key: &Rsa) -> io::Result<Vec<u8>> {
        yggdrasil::rsa_decrypt(key, &self.verify_token)
    }
}

impl StatusRequest {
    fn to_u8(&self) -> io::Result<Vec<u8>> {
        let mut ret = Vec::new();
        write_varint(&StatusRequest::get_packet_id(), &mut ret)?;
        Ok(ret)
    }
    fn deserialize<R: Read>(_: &mut R) -> io::Result<ServerboundPacket> {
        Ok(ServerboundPacket::StatusRequest(StatusRequest {}))
    }
}

impl TabComplete {
    fn to_u8(&self) -> io::Result<Vec<u8>> {
        let mut ret = Vec::new();
        write_varint(&TabComplete::get_packet_id(), &mut ret)?;
        write_String(&self.text, &mut ret)?;
        write_bool(&self.assume_command, &mut ret)?;
        match self.looked_at_block {
            Some(x) => {
                write_bool(&true, &mut ret)?;
                write_position(&x, &mut ret)?;
            },
            None => {
                write_bool(&false, &mut ret)?;
            },
        }
        Ok(ret)
    }
    fn deserialize<R: Read>(r: &mut R) -> io::Result<ServerboundPacket> {
        let text = read_String(r)?;
        let assume_command = read_bool(r)?;
        let has_position = read_bool(r)?;
        let looked_at_block = if has_position {
            Some(read_position(r)?)
        } else {
            None
        };

        Ok(ServerboundPacket::TabComplete(TabComplete {
                                              text: text,
                                              assume_command: assume_command,
                                              looked_at_block: looked_at_block,
                                          }))
    }
}

impl UseEntity {
    fn to_u8(&self) -> io::Result<Vec<u8>> {
        let mut ret = Vec::new();
        write_varint(&UseEntity::get_packet_id(), &mut ret)?;
        write_varint(&self.target, &mut ret)?;
        write_varint(&self.action, &mut ret)?;
        match self.action {
            2 => {
                if let Some((x, y, z)) = self.location {
                    write_f32(&x, &mut ret)?;
                    write_f32(&y, &mut ret)?;
                    write_f32(&z, &mut ret)?;
                } else {
                    return io_error!("UseEntity had invalid values. Location was None even though action was 2.");
                }
            },
            _ => (),
        }

        match self.action {
            0 | 1 => {
                if let Some(x) = self.hand {
                    write_varint(&x, &mut ret)?;
                } else {
                    return io_error!("UseEntity had invalid values. Hand was none even though action was {}",
                                     self.action);
                }
            },
            _ => (),
        }
        Ok(ret)
    }
    fn deserialize<R: Read>(r: &mut R) -> io::Result<ServerboundPacket> {
        let target = read_varint(r)?;
        let action = read_varint(r)?;

        let location = if action == 2 {
            Some((read_f32(r)?, read_f32(r)?, read_f32(r)?))
        } else {
            None
        };

        let hand = if action == 0 || action == 1 {
            Some(read_varint(r)?)
        } else {
            None
        };
        Ok(ServerboundPacket::UseEntity(UseEntity {
                                            target: target,
                                            action: action,
                                            location: location,
                                            hand: hand,
                                        }))
    }
}

impl EncryptionResponse {
    /// Create the EncryptionResponse packet from the unencrypted shared secret
    /// and verify token, and the server's public key in DER format.
    pub fn new_unencrypted(key: &[u8],
                           shared_secret: &[u8],
                           verify_token: &[u8])
                           -> io::Result<ServerboundPacket> {
        let ss_encrypted = yggdrasil::rsa_encrypt(key, shared_secret)?;
        let verify_encrypted = yggdrasil::rsa_encrypt(key, verify_token)?;

        Ok(EncryptionResponse::new(ss_encrypted, verify_encrypted))
    }
}
<|endoftext|>


<commit_before><commit_msg>Reformat storage module.<commit_after>
<|endoftext|>


<commit_before>/// Strongly borrowed from TypedArena
/// Differs in growth strategy (non-doubling)
/// And only for variable-sized strings

use std::cell::{Cell,RefCell};
use std::cmp::max;
use std::collections::DList;
use std::collections::hash_map::{HashMap,Occupied,Vacant};
use std::fmt;
use std::hash;
use std::mem;
use std::ptr;
use std::raw::Slice;
use std::rt::heap::{allocate, deallocate};
use std::str;
use xxhash::{XXHasher};

struct Chunk {
    start: *mut u8,
    capacity: uint,
}

impl Chunk {
    fn new(capacity: uint) -> Chunk {
        Chunk {
            start: unsafe { allocate(capacity, mem::min_align_of::<u8>()) },
            capacity: capacity,
        }
    }

    // Returns a pointer to the beginning of the allocated space.
    #[inline]
    fn start(&self) -> *const u8 {
        self.start as *const u8
    }

    // Returns a pointer to the end of the allocated space.
    #[inline]
    fn end(&self) -> *const u8 {
        unsafe { self.start().offset(self.capacity as int) }
    }
}

impl Drop for Chunk {
    fn drop(&mut self) {
        unsafe {
            deallocate(self.start, self.capacity, mem::min_align_of::<u8>());
        }
    }
}

pub struct InternedString {
    slice: Slice<u8>,
}

impl InternedString {
    fn from_parts(data: *const u8, len: uint) -> InternedString {
        InternedString {
            slice: Slice {
                data: data,
                len: len,
            },
        }
    }

    pub fn from_str(s: &str) -> InternedString {
        let bytes: &[u8] = s.as_bytes();
        let slice: Slice<u8> = unsafe { mem::transmute(bytes) };
        InternedString {
            slice: slice,
        }
    }

    pub fn as_slice<'s>(&self) -> &'s str {
        unsafe {
            let bytes: &[u8] = mem::transmute(self.slice);
            str::raw::from_utf8(bytes)
        }
    }
}

impl fmt::Show for InternedString {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.as_slice().fmt(f)
    }
}

impl PartialEq for InternedString {
    fn eq(&self, other: &InternedString) -> bool {
        self.as_slice().eq(other.as_slice())
    }
}

impl Eq for InternedString {}

impl<S: hash::Writer> hash::Hash<S> for InternedString {
    fn hash(&self, state: &mut S) {
        self.as_slice().hash(state)
    }
}

pub struct StringPool {
    start: Cell<*mut u8>,
    end: Cell<*const u8>,
    chunks: RefCell<DList<Chunk>>,
    index: RefCell<HashMap<InternedString, InternedString, XXHasher>>,
}

static CAPACITY: uint = 10240;

impl StringPool {
    pub fn new() -> StringPool {
        StringPool{
            start: Cell::new(ptr::null_mut()),
            end: Cell::new(ptr::null()),
            chunks: RefCell::new(DList::new()),
            index: RefCell::new(HashMap::with_hasher(XXHasher::new())),
        }
    }

    pub fn intern<'s>(&'s self, s: &str) -> &'s str {
        if s == "" { return ""; }

        let search_string = InternedString::from_str(s);

        let interned_str = match self.index.borrow_mut().entry(search_string) {
            Occupied(entry) => *entry.get(),
            Vacant(entry) => *entry.set(self.do_intern(s)),
        };

        // The lifetime is really matched to us
        unsafe { mem::transmute(interned_str.as_slice()) }
    }

    fn do_intern(&self, s: &str) -> InternedString {
        self.ensure_capacity(s.len());
        self.store(s)
    }

    fn ensure_capacity(&self, str_len: uint) {
        let remaining = self.end.get() as uint - self.start.get() as uint;
        if remaining < str_len {
            self.allocate_another(max(CAPACITY, str_len))
        }
    }

    fn allocate_another(&self, capacity: uint) {
        let chunk = Chunk::new(capacity);
        self.start.set(chunk.start() as *mut u8);
        self.end.set(chunk.end());
        self.chunks.borrow_mut().push_front(chunk);
    }

    fn store(&self, s: &str) -> InternedString {
        let str_start = s.as_bytes().as_ptr();
        let str_len = s.len();

        unsafe {
            ptr::copy_nonoverlapping_memory(self.start.get(), str_start, str_len);

            // Rebuild the string from our buffer
            let interned_str = InternedString::from_parts(self.start.get() as *const u8, str_len);

            // Increase current pointer
            self.start.set(self.start.get().offset(str_len as int));

            interned_str
        }
    }
}

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

    #[test]
    fn keeps_the_same_string() {
        let s = StringPool::new();

        let interned = s.intern("hello");

        assert_eq!(interned, "hello");
    }

    #[test]
    fn does_not_reuse_the_pointer_of_the_input() {
        let s = StringPool::new();
        let input = "hello";

        let interned = s.intern(input);

        assert!(
            input.as_bytes().as_ptr() !=
            interned.as_bytes().as_ptr()
        );
    }

    #[test]
    fn reuses_the_pointer_for_repeated_input() {
        let s = StringPool::new();

        let interned1 = s.intern("world");
        let interned2 = s.intern("world");

        assert_eq!(
            interned1.as_bytes().as_ptr(),
            interned2.as_bytes().as_ptr()
        );
    }

    // #[test]
    // #[compile_failure]
    // fn string_cannot_outlive_the_pool() {
    //     let z = {
    //         let s = StringPool::new();
    //         s.intern("hello")
    //     };
    // }

    #[test]
    fn ignores_the_lifetime_of_the_input_string() {
        let s = StringPool::new();

        let interned = {
            let allocated_string = String::from_str("green");
            s.intern(allocated_string.as_slice())
        };

        // allocated_string is gone now, but we should be able to
        // access the result value until the storage goes away.

        assert_eq!(interned, "green");
    }

    #[test]
    fn can_be_dropped_immediately() {
        StringPool::new();
    }

    fn return_populated_storage() -> (StringPool, *const u8) {
        let s = StringPool::new();
        let ptr = {
            let interned = s.intern("hello");
            interned.as_ptr()
        };
        (s, ptr)
    }

    #[test]
    fn can_return_storage_populated_with_values() {
        let (s, ptr_val) = return_populated_storage();
        let interned = s.intern("hello");
        assert_eq!(interned.as_ptr(), ptr_val);
    }
}

#[cfg(test)]
mod bench {
    use test::Bencher;

    use super::StringPool;

    #[bench]
    fn single_string(b: &mut Bencher) {
        let s = StringPool::new();
        b.iter(|| s.intern("hello"));
        b.bytes = "hello".len() as u64;
    }

    #[bench]
    fn many_unique_string(b: &mut Bencher) {
        let s = StringPool::new();

        let strings: Vec<String> =
            range(0u, 1000)
            .map(|i| format!("str{}str", i))
            .collect();
        b.iter(|| {
            for ss in strings.iter() {
                s.intern(ss.as_slice());
            }
        });
        b.bytes = strings.iter().fold(0, |a, s| a + s.len()) as u64;
    }

    #[bench]
    fn many_repeated_string(b: &mut Bencher) {
        let s = StringPool::new();

        let strings: Vec<String> =
            range(0u, 1000)
            .map(|i| format!("str{}str", i % 100))
            .collect();
        b.iter(|| {
            for ss in strings.iter() {
                s.intern(ss.as_slice());
            }
        });
        b.bytes = strings.iter().fold(0, |a, s| a + s.len()) as u64;
    }
}
<commit_msg>Update deprecated str::raw::from_utf8<commit_after>/// Strongly borrowed from TypedArena
/// Differs in growth strategy (non-doubling)
/// And only for variable-sized strings

use std::cell::{Cell,RefCell};
use std::cmp::max;
use std::collections::DList;
use std::collections::hash_map::{HashMap,Occupied,Vacant};
use std::fmt;
use std::hash;
use std::mem;
use std::ptr;
use std::raw::Slice;
use std::rt::heap::{allocate, deallocate};
use std::str;
use xxhash::{XXHasher};

struct Chunk {
    start: *mut u8,
    capacity: uint,
}

impl Chunk {
    fn new(capacity: uint) -> Chunk {
        Chunk {
            start: unsafe { allocate(capacity, mem::min_align_of::<u8>()) },
            capacity: capacity,
        }
    }

    // Returns a pointer to the beginning of the allocated space.
    #[inline]
    fn start(&self) -> *const u8 {
        self.start as *const u8
    }

    // Returns a pointer to the end of the allocated space.
    #[inline]
    fn end(&self) -> *const u8 {
        unsafe { self.start().offset(self.capacity as int) }
    }
}

impl Drop for Chunk {
    fn drop(&mut self) {
        unsafe {
            deallocate(self.start, self.capacity, mem::min_align_of::<u8>());
        }
    }
}

pub struct InternedString {
    slice: Slice<u8>,
}

impl InternedString {
    fn from_parts(data: *const u8, len: uint) -> InternedString {
        InternedString {
            slice: Slice {
                data: data,
                len: len,
            },
        }
    }

    pub fn from_str(s: &str) -> InternedString {
        let bytes: &[u8] = s.as_bytes();
        let slice: Slice<u8> = unsafe { mem::transmute(bytes) };
        InternedString {
            slice: slice,
        }
    }

    pub fn as_slice<'s>(&self) -> &'s str {
        unsafe {
            let bytes: &[u8] = mem::transmute(self.slice);
            str::from_utf8_unchecked(bytes)
        }
    }
}

impl fmt::Show for InternedString {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.as_slice().fmt(f)
    }
}

impl PartialEq for InternedString {
    fn eq(&self, other: &InternedString) -> bool {
        self.as_slice().eq(other.as_slice())
    }
}

impl Eq for InternedString {}

impl<S: hash::Writer> hash::Hash<S> for InternedString {
    fn hash(&self, state: &mut S) {
        self.as_slice().hash(state)
    }
}

pub struct StringPool {
    start: Cell<*mut u8>,
    end: Cell<*const u8>,
    chunks: RefCell<DList<Chunk>>,
    index: RefCell<HashMap<InternedString, InternedString, XXHasher>>,
}

static CAPACITY: uint = 10240;

impl StringPool {
    pub fn new() -> StringPool {
        StringPool{
            start: Cell::new(ptr::null_mut()),
            end: Cell::new(ptr::null()),
            chunks: RefCell::new(DList::new()),
            index: RefCell::new(HashMap::with_hasher(XXHasher::new())),
        }
    }

    pub fn intern<'s>(&'s self, s: &str) -> &'s str {
        if s == "" { return ""; }

        let search_string = InternedString::from_str(s);

        let interned_str = match self.index.borrow_mut().entry(search_string) {
            Occupied(entry) => *entry.get(),
            Vacant(entry) => *entry.set(self.do_intern(s)),
        };

        // The lifetime is really matched to us
        unsafe { mem::transmute(interned_str.as_slice()) }
    }

    fn do_intern(&self, s: &str) -> InternedString {
        self.ensure_capacity(s.len());
        self.store(s)
    }

    fn ensure_capacity(&self, str_len: uint) {
        let remaining = self.end.get() as uint - self.start.get() as uint;
        if remaining < str_len {
            self.allocate_another(max(CAPACITY, str_len))
        }
    }

    fn allocate_another(&self, capacity: uint) {
        let chunk = Chunk::new(capacity);
        self.start.set(chunk.start() as *mut u8);
        self.end.set(chunk.end());
        self.chunks.borrow_mut().push_front(chunk);
    }

    fn store(&self, s: &str) -> InternedString {
        let str_start = s.as_bytes().as_ptr();
        let str_len = s.len();

        unsafe {
            ptr::copy_nonoverlapping_memory(self.start.get(), str_start, str_len);

            // Rebuild the string from our buffer
            let interned_str = InternedString::from_parts(self.start.get() as *const u8, str_len);

            // Increase current pointer
            self.start.set(self.start.get().offset(str_len as int));

            interned_str
        }
    }
}

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

    #[test]
    fn keeps_the_same_string() {
        let s = StringPool::new();

        let interned = s.intern("hello");

        assert_eq!(interned, "hello");
    }

    #[test]
    fn does_not_reuse_the_pointer_of_the_input() {
        let s = StringPool::new();
        let input = "hello";

        let interned = s.intern(input);

        assert!(
            input.as_bytes().as_ptr() !=
            interned.as_bytes().as_ptr()
        );
    }

    #[test]
    fn reuses_the_pointer_for_repeated_input() {
        let s = StringPool::new();

        let interned1 = s.intern("world");
        let interned2 = s.intern("world");

        assert_eq!(
            interned1.as_bytes().as_ptr(),
            interned2.as_bytes().as_ptr()
        );
    }

    // #[test]
    // #[compile_failure]
    // fn string_cannot_outlive_the_pool() {
    //     let z = {
    //         let s = StringPool::new();
    //         s.intern("hello")
    //     };
    // }

    #[test]
    fn ignores_the_lifetime_of_the_input_string() {
        let s = StringPool::new();

        let interned = {
            let allocated_string = String::from_str("green");
            s.intern(allocated_string.as_slice())
        };

        // allocated_string is gone now, but we should be able to
        // access the result value until the storage goes away.

        assert_eq!(interned, "green");
    }

    #[test]
    fn can_be_dropped_immediately() {
        StringPool::new();
    }

    fn return_populated_storage() -> (StringPool, *const u8) {
        let s = StringPool::new();
        let ptr = {
            let interned = s.intern("hello");
            interned.as_ptr()
        };
        (s, ptr)
    }

    #[test]
    fn can_return_storage_populated_with_values() {
        let (s, ptr_val) = return_populated_storage();
        let interned = s.intern("hello");
        assert_eq!(interned.as_ptr(), ptr_val);
    }
}

#[cfg(test)]
mod bench {
    use test::Bencher;

    use super::StringPool;

    #[bench]
    fn single_string(b: &mut Bencher) {
        let s = StringPool::new();
        b.iter(|| s.intern("hello"));
        b.bytes = "hello".len() as u64;
    }

    #[bench]
    fn many_unique_string(b: &mut Bencher) {
        let s = StringPool::new();

        let strings: Vec<String> =
            range(0u, 1000)
            .map(|i| format!("str{}str", i))
            .collect();
        b.iter(|| {
            for ss in strings.iter() {
                s.intern(ss.as_slice());
            }
        });
        b.bytes = strings.iter().fold(0, |a, s| a + s.len()) as u64;
    }

    #[bench]
    fn many_repeated_string(b: &mut Bencher) {
        let s = StringPool::new();

        let strings: Vec<String> =
            range(0u, 1000)
            .map(|i| format!("str{}str", i % 100))
            .collect();
        b.iter(|| {
            for ss in strings.iter() {
                s.intern(ss.as_slice());
            }
        });
        b.bytes = strings.iter().fold(0, |a, s| a + s.len()) as u64;
    }
}
<|endoftext|>