<commit_before>#![crate_id = "ansi_term#0.1dev"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![desc = "A rust library for ANSI terminal colours and styles (bold, underline)"]

//! This is a library for controlling colours and formatting, such as
//! red bold text or blue underlined text, on ANSI terminals.
//!
//! Simple Colours
//! --------------
//!
//! You can format strings by calling the `paint` method on a Colour
//! or a Style object, passing in the string you want to format. For
//! example, to get some red text, call the `paint` method on `Red`:
//!
//! ```rust
//! Red.paint("Red!")
//! ```
//!
//! You can also call the `paint` method on a Style. To turn a Colour
//! into a Style, use the `normal` method, though this does the exact
//! some thing as above:
//!
//! ```rust
//! Red.normal().paint("Still red!")
//! ```
//!
//! Bold, Underline, and Background
//! -------------------------------
//!
//! To do anything more complex than just foreground colours, you need
//! to use Style objects. Calling the `bold` or `underline` method on
//! a Colour returns a Style that has the appropriate property set on
//! it:
//!
//! ```rust
//! Blue.bold().paint("Blue bold!")
//! Yellow.underline().paint("Yellow underline!")
//! ```
//!
//! Again, you can call these methods on Styles as well as just Colours:
//!
//! ```rust
//! Blue.normal().bold().paint("Still blue bold!")
//! ```
//!
//! Finally, you can set the background colour of a Style by using the
//! `on` method:
//!
//! ```rust
//! Blue.on(Yellow).paint("Blue on yellow!")
//! ```
//!
//! Extended Colours
//! ----------------
//!
//! You can access the extended range of 256 colours by using the
//! Fixed constructor, which takes an argument of the colour number to
//! use. This can be used wherever you would use a Colour:
//!
//! ```rust
//! Fixed(134).paint("A sort of light purple.")
//! ```
//!
//! This even works for background colours:
//!
//! ```rust
//! Fixed(221).on(Fixed(124)).paint("Mustard in the ketchup.")
//! ```
//!
//! No Formatting
//! -------------
//!
//! Finally, for the sake of completeness, the Plain style provides
//! neither colours nor formatting.
//!
//! ```rust
//! Plain.paint("No colours here.")
//! ```

#![feature(phase)] extern crate regex;
#[phase(plugin)] extern crate regex_macros;

/// A colour is one specific type of ANSI escape code, and can refer
/// to either the foreground or background colour.
pub enum Colour {
    Black, Red, Green, Yellow, Blue, Purple, Cyan, White, Fixed(u8),
}

// These are the standard numeric sequences.
// See http://invisible-island.net/xterm/ctlseqs/ctlseqs.html

impl Colour {
    fn foreground_code(&self) -> String {
        match *self {
            Black => "30".to_string(),
            Red => "31".to_string(),
            Green => "32".to_string(),
            Yellow => "33".to_string(),
            Blue => "34".to_string(),
            Purple => "35".to_string(),
            Cyan => "36".to_string(),
            White => "37".to_string(),
            Fixed(num) => format!("38;5;{}", num),
        }
    }

    fn background_code(&self) -> String {
        match *self {
            Black => "40".to_string(),
            Red => "41".to_string(),
            Green => "42".to_string(),
            Yellow => "43".to_string(),
            Blue => "44".to_string(),
            Purple => "45".to_string(),
            Cyan => "46".to_string(),
            White => "47".to_string(),
            Fixed(num) => format!("48;5;{}", num),
        }
    }
}

/// A style is a collection of properties that can format a string
/// using ANSI escape codes.
pub enum Style {
    /// The Plain style provides no formatting.
    Plain,
    /// The Foreground style provides just a foreground colour.
    Foreground(Colour),
    /// The Style style is a catch-all for anything more complicated
    /// than that. It's technically possible for there to be other
    /// cases, such as "bold foreground", but probably isn't worth it.
    Style(StyleStruct),
}

// Having a struct inside an enum is currently unfinished in Rust, but
// should be put in there when that feature is complete.

struct StyleStruct {
    foreground: Colour,
    background: Option<Colour>,
    bold: bool,
    underline: bool,
}

impl Style {
    /// Paints the given text with this style, returning a String of
    /// text with the relevant ANSI escape codes added.
    pub fn paint(&self, input: &str) -> String {
        match *self {
            Plain => input.to_string(),
            Foreground(c) => c.paint(input),
            Style(s) => match s {
                StyleStruct { foreground, background, bold, underline } => {
                    let bg = match background {
                        Some(c) => format!("{};", c.background_code()),
                        None => "".to_string()
                    };
                    let bo = if bold { "1;" } else { "" };
                    let un = if underline { "4;" } else { "" };
                    let painted = format!("\x1B[{}{}{}{}m{}\x1B[0m", bo, un, bg, foreground.foreground_code(), input.to_string());
                    return painted.to_string();
                }
            }
        }
    }

    /// Return a Style with the bold property set.
    pub fn bold(&self) -> Style {
        match *self {
            Plain => Style(StyleStruct         { foreground: White,         background: None,          bold: true, underline: false }),
            Foreground(c) => Style(StyleStruct { foreground: c,             background: None,          bold: true, underline: false }),
            Style(st) => Style(StyleStruct     { foreground: st.foreground, background: st.background, bold: true, underline: st.underline }),
        }
    }

    /// Return a Style with the underline property set.
    pub fn underline(&self) -> Style {
        match *self {
            Plain => Style(StyleStruct         { foreground: White,         background: None,          bold: false,   underline: true }),
            Foreground(c) => Style(StyleStruct { foreground: c,             background: None,          bold: false,   underline: true }),
            Style(st) => Style(StyleStruct     { foreground: st.foreground, background: st.background, bold: st.bold, underline: true }),
        }
    }

    /// Return a Style with the background colour set.
    pub fn on(&self, background: Colour) -> Style {
        match *self {
            Plain => Style(StyleStruct         { foreground: White,         background: Some(background), bold: false,   underline: false }),
            Foreground(c) => Style(StyleStruct { foreground: c,             background: Some(background), bold: false,   underline: false }),
            Style(st) => Style(StyleStruct     { foreground: st.foreground, background: Some(background), bold: st.bold, underline: st.underline }),
        }
    }
}

impl Colour {
    /// Paints the given text with this colour. This is a short-cut so
    /// you don't have to use Blue.normal() just to get blue text.
    pub fn paint(&self, input: &str) -> String {
        let re = format!("\x1B[{}m{}\x1B[0m", self.foreground_code(), input);
        return re.to_string();
    }

    /// Returns a Style with the underline property set.
    pub fn underline(&self) -> Style {
        Style(StyleStruct { foreground: *self, background: None, bold: false, underline: true })
    }

    /// Return a Style with the bold property set.
    pub fn bold(&self) -> Style {
        Style(StyleStruct { foreground: *self, background: None, bold: true, underline: false })
    }

    /// Return a Style with the foreground colour set to this colour.
    pub fn normal(&self) -> Style {
        Style(StyleStruct { foreground: *self, background: None, bold: false, underline: false })
    }

    /// Return a Style with the background colour set.
    pub fn on(&self, background: Colour) -> Style {
        Style(StyleStruct { foreground: *self, background: Some(background), bold: false, underline: false })
    }
}

/// Return a String with all ANSI escape codes removed. For example:
///
/// ```rust
/// strip_formatting(Blue.paint("hello!")) == "hello!"
/// ```
pub fn strip_formatting(input: String) -> String {
    // What's blue and smells like red paint? Blue paint.
    let re = regex!("\x1B\\[.+?m");
    re.replace_all(input.as_slice(), "").to_string()
}

#[cfg(test)]
mod tests {
    use super::{Black, Red, Green, Yellow, Blue, Purple, Cyan, White, Fixed, Plain, strip_formatting};

    #[test]
    fn test_plain() {
        let hi = Plain.paint("text/plain");
        assert!(hi == "text/plain".to_string());
    }

    #[test]
    fn test_red() {
        let hi = Red.paint("hi");
        assert!(hi == "\x1B[31mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_black() {
        let hi = Black.normal().paint("hi");
        assert!(hi == "\x1B[30mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_yellow_bold() {
        let hi = Yellow.bold().paint("hi");
        assert!(hi == "\x1B[1;33mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_yellow_bold_2() {
        let hi = Yellow.normal().bold().paint("hi");
        assert!(hi == "\x1B[1;33mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_blue_underline() {
        let hi = Blue.underline().paint("hi");
        assert!(hi == "\x1B[4;34mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_green_bold_underline() {
        let hi = Green.bold().underline().paint("hi");
        assert!(hi == "\x1B[1;4;32mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_green_bold_underline_2() {
        let hi = Green.underline().bold().paint("hi");
        assert!(hi == "\x1B[1;4;32mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_purple_on_white() {
        let hi = Purple.on(White).paint("hi");
        assert!(hi == "\x1B[47;35mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_purple_on_white_2() {
        let hi = Purple.normal().on(White).paint("hi");
        assert!(hi == "\x1B[47;35mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_cyan_bold_on_white() {
        let hi = Cyan.bold().on(White).paint("hi");
        assert!(hi == "\x1B[1;47;36mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_cyan_underline_on_white() {
        let hi = Cyan.underline().on(White).paint("hi");
        assert!(hi == "\x1B[4;47;36mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_cyan_bold_underline_on_white() {
        let hi = Cyan.bold().underline().on(White).paint("hi");
        assert!(hi == "\x1B[1;4;47;36mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_cyan_underline_bold_on_white() {
        let hi = Cyan.underline().bold().on(White).paint("hi");
        assert!(hi == "\x1B[1;4;47;36mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_fixed() {
        let hi = Fixed(100).paint("hi");
        assert!(hi == "\x1B[38;5;100mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_fixed_on_purple() {
        let hi = Fixed(100).on(Purple).paint("hi");
        assert!(hi == "\x1B[45;38;5;100mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_fixed_on_fixed() {
        let hi = Fixed(100).on(Fixed(200)).paint("hi");
        assert!(hi == "\x1B[48;5;200;38;5;100mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_strip_formatting() {
        let hi = strip_formatting(Blue.paint("hi"));
        assert!(hi == "hi".to_string());
    }

    #[test]
    fn test_strip_formatting_2() {
        let hi = strip_formatting(Blue.on(Fixed(230)).bold().paint("hi"));
        assert!(hi == "hi".to_string());
    }
}
<commit_msg>Give Style and Colour a common trait<commit_after>#![crate_id = "ansi_term#0.1dev"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![desc = "A rust library for ANSI terminal colours and styles (bold, underline)"]

//! This is a library for controlling colours and formatting, such as
//! red bold text or blue underlined text, on ANSI terminals.
//!
//! Simple Colours
//! --------------
//!
//! You can format strings by calling the `paint` method on a Colour
//! or a Style object, passing in the string you want to format. For
//! example, to get some red text, call the `paint` method on `Red`:
//!
//! ```rust
//! Red.paint("Red!")
//! ```
//!
//! You can also call the `paint` method on a Style. To turn a Colour
//! into a Style, use the `normal` method, though this does the exact
//! some thing as above:
//!
//! ```rust
//! Red.normal().paint("Still red!")
//! ```
//!
//! Bold, Underline, and Background
//! -------------------------------
//!
//! To do anything more complex than just foreground colours, you need
//! to use Style objects. Calling the `bold` or `underline` method on
//! a Colour returns a Style that has the appropriate property set on
//! it:
//!
//! ```rust
//! Blue.bold().paint("Blue bold!")
//! Yellow.underline().paint("Yellow underline!")
//! ```
//!
//! Again, you can call these methods on Styles as well as just Colours:
//!
//! ```rust
//! Blue.normal().bold().paint("Still blue bold!")
//! ```
//!
//! Finally, you can set the background colour of a Style by using the
//! `on` method:
//!
//! ```rust
//! Blue.on(Yellow).paint("Blue on yellow!")
//! ```
//!
//! Extended Colours
//! ----------------
//!
//! You can access the extended range of 256 colours by using the
//! Fixed constructor, which takes an argument of the colour number to
//! use. This can be used wherever you would use a Colour:
//!
//! ```rust
//! Fixed(134).paint("A sort of light purple.")
//! ```
//!
//! This even works for background colours:
//!
//! ```rust
//! Fixed(221).on(Fixed(124)).paint("Mustard in the ketchup.")
//! ```
//!
//! No Formatting
//! -------------
//!
//! Finally, for the sake of completeness, the Plain style provides
//! neither colours nor formatting.
//!
//! ```rust
//! Plain.paint("No colours here.")
//! ```

#![feature(phase)] extern crate regex;
#[phase(plugin)] extern crate regex_macros;

trait Paint {
    /// Paints the given text with this colour. This is a short-cut so
    /// you don't have to use Blue.normal() just to get blue text.
    fn paint(&self, input: &str) -> String;

    /// Returns a Style with the underline property set.
    fn underline(&self) -> Style;

    /// Return a Style with the bold property set.
    fn bold(&self) -> Style;

    /// Return a Style with the background colour set.
    fn on(&self, background: Colour) -> Style;
}

/// A colour is one specific type of ANSI escape code, and can refer
/// to either the foreground or background colour.
pub enum Colour {
    Black, Red, Green, Yellow, Blue, Purple, Cyan, White, Fixed(u8),
}

// These are the standard numeric sequences.
// See http://invisible-island.net/xterm/ctlseqs/ctlseqs.html

impl Colour {
    fn foreground_code(&self) -> String {
        match *self {
            Black => "30".to_string(),
            Red => "31".to_string(),
            Green => "32".to_string(),
            Yellow => "33".to_string(),
            Blue => "34".to_string(),
            Purple => "35".to_string(),
            Cyan => "36".to_string(),
            White => "37".to_string(),
            Fixed(num) => format!("38;5;{}", num),
        }
    }

    fn background_code(&self) -> String {
        match *self {
            Black => "40".to_string(),
            Red => "41".to_string(),
            Green => "42".to_string(),
            Yellow => "43".to_string(),
            Blue => "44".to_string(),
            Purple => "45".to_string(),
            Cyan => "46".to_string(),
            White => "47".to_string(),
            Fixed(num) => format!("48;5;{}", num),
        }
    }

    /// Return a Style with the foreground colour set to this colour.
    pub fn normal(&self) -> Style {
        Style(StyleStruct { foreground: *self, background: None, bold: false, underline: false })
    }
}

/// The Paint trait represents a style or colour that can be applied
/// to a piece of text.
impl Paint for Colour {
    /// Paints the given text with this colour. This is a short-cut so
    /// you don't have to use Blue.normal() just to get blue text.
    fn paint(&self, input: &str) -> String {
        let re = format!("\x1B[{}m{}\x1B[0m", self.foreground_code(), input);
        return re.to_string();
    }

    /// Returns a Style with the underline property set.
    fn underline(&self) -> Style {
        Style(StyleStruct { foreground: *self, background: None, bold: false, underline: true })
    }

    /// Return a Style with the bold property set.
    fn bold(&self) -> Style {
        Style(StyleStruct { foreground: *self, background: None, bold: true, underline: false })
    }

    /// Return a Style with the background colour set.
    fn on(&self, background: Colour) -> Style {
        Style(StyleStruct { foreground: *self, background: Some(background), bold: false, underline: false })
    }
}

/// A style is a collection of properties that can format a string
/// using ANSI escape codes.
pub enum Style {
    /// The Plain style provides no formatting.
    Plain,
    /// The Foreground style provides just a foreground colour.
    Foreground(Colour),
    /// The Style style is a catch-all for anything more complicated
    /// than that. It's technically possible for there to be other
    /// cases, such as "bold foreground", but probably isn't worth it.
    Style(StyleStruct),
}

// Having a struct inside an enum is currently unfinished in Rust, but
// should be put in there when that feature is complete.

struct StyleStruct {
    foreground: Colour,
    background: Option<Colour>,
    bold: bool,
    underline: bool,
}

impl Paint for Style {
    /// Paints the given text with this style, returning a String of
    /// text with the relevant ANSI escape codes added.
    fn paint(&self, input: &str) -> String {
        match *self {
            Plain => input.to_string(),
            Foreground(c) => c.paint(input),
            Style(s) => match s {
                StyleStruct { foreground, background, bold, underline } => {
                    let bg = match background {
                        Some(c) => format!("{};", c.background_code()),
                        None => "".to_string()
                    };
                    let bo = if bold { "1;" } else { "" };
                    let un = if underline { "4;" } else { "" };
                    let painted = format!("\x1B[{}{}{}{}m{}\x1B[0m", bo, un, bg, foreground.foreground_code(), input.to_string());
                    return painted.to_string();
                }
            }
        }
    }

    /// Return a Style with the bold property set.
    fn bold(&self) -> Style {
        match *self {
            Plain => Style(StyleStruct         { foreground: White,         background: None,          bold: true, underline: false }),
            Foreground(c) => Style(StyleStruct { foreground: c,             background: None,          bold: true, underline: false }),
            Style(st) => Style(StyleStruct     { foreground: st.foreground, background: st.background, bold: true, underline: st.underline }),
        }
    }

    /// Return a Style with the underline property set.
    fn underline(&self) -> Style {
        match *self {
            Plain => Style(StyleStruct         { foreground: White,         background: None,          bold: false,   underline: true }),
            Foreground(c) => Style(StyleStruct { foreground: c,             background: None,          bold: false,   underline: true }),
            Style(st) => Style(StyleStruct     { foreground: st.foreground, background: st.background, bold: st.bold, underline: true }),
        }
    }

    /// Return a Style with the background colour set.
    fn on(&self, background: Colour) -> Style {
        match *self {
            Plain => Style(StyleStruct         { foreground: White,         background: Some(background), bold: false,   underline: false }),
            Foreground(c) => Style(StyleStruct { foreground: c,             background: Some(background), bold: false,   underline: false }),
            Style(st) => Style(StyleStruct     { foreground: st.foreground, background: Some(background), bold: st.bold, underline: st.underline }),
        }
    }
}

/// Return a String with all ANSI escape codes removed. For example:
///
/// ```rust
/// strip_formatting(Blue.paint("hello!")) == "hello!"
/// ```
pub fn strip_formatting(input: String) -> String {
    // What's blue and smells like red paint? Blue paint.
    let re = regex!("\x1B\\[.+?m");
    re.replace_all(input.as_slice(), "").to_string()
}

#[cfg(test)]
mod tests {
    use super::{Paint, Black, Red, Green, Yellow, Blue, Purple, Cyan, White, Fixed, Plain, strip_formatting};

    #[test]
    fn test_plain() {
        let hi = Plain.paint("text/plain");
        assert!(hi == "text/plain".to_string());
    }

    #[test]
    fn test_red() {
        let hi = Red.paint("hi");
        assert!(hi == "\x1B[31mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_black() {
        let hi = Black.normal().paint("hi");
        assert!(hi == "\x1B[30mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_yellow_bold() {
        let hi = Yellow.bold().paint("hi");
        assert!(hi == "\x1B[1;33mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_yellow_bold_2() {
        let hi = Yellow.normal().bold().paint("hi");
        assert!(hi == "\x1B[1;33mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_blue_underline() {
        let hi = Blue.underline().paint("hi");
        assert!(hi == "\x1B[4;34mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_green_bold_underline() {
        let hi = Green.bold().underline().paint("hi");
        assert!(hi == "\x1B[1;4;32mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_green_bold_underline_2() {
        let hi = Green.underline().bold().paint("hi");
        assert!(hi == "\x1B[1;4;32mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_purple_on_white() {
        let hi = Purple.on(White).paint("hi");
        assert!(hi == "\x1B[47;35mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_purple_on_white_2() {
        let hi = Purple.normal().on(White).paint("hi");
        assert!(hi == "\x1B[47;35mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_cyan_bold_on_white() {
        let hi = Cyan.bold().on(White).paint("hi");
        assert!(hi == "\x1B[1;47;36mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_cyan_underline_on_white() {
        let hi = Cyan.underline().on(White).paint("hi");
        assert!(hi == "\x1B[4;47;36mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_cyan_bold_underline_on_white() {
        let hi = Cyan.bold().underline().on(White).paint("hi");
        assert!(hi == "\x1B[1;4;47;36mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_cyan_underline_bold_on_white() {
        let hi = Cyan.underline().bold().on(White).paint("hi");
        assert!(hi == "\x1B[1;4;47;36mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_fixed() {
        let hi = Fixed(100).paint("hi");
        assert!(hi == "\x1B[38;5;100mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_fixed_on_purple() {
        let hi = Fixed(100).on(Purple).paint("hi");
        assert!(hi == "\x1B[45;38;5;100mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_fixed_on_fixed() {
        let hi = Fixed(100).on(Fixed(200)).paint("hi");
        assert!(hi == "\x1B[48;5;200;38;5;100mhi\x1B[0m".to_string());
    }

    #[test]
    fn test_strip_formatting() {
        let hi = strip_formatting(Blue.paint("hi"));
        assert!(hi == "hi".to_string());
    }

    #[test]
    fn test_strip_formatting_2() {
        let hi = strip_formatting(Blue.on(Fixed(230)).bold().paint("hi"));
        assert!(hi == "hi".to_string());
    }
}
<|endoftext|>


<commit_before>use std::rand;
use std::rand::{Rand, Rng};

pub fn arbitrary<A: Arbitrary>() -> A {
    Arbitrary::arbitrary(&mut sized_rng(rand::rng(), 20))
}

pub fn sized_rng<R: Rng>(rng: R, size: uint) -> Gen<R> {
    Gen{rng: rng, size: size}
}

pub trait SizedRng : Rng {
    fn size(&mut self) -> uint;
}

struct Gen<R> {
    rng: R,
    size: uint,
}

impl<R: Rng> Rng for Gen<R> {
    fn next_u32(&mut self) -> u32 { self.rng.next_u32() }
}

impl<R: Rng> SizedRng for Gen<R> {
    fn size(&mut self) -> uint { self.size }
}

pub trait Arbitrary {
    fn arbitrary<R: SizedRng>(rng: &mut R) -> Self;
}

impl Arbitrary for () {
    fn arbitrary<R: SizedRng>(_: &mut R) -> () { () }
}

impl Arbitrary for bool {
    fn arbitrary<R: SizedRng>(rng: &mut R) -> bool {
        Rand::rand(rng)
    }
}

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

    #[test]
    fn unit() {
        assert_eq!(arbitrary::<()>(), ());
    }
}
<commit_msg>Rename SizedRng to Gen and use the Gen for any configuration needed for arbitrary generation. (Currently the only parameter is a size hint for random values.)<commit_after>use std::rand;
use std::rand::{Rand, Rng};

pub trait Gen : Rng {
    fn size(&mut self) -> uint;
}

struct StdGen<R> {
    rng: R,
    size: uint,
}

impl<R: Rng> Rng for StdGen<R> {
    fn next_u32(&mut self) -> u32 { self.rng.next_u32() }
}

impl<R: Rng> Gen for StdGen<R> {
    fn size(&mut self) -> uint { self.size }
}

pub trait Arbitrary {
    fn arbitrary<G: Gen>(g: &mut G) -> Self;
}

impl Arbitrary for () {
    fn arbitrary<G: Gen>(_: &mut G) -> () { () }
}

impl Arbitrary for bool {
    fn arbitrary<G: Gen>(g: &mut G) -> bool {
        Rand::rand(g)
    }
}

pub fn arbitrary<A: Arbitrary>() -> A {
    Arbitrary::arbitrary(&mut gen(rand::task_rng(), 20))
}

pub fn gen<R: Rng>(rng: R, size: uint) -> StdGen<R> {
    StdGen{rng: rng, size: size}
}

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

    #[test]
    fn unit() {
        assert_eq!(arbitrary::<()>(), ());
    }
}
<|endoftext|>


<commit_before>extern crate frappe;

use std::fs::File;

use frappe::classfile::ClassFile;
use frappe::classfile::attr;
use frappe::classfile::constant_pool;

trait Javap {
    fn pretty_print(&self) -> String;
}

impl Javap for constant_pool::Tag {
    fn pretty_print(&self) -> String {
        match *self {
            constant_pool::Tag::Methodref(constant_pool::MethodrefTag{ref class_index, ref name_and_type_index}) => {
                format!("Methodref\t\t#{}.#{}", class_index, name_and_type_index)
            },
            constant_pool::Tag::Fieldref(constant_pool::FieldrefTag{ref class_index, ref name_and_type_index}) => {
                format!("Fieldref\t\t\t#{}.#{}", class_index, name_and_type_index)
            },
            constant_pool::Tag::String(constant_pool::StringTag{ref string_index}) => {
                format!("String\t\t\t#{}", string_index)
            },
            constant_pool::Tag::Class(constant_pool::ClassTag{ref name_index}) => {
                format!("Class\t\t\t#{}", name_index)
            },
            constant_pool::Tag::Utf8(ref string) => {
                format!("Utf8\t\t\t{}", string)
            },
            constant_pool::Tag::NameAndType(constant_pool::NameAndTypeTag{ref name_index, ref descriptor_index}) => {
                format!("NameAndType\t\t#{}:#{}", name_index, descriptor_index)
            },
            _ => format!("{:?}", self)
        }
    }
}

impl Javap for constant_pool::ConstantPool {
    fn pretty_print(&self) -> String {
        let mut pretty = String::new();
        pretty.push_str(&format!("Constant pool:\n"));
        for (i, tag) in self.iter().enumerate() {
            pretty.push_str(&format!("  #{} = {}\n", i, tag.pretty_print()));
        }
        pretty
    }
}

fn main() {
    let verbose = true;
    let classname = "io.hcf.frappe.HelloWorld";
    let mut class_filename = classname.replace('.', "/");
    class_filename.push_str(".class");
    let mut class_file = File::open(class_filename).unwrap();
    let class = ClassFile::read(&mut class_file).unwrap();

    for attribute in class.attributes.iter() {
        if let attr::AttributeInfo::SourceFile(ref sourcefile_info) = *attribute {
            let source_file = &class.constant_pool[sourcefile_info.sourcefile_index];
            println!("Compiled from \"{}\"", source_file.as_utf8().unwrap());
        }
    }
    let this_class = class.this_class();
    let class_name = class.constant_pool.get_string(this_class.name_index).unwrap();
    if class.access_flags.is_public() {
        print!("public ");
    }
    if class.access_flags.is_interface() {
        print!("interface");
    } else if class.access_flags.is_annotation() {
        print!("@interface");
    } else {
        print!("class");
    }
    print!(" ");
    print!("{}", class_name.replace("/", "."));
    println!(" {{");
    if verbose {
        println!("  minor version: {}", class.minor_version);
        println!("  major version: {}", class.minor_version);
        println!("  access flags: {}", class.access_flags);
        println!("{}", class.constant_pool.pretty_print());
    }
    for method in class.methods.iter() {
        print!("  ");
        if method.access_flags.is_public() {
            print!("public ");
        } else if method.access_flags.is_private() {
            print!("private ");
        } else if method.access_flags.is_protected() {
            print!("protected ");
        } else {
            print!("/* package */ ");
        }
        if method.access_flags.is_static() {
            print!("static ");
        }
        let method_name = class.constant_pool.get_string(method.name_index);
        println!("{}", method_name.unwrap());
    }
    println!("}}");
}
<commit_msg>Fix typo in major/minor version printing.<commit_after>extern crate frappe;

use std::fs::File;

use frappe::classfile::ClassFile;
use frappe::classfile::attr;
use frappe::classfile::constant_pool;

trait Javap {
    fn pretty_print(&self) -> String;
}

impl Javap for constant_pool::Tag {
    fn pretty_print(&self) -> String {
        match *self {
            constant_pool::Tag::Methodref(constant_pool::MethodrefTag{ref class_index, ref name_and_type_index}) => {
                format!("Methodref\t\t#{}.#{}", class_index, name_and_type_index)
            },
            constant_pool::Tag::Fieldref(constant_pool::FieldrefTag{ref class_index, ref name_and_type_index}) => {
                format!("Fieldref\t\t\t#{}.#{}", class_index, name_and_type_index)
            },
            constant_pool::Tag::String(constant_pool::StringTag{ref string_index}) => {
                format!("String\t\t\t#{}", string_index)
            },
            constant_pool::Tag::Class(constant_pool::ClassTag{ref name_index}) => {
                format!("Class\t\t\t#{}", name_index)
            },
            constant_pool::Tag::Utf8(ref string) => {
                format!("Utf8\t\t\t{}", string)
            },
            constant_pool::Tag::NameAndType(constant_pool::NameAndTypeTag{ref name_index, ref descriptor_index}) => {
                format!("NameAndType\t\t#{}:#{}", name_index, descriptor_index)
            },
            _ => format!("{:?}", self)
        }
    }
}

impl Javap for constant_pool::ConstantPool {
    fn pretty_print(&self) -> String {
        let mut pretty = String::new();
        pretty.push_str(&format!("Constant pool:\n"));
        for (i, tag) in self.iter().enumerate() {
            pretty.push_str(&format!("  #{} = {}\n", i, tag.pretty_print()));
        }
        pretty
    }
}

fn main() {
    let verbose = true;
    let classname = "io.hcf.frappe.HelloWorld";
    let mut class_filename = classname.replace('.', "/");
    class_filename.push_str(".class");
    let mut class_file = File::open(class_filename).unwrap();
    let class = ClassFile::read(&mut class_file).unwrap();

    for attribute in class.attributes.iter() {
        if let attr::AttributeInfo::SourceFile(ref sourcefile_info) = *attribute {
            let source_file = &class.constant_pool[sourcefile_info.sourcefile_index];
            println!("Compiled from \"{}\"", source_file.as_utf8().unwrap());
        }
    }
    let this_class = class.this_class();
    let class_name = class.constant_pool.get_string(this_class.name_index).unwrap();
    if class.access_flags.is_public() {
        print!("public ");
    }
    if class.access_flags.is_interface() {
        print!("interface");
    } else if class.access_flags.is_annotation() {
        print!("@interface");
    } else {
        print!("class");
    }
    print!(" ");
    print!("{}", class_name.replace("/", "."));
    println!(" {{");
    if verbose {
        println!("  minor version: {}", class.minor_version);
        println!("  major version: {}", class.major_version);
        println!("  access flags: {}", class.access_flags);
        println!("{}", class.constant_pool.pretty_print());
    }
    for method in class.methods.iter() {
        print!("  ");
        if method.access_flags.is_public() {
            print!("public ");
        } else if method.access_flags.is_private() {
            print!("private ");
        } else if method.access_flags.is_protected() {
            print!("protected ");
        } else {
            print!("/* package */ ");
        }
        if method.access_flags.is_static() {
            print!("static ");
        }
        let method_name = class.constant_pool.get_string(method.name_index);
        println!("{}", method_name.unwrap());
    }
    println!("}}");
}
<|endoftext|>


<commit_before>use cargo::ops;
use cargo::util::{CliResult, CliError, Config};

#[derive(RustcDecodable)]
struct Options {
    arg_crate: Option<String>,
    flag_token: Option<String>,
    flag_add: Option<Vec<String>>,
    flag_remove: Option<Vec<String>>,
    flag_index: Option<String>,
    flag_verbose: bool,
    flag_quiet: bool,
    flag_color: Option<String>,
    flag_list: bool,
}

pub const USAGE: &'static str = "
Manage the owners of a crate on the registry

Usage:
    cargo owner [options] [<crate>]

Options:
    -h, --help               Print this message
    -a, --add LOGIN          Login of a user to add as an owner
    -r, --remove LOGIN       Login of a user to remove as an owner
    -l, --list               List owners of a crate
    --index INDEX            Registry index to modify owners for
    --token TOKEN            API token to use when authenticating
    -v, --verbose            Use verbose output
    -q, --quiet              No output printed to stdout
    --color WHEN             Coloring: auto, always, never

This command will modify the owners for a package on the specified registry (or
default). Note that owners of a package can upload new versions, yank old
versions, and also modify the set of owners, so take caution!
";

pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
    try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet));
    try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..])));
    let opts = ops::OwnersOptions {
        krate: options.arg_crate,
        token: options.flag_token,
        index: options.flag_index,
        to_add: options.flag_add,
        to_remove: options.flag_remove,
        list: options.flag_list,
    };
    try!(ops::modify_owners(config, &opts).map_err(|e| {
        CliError::from_boxed(e, 101)
    }));
    Ok(None)
}

<commit_msg>modify help owner<commit_after>use cargo::ops;
use cargo::util::{CliResult, CliError, Config};

#[derive(RustcDecodable)]
struct Options {
    arg_crate: Option<String>,
    flag_token: Option<String>,
    flag_add: Option<Vec<String>>,
    flag_remove: Option<Vec<String>>,
    flag_index: Option<String>,
    flag_verbose: bool,
    flag_quiet: bool,
    flag_color: Option<String>,
    flag_list: bool,
}

pub const USAGE: &'static str = "
Manage the owners of a crate on the registry

Usage:
    cargo owner [options] [<crate>]

Options:
    -h, --help               Print this message
    -a, --add LOGIN          Name of a user or team to add as an owner
    -r, --remove LOGIN       Name of a user or team to remove as an owner
    -l, --list               List owners of a crate
    --index INDEX            Registry index to modify owners for
    --token TOKEN            API token to use when authenticating
    -v, --verbose            Use verbose output
    -q, --quiet              No output printed to stdout
    --color WHEN             Coloring: auto, always, never

This command will modify the owners for a package on the specified registry (or
default). Note that owners of a package can upload new versions, yank old
versions. Explicitly named owners can also modify the set of owners, so take
caution!

See http://doc.crates.io/crates-io.html#cargo-owner for detailed documentation
and troubleshooting.
";

pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
    try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet));
    try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..])));
    let opts = ops::OwnersOptions {
        krate: options.arg_crate,
        token: options.flag_token,
        index: options.flag_index,
        to_add: options.flag_add,
        to_remove: options.flag_remove,
        list: options.flag_list,
    };
    try!(ops::modify_owners(config, &opts).map_err(|e| {
        CliError::from_boxed(e, 101)
    }));
    Ok(None)
}

<|endoftext|>


<commit_before>#![deny(unused)]
#![cfg_attr(test, deny(warnings))]

#[cfg(test)] extern crate hamcrest;
#[macro_use] extern crate log;
extern crate crates_io as registry;
extern crate crossbeam;
extern crate curl;
extern crate docopt;
extern crate filetime;
extern crate flate2;
extern crate fs2;
extern crate git2;
extern crate glob;
extern crate libc;
extern crate libgit2_sys;
extern crate num_cpus;
extern crate regex;
extern crate rustc_serialize;
extern crate semver;
extern crate tar;
extern crate tempdir;
extern crate term;
extern crate toml;
extern crate url;

use std::env;
use std::io::prelude::*;
use std::io;
use rustc_serialize::{Decodable, Encodable};
use rustc_serialize::json::{self, Json};
use docopt::Docopt;

use core::{Shell, MultiShell, ShellConfig, Verbosity, ColorConfig};
use core::shell::Verbosity::{Verbose};
use core::shell::ColorConfig::{Auto};
use term::color::{BLACK};

pub use util::{CargoError, CargoResult, CliError, CliResult, human, Config, ChainError};

macro_rules! bail {
    ($($fmt:tt)*) => (
        return Err(::util::human(&format_args!($($fmt)*)))
    )
}

pub mod core;
pub mod ops;
pub mod sources;
pub mod util;

pub fn execute_main<T, U, V>(
                        exec: fn(T, U, &Config) -> CliResult<Option<V>>,
                        options_first: bool,
                        usage: &str)
    where V: Encodable, T: Decodable, U: Decodable
{
    process::<V, _>(|rest, shell| {
        call_main(exec, shell, usage, rest, options_first)
    });
}

pub fn call_main<T, U, V>(
            exec: fn(T, U, &Config) -> CliResult<Option<V>>,
            shell: &Config,
            usage: &str,
            args: &[String],
            options_first: bool) -> CliResult<Option<V>>
    where V: Encodable, T: Decodable, U: Decodable
{
    let flags = try!(flags_from_args::<T>(usage, args, options_first));
    let json = try!(json_from_stdin::<U>());

    exec(flags, json, shell)
}

pub fn execute_main_without_stdin<T, V>(
                                      exec: fn(T, &Config) -> CliResult<Option<V>>,
                                      options_first: bool,
                                      usage: &str)
    where V: Encodable, T: Decodable
{
    process::<V, _>(|rest, shell| {
        call_main_without_stdin(exec, shell, usage, rest, options_first)
    });
}

pub fn call_main_without_stdin<T, V>(
            exec: fn(T, &Config) -> CliResult<Option<V>>,
            shell: &Config,
            usage: &str,
            args: &[String],
            options_first: bool) -> CliResult<Option<V>>
    where V: Encodable, T: Decodable
{
    let flags = try!(flags_from_args::<T>(usage, args, options_first));
    exec(flags, shell)
}

fn process<V, F>(mut callback: F)
    where F: FnMut(&[String], &Config) -> CliResult<Option<V>>,
          V: Encodable
{
    let mut config = None;
    let result = (|| {
        config = Some(try!(Config::default()));
        let args: Vec<_> = try!(env::args_os().map(|s| {
            s.into_string().map_err(|s| {
                human(format!("invalid unicode in argument: {:?}", s))
            })
        }).collect());
        callback(&args, config.as_ref().unwrap())
    })();
    let mut verbose_shell = shell(Verbose, Auto);
    let mut shell = config.as_ref().map(|s| s.shell());
    let shell = shell.as_mut().map(|s| &mut **s).unwrap_or(&mut verbose_shell);
    process_executed(result, shell)
}

pub fn process_executed<T>(result: CliResult<Option<T>>, shell: &mut MultiShell)
    where T: Encodable
{
    match result {
        Err(e) => handle_error(e, shell),
        Ok(Some(encodable)) => {
            let encoded = json::encode(&encodable).unwrap();
            println!("{}", encoded);
        }
        Ok(None) => {}
    }
}

pub fn shell(verbosity: Verbosity, color_config: ColorConfig) -> MultiShell {
    enum Output {
        Stdout,
        Stderr,
    }

    let tty = isatty(Output::Stderr);

    let config = ShellConfig { color_config: color_config, tty: tty };
    let err = Shell::create(|| Box::new(io::stderr()), config);

    let tty = isatty(Output::Stdout);

    let config = ShellConfig { color_config: color_config, tty: tty };
    let out = Shell::create(|| Box::new(io::stdout()), config);

    return MultiShell::new(out, err, verbosity);

    #[cfg(unix)]
    fn isatty(output: Output) -> bool {
        let fd = match output {
            Output::Stdout => libc::STDOUT_FILENO,
            Output::Stderr => libc::STDERR_FILENO,
        };

        unsafe { libc::isatty(fd) != 0 }
    }
    #[cfg(windows)]
    fn isatty(output: Output) -> bool {
        extern crate kernel32;
        extern crate winapi;

        let handle = match output {
            Output::Stdout => winapi::winbase::STD_OUTPUT_HANDLE,
            Output::Stderr => winapi::winbase::STD_ERROR_HANDLE,
        };

        unsafe {
            let handle = kernel32::GetStdHandle(handle);
            let mut out = 0;
            kernel32::GetConsoleMode(handle, &mut out) != 0
        }
    }
}

pub fn handle_error(err: CliError, shell: &mut MultiShell) {
    debug!("handle_error; err={:?}", err);

    let CliError { error, exit_code, unknown } = err;
    // exit_code == 0 is non-fatal error, e.g. docopt version info
    let fatal = exit_code != 0;

    let hide = unknown && shell.get_verbose() != Verbose;

    if let Some(error) = error {
        let _ignored_result = if hide {
            shell.error("An unknown error occurred")
        } else if fatal {
            shell.error(&error)
        } else {
            shell.say(&error, BLACK)
        };

        if !handle_cause(&error, shell) || hide {
            let _ = shell.err().say("\nTo learn more, run the command again \
                                     with --verbose.".to_string(), BLACK);
        }
    }

    std::process::exit(exit_code);
}

fn handle_cause(mut cargo_err: &CargoError, shell: &mut MultiShell) -> bool {
    let verbose = shell.get_verbose();
    let mut err;
    loop {
        cargo_err = match cargo_err.cargo_cause() {
            Some(cause) => cause,
            None => { err = cargo_err.cause(); break }
        };
        if verbose != Verbose && !cargo_err.is_human() { return false }
        print(cargo_err.to_string(), shell);
    }
    loop {
        let cause = match err { Some(err) => err, None => return true };
        if verbose != Verbose { return false }
        print(cause.to_string(), shell);
        err = cause.cause();
    }

    fn print(error: String, shell: &mut MultiShell) {
        let _ = shell.err().say("\nCaused by:", BLACK);
        let _ = shell.err().say(format!("  {}", error), BLACK);
    }
}

pub fn version() -> String {
    format!("cargo {}", match option_env!("CFG_VERSION") {
        Some(s) => s.to_string(),
        None => format!("{}.{}.{}{}",
                        env!("CARGO_PKG_VERSION_MAJOR"),
                        env!("CARGO_PKG_VERSION_MINOR"),
                        env!("CARGO_PKG_VERSION_PATCH"),
                        option_env!("CARGO_PKG_VERSION_PRE").unwrap_or(""))
    })
}

fn flags_from_args<T>(usage: &str, args: &[String],
                          options_first: bool) -> CliResult<T>
    where T: Decodable
{
    let docopt = Docopt::new(usage).unwrap()
                                   .options_first(options_first)
                                   .argv(args.iter().map(|s| &s[..]))
                                   .help(true);
    docopt.decode().map_err(|e| {
        let code = if e.fatal() {1} else {0};
        CliError::new(human(e.to_string()), code)
    })
}

fn json_from_stdin<T: Decodable>() -> CliResult<T> {
    let mut reader = io::stdin();
    let mut input = String::new();
    try!(reader.read_to_string(&mut input).map_err(|_| {
        CliError::new(human("Standard in did not exist or was not UTF-8"), 1)
    }));

    let json = try!(Json::from_str(&input).map_err(|_| {
        CliError::new(human("Could not parse standard in as JSON"), 1)
    }));
    let mut decoder = json::Decoder::new(json);

    Decodable::decode(&mut decoder).map_err(|_| {
        CliError::new(human("Could not process standard in as input"), 1)
    })
}
<commit_msg>Remove dead code<commit_after>#![deny(unused)]
#![cfg_attr(test, deny(warnings))]

#[cfg(test)] extern crate hamcrest;
#[macro_use] extern crate log;
extern crate crates_io as registry;
extern crate crossbeam;
extern crate curl;
extern crate docopt;
extern crate filetime;
extern crate flate2;
extern crate fs2;
extern crate git2;
extern crate glob;
extern crate libc;
extern crate libgit2_sys;
extern crate num_cpus;
extern crate regex;
extern crate rustc_serialize;
extern crate semver;
extern crate tar;
extern crate tempdir;
extern crate term;
extern crate toml;
extern crate url;

use std::env;
use std::io;
use rustc_serialize::{Decodable, Encodable};
use rustc_serialize::json;
use docopt::Docopt;

use core::{Shell, MultiShell, ShellConfig, Verbosity, ColorConfig};
use core::shell::Verbosity::{Verbose};
use core::shell::ColorConfig::{Auto};
use term::color::{BLACK};

pub use util::{CargoError, CargoResult, CliError, CliResult, human, Config, ChainError};

macro_rules! bail {
    ($($fmt:tt)*) => (
        return Err(::util::human(&format_args!($($fmt)*)))
    )
}

pub mod core;
pub mod ops;
pub mod sources;
pub mod util;

pub fn execute_main_without_stdin<T, V>(
                                      exec: fn(T, &Config) -> CliResult<Option<V>>,
                                      options_first: bool,
                                      usage: &str)
    where V: Encodable, T: Decodable
{
    process::<V, _>(|rest, shell| {
        call_main_without_stdin(exec, shell, usage, rest, options_first)
    });
}

pub fn call_main_without_stdin<T, V>(
            exec: fn(T, &Config) -> CliResult<Option<V>>,
            shell: &Config,
            usage: &str,
            args: &[String],
            options_first: bool) -> CliResult<Option<V>>
    where V: Encodable, T: Decodable
{
    let flags = try!(flags_from_args::<T>(usage, args, options_first));
    exec(flags, shell)
}

fn process<V, F>(mut callback: F)
    where F: FnMut(&[String], &Config) -> CliResult<Option<V>>,
          V: Encodable
{
    let mut config = None;
    let result = (|| {
        config = Some(try!(Config::default()));
        let args: Vec<_> = try!(env::args_os().map(|s| {
            s.into_string().map_err(|s| {
                human(format!("invalid unicode in argument: {:?}", s))
            })
        }).collect());
        callback(&args, config.as_ref().unwrap())
    })();
    let mut verbose_shell = shell(Verbose, Auto);
    let mut shell = config.as_ref().map(|s| s.shell());
    let shell = shell.as_mut().map(|s| &mut **s).unwrap_or(&mut verbose_shell);
    process_executed(result, shell)
}

pub fn process_executed<T>(result: CliResult<Option<T>>, shell: &mut MultiShell)
    where T: Encodable
{
    match result {
        Err(e) => handle_error(e, shell),
        Ok(Some(encodable)) => {
            let encoded = json::encode(&encodable).unwrap();
            println!("{}", encoded);
        }
        Ok(None) => {}
    }
}

pub fn shell(verbosity: Verbosity, color_config: ColorConfig) -> MultiShell {
    enum Output {
        Stdout,
        Stderr,
    }

    let tty = isatty(Output::Stderr);

    let config = ShellConfig { color_config: color_config, tty: tty };
    let err = Shell::create(|| Box::new(io::stderr()), config);

    let tty = isatty(Output::Stdout);

    let config = ShellConfig { color_config: color_config, tty: tty };
    let out = Shell::create(|| Box::new(io::stdout()), config);

    return MultiShell::new(out, err, verbosity);

    #[cfg(unix)]
    fn isatty(output: Output) -> bool {
        let fd = match output {
            Output::Stdout => libc::STDOUT_FILENO,
            Output::Stderr => libc::STDERR_FILENO,
        };

        unsafe { libc::isatty(fd) != 0 }
    }
    #[cfg(windows)]
    fn isatty(output: Output) -> bool {
        extern crate kernel32;
        extern crate winapi;

        let handle = match output {
            Output::Stdout => winapi::winbase::STD_OUTPUT_HANDLE,
            Output::Stderr => winapi::winbase::STD_ERROR_HANDLE,
        };

        unsafe {
            let handle = kernel32::GetStdHandle(handle);
            let mut out = 0;
            kernel32::GetConsoleMode(handle, &mut out) != 0
        }
    }
}

pub fn handle_error(err: CliError, shell: &mut MultiShell) {
    debug!("handle_error; err={:?}", err);

    let CliError { error, exit_code, unknown } = err;
    // exit_code == 0 is non-fatal error, e.g. docopt version info
    let fatal = exit_code != 0;

    let hide = unknown && shell.get_verbose() != Verbose;

    if let Some(error) = error {
        let _ignored_result = if hide {
            shell.error("An unknown error occurred")
        } else if fatal {
            shell.error(&error)
        } else {
            shell.say(&error, BLACK)
        };

        if !handle_cause(&error, shell) || hide {
            let _ = shell.err().say("\nTo learn more, run the command again \
                                     with --verbose.".to_string(), BLACK);
        }
    }

    std::process::exit(exit_code);
}

fn handle_cause(mut cargo_err: &CargoError, shell: &mut MultiShell) -> bool {
    let verbose = shell.get_verbose();
    let mut err;
    loop {
        cargo_err = match cargo_err.cargo_cause() {
            Some(cause) => cause,
            None => { err = cargo_err.cause(); break }
        };
        if verbose != Verbose && !cargo_err.is_human() { return false }
        print(cargo_err.to_string(), shell);
    }
    loop {
        let cause = match err { Some(err) => err, None => return true };
        if verbose != Verbose { return false }
        print(cause.to_string(), shell);
        err = cause.cause();
    }

    fn print(error: String, shell: &mut MultiShell) {
        let _ = shell.err().say("\nCaused by:", BLACK);
        let _ = shell.err().say(format!("  {}", error), BLACK);
    }
}

pub fn version() -> String {
    format!("cargo {}", match option_env!("CFG_VERSION") {
        Some(s) => s.to_string(),
        None => format!("{}.{}.{}{}",
                        env!("CARGO_PKG_VERSION_MAJOR"),
                        env!("CARGO_PKG_VERSION_MINOR"),
                        env!("CARGO_PKG_VERSION_PATCH"),
                        option_env!("CARGO_PKG_VERSION_PRE").unwrap_or(""))
    })
}

fn flags_from_args<T>(usage: &str, args: &[String],
                          options_first: bool) -> CliResult<T>
    where T: Decodable
{
    let docopt = Docopt::new(usage).unwrap()
                                   .options_first(options_first)
                                   .argv(args.iter().map(|s| &s[..]))
                                   .help(true);
    docopt.decode().map_err(|e| {
        let code = if e.fatal() {1} else {0};
        CliError::new(human(e.to_string()), code)
    })
}
<|endoftext|>


<commit_before>extern crate mio;
use getopts::{Options,Matches};
use std::net::{SocketAddr,lookup_host,IpAddr};
use std::io::{BufStream,Write};
use std::old_io;

use self::mio::*;
use self::mio::net::tcp::*;
use self::mio::buf::{ByteBuf};
use self::mio::net::*;
use std::str::FromStr;
use std::net::ToSocketAddrs;

const CLIENT: Token = Token(1);

struct ClientHandler {
    sock: NonBlock<TcpStream>
}

impl Handler for ClientHandler {
    type Timeout = usize;
    type Message = ();

    fn readable(&mut self, event_loop: &mut EventLoop<ClientHandler>, token: Token, _: ReadHint) {
        match token {
            CLIENT => {
                let mut read_buf = ByteBuf::mut_with_capacity(2048);
                match self.sock.read(&mut read_buf) {
                    Ok(None) => {
                        panic!("Read operation would block, bailing cuz this shouldn't happen.");
                    }
                    Ok(Some(r)) => {
                        // `_` would be the number of bytes read.
                        // `flip` will return a `ByteBuf` on which we can call
                        // `read_slice` to get the data available to be read.
                        // See http://carllerche.github.io/bytes/bytes/struct.ByteBuf.html
                        let mut buf = read_buf.flip();
                        let mut sl = [0; 2048];
                        buf.read_slice(&mut sl);
                        // Assuming what was written was encoded as UTF8, print what
                        // was read to STDOUT.
                        print!("{}", String::from_utf8(sl.to_vec()).unwrap());
                    }
                    Err(e) => {
                        panic!(e);
                        // println!("Client closed connection, shutting down.");
                        // event_loop.shutdown();
                    }
                }
            },
            _ => {
                panic!("unepxected token!".to_string());
            }
        }
    }
}

pub fn nc_connect(matches: &Matches) {
    let addr = parse_addr(matches);
    println!("addr: {}", addr);
    let sock = match addr.ip() {
        IpAddr::V4(..) => v4(),
        IpAddr::V6(..) => v6()
    }.unwrap();

    let mut event_loop = EventLoop::new().unwrap();

    match sock.connect(&addr) {
        Ok((stream, _)) => {
            let mut client = ClientHandler { sock: stream };
            event_loop.register(&client.sock, CLIENT).unwrap();
            let _ = event_loop.run(&mut client);
        },
        Err(f) => {
            println!("exiting");
            // just exit
        }
    }
}

fn readwrite(stream: &TcpStream) {
    let mut buf_stream = BufStream::new(stream);
    let mut stdin_reader = old_io::stdin();
    let mut read_buf = [0, 4096];
    loop {
        // Have to block here, so we can't immediately terminate if server closes socket.
        match stdin_reader.read(&mut read_buf) {
            Ok(n) => {
                buf_stream.write_all(&read_buf.slice_to(n)).unwrap();
                match buf_stream.flush() {
                    Ok(_) => { /* */ },
                    Err(f) => {
                        println!("closed");
                        // other end closed socket
                        return;
                    }
                }
            },
            Err(f) => {
                panic!(f.to_string());
            }
        }
    }
}

// pretty ugly...
fn parse_addr(matches: &Matches) -> SocketAddr {
    let host = matches.free.get(0).unwrap();
    let port_string = matches.free.get(1).unwrap();
    let port: u16 = FromStr::from_str(port_string.as_slice()).unwrap();
    return (host.as_slice(), port).to_socket_addrs().unwrap().next().unwrap();
}
<commit_msg>handle case when client can't connect to server unsure if this is the only scenario that will trigger this error<commit_after>extern crate mio;
use getopts::{Options,Matches};
use std::net::{SocketAddr,lookup_host,IpAddr};
use std::io::{BufStream,Write};
use std::old_io;

use self::mio::*;
use self::mio::net::tcp::*;
use self::mio::buf::{ByteBuf};
use self::mio::net::*;
use std::str::FromStr;
use std::net::ToSocketAddrs;

const CLIENT: Token = Token(1);

struct ClientHandler {
    sock: NonBlock<TcpStream>
}

impl Handler for ClientHandler {
    type Timeout = usize;
    type Message = ();

    fn readable(&mut self, event_loop: &mut EventLoop<ClientHandler>, token: Token, _: ReadHint) {
        match token {
            CLIENT => {
                let mut read_buf = ByteBuf::mut_with_capacity(2048);
                match self.sock.read(&mut read_buf) {
                    Ok(None) => {
                        panic!("Read operation would block, bailing cuz this shouldn't happen.");
                    }
                    Ok(Some(r)) => {
                        // `_` would be the number of bytes read.
                        // `flip` will return a `ByteBuf` on which we can call
                        // `read_slice` to get the data available to be read.
                        // See http://carllerche.github.io/bytes/bytes/struct.ByteBuf.html
                        let mut buf = read_buf.flip();
                        let mut sl = [0; 2048];
                        buf.read_slice(&mut sl);
                        // Assuming what was written was encoded as UTF8, print what
                        // was read to STDOUT.
                        print!("{}", String::from_utf8(sl.to_vec()).unwrap());
                    }
                    Err(e) => {
                        // Probably because connection could not be established.
                        event_loop.shutdown();
                        panic!(e.to_string());
                    }
                }
            },
            _ => {
                panic!("unepxected token!".to_string());
            }
        }
    }
}

pub fn nc_connect(matches: &Matches) {
    let addr = parse_addr(matches);
    let sock = match addr.ip() {
        IpAddr::V4(..) => v4(),
        IpAddr::V6(..) => v6()
    }.unwrap();

    let mut event_loop = EventLoop::new().unwrap();

    match sock.connect(&addr) {
        Ok((stream, _)) => {
            let mut client = ClientHandler { sock: stream };
            event_loop.register(&client.sock, CLIENT).unwrap();
            let _ = event_loop.run(&mut client);
        },
        Err(f) => {
            println!("exiting");
            // just exit
        }
    }
}

fn readwrite(stream: &TcpStream) {
    let mut buf_stream = BufStream::new(stream);
    let mut stdin_reader = old_io::stdin();
    let mut read_buf = [0, 4096];
    loop {
        // Have to block here, so we can't immediately terminate if server closes socket.
        match stdin_reader.read(&mut read_buf) {
            Ok(n) => {
                buf_stream.write_all(&read_buf.slice_to(n)).unwrap();
                match buf_stream.flush() {
                    Ok(_) => { /* */ },
                    Err(f) => {
                        println!("closed");
                        // other end closed socket
                        return;
                    }
                }
            },
            Err(f) => {
                panic!(f.to_string());
            }
        }
    }
}

// pretty ugly...
fn parse_addr(matches: &Matches) -> SocketAddr {
    let host = matches.free.get(0).unwrap();
    let port_string = matches.free.get(1).unwrap();
    let port: u16 = FromStr::from_str(port_string.as_slice()).unwrap();
    return (host.as_slice(), port).to_socket_addrs().unwrap().next().unwrap();
}
<|endoftext|>


<commit_before>// x, y
pub struct Coordinate(pub isize, pub isize);

// In the stencil and the image, the first coordinate is x, the second is y.
// This is computing the convolution between the stencil and the extracted matrix from the
// image
pub fn compute_pixel(stencil: &Vec<Vec<f32>>, coordinate: Coordinate, image_ref: &Vec<Vec<(f32, f32, f32)>>) -> (f32, f32, f32) {
    let stencil_size = (stencil.len(), stencil[0].len());

    let extracted_matrix = extract_matrix(image_ref, coordinate, stencil_size);

    let mut result: (f32, f32, f32) = (0.0, 0.0, 0.0);

    for i in 0..stencil_size.0 {
        for j in 0..stencil_size.1 {
            result.0 += extracted_matrix[i][j].0 * stencil[i][j];
            result.1 += extracted_matrix[i][j].1 * stencil[i][j];
            result.2 += extracted_matrix[i][j].2 * stencil[i][j];
        }
    }
    result
}

// Extracts the pixels values for a given stencil dimensions from an image
pub fn extract_matrix(image_ref: &Vec<Vec<(f32, f32, f32)>>, coordinate: Coordinate, dimensions: (usize, usize))
-> Vec<Vec<(f32, f32, f32)>>{

    let delta_x = ((dimensions.0 - 1) as f32 / 2.0) as isize;
    let delta_y = ((dimensions.1 - 1) as f32 / 2.0) as isize;

    let width = image_ref[0].len() as isize;
    let height = image_ref.len() as isize;

    let mut extracted_matrix: Vec<Vec<(f32, f32, f32)>> = Vec::with_capacity(dimensions.1);

    for (i, y) in ((coordinate.1 - delta_y)..(coordinate.1 + delta_y + 1)).enumerate() {
        extracted_matrix.push(Vec::with_capacity(dimensions.0));
        for x in (coordinate.0 - delta_x)..(coordinate.0 + delta_x + 1) {
            if x < 0 || y < 0 || x >= width || y >= height {
                extracted_matrix[i].push((0.0, 0.0, 0.0));
            } else {
                extracted_matrix[i].push(image_ref[y as usize][x as usize]);
            }
        }
    }

    extracted_matrix
}

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

    #[test]
    fn matrix_regular_extraction() {
        let image: Vec<Vec<(f32, f32, f32)>>= vec!(
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0))
        );

        let stencil: Vec<Vec<f32>> = vec!(
            vec!(1.0,3.0,4.0),
            vec!(1.0,3.0,4.0),
            vec!(1.0,3.0,4.0)
        );
        let stencil_size = (stencil.len(), stencil[0].len());
        let coord = Coordinate(1, 1);
        let extracted = extract_matrix(&image, coord, stencil_size);

        assert_eq!(extracted.len(), 3);
        assert_eq!(extracted[0].len(), 3);
        assert_eq!(extracted[0][0], (1.0,3.0,4.0));
        assert_eq!(extracted[0][1], (5.0,6.0,3.0));
        assert_eq!(extracted[1][0], (1.0,3.0,4.0));
        assert_eq!(extracted[1][1], (5.0,6.0,3.0));
        assert_eq!(extracted[2][2], (4.0,5.0,6.0));
    }

    #[test]
    fn matrix_lower_border_extraction() {
        let image: Vec<Vec<(f32, f32, f32)>>= vec!(
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0))
        );

        let stencil: Vec<Vec<f32>> = vec!(
            vec!(1.0,3.0,4.0),
            vec!(1.0,3.0,4.0),
            vec!(1.0,3.0,4.0)
        );
        let stencil_size = (stencil.len(), stencil[0].len());
        let coord = Coordinate(0, 0);
        let extracted = extract_matrix(&image, coord, stencil_size);

        assert_eq!(extracted.len(), 3);
        assert_eq!(extracted[0].len(), 3);
        assert_eq!(extracted[0][0], (0.0,0.0,0.0));
        assert_eq!(extracted[0][1], (0.0,0.0,0.0));
        assert_eq!(extracted[1][0], (0.0,0.0,0.0));
        assert_eq!(extracted[1][1], (1.0,3.0,4.0));
        assert_eq!(extracted[2][2], (5.0,6.0,3.0));
    }

    #[test]
    fn matrix_higher_border_extraction() {
        let image: Vec<Vec<(f32, f32, f32)>>= vec!(
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0))
        );

        let stencil: Vec<Vec<f32>> = vec!(
            vec!(1.0,3.0,4.0),
            vec!(1.0,3.0,4.0),
            vec!(1.0,3.0,4.0)
        );
        let stencil_size = (stencil.len(), stencil[0].len());
        let coord = Coordinate(2, 8);
        let extracted = extract_matrix(&image, coord, stencil_size);

        assert_eq!(extracted.len(), 3);
        assert_eq!(extracted[0].len(), 3);
        assert_eq!(extracted[0][0], (5.0, 6.0, 3.0));
        assert_eq!(extracted[0][1], (4.0, 5.0, 6.0));
        assert_eq!(extracted[1][0], (5.0, 6.0, 3.0));
        assert_eq!(extracted[1][1], (4.0, 5.0, 6.0));
        assert_eq!(extracted[2][2], (0.0, 0.0, 0.0));
    }

    #[test]
    fn compute_pixel_test() {
        let image: Vec<Vec<(f32, f32, f32)>>= vec!(
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0))
        );

        let stencil: Vec<Vec<f32>> = vec!(
            vec!(1.0,3.0,4.0),
            vec!(1.0,3.0,4.0),
            vec!(1.0,3.0,4.0)
        );
        let coord = Coordinate(1, 1);
        let pixel_value = compute_pixel(&stencil, coord, &image);

        assert_eq!(pixel_value, (96.0, 123.0, 111.0));
    }
}
<commit_msg>Update test with mono pixel case<commit_after>// x, y
pub struct Coordinate(pub isize, pub isize);

// In the stencil and the image, the first coordinate is x, the second is y.
// This is computing the convolution between the stencil and the extracted matrix from the
// image
pub fn compute_pixel(stencil: &Vec<Vec<f32>>, coordinate: Coordinate, image_ref: &Vec<Vec<(f32, f32, f32)>>) -> (f32, f32, f32) {
    let stencil_size = (stencil.len(), stencil[0].len());

    let extracted_matrix = extract_matrix(image_ref, coordinate, stencil_size);

    let mut result: (f32, f32, f32) = (0.0, 0.0, 0.0);

    for i in 0..stencil_size.1 {
        for j in 0..stencil_size.0 {
            result.0 += extracted_matrix[i][j].0 * stencil[i][j];
            result.1 += extracted_matrix[i][j].1 * stencil[i][j];
            result.2 += extracted_matrix[i][j].2 * stencil[i][j];
        }
    }
    result
}

// Extracts the pixels values for a given stencil dimensions from an image
pub fn extract_matrix(image_ref: &Vec<Vec<(f32, f32, f32)>>, coordinate: Coordinate, dimensions: (usize, usize))
-> Vec<Vec<(f32, f32, f32)>>{

    let delta_x = ((dimensions.0 - 1) as f32 / 2.0) as isize;
    let delta_y = ((dimensions.1 - 1) as f32 / 2.0) as isize;

    let width = image_ref[0].len() as isize;
    let height = image_ref.len() as isize;

    let mut extracted_matrix: Vec<Vec<(f32, f32, f32)>> = Vec::with_capacity(dimensions.1);

    for (i, y) in ((coordinate.1 - delta_y)..(coordinate.1 + delta_y + 1)).enumerate() {
        extracted_matrix.push(Vec::with_capacity(dimensions.0));
        for x in (coordinate.0 - delta_x)..(coordinate.0 + delta_x + 1) {
            if x < 0 || y < 0 || x >= width || y >= height {
                extracted_matrix[i].push((0.0, 0.0, 0.0));
            } else {
                extracted_matrix[i].push(image_ref[y as usize][x as usize]);
            }
        }
    }

    extracted_matrix
}

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

    #[test]
    fn matrix_regular_extraction() {
        let image: Vec<Vec<(f32, f32, f32)>>= vec!(
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0))
        );

        let stencil: Vec<Vec<f32>> = vec!(
            vec!(1.0,3.0,4.0),
            vec!(1.0,3.0,4.0),
            vec!(1.0,3.0,4.0)
        );
        let stencil_size = (stencil.len(), stencil[0].len());
        let coord = Coordinate(1, 1);
        let extracted = extract_matrix(&image, coord, stencil_size);

        assert_eq!(extracted.len(), 3);
        assert_eq!(extracted[0].len(), 3);
        assert_eq!(extracted[0][0], (1.0,3.0,4.0));
        assert_eq!(extracted[0][1], (5.0,6.0,3.0));
        assert_eq!(extracted[1][0], (1.0,3.0,4.0));
        assert_eq!(extracted[1][1], (5.0,6.0,3.0));
        assert_eq!(extracted[2][2], (4.0,5.0,6.0));
    }

    #[test]
    fn matrix_lower_border_extraction() {
        let image: Vec<Vec<(f32, f32, f32)>>= vec!(
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0))
        );

        let stencil: Vec<Vec<f32>> = vec!(
            vec!(1.0,3.0,4.0),
            vec!(1.0,3.0,4.0),
            vec!(1.0,3.0,4.0)
        );
        let stencil_size = (stencil.len(), stencil[0].len());
        let coord = Coordinate(0, 0);
        let extracted = extract_matrix(&image, coord, stencil_size);

        assert_eq!(extracted.len(), 3);
        assert_eq!(extracted[0].len(), 3);
        assert_eq!(extracted[0][0], (0.0,0.0,0.0));
        assert_eq!(extracted[0][1], (0.0,0.0,0.0));
        assert_eq!(extracted[1][0], (0.0,0.0,0.0));
        assert_eq!(extracted[1][1], (1.0,3.0,4.0));
        assert_eq!(extracted[2][2], (5.0,6.0,3.0));
    }

    #[test]
    fn matrix_higher_border_extraction() {
        let image: Vec<Vec<(f32, f32, f32)>>= vec!(
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0))
        );

        let stencil: Vec<Vec<f32>> = vec!(
            vec!(1.0,3.0,4.0),
            vec!(1.0,3.0,4.0),
            vec!(1.0,3.0,4.0)
        );
        let stencil_size = (stencil.len(), stencil[0].len());
        let coord = Coordinate(2, 8);
        let extracted = extract_matrix(&image, coord, stencil_size);

        assert_eq!(extracted.len(), 3);
        assert_eq!(extracted[0].len(), 3);
        assert_eq!(extracted[0][0], (5.0, 6.0, 3.0));
        assert_eq!(extracted[0][1], (4.0, 5.0, 6.0));
        assert_eq!(extracted[1][0], (5.0, 6.0, 3.0));
        assert_eq!(extracted[1][1], (4.0, 5.0, 6.0));
        assert_eq!(extracted[2][2], (0.0, 0.0, 0.0));
    }

    #[test]
    fn compute_pixel_test() {
        let image: Vec<Vec<(f32, f32, f32)>>= vec!(
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0)),
            vec!((1.0,3.0,4.0), (5.0,6.0,3.0), (4.0,5.0,6.0))
        );

        let stencil: Vec<Vec<f32>> = vec!(
            vec!(1.0,3.0,4.0),
            vec!(1.0,3.0,4.0),
            vec!(1.0,3.0,4.0)
        );
        let coord = Coordinate(1, 1);
        let pixel_value = compute_pixel(&stencil, coord, &image);

        assert_eq!(pixel_value, (96.0, 123.0, 111.0));
    }

    #[test]
    fn compute_mono_pixel_test() {
        let image: Vec<Vec<(f32, f32, f32)>>= vec!(vec!((1.0,3.0,4.0)));

        let stencil: Vec<Vec<f32>> = vec!(
            vec!(1.0,3.0,4.0),
            vec!(1.0,3.0,4.0),
            vec!(1.0,3.0,4.0)
        );
        let coord = Coordinate(0, 0);
        let pixel_value = compute_pixel(&stencil, coord, &image);

        assert_eq!(pixel_value, (3.0, 9.0, 12.0));
    }
}
<|endoftext|>


<commit_before>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.

use std::mem;

use basic::Type;
use rand::{Rng, Rand};
use util::memory::{ByteBuffer, ByteBufferPtr};

// ----------------------------------------------------------------------
// Types connect Parquet physical types with Rust-specific types

// TODO: alignment?
// TODO: we could also use [u32; 3], however it seems there is no easy way
//   to convert [u32] to [u32; 3] in decoding.
#[derive(Clone, Debug)]
pub struct Int96 {
  value: Option<Vec<u32>>,
}

impl Int96 {
  pub fn new() -> Self {
    Int96 { value: None }
  }

  pub fn data(&self) -> &[u32] {
    assert!(self.value.is_some());
    &self.value.as_ref().unwrap()
  }

  pub fn set_data(&mut self, v: Vec<u32>) {
    assert_eq!(v.len(), 3);
    self.value = Some(v);
  }
}

impl Default for Int96 {
  fn default() -> Self { Int96 { value: None } }
}

impl PartialEq for Int96 {
  fn eq(&self, other: &Int96) -> bool {
    self.data() == other.data()
  }
}

impl From<Vec<u32>> for Int96 {
  fn from(buf: Vec<u32>) -> Int96 {
    assert_eq!(buf.len(), 3);
    Self { value: Some(buf) }
  }
}

impl Rand for Int96 {
  fn rand<R: Rng>(rng: &mut R) -> Self {
    let mut result = Int96::new();
    let mut value = vec!();
    for _ in 0..3 {
      value.push(rng.gen::<u32>());
    }
    result.set_data(value);
    result
  }
}

#[derive(Clone, Debug)]
pub struct ByteArray {
  data: Option<ByteBufferPtr>,
}

impl ByteArray {
  pub fn new() -> Self {
    ByteArray { data: None }
  }

  pub fn len(&self) -> usize {
    assert!(self.data.is_some());
    self.data.as_ref().unwrap().len()
  }

  pub fn data(&self) -> &[u8] {
    assert!(self.data.is_some());
    self.data.as_ref().unwrap().as_ref()
  }

  pub fn set_data(&mut self, data: ByteBufferPtr) {
    self.data = Some(data);
  }
}

impl From<Vec<u8>> for ByteArray {
  fn from(buf: Vec<u8>) -> ByteArray {
    Self { data: Some(ByteBufferPtr::new(buf)) }
  }
}

impl From<ByteBufferPtr> for ByteArray {
  fn from(ptr: ByteBufferPtr) -> ByteArray {
    Self { data: Some(ptr) }
  }
}

impl From<ByteBuffer> for ByteArray {
  fn from(mut buf: ByteBuffer) -> ByteArray {
    Self { data: Some(buf.consume()) }
  }
}

impl Default for ByteArray {
  fn default() -> Self { ByteArray { data: None } }
}

impl PartialEq for ByteArray {
  fn eq(&self, other: &ByteArray) -> bool {
    self.data() == other.data()
  }
}

impl Rand for ByteArray {
  fn rand<R: Rng>(rng: &mut R) -> Self {
    let mut result = ByteArray::new();
    let mut value = vec!();
    let len = rng.gen_range::<usize>(0, 128);
    for _ in 0..len {
      value.push(rng.gen_range(0, 255) & 0xFF);
    }
    result.set_data(ByteBufferPtr::new(value));
    result
  }
}

// ----------------------------------------------------------------------
// AsBytes converts an instance of data type to a slice of u8

pub trait AsBytes {
  fn as_bytes(&self) -> &[u8];
}

impl AsBytes for bool {
  fn as_bytes(&self) -> &[u8] {
    unsafe {
      ::std::slice::from_raw_parts(self as *const bool as *const u8, 1)
    }
  }
}

impl AsBytes for u8 {
  fn as_bytes(&self) -> &[u8] {
    unsafe {
      ::std::slice::from_raw_parts(self as *const u8, 1)
    }
  }
}

impl AsBytes for i32 {
  fn as_bytes(&self) -> &[u8] {
    unsafe {
      ::std::slice::from_raw_parts(self as *const i32 as *const u8, 4)
    }
  }
}

impl AsBytes for u32 {
  fn as_bytes(&self) -> &[u8] {
    unsafe {
      ::std::slice::from_raw_parts(self as *const u32 as *const u8, 4)
    }
  }
}

impl AsBytes for i64 {
  fn as_bytes(&self) -> &[u8] {
    unsafe {
      ::std::slice::from_raw_parts(self as *const i64 as *const u8, 8)
    }
  }
}

impl AsBytes for Int96 {
  fn as_bytes(&self) -> &[u8] {
    unsafe {
      ::std::slice::from_raw_parts(self.data() as *const [u32] as *const u8, 12)
    }
  }
}

impl AsBytes for f32 {
  fn as_bytes(&self) -> &[u8] {
    unsafe {
      ::std::slice::from_raw_parts(self as *const f32 as *const u8, 4)
    }
  }
}

impl AsBytes for f64 {
  fn as_bytes(&self) -> &[u8] {
    unsafe {
      ::std::slice::from_raw_parts(self as *const f64 as *const u8, 8)
    }
  }
}

impl AsBytes for ByteArray {
  fn as_bytes(&self) -> &[u8] {
    self.data()
  }
}

impl AsBytes for Vec<u8> {
  fn as_bytes(&self) -> &[u8] {
    self.as_slice()
  }
}

impl<'a> AsBytes for &'a str {
  fn as_bytes(&self) -> &[u8] {
    (self as &str).as_bytes()
  }
}

impl AsBytes for str {
  fn as_bytes(&self) -> &[u8] {
    (self as &str).as_bytes()
  }
}

// ----------------------------------------------------------------------
// DataType trait, which contains the Parquet physical type info as well as
// the Rust primitive type presentation.

pub trait DataType {
  type T: ::std::cmp::PartialEq + ::std::fmt::Debug + ::std::default::Default
    + ::std::clone::Clone + Rand + AsBytes;
  fn get_physical_type() -> Type;
  fn get_type_size() -> usize;
}

macro_rules! make_type {
  ($name:ident, $physical_ty:path, $native_ty:ty, $size:expr) => {
    pub struct $name {
    }

    impl DataType for $name {
      type T = $native_ty;

      fn get_physical_type() -> Type {
        $physical_ty
      }

      fn get_type_size() -> usize {
        $size
      }
    }
  };
}

/// Generate struct definitions for all physical types

make_type!(BoolType, Type::BOOLEAN, bool, 1);
make_type!(Int32Type, Type::INT32, i32, 4);
make_type!(Int64Type, Type::INT64, i64, 8);
make_type!(Int96Type, Type::INT96, Int96, mem::size_of::<Int96>());
make_type!(FloatType, Type::FLOAT, f32, 4);
make_type!(DoubleType, Type::DOUBLE, f64, 8);
make_type!(ByteArrayType, Type::BYTE_ARRAY, ByteArray, mem::size_of::<ByteArray>());
make_type!(FixedLenByteArrayType, Type::FIXED_LEN_BYTE_ARRAY,
           ByteArray, mem::size_of::<ByteArray>());

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

  #[test]
  fn test_as_bytes() {
    assert_eq!(false.as_bytes(), &[0]);
    assert_eq!(true.as_bytes(), &[1]);
    assert_eq!((7 as i32).as_bytes(), &[7, 0, 0, 0]);
    assert_eq!((555 as i32).as_bytes(), &[43, 2, 0, 0]);
    assert_eq!(i32::max_value().as_bytes(), &[255, 255, 255, 127]);
    assert_eq!(i32::min_value().as_bytes(), &[0, 0, 0, 128]);
    assert_eq!((7 as i64).as_bytes(), &[7, 0, 0, 0, 0, 0, 0, 0]);
    assert_eq!((555 as i64).as_bytes(), &[43, 2, 0, 0, 0, 0, 0, 0]);
    assert_eq!((i64::max_value()).as_bytes(), &[255, 255, 255, 255, 255, 255, 255, 127]);
    assert_eq!((i64::min_value()).as_bytes(), &[0, 0, 0, 0, 0, 0, 0, 128]);
    assert_eq!((3.14 as f32).as_bytes(), &[195, 245, 72, 64]);
    assert_eq!((3.14 as f64).as_bytes(), &[31, 133, 235, 81, 184, 30, 9, 64]);
    assert_eq!("hello".as_bytes(), &[b'h', b'e', b'l', b'l', b'o']);
    assert_eq!(Vec::from("hello".as_bytes()).as_bytes(), &[b'h', b'e', b'l', b'l', b'o']);

    // Test Int96
    let i96 = Int96::from(vec![1, 2, 3]);
    assert_eq!(i96.as_bytes(), &[1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0]);

    // Test ByteArray
    let ba = ByteArray::from(vec![1, 2, 3]);
    assert_eq!(ba.as_bytes(), &[1, 2, 3]);
  }
}
<commit_msg>Use macro to generate AsBytes for primitive types<commit_after>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.

use std::mem;

use basic::Type;
use rand::{Rng, Rand};
use util::memory::{ByteBuffer, ByteBufferPtr};

// ----------------------------------------------------------------------
// Types connect Parquet physical types with Rust-specific types

// TODO: alignment?
// TODO: we could also use [u32; 3], however it seems there is no easy way
//   to convert [u32] to [u32; 3] in decoding.
#[derive(Clone, Debug)]
pub struct Int96 {
  value: Option<Vec<u32>>,
}

impl Int96 {
  pub fn new() -> Self {
    Int96 { value: None }
  }

  pub fn data(&self) -> &[u32] {
    assert!(self.value.is_some());
    &self.value.as_ref().unwrap()
  }

  pub fn set_data(&mut self, v: Vec<u32>) {
    assert_eq!(v.len(), 3);
    self.value = Some(v);
  }
}

impl Default for Int96 {
  fn default() -> Self { Int96 { value: None } }
}

impl PartialEq for Int96 {
  fn eq(&self, other: &Int96) -> bool {
    self.data() == other.data()
  }
}

impl From<Vec<u32>> for Int96 {
  fn from(buf: Vec<u32>) -> Int96 {
    assert_eq!(buf.len(), 3);
    Self { value: Some(buf) }
  }
}

impl Rand for Int96 {
  fn rand<R: Rng>(rng: &mut R) -> Self {
    let mut result = Int96::new();
    let mut value = vec!();
    for _ in 0..3 {
      value.push(rng.gen::<u32>());
    }
    result.set_data(value);
    result
  }
}

#[derive(Clone, Debug)]
pub struct ByteArray {
  data: Option<ByteBufferPtr>,
}

impl ByteArray {
  pub fn new() -> Self {
    ByteArray { data: None }
  }

  pub fn len(&self) -> usize {
    assert!(self.data.is_some());
    self.data.as_ref().unwrap().len()
  }

  pub fn data(&self) -> &[u8] {
    assert!(self.data.is_some());
    self.data.as_ref().unwrap().as_ref()
  }

  pub fn set_data(&mut self, data: ByteBufferPtr) {
    self.data = Some(data);
  }
}

impl From<Vec<u8>> for ByteArray {
  fn from(buf: Vec<u8>) -> ByteArray {
    Self { data: Some(ByteBufferPtr::new(buf)) }
  }
}

impl From<ByteBufferPtr> for ByteArray {
  fn from(ptr: ByteBufferPtr) -> ByteArray {
    Self { data: Some(ptr) }
  }
}

impl From<ByteBuffer> for ByteArray {
  fn from(mut buf: ByteBuffer) -> ByteArray {
    Self { data: Some(buf.consume()) }
  }
}

impl Default for ByteArray {
  fn default() -> Self { ByteArray { data: None } }
}

impl PartialEq for ByteArray {
  fn eq(&self, other: &ByteArray) -> bool {
    self.data() == other.data()
  }
}

impl Rand for ByteArray {
  fn rand<R: Rng>(rng: &mut R) -> Self {
    let mut result = ByteArray::new();
    let mut value = vec!();
    let len = rng.gen_range::<usize>(0, 128);
    for _ in 0..len {
      value.push(rng.gen_range(0, 255) & 0xFF);
    }
    result.set_data(ByteBufferPtr::new(value));
    result
  }
}

// ----------------------------------------------------------------------
// AsBytes converts an instance of data type to a slice of u8

pub trait AsBytes {
  fn as_bytes(&self) -> &[u8];
}

macro_rules! gen_as_bytes {
  ($source_ty:ident) => {
    impl AsBytes for $source_ty {
      fn as_bytes(&self) -> &[u8] {
        unsafe {
          ::std::slice::from_raw_parts(
            self as *const $source_ty as *const u8, ::std::mem::size_of::<$source_ty>())
        }
      }
    }
  };
}

gen_as_bytes!(bool);
gen_as_bytes!(u8);
gen_as_bytes!(i32);
gen_as_bytes!(u32);
gen_as_bytes!(i64);
gen_as_bytes!(f32);
gen_as_bytes!(f64);

impl AsBytes for Int96 {
  fn as_bytes(&self) -> &[u8] {
    unsafe {
      ::std::slice::from_raw_parts(self.data() as *const [u32] as *const u8, 12)
    }
  }
}

impl AsBytes for ByteArray {
  fn as_bytes(&self) -> &[u8] {
    self.data()
  }
}

impl AsBytes for Vec<u8> {
  fn as_bytes(&self) -> &[u8] {
    self.as_slice()
  }
}

impl<'a> AsBytes for &'a str {
  fn as_bytes(&self) -> &[u8] {
    (self as &str).as_bytes()
  }
}

impl AsBytes for str {
  fn as_bytes(&self) -> &[u8] {
    (self as &str).as_bytes()
  }
}

// ----------------------------------------------------------------------
// DataType trait, which contains the Parquet physical type info as well as
// the Rust primitive type presentation.

pub trait DataType {
  type T: ::std::cmp::PartialEq + ::std::fmt::Debug + ::std::default::Default
    + ::std::clone::Clone + Rand + AsBytes;
  fn get_physical_type() -> Type;
  fn get_type_size() -> usize;
}

macro_rules! make_type {
  ($name:ident, $physical_ty:path, $native_ty:ty, $size:expr) => {
    pub struct $name {
    }

    impl DataType for $name {
      type T = $native_ty;

      fn get_physical_type() -> Type {
        $physical_ty
      }

      fn get_type_size() -> usize {
        $size
      }
    }
  };
}

/// Generate struct definitions for all physical types

make_type!(BoolType, Type::BOOLEAN, bool, 1);
make_type!(Int32Type, Type::INT32, i32, 4);
make_type!(Int64Type, Type::INT64, i64, 8);
make_type!(Int96Type, Type::INT96, Int96, mem::size_of::<Int96>());
make_type!(FloatType, Type::FLOAT, f32, 4);
make_type!(DoubleType, Type::DOUBLE, f64, 8);
make_type!(ByteArrayType, Type::BYTE_ARRAY, ByteArray, mem::size_of::<ByteArray>());
make_type!(FixedLenByteArrayType, Type::FIXED_LEN_BYTE_ARRAY,
           ByteArray, mem::size_of::<ByteArray>());

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

  #[test]
  fn test_as_bytes() {
    assert_eq!(false.as_bytes(), &[0]);
    assert_eq!(true.as_bytes(), &[1]);
    assert_eq!((7 as i32).as_bytes(), &[7, 0, 0, 0]);
    assert_eq!((555 as i32).as_bytes(), &[43, 2, 0, 0]);
    assert_eq!((555 as u32).as_bytes(), &[43, 2, 0, 0]);
    assert_eq!(i32::max_value().as_bytes(), &[255, 255, 255, 127]);
    assert_eq!(i32::min_value().as_bytes(), &[0, 0, 0, 128]);
    assert_eq!((7 as i64).as_bytes(), &[7, 0, 0, 0, 0, 0, 0, 0]);
    assert_eq!((555 as i64).as_bytes(), &[43, 2, 0, 0, 0, 0, 0, 0]);
    assert_eq!((i64::max_value()).as_bytes(), &[255, 255, 255, 255, 255, 255, 255, 127]);
    assert_eq!((i64::min_value()).as_bytes(), &[0, 0, 0, 0, 0, 0, 0, 128]);
    assert_eq!((3.14 as f32).as_bytes(), &[195, 245, 72, 64]);
    assert_eq!((3.14 as f64).as_bytes(), &[31, 133, 235, 81, 184, 30, 9, 64]);
    assert_eq!("hello".as_bytes(), &[b'h', b'e', b'l', b'l', b'o']);
    assert_eq!(Vec::from("hello".as_bytes()).as_bytes(), &[b'h', b'e', b'l', b'l', b'o']);

    // Test Int96
    let i96 = Int96::from(vec![1, 2, 3]);
    assert_eq!(i96.as_bytes(), &[1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0]);

    // Test ByteArray
    let ba = ByteArray::from(vec![1, 2, 3]);
    assert_eq!(ba.as_bytes(), &[1, 2, 3]);
  }
}
<|endoftext|>