<commit_before>//#![deny(warnings)]
#[macro_use]
extern crate error_chain;

extern crate svgbob;
extern crate csv;
extern crate comrak;
extern crate typed_arena;
use typed_arena::Arena;
use comrak::{parse_document, format_html, ComrakOptions};
use comrak::nodes::{AstNode, NodeValue, NodeHtmlBlock};
use std::collections::HashMap;
use errors::*;
use svgbob::Grid;
use svgbob::Settings;

mod errors {
    error_chain!{
    }
}

fn build_cells(text: &Vec<Vec<Option<&String>>>) -> String {
    let mut buff = String::new();
    for line in text{
        for l in line{
            match *l{
                Some(ref l) => buff.push_str(&format!("
{}
",l)),
                None => buff.push_str("

"),
            }
        }
    }
    buff
}

fn bob_handler(s: &str) -> Result<String> {
    bob_handler_with_option(s, false)
}

/// convert bob ascii diagrams to svg
fn bob_handler_with_option(s: &str, include_lens: bool) -> Result<String> {
    let now = std::time::SystemTime::now();
    let grid = Grid::from_str(s, &Settings::compact());
    let (width, height) = grid.get_size();
    let svg = grid.get_svg();
    let text = grid.get_all_text();
    let cells = build_cells(&text);
    let content = format!("
{}
",width, height, cells);
    let lens = if include_lens{ format!("
{}
",content) } else { "".to_string() };
    let bob_container = format!("
{}{}
",width, height, svg, lens);
    println!("took bob handler: {:?}", now.elapsed());
    Ok(bob_container)
}

/// convert csv content into html table
fn csv_handler(s: &str) -> Result<String>{
    let now = std::time::SystemTime::now();
    let mut buff = String::new();
    let mut rdr = csv::Reader::from_string(s);
    buff.push_str("
");
    buff.push_str("
");
    for header in rdr.byte_headers(){
        buff.push_str("
");
        for h in header{
            buff.push_str(&format!("{}	", String::from_utf8(h).unwrap_or("".into())));
        }
        buff.push_str("
");
    }
    buff.push_str("
");
    buff.push_str("
");
    buff.push_str("
");
    for record in rdr.byte_records().map(|r| r.unwrap()) {
        buff.push_str("
");
        for r in record{
            buff.push_str(&format!("{}	",String::from_utf8(r).unwrap_or("".into())));
        }
        buff.push_str("
");
    }
    buff.push_str("
");
    buff.push_str("
");
    println!("csv handler took: {:?}", now.elapsed());
    Ok(buff)
}

pub fn parse(arg: &str) -> String{
    let now = std::time::SystemTime::now();
    let mut plugins:HashMap<String, Box<Fn(&str)-> Result<String>>>  = HashMap::new();
    plugins.insert("bob".into(), Box::new(bob_handler));
    plugins.insert("csv".into(), Box::new(csv_handler));
    let html = parse_via_comrak(arg, &plugins);
    println!("sponge down parse took: {:?}", now.elapsed());
    html
}

pub fn parse_bob(arg: &str) -> String{
    bob_handler(arg).unwrap()
}

pub fn parse_csv(arg: &str) -> Result<String> {
    csv_handler(arg)
}

/// Plugin info, format:
/// [<selector>] <plugin_name>[@version][://<URI>]
/// example:
/// #table1 csv://data_file.csv
#[allow(dead_code)]
struct PluginInfo{
    selector: Option<String>,
    plugin_name: String,
    version: Option<String>,
    uri: Option<String>,
}

fn parse_via_comrak(arg: &str, plugins: &HashMap<String, Box<Fn(&str) -> Result<String>>>)->String{

    // The returned nodes are created in the supplied Arena, and are bound by its lifetime.
    let arena = Arena::new();
    let option = ComrakOptions {
        hardbreaks: true,
        github_pre_lang: true,
        width: 0,
        ext_strikethrough: true,
        ext_tagfilter: true,
        ext_table: true,
        ext_autolink: true,
        ext_tasklist: true,
        ext_superscript: false,
    };

    let root = parse_document(
        &arena,
        arg,
        &option);

    fn iter_nodes<'a, F>(node: &'a AstNode<'a>, f: &F)
        where F : Fn(&'a AstNode<'a>) {
        f(node);
        for c in node.children() {
            iter_nodes(c, f);
        }
    }

    iter_nodes(root, &|node| {
        let ref mut value = node.data.borrow_mut().value;
        let new_value = match value{
            &mut NodeValue::CodeBlock(ref codeblock) => {
                match plugins.get(&codeblock.info) {
                    Some(handler) => {
                        match handler(&codeblock.literal){
                            Ok(out) => {
                                NodeValue::HtmlBlock(
                                    NodeHtmlBlock{
                                        literal: out,
                                        block_type: 0
                                    }
                                )
                            },
                            Err(_) => {
                                NodeValue::CodeBlock(codeblock.clone())
                            }
                        }
                    }
                    None => {
                        NodeValue::CodeBlock(codeblock.clone())
                    }
                }
            }
            _ => value.to_owned(),
        };
        *value = new_value;
    });

    let html: String = format_html(root, &ComrakOptions::default());
    html
}
<commit_msg>add settings to enable/disable lens<commit_after>//#![deny(warnings)]
#[macro_use]
extern crate error_chain;

extern crate svgbob;
extern crate csv;
extern crate comrak;
extern crate typed_arena;
use typed_arena::Arena;
use comrak::{parse_document, format_html, ComrakOptions};
use comrak::nodes::{AstNode, NodeValue, NodeHtmlBlock};
use std::collections::HashMap;
use errors::*;
use svgbob::Grid;

mod errors {
    error_chain!{
    }
}

fn build_cells(text: &Vec<Vec<Option<&String>>>) -> String {
    let mut buff = String::new();
    for line in text{
        for l in line{
            match *l{
                Some(ref l) => buff.push_str(&format!("
{}
",l)),
                None => buff.push_str("

"),
            }
        }
    }
    buff
}

/// convert bob ascii diagrams to svg
fn bob_handler(s: &str, settings: &Settings) -> Result<String> {
    let now = std::time::SystemTime::now();
    let grid = Grid::from_str(s, &svgbob::Settings::compact());
    let (width, height) = grid.get_size();
    let svg = grid.get_svg();
    let text = grid.get_all_text();
    let cells = build_cells(&text);
    let content = format!("
{}
",width, height, cells);
    let lens = if settings.enable_lens{ format!("
{}
",content) } else { "".to_string() };
    let bob_container = format!("
{}{}
",width, height, svg, lens);
    println!("took bob handler: {:?}", now.elapsed());
    Ok(bob_container)
}

/// convert csv content into html table
fn csv_handler(s: &str, settings: &Settings) -> Result<String>{
    let now = std::time::SystemTime::now();
    let mut buff = String::new();
    let mut rdr = csv::Reader::from_string(s);
    buff.push_str("
");
    buff.push_str("
");
    for header in rdr.byte_headers(){
        buff.push_str("
");
        for h in header{
            buff.push_str(&format!("{}	", String::from_utf8(h).unwrap_or("".into())));
        }
        buff.push_str("
");
    }
    buff.push_str("
");
    buff.push_str("
");
    buff.push_str("
");
    for record in rdr.byte_records().map(|r| r.unwrap()) {
        buff.push_str("
");
        for r in record{
            buff.push_str(&format!("{}	",String::from_utf8(r).unwrap_or("".into())));
        }
        buff.push_str("
");
    }
    buff.push_str("
");
    buff.push_str("
");
    println!("csv handler took: {:?}", now.elapsed());
    Ok(buff)
}

pub struct Settings{
    enable_lens: bool,
}

impl Default for Settings{

    fn default() -> Self {
        Settings{
            enable_lens: false
        }
    }
}

pub fn parse(arg: &str) -> String {
    parse_with_settings(arg, &Settings::default())
}

pub fn parse_include_lens(arg: &str) -> String {
    parse_with_settings(arg, &Settings{enable_lens: true})
}

pub fn parse_with_settings(arg: &str, settings: &Settings) -> String{
    let now = std::time::SystemTime::now();
    let mut plugins:HashMap<String, Box<Fn(&str, &Settings)-> Result<String>>>  = HashMap::new();
    plugins.insert("bob".into(), Box::new(bob_handler));
    plugins.insert("csv".into(), Box::new(csv_handler));
    let html = parse_via_comrak(arg, &plugins, settings);
    println!("sponge down parse took: {:?}", now.elapsed());
    html
}

pub fn parse_bob(arg: &str) -> String{
    bob_handler(arg, &Settings::default()).unwrap()
}

pub fn parse_csv(arg: &str) -> Result<String> {
    csv_handler(arg, &Settings::default())
}

/// Plugin info, format:
/// [<selector>] <plugin_name>[@version][://<URI>]
/// example:
/// #table1 csv://data_file.csv
#[allow(dead_code)]
struct PluginInfo{
    selector: Option<String>,
    plugin_name: String,
    version: Option<String>,
    uri: Option<String>,
}

fn parse_via_comrak(arg: &str, plugins: &HashMap<String, Box<Fn(&str, &Settings) -> Result<String>>>, settings: &Settings)->String{

    // The returned nodes are created in the supplied Arena, and are bound by its lifetime.
    let arena = Arena::new();
    let option = ComrakOptions {
        hardbreaks: true,
        github_pre_lang: true,
        width: 0,
        ext_strikethrough: true,
        ext_tagfilter: true,
        ext_table: true,
        ext_autolink: true,
        ext_tasklist: true,
        ext_superscript: false,
    };

    let root = parse_document(
        &arena,
        arg,
        &option);

    fn iter_nodes<'a, F>(node: &'a AstNode<'a>, f: &F)
        where F : Fn(&'a AstNode<'a>) {
        f(node);
        for c in node.children() {
            iter_nodes(c, f);
        }
    }

    iter_nodes(root, &|node| {
        let ref mut value = node.data.borrow_mut().value;
        let new_value = match value{
            &mut NodeValue::CodeBlock(ref codeblock) => {
                match plugins.get(&codeblock.info) {
                    Some(handler) => {
                        match handler(&codeblock.literal, settings){
                            Ok(out) => {
                                NodeValue::HtmlBlock(
                                    NodeHtmlBlock{
                                        literal: out,
                                        block_type: 0
                                    }
                                )
                            },
                            Err(_) => {
                                NodeValue::CodeBlock(codeblock.clone())
                            }
                        }
                    }
                    None => {
                        NodeValue::CodeBlock(codeblock.clone())
                    }
                }
            }
            _ => value.to_owned(),
        };
        *value = new_value;
    });

    let html: String = format_html(root, &ComrakOptions::default());
    html
}
<|endoftext|>


<commit_before>#![warn(missing_docs)]

//! A stream based HTML5 templating system with code side logic.
//!
//! Everything about this crate is **experimental**.
//!
//! This library allows transforming a HTML5 stream with an iterator-like interface. It was
//! inspired by [`HTML::Zoom`](https://metacpan.org/release/HTML-Zoom).
//!
//! Since this library is intended for templating, the HTML5 parser is rather simple and
//! certainly lacking in some areas. Verification of input and output markup structure only
//! happens when necessary for transformations.
//!
//! # Templates
//!
//! Templates are sequences of events stored in a vector. The `transform` method of a template
//! can be used to generate a newly transformed template. See the `Api` type below for
//! information on available transform mechanisms.
//!
//! # Example
//!
//! ```
//! # use std::error;
//! # fn example() -> Result<(), Box<error::Error>> {
//! use html5_fuser::{ Template, ParseOptions };
//!
//! let template = Template::from_str(r#"
//!     <html>
//!         <head><title>Template Title</title></head>
//!         <body>
//!             <ul id="items">
//!                 <li class="item"/>
//!             </ul>
//!         </body>
//!     </html>
//! "#, ParseOptions::default())?;
//!
//! let transformed = template.transform(|html| html
//!     .select("title", |html| html.replace_contents("New Title"))
//!     .select("#items", |html| html
//!         .repeat(2..5, |html, value| html
//!             .replace_contents(format!("Item {}", value))
//!         )
//!     )
//! )?;
//!
//! println!("{}", transformed);
//! # Ok(())
//! # }
//! # fn main() { example().unwrap() }
//! ```
//!
extern crate tendril;

#[cfg(test)]
macro_rules! test_transform {
    ($options:expr, $input:expr, $expected:expr, $transform:expr $(,)*) => {{
        let template = ::Template::from_str($input, $options).unwrap();
        let modified = template.transform($transform).unwrap();
        let rendered = format!("{}", &modified);
        assert_eq!(rendered, $expected);
        modified
    }}
}

#[cfg(test)]
macro_rules! test_stream_error {
    ($options:expr, $input:expr, $expected:pat, $transform:expr $(,)*) => {{
        let template = ::Template::from_str($input, $options).unwrap();
        let result = template.transform($transform);
        if let Err($expected) = result {
        } else {
            panic!("invalid result: {:?}", result);
        }
    }}
}

mod input;
pub mod content;
pub mod builder;
pub mod location;
pub mod template;
pub mod event;
pub mod text;
pub mod select;
pub mod transform;
pub mod modifier;
pub mod parse;

pub use event::{
    Stream,
    StreamError,
    ElementStream,
};

pub use template::{
    Template,
};

pub use parse::{
    Options as ParseOptions,
};

pub use transform::{
    Api,
    BoxedApi,
    BoxedElementApi,
};
<commit_msg>new test structure<commit_after>#![warn(missing_docs)]

//! A stream based HTML5 templating system with code side logic.
//!
//! Everything about this crate is **experimental**.
//!
//! This library allows transforming a HTML5 stream with an iterator-like interface. It was
//! inspired by [`HTML::Zoom`](https://metacpan.org/release/HTML-Zoom).
//!
//! Since this library is intended for templating, the HTML5 parser is rather simple and
//! certainly lacking in some areas. Verification of input and output markup structure only
//! happens when necessary for transformations.
//!
//! # Templates
//!
//! Templates are sequences of events stored in a vector. The `transform` method of a template
//! can be used to generate a newly transformed template. See the `Api` type below for
//! information on available transform mechanisms.
//!
//! # Example
//!
//! ```
//! # use std::error;
//! # fn example() -> Result<(), Box<error::Error>> {
//! use html5_fuser::{ Template, ParseOptions };
//!
//! let template = Template::from_str(r#"
//!     <html>
//!         <head><title>Template Title</title></head>
//!         <body>
//!             <ul id="items">
//!                 <li class="item"/>
//!             </ul>
//!         </body>
//!     </html>
//! "#, ParseOptions::default())?;
//!
//! let transformed = template.transform(|html| html
//!     .select("title", |html| html.replace_contents("New Title"))
//!     .select("#items", |html| html
//!         .repeat(2..5, |html, value| html
//!             .replace_contents(format!("Item {}", value))
//!         )
//!     )
//! )?;
//!
//! println!("{}", transformed);
//! # Ok(())
//! # }
//! # fn main() { example().unwrap() }
//! ```
//!
extern crate tendril;

#[cfg(test)]
macro_rules! test_group {
    ($name:ident: $( $title:expr => $test:expr ),* $(,)*) => {
        #[test]
        fn $name() {
            use std::panic;
            $(
                panic::catch_unwind(|| $test)
                .expect(&format!("Failed test case: {}", $title));
            )*
        }
    }
}

#[cfg(test)]
macro_rules! transform_test {
    ($input:expr, $expected:expr, $transform:expr $(,)*) => {
        {
            let template = ::Template::from_str($input, Default::default()).unwrap();
            let modified = template.transform($transform).unwrap();
            let rendered = format!("{}", &modified);
            assert_eq!(rendered, $expected);
        }
    }
}

#[cfg(test)]
macro_rules! test_transform {
    ($options:expr, $input:expr, $expected:expr, $transform:expr $(,)*) => {{
        let template = ::Template::from_str($input, $options).unwrap();
        let modified = template.transform($transform).unwrap();
        let rendered = format!("{}", &modified);
        assert_eq!(rendered, $expected);
        modified
    }}
}

#[cfg(test)]
macro_rules! test_stream_error {
    ($options:expr, $input:expr, $expected:pat, $transform:expr $(,)*) => {{
        let template = ::Template::from_str($input, $options).unwrap();
        let result = template.transform($transform);
        if let Err($expected) = result {
        } else {
            panic!("invalid result: {:?}", result);
        }
    }}
}

mod input;
pub mod content;
pub mod builder;
pub mod location;
pub mod template;
pub mod event;
pub mod text;
pub mod select;
pub mod transform;
pub mod modifier;
pub mod parse;

pub use event::{
    Stream,
    StreamError,
    ElementStream,
};

pub use template::{
    Template,
};

pub use parse::{
    Options as ParseOptions,
};

pub use transform::{
    Api,
    BoxedApi,
    BoxedElementApi,
};
<|endoftext|>


<commit_before>#![crate_name = "shader_version"]
#![deny(missing_doc)]

//! A helper library for detecting and picking compatible shaders.

/// Models knowledge about version range.
pub enum VersionRange<T> {
    /// The version range is working from a version,
    /// up to but not included another version.
    ///
    /// With other words, from first time it works until it breaks.
    VersionFromTo(T, T),
    /// The version range is working from a version,
    /// and possibly for all newer versions unless
    /// the context it is used implies otherwise.
    VersionFrom(T)
}

#[allow(non_camel_case_types)]
#[allow(missing_doc)]
pub enum OpenGL {
    OpenGL_2_0,
    OpenGL_2_1,
    OpenGL_3_0,
    OpenGL_3_1,
    OpenGL_3_2,
    OpenGL_3_3,
    OpenGL_4_0,
    OpenGL_4_1,
    OpenGL_4_2,
    OpenGL_4_3,
    OpenGL_4_4
}

/// For OpenGL version 3.3 and above,
/// the GLSL version is the same as the OpenGL version.
///
/// Source: http://www.opengl.org/wiki/Core_Language_%28GLSL%29
#[allow(missing_doc)]
#[allow(non_camel_case_types)]
pub enum GLSL {
    GLSL_1_10,
    GLSL_1_20,
    GLSL_1_30,
    GLSL_1_40,
    GLSL_1_50,
    GLSL_3_30,
    GLSL_4_00,
    GLSL_4_10,
    GLSL_4_20,
    GLSL_4_30,
    GLSL_4_40
}
<commit_msg>Added method that gets GLSL version from OpenGL<commit_after>#![crate_name = "shader_version"]
#![deny(missing_doc)]

//! A helper library for detecting and picking compatible shaders.

/// Models knowledge about version range.
pub enum VersionRange<T> {
    /// The version range is working from a version,
    /// up to but not included another version.
    ///
    /// With other words, from first time it works until it breaks.
    VersionFromTo(T, T),
    /// The version range is working from a version,
    /// and possibly for all newer versions unless
    /// the context it is used implies otherwise.
    VersionFrom(T)
}

#[allow(non_camel_case_types)]
#[allow(missing_doc)]
pub enum OpenGL {
    OpenGL_2_0,
    OpenGL_2_1,
    OpenGL_3_0,
    OpenGL_3_1,
    OpenGL_3_2,
    OpenGL_3_3,
    OpenGL_4_0,
    OpenGL_4_1,
    OpenGL_4_2,
    OpenGL_4_3,
    OpenGL_4_4
}

/// For OpenGL version 3.3 and above,
/// the GLSL version is the same as the OpenGL version.
///
/// Source: http://www.opengl.org/wiki/Core_Language_%28GLSL%29
#[allow(missing_doc)]
#[allow(non_camel_case_types)]
pub enum GLSL {
    GLSL_1_10,
    GLSL_1_20,
    GLSL_1_30,
    GLSL_1_40,
    GLSL_1_50,
    GLSL_3_30,
    GLSL_4_00,
    GLSL_4_10,
    GLSL_4_20,
    GLSL_4_30,
    GLSL_4_40
}

impl OpenGL {
    /// Gets GLSL version associated with OpenGL.
    #[allow(non_snake_case_functions)]
    pub fn to_GLSL(&self) -> GLSL {
        match *self {
            OpenGL_2_0 => GLSL_1_10,
            OpenGL_2_1 => GLSL_1_20,
            OpenGL_3_0 => GLSL_1_30,
            OpenGL_3_1 => GLSL_1_40,
            OpenGL_3_2 => GLSL_1_50,
            OpenGL_3_3 => GLSL_3_30,
            OpenGL_4_0 => GLSL_4_00,
            OpenGL_4_1 => GLSL_4_10,
            OpenGL_4_2 => GLSL_4_20,
            OpenGL_4_3 => GLSL_4_30,
            OpenGL_4_4 => GLSL_4_40,
        }
    }
}

<|endoftext|>


<commit_before>//! Furry Fiesta is a library for poker.
//! It's mostly meant for Holdem games, however the core functionality
//! should work for all game types.
//!
//! # Implemented:
//! Currently Furry Fiesta supports:
//!
//! * Hand Iteration.
//! * Hand Ranking.
//! * Hand Range parsing.
//! * Hand Range generation.
//!
//! # Planned:
//! * Holdem Game State.
//! * Multi-threading
//!
extern crate rand;

/// Allow all the core poker functionality to be used
/// externally. Everything in core should be agnostic
/// to poker style.
pub mod core;
/// The holdem specific code. This contains range
/// parsing, game state, and starting hand code.
pub mod holdem;
<commit_msg>Remove the old name<commit_after>//! RS-Poker is a library for poker.
//! It's mostly meant for Holdem games, however the core functionality
//! should work for all game types.
//!
//! # Implemented:
//! Currently RS-Poker supports:
//!
//! * Hand Iteration.
//! * Hand Ranking.
//! * Hand Range parsing.
//! * Hand Range generation.
//!
//! # Planned:
//! * Holdem Game State.
//! * Multi-threading
//!
extern crate rand;

/// Allow all the core poker functionality to be used
/// externally. Everything in core should be agnostic
/// to poker style.
pub mod core;
/// The holdem specific code. This contains range
/// parsing, game state, and starting hand code.
pub mod holdem;
<|endoftext|>


<commit_before>//! The `ipnetwork` crate provides a set of APIs to work with IP CIDRs in
//! Rust. Implementation for IPv4 is more or less stable, IPv6 implementation
//! is still WIP.
#![cfg_attr(feature = "dev", feature(plugin))]
#![cfg_attr(feature = "dev", plugin(clippy))]
#![crate_type = "lib"]

use std::net::IpAddr;

mod ipv4;
mod ipv6;
mod common;

pub use ipv4::{Ipv4Network, ipv4_mask_to_prefix};
pub use ipv6::{Ipv6Network, ipv6_mask_to_prefix};
pub use common::IpNetworkError;

/// Represents a generic network range. This type can have two variants:
/// the v4 and the v6 case.
#[derive(Debug,Clone,Copy,Hash,PartialEq,Eq)]
pub enum IpNetwork {
    V4(Ipv4Network),
    V6(Ipv6Network),
}

impl IpNetwork {
    /// Constructs a new `IpNetwork` from a given `IpAddr` and a prefix denoting the
    /// network size. If the prefix is larger than 32 (for IPv4) or 128 (for IPv6), this
    /// will raise an `IpNetworkError::InvalidPrefix` error. Support for IPv6 is not
    /// complete yet.
    pub fn new(ip: IpAddr, prefix: u8) -> Result<IpNetwork, IpNetworkError> {
        match ip {
            IpAddr::V4(a) => Ok(IpNetwork::V4(Ipv4Network::new(a, prefix)?)),
            IpAddr::V6(a) => Ok(IpNetwork::V6(Ipv6Network::new(a, prefix)?)),
        }
    }

    /// Returns the IP part of a given `IpNetwork`
    ///
    /// # Example
    /// ```
    /// use std::net::{Ipv4Addr, Ipv6Addr};
    /// use ipnetwork::IpNetwork;
    ///
    /// assert_eq!(IpNetwork::V4("10.9.0.32/16".parse().unwrap()).ip(), "10.9.0.32".parse().unwrap());
    /// assert_eq!(IpNetwork::V6("ff01::0/32".parse().unwrap()).ip(), "ff01::0".parse().unwrap());
    /// ```
    pub fn ip(&self) -> IpAddr {
        match *self {
            IpNetwork::V4(ref a) => IpAddr::V4(a.ip()),
            IpNetwork::V6(ref a) => IpAddr::V6(a.ip()),
        }
    }

    /// Returns the prefix of the given `IpNetwork`
    ///
    /// # Example
    /// ```
    /// use ipnetwork::IpNetwork;
    ///
    /// assert_eq!(IpNetwork::V4("10.9.0.32/16".parse().unwrap()).prefix(), 16u8);
    /// assert_eq!(IpNetwork::V6("ff01::0/32".parse().unwrap()).prefix(), 32u8);
    /// ```
    pub fn prefix(&self) -> u8 {
        match *self {
            IpNetwork::V4(ref a) => a.prefix(),
            IpNetwork::V6(ref a) => a.prefix(),
        }
    }

    /// Returns the mask of the given `IpNetwork`
    ///
    /// # Example
    /// ```
    /// use ipnetwork::IpNetwork;
    ///
    /// assert_eq!(IpNetwork::V4("10.9.0.32/16".parse().unwrap()).mask(), 16u8);
    /// assert_eq!(IpNetwork::V6("ff01::0/32".parse().unwrap()).mask(), 32u8);
    ///```
    pub fn mask(&self) -> IpAddr {
        match *self {
            IpNetwork::V4(ref a) => IpAddr::V4(a.mask()),
            IpNetwork::V6(ref a) => IpAddr::V6(a.mask()),
        }
    }
}

impl From<Ipv4Network> for IpNetwork {
    fn from(v4: Ipv4Network) -> IpNetwork {
        IpNetwork::V4(v4)
    }
}

impl From<Ipv6Network> for IpNetwork {
    fn from(v6: Ipv6Network) -> IpNetwork {
        IpNetwork::V6(v6)
    }
}

/// Converts a `IpAddr` network mask into a prefix.
/// If the mask is invalid this will return an `IpNetworkError::InvalidPrefix`.
pub fn ip_mask_to_prefix(mask: IpAddr) -> Result<u8, IpNetworkError> {
    match mask {
        IpAddr::V4(mask) => ipv4_mask_to_prefix(mask),
        IpAddr::V6(mask) => ipv6_mask_to_prefix(mask),
    }
}
<commit_msg>Add two methods to check IP version<commit_after>//! The `ipnetwork` crate provides a set of APIs to work with IP CIDRs in
//! Rust. Implementation for IPv4 is more or less stable, IPv6 implementation
//! is still WIP.
#![cfg_attr(feature = "dev", feature(plugin))]
#![cfg_attr(feature = "dev", plugin(clippy))]
#![crate_type = "lib"]

use std::net::IpAddr;

mod ipv4;
mod ipv6;
mod common;

pub use ipv4::{Ipv4Network, ipv4_mask_to_prefix};
pub use ipv6::{Ipv6Network, ipv6_mask_to_prefix};
pub use common::IpNetworkError;

/// Represents a generic network range. This type can have two variants:
/// the v4 and the v6 case.
#[derive(Debug,Clone,Copy,Hash,PartialEq,Eq)]
pub enum IpNetwork {
    V4(Ipv4Network),
    V6(Ipv6Network),
}

impl IpNetwork {
    /// Constructs a new `IpNetwork` from a given `IpAddr` and a prefix denoting the
    /// network size. If the prefix is larger than 32 (for IPv4) or 128 (for IPv6), this
    /// will raise an `IpNetworkError::InvalidPrefix` error. Support for IPv6 is not
    /// complete yet.
    pub fn new(ip: IpAddr, prefix: u8) -> Result<IpNetwork, IpNetworkError> {
        match ip {
            IpAddr::V4(a) => Ok(IpNetwork::V4(Ipv4Network::new(a, prefix)?)),
            IpAddr::V6(a) => Ok(IpNetwork::V6(Ipv6Network::new(a, prefix)?)),
        }
    }

    /// Returns the IP part of a given `IpNetwork`
    ///
    /// # Example
    /// ```
    /// use std::net::{Ipv4Addr, Ipv6Addr};
    /// use ipnetwork::IpNetwork;
    ///
    /// assert_eq!(IpNetwork::V4("10.9.0.32/16".parse().unwrap()).ip(), "10.9.0.32".parse().unwrap());
    /// assert_eq!(IpNetwork::V6("ff01::0/32".parse().unwrap()).ip(), "ff01::0".parse().unwrap());
    /// ```
    pub fn ip(&self) -> IpAddr {
        match *self {
            IpNetwork::V4(ref a) => IpAddr::V4(a.ip()),
            IpNetwork::V6(ref a) => IpAddr::V6(a.ip()),
        }
    }

    /// Returns the prefix of the given `IpNetwork`
    ///
    /// # Example
    /// ```
    /// use ipnetwork::IpNetwork;
    ///
    /// assert_eq!(IpNetwork::V4("10.9.0.32/16".parse().unwrap()).prefix(), 16u8);
    /// assert_eq!(IpNetwork::V6("ff01::0/32".parse().unwrap()).prefix(), 32u8);
    /// ```
    pub fn prefix(&self) -> u8 {
        match *self {
            IpNetwork::V4(ref a) => a.prefix(),
            IpNetwork::V6(ref a) => a.prefix(),
        }
    }

    /// Returns the mask of the given `IpNetwork`
    ///
    /// # Example
    /// ```
    /// use ipnetwork::IpNetwork;
    ///
    /// assert_eq!(IpNetwork::V4("10.9.0.32/16".parse().unwrap()).mask(), 16u8);
    /// assert_eq!(IpNetwork::V6("ff01::0/32".parse().unwrap()).mask(), 32u8);
    ///```
    pub fn mask(&self) -> IpAddr {
        match *self {
            IpNetwork::V4(ref a) => IpAddr::V4(a.mask()),
            IpNetwork::V6(ref a) => IpAddr::V6(a.mask()),
        }
    }

    /// Returns true if the IP in this `IpNetwork` is a valid IPv4 address,
    /// false if it's a valid IPv6 address.
    ///
    /// # Example
    ///
    ///```
    /// use ipnetwork::IpNetwork;
    ///
    /// let v4: IpNetwork = IpNetwork::V4("10.9.0.32/16".parse().unwrap());
    /// assert_eq!(v4.is_ipv4(), true);
    /// assert_eq!(v4.is_ipv6(), false);
    ///```
    pub fn is_ipv4(&self) -> bool {
        match *self {
            IpNetwork::V4(_) => true,
            IpNetwork::V6(_) => false,
        }
    }

    /// Returns true if the IP in this `IpNetwork` is a valid IPv6 address,
    /// false if it's a valid IPv4 address.
    ///
    /// # Example
    ///
    ///```
    /// use ipnetwork::IpNetwork;
    ///
    /// let v6: IpNetwork = IpNetwork::V6("ff01::0/32".parse().unwrap());
    /// assert_eq!(v6.is_ipv6(), true);
    /// assert_eq!(v6.is_ipv4(), false);
    ///```
    pub fn is_ipv6(&self) -> bool {
        match *self {
            IpNetwork::V4(_) => false,
            IpNetwork::V6(_) => true,
        }
    }
}

impl From<Ipv4Network> for IpNetwork {
    fn from(v4: Ipv4Network) -> IpNetwork {
        IpNetwork::V4(v4)
    }
}

impl From<Ipv6Network> for IpNetwork {
    fn from(v6: Ipv6Network) -> IpNetwork {
        IpNetwork::V6(v6)
    }
}

/// Converts a `IpAddr` network mask into a prefix.
/// If the mask is invalid this will return an `IpNetworkError::InvalidPrefix`.
pub fn ip_mask_to_prefix(mask: IpAddr) -> Result<u8, IpNetworkError> {
    match mask {
        IpAddr::V4(mask) => ipv4_mask_to_prefix(mask),
        IpAddr::V6(mask) => ipv6_mask_to_prefix(mask),
    }
}
<|endoftext|>


<commit_before>//! `icndb` provides a simple interface to `api.icndb.com` and is
//! designed especially for use with `fun`. Extracting this functionality
//! into a library grants us greater flexibility with regard to our
//! base application and will permit a large number of improvements
//! in the future.
//!
//! ** Examples should go here. **

#![feature(box_syntax, io, plugin)]

extern crate hyper;
extern crate "rustc-serialize" as rustc_serialize;

use hyper::Client;
use rustc_serialize::json;
use std::io::Read;

/// Wraps an API response from the `api.icndb.com`. The authors'
/// intent appears to have been to provide an interface for both
/// failed and successful requests, but it has been difficult to
/// represent the full wrapper in Rust, and the wrapper adds no
/// real value.
#[derive(RustcDecodable, RustcEncodable)]
struct ApiResponseWrapper {
    // type: String, // terrible field name
    value: ApiResponse,
}

/// Represents a single joke provided by the ICNDB. The `id` field
/// uniquely identifies this specific joke, which allows the user
/// to get this joke again at a later time if he or she so desires.
#[derive(RustcDecodable, RustcEncodable)]
pub struct ApiResponse {
    pub id: u64,
    pub joke: String,
    pub categories: Box<[String]>
}

/// Returns an option value containing a random joke from the API
/// or, failing that, None.
pub fn next() -> Option<ApiResponse> {
    unwrap_response(execute_request("http://api.icndb.com/jokes/random"))
}

/// Returns an option value containing a random joke from the API
/// using the names supplied to the function instead of the default
/// name (Chuck Norris) or, failing that, None.
pub fn next_with_names(first: &str, last: &str) -> Option<ApiResponse> {
    unwrap_response(execute_request(&format!("http://api.icndb.com/jokes/random?firstName={}&lastName={}", first, last)))
}

/// Returns an option value containing a specified joke from the API
/// or, failing that, None.
pub fn get_by_id(id: u64) -> Option<ApiResponse> {
    unwrap_response(execute_request(&format!("http://api.icndb.com/jokes/{}", id)))
}

/// Returns an option value containing a specified joke from the API
/// using the names supplied to the function instead of the default
/// name (Chuck Norris) or, failing that, None.
pub fn get_by_id_with_names(id: u64, first: &str, last: &str) -> Option<ApiResponse> {
    unwrap_response(
        execute_request(
            &format!(
                "http://api.icndb.com/jokes/{}?firstName={}&lastName={}",
                id,
                first,
                last)))
}

/// Parses the response returned by a query against the ICNDB API
/// into an ApiResponse or, failing that, None.
fn unwrap_response(response: Option<String>) -> Option<ApiResponse> {
    let raw_response = match response {
        Some(response) => response,
        None => return None,
    };

    match json::decode::<ApiResponseWrapper>(&raw_response) {
        Ok(result) => unescape_content(result.value),
        _ => None
    }
}

/// Unescape HTML entities found in joke contents.
///
/// The ICNDB represents some values as HTML entities in the json
/// packets returned to the caller and rustc_deserialize does not
/// unescape these entities upon deserializing the json packet.
/// This function deals with that by taking the (potentially) escaped
/// values and unescaping any HTML entities contained therein before
/// returning a new ApiResponse struct containing the unescaped
/// values.
///
/// ** Entities handled include: **
/// - "
///
/// Hopefully we won't discover anymore.
fn unescape_content(response: ApiResponse) -> Option<ApiResponse> {
    if response.joke.contains(""") {
        Some(ApiResponse {
            id: response.id,
            joke: response.joke.replace(""", "\""),
            categories: response.categories
        })
    } else {
        Some(response)
    }
}

/// Executes an arbitrary request against the ICNDB API.
fn execute_request(request: &str) -> Option<String> {
    let mut client = Client::new();
    let mut response = match client.get(request).send() {
        Ok(res) => res,
        _ => return None
    };

    let mut content = String::new();
    match response.read_to_string(&mut content) {
       Ok(()) => Some(content),
        _ => None
    }
}

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

    #[test]
    fn next_works() {
        assert!(next().is_some());
    }

    #[test]
    fn next_with_names_works() {
        assert!(next_with_names("John", "Archer").is_some());
    }

    #[test]
    fn get_by_id_works() {
        assert!(get_by_id(13).is_some());
    }

    #[test]
    fn get_by_id_with_names_works() {
        assert!(get_by_id_with_names(13, "John", "Archer").is_some());
    }
}
<commit_msg>Remove tests requiring connection to an external API.<commit_after>//! `icndb` provides a simple interface to `api.icndb.com` and is
//! designed especially for use with `fun`. Extracting this functionality
//! into a library grants us greater flexibility with regard to our
//! base application and will permit a large number of improvements
//! in the future.
//!
//! ** Examples should go here. **

#![feature(box_syntax, io, plugin)]

extern crate hyper;
extern crate "rustc-serialize" as rustc_serialize;

use hyper::Client;
use rustc_serialize::json;
use std::io::Read;

/// Wraps an API response from the `api.icndb.com`. The authors'
/// intent appears to have been to provide an interface for both
/// failed and successful requests, but it has been difficult to
/// represent the full wrapper in Rust, and the wrapper adds no
/// real value.
#[derive(RustcDecodable, RustcEncodable)]
struct ApiResponseWrapper {
    // type: String, // terrible field name
    value: ApiResponse,
}

/// Represents a single joke provided by the ICNDB. The `id` field
/// uniquely identifies this specific joke, which allows the user
/// to get this joke again at a later time if he or she so desires.
#[derive(RustcDecodable, RustcEncodable)]
pub struct ApiResponse {
    pub id: u64,
    pub joke: String,
    pub categories: Box<[String]>
}

/// Returns an option value containing a random joke from the API
/// or, failing that, None.
pub fn next() -> Option<ApiResponse> {
    unwrap_response(execute_request("http://api.icndb.com/jokes/random"))
}

/// Returns an option value containing a random joke from the API
/// using the names supplied to the function instead of the default
/// name (Chuck Norris) or, failing that, None.
pub fn next_with_names(first: &str, last: &str) -> Option<ApiResponse> {
    unwrap_response(execute_request(&format!("http://api.icndb.com/jokes/random?firstName={}&lastName={}", first, last)))
}

/// Returns an option value containing a specified joke from the API
/// or, failing that, None.
pub fn get_by_id(id: u64) -> Option<ApiResponse> {
    unwrap_response(execute_request(&format!("http://api.icndb.com/jokes/{}", id)))
}

/// Returns an option value containing a specified joke from the API
/// using the names supplied to the function instead of the default
/// name (Chuck Norris) or, failing that, None.
pub fn get_by_id_with_names(id: u64, first: &str, last: &str) -> Option<ApiResponse> {
    unwrap_response(
        execute_request(
            &format!(
                "http://api.icndb.com/jokes/{}?firstName={}&lastName={}",
                id,
                first,
                last)))
}

/// Parses the response returned by a query against the ICNDB API
/// into an ApiResponse or, failing that, None.
fn unwrap_response(response: Option<String>) -> Option<ApiResponse> {
    let raw_response = match response {
        Some(response) => response,
        None => return None,
    };

    match json::decode::<ApiResponseWrapper>(&raw_response) {
        Ok(result) => unescape_content(result.value),
        _ => None
    }
}

/// Unescape HTML entities found in joke contents.
///
/// The ICNDB represents some values as HTML entities in the json
/// packets returned to the caller and rustc_deserialize does not
/// unescape these entities upon deserializing the json packet.
/// This function deals with that by taking the (potentially) escaped
/// values and unescaping any HTML entities contained therein before
/// returning a new ApiResponse struct containing the unescaped
/// values.
///
/// ** Entities handled include: **
/// - "
///
/// Hopefully we won't discover anymore.
fn unescape_content(response: ApiResponse) -> Option<ApiResponse> {
    if response.joke.contains(""") {
        Some(ApiResponse {
            id: response.id,
            joke: response.joke.replace(""", "\""),
            categories: response.categories
        })
    } else {
        Some(response)
    }
}

/// Executes an arbitrary request against the ICNDB API.
fn execute_request(request: &str) -> Option<String> {
    let mut client = Client::new();
    let mut response = match client.get(request).send() {
        Ok(res) => res,
        _ => return None
    };

    let mut content = String::new();
    match response.read_to_string(&mut content) {
       Ok(()) => Some(content),
        _ => None
    }
}
<|endoftext|>


<commit_before>#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub enum Param {
    Short(char),
    Long(String),
}

#[derive(Clone, Debug, Eq, PartialEq, Hash)]
enum Value {
    Flag(bool),
    Opt(Option<String>),
}

pub trait IntoParam {
    fn into_param(self) -> Param;
}

impl IntoParam for &'static str {
    fn into_param(self) -> Param {
        Param::Long(self.to_owned())
    }
}

impl IntoParam for char {
    fn into_param(self) -> Param {
        Param::Short(self)
    }
}

use std::collections::HashMap;

/// Our homebrewed Arg Parser
#[derive(Clone, Debug, Default)]
pub struct ArgParser {
    params: HashMap<Param, Value>,
    pub args: Vec<String>,
}

impl ArgParser {
    /// Create a new ArgParser object
    pub fn new(capacity: usize) -> Self {
        ArgParser {
            params: HashMap::with_capacity(capacity),
            args: Vec::new(),
        }
    }

    /// Builder method for adding both short and long flags
    pub fn add_flag(mut self, short: &str, long: &str) -> Self {
        if let Some(short) = short.chars().next() {
            self.params.insert(Param::Short(short), Value::Flag(false));
        }
        if !long.is_empty() {
            self.params.insert(Param::Long(long.to_owned()), Value::Flag(false));
        }
        self
    }

    /// Builder method for adding both short and long opts
    pub fn add_opt(mut self, short: &str, long: &str) -> Self {
        if let Some(short) = short.chars().next() {
            self.params.insert(Param::Short(short), Value::Opt(None));
        }
        if !long.is_empty() {
            self.params.insert(Param::Long(long.to_owned()), Value::Opt(None));
        }
        self
    }

    /// Start parsing user inputted args for which flags are used
    pub fn initialize<A: Iterator<Item=String>>(&mut self, args: A) {
        let mut args = args.skip(1);
        while let Some(mut arg) = args.next() {
            if arg.starts_with("--") {
                // Remove both dashes
                arg.remove(0);
                arg.remove(0);
                if let Some(i) = arg.find('=') {
                    let (lhs, rhs) = arg.split_at(i);
                    if let Some(&mut Value::Opt(Some(ref mut value))) = self.params.get_mut(&Param::Long(lhs.to_owned())) {
                        *value = rhs.to_owned();
                    }
                }
                else {
                    if let Some(&mut Value::Flag(ref mut switch)) = self.params.get_mut(&Param::Long(arg)) {
                        *switch = true;
                    }
                }
            }
            else if arg.starts_with("-") {
                for ch in arg[1..].chars() {
                    match self.params.get_mut(&Param::Short(ch)) {
                        Some(&mut Value::Flag(ref mut switch)) => *switch = true,
                        Some(&mut Value::Opt(ref mut value)) => *value = args.next(),
                        None => (),
                    }
                }
            }
            else {
                self.args.push(arg);
            }
        }
    }

    /// Check if a flag has been used
    pub fn flagged<P: IntoParam>(&self, name: P) -> bool {
        match self.params.get(&name.into_param()) {
            Some(&Value::Flag(switch)) => switch,
            Some(&Value::Opt(Some(_))) => true,
            _ => false,
        }
    }

    pub fn set_flag<F: IntoParam>(&mut self, flag: F, state: bool) {
        if let Some(&mut Value::Flag(ref mut switch)) = self.params.get_mut(&flag.into_param()) {
            *switch = state;
        }
    }

    pub fn set_opt<O: IntoParam>(&mut self, opt: O, state: Option<String>) {
        if let Some(&mut Value::Opt(ref mut value)) = self.params.get_mut(&opt.into_param()) {
            *value = state;
        }
    }

    pub fn get_opt<O: IntoParam>(&self, opt: O) -> Option<String> {
        if let Some(&Value::Opt(ref value)) = self.params.get(&opt.into_param()) {
            return value.clone();
        }
        None
    }
}

pub fn to_human_readable_string(size: u64) -> String {
    if size < 1024 {
        return format!("{}", size);
    }

    static UNITS: [&'static str; 7] = ["", "K", "M", "G", "T", "P", "E"];

    let sizef = size as f64;
    let digit_groups = (sizef.log10() / 1024f64.log10()) as i32;
    format!("{:.1}{}",
            sizef / 1024f64.powf(digit_groups as f64),
            UNITS[digit_groups as usize])
}
<commit_msg>Add more API documentation to ArgParser<commit_after>#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub enum Param {
    Short(char),
    Long(String),
}

#[derive(Clone, Debug, Eq, PartialEq, Hash)]
enum Value {
    Flag(bool),
    Opt(Option<String>),
}

pub trait IntoParam {
    fn into_param(self) -> Param;
}

impl IntoParam for &'static str {
    fn into_param(self) -> Param {
        Param::Long(self.to_owned())
    }
}

impl IntoParam for char {
    fn into_param(self) -> Param {
        Param::Short(self)
    }
}

use std::collections::HashMap;

/// Our homebrewed Arg Parser
#[derive(Clone, Debug, Default)]
pub struct ArgParser {
    params: HashMap<Param, Value>,
    pub args: Vec<String>,
}

impl ArgParser {
    /// Create a new ArgParser object
    ///
    /// The capacity specifies the initial capacity of the number parameters.
    /// Always good to set it at the number of flags and opts total.
    pub fn new(capacity: usize) -> Self {
        ArgParser {
            params: HashMap::with_capacity(capacity),
            args: Vec::new(),
        }
    }

    /// Builder method for adding both short and long flags
    ///
    /// Flags are just parameters that have no assigned values. They are used
    /// for when certain features or options have been enabled for the application
    ///
    /// For example
    /// > ls -l --human-readable
    ///   ^  ^  ^
    ///   |  |  |
    ///   |  |  `-- A long flag to enable human readable numbers.
    ///   |  `-- A short flag to enable the long format.
    ///   `-- The command to list files.
    pub fn add_flag(mut self, short: &str, long: &str) -> Self {
        if let Some(short) = short.chars().next() {
            self.params.insert(Param::Short(short), Value::Flag(false));
        }
        if !long.is_empty() {
            self.params.insert(Param::Long(long.to_owned()), Value::Flag(false));
        }
        self
    }

    /// Builder method for adding both short and long opts
    ///
    /// Opts are parameters that hold assigned values. They are used
    /// for when certain features or options have been enabled for the application
    ///
    /// For example
    /// > ls -T 4 --color=always
    ///   ^  ^    ^
    ///   |  |    |
    ///   |  |    `-- A long opt to enable the use of color with value `always`.
    ///   |  `-- A short opt to set tab size to the value `4`.
    ///   `-- The command to list files.
    pub fn add_opt(mut self, short: &str, long: &str) -> Self {
        if let Some(short) = short.chars().next() {
            self.params.insert(Param::Short(short), Value::Opt(None));
        }
        if !long.is_empty() {
            self.params.insert(Param::Long(long.to_owned()), Value::Opt(None));
        }
        self
    }

    /// Start parsing user inputted args for which flags and opts are used at
    /// runtime. The rest of the args that are not associated to opts get added
    /// to `ArgParser.args`.
    pub fn initialize<A: Iterator<Item=String>>(&mut self, args: A) {
        let mut args = args.skip(1);
        while let Some(mut arg) = args.next() {
            if arg.starts_with("--") {
                // Remove both dashes
                arg.remove(0);
                arg.remove(0);
                if let Some(i) = arg.find('=') {
                    let (lhs, rhs) = arg.split_at(i);
                    if let Some(&mut Value::Opt(Some(ref mut value))) = self.params.get_mut(&Param::Long(lhs.to_owned())) {
                        *value = rhs.to_owned();
                    }
                }
                else {
                    if let Some(&mut Value::Flag(ref mut switch)) = self.params.get_mut(&Param::Long(arg)) {
                        *switch = true;
                    }
                }
            }
            else if arg.starts_with("-") {
                for ch in arg[1..].chars() {
                    match self.params.get_mut(&Param::Short(ch)) {
                        Some(&mut Value::Flag(ref mut switch)) => *switch = true,
                        Some(&mut Value::Opt(ref mut value)) => *value = args.next(),
                        None => (),
                    }
                }
            }
            else {
                self.args.push(arg);
            }
        }
    }

    /// Check if a Flag or Opt has been found after initialization.
    pub fn flagged<P: IntoParam>(&self, name: P) -> bool {
        match self.params.get(&name.into_param()) {
            Some(&Value::Flag(switch)) => switch,
            Some(&Value::Opt(Some(_))) => true,
            _ => false,
        }
    }

    /// Modify the state of a flag. Use `true` if the flag is to be enabled. Use `false` to
    /// disable its use.
    pub fn set_flag<F: IntoParam>(&mut self, flag: F, state: bool) {
        if let Some(&mut Value::Flag(ref mut switch)) = self.params.get_mut(&flag.into_param()) {
            *switch = state;
        }
    }

    /// Modify the state value of an opt. Use `Some(String)` to set if the opt is to be enabled and
    /// has been assigned a value from `String`. Use `None` to disable the opt's use.
    pub fn set_opt<O: IntoParam>(&mut self, opt: O, state: Option<String>) {
        if let Some(&mut Value::Opt(ref mut value)) = self.params.get_mut(&opt.into_param()) {
            *value = state;
        }
    }

    /// Get the state of an Opt. If it has been enabled, it will return a `Some(String)` value
    /// otherwise it will return None.
    pub fn get_opt<O: IntoParam>(&self, opt: O) -> Option<String> {
        if let Some(&Value::Opt(ref value)) = self.params.get(&opt.into_param()) {
            return value.clone();
        }
        None
    }
}

pub fn to_human_readable_string(size: u64) -> String {
    if size < 1024 {
        return format!("{}", size);
    }

    static UNITS: [&'static str; 7] = ["", "K", "M", "G", "T", "P", "E"];

    let sizef = size as f64;
    let digit_groups = (sizef.log10() / 1024f64.log10()) as i32;
    format!("{:.1}{}",
            sizef / 1024f64.powf(digit_groups as f64),
            UNITS[digit_groups as usize])
}
<|endoftext|>


<commit_before>#![feature(macro_rules)]

extern crate libc;

use pin::{Pin, RequiresRoot};

macro_rules! impl_pins(
    ($($name:ident),+) => (
        $(
            pub struct $name;

            impl Pin for $name {}
        )+
    )
)

macro_rules! require_root(
    ($($name:ident: $pwm:expr),+) => (
        $(
            impl RequiresRoot for $name {
                #[inline(allways)]
                fn pwm_pin() -> PwmPin<$name> {
                    PwmPin::new($pwm)
                }
            }
        )+
    )
)

mod bindings;

pub mod time {
    use libc;
    use bindings;
    use std::time::Duration;

/**

This causes program execution to pause for at least the provided duration in
milliseconds.

Due to the multi-tasking nature of Linux it could be longer. Note that the
maximum delay is an unsigned 32-bit integer or approximately 49 days.

*/
    pub fn delay(duration: Duration) {
        let duration = duration.num_milliseconds();
        if duration <= 0 {
            return;
        }

        unsafe {
            bindings::delay(duration as libc::c_uint);
        }
    }

/**

This causes program execution to pause for at least the provided number of
microseconds.

Due to the multi-tasking nature of Linux it could be longer. Note that the
maximum delay is an unsigned 32-bit integer microseconds or approximately 71
minutes.

*/
    pub fn delay_microseconds(microseconds: uint) {
        unsafe {
            bindings::delayMicroseconds(microseconds as libc::c_uint);
        }
    }

/**

This returns a number representing the number if milliseconds since your
program called one of the setup functions.

It returns an unsigned 32-bit number which wraps after 49 days.

*/

    pub fn millis() -> uint {
        unsafe {
            bindings::millis() as uint
        }
    }

/**

This returns a number representing the number if microseconds since your
program called one of the setup functions.

It returns an unsigned 32-bit number which wraps after 71 minutes.

*/

    pub fn micros() -> uint {
        unsafe {
            bindings::micros() as uint
        }
    }
}

pub mod thread {
    use bindings;
    use libc;

/**

This attempts to shift your program (or thread in a multi-threaded
program) to a higher priority and enables a real-time scheduling.

The priority parameter should be from 0 (the default) to 99 (the maximum).
This won’t make your program go any faster, but it will give it a bigger slice
of time when other programs are running. The priority parameter works relative
to others – so you can make one program priority 1 and another priority 2 and
it will have the same effect as setting one to 10 and the other to 90 (as long
as no other programs are running with elevated priorities)

The return value is `true` for success and `false` for error. If an error is returned,
the program should then consult the _errno_ global variable, as per the usual
conventions.

_Note_: Only programs running as root can change their priority. If called from
a non-root program then nothing happens.

*/
    pub fn priority(priority: u8) -> bool {
        unsafe {
            bindings::piHiPri(priority as libc::c_int) >= 0
        }
    }
}

pub mod pin {
    use bindings;
    use libc;

    impl_pins!(WiringPi, Gpio, Sys)
    require_root!(WiringPi: 1, Gpio: 18)

    pub trait Pin {}

    pub trait RequiresRoot: Pin {
        fn pwm_pin() -> PwmPin<Self>;
    }

    pub enum Value {
        Low = 0,
        High
    }

    pub enum Pull {
        Off = 0,
        Down,
        Up
    }

    pub enum PwmMode {
        MarkSpace = 0,
        Balanced
    }

    pub struct InputPin<Pin>(libc::c_int);

    impl<P: Pin> InputPin<P> {
        pub fn new(pin: libc::c_int) -> InputPin<P> {
            unsafe {
                bindings::pinMode(pin, 0);
            }

            InputPin(pin)
        }

        #[inline(allways)]
        pub fn number(&self) -> libc::c_int {
            let &InputPin(number) = self;
            number
        }

        pub fn into_output(self) -> OutputPin<P> {
            let InputPin(number) = self;
            OutputPin::new(number)
        }

        ///This function returns the value read at the given pin.
        ///
        ///It will be `High` or `Low` (1 or 0) depending on the logic level at the pin.
        pub fn digital_read(&self) -> Value {
            let value = unsafe {
                bindings::digitalRead(self.number())
            };

            if value == 0 {
                Low
            } else {
                High
            }
        }
    }

    impl<P: Pin + RequiresRoot> InputPin<P> {
        pub fn into_pwm(self) -> PwmPin<P> {
            let InputPin(number) = self;
            PwmPin::new(number)
        }
/**

This sets the pull-up or pull-down resistor mode on the given pin.

Unlike the Arduino, the BCM2835 has both pull-up an down internal resistors.
The parameter pud should be; `Off`, (no pull up/down), `Down` (pull to ground)
or `Up` (pull to 3.3v)

*/
        pub fn pull_up_dn_control(&self, pud: Pull) {
            unsafe {
                bindings::pullUpDnControl(self.number(), pud as libc::c_int);
            }
        }
    }

    pub struct OutputPin<Pin>(libc::c_int);

    impl<P: Pin> OutputPin<P> {
        pub fn new(pin: libc::c_int) -> OutputPin<P> {
            unsafe {
                bindings::pinMode(pin, 1);
            }

            OutputPin(pin)
        }

        #[inline(allways)]
        pub fn number(&self) -> libc::c_int {
            let &OutputPin(number) = self;
            number
        }

        pub fn into_input(self) -> InputPin<P> {
            let OutputPin(number) = self;
            InputPin::new(number)
        }

        ///Writes the value `High` or `Low` (1 or 0) to the given pin which must have been previously set as an output.
        pub fn digital_write(&self, value: Value) {
            unsafe {
                bindings::digitalWrite(self.number(), value as libc::c_int);
            }
        }
    }

    impl<P: Pin + RequiresRoot> OutputPin<P> {
        pub fn into_pwm(self) -> PwmPin<P> {
            let OutputPin(number) = self;
            PwmPin::new(number)
        }
    }

    ///To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual.
    pub struct PwmPin<Pin>(libc::c_int);

    impl<P: Pin + RequiresRoot> PwmPin<P> {
        pub fn new(pin: libc::c_int) -> PwmPin<P> {
            unsafe {
                bindings::pinMode(pin, 2);
            }

            PwmPin(pin)
        }

        #[inline(allways)]
        pub fn number(&self) -> libc::c_int {
            let &PwmPin(number) = self;
            number
        }

        pub fn into_input(self) -> InputPin<P> {
            let PwmPin(number) = self;
            InputPin::new(number)
        }

        pub fn into_output(self) -> OutputPin<P> {
            let PwmPin(number) = self;
            OutputPin::new(number)
        }

        ///Writes the value to the PWM register for the given pin.
        ///
        ///The value must be between 0 and 1024.
        pub fn write(&self, value: uint) {
            unsafe {
                bindings::pwmWrite(self.number(), value as libc::c_int);
            }
        }

/**

The PWM generator can run in 2 modes – "balanced" and "mark:space".

The mark:space mode is traditional, however the default mode in the Pi is
"balanced". You can switch modes by supplying the parameter: `Balanced` or
`MarkSpace`.

*/
        pub fn set_mode(&self, mode: PwmMode) {
            unsafe {
                bindings::pwmSetMode(mode as libc::c_int);
            }
        }

        ///This sets the range register in the PWM generator. The default is 1024.
        pub fn set_range(&self, value: uint) {
            unsafe {
                bindings::pwmSetRange(value as libc::c_uint);
            }
        }

        ///This sets the divisor for the PWM clock.
        pub fn set_clock(&self, value: uint) {
            unsafe {
                bindings::pwmSetClock(value as libc::c_int);
            }
        }
    }
}

/**

This initialises the wiringPi system and assumes that the calling program is
going to be using the **wiringPi** pin numbering scheme.

This is a simplified numbering scheme which provides a mapping from virtual
pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers. See
the pins page for a table which maps the **wiringPi** pin number to the Broadcom
GPIO pin number to the physical location on the edge connector.

This function needs to be called with root privileges.

*/
pub fn setup() -> Option<WiringPi<pin::WiringPi>> {
    unsafe {
        if bindings::wiringPiSetup() >= 0 {
            Some(WiringPi)
        } else {
            None
        }
    }
}

/**

This is identical `setup()`, however it allows the calling programs to use the
Broadcom GPIO pin numbers directly with no re-mapping.

This function needs to be called with root privileges.

*/
pub fn setup_gpio() -> Option<WiringPi<pin::Gpio>> {
    unsafe {
        if bindings::wiringPiSetupGpio() >= 0 {
            Some(WiringPi)
        } else {
            None
        }
    }
}

/**

This initialises the wiringPi system but uses the /sys/class/gpio interface
rather than accessing the hardware directly.

This can be called as a non-root user provided the GPIO pins have been
exported before-hand using the gpio program. Pin number in this mode is the
native Broadcom GPIO numbers.

_Note_: In this mode you can only use the pins which have been exported via the
/sys/class/gpio interface. You must export these pins before you call your
program. You can do this in a separate shell-script, or by using the system()
function from inside your program.

Also note that some functions have no effect when using this mode as they’re
not currently possible to action unless called with root privileges.

*/
pub fn setup_sys() -> Option<WiringPi<pin::Sys>> {
    unsafe {
        if bindings::wiringPiSetupSys() >= 0 {
            Some(WiringPi)
        } else {
            None
        }
    }
}

/**

This returns the board revision of the Raspberry Pi.

It will be either 1 or 2. Some of the BCM_GPIO pins changed number and
function when moving from board revision 1 to 2, so if you are using BCM_GPIO
pin numbers, then you need to be aware of the differences.

*/
pub fn board_revision() -> uint {
    unsafe {
        bindings::piBoardRev() as uint
    }
}

///This returns the BCM_GPIO pin number of the supplied **wiringPi** pin.
///
///It takes the board revision into account.
pub fn to_gpio_number(wpi_number: uint) -> uint {
    unsafe {
        bindings::wpiPinToGpio(wpi_number as libc::c_int) as uint
    }
}

pub struct WiringPi<Pin>;

impl<P: Pin> WiringPi<P> {
    pub fn input_pin(&self, pin: uint) -> pin::InputPin<P> {
        let pin = pin as libc::c_int;
        pin::InputPin::new(pin)
    }

    pub fn output_pin(&self, pin: uint) -> pin::OutputPin<P> {
        let pin = pin as libc::c_int;
        pin::OutputPin::new(pin)
    }
}

impl<P: RequiresRoot + Pin> WiringPi<P> {
    pub fn pwm_pin(&self) -> pin::PwmPin<P> {
        RequiresRoot::pwm_pin()
    }
}<commit_msg>Update for namespaced enums<commit_after>#![feature(macro_rules)]

extern crate libc;

use pin::{Pin, RequiresRoot};

macro_rules! impl_pins(
    ($($name:ident),+) => (
        $(
            pub struct $name;

            impl Pin for $name {}
        )+
    )
)

macro_rules! require_root(
    ($($name:ident: $pwm:expr),+) => (
        $(
            impl RequiresRoot for $name {
                #[inline(allways)]
                fn pwm_pin() -> PwmPin<$name> {
                    PwmPin::new($pwm)
                }
            }
        )+
    )
)

mod bindings;

pub mod time {
    use libc;
    use bindings;
    use std::time::Duration;

/**

This causes program execution to pause for at least the provided duration in
milliseconds.

Due to the multi-tasking nature of Linux it could be longer. Note that the
maximum delay is an unsigned 32-bit integer or approximately 49 days.

*/
    pub fn delay(duration: Duration) {
        let duration = duration.num_milliseconds();
        if duration <= 0 {
            return;
        }

        unsafe {
            bindings::delay(duration as libc::c_uint);
        }
    }

/**

This causes program execution to pause for at least the provided number of
microseconds.

Due to the multi-tasking nature of Linux it could be longer. Note that the
maximum delay is an unsigned 32-bit integer microseconds or approximately 71
minutes.

*/
    pub fn delay_microseconds(microseconds: uint) {
        unsafe {
            bindings::delayMicroseconds(microseconds as libc::c_uint);
        }
    }

/**

This returns a number representing the number if milliseconds since your
program called one of the setup functions.

It returns an unsigned 32-bit number which wraps after 49 days.

*/

    pub fn millis() -> uint {
        unsafe {
            bindings::millis() as uint
        }
    }

/**

This returns a number representing the number if microseconds since your
program called one of the setup functions.

It returns an unsigned 32-bit number which wraps after 71 minutes.

*/

    pub fn micros() -> uint {
        unsafe {
            bindings::micros() as uint
        }
    }
}

pub mod thread {
    use bindings;
    use libc;

/**

This attempts to shift your program (or thread in a multi-threaded
program) to a higher priority and enables a real-time scheduling.

The priority parameter should be from 0 (the default) to 99 (the maximum).
This won’t make your program go any faster, but it will give it a bigger slice
of time when other programs are running. The priority parameter works relative
to others – so you can make one program priority 1 and another priority 2 and
it will have the same effect as setting one to 10 and the other to 90 (as long
as no other programs are running with elevated priorities)

The return value is `true` for success and `false` for error. If an error is returned,
the program should then consult the _errno_ global variable, as per the usual
conventions.

_Note_: Only programs running as root can change their priority. If called from
a non-root program then nothing happens.

*/
    pub fn priority(priority: u8) -> bool {
        unsafe {
            bindings::piHiPri(priority as libc::c_int) >= 0
        }
    }
}

pub mod pin {
    use bindings;
    use libc;
    use self::Value::{Low, High};

    impl_pins!(WiringPi, Gpio, Sys)
    require_root!(WiringPi: 1, Gpio: 18)

    pub trait Pin {}

    pub trait RequiresRoot: Pin {
        fn pwm_pin() -> PwmPin<Self>;
    }

    pub enum Value {
        Low = 0,
        High
    }

    pub enum Pull {
        Off = 0,
        Down,
        Up
    }

    pub enum PwmMode {
        MarkSpace = 0,
        Balanced
    }

    pub struct InputPin<Pin>(libc::c_int);

    impl<P: Pin> InputPin<P> {
        pub fn new(pin: libc::c_int) -> InputPin<P> {
            unsafe {
                bindings::pinMode(pin, 0);
            }

            InputPin(pin)
        }

        #[inline(allways)]
        pub fn number(&self) -> libc::c_int {
            let &InputPin(number) = self;
            number
        }

        pub fn into_output(self) -> OutputPin<P> {
            let InputPin(number) = self;
            OutputPin::new(number)
        }

        ///This function returns the value read at the given pin.
        ///
        ///It will be `High` or `Low` (1 or 0) depending on the logic level at the pin.
        pub fn digital_read(&self) -> Value {
            let value = unsafe {
                bindings::digitalRead(self.number())
            };

            if value == 0 {
                Low
            } else {
                High
            }
        }
    }

    impl<P: Pin + RequiresRoot> InputPin<P> {
        pub fn into_pwm(self) -> PwmPin<P> {
            let InputPin(number) = self;
            PwmPin::new(number)
        }
/**

This sets the pull-up or pull-down resistor mode on the given pin.

Unlike the Arduino, the BCM2835 has both pull-up an down internal resistors.
The parameter pud should be; `Off`, (no pull up/down), `Down` (pull to ground)
or `Up` (pull to 3.3v)

*/
        pub fn pull_up_dn_control(&self, pud: Pull) {
            unsafe {
                bindings::pullUpDnControl(self.number(), pud as libc::c_int);
            }
        }
    }

    pub struct OutputPin<Pin>(libc::c_int);

    impl<P: Pin> OutputPin<P> {
        pub fn new(pin: libc::c_int) -> OutputPin<P> {
            unsafe {
                bindings::pinMode(pin, 1);
            }

            OutputPin(pin)
        }

        #[inline(allways)]
        pub fn number(&self) -> libc::c_int {
            let &OutputPin(number) = self;
            number
        }

        pub fn into_input(self) -> InputPin<P> {
            let OutputPin(number) = self;
            InputPin::new(number)
        }

        ///Writes the value `High` or `Low` (1 or 0) to the given pin which must have been previously set as an output.
        pub fn digital_write(&self, value: Value) {
            unsafe {
                bindings::digitalWrite(self.number(), value as libc::c_int);
            }
        }
    }

    impl<P: Pin + RequiresRoot> OutputPin<P> {
        pub fn into_pwm(self) -> PwmPin<P> {
            let OutputPin(number) = self;
            PwmPin::new(number)
        }
    }

    ///To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual.
    pub struct PwmPin<Pin>(libc::c_int);

    impl<P: Pin + RequiresRoot> PwmPin<P> {
        pub fn new(pin: libc::c_int) -> PwmPin<P> {
            unsafe {
                bindings::pinMode(pin, 2);
            }

            PwmPin(pin)
        }

        #[inline(allways)]
        pub fn number(&self) -> libc::c_int {
            let &PwmPin(number) = self;
            number
        }

        pub fn into_input(self) -> InputPin<P> {
            let PwmPin(number) = self;
            InputPin::new(number)
        }

        pub fn into_output(self) -> OutputPin<P> {
            let PwmPin(number) = self;
            OutputPin::new(number)
        }

        ///Writes the value to the PWM register for the given pin.
        ///
        ///The value must be between 0 and 1024.
        pub fn write(&self, value: uint) {
            unsafe {
                bindings::pwmWrite(self.number(), value as libc::c_int);
            }
        }

/**

The PWM generator can run in 2 modes – "balanced" and "mark:space".

The mark:space mode is traditional, however the default mode in the Pi is
"balanced". You can switch modes by supplying the parameter: `Balanced` or
`MarkSpace`.

*/
        pub fn set_mode(&self, mode: PwmMode) {
            unsafe {
                bindings::pwmSetMode(mode as libc::c_int);
            }
        }

        ///This sets the range register in the PWM generator. The default is 1024.
        pub fn set_range(&self, value: uint) {
            unsafe {
                bindings::pwmSetRange(value as libc::c_uint);
            }
        }

        ///This sets the divisor for the PWM clock.
        pub fn set_clock(&self, value: uint) {
            unsafe {
                bindings::pwmSetClock(value as libc::c_int);
            }
        }
    }
}

/**

This initialises the wiringPi system and assumes that the calling program is
going to be using the **wiringPi** pin numbering scheme.

This is a simplified numbering scheme which provides a mapping from virtual
pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers. See
the pins page for a table which maps the **wiringPi** pin number to the Broadcom
GPIO pin number to the physical location on the edge connector.

This function needs to be called with root privileges.

*/
pub fn setup() -> Option<WiringPi<pin::WiringPi>> {
    unsafe {
        if bindings::wiringPiSetup() >= 0 {
            Some(WiringPi)
        } else {
            None
        }
    }
}

/**

This is identical `setup()`, however it allows the calling programs to use the
Broadcom GPIO pin numbers directly with no re-mapping.

This function needs to be called with root privileges.

*/
pub fn setup_gpio() -> Option<WiringPi<pin::Gpio>> {
    unsafe {
        if bindings::wiringPiSetupGpio() >= 0 {
            Some(WiringPi)
        } else {
            None
        }
    }
}

/**

This initialises the wiringPi system but uses the /sys/class/gpio interface
rather than accessing the hardware directly.

This can be called as a non-root user provided the GPIO pins have been
exported before-hand using the gpio program. Pin number in this mode is the
native Broadcom GPIO numbers.

_Note_: In this mode you can only use the pins which have been exported via the
/sys/class/gpio interface. You must export these pins before you call your
program. You can do this in a separate shell-script, or by using the system()
function from inside your program.

Also note that some functions have no effect when using this mode as they’re
not currently possible to action unless called with root privileges.

*/
pub fn setup_sys() -> Option<WiringPi<pin::Sys>> {
    unsafe {
        if bindings::wiringPiSetupSys() >= 0 {
            Some(WiringPi)
        } else {
            None
        }
    }
}

/**

This returns the board revision of the Raspberry Pi.

It will be either 1 or 2. Some of the BCM_GPIO pins changed number and
function when moving from board revision 1 to 2, so if you are using BCM_GPIO
pin numbers, then you need to be aware of the differences.

*/
pub fn board_revision() -> uint {
    unsafe {
        bindings::piBoardRev() as uint
    }
}

///This returns the BCM_GPIO pin number of the supplied **wiringPi** pin.
///
///It takes the board revision into account.
pub fn to_gpio_number(wpi_number: uint) -> uint {
    unsafe {
        bindings::wpiPinToGpio(wpi_number as libc::c_int) as uint
    }
}

pub struct WiringPi<Pin>;

impl<P: Pin> WiringPi<P> {
    pub fn input_pin(&self, pin: uint) -> pin::InputPin<P> {
        let pin = pin as libc::c_int;
        pin::InputPin::new(pin)
    }

    pub fn output_pin(&self, pin: uint) -> pin::OutputPin<P> {
        let pin = pin as libc::c_int;
        pin::OutputPin::new(pin)
    }
}

impl<P: RequiresRoot + Pin> WiringPi<P> {
    pub fn pwm_pin(&self) -> pin::PwmPin<P> {
        RequiresRoot::pwm_pin()
    }
}<|endoftext|>


<commit_before>//! # derive_more
//! Rust has lots of builtin traits that are implemented for its basic types, such as [`Add`],
//! [`Not`] or [`From`].
//! However, when wrapping these types inside your own structs or enums you lose the
//! implementations of these traits and are required to recreate them.
//! This is especially annoying when your own structures are very simple, such as when using the
//! commonly advised newtype pattern (e.g. `MyInt(i32)`).
//!
//! This library tries to remove these annoyances and the corresponding boilerplate code.
//! It does this by allowing you to derive lots of commonly used traits for both structs and enums.
//!
//! ## Example code
//!
//! By using this library the following code just works:
//!
//!
//! ```rust
//! # #[macro_use] extern crate derive_more;
//!
//! #[derive(Debug, Eq, PartialEq, From, Add)]
//! struct MyInt(i32);
//!
//! #[derive(Debug, Eq, PartialEq, From, Into, Constructor, Mul)]
//! struct Point2D {
//!     x: i32,
//!     y: i32,
//! }
//!
//! #[derive(Debug, Eq, PartialEq, From, Add)]
//! enum MyEnum {
//!     Int(i32),
//!     UnsignedInt(u32),
//!     Nothing,
//! }
//!
//! fn main() {
//!     let my_11 = MyInt(5) + 6.into();
//!     assert_eq!(MyInt(11), MyInt(5) + 6.into());
//!     assert_eq!(Point2D { x: 5, y: 6 } * 10, (50, 60).into());
//!     assert_eq!((5, 6), Point2D { x: 5, y: 6 }.into());
//!     assert_eq!(Point2D { x: 5, y: 6 }, Point2D::new(5, 6));
//!     assert_eq!(MyEnum::Int(15), (MyEnum::Int(8) + 7.into()).unwrap())
//! }
//! ```
//!
//! ## The newly derivable traits
//!
//! Obviously not all traits should be derived to the same code, because they are different
//! different traits after all.
//! However, some of the semantics of the traits overlap a lot, so they have been grouped in the
//! following way:
//!
//! 1. `From`, only contains [`From`].
//! 2. `Into`, only contains [`Into`].
//! 3. `Constructor`, this doesn't derive a trait, but it derives a `new` method that can be
//!    used as a constructor.
//! 4. `Not`-like, contains [`Not`] and [`Neg`].
//! 5. `Add`-like, contains [`Add`], [`Sub`], [`BitAnd`], [`BitOr`] and [`BitXor`].
//! 6. `AddAssign`-like, contains [`AddAssign`], [`SubAssign`], [`BitAndAssign`], [`BitOrAssign`]
//!    and [`BitXorAssign`].
//! 7. `Mul`-like, contains [`Mul`], [`Div`], [`Rem`], [`Shr`] and [`Shl`].
//! 8. `MulAssign`-like, contains [`MulAssign`], [`DivAssign`], [`RemAssign`], [`ShrAssign`] and [`ShlAssign`].
//!
//!
//! ## Generated code
//!
//! It is important to understand what code gets generated when using one of the derives from this
//! crate.
//! That is why the links below explain what code gets generated for a trait for each group from
//! before.
//!
//! 1. [`#[derive(From)]`](from.html)
//! 2. [`#[derive(Into)]`](into.html)
//! 3. [`#[derive(Constructor)]`](constructor.html)
//! 4. [`#[derive(Not)]`](not.html)
//! 5. [`#[derive(Add)]`](add.html)
//! 6. [`#[derive(AddAssign)]`](add_assign.html)
//! 7. [`#[derive(Mul)]`](mul.html)
//! 8. [`#[derive(MulAssign)]`](mul_assign.html)
//!
//! If you want to be sure what code is generated for your specific type I recommend using the
//! [`cargo-expand`] utility.
//! This will show you your code with all macros and derives expanded.
//!
//! ## Installation
//!
//! This library requires Rust 1.15 or higher, so this needs to be installed.
//! Then add the following to `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! derive_more = "0.6.0"
//! ```
//!
//! And this to the top of your Rust file:
//!
//! ```rust
//! #[macro_use]
//! extern crate derive_more;
//! # fn main () {}
//! ```
//!
//! [`cargo-expand`]: https://github.com/dtolnay/cargo-expand
//! [`From`]: https://doc.rust-lang.org/core/convert/trait.From.html
//! [`Into`]: https://doc.rust-lang.org/core/convert/trait.Into.html
//! [`Not`]: https://doc.rust-lang.org/std/ops/trait.Not.html
//! [`Neg`]: https://doc.rust-lang.org/std/ops/trait.Neg.html
//! [`Add`]: https://doc.rust-lang.org/std/ops/trait.Add.html
//! [`Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
//! [`BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
//! [`BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
//! [`BitXor`]: https://doc.rust-lang.org/std/ops/trait.BitXor.html
//! [`AddAssign`]: https://doc.rust-lang.org/std/ops/trait.AddAssign.html
//! [`SubAssign`]: https://doc.rust-lang.org/std/ops/trait.SubAssign.html
//! [`BitAndAssign`]: https://doc.rust-lang.org/std/ops/trait.BitAndAssign.html
//! [`BitOrAssign`]: https://doc.rust-lang.org/std/ops/trait.BitOrAssign.html
//! [`BitXorAssign`]: https://doc.rust-lang.org/std/ops/trait.BitXorAssign.html
//! [`Mul`]: https://doc.rust-lang.org/std/ops/trait.Mul.html
//! [`Div`]: https://doc.rust-lang.org/std/ops/trait.Div.html
//! [`Rem`]: https://doc.rust-lang.org/std/ops/trait.Rem.html
//! [`Shr`]: https://doc.rust-lang.org/std/ops/trait.Shr.html
//! [`Shl`]: https://doc.rust-lang.org/std/ops/trait.Shl.html
//! [`MulAssign`]: https://doc.rust-lang.org/std/ops/trait.MulAssign.html
//! [`DivAssign`]: https://doc.rust-lang.org/std/ops/trait.DivAssign.html
//! [`RemAssign`]: https://doc.rust-lang.org/std/ops/trait.RemAssign.html
//! [`ShrAssign`]: https://doc.rust-lang.org/std/ops/trait.ShrAssign.html
//! [`ShlAssign`]: https://doc.rust-lang.org/std/ops/trait.ShlAssign.html

extern crate proc_macro;
#[macro_use]
extern crate quote;
extern crate syn;

use proc_macro::TokenStream;

mod utils;

mod from;
mod into;
mod constructor;
mod not_like;
mod add_like;
mod add_assign_like;
mod mul_like;
mod mul_assign_like;

macro_rules! create_derive(
    ($mod_:ident, $trait_:ident, $fn_name: ident) => {
        #[proc_macro_derive($trait_)]
        #[doc(hidden)]
        pub fn $fn_name(input: TokenStream) -> TokenStream {
            let s = input.to_string();
            let ast = syn::parse_derive_input(&s).unwrap();
            $mod_::expand(&ast, stringify!($trait_)).parse().expect("Expanded output was no correct Rust code")
        }
    }
);

create_derive!(from, From, from_derive);

create_derive!(into, Into, into_derive);

create_derive!(constructor, Constructor, constructor_derive);

create_derive!(not_like, Not, not_derive);
create_derive!(not_like, Neg, neg_derive);

create_derive!(add_like, Add, add_derive);
create_derive!(add_like, Sub, sub_derive);
create_derive!(add_like, BitAnd, bit_and_derive);
create_derive!(add_like, BitOr, bit_or_derive);
create_derive!(add_like, BitXor, bit_xor_derive);

create_derive!(mul_like, Mul, mul_derive);
create_derive!(mul_like, Div, div_derive);
create_derive!(mul_like, Rem, rem_derive);
create_derive!(mul_like, Shr, shr_derive);
create_derive!(mul_like, Shl, shl_derive);

create_derive!(add_assign_like, AddAssign, add_assign_derive);
create_derive!(add_assign_like, SubAssign, sub_assign_derive);
create_derive!(add_assign_like, BitAndAssign, bit_and_assign_derive);
create_derive!(add_assign_like, BitOrAssign, bit_or_assign_derive);
create_derive!(add_assign_like, BitXorAssign, bit_xor_assign_derive);

create_derive!(mul_assign_like, MulAssign, mul_assign_derive);
create_derive!(mul_assign_like, DivAssign, div_assign_derive);
create_derive!(mul_assign_like, RemAssign, rem_assign_derive);
create_derive!(mul_assign_like, ShrAssign, shr_assign_derive);
create_derive!(mul_assign_like, ShlAssign, shl_assign_derive);
<commit_msg>One different is fine<commit_after>//! # derive_more
//! Rust has lots of builtin traits that are implemented for its basic types, such as [`Add`],
//! [`Not`] or [`From`].
//! However, when wrapping these types inside your own structs or enums you lose the
//! implementations of these traits and are required to recreate them.
//! This is especially annoying when your own structures are very simple, such as when using the
//! commonly advised newtype pattern (e.g. `MyInt(i32)`).
//!
//! This library tries to remove these annoyances and the corresponding boilerplate code.
//! It does this by allowing you to derive lots of commonly used traits for both structs and enums.
//!
//! ## Example code
//!
//! By using this library the following code just works:
//!
//!
//! ```rust
//! # #[macro_use] extern crate derive_more;
//!
//! #[derive(Debug, Eq, PartialEq, From, Add)]
//! struct MyInt(i32);
//!
//! #[derive(Debug, Eq, PartialEq, From, Into, Constructor, Mul)]
//! struct Point2D {
//!     x: i32,
//!     y: i32,
//! }
//!
//! #[derive(Debug, Eq, PartialEq, From, Add)]
//! enum MyEnum {
//!     Int(i32),
//!     UnsignedInt(u32),
//!     Nothing,
//! }
//!
//! fn main() {
//!     let my_11 = MyInt(5) + 6.into();
//!     assert_eq!(MyInt(11), MyInt(5) + 6.into());
//!     assert_eq!(Point2D { x: 5, y: 6 } * 10, (50, 60).into());
//!     assert_eq!((5, 6), Point2D { x: 5, y: 6 }.into());
//!     assert_eq!(Point2D { x: 5, y: 6 }, Point2D::new(5, 6));
//!     assert_eq!(MyEnum::Int(15), (MyEnum::Int(8) + 7.into()).unwrap())
//! }
//! ```
//!
//! ## The newly derivable traits
//!
//! Obviously not all traits should be derived to the same code, because they are different
//! traits after all.
//! However, some of the semantics of the traits overlap a lot, so they have been grouped in the
//! following way:
//!
//! 1. `From`, only contains [`From`].
//! 2. `Into`, only contains [`Into`].
//! 3. `Constructor`, this doesn't derive a trait, but it derives a `new` method that can be
//!    used as a constructor.
//! 4. `Not`-like, contains [`Not`] and [`Neg`].
//! 5. `Add`-like, contains [`Add`], [`Sub`], [`BitAnd`], [`BitOr`] and [`BitXor`].
//! 6. `AddAssign`-like, contains [`AddAssign`], [`SubAssign`], [`BitAndAssign`], [`BitOrAssign`]
//!    and [`BitXorAssign`].
//! 7. `Mul`-like, contains [`Mul`], [`Div`], [`Rem`], [`Shr`] and [`Shl`].
//! 8. `MulAssign`-like, contains [`MulAssign`], [`DivAssign`], [`RemAssign`], [`ShrAssign`] and [`ShlAssign`].
//!
//!
//! ## Generated code
//!
//! It is important to understand what code gets generated when using one of the derives from this
//! crate.
//! That is why the links below explain what code gets generated for a trait for each group from
//! before.
//!
//! 1. [`#[derive(From)]`](from.html)
//! 2. [`#[derive(Into)]`](into.html)
//! 3. [`#[derive(Constructor)]`](constructor.html)
//! 4. [`#[derive(Not)]`](not.html)
//! 5. [`#[derive(Add)]`](add.html)
//! 6. [`#[derive(AddAssign)]`](add_assign.html)
//! 7. [`#[derive(Mul)]`](mul.html)
//! 8. [`#[derive(MulAssign)]`](mul_assign.html)
//!
//! If you want to be sure what code is generated for your specific type I recommend using the
//! [`cargo-expand`] utility.
//! This will show you your code with all macros and derives expanded.
//!
//! ## Installation
//!
//! This library requires Rust 1.15 or higher, so this needs to be installed.
//! Then add the following to `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! derive_more = "0.6.0"
//! ```
//!
//! And this to the top of your Rust file:
//!
//! ```rust
//! #[macro_use]
//! extern crate derive_more;
//! # fn main () {}
//! ```
//!
//! [`cargo-expand`]: https://github.com/dtolnay/cargo-expand
//! [`From`]: https://doc.rust-lang.org/core/convert/trait.From.html
//! [`Into`]: https://doc.rust-lang.org/core/convert/trait.Into.html
//! [`Not`]: https://doc.rust-lang.org/std/ops/trait.Not.html
//! [`Neg`]: https://doc.rust-lang.org/std/ops/trait.Neg.html
//! [`Add`]: https://doc.rust-lang.org/std/ops/trait.Add.html
//! [`Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
//! [`BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
//! [`BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
//! [`BitXor`]: https://doc.rust-lang.org/std/ops/trait.BitXor.html
//! [`AddAssign`]: https://doc.rust-lang.org/std/ops/trait.AddAssign.html
//! [`SubAssign`]: https://doc.rust-lang.org/std/ops/trait.SubAssign.html
//! [`BitAndAssign`]: https://doc.rust-lang.org/std/ops/trait.BitAndAssign.html
//! [`BitOrAssign`]: https://doc.rust-lang.org/std/ops/trait.BitOrAssign.html
//! [`BitXorAssign`]: https://doc.rust-lang.org/std/ops/trait.BitXorAssign.html
//! [`Mul`]: https://doc.rust-lang.org/std/ops/trait.Mul.html
//! [`Div`]: https://doc.rust-lang.org/std/ops/trait.Div.html
//! [`Rem`]: https://doc.rust-lang.org/std/ops/trait.Rem.html
//! [`Shr`]: https://doc.rust-lang.org/std/ops/trait.Shr.html
//! [`Shl`]: https://doc.rust-lang.org/std/ops/trait.Shl.html
//! [`MulAssign`]: https://doc.rust-lang.org/std/ops/trait.MulAssign.html
//! [`DivAssign`]: https://doc.rust-lang.org/std/ops/trait.DivAssign.html
//! [`RemAssign`]: https://doc.rust-lang.org/std/ops/trait.RemAssign.html
//! [`ShrAssign`]: https://doc.rust-lang.org/std/ops/trait.ShrAssign.html
//! [`ShlAssign`]: https://doc.rust-lang.org/std/ops/trait.ShlAssign.html

extern crate proc_macro;
#[macro_use]
extern crate quote;
extern crate syn;

use proc_macro::TokenStream;

mod utils;

mod from;
mod into;
mod constructor;
mod not_like;
mod add_like;
mod add_assign_like;
mod mul_like;
mod mul_assign_like;

macro_rules! create_derive(
    ($mod_:ident, $trait_:ident, $fn_name: ident) => {
        #[proc_macro_derive($trait_)]
        #[doc(hidden)]
        pub fn $fn_name(input: TokenStream) -> TokenStream {
            let s = input.to_string();
            let ast = syn::parse_derive_input(&s).unwrap();
            $mod_::expand(&ast, stringify!($trait_)).parse().expect("Expanded output was no correct Rust code")
        }
    }
);

create_derive!(from, From, from_derive);

create_derive!(into, Into, into_derive);

create_derive!(constructor, Constructor, constructor_derive);

create_derive!(not_like, Not, not_derive);
create_derive!(not_like, Neg, neg_derive);

create_derive!(add_like, Add, add_derive);
create_derive!(add_like, Sub, sub_derive);
create_derive!(add_like, BitAnd, bit_and_derive);
create_derive!(add_like, BitOr, bit_or_derive);
create_derive!(add_like, BitXor, bit_xor_derive);

create_derive!(mul_like, Mul, mul_derive);
create_derive!(mul_like, Div, div_derive);
create_derive!(mul_like, Rem, rem_derive);
create_derive!(mul_like, Shr, shr_derive);
create_derive!(mul_like, Shl, shl_derive);

create_derive!(add_assign_like, AddAssign, add_assign_derive);
create_derive!(add_assign_like, SubAssign, sub_assign_derive);
create_derive!(add_assign_like, BitAndAssign, bit_and_assign_derive);
create_derive!(add_assign_like, BitOrAssign, bit_or_assign_derive);
create_derive!(add_assign_like, BitXorAssign, bit_xor_assign_derive);

create_derive!(mul_assign_like, MulAssign, mul_assign_derive);
create_derive!(mul_assign_like, DivAssign, div_assign_derive);
create_derive!(mul_assign_like, RemAssign, rem_assign_derive);
create_derive!(mul_assign_like, ShrAssign, shr_assign_derive);
create_derive!(mul_assign_like, ShlAssign, shl_assign_derive);
<|endoftext|>