<commit_before>use ansi_term::Style;
use fs::File;
use info::filetype::FileExtensions;
use output::file_name::FileStyle;

pub trait FileIcon {
    fn icon_file(&self, file: &File) -> Option<char>;
}

pub enum Icons {
    Audio,
    Image,
    Video,
}

impl Icons {
    pub fn value(&self) -> char {
        match *self {
            Icons::Audio => '\u{f001}',
            Icons::Image => '\u{f1c5}',
            Icons::Video => '\u{f03d}',
        }
    }
}

pub fn painted_icon(file: &File, style: &FileStyle) -> String {
    let file_icon = icon(&file).to_string();
    let painted = style.exts
            .colour_file(&file)
            .map_or(file_icon.to_string(), |c| {
                // Remove underline from icon
                if c.is_underline {
                    match c.foreground {
                        Some(color) => Style::from(color).paint(file_icon).to_string(),
                        None => Style::default().paint(file_icon).to_string(),
                    }
                } else {
                    c.paint(file_icon).to_string()
                }
            });
    format!("{} ", painted)
}

fn icon(file: &File) -> char {
    let extensions = Box::new(FileExtensions);
    if file.is_directory() { '\u{f115}' }
    else if let Some(icon) = extensions.icon_file(file) { icon }
    else {
        if let Some(ext) = file.ext.as_ref() {
            match ext.as_str() {
                "ai" => '\u{e7b4}',
                "android" => '\u{e70e}',
                "apple" => '\u{f179}',
                "avro" => '\u{e60b}',
                "clj" => '\u{e768}',
                "coffee" => '\u{f0f4}',
                "conf" => '\u{e615}',
                "cpp" => '\u{e61d}',
                "hpp" => '\u{e61d}',
                "c" => '\u{e61e}',
                "h" => '\u{e61e}',
                "cs" => '\u{f81a}',
                "css" => '\u{e749}',
                "d" => '\u{e7af}',
                "dart" => '\u{e798}',
                "db" => '\u{f1c0}',
                "diff" => '\u{f440}',
                "patch" => '\u{f440}',
                "doc" => '\u{f1c2}',
                "docx" => '\u{f1c2}',
                "odt" => '\u{f1c2}',
                "ebook" => '\u{e28b}',
                "env" => '\u{f462}',
                "epub" => '\u{e28a}',
                "erl" => '\u{e7b1}',
                "font" => '\u{f031}',
                "gform" => '\u{f298}',
                "git" => '\u{f1d3}',
                "go" => '\u{e626}',
                "hs" => '\u{e777}',
                "html" => '\u{f13b}',
                "iml" => '\u{e7b5}',
                "java" => '\u{e204}',
                "js" => '\u{e74e}',
                "mjs" => '\u{e74e}',
                "json" => '\u{e60b}',
                "jsx" => '\u{e7ba}',
                "vue" => '\u{fd42}',
                "node" => '\u{f898}',
                "less" => '\u{e758}',
                "log" => '\u{f18d}',
                "lua" => '\u{e620}',
                "md" => '\u{f48a}',
                "markdown" => '\u{f48a}',
                "mustache" => '\u{e60f}',
                "npmignore" => '\u{e71e}',
                "pdf" => '\u{f1c1}',
                "php" => '\u{e73d}',
                "pl" => '\u{e769}',
                "ppt" => '\u{f1c4}',
                "psd" => '\u{e7b8}',
                "py" => '\u{e606}',
                "r" => '\u{f25d}',
                "rb" => '\u{e21e}',
                "rdb" => '\u{e76d}',
                "rs" => '\u{e7a8}',
                "rss" => '\u{f09e}',
                "rubydoc" => '\u{e73b}',
                "sass" => '\u{e603}',
                "scala" => '\u{e737}',
                "shell" => '\u{f489}',
                "sqlite3" => '\u{e7c4}',
                "styl" => '\u{e600}',
                "tex" => '\u{e600}',
                "ts" => '\u{e628}',
                "tsx" => '\u{e628}',
                "twig" => '\u{e61c}',
                "txt" => '\u{f15c}',
                "video" => '\u{f03d}',
                "vim" => '\u{e62b}',
                "xml" => '\u{e619}',
                "yml" => '\u{f481}',
                "zip" => '\u{f410}',
                "deb" => '\u{e77d}',
                "rpm" => '\u{e7bb}',
                "exe" => '\u{e70f}',
                "msi" => '\u{e70f}',
                "dll" => '\u{e70f}',
                "sh" => '\u{e795}',
                "bash" => '\u{e795}',
                "zsh" => '\u{e795}',
                "fish" => '\u{e795}',
                "csh" => '\u{e795}',
                "ini" => '\u{e615}',
                "toml" => '\u{e615}',
                "apk" => '\u{e70e}',
                "ttf" => '\u{f031}',
                "woff" => '\u{f031}',
                "woff2" => '\u{f031}',
                "otf" => '\u{f031}',
                "csv" => '\u{f1c3}',
                "tsv" => '\u{f1c3}',
                "xls" => '\u{f1c3}',
                "xlsx" => '\u{f1c3}',
                "ods" => '\u{f1c3}',
                "so" => '\u{f17c}',
                "sql" => '\u{f1c0}',
                "jar" => '\u{e256}',
                "jad" => '\u{e256}',
                "war" => '\u{e256}',
                "groovy" => '\u{e775}',
                _ => '\u{f15b}'
            }
        } else {
            '\u{f15b}'
        }
    }
}
<commit_msg>Align file<commit_after>use ansi_term::Style;
use fs::File;
use info::filetype::FileExtensions;
use output::file_name::FileStyle;

pub trait FileIcon {
    fn icon_file(&self, file: &File) -> Option<char>;
}

pub enum Icons {
    Audio,
    Image,
    Video,
}

impl Icons {
    pub fn value(&self) -> char {
        match *self {
            Icons::Audio => '\u{f001}',
            Icons::Image => '\u{f1c5}',
            Icons::Video => '\u{f03d}',
        }
    }
}

pub fn painted_icon(file: &File, style: &FileStyle) -> String {
    let file_icon = icon(&file).to_string();
    let painted = style.exts
            .colour_file(&file)
            .map_or(file_icon.to_string(), |c| {
                // Remove underline from icon
                if c.is_underline {
                    match c.foreground {
                        Some(color) => Style::from(color).paint(file_icon).to_string(),
                        None => Style::default().paint(file_icon).to_string(),
                    }
                } else {
                    c.paint(file_icon).to_string()
                }
            });
    format!("{} ", painted)
}

fn icon(file: &File) -> char {
    let extensions = Box::new(FileExtensions);
    if file.is_directory() { '\u{f115}' }
    else if let Some(icon) = extensions.icon_file(file) { icon }
    else {
        if let Some(ext) = file.ext.as_ref() {
            match ext.as_str() {
                "ai"        => '\u{e7b4}',
                "android"   => '\u{e70e}',
                "apple"     => '\u{f179}',
                "avro"      => '\u{e60b}',
                "clj"       => '\u{e768}',
                "coffee"    => '\u{f0f4}',
                "conf"      => '\u{e615}',
                "cpp"       => '\u{e61d}',
                "hpp"       => '\u{e61d}',
                "c"         => '\u{e61e}',
                "h"         => '\u{e61e}',
                "cs"        => '\u{f81a}',
                "css"       => '\u{e749}',
                "d"         => '\u{e7af}',
                "dart"      => '\u{e798}',
                "db"        => '\u{f1c0}',
                "diff"      => '\u{f440}',
                "patch"     => '\u{f440}',
                "doc"       => '\u{f1c2}',
                "docx"      => '\u{f1c2}',
                "odt"       => '\u{f1c2}',
                "ebook"     => '\u{e28b}',
                "env"       => '\u{f462}',
                "epub"      => '\u{e28a}',
                "erl"       => '\u{e7b1}',
                "font"      => '\u{f031}',
                "gform"     => '\u{f298}',
                "git"       => '\u{f1d3}',
                "go"        => '\u{e626}',
                "hs"        => '\u{e777}',
                "html"      => '\u{f13b}',
                "iml"       => '\u{e7b5}',
                "java"      => '\u{e204}',
                "js"        => '\u{e74e}',
                "mjs"       => '\u{e74e}',
                "json"      => '\u{e60b}',
                "jsx"       => '\u{e7ba}',
                "vue"       => '\u{fd42}',
                "node"      => '\u{f898}',
                "less"      => '\u{e758}',
                "log"       => '\u{f18d}',
                "lua"       => '\u{e620}',
                "md"        => '\u{f48a}',
                "markdown"  => '\u{f48a}',
                "mustache"  => '\u{e60f}',
                "npmignore" => '\u{e71e}',
                "pdf"       => '\u{f1c1}',
                "php"       => '\u{e73d}',
                "pl"        => '\u{e769}',
                "ppt"       => '\u{f1c4}',
                "psd"       => '\u{e7b8}',
                "py"        => '\u{e606}',
                "r"         => '\u{f25d}',
                "rb"        => '\u{e21e}',
                "rdb"       => '\u{e76d}',
                "rs"        => '\u{e7a8}',
                "rss"       => '\u{f09e}',
                "rubydoc"   => '\u{e73b}',
                "sass"      => '\u{e603}',
                "scala"     => '\u{e737}',
                "shell"     => '\u{f489}',
                "sqlite3"   => '\u{e7c4}',
                "styl"      => '\u{e600}',
                "tex"       => '\u{e600}',
                "ts"        => '\u{e628}',
                "tsx"       => '\u{e628}',
                "twig"      => '\u{e61c}',
                "txt"       => '\u{f15c}',
                "video"     => '\u{f03d}',
                "vim"       => '\u{e62b}',
                "xml"       => '\u{e619}',
                "yml"       => '\u{f481}',
                "zip"       => '\u{f410}',
                "deb"       => '\u{e77d}',
                "rpm"       => '\u{e7bb}',
                "exe"       => '\u{e70f}',
                "msi"       => '\u{e70f}',
                "dll"       => '\u{e70f}',
                "sh"        => '\u{e795}',
                "bash"      => '\u{e795}',
                "zsh"       => '\u{e795}',
                "fish"      => '\u{e795}',
                "csh"       => '\u{e795}',
                "ini"       => '\u{e615}',
                "toml"      => '\u{e615}',
                "apk"       => '\u{e70e}',
                "ttf"       => '\u{f031}',
                "woff"      => '\u{f031}',
                "woff2"     => '\u{f031}',
                "otf"       => '\u{f031}',
                "csv"       => '\u{f1c3}',
                "tsv"       => '\u{f1c3}',
                "xls"       => '\u{f1c3}',
                "xlsx"      => '\u{f1c3}',
                "ods"       => '\u{f1c3}',
                "so"        => '\u{f17c}',
                "sql"       => '\u{f1c0}',
                "jar"       => '\u{e256}',
                "jad"       => '\u{e256}',
                "war"       => '\u{e256}',
                "groovy"    => '\u{e775}',
                _           => '\u{f15b}'
            }
        } else {
            '\u{f15b}'
        }
    }
}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::collections::BTreeMap;
use std::iter::FromIterator;
use std::path::Path;
use std::vec::Vec;

use engine::Cache;
use engine::Dev;
use engine::EngineResult;
use engine::Filesystem;
use engine::Pool;

use super::blockdev::SimDev;
use super::cache::SimCacheDev;
use super::filesystem::SimFilesystem;

#[derive(Debug)]
pub struct SimPool {
    pub block_devs: Vec<Box<SimDev>>,
    pub cache_devs: Vec<Box<SimCacheDev>>,
    pub filesystems: BTreeMap<String, Box<SimFilesystem>>,
    pub raid_level: u16,
    pub online: bool,
    pub checking: bool,
}

impl SimPool {
    pub fn new_pool(blockdevs: &[Box<SimDev>], raid_level: u16) -> Box<Pool> {

        let mut vec = Vec::new();
        vec.extend_from_slice(blockdevs);
        let new_pool = SimPool {
            block_devs: vec,
            filesystems: BTreeMap::new(),
            cache_devs: Vec::new(),
            raid_level: raid_level,
            online: true,
            checking: false,
        };

        Box::new(new_pool)
    }
}

impl Pool for SimPool {
    fn add_blockdev(&mut self, path: &Path) -> EngineResult<()> {
        self.block_devs.push(SimDev::new_dev(path));
        Ok(())
    }

    fn add_cachedev(&mut self, path: &Path) -> EngineResult<()> {
        self.cache_devs.push(SimCacheDev::new_cache(path));
        Ok(())
    }

    fn destroy(&mut self) -> EngineResult<()> {
        println!("sim: pool::destroy");
        Ok(())
    }

    fn copy(&self) -> Box<Pool> {
        let pool_copy = SimPool {
            block_devs: self.block_devs.clone(),
            cache_devs: self.cache_devs.clone(),
            filesystems: self.filesystems.clone(),
            raid_level: self.raid_level.clone(),
            online: true,
            checking: false,
        };
        Box::new(pool_copy)
    }

    fn create_filesystem(&mut self,
                         filesystem_name: &str,
                         mount_point: &str,
                         size: u64)
                         -> EngineResult<()> {
        self.filesystems.insert(filesystem_name.to_owned(),
                                SimFilesystem::new_filesystem(mount_point, size));
        Ok(())
    }

    fn list_filesystems(&self) -> EngineResult<BTreeMap<String, Box<Filesystem>>> {
        Ok(BTreeMap::from_iter(self.filesystems.iter().map(|x| (x.0.clone(), x.1.copy()))))
    }

    fn list_blockdevs(&self) -> EngineResult<Vec<Box<Dev>>> {
        Ok(Vec::from_iter(self.block_devs.iter().map(|x| (x.copy()))))
    }

    fn list_cachedevs(&self) -> EngineResult<Vec<Box<Cache>>> {
        Ok(Vec::from_iter(self.cache_devs.iter().map(|x| (x.copy()))))
    }
}
<commit_msg>If filesystem already exists for this pool, return an error.<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::collections::BTreeMap;
use std::iter::FromIterator;
use std::path::Path;
use std::vec::Vec;

use engine::Cache;
use engine::Dev;
use engine::EngineError;
use engine::EngineResult;
use engine::ErrorEnum;
use engine::Filesystem;
use engine::Pool;

use super::blockdev::SimDev;
use super::cache::SimCacheDev;
use super::filesystem::SimFilesystem;

#[derive(Debug)]
pub struct SimPool {
    pub block_devs: Vec<Box<SimDev>>,
    pub cache_devs: Vec<Box<SimCacheDev>>,
    pub filesystems: BTreeMap<String, Box<SimFilesystem>>,
    pub raid_level: u16,
    pub online: bool,
    pub checking: bool,
}

impl SimPool {
    pub fn new_pool(blockdevs: &[Box<SimDev>], raid_level: u16) -> Box<Pool> {

        let mut vec = Vec::new();
        vec.extend_from_slice(blockdevs);
        let new_pool = SimPool {
            block_devs: vec,
            filesystems: BTreeMap::new(),
            cache_devs: Vec::new(),
            raid_level: raid_level,
            online: true,
            checking: false,
        };

        Box::new(new_pool)
    }
}

impl Pool for SimPool {
    fn add_blockdev(&mut self, path: &Path) -> EngineResult<()> {
        self.block_devs.push(SimDev::new_dev(path));
        Ok(())
    }

    fn add_cachedev(&mut self, path: &Path) -> EngineResult<()> {
        self.cache_devs.push(SimCacheDev::new_cache(path));
        Ok(())
    }

    fn destroy(&mut self) -> EngineResult<()> {
        println!("sim: pool::destroy");
        Ok(())
    }

    fn copy(&self) -> Box<Pool> {
        let pool_copy = SimPool {
            block_devs: self.block_devs.clone(),
            cache_devs: self.cache_devs.clone(),
            filesystems: self.filesystems.clone(),
            raid_level: self.raid_level.clone(),
            online: true,
            checking: false,
        };
        Box::new(pool_copy)
    }

    fn create_filesystem(&mut self,
                         filesystem_name: &str,
                         mount_point: &str,
                         size: u64)
                         -> EngineResult<()> {

        if self.filesystems.contains_key(filesystem_name) {
            return Err(EngineError::Stratis(ErrorEnum::AlreadyExists(filesystem_name.into())));
        }

        self.filesystems.insert(filesystem_name.to_owned(),
                                SimFilesystem::new_filesystem(mount_point, size));
        Ok(())
    }

    fn list_filesystems(&self) -> EngineResult<BTreeMap<String, Box<Filesystem>>> {
        Ok(BTreeMap::from_iter(self.filesystems.iter().map(|x| (x.0.clone(), x.1.copy()))))
    }

    fn list_blockdevs(&self) -> EngineResult<Vec<Box<Dev>>> {
        Ok(Vec::from_iter(self.block_devs.iter().map(|x| (x.copy()))))
    }

    fn list_cachedevs(&self) -> EngineResult<Vec<Box<Cache>>> {
        Ok(Vec::from_iter(self.cache_devs.iter().map(|x| (x.copy()))))
    }
}
<|endoftext|>


<commit_before>#[derive(Debug, Clone, PartialEq)]
pub enum TokenOperator {
    START,
    CMD,
    AND,
    OR,
    PIPE,
    RIGHT,
    LEFT,
    SEMI,
    EOF
}

#[derive(Debug, Clone)]
pub struct Token {
    pub kind: TokenOperator,
    pub value: Option<String>
}

pub struct Lexer {
    command: String,
    pos: usize,
    current_char: Option<char>,
}

impl Lexer {
    pub fn new(command: String) -> Lexer {
        let c = command.clone().chars().next();
        return Lexer {
            command,
            pos: 0,
            current_char: c
        }
    }

    fn peek(&self) -> Option<char> {
        let peek_pos = self.pos + 1;
        if peek_pos > self.command.len() {
            return None;
        }
        return self.command.chars().nth(peek_pos)
    }

    fn command(&mut self) -> Token {
        let mut result: String = String::new();
        while let Some(c) = self.current_char {
            if !";|&><".contains(c) {
                result.push(c);
                self.advance();
            } else if c.is_whitespace() {
                self.skip_whitespace();
            } else {
                break;
            }

        }
        result = result.trim().to_string();
        return Token {
            kind: TokenOperator:: CMD,
            value: Some(result)
        }
    }

    fn advance(&mut self) {
        self.pos += 1;
        self.current_char = self.command.chars().nth(self.pos);
    }

    fn skip_whitespace(&mut self) {
        while self.pos < self.command.len() && self.current_char.unwrap().is_whitespace() {
            self.advance();
        }
    }

    fn peek_check(&mut self, c: char) -> bool{
        match self.peek() {
            Some(p) => return p == c,
            None    => return false
        }
    }

    pub fn get_next_token(&mut self) -> Token {
        while self.current_char.is_some() {
            let c = self.current_char.unwrap();
            if c.is_whitespace() {
                self.skip_whitespace();
                continue;
            }

            if c == ';' {
                self.advance();
                return Token { kind: TokenOperator::SEMI, value: None }
            } else if c == '|' && self.peek_check(c) {
                self.advance();
                self.advance();
                return Token { kind: TokenOperator::OR, value: None }
            } else if c == '&' && self.peek_check(c) {
                self.advance();
                self.advance();
                return Token { kind: TokenOperator::AND, value: None }
            } else if c.is_alphabetic() {
                return self.command();
            } else {
                panic!("Unknown token")
            }
        }
        return Token { kind: TokenOperator::EOF, value: None }
    }

    pub fn set_command(&mut self, command: String) {
        let c = command.clone().chars().next();
        self.command = command;
        self.pos = 0;
        self.current_char = c
    }
}
<commit_msg>Changed enum names to match guidelines<commit_after>#[derive(Debug, Clone, PartialEq)]
pub enum TokenOperator {
    Start,
    Cmd,
    And,
    Or,
    Pipe,
    SingleRight,
    SingleLeft,
    Semi,
    Eof
}

#[derive(Debug, Clone)]
pub struct Token {
    pub kind: TokenOperator,
    pub value: Option<String>
}

pub struct Lexer {
    command: String,
    pos: usize,
    current_char: Option<char>,
}

impl Lexer {
    pub fn new(command: String) -> Lexer {
        let c = command.clone().chars().next();
        return Lexer {
            command,
            pos: 0,
            current_char: c
        }
    }

    fn peek(&self) -> Option<char> {
        let peek_pos = self.pos + 1;
        if peek_pos > self.command.len() {
            return None;
        }
        return self.command.chars().nth(peek_pos)
    }

    fn command(&mut self) -> Token {
        let mut result: String = String::new();
        while let Some(c) = self.current_char {
            if !";|&><".contains(c) {
                result.push(c);
                self.advance();
            } else if c.is_whitespace() {
                self.skip_whitespace();
            } else {
                break;
            }

        }
        result = result.trim().to_string();
        return Token {
            kind: TokenOperator:: CMD,
            value: Some(result)
        }
    }

    fn advance(&mut self) {
        self.pos += 1;
        self.current_char = self.command.chars().nth(self.pos);
    }

    fn skip_whitespace(&mut self) {
        while self.pos < self.command.len() && self.current_char.unwrap().is_whitespace() {
            self.advance();
        }
    }

    fn peek_check(&mut self, c: char) -> bool{
        match self.peek() {
            Some(p) => return p == c,
            None    => return false
        }
    }

    pub fn get_next_token(&mut self) -> Token {
        while self.current_char.is_some() {
            let c = self.current_char.unwrap();
            if c.is_whitespace() {
                self.skip_whitespace();
                continue;
            }

            if c == ';' {
                self.advance();
                return Token { kind: TokenOperator::SEMI, value: None }
            } else if c == '|' && self.peek_check(c) {
                self.advance();
                self.advance();
                return Token { kind: TokenOperator::OR, value: None }
            } else if c == '&' && self.peek_check(c) {
                self.advance();
                self.advance();
                return Token { kind: TokenOperator::AND, value: None }
            } else if c.is_alphabetic() {
                return self.command();
            } else {
                panic!("Unknown token")
            }
        }
        return Token { kind: TokenOperator::EOF, value: None }
    }

    pub fn set_command(&mut self, command: String) {
        let c = command.clone().chars().next();
        self.command = command;
        self.pos = 0;
        self.current_char = c
    }
}
<|endoftext|>


<commit_before>#!/usr/bin/env rust

use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();
    let args = &args[1..];

    let output = if args.is_empty() { "y".to_string() } else { args.join(" ") };
    loop {
        println!("{}", output)
    }
}
<commit_msg>Fix rust shebang rust->rustc<commit_after>#!/usr/bin/env rustc

use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();
    let args = &args[1..];

    let output = if args.is_empty() { "y".to_string() } else { args.join(" ") };
    loop {
        println!("{}", output)
    }
}
<|endoftext|>


<commit_before>//! List projects
//!
//! https://docs.gitlab.com/ce/api/projects.html
//!
//! # List projects
//!
//! Get a list of projects for which the authenticated user is a member.
//!
//! ```text
//! GET /projects
//! ```
//!
//! Parameters:
//!
//! | Attribute | Type | Required | Description |
//! | --------- | ---- | -------- | ----------- |
//! | `archived` | boolean | no | Limit by archived status |
//! | `visibility` | string | no | Limit by visibility `public`, `internal`, or `private` |
//! | `order_by` | string | no | Return projects ordered by `id`, `name`, `path`, `created_at`, `updated_at`, or `last_activity_at` fields. Default is `created_at` |
//! | `sort` | string | no | Return projects sorted in `asc` or `desc` order. Default is `desc` |
//! | `search` | string | no | Return list of authorized projects matching the search criteria |
//! | `simple` | boolean | no | Return only the ID, URL, name, and path of each project |
//!

use BuildQuery;

use serde_json;

use gitlab::GitLab;
use Project;
use Projects;

pub mod all;
pub mod id_branches;
pub mod id_branch;
pub mod id_events;
pub mod id_hooks_id;
pub mod id_hooks;
pub mod id;
pub mod owned;
pub mod search;
pub mod starred;
pub mod visible;

// TODO:
//
// Creates a new project owned by the authenticated user.
// POST /projects
//
// Creates a new project owned by the specified user. Available only for admins.
// POST /projects/user/:user_id
//
// Updates an existing project
// PUT /projects/:id
//
// Forks a project into the user namespace of the authenticated user or the one provided.
// POST /projects/fork/:id
//
// Stars a given project. Returns status code `201` and the project on success and `304` if the
// project is already starred.
// POST /projects/:id/star
//
// Unstars a given project. Returns status code `200` and the project on success and `304` if the
// project is not starred.
// DELETE /projects/:id/star
//
// Archives the project if the user is either admin or the project owner of this project. This
// action is idempotent, thus archiving an already archived project will not change the project.
//
// Status code `201` with the project as body is given when successful, in case the user doesn't
// have the proper access rights, code `403` is returned. Status `404` is returned if the project
// doesn't exist, or is hidden to the user.
// POST /projects/:id/archive
//
//
// Unarchives the project if the user is either admin or the project owner of this project. This
// action is idempotent, thus unarchiving an non-archived project will not change the project.
//
// Status code `201` with the project as body is given when successful, in case the user doesn't
// have the proper access rights, code `403` is returned. Status `404` is returned if the project
// doesn't exist, or is hidden to the user.
// POST /projects/:id/unarchive
//
//
// Removes a project including all associated resources (issues, merge requests etc.)
// DELETE /projects/:id
//
//
// Uploads a file to the specified project to be used in an issue or merge request description, or
// a comment.
// POST /projects/:id/uploads
//
//
// Allow to share project with group.
// POST /projects/:id/share
//
//
// Adds a hook to a specified project.
// POST /projects/:id/hooks
//
//
// Edits a hook for a specified project.
// PUT /projects/:id/hooks/:hook_id
//
//
// Removes a hook from a project. This is an idempotent method and can be called multiple times.
// Either the hook is available or not.
// DELETE /projects/:id/hooks/:hook_id
//
//
// Protects a single branch of a project.
// PUT /projects/:id/repository/branches/:branch/protect
//
//
// Unprotects a single branch of a project.
// PUT /projects/:id/repository/branches/:branch/unprotect
//
//
// Create a forked from/to relation between existing projects.
// POST /projects/:id/fork/:forked_from_id
//
//
// Delete an existing forked from relationship
// DELETE /projects/:id/fork
//

impl GitLab {
    pub fn projects_list(&self, listing: Listing) -> Result<Projects, serde_json::Error> {
        let query = listing.build_query();
        self.get(&query)
    }
}

// https://docs.gitlab.com/ce/api/projects.html#list-projects

#[derive(Debug, Copy, Clone)]
pub enum ListingOrderBy {
    Id,
    Name,
    Path,
    CreatedAt,
    UpdatedAt,
    LastActivityAt,
}

custom_derive!{
    #[derive(Default, Debug, Builder)]
    pub struct ProjectsLister {
        /// Limit by archived status
        archived: Option<bool>,
        /// Limit by visibility.
        visibility: Option<::ListingVisibility>,
        /// Return requests ordered by. Default is `ListingOrderBy::CreatedAt`.
        order_by: Option<ListingOrderBy>,
        /// Return requests sorted. Default is `::ListingSort::Desc`.
        sort: Option<::ListingSort>,
        /// Return list of authorized projects matching the search criteria.
        search: String,
        /// Return only the ID, URL, name, and path of each project
        simple: Option<bool>,
    }
}

impl ProjectsLister {
    /// Commit the lister: Query GitLab and return a list of projects.
    pub fn list(&mut self) -> Projects {
        Default::default()
    }
}

#[derive(Default, Debug, Clone)]
pub struct Listing {
    /// Limit by archived status
    archived: Option<bool>,
    /// Limit by visibility.
    visibility: Option<::ListingVisibility>,
    /// Return requests ordered by. Default is `ListingOrderBy::CreatedAt`.
    order_by: Option<ListingOrderBy>,
    /// Return requests sorted. Default is `::ListingSort::Desc`.
    sort: Option<::ListingSort>,
    /// Return list of authorized projects matching the search criteria.
    search: String,
    /// Return only the ID, URL, name, and path of each project
    simple: Option<bool>,
}

#[allow(dead_code)]
impl Listing {
    pub fn new() -> Listing {
        Default::default()
    }
    pub fn archived(&mut self, archived: bool) -> &mut Listing {
        self.archived = Some(archived);
        self
    }
    pub fn visibility(&mut self, visibility: ::ListingVisibility) -> &mut Listing {
        self.visibility = Some(visibility);
        self
    }
    pub fn order_by(&mut self, order_by: ListingOrderBy) -> &mut Listing {
        self.order_by = Some(order_by);
        self
    }
    fn sort(&mut self, sort: ::ListingSort) -> &mut Listing {
        self.sort = Some(sort);
        self
    }
    pub fn search(&mut self, search: String) -> &mut Listing {
        self.search = search;
        self
    }
    pub fn simple(&mut self, simple: bool) -> &mut Listing {
        self.simple = Some(simple);
        self
    }
}

impl BuildQuery for Listing {
    fn build_query(&self) -> String {

        let mut query = String::from("projects");

        let amp_char = "&";
        let none_char = "";
        let mut split_char = &none_char;

        // Append a "?" only if at least one of the `Option` is `Some(_)` or if
        // strings contain something.
        query.push_str(match (&self.archived,
                              &self.visibility,
                              &self.order_by,
                              &self.sort,
                              self.search.is_empty(),
                              &self.simple) {
            (&None, &None, &None, &None, true, &None) => "",
            _ => "?",
        });

        self.archived.map(|archived| {
            query.push_str(split_char);
            split_char = &amp_char;

            if archived {
                query.push_str("archived=true")
            } else {
                query.push_str("archived=false")
            }
        });

        self.visibility.map(|visibility| {
            query.push_str(split_char);
            split_char = &amp_char;

            query.push_str("visibility=");
            query.push_str(match visibility {
                ::ListingVisibility::Public => "public",
                ::ListingVisibility::Internal => "internal",
                ::ListingVisibility::Private => "private",
            });
        });

        self.order_by.map(|order_by| {
            query.push_str(split_char);
            split_char = &amp_char;

            query.push_str("order_by=");
            query.push_str(match order_by {
                ListingOrderBy::Id => "id",
                ListingOrderBy::Name => "name",
                ListingOrderBy::Path => "path",
                ListingOrderBy::CreatedAt => "created_at",
                ListingOrderBy::UpdatedAt => "updated_at",
                ListingOrderBy::LastActivityAt => "last_activity_at",
            });
        });

        self.sort.map(|sort| {
            query.push_str(split_char);
            split_char = &amp_char;

            query.push_str("sort=");
            query.push_str(match sort {
                ::ListingSort::Asc => "asc",
                ::ListingSort::Desc => "desc",
            });
        });

        if !self.search.is_empty() {
            query.push_str(split_char);
            split_char = &amp_char;

            query.push_str("search=");
            query.push_str(&self.search);
        }

        self.simple.map(|simple| {
            query.push_str(split_char);
            split_char = &amp_char;

            if simple {
                query.push_str("simple=true")
            } else {
                query.push_str("simple=false")
            }
        });

        query
    }
}

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

    #[test]
    fn build_query_default() {
        let expected_string = "projects";
        let listing: Listing = Default::default();
        let query = listing.build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects";
        let listing = Listing::new();
        let query = listing.build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_archived() {
        let expected_string = "projects?archived=true";
        let query = Listing::new().archived(true).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?archived=false";
        let query = Listing::new().archived(false).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_visibility() {
        let expected_string = "projects?visibility=public";
        let query = Listing::new().visibility(::ListingVisibility::Public).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?visibility=internal";
        let query = Listing::new().visibility(::ListingVisibility::Internal).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?visibility=private";
        let query = Listing::new().visibility(::ListingVisibility::Private).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_order_by() {
        let expected_string = "projects?order_by=id";
        let query = Listing::new().order_by(ListingOrderBy::Id).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?order_by=name";
        let query = Listing::new().order_by(ListingOrderBy::Name).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?order_by=path";
        let query = Listing::new().order_by(ListingOrderBy::Path).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?order_by=created_at";
        let query = Listing::new().order_by(ListingOrderBy::CreatedAt).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?order_by=updated_at";
        let query = Listing::new().order_by(ListingOrderBy::UpdatedAt).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?order_by=last_activity_at";
        let query = Listing::new().order_by(ListingOrderBy::LastActivityAt).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_sort() {
        let expected_string = "projects?sort=asc";
        let query = Listing::new().sort(::ListingSort::Asc).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?sort=desc";
        let query = Listing::new().sort(::ListingSort::Desc).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_search() {
        let expected_string = "projects?search=SearchPattern";
        let query = Listing::new().search(String::from("SearchPattern")).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_simple() {
        let expected_string = "projects?simple=true";
        let query = Listing::new().simple(true).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?simple=false";
        let query = Listing::new().simple(false).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn groups_build_query_multiple() {
        let expected_string = "projects?archived=true&simple=true";
        let query = Listing::new().archived(true).simple(true).build_query();
        assert_eq!(query, expected_string);
    }
}
<commit_msg>Let `ProjectsLister` derive `Clone`<commit_after>//! List projects
//!
//! https://docs.gitlab.com/ce/api/projects.html
//!
//! # List projects
//!
//! Get a list of projects for which the authenticated user is a member.
//!
//! ```text
//! GET /projects
//! ```
//!
//! Parameters:
//!
//! | Attribute | Type | Required | Description |
//! | --------- | ---- | -------- | ----------- |
//! | `archived` | boolean | no | Limit by archived status |
//! | `visibility` | string | no | Limit by visibility `public`, `internal`, or `private` |
//! | `order_by` | string | no | Return projects ordered by `id`, `name`, `path`, `created_at`, `updated_at`, or `last_activity_at` fields. Default is `created_at` |
//! | `sort` | string | no | Return projects sorted in `asc` or `desc` order. Default is `desc` |
//! | `search` | string | no | Return list of authorized projects matching the search criteria |
//! | `simple` | boolean | no | Return only the ID, URL, name, and path of each project |
//!

use BuildQuery;

use serde_json;

use gitlab::GitLab;
use Project;
use Projects;

pub mod all;
pub mod id_branches;
pub mod id_branch;
pub mod id_events;
pub mod id_hooks_id;
pub mod id_hooks;
pub mod id;
pub mod owned;
pub mod search;
pub mod starred;
pub mod visible;

// TODO:
//
// Creates a new project owned by the authenticated user.
// POST /projects
//
// Creates a new project owned by the specified user. Available only for admins.
// POST /projects/user/:user_id
//
// Updates an existing project
// PUT /projects/:id
//
// Forks a project into the user namespace of the authenticated user or the one provided.
// POST /projects/fork/:id
//
// Stars a given project. Returns status code `201` and the project on success and `304` if the
// project is already starred.
// POST /projects/:id/star
//
// Unstars a given project. Returns status code `200` and the project on success and `304` if the
// project is not starred.
// DELETE /projects/:id/star
//
// Archives the project if the user is either admin or the project owner of this project. This
// action is idempotent, thus archiving an already archived project will not change the project.
//
// Status code `201` with the project as body is given when successful, in case the user doesn't
// have the proper access rights, code `403` is returned. Status `404` is returned if the project
// doesn't exist, or is hidden to the user.
// POST /projects/:id/archive
//
//
// Unarchives the project if the user is either admin or the project owner of this project. This
// action is idempotent, thus unarchiving an non-archived project will not change the project.
//
// Status code `201` with the project as body is given when successful, in case the user doesn't
// have the proper access rights, code `403` is returned. Status `404` is returned if the project
// doesn't exist, or is hidden to the user.
// POST /projects/:id/unarchive
//
//
// Removes a project including all associated resources (issues, merge requests etc.)
// DELETE /projects/:id
//
//
// Uploads a file to the specified project to be used in an issue or merge request description, or
// a comment.
// POST /projects/:id/uploads
//
//
// Allow to share project with group.
// POST /projects/:id/share
//
//
// Adds a hook to a specified project.
// POST /projects/:id/hooks
//
//
// Edits a hook for a specified project.
// PUT /projects/:id/hooks/:hook_id
//
//
// Removes a hook from a project. This is an idempotent method and can be called multiple times.
// Either the hook is available or not.
// DELETE /projects/:id/hooks/:hook_id
//
//
// Protects a single branch of a project.
// PUT /projects/:id/repository/branches/:branch/protect
//
//
// Unprotects a single branch of a project.
// PUT /projects/:id/repository/branches/:branch/unprotect
//
//
// Create a forked from/to relation between existing projects.
// POST /projects/:id/fork/:forked_from_id
//
//
// Delete an existing forked from relationship
// DELETE /projects/:id/fork
//

impl GitLab {
    pub fn projects_list(&self, listing: Listing) -> Result<Projects, serde_json::Error> {
        let query = listing.build_query();
        self.get(&query)
    }
}

// https://docs.gitlab.com/ce/api/projects.html#list-projects

#[derive(Debug, Copy, Clone)]
pub enum ListingOrderBy {
    Id,
    Name,
    Path,
    CreatedAt,
    UpdatedAt,
    LastActivityAt,
}

custom_derive!{
    #[derive(Default, Debug, Clone, Builder)]
    pub struct ProjectsLister {
        /// Limit by archived status
        archived: Option<bool>,
        /// Limit by visibility.
        visibility: Option<::ListingVisibility>,
        /// Return requests ordered by. Default is `ListingOrderBy::CreatedAt`.
        order_by: Option<ListingOrderBy>,
        /// Return requests sorted. Default is `::ListingSort::Desc`.
        sort: Option<::ListingSort>,
        /// Return list of authorized projects matching the search criteria.
        search: String,
        /// Return only the ID, URL, name, and path of each project
        simple: Option<bool>,
    }
}

impl ProjectsLister {
    /// Commit the lister: Query GitLab and return a list of projects.
    pub fn list(&mut self) -> Projects {
        Default::default()
    }
}

#[derive(Default, Debug, Clone)]
pub struct Listing {
    /// Limit by archived status
    archived: Option<bool>,
    /// Limit by visibility.
    visibility: Option<::ListingVisibility>,
    /// Return requests ordered by. Default is `ListingOrderBy::CreatedAt`.
    order_by: Option<ListingOrderBy>,
    /// Return requests sorted. Default is `::ListingSort::Desc`.
    sort: Option<::ListingSort>,
    /// Return list of authorized projects matching the search criteria.
    search: String,
    /// Return only the ID, URL, name, and path of each project
    simple: Option<bool>,
}

#[allow(dead_code)]
impl Listing {
    pub fn new() -> Listing {
        Default::default()
    }
    pub fn archived(&mut self, archived: bool) -> &mut Listing {
        self.archived = Some(archived);
        self
    }
    pub fn visibility(&mut self, visibility: ::ListingVisibility) -> &mut Listing {
        self.visibility = Some(visibility);
        self
    }
    pub fn order_by(&mut self, order_by: ListingOrderBy) -> &mut Listing {
        self.order_by = Some(order_by);
        self
    }
    fn sort(&mut self, sort: ::ListingSort) -> &mut Listing {
        self.sort = Some(sort);
        self
    }
    pub fn search(&mut self, search: String) -> &mut Listing {
        self.search = search;
        self
    }
    pub fn simple(&mut self, simple: bool) -> &mut Listing {
        self.simple = Some(simple);
        self
    }
}

impl BuildQuery for Listing {
    fn build_query(&self) -> String {

        let mut query = String::from("projects");

        let amp_char = "&";
        let none_char = "";
        let mut split_char = &none_char;

        // Append a "?" only if at least one of the `Option` is `Some(_)` or if
        // strings contain something.
        query.push_str(match (&self.archived,
                              &self.visibility,
                              &self.order_by,
                              &self.sort,
                              self.search.is_empty(),
                              &self.simple) {
            (&None, &None, &None, &None, true, &None) => "",
            _ => "?",
        });

        self.archived.map(|archived| {
            query.push_str(split_char);
            split_char = &amp_char;

            if archived {
                query.push_str("archived=true")
            } else {
                query.push_str("archived=false")
            }
        });

        self.visibility.map(|visibility| {
            query.push_str(split_char);
            split_char = &amp_char;

            query.push_str("visibility=");
            query.push_str(match visibility {
                ::ListingVisibility::Public => "public",
                ::ListingVisibility::Internal => "internal",
                ::ListingVisibility::Private => "private",
            });
        });

        self.order_by.map(|order_by| {
            query.push_str(split_char);
            split_char = &amp_char;

            query.push_str("order_by=");
            query.push_str(match order_by {
                ListingOrderBy::Id => "id",
                ListingOrderBy::Name => "name",
                ListingOrderBy::Path => "path",
                ListingOrderBy::CreatedAt => "created_at",
                ListingOrderBy::UpdatedAt => "updated_at",
                ListingOrderBy::LastActivityAt => "last_activity_at",
            });
        });

        self.sort.map(|sort| {
            query.push_str(split_char);
            split_char = &amp_char;

            query.push_str("sort=");
            query.push_str(match sort {
                ::ListingSort::Asc => "asc",
                ::ListingSort::Desc => "desc",
            });
        });

        if !self.search.is_empty() {
            query.push_str(split_char);
            split_char = &amp_char;

            query.push_str("search=");
            query.push_str(&self.search);
        }

        self.simple.map(|simple| {
            query.push_str(split_char);
            split_char = &amp_char;

            if simple {
                query.push_str("simple=true")
            } else {
                query.push_str("simple=false")
            }
        });

        query
    }
}

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

    #[test]
    fn build_query_default() {
        let expected_string = "projects";
        let listing: Listing = Default::default();
        let query = listing.build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects";
        let listing = Listing::new();
        let query = listing.build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_archived() {
        let expected_string = "projects?archived=true";
        let query = Listing::new().archived(true).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?archived=false";
        let query = Listing::new().archived(false).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_visibility() {
        let expected_string = "projects?visibility=public";
        let query = Listing::new().visibility(::ListingVisibility::Public).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?visibility=internal";
        let query = Listing::new().visibility(::ListingVisibility::Internal).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?visibility=private";
        let query = Listing::new().visibility(::ListingVisibility::Private).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_order_by() {
        let expected_string = "projects?order_by=id";
        let query = Listing::new().order_by(ListingOrderBy::Id).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?order_by=name";
        let query = Listing::new().order_by(ListingOrderBy::Name).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?order_by=path";
        let query = Listing::new().order_by(ListingOrderBy::Path).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?order_by=created_at";
        let query = Listing::new().order_by(ListingOrderBy::CreatedAt).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?order_by=updated_at";
        let query = Listing::new().order_by(ListingOrderBy::UpdatedAt).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?order_by=last_activity_at";
        let query = Listing::new().order_by(ListingOrderBy::LastActivityAt).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_sort() {
        let expected_string = "projects?sort=asc";
        let query = Listing::new().sort(::ListingSort::Asc).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?sort=desc";
        let query = Listing::new().sort(::ListingSort::Desc).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_search() {
        let expected_string = "projects?search=SearchPattern";
        let query = Listing::new().search(String::from("SearchPattern")).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn build_query_simple() {
        let expected_string = "projects?simple=true";
        let query = Listing::new().simple(true).build_query();
        assert_eq!(query, expected_string);

        let expected_string = "projects?simple=false";
        let query = Listing::new().simple(false).build_query();
        assert_eq!(query, expected_string);
    }

    #[test]
    fn groups_build_query_multiple() {
        let expected_string = "projects?archived=true&simple=true";
        let query = Listing::new().archived(true).simple(true).build_query();
        assert_eq!(query, expected_string);
    }
}
<|endoftext|>


<commit_before>//!
//! This module defines the external interface for controlling one particular
//! instance of a mock server.
//!

use hyper_server;
use matching::MatchResult;

use pact_matching::models::{Pact, Interaction, PactSpecification};
use std::ffi::CString;
use std::path::PathBuf;
use std::io;
use std::sync::Mutex;
use serde_json::json;
use futures::future::Future;

lazy_static! {
    static ref PACT_FILE_MUTEX: Mutex<()> = Mutex::new(());
}

/// Struct to represent the "foreground" part of mock server
#[derive(Debug)]
pub struct MockServer {
    /// Mock server unique ID
    pub id: String,
    /// Address the mock server is running on
    pub addr: std::net::SocketAddr,
    /// List of all match results for requests this mock server has received
    pub matches: Vec<MatchResult>,
    /// List of resources that need to be cleaned up when the mock server completes
    pub resources: Vec<CString>,
    /// Pact that this mock server is based on
    pub pact: Pact,
    /// Receiver of match results
    matches_rx: std::sync::mpsc::Receiver<MatchResult>,
    /// Shutdown signal
    shutdown_tx: Option<futures::sync::oneshot::Sender<()>>
}

impl MockServer {
    /// Creates a new mock server with the given ID, pact and socket address,
    /// and spawns it on a tokio runtime
    pub fn spawn(id: String, pact: Pact, port: u16,
        runtime: &mut tokio::runtime::Runtime
    ) -> Result<MockServer, String> {
        let (mock_server, future) = MockServer::create_and_bind(id, pact, port)?;
        runtime.spawn(future);
        Ok(mock_server)
    }

    /// Creates a new mock server with the given ID, pact and socket address,
    /// and spawns it onto a tokio current_thread runtime (convenient for testing)
    pub fn spawn_current_thread(id: String, pact: Pact, port: u16,
        runtime: &mut tokio::runtime::current_thread::Runtime
    ) -> Result<MockServer, String> {
        let (mock_server, future) = MockServer::create_and_bind(id, pact, port)?;
        runtime.spawn(future);
        Ok(mock_server)
    }

    fn create_and_bind(id: String, pact: Pact, port: u16) -> Result<(MockServer, impl Future<Item = (), Error = ()>), String> {
        let (shutdown_tx, shutdown_rx) = futures::sync::oneshot::channel();
        let (matches_tx, matches_rx) = std::sync::mpsc::channel();

        let (future, socket_addr) = hyper_server::create_and_bind(
            pact.clone(),
            port as u16,
            shutdown_rx.map_err(|_| ()),
            matches_tx
        ).map_err(|err| format!("Could not start server: {}", err))?;

        let mock_server = MockServer {
            id: id.clone(),
            addr: socket_addr,
            matches: vec![],
            resources: vec![],
            pact: pact,
            matches_rx: matches_rx,
            shutdown_tx: Some(shutdown_tx)
        };

        Ok((mock_server, future))
    }

    /// Send the shutdown signal to the server
    pub fn shutdown(&mut self) -> Result<(), String> {
        match self.shutdown_tx.take() {
            Some(sender) => {
                match sender.send(()) {
                    Ok(()) => Ok(()),
                    Err(_) => Err("Problem sending shutdown signal to mock server".into())
                }
            },
            _ => Err("Mock server already shut down".into())
        }
    }

    /// Read pending matches from the running server. Will not block.
    pub fn read_match_results_from_server(&mut self) {
        loop {
            match self.matches_rx.try_recv() {
                Ok(match_result) => self.matches.push(match_result),
                Err(_) => break
            }
        }
    }

    /// Converts this mock server to a `Value` struct
    pub fn to_json(&self) -> serde_json::Value {
        json!({
            "id" : json!(self.id.clone()),
            "port" : json!(self.addr.port() as u64),
            "provider" : json!(self.pact.provider.name.clone()),
            "status" : json!(if self.mismatches().is_empty() { "ok" } else { "error" })
        })
    }

    /// Returns all the mismatches that have occurred with this mock server
    pub fn mismatches(&self) -> Vec<MatchResult> {
        //self.matches.extend(self.matches_rx.iter());

        let mismatches = self.matches.iter()
            .filter(|m| !m.matched())
            .map(|m| m.clone());
        let interactions: Vec<&Interaction> = self.matches.iter().map(|m| {
            match *m {
                MatchResult::RequestMatch(ref interaction) => Some(interaction),
                MatchResult::RequestMismatch(ref interaction, _) => Some(interaction),
                MatchResult::RequestNotFound(_) => None,
                MatchResult::MissingRequest(_) => None
            }
        }).filter(|o| o.is_some()).map(|o| o.unwrap()).collect();
        let missing = self.pact.interactions.iter()
            .filter(|i| !interactions.contains(i))
            .map(|i| MatchResult::MissingRequest(i.clone()));
        mismatches.chain(missing).collect()
    }

    /// Mock server writes its pact out to the provided directory
    pub fn write_pact(&self, output_path: &Option<String>) -> io::Result<()> {
        let pact_file_name = self.pact.default_file_name();
        let filename = match *output_path {
            Some(ref path) => {
                let mut path = PathBuf::from(path);
                path.push(pact_file_name);
                path
            },
            None => PathBuf::from(pact_file_name)
        };

        info!("Writing pact out to '{}'", filename.display());

        // Lock so that no two threads can read/write pact file at the same time.
        let _write_lock = PACT_FILE_MUTEX.lock().unwrap();

        match self.pact.write_pact(filename.as_path(), PactSpecification::V3) {
            Ok(_) => Ok(()),
            Err(err) => {
                warn!("Failed to write pact to file - {}", err);
                Err(err)
            }
        }
    }

    /// Returns the URL of the mock server
    pub fn url(&self) -> String {
        format!("http://localhost:{}", self.addr.port())
    }
}

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

    #[test]
    fn mock_server_read_matches_should_read_matches_when_sender_is_closed() {
        let match_result = MatchResult::RequestMatch(Interaction::default());

        let mut mock_server = {
            let (shutdown_tx, _) = futures::sync::oneshot::channel();
            let (matches_tx, matches_rx) = std::sync::mpsc::channel();

            matches_tx.send(match_result.clone()).unwrap();

            MockServer {
                id: "foobar".into(),
                addr: ([0, 0, 0, 0], 0).into(),
                matches: vec![],
                resources: vec![],
                pact: Pact::default(),
                matches_rx: matches_rx,
                shutdown_tx: Some(shutdown_tx)
            }
        };

        mock_server.read_match_results_from_server();
        assert_eq!(mock_server.matches, vec![match_result]);
    }
}
<commit_msg>Comment the use of PACT_FILE_MUTEX<commit_after>//!
//! This module defines the external interface for controlling one particular
//! instance of a mock server.
//!

use hyper_server;
use matching::MatchResult;

use pact_matching::models::{Pact, Interaction, PactSpecification};
use std::ffi::CString;
use std::path::PathBuf;
use std::io;
use std::sync::Mutex;
use serde_json::json;
use futures::future::Future;

lazy_static! {
    static ref PACT_FILE_MUTEX: Mutex<()> = Mutex::new(());
}

/// Struct to represent the "foreground" part of mock server
#[derive(Debug)]
pub struct MockServer {
    /// Mock server unique ID
    pub id: String,
    /// Address the mock server is running on
    pub addr: std::net::SocketAddr,
    /// List of all match results for requests this mock server has received
    pub matches: Vec<MatchResult>,
    /// List of resources that need to be cleaned up when the mock server completes
    pub resources: Vec<CString>,
    /// Pact that this mock server is based on
    pub pact: Pact,
    /// Receiver of match results
    matches_rx: std::sync::mpsc::Receiver<MatchResult>,
    /// Shutdown signal
    shutdown_tx: Option<futures::sync::oneshot::Sender<()>>
}

impl MockServer {
    /// Creates a new mock server with the given ID, pact and socket address,
    /// and spawns it on a tokio runtime
    pub fn spawn(id: String, pact: Pact, port: u16,
        runtime: &mut tokio::runtime::Runtime
    ) -> Result<MockServer, String> {
        let (mock_server, future) = MockServer::create_and_bind(id, pact, port)?;
        runtime.spawn(future);
        Ok(mock_server)
    }

    /// Creates a new mock server with the given ID, pact and socket address,
    /// and spawns it onto a tokio current_thread runtime (convenient for testing)
    pub fn spawn_current_thread(id: String, pact: Pact, port: u16,
        runtime: &mut tokio::runtime::current_thread::Runtime
    ) -> Result<MockServer, String> {
        let (mock_server, future) = MockServer::create_and_bind(id, pact, port)?;
        runtime.spawn(future);
        Ok(mock_server)
    }

    fn create_and_bind(id: String, pact: Pact, port: u16) -> Result<(MockServer, impl Future<Item = (), Error = ()>), String> {
        let (shutdown_tx, shutdown_rx) = futures::sync::oneshot::channel();
        let (matches_tx, matches_rx) = std::sync::mpsc::channel();

        let (future, socket_addr) = hyper_server::create_and_bind(
            pact.clone(),
            port as u16,
            shutdown_rx.map_err(|_| ()),
            matches_tx
        ).map_err(|err| format!("Could not start server: {}", err))?;

        let mock_server = MockServer {
            id: id.clone(),
            addr: socket_addr,
            matches: vec![],
            resources: vec![],
            pact: pact,
            matches_rx: matches_rx,
            shutdown_tx: Some(shutdown_tx)
        };

        Ok((mock_server, future))
    }

    /// Send the shutdown signal to the server
    pub fn shutdown(&mut self) -> Result<(), String> {
        match self.shutdown_tx.take() {
            Some(sender) => {
                match sender.send(()) {
                    Ok(()) => Ok(()),
                    Err(_) => Err("Problem sending shutdown signal to mock server".into())
                }
            },
            _ => Err("Mock server already shut down".into())
        }
    }

    /// Read pending matches from the running server. Will not block.
    pub fn read_match_results_from_server(&mut self) {
        loop {
            match self.matches_rx.try_recv() {
                Ok(match_result) => self.matches.push(match_result),
                Err(_) => break
            }
        }
    }

    /// Converts this mock server to a `Value` struct
    pub fn to_json(&self) -> serde_json::Value {
        json!({
            "id" : json!(self.id.clone()),
            "port" : json!(self.addr.port() as u64),
            "provider" : json!(self.pact.provider.name.clone()),
            "status" : json!(if self.mismatches().is_empty() { "ok" } else { "error" })
        })
    }

    /// Returns all the mismatches that have occurred with this mock server
    pub fn mismatches(&self) -> Vec<MatchResult> {
        let mismatches = self.matches.iter()
            .filter(|m| !m.matched())
            .map(|m| m.clone());
        let interactions: Vec<&Interaction> = self.matches.iter().map(|m| {
            match *m {
                MatchResult::RequestMatch(ref interaction) => Some(interaction),
                MatchResult::RequestMismatch(ref interaction, _) => Some(interaction),
                MatchResult::RequestNotFound(_) => None,
                MatchResult::MissingRequest(_) => None
            }
        }).filter(|o| o.is_some()).map(|o| o.unwrap()).collect();
        let missing = self.pact.interactions.iter()
            .filter(|i| !interactions.contains(i))
            .map(|i| MatchResult::MissingRequest(i.clone()));
        mismatches.chain(missing).collect()
    }

    /// Mock server writes its pact out to the provided directory
    pub fn write_pact(&self, output_path: &Option<String>) -> io::Result<()> {
        let pact_file_name = self.pact.default_file_name();
        let filename = match *output_path {
            Some(ref path) => {
                let mut path = PathBuf::from(path);
                path.push(pact_file_name);
                path
            },
            None => PathBuf::from(pact_file_name)
        };

        info!("Writing pact out to '{}'", filename.display());

        // Lock so that no two threads can read/write pact file at the same time.
        // TODO: Could use a fs-based lock in case multiple processes are doing
        // this concurrently?
        let _file_lock = PACT_FILE_MUTEX.lock().unwrap();

        match self.pact.write_pact(filename.as_path(), PactSpecification::V3) {
            Ok(_) => Ok(()),
            Err(err) => {
                warn!("Failed to write pact to file - {}", err);
                Err(err)
            }
        }
    }

    /// Returns the URL of the mock server
    pub fn url(&self) -> String {
        format!("http://localhost:{}", self.addr.port())
    }
}

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

    #[test]
    fn mock_server_read_matches_should_read_matches_when_sender_is_closed() {
        let match_result = MatchResult::RequestMatch(Interaction::default());

        let mut mock_server = {
            let (shutdown_tx, _) = futures::sync::oneshot::channel();
            let (matches_tx, matches_rx) = std::sync::mpsc::channel();

            matches_tx.send(match_result.clone()).unwrap();

            MockServer {
                id: "foobar".into(),
                addr: ([0, 0, 0, 0], 0).into(),
                matches: vec![],
                resources: vec![],
                pact: Pact::default(),
                matches_rx: matches_rx,
                shutdown_tx: Some(shutdown_tx)
            }
        };

        mock_server.read_match_results_from_server();
        assert_eq!(mock_server.matches, vec![match_result]);
    }
}
<|endoftext|>


<commit_before>use askama::Template;

#[derive(Template)]
#[template(path = "for.html")]
struct ForTemplate<'a> {
    strings: Vec<&'a str>,
    tuple_strings: Vec<(&'a str, &'a str)>,
}

#[test]
fn test_for() {
    let s = ForTemplate {
        strings: vec!["A", "alfa", "1"],
        tuple_strings: vec![("B", "beta")],
    };
    assert_eq!(
        s.render().unwrap(),
        "0. A (first)\n1. alfa\n2. 1\n\n0. B,beta (first)\n"
    );
}

#[derive(Template)]
#[template(path = "nested-for.html")]
struct NestedForTemplate<'a> {
    seqs: Vec<&'a [&'a str]>,
}

#[test]
fn test_nested_for() {
    let alpha = vec!["a", "b", "c"];
    let numbers = vec!["one", "two"];
    let s = NestedForTemplate {
        seqs: vec![&alpha, &numbers],
    };
    assert_eq!(s.render().unwrap(), "1\n  0a1b2c2\n  0one1two");
}

#[derive(Template)]
#[template(path = "precedence-for.html")]
struct PrecedenceTemplate<'a> {
    strings: Vec<&'a str>,
}

#[test]
fn test_precedence_for() {
    let s = PrecedenceTemplate {
        strings: vec!["A", "alfa", "1"],
    };
    assert_eq!(
        s.render().unwrap(),
        "0. A2 (first)\n1. alfa4\n2. 16 (last)\n"
    );
}

#[derive(Template)]
#[template(path = "for-range.html")]
struct ForRangeTemplate {
    init: i32,
    end: i32,
}

#[test]
fn test_for_range() {
    let s = ForRangeTemplate { init: -1, end: 1 };
    assert_eq!(
        s.render().unwrap(),
        "foo (first)\nfoo (last)\nbar\nbar\nfoo\nbar\nbar\n"
    );
}

#[derive(Template)]
#[template(source = "{% for i in [1, 2, 3] %}{{ i }}{% endfor %}", ext = "txt")]
struct ForArrayTemplate;

#[test]
fn test_for_array() {
    let t = ForArrayTemplate;
    assert_eq!(t.render().unwrap(), "123");
}

#[derive(Template)]
#[template(
    source = "{% for i in [1, 2, 3].iter() %}{{ i }}{% endfor %}",
    ext = "txt"
)]
struct ForMethodCallTemplate;

#[test]
fn test_for_method_call() {
    let t = ForMethodCallTemplate;
    assert_eq!(t.render().unwrap(), "123");
}

#[derive(Template)]
#[template(
    source = "{% for i in ::std::iter::repeat(\"a\").take(5) %}{{ i }}{% endfor %}",
    ext = "txt"
)]
struct ForPathCallTemplate;

#[test]
fn test_for_path_call() {
    assert_eq!(ForPathCallTemplate.render().unwrap(), "aaaaa");
}

#[derive(Template)]
#[template(
    source = "{% for i in [1, 2, 3, 4, 5][3..] %}{{ i }}{% endfor %}",
    ext = "txt"
)]
struct ForIndexTemplate;

#[test]
fn test_for_index() {
    let t = ForIndexTemplate;
    assert_eq!(t.render().unwrap(), "45");
}

#[derive(Template)]
#[template(
    source = "{% for (i, j) in (0..10).zip(10..20).zip(30..40) %}{{ i.0 }} {{ i.1 }} {{ j }} {% endfor %}",
    ext = "txt"
)]
struct ForZipRangesTemplate;

#[test]
fn test_for_zip_ranges() {
    let t = ForZipRangesTemplate;
    assert_eq!(
        t.render().unwrap(),
        "0 10 30 1 11 31 2 12 32 3 13 33 4 14 34 5 15 35 6 16 36 7 17 37 8 18 38 9 19 39 "
    );
}
<commit_msg>Added loop tests<commit_after>use std::ops::Range;

use askama::Template;

#[derive(Template)]
#[template(path = "for.html")]
struct ForTemplate<'a> {
    strings: Vec<&'a str>,
    tuple_strings: Vec<(&'a str, &'a str)>,
}

#[test]
fn test_for() {
    let s = ForTemplate {
        strings: vec!["A", "alfa", "1"],
        tuple_strings: vec![("B", "beta")],
    };
    assert_eq!(
        s.render().unwrap(),
        "0. A (first)\n1. alfa\n2. 1\n\n0. B,beta (first)\n"
    );
}

#[derive(Template)]
#[template(path = "nested-for.html")]
struct NestedForTemplate<'a> {
    seqs: Vec<&'a [&'a str]>,
}

#[test]
fn test_nested_for() {
    let alpha = vec!["a", "b", "c"];
    let numbers = vec!["one", "two"];
    let s = NestedForTemplate {
        seqs: vec![&alpha, &numbers],
    };
    assert_eq!(s.render().unwrap(), "1\n  0a1b2c2\n  0one1two");
}

#[derive(Template)]
#[template(path = "precedence-for.html")]
struct PrecedenceTemplate<'a> {
    strings: Vec<&'a str>,
}

#[test]
fn test_precedence_for() {
    let s = PrecedenceTemplate {
        strings: vec!["A", "alfa", "1"],
    };
    assert_eq!(
        s.render().unwrap(),
        "0. A2 (first)\n1. alfa4\n2. 16 (last)\n"
    );
}

#[derive(Template)]
#[template(path = "for-range.html")]
struct ForRangeTemplate {
    init: i32,
    end: i32,
}

#[test]
fn test_for_range() {
    let s = ForRangeTemplate { init: -1, end: 1 };
    assert_eq!(
        s.render().unwrap(),
        "foo (first)\nfoo (last)\nbar\nbar\nfoo\nbar\nbar\n"
    );
}

#[derive(Template)]
#[template(source = "{% for i in [1, 2, 3] %}{{ i }}{% endfor %}", ext = "txt")]
struct ForArrayTemplate;

#[test]
fn test_for_array() {
    let t = ForArrayTemplate;
    assert_eq!(t.render().unwrap(), "123");
}

#[derive(Template)]
#[template(
    source = "{% for i in [1, 2, 3].iter() %}{{ i }}{% endfor %}",
    ext = "txt"
)]
struct ForMethodCallTemplate;

#[test]
fn test_for_method_call() {
    let t = ForMethodCallTemplate;
    assert_eq!(t.render().unwrap(), "123");
}

#[derive(Template)]
#[template(
    source = "{% for i in ::std::iter::repeat(\"a\").take(5) %}{{ i }}{% endfor %}",
    ext = "txt"
)]
struct ForPathCallTemplate;

#[test]
fn test_for_path_call() {
    assert_eq!(ForPathCallTemplate.render().unwrap(), "aaaaa");
}

#[derive(Template)]
#[template(
    source = "{% for i in [1, 2, 3, 4, 5][3..] %}{{ i }}{% endfor %}",
    ext = "txt"
)]
struct ForIndexTemplate;

#[test]
fn test_for_index() {
    let t = ForIndexTemplate;
    assert_eq!(t.render().unwrap(), "45");
}

#[derive(Template)]
#[template(
    source = "{% for (i, j) in (0..10).zip(10..20).zip(30..40) %}{{ i.0 }} {{ i.1 }} {{ j }} {% endfor %}",
    ext = "txt"
)]
struct ForZipRangesTemplate;

#[test]
fn test_for_zip_ranges() {
    let t = ForZipRangesTemplate;
    assert_eq!(
        t.render().unwrap(),
        "0 10 30 1 11 31 2 12 32 3 13 33 4 14 34 5 15 35 6 16 36 7 17 37 8 18 38 9 19 39 "
    );
}

struct ForVecAttrVec {
    iterable: Vec<i32>,
}

#[derive(Template)]
#[template(
    source = "{% for x in v %}{% for y in x.iterable %}{{ y }} {% endfor %}{% endfor %}",
    ext = "txt"
)]
struct ForVecAttrVecTemplate {
    v: Vec<ForVecAttrVec>,
}

#[test]
fn test_for_vec_attr_vec() {
    let t = ForVecAttrVecTemplate {
        v: vec![
            ForVecAttrVec {
                iterable: vec![1, 2],
            },
            ForVecAttrVec {
                iterable: vec![3, 4],
            },
            ForVecAttrVec {
                iterable: vec![5, 6],
            },
        ],
    };
    assert_eq!(t.render().unwrap(), "1 2 3 4 5 6 ");
}

struct ForVecAttrSlice {
    iterable: &'static [i32],
}

#[derive(Template)]
#[template(
    source = "{% for x in v %}{% for y in x.iterable %}{{ y }} {% endfor %}{% endfor %}",
    ext = "txt"
)]
struct ForVecAttrSliceTemplate {
    v: Vec<ForVecAttrSlice>,
}

#[test]
fn test_for_vec_attr_slice() {
    let t = ForVecAttrSliceTemplate {
        v: vec![
            ForVecAttrSlice { iterable: &[1, 2] },
            ForVecAttrSlice { iterable: &[3, 4] },
            ForVecAttrSlice { iterable: &[5, 6] },
        ],
    };
    assert_eq!(t.render().unwrap(), "1 2 3 4 5 6 ");
}

struct ForVecAttrRange {
    iterable: Range<usize>,
}

#[derive(Template)]
#[template(
    source = "{% for x in v %}{% for y in x.iterable.clone() %}{{ y }} {% endfor %}{% endfor %}",
    ext = "txt"
)]
struct ForVecAttrRangeTemplate {
    v: Vec<ForVecAttrRange>,
}

#[test]
fn test_for_vec_attr_range() {
    let t = ForVecAttrRangeTemplate {
        v: vec![
            ForVecAttrRange { iterable: 1..3 },
            ForVecAttrRange { iterable: 3..5 },
            ForVecAttrRange { iterable: 5..7 },
        ],
    };
    assert_eq!(t.render().unwrap(), "1 2 3 4 5 6 ");
}
<|endoftext|>


<commit_before>use super::column::Column;
use super::table::Table;
use std::io::{Write, Read, Seek};

/// The Rows struct represents the file level implementation
/// of the table
pub struct Rows<B: Write + Read + Seek> {
    buf: B,
    // TODO:add column_size, header_offset
}

// TODO: implement insert_row and select_row
impl<B: Write + Read + Seek> Rows<B> {
    pub fn new(buf: B) -> Self {
        Rows {
            buf: buf
        }
    }
}
<commit_msg>implemented insert row<commit_after>use super::column::Column;
use super::table::Table;
use super::Error;
use std::io::{Write, Read, Seek, SeekFrom};

/// The Rows struct represents the file level implementation
/// of the table
pub struct Rows<B: Write + Read + Seek> {
    buf: B,
    // TODO:add column_size, header_offset
}

// TODO: implement insert_row and select_row
impl<B: Write + Read + Seek> Rows<B> {
    pub fn new(buf: B) -> Self {
        Rows {
            buf: buf
        }
    }

    pub fn insert_row(&mut self, data: &[u8]) -> Result<usize, Error> {
        info!("inserting row");
        try!(self.buf.seek(SeekFrom::End(0)));
        self.write_bytes(data)
    }

    fn write_bytes(&mut self, data: &[u8]) -> Result<usize, Error> {
        match self.buf.write_all(data) {
            Ok(_) => Ok(data.len()),
            Err(e) => Err(Error::Io(e))
        }
    }
}
<|endoftext|>


<commit_before>//! Matrix with dimensions unknown at compile-time.

#![allow(missing_docs)] // we hide doc to not have to document the $trhs double dispatch trait.

use std::cmp;
use std::mem;
use std::iter::repeat;
use std::ops::{Add, Sub, Mul, Div, Index, IndexMut};
use std::fmt::{Debug, Formatter, Result};
use rand::{self, Rand};
use num::{Zero, One};
use structs::dvec::DVec;
use traits::operations::{ApproxEq, Inv, Transpose, Mean, Cov};
use traits::structure::{Cast, Col, ColSlice, Row, RowSlice, Diag, DiagMut, Eye, Indexable, Shape, BaseNum};
#[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen};

/// Matrix with dimensions unknown at compile-time.
#[derive(Eq, PartialEq, Clone)]
pub struct DMat<N> {
    nrows: usize,
    ncols: usize,
    mij:   Vec<N>
}

impl<N> DMat<N> {
    /// Creates an uninitialized matrix.
    #[inline]
    pub unsafe fn new_uninitialized(nrows: usize, ncols: usize) -> DMat<N> {
        let mut vec = Vec::with_capacity(nrows * ncols);
        vec.set_len(nrows * ncols);

        DMat {
            nrows: nrows,
            ncols: ncols,
            mij:   vec
        }
    }
}

impl<N: Clone + Copy> DMat<N> {
    /// Builds a matrix filled with a given constant.
    #[inline]
    pub fn from_elem(nrows: usize, ncols: usize, val: N) -> DMat<N> {
        DMat {
            nrows: nrows,
            ncols: ncols,
            mij:   repeat(val).take(nrows * ncols).collect()
        }
    }

    /// Builds a matrix filled with the components provided by a vector.
    /// The vector contains the matrix data in row-major order.
    /// Note that `from_col_vec` is much faster than `from_row_vec` since a `DMat` stores its data
    /// in column-major order.
    ///
    /// The vector must have at least `nrows * ncols` elements.
    #[inline]
    pub fn from_row_vec(nrows: usize, ncols: usize, vec: &[N]) -> DMat<N> {
        let mut res = DMat::from_col_vec(ncols, nrows, vec);

        // we transpose because the buffer is row_major
        res.transpose_mut();

        res
    }

    /// Builds a matrix filled with the components provided by a vector.
    /// The vector contains the matrix data in column-major order.
    /// Note that `from_col_vec` is much faster than `from_row_vec` since a `DMat` stores its data
    /// in column-major order.
    ///
    /// The vector must have at least `nrows * ncols` elements.
    #[inline]
    pub fn from_col_vec(nrows: usize, ncols: usize, vec: &[N]) -> DMat<N> {
        assert!(nrows * ncols == vec.len());

        DMat {
            nrows: nrows,
            ncols: ncols,
            mij:   vec.to_vec()
        }
    }
}

impl<N> DMat<N> {
    /// Builds a matrix using an initialization function.
    #[inline(always)]
    pub fn from_fn<F: FnMut(usize, usize) -> N>(nrows: usize, ncols: usize, mut f: F) -> DMat<N> {
        DMat {
            nrows: nrows,
            ncols: ncols,
            mij:   (0 .. nrows * ncols).map(|i| { let m = i / nrows; f(i - m * nrows, m) }).collect()
        }
    }

    /// Transforms this matrix into an array. This consumes the matrix and is O(1).
    /// The returned vector contains the matrix data in column-major order.
    #[inline]
    pub fn into_vec(self) -> Vec<N> {
        self.mij
    }
}

dmat_impl!(DMat);

pub struct DMat1<N> {
    nrows: usize,
    ncols: usize,
    mij:   [N; 1 * 1],
}

small_dmat_impl!(DMat1, 1, 0);
small_dmat_from_impl!(DMat1, 1, ::zero());

pub struct DMat2<N> {
    nrows: usize,
    ncols: usize,
    mij:   [N; 2 * 2],
}

small_dmat_impl!(DMat2, 2, 0, 1,
                           2, 3);
small_dmat_from_impl!(DMat2, 2, ::zero(), ::zero(),
                                ::zero(), ::zero());

pub struct DMat3<N> {
    nrows: usize,
    ncols: usize,
    mij:   [N; 3 * 3],
}

small_dmat_impl!(DMat3, 3, 0, 1, 2,
                           3, 4, 5,
                           6, 7, 8);
small_dmat_from_impl!(DMat3, 3, ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero());

pub struct DMat4<N> {
    nrows: usize,
    ncols: usize,
    mij:   [N; 4 * 4],
}

small_dmat_impl!(DMat4, 4,  0,  1,  2,  3,
                            4,  5,  6,  7,
                            8,  9,  10, 11,
                            12, 13, 14, 15);
small_dmat_from_impl!(DMat4, 4, ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero());

pub struct DMat5<N> {
    nrows: usize,
    ncols: usize,
    mij:   [N; 5 * 5],
}

small_dmat_impl!(DMat5, 5, 0,  1,  2,  3,  4,
                           5,  6,  7,  8,  9,
                           10, 11, 12, 13, 14,
                           15, 16, 17, 18, 19,
                           20, 21, 22, 23, 24);
small_dmat_from_impl!(DMat5, 5, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero(), ::zero());

pub struct DMat6<N> {
    nrows: usize,
    ncols: usize,
    mij:   [N; 6 * 6],
}

small_dmat_impl!(DMat6, 6, 0,  1,  2,  3,  4,  5,
                           6,  7,  8,  9,  10, 11,
                           12, 13, 14, 15, 16, 17,
                           18, 19, 20, 21, 22, 23,
                           24, 25, 26, 27, 28, 29,
                           30, 31, 32, 33, 34, 35);
small_dmat_from_impl!(DMat6, 6, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero());
<commit_msg>DMat: implement `from_row_iter` and `from_col_iter`.<commit_after>//! Matrix with dimensions unknown at compile-time.

#![allow(missing_docs)] // we hide doc to not have to document the $trhs double dispatch trait.

use std::cmp;
use std::mem;
use std::iter::repeat;
use std::ops::{Add, Sub, Mul, Div, Index, IndexMut};
use std::fmt::{Debug, Formatter, Result};
use rand::{self, Rand};
use num::{Zero, One};
use structs::dvec::DVec;
use traits::operations::{ApproxEq, Inv, Transpose, Mean, Cov};
use traits::structure::{Cast, Col, ColSlice, Row, RowSlice, Diag, DiagMut, Eye, Indexable, Shape, BaseNum};
#[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen};

/// Matrix with dimensions unknown at compile-time.
#[derive(Eq, PartialEq, Clone)]
pub struct DMat<N> {
    nrows: usize,
    ncols: usize,
    mij:   Vec<N>
}

impl<N> DMat<N> {
    /// Creates an uninitialized matrix.
    #[inline]
    pub unsafe fn new_uninitialized(nrows: usize, ncols: usize) -> DMat<N> {
        let mut vec = Vec::with_capacity(nrows * ncols);
        vec.set_len(nrows * ncols);

        DMat {
            nrows: nrows,
            ncols: ncols,
            mij:   vec
        }
    }
}

impl<N: Clone + Copy> DMat<N> {
    /// Builds a matrix filled with a given constant.
    #[inline]
    pub fn from_elem(nrows: usize, ncols: usize, val: N) -> DMat<N> {
        DMat {
            nrows: nrows,
            ncols: ncols,
            mij:   repeat(val).take(nrows * ncols).collect()
        }
    }

    /// Builds a matrix filled with the components provided by a vector.
    /// The vector contains the matrix data in row-major order.
    /// Note that `from_col_vec` is much faster than `from_row_vec` since a `DMat` stores its data
    /// in column-major order.
    ///
    /// The vector must have exactly `nrows * ncols` elements.
    #[inline]
    pub fn from_row_vec(nrows: usize, ncols: usize, vec: &[N]) -> DMat<N> {
        DMat::from_row_iter(nrows, ncols, vec.to_vec())
    }

    /// Builds a matrix filled with the components provided by a vector.
    /// The vector contains the matrix data in column-major order.
    /// Note that `from_col_vec` is much faster than `from_row_vec` since a `DMat` stores its data
    /// in column-major order.
    ///
    /// The vector must have exactly `nrows * ncols` elements.
    #[inline]
    pub fn from_col_vec(nrows: usize, ncols: usize, vec: &[N]) -> DMat<N> {
        DMat::from_col_iter(nrows, ncols, vec.to_vec())
    }

    /// Builds a matrix filled with the components provided by a source that may be moved into an iterator.
    /// The source contains the matrix data in row-major order.
    /// Note that `from_col_iter` is much faster than `from_row_iter` since a `DMat` stores its data
    /// in column-major order.
    ///
    /// The source must have exactly `nrows * ncols` elements.
    #[inline]
    pub fn from_row_iter<I: IntoIterator<Item = N>>(nrows: usize, ncols: usize, param: I) -> DMat<N> {
        let mut res = DMat::from_col_iter(ncols, nrows, param);

        // we transpose because the buffer is row_major
        res.transpose_mut();

        res
    }

    /// Builds a matrix filled with the components provided by a source that may be moved into an iterator.
    /// The source contains the matrix data in column-major order.
    /// Note that `from_col_iter` is much faster than `from_row_iter` since a `DMat` stores its data
    /// in column-major order.
    ///
    /// The source must have exactly `nrows * ncols` elements.
    #[inline]
    pub fn from_col_iter<I: IntoIterator<Item = N>>(nrows: usize, ncols: usize, param: I) -> DMat<N> {
        let mij: Vec<N> = param.into_iter().collect();

        assert!(nrows * ncols == mij.len(), "The ammount of data provided does not matches the matrix size.");

        DMat {
            nrows: nrows,
            ncols: ncols,
            mij:   mij
        }
    }
}

impl<N> DMat<N> {
    /// Builds a matrix using an initialization function.
    #[inline(always)]
    pub fn from_fn<F: FnMut(usize, usize) -> N>(nrows: usize, ncols: usize, mut f: F) -> DMat<N> {
        DMat {
            nrows: nrows,
            ncols: ncols,
            mij:   (0 .. nrows * ncols).map(|i| { let m = i / nrows; f(i - m * nrows, m) }).collect()
        }
    }

    /// Transforms this matrix into an array. This consumes the matrix and is O(1).
    /// The returned vector contains the matrix data in column-major order.
    #[inline]
    pub fn into_vec(self) -> Vec<N> {
        self.mij
    }
}

dmat_impl!(DMat);

pub struct DMat1<N> {
    nrows: usize,
    ncols: usize,
    mij:   [N; 1 * 1],
}

small_dmat_impl!(DMat1, 1, 0);
small_dmat_from_impl!(DMat1, 1, ::zero());

pub struct DMat2<N> {
    nrows: usize,
    ncols: usize,
    mij:   [N; 2 * 2],
}

small_dmat_impl!(DMat2, 2, 0, 1,
                           2, 3);
small_dmat_from_impl!(DMat2, 2, ::zero(), ::zero(),
                                ::zero(), ::zero());

pub struct DMat3<N> {
    nrows: usize,
    ncols: usize,
    mij:   [N; 3 * 3],
}

small_dmat_impl!(DMat3, 3, 0, 1, 2,
                           3, 4, 5,
                           6, 7, 8);
small_dmat_from_impl!(DMat3, 3, ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero());

pub struct DMat4<N> {
    nrows: usize,
    ncols: usize,
    mij:   [N; 4 * 4],
}

small_dmat_impl!(DMat4, 4,  0,  1,  2,  3,
                            4,  5,  6,  7,
                            8,  9,  10, 11,
                            12, 13, 14, 15);
small_dmat_from_impl!(DMat4, 4, ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero());

pub struct DMat5<N> {
    nrows: usize,
    ncols: usize,
    mij:   [N; 5 * 5],
}

small_dmat_impl!(DMat5, 5, 0,  1,  2,  3,  4,
                           5,  6,  7,  8,  9,
                           10, 11, 12, 13, 14,
                           15, 16, 17, 18, 19,
                           20, 21, 22, 23, 24);
small_dmat_from_impl!(DMat5, 5, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero(), ::zero());

pub struct DMat6<N> {
    nrows: usize,
    ncols: usize,
    mij:   [N; 6 * 6],
}

small_dmat_impl!(DMat6, 6, 0,  1,  2,  3,  4,  5,
                           6,  7,  8,  9,  10, 11,
                           12, 13, 14, 15, 16, 17,
                           18, 19, 20, 21, 22, 23,
                           24, 25, 26, 27, 28, 29,
                           30, 31, 32, 33, 34, 35);
small_dmat_from_impl!(DMat6, 6, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
                                ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero());
<|endoftext|>