<commit_before>#![crate_name = "docopt_macros"]
#![crate_type = "dylib"]

#![feature(plugin_registrar, quote, rustc_private)]

//! This crate defines the `docopt!` macro. It is documented in the
//! documentation of the `docopt` crate.

extern crate syntax;
extern crate rustc_plugin;
extern crate docopt;

use std::borrow::Borrow;
use std::collections::HashMap;

use rustc_plugin::Registry;
use syntax::{ast, codemap};
use syntax::errors::DiagnosticBuilder;
use syntax::ext::base::{ExtCtxt, MacResult, MacEager, DummyResult};
use syntax::ext::build::AstBuilder;
use syntax::fold::Folder;
use syntax::parse::common::SeqSep;
use syntax::parse::parser::Parser;
use syntax::parse::token;
use syntax::print::pprust;
use syntax::ptr::P;
use syntax::util::small_vector::SmallVector;

use docopt::{Docopt, ArgvMap};
use docopt::parse::{Options, Atom, Positional, Zero, One};

type PResult<'a, T> = Result<T, DiagnosticBuilder<'a>>;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("docopt", expand);
}

fn expand(cx: &mut ExtCtxt, span: codemap::Span, tts: &[ast::TokenTree])
         -> Box<MacResult+'static> {
    let parsed = match MacParser::new(cx, tts).parse() {
        Ok(parsed) => parsed,
        Err(_) => return DummyResult::any(span),
    };
    parsed.items(cx)
}

/// Parsed corresponds to the result of parsing a `docopt` macro call.
/// It can be used to write a corresponding struct.
struct Parsed {
    struct_info: StructInfo,
    doc: Docopt,
    /// Overrided type annotations for struct members. May be empty.
    /// When a type annotation for an atom doesn't exist, then one is
    /// inferred automatically. It is one of: `bool`, `usize`, `String` or
    /// `Vec<String>`.
    types: HashMap<Atom, P<ast::Ty>>,
}

impl Parsed {
    /// Returns a macro result suitable for expansion.
    /// Contains two items: one for the struct and one for the struct impls.
    fn items(&self, cx: &ExtCtxt) -> Box<MacResult+'static> {
        let mut its = vec!();
        its.push(self.struct_decl(cx));

        let struct_name = self.struct_info.name;
        let full_doc = &*self.doc.parser().full_doc;
        its.push(quote_item!(cx,
            impl $struct_name {
                #[allow(dead_code)]
                fn docopt() -> docopt::Docopt {
                    // The unwrap is justified here because this code
                    // gen only happens if the Docopt usage string is valid.
                    docopt::Docopt::new($full_doc).unwrap()
                }
            }
        ).unwrap());
        MacEager::items(SmallVector::many(its))
    }

    /// Returns an item for the struct definition.
    fn struct_decl(&self, cx: &ExtCtxt) -> P<ast::Item> {
        let name = self.struct_info.name.clone();
        let vis = if self.struct_info.public { ast::Visibility::Public }
                  else { ast::Visibility::Inherited };
        let def = ast::VariantData::Struct(
            self.struct_fields(cx), ast::DUMMY_NODE_ID);

        let mut traits = vec!["RustcDecodable".to_string()];
        traits.extend(self.struct_info.deriving.iter().cloned());
        let attrs = vec![attribute(cx, "allow", vec!["non_snake_case"]),
                         attribute(cx, "derive", traits)];

        let st = cx.item_struct(codemap::DUMMY_SP, name.clone(), def);
        cx.item(codemap::DUMMY_SP, name, attrs, st.node.clone()).map(|mut it| {
            it.vis = vis;
            it
        })
    }

    /// Returns a list of fields for the struct definition.
    /// Handles type annotations.
    fn struct_fields(&self, cx: &ExtCtxt) -> Vec<ast::StructField> {
        let mut fields: Vec<ast::StructField> = vec!();
        for (atom, opts) in self.doc.parser().descs.iter() {
            let name = ArgvMap::key_to_struct_field(&*atom.to_string());
            let ty = match self.types.get(atom) {
                None => self.pat_type(cx, atom, opts),
                Some(ty) => ty.clone(),
            };
            fields.push(self.mk_struct_field(&*name, ty));
        }
        fields
    }

    /// Returns an inferred type for a usage pattern.
    /// This is only invoked when a type annotation is not present.
    fn pat_type(&self, cx: &ExtCtxt, atom: &Atom, opts: &Options) -> P<ast::Ty> {
        let sp = codemap::DUMMY_SP;
        match (opts.repeats, &opts.arg) {
            (false, &Zero) => {
                match atom {
                    &Positional(_) => cx.ty_ident(sp, ident("String")),
                    _ => cx.ty_ident(sp, ident("bool")),
                }
            }
            (true, &Zero) => {
                match atom {
                    &Positional(_) => ty_vec_string(cx),
                    _ => cx.ty_ident(sp, ident("usize")),
                }
            }
            (false, &One(_)) => cx.ty_ident(sp, ident("String")),
            (true, &One(_)) => ty_vec_string(cx),
        }
    }

    /// Creates a struct field from a member name and type.
    fn mk_struct_field(&self, name: &str, ty: P<ast::Ty>) -> ast::StructField {
        ast::StructField {
            span: codemap::DUMMY_SP,
            ident: Some(ident(name)),
            vis: ast::Visibility::Public,
            id: ast::DUMMY_NODE_ID,
            ty: ty,
            attrs: vec!(),
        }
    }
}

/// State for parsing a `docopt` macro invocation.
struct MacParser<'a, 'b:'a> {
    cx: &'a mut ExtCtxt<'b>,
    p: Parser<'b>,
}

impl<'a, 'b> MacParser<'a, 'b> {
    fn new(cx: &'a mut ExtCtxt<'b>, tts: &[ast::TokenTree]) -> MacParser<'a, 'b> {
        let p = cx.new_parser_from_tts(tts);
        MacParser { cx: cx, p: p }
    }

    /// Main entry point for parsing arguments to `docopt` macro.
    /// First looks for an identifier for the struct name.
    /// Second, a string containing the docopt usage patterns.
    /// Third, an optional list of type annotations.
    fn parse(&mut self) -> PResult<'b, Parsed> {
        if self.p.token == token::Eof {
            let err = self.cx.struct_span_err(
                self.cx.call_site(), "macro expects arguments");
            return Err(err);
        }
        let struct_info = try!(self.parse_struct_info());
        let docstr = try!(self.parse_str());

        let mut types = HashMap::new();
        if !self.p.check(&token::Eof) {
            let sep = SeqSep {
                sep: Some(token::Comma),
                trailing_sep_allowed: true,
            };
            types = self.p.parse_seq_to_before_end(
                &token::Eof, sep, |p| MacParser::parse_type_annotation(p)
            ).into_iter()
             .map(|(ident, ty)| {
                  let field_name = ident.to_string();
                  let key = ArgvMap::struct_field_to_key(&*field_name);
                  (Atom::new(&*key), ty)
              })
             .collect::<HashMap<Atom, P<ast::Ty>>>();
            try!(self.p.expect(&token::Eof));
        }

        // This config does not matter because we're only asking for the
        // usage patterns in the Docopt string. The configuration does not
        // affect the retrieval of usage patterns.
        let doc = match Docopt::new(docstr) {
            Ok(doc) => doc,
            Err(err) => {
                let err = self.cx.struct_span_err(
                    self.cx.call_site(),
                    &format!("Invalid Docopt usage: {}", err));
                return Err(err);
            }
        };
        Ok(Parsed {
            struct_info: struct_info,
            doc: doc,
            types: types,
        })
    }

    /// Parses a single string literal. On failure, an error is logged and
    /// unit is returned.
    fn parse_str(&mut self) -> PResult<'b, String> {
        fn lit_is_str(lit: &ast::Lit) -> bool {
            match lit.node {
                ast::LitKind::Str(_, _) => true,
                _ => false,
            }
        }
        fn lit_to_string(lit: &ast::Lit) -> String {
            match lit.node {
                ast::LitKind::Str(ref s, _) => s.to_string(),
                _ => panic!("BUG: expected string literal"),
            }
        }
        let exp = self.cx.expander().fold_expr(self.p.parse_expr().unwrap());
        let s = match exp.node {
            ast::ExprKind::Lit(ref lit) if lit_is_str(&**lit) => {
                lit_to_string(&**lit)
            }
            _ => {
                let err = format!("Expected string literal but got {}",
                                  pprust::expr_to_string(&*exp));
                let err = self.cx.struct_span_err(exp.span, &*err);
                return Err(err);
            }
        };
        self.p.bump();
        Ok(s)
    }

    /// Parses a type annotation in a `docopt` invocation of the form
    /// `ident: Ty`.
    /// Note that this is a static method as it is used as a HOF.
    fn parse_type_annotation(p: &mut Parser<'b>)
                             -> PResult<'b, (ast::Ident, P<ast::Ty>)> {
        let ident = try!(p.parse_ident());
        try!(p.expect(&token::Colon));
        let ty = p.parse_ty().unwrap();
        Ok((ident, ty))
    }

    /// Parses struct information, like visibility, name and deriving.
    fn parse_struct_info(&mut self) -> PResult<'b, StructInfo> {
        let public = self.p.eat_keyword(token::keywords::Pub);
        let mut info = StructInfo {
            name: try!(self.p.parse_ident()),
            public: public,
            deriving: vec![],
        };
        if self.p.eat(&token::Comma) { return Ok(info); }
        let deriving = try!(self.p.parse_ident());
        if deriving.name.as_str() != "derive" {
            let err = format!("Expected 'derive' keyword but got '{}'",
                              deriving);
            let err = self.cx.struct_span_err(self.cx.call_site(), &*err);
            return Err(err);
        }
        while !self.p.eat(&token::Comma) {
            info.deriving.push(
                try!(self.p.parse_ident()).name.to_string());
        }
        Ok(info)
    }
}

struct StructInfo {
    name: ast::Ident,
    public: bool,
    deriving: Vec<String>,
}

// Convenience functions for building intermediate values.

fn ident(s: &str) -> ast::Ident {
    ast::Ident::with_empty_ctxt(token::intern(s))
}

fn attribute<S, T>(cx: &ExtCtxt, name: S, items: Vec<T>) -> ast::Attribute
            where S: Borrow<str>, T: Borrow<str> {
    let sp = codemap::DUMMY_SP;
    let its = items.into_iter().map(|s| meta_item(cx, s.borrow())).collect();
    let mi = cx.meta_list(sp, intern(name.borrow()), its);
    cx.attribute(sp, mi)
}

fn meta_item(cx: &ExtCtxt, s: &str) -> P<ast::MetaItem> {
    cx.meta_word(codemap::DUMMY_SP, intern(s))
}

fn intern(s: &str) -> token::InternedString {
    token::intern_and_get_ident(s)
}

fn ty_vec_string(cx: &ExtCtxt) -> P<ast::Ty> {
    let sp = codemap::DUMMY_SP;
    let tystr = ast::AngleBracketedParameterData {
        lifetimes: vec![],
        types: P::from_vec(vec![cx.ty_ident(sp, ident("String"))]),
        bindings: P::empty(),
    };
    cx.ty_path(ast::Path {
        span: sp,
        global: false,
        segments: vec![ast::PathSegment {
            identifier: ident("Vec"),
            parameters: ast::PathParameters::AngleBracketed(tystr),
        }]
    })
}
<commit_msg>Switch to P::new instead of P::empty<commit_after>#![crate_name = "docopt_macros"]
#![crate_type = "dylib"]

#![feature(plugin_registrar, quote, rustc_private)]

//! This crate defines the `docopt!` macro. It is documented in the
//! documentation of the `docopt` crate.

extern crate syntax;
extern crate rustc_plugin;
extern crate docopt;

use std::borrow::Borrow;
use std::collections::HashMap;

use rustc_plugin::Registry;
use syntax::{ast, codemap};
use syntax::errors::DiagnosticBuilder;
use syntax::ext::base::{ExtCtxt, MacResult, MacEager, DummyResult};
use syntax::ext::build::AstBuilder;
use syntax::fold::Folder;
use syntax::parse::common::SeqSep;
use syntax::parse::parser::Parser;
use syntax::parse::token;
use syntax::print::pprust;
use syntax::ptr::P;
use syntax::util::small_vector::SmallVector;

use docopt::{Docopt, ArgvMap};
use docopt::parse::{Options, Atom, Positional, Zero, One};

type PResult<'a, T> = Result<T, DiagnosticBuilder<'a>>;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("docopt", expand);
}

fn expand(cx: &mut ExtCtxt, span: codemap::Span, tts: &[ast::TokenTree])
         -> Box<MacResult+'static> {
    let parsed = match MacParser::new(cx, tts).parse() {
        Ok(parsed) => parsed,
        Err(_) => return DummyResult::any(span),
    };
    parsed.items(cx)
}

/// Parsed corresponds to the result of parsing a `docopt` macro call.
/// It can be used to write a corresponding struct.
struct Parsed {
    struct_info: StructInfo,
    doc: Docopt,
    /// Overrided type annotations for struct members. May be empty.
    /// When a type annotation for an atom doesn't exist, then one is
    /// inferred automatically. It is one of: `bool`, `usize`, `String` or
    /// `Vec<String>`.
    types: HashMap<Atom, P<ast::Ty>>,
}

impl Parsed {
    /// Returns a macro result suitable for expansion.
    /// Contains two items: one for the struct and one for the struct impls.
    fn items(&self, cx: &ExtCtxt) -> Box<MacResult+'static> {
        let mut its = vec!();
        its.push(self.struct_decl(cx));

        let struct_name = self.struct_info.name;
        let full_doc = &*self.doc.parser().full_doc;
        its.push(quote_item!(cx,
            impl $struct_name {
                #[allow(dead_code)]
                fn docopt() -> docopt::Docopt {
                    // The unwrap is justified here because this code
                    // gen only happens if the Docopt usage string is valid.
                    docopt::Docopt::new($full_doc).unwrap()
                }
            }
        ).unwrap());
        MacEager::items(SmallVector::many(its))
    }

    /// Returns an item for the struct definition.
    fn struct_decl(&self, cx: &ExtCtxt) -> P<ast::Item> {
        let name = self.struct_info.name.clone();
        let vis = if self.struct_info.public { ast::Visibility::Public }
                  else { ast::Visibility::Inherited };
        let def = ast::VariantData::Struct(
            self.struct_fields(cx), ast::DUMMY_NODE_ID);

        let mut traits = vec!["RustcDecodable".to_string()];
        traits.extend(self.struct_info.deriving.iter().cloned());
        let attrs = vec![attribute(cx, "allow", vec!["non_snake_case"]),
                         attribute(cx, "derive", traits)];

        let st = cx.item_struct(codemap::DUMMY_SP, name.clone(), def);
        cx.item(codemap::DUMMY_SP, name, attrs, st.node.clone()).map(|mut it| {
            it.vis = vis;
            it
        })
    }

    /// Returns a list of fields for the struct definition.
    /// Handles type annotations.
    fn struct_fields(&self, cx: &ExtCtxt) -> Vec<ast::StructField> {
        let mut fields: Vec<ast::StructField> = vec!();
        for (atom, opts) in self.doc.parser().descs.iter() {
            let name = ArgvMap::key_to_struct_field(&*atom.to_string());
            let ty = match self.types.get(atom) {
                None => self.pat_type(cx, atom, opts),
                Some(ty) => ty.clone(),
            };
            fields.push(self.mk_struct_field(&*name, ty));
        }
        fields
    }

    /// Returns an inferred type for a usage pattern.
    /// This is only invoked when a type annotation is not present.
    fn pat_type(&self, cx: &ExtCtxt, atom: &Atom, opts: &Options) -> P<ast::Ty> {
        let sp = codemap::DUMMY_SP;
        match (opts.repeats, &opts.arg) {
            (false, &Zero) => {
                match atom {
                    &Positional(_) => cx.ty_ident(sp, ident("String")),
                    _ => cx.ty_ident(sp, ident("bool")),
                }
            }
            (true, &Zero) => {
                match atom {
                    &Positional(_) => ty_vec_string(cx),
                    _ => cx.ty_ident(sp, ident("usize")),
                }
            }
            (false, &One(_)) => cx.ty_ident(sp, ident("String")),
            (true, &One(_)) => ty_vec_string(cx),
        }
    }

    /// Creates a struct field from a member name and type.
    fn mk_struct_field(&self, name: &str, ty: P<ast::Ty>) -> ast::StructField {
        ast::StructField {
            span: codemap::DUMMY_SP,
            ident: Some(ident(name)),
            vis: ast::Visibility::Public,
            id: ast::DUMMY_NODE_ID,
            ty: ty,
            attrs: vec!(),
        }
    }
}

/// State for parsing a `docopt` macro invocation.
struct MacParser<'a, 'b:'a> {
    cx: &'a mut ExtCtxt<'b>,
    p: Parser<'b>,
}

impl<'a, 'b> MacParser<'a, 'b> {
    fn new(cx: &'a mut ExtCtxt<'b>, tts: &[ast::TokenTree]) -> MacParser<'a, 'b> {
        let p = cx.new_parser_from_tts(tts);
        MacParser { cx: cx, p: p }
    }

    /// Main entry point for parsing arguments to `docopt` macro.
    /// First looks for an identifier for the struct name.
    /// Second, a string containing the docopt usage patterns.
    /// Third, an optional list of type annotations.
    fn parse(&mut self) -> PResult<'b, Parsed> {
        if self.p.token == token::Eof {
            let err = self.cx.struct_span_err(
                self.cx.call_site(), "macro expects arguments");
            return Err(err);
        }
        let struct_info = try!(self.parse_struct_info());
        let docstr = try!(self.parse_str());

        let mut types = HashMap::new();
        if !self.p.check(&token::Eof) {
            let sep = SeqSep {
                sep: Some(token::Comma),
                trailing_sep_allowed: true,
            };
            types = self.p.parse_seq_to_before_end(
                &token::Eof, sep, |p| MacParser::parse_type_annotation(p)
            ).into_iter()
             .map(|(ident, ty)| {
                  let field_name = ident.to_string();
                  let key = ArgvMap::struct_field_to_key(&*field_name);
                  (Atom::new(&*key), ty)
              })
             .collect::<HashMap<Atom, P<ast::Ty>>>();
            try!(self.p.expect(&token::Eof));
        }

        // This config does not matter because we're only asking for the
        // usage patterns in the Docopt string. The configuration does not
        // affect the retrieval of usage patterns.
        let doc = match Docopt::new(docstr) {
            Ok(doc) => doc,
            Err(err) => {
                let err = self.cx.struct_span_err(
                    self.cx.call_site(),
                    &format!("Invalid Docopt usage: {}", err));
                return Err(err);
            }
        };
        Ok(Parsed {
            struct_info: struct_info,
            doc: doc,
            types: types,
        })
    }

    /// Parses a single string literal. On failure, an error is logged and
    /// unit is returned.
    fn parse_str(&mut self) -> PResult<'b, String> {
        fn lit_is_str(lit: &ast::Lit) -> bool {
            match lit.node {
                ast::LitKind::Str(_, _) => true,
                _ => false,
            }
        }
        fn lit_to_string(lit: &ast::Lit) -> String {
            match lit.node {
                ast::LitKind::Str(ref s, _) => s.to_string(),
                _ => panic!("BUG: expected string literal"),
            }
        }
        let exp = self.cx.expander().fold_expr(self.p.parse_expr().unwrap());
        let s = match exp.node {
            ast::ExprKind::Lit(ref lit) if lit_is_str(&**lit) => {
                lit_to_string(&**lit)
            }
            _ => {
                let err = format!("Expected string literal but got {}",
                                  pprust::expr_to_string(&*exp));
                let err = self.cx.struct_span_err(exp.span, &*err);
                return Err(err);
            }
        };
        self.p.bump();
        Ok(s)
    }

    /// Parses a type annotation in a `docopt` invocation of the form
    /// `ident: Ty`.
    /// Note that this is a static method as it is used as a HOF.
    fn parse_type_annotation(p: &mut Parser<'b>)
                             -> PResult<'b, (ast::Ident, P<ast::Ty>)> {
        let ident = try!(p.parse_ident());
        try!(p.expect(&token::Colon));
        let ty = p.parse_ty().unwrap();
        Ok((ident, ty))
    }

    /// Parses struct information, like visibility, name and deriving.
    fn parse_struct_info(&mut self) -> PResult<'b, StructInfo> {
        let public = self.p.eat_keyword(token::keywords::Pub);
        let mut info = StructInfo {
            name: try!(self.p.parse_ident()),
            public: public,
            deriving: vec![],
        };
        if self.p.eat(&token::Comma) { return Ok(info); }
        let deriving = try!(self.p.parse_ident());
        if deriving.name.as_str() != "derive" {
            let err = format!("Expected 'derive' keyword but got '{}'",
                              deriving);
            let err = self.cx.struct_span_err(self.cx.call_site(), &*err);
            return Err(err);
        }
        while !self.p.eat(&token::Comma) {
            info.deriving.push(
                try!(self.p.parse_ident()).name.to_string());
        }
        Ok(info)
    }
}

struct StructInfo {
    name: ast::Ident,
    public: bool,
    deriving: Vec<String>,
}

// Convenience functions for building intermediate values.

fn ident(s: &str) -> ast::Ident {
    ast::Ident::with_empty_ctxt(token::intern(s))
}

fn attribute<S, T>(cx: &ExtCtxt, name: S, items: Vec<T>) -> ast::Attribute
            where S: Borrow<str>, T: Borrow<str> {
    let sp = codemap::DUMMY_SP;
    let its = items.into_iter().map(|s| meta_item(cx, s.borrow())).collect();
    let mi = cx.meta_list(sp, intern(name.borrow()), its);
    cx.attribute(sp, mi)
}

fn meta_item(cx: &ExtCtxt, s: &str) -> P<ast::MetaItem> {
    cx.meta_word(codemap::DUMMY_SP, intern(s))
}

fn intern(s: &str) -> token::InternedString {
    token::intern_and_get_ident(s)
}

fn ty_vec_string(cx: &ExtCtxt) -> P<ast::Ty> {
    let sp = codemap::DUMMY_SP;
    let tystr = ast::AngleBracketedParameterData {
        lifetimes: vec![],
        types: P::from_vec(vec![cx.ty_ident(sp, ident("String"))]),
        bindings: P::new(),
    };
    cx.ty_path(ast::Path {
        span: sp,
        global: false,
        segments: vec![ast::PathSegment {
            identifier: ident("Vec"),
            parameters: ast::PathParameters::AngleBracketed(tystr),
        }]
    })
}
<|endoftext|>


<commit_before>//! The integration suite for inspecting sessions.

extern crate libc;
extern crate rand;

use std::process::Command;
use libc::system;
use std::ffi::CString;
use rand::random;
use std::fs::File;
use std::fs;
use std::path::{Path, PathBuf};
use std::io::prelude::*;
use std::env::home_dir;
use std::thread::sleep;
use std::time::Duration;

fn homedir() -> Result<PathBuf, String>{
    match home_dir() {
        Some(dir) => Ok(dir),
        None      => Err(String::from("We couldn't find your home directory."))
    }
}

/// List windows will give details about the active sessions in testing.
/// target: A string represented by the {named_session}:{named_window}
fn list_windows(target: &String) -> String {
    let output = Command::new("tmux")
                     .arg("list-windows")
                     .arg("-t")
                     .arg(target)
                     .output()
                     .unwrap_or_else(|e| { panic!("failed to execute process: {}", e) });

    String::from_utf8_lossy(&output.stdout).into_owned()
}

fn open_muxed(project: &String) -> () {
    let output = Command::new("./target/debug/muxed")
        .arg("-d")
        .arg(format!("{}", project))
        .output()
        .unwrap_or_else(|e| { panic!("failed to execute process: {}", e) });
}

#[test]
fn list_3_windows() {
    let name = random::<u16>();
    let home = homedir().unwrap();
    let name1 = format!("{}/.muxed/{}.yml", home.display(), name);
    let path = Path::new(&name1);
    let path1 = &format!("{}/.muxed/", home.display());
    let muxed_path = Path::new(path1);
    if !muxed_path.exists() { println!("{:?}", fs::create_dir(muxed_path)) };
    let mut buffer = File::create(path).unwrap();
    println!("{:?}", buffer);
    println!("exists? {:?}", path.exists());
    let _ = buffer.write(b"---
windows: ['cargo', 'vim', 'git']
");
    open_muxed(&format!("{}", name));
    let time = Duration::new(1, 0);
    sleep(time);
    let result = list_windows(&name.to_string());
    let _ = fs::remove_file(path);
    println!("{:?}", result);
    assert_eq!(result, "hi")
}
<commit_msg>First integration test passes.<commit_after>//! The integration suite for inspecting sessions.

extern crate libc;
extern crate rand;

use std::process::Command;
use rand::random;
use std::fs::File;
use std::fs;
use std::path::{Path, PathBuf};
use std::io::prelude::*;
use std::env::home_dir;

fn homedir() -> Result<PathBuf, String>{
    match home_dir() {
        Some(dir) => Ok(dir),
        None      => Err(String::from("We couldn't find your home directory."))
    }
}

/// List windows will give details about the active sessions in testing.
/// target: A string represented by the {named_session}:{named_window}
fn list_windows(target: &String) -> String {
    let output = Command::new("tmux")
                     .arg("list-windows")
                     .arg("-t")
                     .arg(target)
                     .output()
                     .unwrap_or_else(|e| { panic!("failed to execute process: {}", e) });

    String::from_utf8_lossy(&output.stdout).into_owned()
}

fn open_muxed(project: &String) -> () {
    Command::new("./target/debug/muxed")
        .arg("-d")
        .arg(format!("{}", project))
        .output()
        .unwrap_or_else(|e| { panic!("failed to execute process: {}", e) });
}

fn kill_session(target: &String) -> () {
    Command::new("tmux")
        .arg("kill-session")
        .arg("-t")
        .arg(target)
        .output()
        .unwrap_or_else(|e| { panic!("failed to execute process: {}", e) });
}

fn has_n_windows(results: &Vec<&str>) -> usize {
    results.len() - 1
}

#[test]
fn list_3_windows() {
    let name = random::<u16>();
    let home = homedir().unwrap();
    let name1 = format!("{}/.muxed/{}.yml", home.display(), name);
    let path = Path::new(&name1);
    let path1 = &format!("{}/.muxed/", home.display());
    let muxed_path = Path::new(path1);
    if !muxed_path.exists() { println!("{:?}", fs::create_dir(muxed_path)) };
    let mut buffer = File::create(path).unwrap();
    let _ = buffer.write(b"---
windows: ['cargo', 'vim', 'git']
");
    open_muxed(&format!("{}", name));
    let result = list_windows(&name.to_string());
    let results: Vec<&str> = result.split("\n").collect();
    let _ = fs::remove_file(path);
    kill_session(&name.to_string());
    assert_eq!(has_n_windows(&results), 3)
}
<|endoftext|>


<commit_before>extern crate rig;

mod format_test {

    use std::collections::HashMap;
    use rig::format::{format, Placeholder};

    const W: &'static str = "Fabulous Is Rust";

    #[test]
    fn lower_case() {
        assert_eq!(format(W, "lower".into()), "fabulous is rust");
    }

    #[test]
    fn upper_case() {
        assert_eq!(format(W, "upper".into()), "FABULOUS IS RUST");
    }

    #[test]
    fn capitalize() {
        assert_eq!(format(&W.to_lowercase(), "cap".into()), "Fabulous is rust");
    }

    #[test]
    fn decapitalize() {
        assert_eq!(format(W, "decap".into()), "fabulous Is Rust");
    }

    #[test]
    fn start_case() {
        assert_eq!(format(&W.to_lowercase(), "start".into()), W);
    }

    #[test]
    fn word_only() {
        let includes_ctrls = "_!$what'is-this@charac#ters??";
        assert_eq!(format(includes_ctrls, "word".into()),
                   "_whatisthischaracters");
    }

    #[test]
    fn hyphenate() {
        assert_eq!(format(W, "hyphen".into()), "Fabulous-Is-Rust");
    }

    #[test]
    fn upper_camel() {
        assert_eq!(format(W, "Camel".into()), "FabulousIsRust");
    }

    #[test]
    fn lower_camel() {
        assert_eq!(format(W, "camel".into()), "fabulousIsRust");
    }

    #[test]
    fn normalize() {
        assert_eq!(format(W, "norm".into()), "fabulous-is-rust");
    }

    #[test]
    fn snake_case() {
        assert_eq!(format(W, "snake".into()), "Fabulous_Is_Rust");
    }

    #[test]
    fn directory_path() {
        let p = "path.to.my.directory";
        assert_eq!(format(p, "packaged".into()), "path/to/my/directory");
    }

    #[test]
    fn placeholder_giter8() {
        let ph = Placeholder::parse_g8(r#"project_name;format="upper,hyphen""#).unwrap();
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("project_name".to_owned(), "A simple proj".to_owned());

        assert_eq!(ph.format_with(&params), "A-SIMPLE-PROJ".to_owned());
    }

    #[test]
    fn placeholder_simple() {
        let ph = Placeholder::parse_simple("project_name;norm").unwrap();
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("project_name".to_owned(),
                      "A si\nmPLe         p\trOj".to_owned());

        assert_eq!(ph.format_with(&params), "a-si-mple-p-roj".to_owned());
    }

    #[test]
    fn placeholder_dirname() {
        let ph = Placeholder::parse_dirname("twitter_id__word_cap").unwrap();
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("twitter_id".to_owned(), "bar3s%Ye".to_owned());

        assert_eq!(ph.format_with(&params), "Bar3sye".to_owned());
    }
}

mod template_test {

    use std::collections::HashMap;
    use std::str;
    use rig::format::Style;
    use rig::template::{Params, Template};

    #[test]
    fn compile_inline() {
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("name".to_owned(), "Rust".to_owned());

        let mut out = Vec::new();

        Template::compile_inline(&mut out, Style::Simple, "Hello, $name$!", &params).unwrap();
        assert_eq!(str::from_utf8(&out).unwrap(), "Hello, Rust!");
    }

    #[test]
    fn format_template() {
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("DOCUMENT_NAME".to_owned(),
                      "RUST PROGRAMMING LANGUAGE".to_owned());

        let mut out = Vec::new();

        Template::compile_inline(&mut out,
                                 Style::Simple,
                                 "It's a $DOCUMENT_NAME;camel$",
                                 &params)
            .unwrap();
        assert_eq!(str::from_utf8(&out).unwrap(),
                   "It's a rustProgrammingLanguage".to_owned());
    }

    #[test]
    fn escape_character() {
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("DOCUMENT_NAME".to_owned(),
                      "RUST PROGRAMMING LANGUAGE".to_owned());

        let mut out = Vec::new();

        Template::compile_inline(&mut out,
                                 Style::Simple,
                                 "It's a \\$DOCUMENT_NAME;camel$",
                                 &params)
            .unwrap();
        assert_eq!(str::from_utf8(&out).unwrap(),
                   "It's a \\$DOCUMENT_NAME;camel$".to_owned());
    }

    #[test]
    fn giter8_template() {
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("name".to_owned(),
                      "awesome distributed interface".to_owned());

        let mut out = Vec::new();

        let mut tpl =
            Template::new_g8(r#"trait $name;format="Camel"$[-A] extends js.Dictionary[A]"#);
        tpl.write(&mut out, &params).unwrap();

        assert_eq!(str::from_utf8(&out).unwrap(),
                   "trait AwesomeDistributedInterface[-A] extends js.Dictionary[A]".to_owned());
    }
}

mod project_test {

    // TODO:
}
<commit_msg>tests: added project tests<commit_after>extern crate rig;

mod format_test {

    use std::collections::HashMap;
    use rig::format::{format, Placeholder};

    const W: &'static str = "Fabulous Is Rust";

    #[test]
    fn lower_case() {
        assert_eq!(format(W, "lower".into()), "fabulous is rust");
    }

    #[test]
    fn upper_case() {
        assert_eq!(format(W, "upper".into()), "FABULOUS IS RUST");
    }

    #[test]
    fn capitalize() {
        assert_eq!(format(&W.to_lowercase(), "cap".into()), "Fabulous is rust");
    }

    #[test]
    fn decapitalize() {
        assert_eq!(format(W, "decap".into()), "fabulous Is Rust");
    }

    #[test]
    fn start_case() {
        assert_eq!(format(&W.to_lowercase(), "start".into()), W);
    }

    #[test]
    fn word_only() {
        let includes_ctrls = "_!$what'is-this@charac#ters??";
        assert_eq!(format(includes_ctrls, "word".into()),
                   "_whatisthischaracters");
    }

    #[test]
    fn hyphenate() {
        assert_eq!(format(W, "hyphen".into()), "Fabulous-Is-Rust");
    }

    #[test]
    fn upper_camel() {
        assert_eq!(format(W, "Camel".into()), "FabulousIsRust");
    }

    #[test]
    fn lower_camel() {
        assert_eq!(format(W, "camel".into()), "fabulousIsRust");
    }

    #[test]
    fn normalize() {
        assert_eq!(format(W, "norm".into()), "fabulous-is-rust");
    }

    #[test]
    fn snake_case() {
        assert_eq!(format(W, "snake".into()), "Fabulous_Is_Rust");
    }

    #[test]
    fn directory_path() {
        let p = "path.to.my.directory";
        assert_eq!(format(p, "packaged".into()), "path/to/my/directory");
    }

    #[test]
    fn placeholder_giter8() {
        let ph = Placeholder::parse_g8(r#"project_name;format="upper,hyphen""#).unwrap();
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("project_name".to_owned(), "A simple proj".to_owned());

        assert_eq!(ph.format_with(&params), "A-SIMPLE-PROJ".to_owned());
    }

    #[test]
    fn placeholder_simple() {
        let ph = Placeholder::parse_simple("project_name;norm").unwrap();
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("project_name".to_owned(),
                      "A si\nmPLe         p\trOj".to_owned());

        assert_eq!(ph.format_with(&params), "a-si-mple-p-roj".to_owned());
    }

    #[test]
    fn placeholder_dirname() {
        let ph = Placeholder::parse_dirname("twitter_id__word_cap").unwrap();
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("twitter_id".to_owned(), "bar3s%Ye".to_owned());

        assert_eq!(ph.format_with(&params), "Bar3sye".to_owned());
    }
}

mod template_test {

    use std::collections::HashMap;
    use std::str;
    use rig::format::Style;
    use rig::template::{Params, Template};

    #[test]
    fn compile_inline() {
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("name".to_owned(), "Rust".to_owned());

        let mut out = Vec::new();

        Template::compile_inline(&mut out, Style::Simple, "Hello, $name$!", &params).unwrap();
        assert_eq!(str::from_utf8(&out).unwrap(), "Hello, Rust!");
    }

    #[test]
    fn format_template() {
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("DOCUMENT_NAME".to_owned(),
                      "RUST PROGRAMMING LANGUAGE".to_owned());

        let mut out = Vec::new();

        Template::compile_inline(&mut out,
                                 Style::Simple,
                                 "It's a $DOCUMENT_NAME;camel$",
                                 &params)
            .unwrap();
        assert_eq!(str::from_utf8(&out).unwrap(),
                   "It's a rustProgrammingLanguage".to_owned());
    }

    #[test]
    fn escape_character() {
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("DOCUMENT_NAME".to_owned(),
                      "RUST PROGRAMMING LANGUAGE".to_owned());

        let mut out = Vec::new();

        Template::compile_inline(&mut out,
                                 Style::Simple,
                                 "It's a \\$DOCUMENT_NAME;camel$",
                                 &params)
            .unwrap();
        assert_eq!(str::from_utf8(&out).unwrap(),
                   "It's a \\$DOCUMENT_NAME;camel$".to_owned());
    }

    #[test]
    fn giter8_template() {
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("name".to_owned(),
                      "awesome distributed interface".to_owned());

        let mut out = Vec::new();

        let mut tpl =
            Template::new_g8(r#"trait $name;format="Camel"$[-A] extends js.Dictionary[A]"#);
        tpl.write(&mut out, &params).unwrap();

        assert_eq!(str::from_utf8(&out).unwrap(),
                   "trait AwesomeDistributedInterface[-A] extends js.Dictionary[A]".to_owned());
    }
}

mod project_test {

    extern crate tempdir;
    use std::fs;
    use std::path::{Path, PathBuf};

    use rig::fsutils;
    use rig::project::Project;

    const G8_PROPS: &'static str = r#"
        name = value1
        bar = baz!
        package = com.example.me
    "#;

    const TOML: &'static str = r#"
        name = "My Project"
        package = "deep.pkg.path"
        will_be_ignored = [4, 5, 6, 7]
        module_name = "quux"
    "#;

    #[test]
    fn giter8_project() {

        let g8_dirs = vec![
            "src/main/g8",
            "src/main/g8/project",
            "src/main/g8/src/main/scala/$package$"
        ];

        let src = tempdir::TempDir::new("rig-g8-test").unwrap();
        let src = src.path();
        for dir in &g8_dirs {
            let dir = src.join(dir);
            fs::create_dir_all(dir).unwrap();
        }

        let props = src.join("src/main/g8/default.properties");
        fsutils::write_file(&props, G8_PROPS).unwrap();
        assert!(fsutils::exists(&props));

        let dest = tempdir::TempDir::new("generated-proj").unwrap();
        let dest = dest.path();

        let project = Project::new_g8(Some("src/main/g8"));

        let params = project.default_params(&src).unwrap();
        assert_eq!(params.get("name"), Some(&"value1".to_owned()));

        project.generate(&params, &src, &dest, false).unwrap();

        let expected = vec![
            "project",
            "src/main/scala/com",
            "src/main/scala/com/example",
            "src/main/scala/com/example/me",
        ];

        for goal in &expected {
            let goal = &dest.join(goal);
            assert!(fsutils::exists(&goal));
        }
    }
}
<|endoftext|>


<commit_before>extern crate glob;
extern crate rustc_serialize;

use glob::glob;
use rustc_serialize::json::Json;
use std::env;
use std::fs::File;
use std::result::Result;
use std::io::Read;

// const OUTPUT_FILE: &'static str = "output.csv";

fn main() {

	let args: Vec<String>= env::args().collect();

	if args.len() < 3 {
		panic!("Args are: <field name> <folder>");
	}

	let field = &args[1];
	let folder = &args[2];
	// println!("Will process field '{}' in files located in {}", field, folder);

	let search_path = format!("{}/*.json", folder);
	for path in glob(&search_path).unwrap().filter_map(Result::ok) {

		let mut file = File::open(&path).ok().expect("Failed to open file");
		let mut contents = &mut String::new();
		file.read_to_string(contents).ok().expect("Failed to read file");

		let data = Json::from_str(contents).ok().expect("Malformed JSON");
		let value = data.find(field).expect("Field is missing");
		match value.as_string() {
			Some(_) => (),
			None => panic!("Field is not a string"),
		}
	}
}
<commit_msg>Frustration<commit_after>extern crate glob;
extern crate rustc_serialize;

use glob::glob;
use rustc_serialize::json::Json;
use std::env;
use std::fs::File;
use std::result::Result;
use std::io::Read;
use std::collections::HashMap;
use std::string::as_string;

/***

To much 'unstable' to continue yet=(

***/

// const OUTPUT_FILE: &'static str = "output.csv";

fn main() {

	let args: Vec<String>= env::args().collect();

	if args.len() < 3 {
		panic!("Args are: <field name> <folder>");
	}

	let field = &args[1];
	let folder = &args[2];

	let mut frequencies = HashMap::new();

	let search_path = format!("{}/*.json", folder);
	let file_paths = glob(&search_path).unwrap();
	for path in file_paths.filter_map(Result::ok) {

		let path = path.to_str().unwrap();
		let contents = file_contents(path);

		let data = Json::from_str(&contents).ok();
		let data = data.expect("Malformed JSON");
		// let value = data.find(field).expect("Field is missing");
		// let key = value.as_string().expect("Field is not a string");
		let key = get_string_value(&data, field);

		let counter = match frequencies.get(&key) {
			None => 0,
			Some(&x) => x,
		};
		frequencies.insert(key, counter + 1);

		// let counter = value_option.unwrap_or(0);
		// frequencies.insert(key, *counter + 1);
	}

}

fn get_string_value(json: &Json, key: &str) -> String {
	let value = json.find(key).expect("Field is missing");
	let result = value.as_string().expect("Field is not a string");
	as_string(result)
}

fn file_contents(file_path: &str) -> String {
	let mut file = File::open(file_path).ok().expect("Failed to open file");
	let mut contents = String::new();
	file.read_to_string(&mut contents).ok().expect("Failed to read file");
	contents
}<|endoftext|>


<commit_before>#![cfg(not(miri))] // FIXME: takes too long

use hashbrown::HashSet;
use rand::{distributions::Alphanumeric, rngs::SmallRng, Rng, SeedableRng};

#[test]
fn test_hashset_insert_remove() {
    let mut m: HashSet<Vec<char>> = HashSet::new();
    //let num: u32 = 4096;
    //let tx: Vec<Vec<u8>> = (0..num).map(|i| (i..(16 + i)).collect()).collect();
    let seed: [u8; 16] = [
        130, 220, 246, 217, 111, 124, 221, 189, 190, 234, 121, 93, 67, 95, 100, 43,
    ];

    let rng = &mut SmallRng::from_seed(seed);
    let tx: Vec<Vec<char>> = (0..4096)
        .map(|_| (rng.sample_iter(&Alphanumeric).take(32).collect()))
        .collect();

    // more readable with explicit `true` / `false`
    #[allow(clippy::bool_assert_comparison)]
    for _ in 0..32 {
        for x in tx.iter() {
            assert_eq!(m.contains(x), false);
            assert_eq!(m.insert(x.clone()), true);
        }
        for (i, x) in tx.iter().enumerate() {
            println!("removing {} {:?}", i, x);
            assert_eq!(m.remove(x), true);
        }
    }
}
<commit_msg>Improve code readability of a test<commit_after>#![cfg(not(miri))] // FIXME: takes too long

use hashbrown::HashSet;
use rand::{distributions::Alphanumeric, rngs::SmallRng, Rng, SeedableRng};
use std::iter;

#[test]
fn test_hashset_insert_remove() {
    let mut m: HashSet<Vec<char>> = HashSet::new();

    let seed: [u8; 16] = [
        130, 220, 246, 217, 111, 124, 221, 189, 190, 234, 121, 93, 67, 95, 100, 43,
    ];

    let rng = &mut SmallRng::from_seed(seed);
    let tx: Vec<Vec<char>> =
        iter::repeat_with(|| rng.sample_iter(&Alphanumeric).take(32).collect())
            .take(4096)
            .collect();

    // more readable with explicit `true` / `false`
    #[allow(clippy::bool_assert_comparison)]
    for _ in 0..32 {
        for x in tx.iter() {
            assert_eq!(m.contains(x), false);
            assert_eq!(m.insert(x.clone()), true);
        }
        for (i, x) in tx.iter().enumerate() {
            println!("removing {} {:?}", i, x);
            assert_eq!(m.remove(x), true);
        }
    }
}
<|endoftext|>


<commit_before>

use super::{BaseNum, PartialOrd};
use std::ops::{Div, Mul};

/// A two-dimensional dimension.
#[derive(Debug,Clone,Copy)]
pub struct Dimension2<T: BaseNum> {
    pub width: T,
    pub height: T,
}

pub type Dimension2f = Dimension2<super::DefaultFloat>;
pub type Dimension2i = Dimension2<super::DefaultInt>;
pub type Dimension2u = Dimension2<super::DefaultUnsigned>;

impl<T: BaseNum> Dimension2<T> {
    pub fn new(width: T, height: T) -> Self {
        Dimension2 {
            width: width,
            height: height,
        }
    }
    /// returns the area of a Dimension<T>
    pub fn area(&self) -> <T as Mul>::Output {
        self.width * self.height
    }
    /// scales the Dimension2 with a scalar
    pub fn scale(&self, scale: T) -> Dimension2<T> {
        Dimension2 {
            width: self.width * scale,
            height: self.height * scale,
        }
    }
    /// calculates the aspectratio of a Dimension
    pub fn aspect_ratio(&self) -> <T as Div>::Output {
        assert!(!self.height.is_zero());
        self.width / self.height
    }
    /// Shrinks a dimension until it fits into another dimension
    pub fn fitting(&self, other: Dimension2<T>) -> Dimension2<T> {
        let scale = PartialOrd::partial_min(other.width / self.width, other.height / self.height);
        self.scale(scale)

    }

    /// Expands a dimension until it fills another dimension
    pub fn filling(&self, other: Dimension2<T>) -> Dimension2<T> {
        let scale = PartialOrd::partial_max(other.width / self.width, other.height / self.height);
        self.scale(scale)
    }
}

#[test]
fn test_area() {
    let test1 = Dimension2 {
        width: 3,
        height: 5,
    };
    let test2 = Dimension2 {
        width: 0,
        height: 0,
    };
    assert_eq!(test2.area(), 0);
    assert_eq!(test1.area(), 15);
}
#[test]
fn test_scale() {
    let test1 = Dimension2 {
        width: 3,
        height: 5,
    };
    let test2 = Dimension2 {
        width: 12,
        height: 20,
    };
    let scale = 4;
    let scale1 = 0;
    assert_eq!(test1.scale(scale).width, 12);
    assert_eq!(test2.scale(scale1).width, 0);
}
#[test]
fn test_aspect_ratio() {
    let test1 = Dimension2 {
        width: 3,
        height: 5,
    };
    // let test2 = Dimension2 {
    //     width: 3,
    //     height: 0,
    // };

    assert_eq!(test1.aspect_ratio(), 3 / 5);
}
#[test]
fn test_fitting() {
    let test1 = Dimension2 {
        width: 2.0,
        height: 1.0,
    };
    let test2 = Dimension2 {
        width: 4.0,
        height: 3.0,
    };
    assert_eq!(test2.fitting(test1).width, 4.0 / 3.0);
    assert_eq!(test2.fitting(test1).height, 1.0);
}
#[test]
fn test_filling() {
    let test1 = Dimension2 {
        width: 2.0,
        height: 1.0,
    };
    let test2 = Dimension2 {
        width: 4.0,
        height: 3.0,
    };
    assert_eq!(test1.filling(test2).width, 6.0);
    assert_eq!(test1.filling(test2).height, 3.0);
}
<commit_msg>fix the last commments<commit_after>use super::{BaseNum, PartialOrd};
use std::ops::{Div, Mul};

/// A two-dimensional dimension.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Dimension2<T: BaseNum> {
    pub width: T,
    pub height: T,
}

pub type Dimension2f = Dimension2<super::DefaultFloat>;
pub type Dimension2i = Dimension2<super::DefaultInt>;
pub type Dimension2u = Dimension2<super::DefaultUnsigned>;

impl<T: BaseNum> Dimension2<T> {
    pub fn new(width: T, height: T) -> Self {
        Dimension2 {
            width: width,
            height: height,
        }
    }
    /// Returns the area of a `Dimension`
    pub fn area(&self) -> <T as Mul>::Output {
        self.width * self.height
    }
    /// Scales the `Dimension2` with a scalar
    pub fn scale(&self, scale: T) -> Dimension2<T> {
        Dimension2 {
            width: self.width * scale,
            height: self.height * scale,
        }
    }
    /// Calculates the aspect ratio of a `Dimension`
    pub fn aspect_ratio(&self) -> <T as Div>::Output {
        assert!(!self.height.is_zero());
        self.width / self.height
    }
    /// Shrinks a `Dimension` until it fits into another `Dimension`
    pub fn fitting(&self, other: Dimension2<T>) -> Dimension2<T> {
        let scale = PartialOrd::partial_min(other.width / self.width, other.height / self.height);
        self.scale(scale)
    }
    /// Expands a `Dimension` until it fills another `Dimension`
    pub fn filling(&self, other: Dimension2<T>) -> Dimension2<T> {
        let scale = PartialOrd::partial_max(other.width / self.width, other.height / self.height);
        self.scale(scale)
    }
}

#[test]
fn test_area() {
    let test1 = Dimension2::new(3, 5);
    let test2 = Dimension2::new(0, 0);

    assert_eq!(test2.area(), 0);
    assert_eq!(test1.area(), 15);
}
#[test]
fn test_scale() {
    let test1 = Dimension2::new(3, 5);
    let test2 = Dimension2::new(12, 20);

    assert_eq!(test1.scale(4).width, 12);
    assert_eq!(test2.scale(0).width, 0);
}
#[test]
fn test_aspect_ratio() {
    let test1 = Dimension2::new(3, 5);

    assert_eq!(test1.aspect_ratio(), 3 / 5);
}
#[test]
fn test_fitting() {
    let test1 = Dimension2::new(2.0, 1.0);
    let test2 = Dimension2::new(4.0, 3.0);

    assert_eq!(test2.fitting(test1), Dimension2::new(4.0 / 3.0, 1.0));
}
#[test]
fn test_filling() {
    let test1 = Dimension2::new(2.0, 1.0);
    let test2 = Dimension2::new(4.0, 3.0);

    assert_eq!(test1.filling(test2), Dimension2::new(6.0, 3.0));
}
<|endoftext|>


<commit_before>error_chain! {
    foreign_links {
        Request(::reqwest::Error);
        Io(::std::io::Error);
    }

    errors {
        InvalidRule(t: String) {
            description("invalid rule")
            display("invalid rule: '{}'", t)
        }

        InvalidDomain(t: String) {
            description("invalid domain")
            display("invalid domain: '{}'", t)
        }

        Uts46(t: ::idna::uts46::Errors) {
            description("UTS #46 processing failed")
            display("UTS #46 processing error: '{:?}'", t)
        }
    }
}
<commit_msg>Remove obsolete error def<commit_after>error_chain! {
    foreign_links {
        Request(::reqwest::Error);
        Io(::std::io::Error);
    }

    errors {
        InvalidRule(t: String) {
            description("invalid rule")
            display("invalid rule: '{}'", t)
        }

        Uts46(t: ::idna::uts46::Errors) {
            description("UTS #46 processing failed")
            display("UTS #46 processing error: '{:?}'", t)
        }
    }
}
<|endoftext|>


<commit_before>use std::borrow::Borrow;
use std::cmp;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::mem;
use std::ptr;
use std::ops::{Deref, DerefMut};
use std::str;
use std::str::Utf8Error;
use std::slice;

use array::{Array, ArrayExt};
use array::Index;
use CapacityError;
use errors::PubCrateNew;
use odds::char::encode_utf8;

#[cfg(feature="serde-1")]
use serde::{Serialize, Deserialize, Serializer, Deserializer};

/// A string with a fixed capacity.
///
/// The `ArrayString` is a string backed by a fixed size array. It keeps track
/// of its length.
///
/// The string is a contiguous value that you can store directly on the stack
/// if needed.
#[derive(Copy)]
pub struct ArrayString<A: Array<Item=u8>> {
    xs: A,
    len: A::Index,
}

impl<A: Array<Item=u8>> ArrayString<A> {
    /// Create a new empty `ArrayString`.
    ///
    /// Capacity is inferred from the type parameter.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let mut string = ArrayString::<[_; 16]>::new();
    /// string.push_str("foo");
    /// assert_eq!(&string[..], "foo");
    /// assert_eq!(string.capacity(), 16);
    /// ```
    pub fn new() -> ArrayString<A> {
        unsafe {
            ArrayString {
                xs: ::new_array(),
                len: Index::from(0),
            }
        }
    }

    /// Create a new `ArrayString` from a `str`.
    ///
    /// Capacity is inferred from the type parameter.
    ///
    /// **Errors** if the backing array is not large enough to fit the string.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let mut string = ArrayString::<[_; 3]>::from("foo").unwrap();
    /// assert_eq!(&string[..], "foo");
    /// assert_eq!(string.len(), 3);
    /// assert_eq!(string.capacity(), 3);
    /// ```
    pub fn from(s: &str) -> Result<Self, CapacityError<&str>> {
        let mut arraystr = Self::new();
        arraystr.try_push_str(s)?;
        Ok(arraystr)
    }

    /// Create a new `ArrayString` from a byte string literal.
    ///
    /// **Errors** if the byte string literal is not valid UTF-8.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let string = ArrayString::from_byte_string(b"hello world").unwrap();
    /// ```
    pub fn from_byte_string(b: &A) -> Result<Self, Utf8Error> {
        let mut arraystr = Self::new();
        let s = try!(str::from_utf8(b.as_slice()));
        let _result = arraystr.try_push_str(s);
        debug_assert!(_result.is_ok());
        Ok(arraystr)
    }

    /// Return the capacity of the `ArrayString`.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let string = ArrayString::<[_; 3]>::new();
    /// assert_eq!(string.capacity(), 3);
    /// ```
    #[inline]
    pub fn capacity(&self) -> usize { A::capacity() }

    /// Return if the `ArrayString` is completely filled.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let mut string = ArrayString::<[_; 1]>::new();
    /// assert!(!string.is_full());
    /// string.push_str("A");
    /// assert!(string.is_full());
    /// ```
    pub fn is_full(&self) -> bool { self.len() == self.capacity() }

    /// Adds the given char to the end of the string.
    ///
    /// Returns `Ok` if the push succeeds.
    ///
    /// **Errors** if the backing array is not large enough to fit the additional char.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let mut string = ArrayString::<[_; 2]>::new();
    ///
    /// string.push('a');
    /// string.push('b');
    ///
    /// assert_eq!(&string[..], "ab");
    /// ```
    pub fn push(&mut self, c: char) {
        self.try_push(c).unwrap();
    }

    /// Adds the given char to the end of the string.
    ///
    /// Returns `Ok` if the push succeeds.
    ///
    /// **Errors** if the backing array is not large enough to fit the additional char.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let mut string = ArrayString::<[_; 2]>::new();
    ///
    /// string.try_push('a').unwrap();
    /// string.try_push('b').unwrap();
    /// let overflow = string.try_push('c');
    ///
    /// assert_eq!(&string[..], "ab");
    /// assert_eq!(overflow.unwrap_err().element(), 'c');
    /// ```
    pub fn try_push(&mut self, c: char) -> Result<(), CapacityError<char>> {
        let len = self.len();
        unsafe {
            match encode_utf8(c, &mut self.raw_mut_bytes()[len..]) {
                Ok(n) => {
                    self.set_len(len + n);
                    Ok(())
                }
                Err(_) => Err(CapacityError::new(c)),
            }
        }
    }

    /// Adds the given string slice to the end of the string.
    ///
    /// Returns `Ok` if the push succeeds.
    ///
    /// **Errors** if the backing array is not large enough to fit the string.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let mut string = ArrayString::<[_; 2]>::new();
    ///
    /// string.push_str("a");
    /// string.push_str("d");
    ///
    /// assert_eq!(&string[..], "ad");
    /// ```
    pub fn push_str(&mut self, s: &str) {
        self.try_push_str(s).unwrap()
    }

    /// Adds the given string slice to the end of the string.
    ///
    /// Returns `Ok` if the push succeeds.
    ///
    /// **Errors** if the backing array is not large enough to fit the string.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let mut string = ArrayString::<[_; 2]>::new();
    ///
    /// string.try_push_str("a").unwrap();
    /// let overflow1 = string.try_push_str("bc");
    /// string.try_push_str("d").unwrap();
    /// let overflow2 = string.try_push_str("ef");
    ///
    /// assert_eq!(&string[..], "ad");
    /// assert_eq!(overflow1.unwrap_err().element(), "bc");
    /// assert_eq!(overflow2.unwrap_err().element(), "ef");
    /// ```
    pub fn try_push_str<'a>(&mut self, s: &'a str) -> Result<(), CapacityError<&'a str>> {
        if s.len() > self.capacity() - self.len() {
            return Err(CapacityError::new(s));
        }
        unsafe {
            let dst = self.xs.as_mut_ptr().offset(self.len() as isize);
            let src = s.as_ptr();
            ptr::copy_nonoverlapping(src, dst, s.len());
            let newl = self.len() + s.len();
            self.set_len(newl);
        }
        Ok(())
    }

    /// Make the string empty.
    pub fn clear(&mut self) {
        unsafe {
            self.set_len(0);
        }
    }

    /// Set the strings's length.
    ///
    /// May panic if `length` is greater than the capacity.
    ///
    /// This function is `unsafe` because it changes the notion of the
    /// number of “valid” bytes in the string. Use with care.
    #[inline]
    pub unsafe fn set_len(&mut self, length: usize) {
        debug_assert!(length <= self.capacity());
        self.len = Index::from(length);
    }

    /// Return a string slice of the whole `ArrayString`.
    pub fn as_str(&self) -> &str {
        self
    }

    /// Return a mutable slice of the whole string's buffer
    unsafe fn raw_mut_bytes(&mut self) -> &mut [u8] {
        slice::from_raw_parts_mut(self.xs.as_mut_ptr(), self.capacity())
    }
}

impl<A: Array<Item=u8>> Deref for ArrayString<A> {
    type Target = str;
    #[inline]
    fn deref(&self) -> &str {
        unsafe {
            let sl = slice::from_raw_parts(self.xs.as_ptr(), self.len.to_usize());
            str::from_utf8_unchecked(sl)
        }
    }
}

impl<A: Array<Item=u8>> DerefMut for ArrayString<A> {
    #[inline]
    fn deref_mut(&mut self) -> &mut str {
        unsafe {
            let sl = slice::from_raw_parts_mut(self.xs.as_mut_ptr(), self.len.to_usize());
            // FIXME: Nothing but transmute to do this right now
            mem::transmute(sl)
        }
    }
}

impl<A: Array<Item=u8>> PartialEq for ArrayString<A> {
    fn eq(&self, rhs: &Self) -> bool {
        **self == **rhs
    }
}

impl<A: Array<Item=u8>> PartialEq<str> for ArrayString<A> {
    fn eq(&self, rhs: &str) -> bool {
        &**self == rhs
    }
}

impl<A: Array<Item=u8>> PartialEq<ArrayString<A>> for str {
    fn eq(&self, rhs: &ArrayString<A>) -> bool {
        self == &**rhs
    }
}

impl<A: Array<Item=u8>> Eq for ArrayString<A> { }

impl<A: Array<Item=u8>> Hash for ArrayString<A> {
    fn hash<H: Hasher>(&self, h: &mut H) {
        (**self).hash(h)
    }
}

impl<A: Array<Item=u8>> Borrow<str> for ArrayString<A> {
    fn borrow(&self) -> &str { self }
}

impl<A: Array<Item=u8>> AsRef<str> for ArrayString<A> {
    fn as_ref(&self) -> &str { self }
}

impl<A: Array<Item=u8>> fmt::Debug for ArrayString<A> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) }
}

impl<A: Array<Item=u8>> fmt::Display for ArrayString<A> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) }
}

/// `Write` appends written data to the end of the string.
impl<A: Array<Item=u8>> fmt::Write for ArrayString<A> {
    fn write_char(&mut self, c: char) -> fmt::Result {
        self.try_push(c).map_err(|_| fmt::Error)
    }

    fn write_str(&mut self, s: &str) -> fmt::Result {
        self.try_push_str(s).map_err(|_| fmt::Error)
    }
}

impl<A: Array<Item=u8> + Copy> Clone for ArrayString<A> {
    fn clone(&self) -> ArrayString<A> {
        *self
    }
    fn clone_from(&mut self, rhs: &Self) {
        // guaranteed to fit due to types matching.
        self.clear();
        self.try_push_str(rhs).ok();
    }
}

impl<A: Array<Item=u8>> PartialOrd for ArrayString<A> {
    fn partial_cmp(&self, rhs: &Self) -> Option<cmp::Ordering> {
        (**self).partial_cmp(&**rhs)
    }
    fn lt(&self, rhs: &Self) -> bool { **self < **rhs }
    fn le(&self, rhs: &Self) -> bool { **self <= **rhs }
    fn gt(&self, rhs: &Self) -> bool { **self > **rhs }
    fn ge(&self, rhs: &Self) -> bool { **self >= **rhs }
}

impl<A: Array<Item=u8>> PartialOrd<str> for ArrayString<A> {
    fn partial_cmp(&self, rhs: &str) -> Option<cmp::Ordering> {
        (**self).partial_cmp(rhs)
    }
    fn lt(&self, rhs: &str) -> bool { &**self < rhs }
    fn le(&self, rhs: &str) -> bool { &**self <= rhs }
    fn gt(&self, rhs: &str) -> bool { &**self > rhs }
    fn ge(&self, rhs: &str) -> bool { &**self >= rhs }
}

impl<A: Array<Item=u8>> PartialOrd<ArrayString<A>> for str {
    fn partial_cmp(&self, rhs: &ArrayString<A>) -> Option<cmp::Ordering> {
        self.partial_cmp(&**rhs)
    }
    fn lt(&self, rhs: &ArrayString<A>) -> bool { self < &**rhs }
    fn le(&self, rhs: &ArrayString<A>) -> bool { self <= &**rhs }
    fn gt(&self, rhs: &ArrayString<A>) -> bool { self > &**rhs }
    fn ge(&self, rhs: &ArrayString<A>) -> bool { self >= &**rhs }
}

impl<A: Array<Item=u8>> Ord for ArrayString<A> {
    fn cmp(&self, rhs: &Self) -> cmp::Ordering {
        (**self).cmp(&**rhs)
    }
}

#[cfg(feature="serde-1")]
impl<A: Array<Item=u8>> Serialize for ArrayString<A> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: Serializer
    {
        serializer.serialize_str(&*self)
    }
}

#[cfg(feature="serde-1")]
impl<'de, A: Array<Item=u8>> Deserialize<'de> for ArrayString<A> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: Deserializer<'de>
    {
        use serde::de::{self, Visitor};
        use std::marker::PhantomData;

        struct ArrayStringVisitor<A: Array<Item=u8>>(PhantomData<A>);

        impl<'de, A: Array<Item=u8>> Visitor<'de> for ArrayStringVisitor<A> {
            type Value = ArrayString<A>;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                write!(formatter, "a string no more than {} bytes long", A::capacity())
            }

            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
                where E: de::Error,
            {
                ArrayString::from(v).map_err(|_| E::invalid_length(v.len(), &self))
            }

            fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
                where E: de::Error,
            {
                let s = try!(str::from_utf8(v).map_err(|_| E::invalid_value(de::Unexpected::Bytes(v), &self)));

                ArrayString::from(s).map_err(|_| E::invalid_length(s.len(), &self))
            }
        }

        deserializer.deserialize_str(ArrayStringVisitor::<A>(PhantomData))
    }
}
<commit_msg>DOC: Fix ArrayString docs for push/push_str<commit_after>use std::borrow::Borrow;
use std::cmp;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::mem;
use std::ptr;
use std::ops::{Deref, DerefMut};
use std::str;
use std::str::Utf8Error;
use std::slice;

use array::{Array, ArrayExt};
use array::Index;
use CapacityError;
use errors::PubCrateNew;
use odds::char::encode_utf8;

#[cfg(feature="serde-1")]
use serde::{Serialize, Deserialize, Serializer, Deserializer};

/// A string with a fixed capacity.
///
/// The `ArrayString` is a string backed by a fixed size array. It keeps track
/// of its length.
///
/// The string is a contiguous value that you can store directly on the stack
/// if needed.
#[derive(Copy)]
pub struct ArrayString<A: Array<Item=u8>> {
    xs: A,
    len: A::Index,
}

impl<A: Array<Item=u8>> ArrayString<A> {
    /// Create a new empty `ArrayString`.
    ///
    /// Capacity is inferred from the type parameter.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let mut string = ArrayString::<[_; 16]>::new();
    /// string.push_str("foo");
    /// assert_eq!(&string[..], "foo");
    /// assert_eq!(string.capacity(), 16);
    /// ```
    pub fn new() -> ArrayString<A> {
        unsafe {
            ArrayString {
                xs: ::new_array(),
                len: Index::from(0),
            }
        }
    }

    /// Create a new `ArrayString` from a `str`.
    ///
    /// Capacity is inferred from the type parameter.
    ///
    /// **Errors** if the backing array is not large enough to fit the string.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let mut string = ArrayString::<[_; 3]>::from("foo").unwrap();
    /// assert_eq!(&string[..], "foo");
    /// assert_eq!(string.len(), 3);
    /// assert_eq!(string.capacity(), 3);
    /// ```
    pub fn from(s: &str) -> Result<Self, CapacityError<&str>> {
        let mut arraystr = Self::new();
        arraystr.try_push_str(s)?;
        Ok(arraystr)
    }

    /// Create a new `ArrayString` from a byte string literal.
    ///
    /// **Errors** if the byte string literal is not valid UTF-8.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let string = ArrayString::from_byte_string(b"hello world").unwrap();
    /// ```
    pub fn from_byte_string(b: &A) -> Result<Self, Utf8Error> {
        let mut arraystr = Self::new();
        let s = try!(str::from_utf8(b.as_slice()));
        let _result = arraystr.try_push_str(s);
        debug_assert!(_result.is_ok());
        Ok(arraystr)
    }

    /// Return the capacity of the `ArrayString`.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let string = ArrayString::<[_; 3]>::new();
    /// assert_eq!(string.capacity(), 3);
    /// ```
    #[inline]
    pub fn capacity(&self) -> usize { A::capacity() }

    /// Return if the `ArrayString` is completely filled.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let mut string = ArrayString::<[_; 1]>::new();
    /// assert!(!string.is_full());
    /// string.push_str("A");
    /// assert!(string.is_full());
    /// ```
    pub fn is_full(&self) -> bool { self.len() == self.capacity() }

    /// Adds the given char to the end of the string.
    ///
    /// Returns `Ok` if the push succeeds.
    ///
    /// ***Panics*** if the backing array is not large enough to fit the additional char.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let mut string = ArrayString::<[_; 2]>::new();
    ///
    /// string.push('a');
    /// string.push('b');
    ///
    /// assert_eq!(&string[..], "ab");
    /// ```
    pub fn push(&mut self, c: char) {
        self.try_push(c).unwrap();
    }

    /// Adds the given char to the end of the string.
    ///
    /// Returns `Ok` if the push succeeds.
    ///
    /// **Errors** if the backing array is not large enough to fit the additional char.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let mut string = ArrayString::<[_; 2]>::new();
    ///
    /// string.try_push('a').unwrap();
    /// string.try_push('b').unwrap();
    /// let overflow = string.try_push('c');
    ///
    /// assert_eq!(&string[..], "ab");
    /// assert_eq!(overflow.unwrap_err().element(), 'c');
    /// ```
    pub fn try_push(&mut self, c: char) -> Result<(), CapacityError<char>> {
        let len = self.len();
        unsafe {
            match encode_utf8(c, &mut self.raw_mut_bytes()[len..]) {
                Ok(n) => {
                    self.set_len(len + n);
                    Ok(())
                }
                Err(_) => Err(CapacityError::new(c)),
            }
        }
    }

    /// Adds the given string slice to the end of the string.
    ///
    /// Returns `Ok` if the push succeeds.
    ///
    /// ***Panics*** if the backing array is not large enough to fit the string.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let mut string = ArrayString::<[_; 2]>::new();
    ///
    /// string.push_str("a");
    /// string.push_str("d");
    ///
    /// assert_eq!(&string[..], "ad");
    /// ```
    pub fn push_str(&mut self, s: &str) {
        self.try_push_str(s).unwrap()
    }

    /// Adds the given string slice to the end of the string.
    ///
    /// Returns `Ok` if the push succeeds.
    ///
    /// **Errors** if the backing array is not large enough to fit the string.
    ///
    /// ```
    /// use arrayvec::ArrayString;
    ///
    /// let mut string = ArrayString::<[_; 2]>::new();
    ///
    /// string.try_push_str("a").unwrap();
    /// let overflow1 = string.try_push_str("bc");
    /// string.try_push_str("d").unwrap();
    /// let overflow2 = string.try_push_str("ef");
    ///
    /// assert_eq!(&string[..], "ad");
    /// assert_eq!(overflow1.unwrap_err().element(), "bc");
    /// assert_eq!(overflow2.unwrap_err().element(), "ef");
    /// ```
    pub fn try_push_str<'a>(&mut self, s: &'a str) -> Result<(), CapacityError<&'a str>> {
        if s.len() > self.capacity() - self.len() {
            return Err(CapacityError::new(s));
        }
        unsafe {
            let dst = self.xs.as_mut_ptr().offset(self.len() as isize);
            let src = s.as_ptr();
            ptr::copy_nonoverlapping(src, dst, s.len());
            let newl = self.len() + s.len();
            self.set_len(newl);
        }
        Ok(())
    }

    /// Make the string empty.
    pub fn clear(&mut self) {
        unsafe {
            self.set_len(0);
        }
    }

    /// Set the strings's length.
    ///
    /// May panic if `length` is greater than the capacity.
    ///
    /// This function is `unsafe` because it changes the notion of the
    /// number of “valid” bytes in the string. Use with care.
    #[inline]
    pub unsafe fn set_len(&mut self, length: usize) {
        debug_assert!(length <= self.capacity());
        self.len = Index::from(length);
    }

    /// Return a string slice of the whole `ArrayString`.
    pub fn as_str(&self) -> &str {
        self
    }

    /// Return a mutable slice of the whole string's buffer
    unsafe fn raw_mut_bytes(&mut self) -> &mut [u8] {
        slice::from_raw_parts_mut(self.xs.as_mut_ptr(), self.capacity())
    }
}

impl<A: Array<Item=u8>> Deref for ArrayString<A> {
    type Target = str;
    #[inline]
    fn deref(&self) -> &str {
        unsafe {
            let sl = slice::from_raw_parts(self.xs.as_ptr(), self.len.to_usize());
            str::from_utf8_unchecked(sl)
        }
    }
}

impl<A: Array<Item=u8>> DerefMut for ArrayString<A> {
    #[inline]
    fn deref_mut(&mut self) -> &mut str {
        unsafe {
            let sl = slice::from_raw_parts_mut(self.xs.as_mut_ptr(), self.len.to_usize());
            // FIXME: Nothing but transmute to do this right now
            mem::transmute(sl)
        }
    }
}

impl<A: Array<Item=u8>> PartialEq for ArrayString<A> {
    fn eq(&self, rhs: &Self) -> bool {
        **self == **rhs
    }
}

impl<A: Array<Item=u8>> PartialEq<str> for ArrayString<A> {
    fn eq(&self, rhs: &str) -> bool {
        &**self == rhs
    }
}

impl<A: Array<Item=u8>> PartialEq<ArrayString<A>> for str {
    fn eq(&self, rhs: &ArrayString<A>) -> bool {
        self == &**rhs
    }
}

impl<A: Array<Item=u8>> Eq for ArrayString<A> { }

impl<A: Array<Item=u8>> Hash for ArrayString<A> {
    fn hash<H: Hasher>(&self, h: &mut H) {
        (**self).hash(h)
    }
}

impl<A: Array<Item=u8>> Borrow<str> for ArrayString<A> {
    fn borrow(&self) -> &str { self }
}

impl<A: Array<Item=u8>> AsRef<str> for ArrayString<A> {
    fn as_ref(&self) -> &str { self }
}

impl<A: Array<Item=u8>> fmt::Debug for ArrayString<A> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) }
}

impl<A: Array<Item=u8>> fmt::Display for ArrayString<A> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) }
}

/// `Write` appends written data to the end of the string.
impl<A: Array<Item=u8>> fmt::Write for ArrayString<A> {
    fn write_char(&mut self, c: char) -> fmt::Result {
        self.try_push(c).map_err(|_| fmt::Error)
    }

    fn write_str(&mut self, s: &str) -> fmt::Result {
        self.try_push_str(s).map_err(|_| fmt::Error)
    }
}

impl<A: Array<Item=u8> + Copy> Clone for ArrayString<A> {
    fn clone(&self) -> ArrayString<A> {
        *self
    }
    fn clone_from(&mut self, rhs: &Self) {
        // guaranteed to fit due to types matching.
        self.clear();
        self.try_push_str(rhs).ok();
    }
}

impl<A: Array<Item=u8>> PartialOrd for ArrayString<A> {
    fn partial_cmp(&self, rhs: &Self) -> Option<cmp::Ordering> {
        (**self).partial_cmp(&**rhs)
    }
    fn lt(&self, rhs: &Self) -> bool { **self < **rhs }
    fn le(&self, rhs: &Self) -> bool { **self <= **rhs }
    fn gt(&self, rhs: &Self) -> bool { **self > **rhs }
    fn ge(&self, rhs: &Self) -> bool { **self >= **rhs }
}

impl<A: Array<Item=u8>> PartialOrd<str> for ArrayString<A> {
    fn partial_cmp(&self, rhs: &str) -> Option<cmp::Ordering> {
        (**self).partial_cmp(rhs)
    }
    fn lt(&self, rhs: &str) -> bool { &**self < rhs }
    fn le(&self, rhs: &str) -> bool { &**self <= rhs }
    fn gt(&self, rhs: &str) -> bool { &**self > rhs }
    fn ge(&self, rhs: &str) -> bool { &**self >= rhs }
}

impl<A: Array<Item=u8>> PartialOrd<ArrayString<A>> for str {
    fn partial_cmp(&self, rhs: &ArrayString<A>) -> Option<cmp::Ordering> {
        self.partial_cmp(&**rhs)
    }
    fn lt(&self, rhs: &ArrayString<A>) -> bool { self < &**rhs }
    fn le(&self, rhs: &ArrayString<A>) -> bool { self <= &**rhs }
    fn gt(&self, rhs: &ArrayString<A>) -> bool { self > &**rhs }
    fn ge(&self, rhs: &ArrayString<A>) -> bool { self >= &**rhs }
}

impl<A: Array<Item=u8>> Ord for ArrayString<A> {
    fn cmp(&self, rhs: &Self) -> cmp::Ordering {
        (**self).cmp(&**rhs)
    }
}

#[cfg(feature="serde-1")]
impl<A: Array<Item=u8>> Serialize for ArrayString<A> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: Serializer
    {
        serializer.serialize_str(&*self)
    }
}

#[cfg(feature="serde-1")]
impl<'de, A: Array<Item=u8>> Deserialize<'de> for ArrayString<A> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: Deserializer<'de>
    {
        use serde::de::{self, Visitor};
        use std::marker::PhantomData;

        struct ArrayStringVisitor<A: Array<Item=u8>>(PhantomData<A>);

        impl<'de, A: Array<Item=u8>> Visitor<'de> for ArrayStringVisitor<A> {
            type Value = ArrayString<A>;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                write!(formatter, "a string no more than {} bytes long", A::capacity())
            }

            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
                where E: de::Error,
            {
                ArrayString::from(v).map_err(|_| E::invalid_length(v.len(), &self))
            }

            fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
                where E: de::Error,
            {
                let s = try!(str::from_utf8(v).map_err(|_| E::invalid_value(de::Unexpected::Bytes(v), &self)));

                ArrayString::from(s).map_err(|_| E::invalid_length(s.len(), &self))
            }
        }

        deserializer.deserialize_str(ArrayStringVisitor::<A>(PhantomData))
    }
}
<|endoftext|>