<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// TODO we're going to allocate a whole bunch of temp Strings, is it worth
// keeping some scratch mem for this and running our own StrPool?
// TODO for lint violations of names, emit a refactor script

#[macro_use]
extern crate log;

extern crate syntex_syntax as syntax;
extern crate rustc_serialize;

extern crate strings;

extern crate unicode_segmentation;
extern crate regex;
extern crate diff;
extern crate term;

use syntax::ast;
use syntax::codemap::Span;
use syntax::diagnostic::{EmitterWriter, Handler};
use syntax::parse::{self, ParseSess};

use std::ops::{Add, Sub};
use std::path::Path;
use std::collections::HashMap;
use std::fmt;
use std::str::FromStr;

use issues::{BadIssueSeeker, Issue};
use filemap::FileMap;
use visitor::FmtVisitor;
use config::Config;

#[macro_use]
mod utils;
pub mod config;
pub mod filemap;
mod visitor;
mod items;
mod missed_spans;
mod lists;
mod types;
mod expr;
mod imports;
mod issues;
mod rewrite;
mod string;
mod comment;
mod modules;
pub mod rustfmt_diff;
mod chains;
mod macros;
mod patterns;

const MIN_STRING: usize = 10;
// When we get scoped annotations, we should have rustfmt::skip.
const SKIP_ANNOTATION: &'static str = "rustfmt_skip";

pub trait Spanned {
    fn span(&self) -> Span;
}

impl Spanned for ast::Expr {
    fn span(&self) -> Span {
        self.span
    }
}

impl Spanned for ast::Pat {
    fn span(&self) -> Span {
        self.span
    }
}

impl Spanned for ast::Ty {
    fn span(&self) -> Span {
        self.span
    }
}

#[derive(Copy, Clone, Debug)]
pub struct Indent {
    // Width of the block indent, in characters. Must be a multiple of
    // Config::tab_spaces.
    pub block_indent: usize,
    // Alignment in characters.
    pub alignment: usize,
}

impl Indent {
    pub fn new(block_indent: usize, alignment: usize) -> Indent {
        Indent {
            block_indent: block_indent,
            alignment: alignment,
        }
    }

    pub fn empty() -> Indent {
        Indent::new(0, 0)
    }

    pub fn block_indent(mut self, config: &Config) -> Indent {
        self.block_indent += config.tab_spaces;
        self
    }

    pub fn block_unindent(mut self, config: &Config) -> Indent {
        self.block_indent -= config.tab_spaces;
        self
    }

    pub fn width(&self) -> usize {
        self.block_indent + self.alignment
    }

    pub fn to_string(&self, config: &Config) -> String {
        let (num_tabs, num_spaces) = if config.hard_tabs {
            (self.block_indent / config.tab_spaces, self.alignment)
        } else {
            (0, self.block_indent + self.alignment)
        };
        let num_chars = num_tabs + num_spaces;
        let mut indent = String::with_capacity(num_chars);
        for _ in 0..num_tabs {
            indent.push('\t')
        }
        for _ in 0..num_spaces {
            indent.push(' ')
        }
        indent
    }
}

impl Add for Indent {
    type Output = Indent;

    fn add(self, rhs: Indent) -> Indent {
        Indent {
            block_indent: self.block_indent + rhs.block_indent,
            alignment: self.alignment + rhs.alignment,
        }
    }
}

impl Sub for Indent {
    type Output = Indent;

    fn sub(self, rhs: Indent) -> Indent {
        Indent::new(self.block_indent - rhs.block_indent,
                    self.alignment - rhs.alignment)
    }
}

impl Add<usize> for Indent {
    type Output = Indent;

    fn add(self, rhs: usize) -> Indent {
        Indent::new(self.block_indent, self.alignment + rhs)
    }
}

impl Sub<usize> for Indent {
    type Output = Indent;

    fn sub(self, rhs: usize) -> Indent {
        Indent::new(self.block_indent, self.alignment - rhs)
    }
}

#[derive(Copy, Clone)]
pub enum WriteMode {
    // Backups the original file and overwrites the orignal.
    Replace,
    // Overwrites original file without backup.
    Overwrite,
    // str is the extension of the new file.
    NewFile(&'static str),
    // Write the output to stdout.
    Display,
    // Write the diff to stdout.
    Diff,
    // Return the result as a mapping from filenames to Strings.
    Return,
    // Display how much of the input file was processed
    Coverage,
    // Unfancy stdout
    Plain,
}

impl FromStr for WriteMode {
    type Err = ();

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "replace" => Ok(WriteMode::Replace),
            "display" => Ok(WriteMode::Display),
            "overwrite" => Ok(WriteMode::Overwrite),
            "diff" => Ok(WriteMode::Diff),
            "coverage" => Ok(WriteMode::Coverage),
            "plain" => Ok(WriteMode::Plain),
            _ => Err(()),
        }
    }
}

pub enum ErrorKind {
    // Line has exceeded character limit
    LineOverflow,
    // Line ends in whitespace
    TrailingWhitespace,
    // TO-DO or FIX-ME item without an issue number
    BadIssue(Issue),
}

impl fmt::Display for ErrorKind {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match *self {
            ErrorKind::LineOverflow => {
                write!(fmt, "line exceeded maximum length")
            }
            ErrorKind::TrailingWhitespace => {
                write!(fmt, "left behind trailing whitespace")
            }
            ErrorKind::BadIssue(issue) => {
                write!(fmt, "found {}", issue)
            }
        }
    }
}

// Formatting errors that are identified *after* rustfmt has run.
pub struct FormattingError {
    line: u32,
    kind: ErrorKind,
}

impl FormattingError {
    fn msg_prefix(&self) -> &str {
        match self.kind {
            ErrorKind::LineOverflow |
            ErrorKind::TrailingWhitespace => "Rustfmt failed at",
            ErrorKind::BadIssue(_) => "WARNING:",
        }
    }

    fn msg_suffix(&self) -> &str {
        match self.kind {
            ErrorKind::LineOverflow |
            ErrorKind::TrailingWhitespace => "(sorry)",
            ErrorKind::BadIssue(_) => "",
        }
    }
}

pub struct FormatReport {
    // Maps stringified file paths to their associated formatting errors.
    file_error_map: HashMap<String, Vec<FormattingError>>,
}

impl FormatReport {
    pub fn warning_count(&self) -> usize {
        self.file_error_map.iter().map(|(_, ref errors)| errors.len()).fold(0, |acc, x| acc + x)
    }
}

impl fmt::Display for FormatReport {
    // Prints all the formatting errors.
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        for (file, errors) in &self.file_error_map {
            for error in errors {
                try!(write!(fmt,
                            "{} {}:{}: {} {}\n",
                            error.msg_prefix(),
                            file,
                            error.line,
                            error.kind,
                            error.msg_suffix()));
            }
        }
        Ok(())
    }
}

// Formatting which depends on the AST.
fn fmt_ast(krate: &ast::Crate,
           parse_session: &ParseSess,
           config: &Config,
           mode: WriteMode)
           -> FileMap {
    let mut file_map = FileMap::new();
    for (path, module) in modules::list_files(krate, parse_session.codemap()) {
        let path = path.to_str().unwrap();
        let mut visitor = FmtVisitor::from_codemap(parse_session, config, Some(mode));
        visitor.format_separate_mod(module, path);
        file_map.insert(path.to_owned(), visitor.buffer);
    }
    file_map
}

// Formatting done on a char by char or line by line basis.
// TODO(#209) warn on bad license
// TODO(#20) other stuff for parity with make tidy
pub fn fmt_lines(file_map: &mut FileMap, config: &Config) -> FormatReport {
    let mut truncate_todo = Vec::new();
    let mut report = FormatReport { file_error_map: HashMap::new() };

    // Iterate over the chars in the file map.
    for (f, text) in file_map.iter() {
        let mut trims = vec![];
        let mut last_wspace: Option<usize> = None;
        let mut line_len = 0;
        let mut cur_line = 1;
        let mut newline_count = 0;
        let mut errors = vec![];
        let mut issue_seeker = BadIssueSeeker::new(config.report_todo, config.report_fixme);

        for (c, b) in text.chars() {
            if c == '\r' {
                continue;
            }

            // Add warnings for bad todos/ fixmes
            if let Some(issue) = issue_seeker.inspect(c) {
                errors.push(FormattingError {
                    line: cur_line,
                    kind: ErrorKind::BadIssue(issue),
                });
            }

            if c == '\n' {
                // Check for (and record) trailing whitespace.
                if let Some(lw) = last_wspace {
                    trims.push((cur_line, lw, b));
                    line_len -= b - lw;
                }
                // Check for any line width errors we couldn't correct.
                if line_len > config.max_width {
                    errors.push(FormattingError {
                        line: cur_line,
                        kind: ErrorKind::LineOverflow,
                    });
                }
                line_len = 0;
                cur_line += 1;
                newline_count += 1;
                last_wspace = None;
            } else {
                newline_count = 0;
                line_len += 1;
                if c.is_whitespace() {
                    if last_wspace.is_none() {
                        last_wspace = Some(b);
                    }
                } else {
                    last_wspace = None;
                }
            }
        }

        if newline_count > 1 {
            debug!("track truncate: {} {} {}", f, text.len, newline_count);
            truncate_todo.push((f.to_owned(), text.len - newline_count + 1))
        }

        for &(l, _, _) in &trims {
            errors.push(FormattingError {
                line: l,
                kind: ErrorKind::TrailingWhitespace,
            });
        }

        report.file_error_map.insert(f.to_owned(), errors);
    }

    for (f, l) in truncate_todo {
        file_map.get_mut(&f).unwrap().truncate(l);
    }

    report
}

pub fn format_string(input: String, config: &Config, mode: WriteMode) -> FileMap {
    let path = "stdin";
    let mut parse_session = ParseSess::new();
    let krate = parse::parse_crate_from_source_str(path.to_owned(),
                                                   input,
                                                   Vec::new(),
                                                   &parse_session);

    // Suppress error output after parsing.
    let emitter = Box::new(EmitterWriter::new(Box::new(Vec::new()), None));
    parse_session.span_diagnostic.handler = Handler::with_emitter(false, emitter);

    // FIXME: we still use a FileMap even though we only have
    // one file, because fmt_lines requires a FileMap
    let mut file_map = FileMap::new();

    // do the actual formatting
    let mut visitor = FmtVisitor::from_codemap(&parse_session, config, Some(mode));
    visitor.format_separate_mod(&krate.module, path);

    // append final newline
    visitor.buffer.push_str("\n");
    file_map.insert(path.to_owned(), visitor.buffer);

    return file_map;
}

pub fn format(file: &Path, config: &Config, mode: WriteMode) -> FileMap {
    let mut parse_session = ParseSess::new();
    let krate = parse::parse_crate_from_file(file, Vec::new(), &parse_session);

    // Suppress error output after parsing.
    let emitter = Box::new(EmitterWriter::new(Box::new(Vec::new()), None));
    parse_session.span_diagnostic.handler = Handler::with_emitter(false, emitter);

    let mut file_map = fmt_ast(&krate, &parse_session, config, mode);

    // For some reason, the codemap does not include terminating
    // newlines so we must add one on for each file. This is sad.
    filemap::append_newlines(&mut file_map);

    return file_map;
}

// args are the arguments passed on the command line, generally passed through
// to the compiler.
// write_mode determines what happens to the result of running rustfmt, see
// WriteMode.
pub fn run(file: &Path, write_mode: WriteMode, config: &Config) {
    let mut result = format(file, config, write_mode);

    println!("{}", fmt_lines(&mut result, config));

    let write_result = filemap::write_all_files(&result, write_mode, config);

    if let Err(msg) = write_result {
        println!("Error writing files: {}", msg);
    }
}

// Similar to run, but takes an input String instead of a file to format
pub fn run_from_stdin(input: String, mode: WriteMode, config: &Config) {
    let mut result = format_string(input, config, mode);
    fmt_lines(&mut result, config);

    let write_result = filemap::write_file(&result["stdin"], "stdin", mode, config);

    if let Err(msg) = write_result {
        panic!("Error writing to stdout: {}", msg);
    }
}
<commit_msg>Don't print an unnecessary newline after printing format report<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// TODO we're going to allocate a whole bunch of temp Strings, is it worth
// keeping some scratch mem for this and running our own StrPool?
// TODO for lint violations of names, emit a refactor script

#[macro_use]
extern crate log;

extern crate syntex_syntax as syntax;
extern crate rustc_serialize;

extern crate strings;

extern crate unicode_segmentation;
extern crate regex;
extern crate diff;
extern crate term;

use syntax::ast;
use syntax::codemap::Span;
use syntax::diagnostic::{EmitterWriter, Handler};
use syntax::parse::{self, ParseSess};

use std::ops::{Add, Sub};
use std::path::Path;
use std::collections::HashMap;
use std::fmt;
use std::str::FromStr;

use issues::{BadIssueSeeker, Issue};
use filemap::FileMap;
use visitor::FmtVisitor;
use config::Config;

#[macro_use]
mod utils;
pub mod config;
pub mod filemap;
mod visitor;
mod items;
mod missed_spans;
mod lists;
mod types;
mod expr;
mod imports;
mod issues;
mod rewrite;
mod string;
mod comment;
mod modules;
pub mod rustfmt_diff;
mod chains;
mod macros;
mod patterns;

const MIN_STRING: usize = 10;
// When we get scoped annotations, we should have rustfmt::skip.
const SKIP_ANNOTATION: &'static str = "rustfmt_skip";

pub trait Spanned {
    fn span(&self) -> Span;
}

impl Spanned for ast::Expr {
    fn span(&self) -> Span {
        self.span
    }
}

impl Spanned for ast::Pat {
    fn span(&self) -> Span {
        self.span
    }
}

impl Spanned for ast::Ty {
    fn span(&self) -> Span {
        self.span
    }
}

#[derive(Copy, Clone, Debug)]
pub struct Indent {
    // Width of the block indent, in characters. Must be a multiple of
    // Config::tab_spaces.
    pub block_indent: usize,
    // Alignment in characters.
    pub alignment: usize,
}

impl Indent {
    pub fn new(block_indent: usize, alignment: usize) -> Indent {
        Indent {
            block_indent: block_indent,
            alignment: alignment,
        }
    }

    pub fn empty() -> Indent {
        Indent::new(0, 0)
    }

    pub fn block_indent(mut self, config: &Config) -> Indent {
        self.block_indent += config.tab_spaces;
        self
    }

    pub fn block_unindent(mut self, config: &Config) -> Indent {
        self.block_indent -= config.tab_spaces;
        self
    }

    pub fn width(&self) -> usize {
        self.block_indent + self.alignment
    }

    pub fn to_string(&self, config: &Config) -> String {
        let (num_tabs, num_spaces) = if config.hard_tabs {
            (self.block_indent / config.tab_spaces, self.alignment)
        } else {
            (0, self.block_indent + self.alignment)
        };
        let num_chars = num_tabs + num_spaces;
        let mut indent = String::with_capacity(num_chars);
        for _ in 0..num_tabs {
            indent.push('\t')
        }
        for _ in 0..num_spaces {
            indent.push(' ')
        }
        indent
    }
}

impl Add for Indent {
    type Output = Indent;

    fn add(self, rhs: Indent) -> Indent {
        Indent {
            block_indent: self.block_indent + rhs.block_indent,
            alignment: self.alignment + rhs.alignment,
        }
    }
}

impl Sub for Indent {
    type Output = Indent;

    fn sub(self, rhs: Indent) -> Indent {
        Indent::new(self.block_indent - rhs.block_indent,
                    self.alignment - rhs.alignment)
    }
}

impl Add<usize> for Indent {
    type Output = Indent;

    fn add(self, rhs: usize) -> Indent {
        Indent::new(self.block_indent, self.alignment + rhs)
    }
}

impl Sub<usize> for Indent {
    type Output = Indent;

    fn sub(self, rhs: usize) -> Indent {
        Indent::new(self.block_indent, self.alignment - rhs)
    }
}

#[derive(Copy, Clone)]
pub enum WriteMode {
    // Backups the original file and overwrites the orignal.
    Replace,
    // Overwrites original file without backup.
    Overwrite,
    // str is the extension of the new file.
    NewFile(&'static str),
    // Write the output to stdout.
    Display,
    // Write the diff to stdout.
    Diff,
    // Return the result as a mapping from filenames to Strings.
    Return,
    // Display how much of the input file was processed
    Coverage,
    // Unfancy stdout
    Plain,
}

impl FromStr for WriteMode {
    type Err = ();

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "replace" => Ok(WriteMode::Replace),
            "display" => Ok(WriteMode::Display),
            "overwrite" => Ok(WriteMode::Overwrite),
            "diff" => Ok(WriteMode::Diff),
            "coverage" => Ok(WriteMode::Coverage),
            "plain" => Ok(WriteMode::Plain),
            _ => Err(()),
        }
    }
}

pub enum ErrorKind {
    // Line has exceeded character limit
    LineOverflow,
    // Line ends in whitespace
    TrailingWhitespace,
    // TO-DO or FIX-ME item without an issue number
    BadIssue(Issue),
}

impl fmt::Display for ErrorKind {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match *self {
            ErrorKind::LineOverflow => {
                write!(fmt, "line exceeded maximum length")
            }
            ErrorKind::TrailingWhitespace => {
                write!(fmt, "left behind trailing whitespace")
            }
            ErrorKind::BadIssue(issue) => {
                write!(fmt, "found {}", issue)
            }
        }
    }
}

// Formatting errors that are identified *after* rustfmt has run.
pub struct FormattingError {
    line: u32,
    kind: ErrorKind,
}

impl FormattingError {
    fn msg_prefix(&self) -> &str {
        match self.kind {
            ErrorKind::LineOverflow |
            ErrorKind::TrailingWhitespace => "Rustfmt failed at",
            ErrorKind::BadIssue(_) => "WARNING:",
        }
    }

    fn msg_suffix(&self) -> &str {
        match self.kind {
            ErrorKind::LineOverflow |
            ErrorKind::TrailingWhitespace => "(sorry)",
            ErrorKind::BadIssue(_) => "",
        }
    }
}

pub struct FormatReport {
    // Maps stringified file paths to their associated formatting errors.
    file_error_map: HashMap<String, Vec<FormattingError>>,
}

impl FormatReport {
    pub fn warning_count(&self) -> usize {
        self.file_error_map.iter().map(|(_, ref errors)| errors.len()).fold(0, |acc, x| acc + x)
    }
}

impl fmt::Display for FormatReport {
    // Prints all the formatting errors.
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        for (file, errors) in &self.file_error_map {
            for error in errors {
                try!(write!(fmt,
                            "{} {}:{}: {} {}\n",
                            error.msg_prefix(),
                            file,
                            error.line,
                            error.kind,
                            error.msg_suffix()));
            }
        }
        Ok(())
    }
}

// Formatting which depends on the AST.
fn fmt_ast(krate: &ast::Crate,
           parse_session: &ParseSess,
           config: &Config,
           mode: WriteMode)
           -> FileMap {
    let mut file_map = FileMap::new();
    for (path, module) in modules::list_files(krate, parse_session.codemap()) {
        let path = path.to_str().unwrap();
        let mut visitor = FmtVisitor::from_codemap(parse_session, config, Some(mode));
        visitor.format_separate_mod(module, path);
        file_map.insert(path.to_owned(), visitor.buffer);
    }
    file_map
}

// Formatting done on a char by char or line by line basis.
// TODO(#209) warn on bad license
// TODO(#20) other stuff for parity with make tidy
pub fn fmt_lines(file_map: &mut FileMap, config: &Config) -> FormatReport {
    let mut truncate_todo = Vec::new();
    let mut report = FormatReport { file_error_map: HashMap::new() };

    // Iterate over the chars in the file map.
    for (f, text) in file_map.iter() {
        let mut trims = vec![];
        let mut last_wspace: Option<usize> = None;
        let mut line_len = 0;
        let mut cur_line = 1;
        let mut newline_count = 0;
        let mut errors = vec![];
        let mut issue_seeker = BadIssueSeeker::new(config.report_todo, config.report_fixme);

        for (c, b) in text.chars() {
            if c == '\r' {
                continue;
            }

            // Add warnings for bad todos/ fixmes
            if let Some(issue) = issue_seeker.inspect(c) {
                errors.push(FormattingError {
                    line: cur_line,
                    kind: ErrorKind::BadIssue(issue),
                });
            }

            if c == '\n' {
                // Check for (and record) trailing whitespace.
                if let Some(lw) = last_wspace {
                    trims.push((cur_line, lw, b));
                    line_len -= b - lw;
                }
                // Check for any line width errors we couldn't correct.
                if line_len > config.max_width {
                    errors.push(FormattingError {
                        line: cur_line,
                        kind: ErrorKind::LineOverflow,
                    });
                }
                line_len = 0;
                cur_line += 1;
                newline_count += 1;
                last_wspace = None;
            } else {
                newline_count = 0;
                line_len += 1;
                if c.is_whitespace() {
                    if last_wspace.is_none() {
                        last_wspace = Some(b);
                    }
                } else {
                    last_wspace = None;
                }
            }
        }

        if newline_count > 1 {
            debug!("track truncate: {} {} {}", f, text.len, newline_count);
            truncate_todo.push((f.to_owned(), text.len - newline_count + 1))
        }

        for &(l, _, _) in &trims {
            errors.push(FormattingError {
                line: l,
                kind: ErrorKind::TrailingWhitespace,
            });
        }

        report.file_error_map.insert(f.to_owned(), errors);
    }

    for (f, l) in truncate_todo {
        file_map.get_mut(&f).unwrap().truncate(l);
    }

    report
}

pub fn format_string(input: String, config: &Config, mode: WriteMode) -> FileMap {
    let path = "stdin";
    let mut parse_session = ParseSess::new();
    let krate = parse::parse_crate_from_source_str(path.to_owned(),
                                                   input,
                                                   Vec::new(),
                                                   &parse_session);

    // Suppress error output after parsing.
    let emitter = Box::new(EmitterWriter::new(Box::new(Vec::new()), None));
    parse_session.span_diagnostic.handler = Handler::with_emitter(false, emitter);

    // FIXME: we still use a FileMap even though we only have
    // one file, because fmt_lines requires a FileMap
    let mut file_map = FileMap::new();

    // do the actual formatting
    let mut visitor = FmtVisitor::from_codemap(&parse_session, config, Some(mode));
    visitor.format_separate_mod(&krate.module, path);

    // append final newline
    visitor.buffer.push_str("\n");
    file_map.insert(path.to_owned(), visitor.buffer);

    return file_map;
}

pub fn format(file: &Path, config: &Config, mode: WriteMode) -> FileMap {
    let mut parse_session = ParseSess::new();
    let krate = parse::parse_crate_from_file(file, Vec::new(), &parse_session);

    // Suppress error output after parsing.
    let emitter = Box::new(EmitterWriter::new(Box::new(Vec::new()), None));
    parse_session.span_diagnostic.handler = Handler::with_emitter(false, emitter);

    let mut file_map = fmt_ast(&krate, &parse_session, config, mode);

    // For some reason, the codemap does not include terminating
    // newlines so we must add one on for each file. This is sad.
    filemap::append_newlines(&mut file_map);

    return file_map;
}

// args are the arguments passed on the command line, generally passed through
// to the compiler.
// write_mode determines what happens to the result of running rustfmt, see
// WriteMode.
pub fn run(file: &Path, write_mode: WriteMode, config: &Config) {
    let mut result = format(file, config, write_mode);

    print!("{}", fmt_lines(&mut result, config));

    let write_result = filemap::write_all_files(&result, write_mode, config);

    if let Err(msg) = write_result {
        println!("Error writing files: {}", msg);
    }
}

// Similar to run, but takes an input String instead of a file to format
pub fn run_from_stdin(input: String, mode: WriteMode, config: &Config) {
    let mut result = format_string(input, config, mode);
    fmt_lines(&mut result, config);

    let write_result = filemap::write_file(&result["stdin"], "stdin", mode, config);

    if let Err(msg) = write_result {
        panic!("Error writing to stdout: {}", msg);
    }
}
<|endoftext|>


<commit_before>//! Iterator zippers
//!
//! This crate provides "zippers" as tuple structs: `Zip2`, `Zip3`, etc. These structs accept
//! iterators as fields, and provides iteration over the "zipped" elements.
//!
//! The functionality is similar to the `Iterator::zip` method. The difference is that the `zip`
//! method always produces an iterator that yields *two-element* tuples. If you want to zip 3
//! iterators, you'll write `xs.zip(ys).zip(zs)` which returns an iterator that yields elements of
//! type `((X, Y), Z)`. On the other hand, with this library you can write `Zip3(xs, ys, zs)` which
//! is an iterator that yields elements of type `(X, Y, Z)`.
//!
//! ```
//! use zip::Zip3;
//!
//! let chars = &['a', 'b', 'c'];
//! let mut v = vec![0, 1, 2];
//! for (&c, i, &mut j) in Zip3(chars.iter(), 0..5, v.iter_mut()) {
//!     assert!(i < 3);
//!     assert_eq!(i, j);
//! }
//! ```

#![allow(unstable)]
#![deny(missing_docs, warnings)]

/// This macro emulates an "any-arity" free function that zips iterators
///
/// **Note** This macro calls `into_iter()` on the inputs. For this reason, this macro won't work
/// until `IntoIterator` lands in stdlib, or unless you provide your own `IntoIterator` trait.
///
/// # Examples
///
/// ```
/// #[macro_use]
/// extern crate zip;
///
/// # use std::slice;
/// # trait IntoIterator {
/// #     type Iter: Iterator;
/// #     fn into_iter(self) -> Self::Iter;
/// # }
/// # impl<I> IntoIterator for I where I: Iterator {
/// #     type Iter = I;
/// #     fn into_iter(self) -> I { self }
/// # }
/// # impl<'a, T> IntoIterator for &'a [T] {
/// #     type Iter = slice::Iter<'a, T>;
/// #     fn into_iter(self) -> slice::Iter<'a, T> { self.iter() }
/// # }
/// # impl<'a, T> IntoIterator for &'a mut Vec<T> {
/// #     type Iter = slice::IterMut<'a, T>;
/// #     fn into_iter(self) -> slice::IterMut<'a, T> { self.iter_mut() }
/// # }
/// # fn main() {
/// let chars = &['a', 'b', 'c'];
/// let mut v = vec![0, 1, 2];
///
/// for (&c, i, &mut j) in zip!(chars, 0..5, &mut v) {
///     assert!(i < 3);
///     assert_eq!(i, j);
/// }
/// # }
/// ```
#[macro_export]
macro_rules! zip {
    ($a:expr, $b:expr) => {
        $crate::Zip2(($a).into_iter(), ($b).into_iter())
    };
    ($a:expr, $b:expr, $c:expr) => {
        $crate::Zip3(($a).into_iter(), ($b).into_iter(), ($c).into_iter())
    };
    ($a:expr, $b:expr, $c:expr, $d:expr) => {
        $crate::Zip4(($a).into_iter(), ($b).into_iter(), ($c).into_iter(), ($d).into_iter())
    };
    ($a:expr, $b:expr, $c:expr, $d:expr, $e:expr) => {
        $crate::Zip5(
            ($a).into_iter(),
            ($b).into_iter(),
            ($c).into_iter(),
            ($d).into_iter(),
            ($e).into_iter(),
        )
    };
    ($($x:expr),+,) => { zip!($($x),+) }
}

macro_rules! min {
    ($x:expr) => { $x };
    ($x:expr, $($y:expr),+) => { ::std::cmp::min($x, min!($($y),+)) };
    ($($x:expr),+,) => { min!($($x),+) };
}

/// Two-iterator zipper
pub struct Zip2<A, B>(pub A, pub B);

impl<A, B, AI, BI> Iterator for Zip2<AI, BI> where
    AI: Iterator<Item=A>,
    BI: Iterator<Item=B>,
{
    type Item = (A, B);

    fn next(&mut self) -> Option<(A, B)> {
        if let Some(a) = self.0.next() {
            if let Some(b) = self.1.next() {
                return Some((a, b));
            }
        }

        None
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (min!{
            self.0.size_hint().0,
            self.1.size_hint().0,
        }, None)
    }
}

/// Three-iterator zipper
pub struct Zip3<A, B, C>(pub A, pub B, pub C);

impl<A, B, C, AI, BI, CI> Iterator for Zip3<AI, BI, CI> where
    AI: Iterator<Item=A>,
    BI: Iterator<Item=B>,
    CI: Iterator<Item=C>,
{
    type Item = (A, B, C);

    fn next(&mut self) -> Option<(A, B, C)> {
        if let Some(a) = self.0.next() {
            if let Some(b) = self.1.next() {
                if let Some(c) = self.2.next() {
                    return Some((a, b, c));
                }
            }
        }

        None
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (min!{
            self.0.size_hint().0,
            self.1.size_hint().0,
            self.2.size_hint().0,
        }, None)
    }
}

/// Four-iterator zipper
pub struct Zip4<A, B, C, D>(pub A, pub B, pub C, pub D);

impl<A, B, C, D, AI, BI, CI, DI> Iterator for Zip4<AI, BI, CI, DI> where
    AI: Iterator<Item=A>,
    BI: Iterator<Item=B>,
    CI: Iterator<Item=C>,
    DI: Iterator<Item=D>,
{
    type Item = (A, B, C, D);

    fn next(&mut self) -> Option<(A, B, C, D)> {
        if let Some(a) = self.0.next() {
            if let Some(b) = self.1.next() {
                if let Some(c) = self.2.next() {
                    if let Some(d) = self.3.next() {
                        return Some((a, b, c, d))
                    }
                }
            }
        }

        None
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (min!{
            self.0.size_hint().0,
            self.1.size_hint().0,
            self.2.size_hint().0,
            self.3.size_hint().0,
        }, None)
    }
}

/// Five-iterator zipper
pub struct Zip5<A, B, C, D, E>(pub A, pub B, pub C, pub D, pub E);

impl<A, B, C, D, E, AI, BI, CI, DI, EI> Iterator for Zip5<AI, BI, CI, DI, EI> where
    AI: Iterator<Item=A>,
    BI: Iterator<Item=B>,
    CI: Iterator<Item=C>,
    DI: Iterator<Item=D>,
    EI: Iterator<Item=E>,
{
    type Item = (A, B, C, D, E);

    fn next(&mut self) -> Option<(A, B, C, D, E)> {
        if let Some(a) = self.0.next() {
            if let Some(b) = self.1.next() {
                if let Some(c) = self.2.next() {
                    if let Some(d) = self.3.next() {
                        if let Some(e) = self.4.next() {
                            return Some((a, b, c, d, e))
                        }
                    }
                }
            }
        }

        None
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (min!{
            self.0.size_hint().0,
            self.1.size_hint().0,
            self.2.size_hint().0,
            self.3.size_hint().0,
            self.4.size_hint().0,
        }, None)
    }
}

#[cfg(test)]
mod bench {
    extern crate test;

    use self::test::Bencher;

    const SIZE: usize = 1024;

    #[bench]
    fn collect2(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let b = a;

        z.iter(|| {
            ::Zip2(a.iter(), b.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn collect2_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let b = a;

        z.iter(|| {
            a.iter().zip(b.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn count2(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let b = a;

        z.iter(|| {
            ::Zip2(a.iter(), b.iter()).count()
        })
    }

    #[bench]
    fn count2_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let b = a;

        z.iter(|| {
            a.iter().zip(b.iter()).count()
        })
    }

    #[bench]
    fn collect3(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c) = (a, a);

        z.iter(|| {
            ::Zip3(a.iter(), b.iter(), c.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn collect3_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c) = (a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn count3(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c) = (a, a);

        z.iter(|| {
            ::Zip3(a.iter(), b.iter(), c.iter()).count()
        })
    }

    #[bench]
    fn count3_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c) = (a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).count()
        })
    }

    #[bench]
    fn collect4(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d) = (a, a, a);

        z.iter(|| {
            ::Zip4(a.iter(), b.iter(), c.iter(), d.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn collect4_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d) = (a, a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).zip(d.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn count4(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d) = (a, a, a);

        z.iter(|| {
            ::Zip4(a.iter(), b.iter(), c.iter(), d.iter()).count()
        })
    }

    #[bench]
    fn count4_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d) = (a, a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).zip(d.iter()).count()
        })
    }

    #[bench]
    fn collect5(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d, e) = (a, a, a, a);

        z.iter(|| {
            ::Zip5(a.iter(), b.iter(), c.iter(), d.iter(), e.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn collect5_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d, e) = (a, a, a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).zip(d.iter()).zip(e.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn count5(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d, e) = (a, a, a, a);

        z.iter(|| {
            ::Zip5(a.iter(), b.iter(), c.iter(), d.iter(), e.iter()).count()
        })
    }

    #[bench]
    fn count5_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d, e) = (a, a, a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).zip(d.iter()).zip(e.iter()).count()
        })
    }
}
<commit_msg>fix doctests<commit_after>//! Iterator zippers
//!
//! This crate provides "zippers" as tuple structs: `Zip2`, `Zip3`, etc. These structs accept
//! iterators as fields, and provides iteration over the "zipped" elements.
//!
//! The functionality is similar to the `Iterator::zip` method. The difference is that the `zip`
//! method always produces an iterator that yields *two-element* tuples. If you want to zip 3
//! iterators, you'll write `xs.zip(ys).zip(zs)` which returns an iterator that yields elements of
//! type `((X, Y), Z)`. On the other hand, with this library you can write `Zip3(xs, ys, zs)` which
//! is an iterator that yields elements of type `(X, Y, Z)`.
//!
//! ```
//! use zip::Zip3;
//!
//! let chars = &['a', 'b', 'c'];
//! let mut v = vec![0, 1, 2];
//! for (&c, i, &mut j) in Zip3(chars.iter(), 0i32..5, v.iter_mut()) {
//!     assert!(i < 3);
//!     assert_eq!(i, j);
//! }
//! ```

#![allow(unstable)]
#![deny(missing_docs, warnings)]

/// This macro emulates an "any-arity" free function that zips iterators
///
/// **Note** This macro calls `into_iter()` on the inputs. For this reason, this macro won't work
/// until `IntoIterator` lands in stdlib, or unless you provide your own `IntoIterator` trait.
///
/// # Examples
///
/// ```
/// #[macro_use]
/// extern crate zip;
///
/// # use std::slice;
/// # trait IntoIterator {
/// #     type Iter: Iterator;
/// #     fn into_iter(self) -> Self::Iter;
/// # }
/// # impl<I> IntoIterator for I where I: Iterator {
/// #     type Iter = I;
/// #     fn into_iter(self) -> I { self }
/// # }
/// # impl<'a, T> IntoIterator for &'a [T] {
/// #     type Iter = slice::Iter<'a, T>;
/// #     fn into_iter(self) -> slice::Iter<'a, T> { self.iter() }
/// # }
/// # impl<'a, T> IntoIterator for &'a mut Vec<T> {
/// #     type Iter = slice::IterMut<'a, T>;
/// #     fn into_iter(self) -> slice::IterMut<'a, T> { self.iter_mut() }
/// # }
/// # fn main() {
/// let chars = &['a', 'b', 'c'];
/// let mut v = vec![0, 1, 2];
///
/// for (&c, i, &mut j) in zip!(chars, 0i32..5, &mut v) {
///     assert!(i < 3);
///     assert_eq!(i, j);
/// }
/// # }
/// ```
#[macro_export]
macro_rules! zip {
    ($a:expr, $b:expr) => {
        $crate::Zip2(($a).into_iter(), ($b).into_iter())
    };
    ($a:expr, $b:expr, $c:expr) => {
        $crate::Zip3(($a).into_iter(), ($b).into_iter(), ($c).into_iter())
    };
    ($a:expr, $b:expr, $c:expr, $d:expr) => {
        $crate::Zip4(($a).into_iter(), ($b).into_iter(), ($c).into_iter(), ($d).into_iter())
    };
    ($a:expr, $b:expr, $c:expr, $d:expr, $e:expr) => {
        $crate::Zip5(
            ($a).into_iter(),
            ($b).into_iter(),
            ($c).into_iter(),
            ($d).into_iter(),
            ($e).into_iter(),
        )
    };
    ($($x:expr),+,) => { zip!($($x),+) }
}

macro_rules! min {
    ($x:expr) => { $x };
    ($x:expr, $($y:expr),+) => { ::std::cmp::min($x, min!($($y),+)) };
    ($($x:expr),+,) => { min!($($x),+) };
}

/// Two-iterator zipper
pub struct Zip2<A, B>(pub A, pub B);

impl<A, B, AI, BI> Iterator for Zip2<AI, BI> where
    AI: Iterator<Item=A>,
    BI: Iterator<Item=B>,
{
    type Item = (A, B);

    fn next(&mut self) -> Option<(A, B)> {
        if let Some(a) = self.0.next() {
            if let Some(b) = self.1.next() {
                return Some((a, b));
            }
        }

        None
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (min!{
            self.0.size_hint().0,
            self.1.size_hint().0,
        }, None)
    }
}

/// Three-iterator zipper
pub struct Zip3<A, B, C>(pub A, pub B, pub C);

impl<A, B, C, AI, BI, CI> Iterator for Zip3<AI, BI, CI> where
    AI: Iterator<Item=A>,
    BI: Iterator<Item=B>,
    CI: Iterator<Item=C>,
{
    type Item = (A, B, C);

    fn next(&mut self) -> Option<(A, B, C)> {
        if let Some(a) = self.0.next() {
            if let Some(b) = self.1.next() {
                if let Some(c) = self.2.next() {
                    return Some((a, b, c));
                }
            }
        }

        None
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (min!{
            self.0.size_hint().0,
            self.1.size_hint().0,
            self.2.size_hint().0,
        }, None)
    }
}

/// Four-iterator zipper
pub struct Zip4<A, B, C, D>(pub A, pub B, pub C, pub D);

impl<A, B, C, D, AI, BI, CI, DI> Iterator for Zip4<AI, BI, CI, DI> where
    AI: Iterator<Item=A>,
    BI: Iterator<Item=B>,
    CI: Iterator<Item=C>,
    DI: Iterator<Item=D>,
{
    type Item = (A, B, C, D);

    fn next(&mut self) -> Option<(A, B, C, D)> {
        if let Some(a) = self.0.next() {
            if let Some(b) = self.1.next() {
                if let Some(c) = self.2.next() {
                    if let Some(d) = self.3.next() {
                        return Some((a, b, c, d))
                    }
                }
            }
        }

        None
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (min!{
            self.0.size_hint().0,
            self.1.size_hint().0,
            self.2.size_hint().0,
            self.3.size_hint().0,
        }, None)
    }
}

/// Five-iterator zipper
pub struct Zip5<A, B, C, D, E>(pub A, pub B, pub C, pub D, pub E);

impl<A, B, C, D, E, AI, BI, CI, DI, EI> Iterator for Zip5<AI, BI, CI, DI, EI> where
    AI: Iterator<Item=A>,
    BI: Iterator<Item=B>,
    CI: Iterator<Item=C>,
    DI: Iterator<Item=D>,
    EI: Iterator<Item=E>,
{
    type Item = (A, B, C, D, E);

    fn next(&mut self) -> Option<(A, B, C, D, E)> {
        if let Some(a) = self.0.next() {
            if let Some(b) = self.1.next() {
                if let Some(c) = self.2.next() {
                    if let Some(d) = self.3.next() {
                        if let Some(e) = self.4.next() {
                            return Some((a, b, c, d, e))
                        }
                    }
                }
            }
        }

        None
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (min!{
            self.0.size_hint().0,
            self.1.size_hint().0,
            self.2.size_hint().0,
            self.3.size_hint().0,
            self.4.size_hint().0,
        }, None)
    }
}

#[cfg(test)]
mod bench {
    extern crate test;

    use self::test::Bencher;

    const SIZE: usize = 1024;

    #[bench]
    fn collect2(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let b = a;

        z.iter(|| {
            ::Zip2(a.iter(), b.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn collect2_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let b = a;

        z.iter(|| {
            a.iter().zip(b.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn count2(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let b = a;

        z.iter(|| {
            ::Zip2(a.iter(), b.iter()).count()
        })
    }

    #[bench]
    fn count2_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let b = a;

        z.iter(|| {
            a.iter().zip(b.iter()).count()
        })
    }

    #[bench]
    fn collect3(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c) = (a, a);

        z.iter(|| {
            ::Zip3(a.iter(), b.iter(), c.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn collect3_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c) = (a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn count3(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c) = (a, a);

        z.iter(|| {
            ::Zip3(a.iter(), b.iter(), c.iter()).count()
        })
    }

    #[bench]
    fn count3_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c) = (a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).count()
        })
    }

    #[bench]
    fn collect4(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d) = (a, a, a);

        z.iter(|| {
            ::Zip4(a.iter(), b.iter(), c.iter(), d.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn collect4_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d) = (a, a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).zip(d.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn count4(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d) = (a, a, a);

        z.iter(|| {
            ::Zip4(a.iter(), b.iter(), c.iter(), d.iter()).count()
        })
    }

    #[bench]
    fn count4_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d) = (a, a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).zip(d.iter()).count()
        })
    }

    #[bench]
    fn collect5(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d, e) = (a, a, a, a);

        z.iter(|| {
            ::Zip5(a.iter(), b.iter(), c.iter(), d.iter(), e.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn collect5_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d, e) = (a, a, a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).zip(d.iter()).zip(e.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn count5(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d, e) = (a, a, a, a);

        z.iter(|| {
            ::Zip5(a.iter(), b.iter(), c.iter(), d.iter(), e.iter()).count()
        })
    }

    #[bench]
    fn count5_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d, e) = (a, a, a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).zip(d.iter()).zip(e.iter()).count()
        })
    }
}
<|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;

use std::str::FromStr;

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`
    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,
        }
    }
}

/// Constructs a new `IpNetwork` from a given &str with 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.
/// # Examples
///
/// ```
/// use std::net::Ipv4Addr;
/// use ipnetwork::Ipv4Network;
/// use ipnetwork::IpNetwork;
///
/// let expected = IpNetwork::V4(Ipv4Network::new(Ipv4Addr::new(10, 1, 9, 32), 16).unwrap());
/// let from_cidr: IpNetwork = "10.1.9.32/16".parse().unwrap();
/// assert_eq!(expected.ip(), from_cidr.ip());
/// assert_eq!(expected.prefix(), from_cidr.prefix());
impl FromStr for IpNetwork {
    type Err = IpNetworkError;
    fn from_str(s: &str) -> Result<IpNetwork, IpNetworkError> {
        let v4addr: Result<Ipv4Network, IpNetworkError> = s.parse();
        let v6addr: Result<Ipv6Network, IpNetworkError> = s.parse();

        if v4addr.is_ok() {
            Ok(IpNetwork::V4(v4addr.unwrap()))
        } else if v6addr.is_ok() {
            Ok(IpNetwork::V6(v6addr.unwrap()))
        } else {
            Err(IpNetworkError::InvalidAddr(s.to_string()))
        }
    }
}

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>Implement Display for IpNetwork<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::fmt;
use std::net::IpAddr;

mod ipv4;
mod ipv6;
mod common;

use std::str::FromStr;

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`
    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,
        }
    }
}

/// Constructs a new `IpNetwork` from a given &str with 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.
/// # Examples
///
/// ```
/// use std::net::Ipv4Addr;
/// use ipnetwork::Ipv4Network;
/// use ipnetwork::IpNetwork;
///
/// let expected = IpNetwork::V4(Ipv4Network::new(Ipv4Addr::new(10, 1, 9, 32), 16).unwrap());
/// let from_cidr: IpNetwork = "10.1.9.32/16".parse().unwrap();
/// assert_eq!(expected.ip(), from_cidr.ip());
/// assert_eq!(expected.prefix(), from_cidr.prefix());
impl FromStr for IpNetwork {
    type Err = IpNetworkError;
    fn from_str(s: &str) -> Result<IpNetwork, IpNetworkError> {
        let v4addr: Result<Ipv4Network, IpNetworkError> = s.parse();
        let v6addr: Result<Ipv6Network, IpNetworkError> = s.parse();

        if v4addr.is_ok() {
            Ok(IpNetwork::V4(v4addr.unwrap()))
        } else if v6addr.is_ok() {
            Ok(IpNetwork::V6(v6addr.unwrap()))
        } else {
            Err(IpNetworkError::InvalidAddr(s.to_string()))
        }
    }
}

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)
    }
}

impl fmt::Display for IpNetwork {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            IpNetwork::V4(net) => net.fmt(f),
            IpNetwork::V6(net) => net.fmt(f),
        }
    }
}

/// 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>//! Module: zmq

extern crate libc;
extern crate zmq_sys;

use std::ffi;
use std::sync::atomic::{ AtomicBool, Ordering };
use libc::{ c_int, c_void };

pub const ZMQ_VERSION_MAJOR:i32 = 4;
pub const ZMQ_VERSION_MINOR:i32 = 1;
pub const ZMQ_VERSION_PATCH:i32 = 4;

#[macro_export]
macro_rules! ZMQ_MAKE_VERSION {
    ($major: expr, $minor: expr, $patch: expr) => {
        {
            $major * 10000 + $minor * 100 + $patch
        }
    }
}

pub const ZMQ_VERSION:i32 = ZMQ_MAKE_VERSION!(
    ZMQ_VERSION_MAJOR,
    ZMQ_VERSION_MINOR,
    ZMQ_VERSION_PATCH
);

/*
const ZMQ_HAUSNUMERO: c_int = 156384712;

const ENOTSUP: c_int = (ZMQ_HAUSNUMERO + 1);
const EPROTONOSUPPORT: c_int = (ZMQ_HAUSNUMERO + 2);
const ENOBUFS: c_int = (ZMQ_HAUSNUMERO + 3);
const ENETDOWN: c_int = (ZMQ_HAUSNUMERO + 4);
const EADDRINUSE: c_int = (ZMQ_HAUSNUMERO + 5);
const EADDRNOTAVAIL: c_int = (ZMQ_HAUSNUMERO + 6);
const ECONNREFUSED: c_int = (ZMQ_HAUSNUMERO + 7);
const EINPROGRESS: c_int = (ZMQ_HAUSNUMERO + 8);
const ENOTSOCK: c_int = (ZMQ_HAUSNUMERO + 9);
const EMSGSIZE: c_int = (ZMQ_HAUSNUMERO + 10);
const EAFNOSUPPORT: c_int = (ZMQ_HAUSNUMERO + 11);
const ENETUNREACH: c_int = (ZMQ_HAUSNUMERO + 12);
const ECONNABORTED: c_int = (ZMQ_HAUSNUMERO + 13);
const ECONNRESET: c_int = (ZMQ_HAUSNUMERO + 14);
const ENOTCONN: c_int = (ZMQ_HAUSNUMERO + 15);
const ETIMEDOUT: c_int = (ZMQ_HAUSNUMERO + 16);
const EHOSTUNREACH: c_int = (ZMQ_HAUSNUMERO + 17);
const ENETRESET: c_int = (ZMQ_HAUSNUMERO + 18);

const EFSM: c_int = (ZMQ_HAUSNUMERO + 51);
const ENOCOMPATPROTO: c_int = (ZMQ_HAUSNUMERO + 52);
const ETERM: c_int = (ZMQ_HAUSNUMERO + 53);
const EMTHREAD: c_int = (ZMQ_HAUSNUMERO + 54);
*/

pub struct Error {
    err_num: c_int,
}

impl Error {
    fn from_last_err() -> Error {
        let err_num = errno();

        Error {
            err_num: err_num
        }
    }
}

pub fn errno() -> c_int {
    unsafe {
        zmq_sys::zmq_errno()
    }
}

pub fn strerror(errnum: c_int) -> String {
    unsafe {
        let s = zmq_sys::zmq_strerror(errnum);
        ffi::CStr::from_ptr(s).to_str().unwrap().to_string()
    }
}

pub fn version() -> (i32, i32, i32) {
    let mut major = 0;
    let mut minor = 0;
    let mut patch = 0;

    unsafe {
        zmq_sys::zmq_version(&mut major, &mut minor, &mut patch);
    }

    (major as i32, minor as i32, patch as i32)
}

macro_rules! ret_while_null {
    ($ptr: expr) => {{
        if $ptr.is_null() {
            return Err(Error::from_last_err());
        }
    }}
}

#[allow(non_camel_case_types)]
pub enum ContextSetOption {
    ZMQ_IO_THREADS = 1,
    ZMQ_MAX_SOCKETS = 2,
    ZMQ_THREAD_PRIORITY = 3,
    ZMQ_THREAD_SCHED_POLICY = 4,
    ZMQ_IPV6 = 42,
}

#[allow(non_camel_case_types)]
pub enum ContextGetOption {
    ZMQ_IO_THREADS = 1,
    ZMQ_MAX_SOCKETS = 2,
    ZMQ_SOCKET_LIMIT = 3,
    ZMQ_IPV6 = 42,
}

struct Context {
    ctx_ptr: *mut c_void,
}

impl Context {
    /// void *zmq_ctx_new (void)
    pub fn new() -> Result<Context, Error> {
        let ctx_ptr = unsafe { zmq_sys::zmq_ctx_new() };
        ret_while_null!(ctx_ptr);

        Ok(Context {
            ctx_ptr: ctx_ptr,
        })
    }

    /// int zmq_ctx_term (void *context)
    fn term(&mut self) -> Option<Error> {        // trasnfer owner
        let ret_val = unsafe { zmq_sys::zmq_ctx_term(self.ctx_ptr) };
        if ret_val == -1 {
            Some(Error::from_last_err())
        } else {
            None
        }
    }

    /// int zmq_ctx_shutdown (void *ctx_)
    pub fn shutdown(&self) -> Option<Error> {
        let ret_val = unsafe { zmq_sys::zmq_ctx_shutdown(self.ctx_ptr) };
        if ret_val == -1 {
            Some(Error::from_last_err())
        } else {
            None
        }
    }

    /// int zmq_ctx_set (void *context, int option, int optval)
    pub fn set(&self, option_name: ContextSetOption, option_value: c_int) -> Option<Error> {
        let ret_val = unsafe { zmq_sys::zmq_ctx_set(self.ctx_ptr, option_name as c_int, option_value) };
        if ret_val == -1 {
            Some(Error::from_last_err())
        } else {
            None
        }
    }

    /// int zmq_ctx_get (void *context, int option)
    pub fn get(&self, option_name: ContextGetOption) -> Result<c_int, Error> {
        let ret_val = unsafe { zmq_sys::zmq_ctx_get(self.ctx_ptr, option_name as c_int) };
        if ret_val == -1 {
            Err(Error::from_last_err())
        } else {
            Ok(ret_val)
        }
    }
}

impl Drop for Context {
    fn drop(&mut self) {
        self.term().unwrap();
    }
}
<commit_msg>impl Display Error Debug for Error<commit_after>#![allow(dead_code)]

extern crate libc;
extern crate zmq_sys;

use std::ffi;
use libc::{ c_int, c_void };

pub const ZMQ_VERSION_MAJOR:i32 = 4;
pub const ZMQ_VERSION_MINOR:i32 = 1;
pub const ZMQ_VERSION_PATCH:i32 = 4;

macro_rules! ret_while_null {
    ($ptr: expr) => {{
        if $ptr.is_null() {
            return Err(Error::from_last_err());
        }
    }}
}

#[macro_export]
macro_rules! ZMQ_MAKE_VERSION {
    ($major: expr, $minor: expr, $patch: expr) => {
        {
            $major * 10000 + $minor * 100 + $patch
        }
    }
}

pub const ZMQ_VERSION:i32 = ZMQ_MAKE_VERSION!(
    ZMQ_VERSION_MAJOR,
    ZMQ_VERSION_MINOR,
    ZMQ_VERSION_PATCH
);

/*
const ZMQ_HAUSNUMERO: c_int = 156384712;

const ENOTSUP: c_int = (ZMQ_HAUSNUMERO + 1);
const EPROTONOSUPPORT: c_int = (ZMQ_HAUSNUMERO + 2);
const ENOBUFS: c_int = (ZMQ_HAUSNUMERO + 3);
const ENETDOWN: c_int = (ZMQ_HAUSNUMERO + 4);
const EADDRINUSE: c_int = (ZMQ_HAUSNUMERO + 5);
const EADDRNOTAVAIL: c_int = (ZMQ_HAUSNUMERO + 6);
const ECONNREFUSED: c_int = (ZMQ_HAUSNUMERO + 7);
const EINPROGRESS: c_int = (ZMQ_HAUSNUMERO + 8);
const ENOTSOCK: c_int = (ZMQ_HAUSNUMERO + 9);
const EMSGSIZE: c_int = (ZMQ_HAUSNUMERO + 10);
const EAFNOSUPPORT: c_int = (ZMQ_HAUSNUMERO + 11);
const ENETUNREACH: c_int = (ZMQ_HAUSNUMERO + 12);
const ECONNABORTED: c_int = (ZMQ_HAUSNUMERO + 13);
const ECONNRESET: c_int = (ZMQ_HAUSNUMERO + 14);
const ENOTCONN: c_int = (ZMQ_HAUSNUMERO + 15);
const ETIMEDOUT: c_int = (ZMQ_HAUSNUMERO + 16);
const EHOSTUNREACH: c_int = (ZMQ_HAUSNUMERO + 17);
const ENETRESET: c_int = (ZMQ_HAUSNUMERO + 18);

const EFSM: c_int = (ZMQ_HAUSNUMERO + 51);
const ENOCOMPATPROTO: c_int = (ZMQ_HAUSNUMERO + 52);
const ETERM: c_int = (ZMQ_HAUSNUMERO + 53);
const EMTHREAD: c_int = (ZMQ_HAUSNUMERO + 54);
*/

pub fn errno() -> c_int {
    unsafe {
        zmq_sys::zmq_errno()
    }
}

pub fn strerror(errnum: c_int) -> String {
    unsafe {
        let s = zmq_sys::zmq_strerror(errnum);
        ffi::CStr::from_ptr(s).to_str().unwrap().to_string()
    }
}

pub fn version() -> (i32, i32, i32) {
    let mut major = 0;
    let mut minor = 0;
    let mut patch = 0;

    unsafe {
        zmq_sys::zmq_version(&mut major, &mut minor, &mut patch);
    }

    (major as i32, minor as i32, patch as i32)
}

#[derive(Clone)]
pub struct Error {
    err_num: c_int,
    err_str: String,
}

impl Error {
    fn from_last_err() -> Error {
        let err_num = errno();
        let err_str = strerror(err_num);

        Error {
            err_num: err_num,
            err_str: err_str,
        }
    }
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{} (code {})", self.err_str, self.err_num)
    }
}

impl std::fmt::Debug for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        std::fmt::Display::fmt(self, f)
    }
}

impl std::error::Error for Error {
    fn description(&self) -> &str {
        &self.err_str
    }
}

#[allow(non_camel_case_types)]
pub enum ContextSetOption {
    ZMQ_IO_THREADS = 1,
    ZMQ_MAX_SOCKETS = 2,
    ZMQ_THREAD_PRIORITY = 3,
    ZMQ_THREAD_SCHED_POLICY = 4,
    ZMQ_IPV6 = 42,
}

#[allow(non_camel_case_types)]
pub enum ContextGetOption {
    ZMQ_IO_THREADS = 1,
    ZMQ_MAX_SOCKETS = 2,
    ZMQ_SOCKET_LIMIT = 3,
    ZMQ_IPV6 = 42,
}

struct Context {
    ctx_ptr: *mut c_void,
}

impl Context {
    /// void *zmq_ctx_new (void)
    pub fn new() -> Result<Context, Error> {
        let ctx_ptr = unsafe { zmq_sys::zmq_ctx_new() };
        ret_while_null!(ctx_ptr);

        Ok(Context {
            ctx_ptr: ctx_ptr,
        })
    }

    /// int zmq_ctx_term (void *context)
    fn term(&mut self) -> Option<Error> {        // trasnfer owner
        let ret_val = unsafe { zmq_sys::zmq_ctx_term(self.ctx_ptr) };
        if ret_val == -1 {
            Some(Error::from_last_err())
        } else {
            None
        }
    }

    /// int zmq_ctx_shutdown (void *ctx_)
    pub fn shutdown(&self) -> Option<Error> {
        let ret_val = unsafe { zmq_sys::zmq_ctx_shutdown(self.ctx_ptr) };
        if ret_val == -1 {
            Some(Error::from_last_err())
        } else {
            None
        }
    }

    /// int zmq_ctx_set (void *context, int option, int optval)
    pub fn set(&self, option_name: ContextSetOption, option_value: c_int) -> Option<Error> {
        let ret_val = unsafe { zmq_sys::zmq_ctx_set(self.ctx_ptr, option_name as c_int, option_value) };
        if ret_val == -1 {
            Some(Error::from_last_err())
        } else {
            None
        }
    }

    /// int zmq_ctx_get (void *context, int option)
    pub fn get(&self, option_name: ContextGetOption) -> Result<c_int, Error> {
        let ret_val = unsafe { zmq_sys::zmq_ctx_get(self.ctx_ptr, option_name as c_int) };
        if ret_val == -1 {
            Err(Error::from_last_err())
        } else {
            Ok(ret_val)
        }
    }
}

unsafe impl Send for Context {}
unsafe impl Sync for Context {}

impl Drop for Context {
    fn drop(&mut self) {
        self.term().unwrap();
    }
}
<|endoftext|>


<commit_before>//! Url Encoded middleware for Iron
//!
//! This middleware focuses on parsing the incoming url parameters from client requests.
//! It creates a HashMap that maps String to a Vec of Strings to account for
//! clients that pass more than one value to a given key.
#![crate_id = "urlencoded"]
#![license = "MIT"]

extern crate url;
extern crate iron;
extern crate serialize;

use iron::{Request, Response, Middleware, Alloy};
use iron::mixin::GetUrl;
use iron::middleware::{Status, Continue, Unwind};

use url::from_str;
use std::collections::HashMap;

/// Stores a hashmap of a string and a Vec of strings to address
/// client data that is sent with multiple values for a single key. This
/// structure allows for access to all values passed without overwriting
/// previous values assigned to the same key.
#[deriving(Clone)]
pub struct Encoded(pub HashMap<String, Vec<String>>);

/// This middleware is used for parsing url parameters and storing
/// the data as conveniently accessable data `insert`ed into an Alloy.
#[deriving(Clone)]
pub struct UrlEncoded;

/// Creates a UrlEncoded instance to be `link`ed to `server.chain`. Calling the
/// function will `insert` a new hashmap into the `alloy`.
impl UrlEncoded {
    pub fn new() -> UrlEncoded {
        UrlEncoded
    }
}

impl Middleware for UrlEncoded {
    fn enter(&mut self, req: &mut Request, res: &mut Response, alloy: &mut Alloy) -> Status {

        let query = match url::path_from_str(req.url().unwrap().as_slice()) {
            Ok(e) => {
                e.query
            },
            Err(e) => {
                return Continue;
            }
        };
        alloy.insert::<Encoded>(Encoded(createHash(query)));
        Continue
    }
}

fn createHash(q: Vec<(String, String)>) -> HashMap<String, Vec<String>> {
    let mut hashStrVec: HashMap<String, Vec<String>> = HashMap::new();

    for (k, v) in q.move_iter() {
        hashStrVec.find_with_or_insert_with(
            k, v,
            |_, already, new| {
                already.push(new);
            },
            |_, v| vec![v]
        );
    }
    hashStrVec
}
<commit_msg>(doc) Made for readable<commit_after>//! Url Encoded middleware for Iron
//!
//! This middleware focuses on parsing the incoming url parameters from client requests.
#![crate_id = "urlencoded"]
#![license = "MIT"]

extern crate url;
extern crate iron;
extern crate serialize;

use iron::{Request, Response, Middleware, Alloy};
use iron::mixin::GetUrl;
use iron::middleware::{Status, Continue, Unwind};

use url::from_str;
use std::collections::HashMap;

/// Stores a `HashMap` of a `String` and a `Vec<Strings>` to address
/// client data that is sent with multiple values for a single key.
#[deriving(Clone)]
pub struct Encoded(pub HashMap<String, Vec<String>>);

/// This middleware is used for parsing url parameters and storing
/// the data as conveniently accessible data `insert`ed into an Alloy.
#[deriving(Clone)]
pub struct UrlEncoded;

/// Creates a `UrlEncoded` instance to `link` to `server.chain`. Calling the
/// function will `insert` a new `HashMap` into the `alloy`.
impl UrlEncoded {
    pub fn new() -> UrlEncoded {
        UrlEncoded
    }
}

impl Middleware for UrlEncoded {
    fn enter(&mut self, req: &mut Request, res: &mut Response, alloy: &mut Alloy) -> Status {

        let query = match url::path_from_str(req.url().unwrap().as_slice()) {
            Ok(e) => {
                e.query
            },
            Err(e) => {
                return Continue;
            }
        };
        alloy.insert::<Encoded>(Encoded(createHash(query)));
        Continue
    }
}

fn createHash(q: Vec<(String, String)>) -> HashMap<String, Vec<String>> {
    let mut hashStrVec: HashMap<String, Vec<String>> = HashMap::new();

    for (k, v) in q.move_iter() {
        hashStrVec.find_with_or_insert_with(
            k, v,
            |_, already, new| {
                already.push(new);
            },
            |_, v| vec![v]
        );
    }
    hashStrVec
}
<|endoftext|>


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

pub type EventData<T> = HashMap<String, T>;
pub type EventCallback<'callback, T> = |& mut EventData<T>|:'callback;

pub trait Events<'callback, T> {
  fn on(&mut self, event_name: String, callback: EventCallback<'callback, T>);
  fn off(&mut self, event_name: String);
  fn emit(&mut self, event_name: String, EventData: & mut EventData<T>);
}

pub struct Emitter<'callback, T> {
  events : HashMap<String, Vec<EventCallback<'callback, T>>>
}

impl<'callback, T> Emitter<'callback, T>{
  pub fn new() -> Emitter<'callback, T> {
    Emitter {
      events: HashMap::new()
    }
  }
}

impl<'callback, T> Events<'callback, T> for Emitter<'callback, T> {
  fn on(&mut self, event_name: String, callback: EventCallback<'callback, T>) {
    //let vec : Vec<EventCallback<'callback>>;
    if self.events.contains_key(&event_name) {
      self.events.get_mut(&event_name).push(callback);
    } else {
      let vec = vec![callback];
      self.events.insert(event_name, vec);
    }

  }
  fn off(&mut self, event_name: String) {
    self.events.remove(&event_name);
  }
  fn emit(&mut self, event_name: String, event_data: & mut EventData<T>) {
    match self.events.find_mut(&event_name) {
      Some(callbacks) => {
        for callback in callbacks.iter_mut() {
            (*callback)(event_data);
        }
      }
      _ => {;}
    }
  }
}
<commit_msg>remove stupid comment<commit_after>use std::collections::HashMap;

pub type EventData<T> = HashMap<String, T>;
pub type EventCallback<'callback, T> = |& mut EventData<T>|:'callback;

pub trait Events<'callback, T> {
  fn on(&mut self, event_name: String, callback: EventCallback<'callback, T>);
  fn off(&mut self, event_name: String);
  fn emit(&mut self, event_name: String, EventData: & mut EventData<T>);
}

pub struct Emitter<'callback, T> {
  events : HashMap<String, Vec<EventCallback<'callback, T>>>
}

impl<'callback, T> Emitter<'callback, T>{
  pub fn new() -> Emitter<'callback, T> {
    Emitter {
      events: HashMap::new()
    }
  }
}

impl<'callback, T> Events<'callback, T> for Emitter<'callback, T> {
  fn on(&mut self, event_name: String, callback: EventCallback<'callback, T>) {
    if self.events.contains_key(&event_name) {
      self.events.get_mut(&event_name).push(callback);
    } else {
      let vec = vec![callback];
      self.events.insert(event_name, vec);
    }

  }
  fn off(&mut self, event_name: String) {
    self.events.remove(&event_name);
  }
  fn emit(&mut self, event_name: String, event_data: & mut EventData<T>) {
    match self.events.find_mut(&event_name) {
      Some(callbacks) => {
        for callback in callbacks.iter_mut() {
            (*callback)(event_data);
        }
      }
      _ => {;}
    }
  }
}
<|endoftext|>


<commit_before>//! A mutual exclusion future-powered synchronization primitive useful for protecting shared data.
//!
//! # Examples
//!
//! ```
//! # extern crate futures_mutex;
//! # extern crate futures;
//! # use futures_mutex::Mutex;
//! # use futures::{future, Async, Future};
//! # fn main() {
//! # let future = future::lazy(|| {
//! let lock1 = Mutex::new(0);
//!
//! // Mutex can be easily cloned as long as you need
//! let lock2 = lock1.clone();
//!
//! assert!(lock1.poll_lock().is_ready());
//! assert!(lock2.poll_lock().is_ready());
//!
//! let mut guard = match lock1.poll_lock() {
//!     Async::Ready(v) => v,
//!     Async::NotReady => unreachable!()
//! };
//!
//! *guard += 1;
//!
//! assert!(lock1.poll_lock().is_not_ready());
//! assert!(lock2.poll_lock().is_not_ready());
//!
//! drop(guard);
//!
//! assert!(lock1.poll_lock().is_ready());
//! assert!(lock2.poll_lock().is_ready());
//! # Ok::<(), ()>(())
//! # });
//! # future.wait().unwrap();
//! # }
//! ```
//!
//! Note that `poll_lock` method of the mutex must be called inside the
//! context of the task, otherwise it will panic.
//!
//! You can also call `lock` method of the mutex, which returns a future which resolves to
//! the owned-guard.
//!
//! ```
//! # extern crate futures_mutex;
//! # extern crate futures;
//! # use futures_mutex::Mutex;
//! # use futures::{future, Async, Future};
//! # fn main() {
//! let data = Mutex::new(2);
//! data.clone().lock().map(|mut guard| *guard += 2).wait().unwrap();
//! data.clone().lock().map(|guard| assert_eq!(*guard, 4)).wait().unwrap();
//! # }
//! ```

extern crate futures;
extern crate crossbeam;

use std::mem;
use std::ops::{Deref, DerefMut};
use std::cell::UnsafeCell;
use std::sync::Arc;
use std::sync::atomic::{Ordering, AtomicBool};

use crossbeam::sync::MsQueue;

use futures::{Future, Async, Poll};
use futures::task::{park, Task};

/// A mutex designed to use along with futures crate. API is similar to
/// [`futures::sync::BiLock`](https://docs.rs/futures/0.1/futures/sync/struct.BiLock.html).
/// Though, it can be cloned as long as you need.
#[derive(Debug, Clone)]
pub struct Mutex<T> {
    inner: Arc<Inner<T>>
}

#[derive(Debug)]
struct Inner<T> {
    inner: UnsafeCell<T>,
    locked: AtomicBool,
    queue: MsQueue<Task>
}

unsafe impl<T: Send> Send for Inner<T> {}
unsafe impl<T: Sync> Sync for Inner<T> {}

impl<T> Mutex<T> {
    /// Creates a new mutex in an unlocked state.
    pub fn new(t: T) -> Mutex<T> {
        let inner = Arc::new(Inner {
            inner: UnsafeCell::new(t),
            locked: AtomicBool::new(false),
            queue: MsQueue::new()
        });

        Mutex { inner }
    }

    /// Attempts to acquire mutex, returning `Async::NotReady` if other task already locked it.
    ///
    /// This function acquires the lock in a nonblocking fashion, returning immediately if lock is
    /// already held. If lock is succesefully acquired then `Async::Ready` is returned with
    /// `MutexGuard<T>`. The lock is unlocked when this `MutexGuard<T>` is dropped.
    ///
    /// # Panics
    ///
    /// This function will panic if called outside the context of a future's task.
    pub fn poll_lock(&self) -> Async<MutexGuard<T>> {
        if self.inner.locked.compare_and_swap(false, true, Ordering::SeqCst) {
            self.inner.queue.push(park());
            Async::NotReady
        } else {
            Async::Ready(MutexGuard { inner: self })
        }
    }

    /// Consume this lock into a future that resolves to a guard that allows access to the data.
    ///
    /// This function consumes the `Mutex<T>` and returns a future `MutexAcquire<T>`. The returned
    /// future will resolve to `MutexAcquired<T>` which represents a locked lock similarly to
    /// `MutexGuard<T>`.
    ///
    /// The returned future will never resolve to an error.
    pub fn lock(self) -> MutexAcquire<T> {
        MutexAcquire {
            inner: self
        }
    }

    fn unlock(&self) {
        if !self.inner.locked.swap(false, Ordering::SeqCst) {
            panic!("trying to unlock unlocked mutex");
        }

        while !self.inner.locked.load(Ordering::SeqCst) {
            match self.inner.queue.try_pop() {
                Some(task) => task.unpark(),
                None => return
            }
        }
    }
}

impl<T> Drop for Inner<T> {
    fn drop(&mut self) {
        assert_eq!(self.locked.load(Ordering::SeqCst), false)
    }
}

/// Returned RAII guard from the `poll_lock` method.
///
/// This structure acts as a sentinel to the data in the `Mutex<T>` itself, implementing `Deref`
/// and `DerefMut` to `T`. When dropped, the lock will be unlocked.
#[derive(Debug)]
pub struct MutexGuard<'a, T: 'a> {
    inner: &'a Mutex<T>
}

impl<'a, T> Deref for MutexGuard<'a, T> {
    type Target = T;

    fn deref(&self) -> &T {
        unsafe { &*self.inner.inner.inner.get() }
    }
}

impl<'a, T> DerefMut for MutexGuard<'a, T> {
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut *self.inner.inner.inner.get() }
    }
}

impl<'a, T> Drop for MutexGuard<'a, T> {
    fn drop(&mut self) {
        self.inner.unlock()
    }
}

/// Future returned by `Mutex::lock` which will resolve when the lock is acquired.
#[derive(Debug)]
pub struct MutexAcquire<T> {
    inner: Mutex<T>
}

impl<T> Future for MutexAcquire<T> {
    type Item = MutexAcquired<T>;
    type Error = ();

    fn poll(&mut self) -> Poll<MutexAcquired<T>, ()> {
        match self.inner.poll_lock() {
            Async::Ready(r) => {
                mem::forget(r);
                Ok(MutexAcquired {
                    inner: Mutex { inner: self.inner.inner.clone() }
                }.into())
            }

            Async::NotReady => Ok(Async::NotReady)
        }
    }
}

/// Resolved value of the `MutexAcquire<T>` future.
///
/// This value, like `MutexGuard<T>`, is a sentinel to the value `T` through implementations of
/// `Deref` and `DerefMut` traits. When dropped will unlock the lock.
#[derive(Debug)]
pub struct MutexAcquired<T> {
    inner: Mutex<T>
}

impl<T> Deref for MutexAcquired<T> {
    type Target = T;

    fn deref(&self) -> &T {
        unsafe { &*self.inner.inner.inner.get() }
    }
}

impl<T> DerefMut for MutexAcquired<T> {
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut *self.inner.inner.inner.get() }
    }
}

impl<T> Drop for MutexAcquired<T> {
    fn drop(&mut self) {
        self.inner.unlock();
    }
}

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

    #[test]
    fn simple() {
        let future = future::lazy(|| {
            let lock1 = Mutex::new(vec![]);
            let lock2 = lock1.clone();
            let lock3 = lock1.clone();

            let mut guard = match lock1.poll_lock() {
                Async::Ready(v) => v,
                Async::NotReady => panic!("mutex locked")
            };

            assert_eq!(guard.len(), 0);
            guard.push(32);
            assert_eq!(guard.len(), 1);

            assert!(lock1.poll_lock().is_not_ready());
            assert!(lock2.poll_lock().is_not_ready());
            assert!(lock3.poll_lock().is_not_ready());

            drop(guard);

            assert!(lock1.poll_lock().is_ready());
            assert!(lock2.poll_lock().is_ready());
            assert!(lock3.poll_lock().is_ready());

            let mut guard = match lock2.poll_lock() {
                Async::Ready(v) => v,
                Async::NotReady => panic!("mutex locked")
            };

            assert_eq!(guard.len(), 1);
            guard.remove(0);
            assert_eq!(guard.len(), 0);

            assert!(lock1.poll_lock().is_not_ready());
            assert!(lock2.poll_lock().is_not_ready());
            assert!(lock3.poll_lock().is_not_ready());

            Ok::<(), ()>(())
        });

        future.wait().unwrap();
    }
}
<commit_msg>Fix impl Clone for Mutex<commit_after>//! A mutual exclusion future-powered synchronization primitive useful for protecting shared data.
//!
//! # Examples
//!
//! ```
//! # extern crate futures_mutex;
//! # extern crate futures;
//! # use futures_mutex::Mutex;
//! # use futures::{future, Async, Future};
//! # fn main() {
//! # let future = future::lazy(|| {
//! let lock1 = Mutex::new(0);
//!
//! // Mutex can be easily cloned as long as you need
//! let lock2 = lock1.clone();
//!
//! assert!(lock1.poll_lock().is_ready());
//! assert!(lock2.poll_lock().is_ready());
//!
//! let mut guard = match lock1.poll_lock() {
//!     Async::Ready(v) => v,
//!     Async::NotReady => unreachable!()
//! };
//!
//! *guard += 1;
//!
//! assert!(lock1.poll_lock().is_not_ready());
//! assert!(lock2.poll_lock().is_not_ready());
//!
//! drop(guard);
//!
//! assert!(lock1.poll_lock().is_ready());
//! assert!(lock2.poll_lock().is_ready());
//! # Ok::<(), ()>(())
//! # });
//! # future.wait().unwrap();
//! # }
//! ```
//!
//! Note that `poll_lock` method of the mutex must be called inside the
//! context of the task, otherwise it will panic.
//!
//! You can also call `lock` method of the mutex, which returns a future which resolves to
//! the owned-guard.
//!
//! ```
//! # extern crate futures_mutex;
//! # extern crate futures;
//! # use futures_mutex::Mutex;
//! # use futures::{future, Async, Future};
//! # fn main() {
//! let data = Mutex::new(2);
//! data.clone().lock().map(|mut guard| *guard += 2).wait().unwrap();
//! data.clone().lock().map(|guard| assert_eq!(*guard, 4)).wait().unwrap();
//! # }
//! ```

extern crate futures;
extern crate crossbeam;

use std::mem;
use std::ops::{Deref, DerefMut};
use std::cell::UnsafeCell;
use std::sync::Arc;
use std::sync::atomic::{Ordering, AtomicBool};

use crossbeam::sync::MsQueue;

use futures::{Future, Async, Poll};
use futures::task::{park, Task};

/// A mutex designed to use along with futures crate. API is similar to
/// [`futures::sync::BiLock`](https://docs.rs/futures/0.1/futures/sync/struct.BiLock.html).
/// Though, it can be cloned as long as you need.
#[derive(Debug)]
pub struct Mutex<T> {
    inner: Arc<Inner<T>>
}

#[derive(Debug)]
struct Inner<T> {
    inner: UnsafeCell<T>,
    locked: AtomicBool,
    queue: MsQueue<Task>
}

unsafe impl<T: Send> Send for Inner<T> {}
unsafe impl<T: Sync> Sync for Inner<T> {}

impl<T> Mutex<T> {
    /// Creates a new mutex in an unlocked state.
    pub fn new(t: T) -> Mutex<T> {
        let inner = Arc::new(Inner {
            inner: UnsafeCell::new(t),
            locked: AtomicBool::new(false),
            queue: MsQueue::new()
        });

        Mutex { inner }
    }

    /// Attempts to acquire mutex, returning `Async::NotReady` if other task already locked it.
    ///
    /// This function acquires the lock in a nonblocking fashion, returning immediately if lock is
    /// already held. If lock is succesefully acquired then `Async::Ready` is returned with
    /// `MutexGuard<T>`. The lock is unlocked when this `MutexGuard<T>` is dropped.
    ///
    /// # Panics
    ///
    /// This function will panic if called outside the context of a future's task.
    pub fn poll_lock(&self) -> Async<MutexGuard<T>> {
        if self.inner.locked.compare_and_swap(false, true, Ordering::SeqCst) {
            self.inner.queue.push(park());
            Async::NotReady
        } else {
            Async::Ready(MutexGuard { inner: self })
        }
    }

    /// Consume this lock into a future that resolves to a guard that allows access to the data.
    ///
    /// This function consumes the `Mutex<T>` and returns a future `MutexAcquire<T>`. The returned
    /// future will resolve to `MutexAcquired<T>` which represents a locked lock similarly to
    /// `MutexGuard<T>`.
    ///
    /// The returned future will never resolve to an error.
    pub fn lock(self) -> MutexAcquire<T> {
        MutexAcquire {
            inner: self
        }
    }

    fn unlock(&self) {
        if !self.inner.locked.swap(false, Ordering::SeqCst) {
            panic!("trying to unlock unlocked mutex");
        }

        while !self.inner.locked.load(Ordering::SeqCst) {
            match self.inner.queue.try_pop() {
                Some(task) => task.unpark(),
                None => return
            }
        }
    }
}

impl<T> Drop for Inner<T> {
    fn drop(&mut self) {
        assert_eq!(self.locked.load(Ordering::SeqCst), false)
    }
}

impl<T> Clone for Mutex<T> {
    fn clone(&self) -> Mutex<T> {
        Mutex {
            inner: self.inner.clone()
        }
    }
}

/// Returned RAII guard from the `poll_lock` method.
///
/// This structure acts as a sentinel to the data in the `Mutex<T>` itself, implementing `Deref`
/// and `DerefMut` to `T`. When dropped, the lock will be unlocked.
#[derive(Debug)]
pub struct MutexGuard<'a, T: 'a> {
    inner: &'a Mutex<T>
}

impl<'a, T> Deref for MutexGuard<'a, T> {
    type Target = T;

    fn deref(&self) -> &T {
        unsafe { &*self.inner.inner.inner.get() }
    }
}

impl<'a, T> DerefMut for MutexGuard<'a, T> {
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut *self.inner.inner.inner.get() }
    }
}

impl<'a, T> Drop for MutexGuard<'a, T> {
    fn drop(&mut self) {
        self.inner.unlock()
    }
}

/// Future returned by `Mutex::lock` which will resolve when the lock is acquired.
#[derive(Debug)]
pub struct MutexAcquire<T> {
    inner: Mutex<T>
}

impl<T> Future for MutexAcquire<T> {
    type Item = MutexAcquired<T>;
    type Error = ();

    fn poll(&mut self) -> Poll<MutexAcquired<T>, ()> {
        match self.inner.poll_lock() {
            Async::Ready(r) => {
                mem::forget(r);
                Ok(MutexAcquired {
                    inner: Mutex { inner: self.inner.inner.clone() }
                }.into())
            }

            Async::NotReady => Ok(Async::NotReady)
        }
    }
}

/// Resolved value of the `MutexAcquire<T>` future.
///
/// This value, like `MutexGuard<T>`, is a sentinel to the value `T` through implementations of
/// `Deref` and `DerefMut` traits. When dropped will unlock the lock.
#[derive(Debug)]
pub struct MutexAcquired<T> {
    inner: Mutex<T>
}

impl<T> Deref for MutexAcquired<T> {
    type Target = T;

    fn deref(&self) -> &T {
        unsafe { &*self.inner.inner.inner.get() }
    }
}

impl<T> DerefMut for MutexAcquired<T> {
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut *self.inner.inner.inner.get() }
    }
}

impl<T> Drop for MutexAcquired<T> {
    fn drop(&mut self) {
        self.inner.unlock();
    }
}

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

    #[test]
    fn simple() {
        let future = future::lazy(|| {
            let lock1 = Mutex::new(vec![]);
            let lock2 = lock1.clone();
            let lock3 = lock1.clone();

            let mut guard = match lock1.poll_lock() {
                Async::Ready(v) => v,
                Async::NotReady => panic!("mutex locked")
            };

            assert_eq!(guard.len(), 0);
            guard.push(32);
            assert_eq!(guard.len(), 1);

            assert!(lock1.poll_lock().is_not_ready());
            assert!(lock2.poll_lock().is_not_ready());
            assert!(lock3.poll_lock().is_not_ready());

            drop(guard);

            assert!(lock1.poll_lock().is_ready());
            assert!(lock2.poll_lock().is_ready());
            assert!(lock3.poll_lock().is_ready());

            let mut guard = match lock2.poll_lock() {
                Async::Ready(v) => v,
                Async::NotReady => panic!("mutex locked")
            };

            assert_eq!(guard.len(), 1);
            guard.remove(0);
            assert_eq!(guard.len(), 0);

            assert!(lock1.poll_lock().is_not_ready());
            assert!(lock2.poll_lock().is_not_ready());
            assert!(lock3.poll_lock().is_not_ready());

            Ok::<(), ()>(())
        });

        future.wait().unwrap();
    }
}
<|endoftext|>