<commit_before>#![deny(warnings)]

extern crate cobalt;
extern crate getopts;
extern crate env_logger;
extern crate notify;
extern crate ghp;

#[macro_use]
extern crate nickel;

#[macro_use]
extern crate log;

use getopts::Options;
use std::env;
use std::fs;
use cobalt::Config;
use log::{LogRecord, LogLevelFilter};
use env_logger::LogBuilder;
use nickel::{Nickel, Options as NickelOptions, StaticFilesHandler};
use ghp::import_dir;

use notify::{RecommendedWatcher, Error, Watcher};
use std::sync::mpsc::channel;
use std::thread;
use std::path::PathBuf;

fn print_version() {
    println!("0.2.0");
}

fn print_usage(opts: Options) {
    let usage = concat!("\n\tbuild -- build the cobalt project at the source dir",
                        "\n\tserve -- build and serve the cobalt project at the source dir",
                        "\n\twatch -- build, serve, and watch the project at the source dir",
                        "\n\timport -- moves the contents of the dest folder to the gh-pages branch");
    println!("{}", opts.usage(usage));
}

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

    let mut opts = Options::new();

    opts.optopt("s", "source", "Source folder, Default: ./", "");
    opts.optopt("d", "destination", "Destination folder, Default: ./", "");
    opts.optopt("c",
                "config",
                "Config file to use, Default: .cobalt.yml",
                "");
    opts.optopt("l",
                "layouts",
                "\tLayout templates folder, Default: _layouts/",
                "");
    opts.optopt("p", "posts", "Posts folder, Default: _posts/", "");
    opts.optopt("P", "port", "Port to serve from, Default: 3000", "");
    opts.optopt("b", "branch", "Branch that will be used to import the site to, Default: gh-pages", "");
    opts.optopt("m", "message", "Commit message that will be used on import, Default: cobalt site import", "");

    opts.optflag("", "debug", "Log verbose (debug level) information");
    opts.optflag("", "trace", "Log ultra-verbose (trace level) information");
    opts.optflag("", "silent", "Suppress all output");
    opts.optflag("i", "import", "Import after build to gh-pages branch");
    opts.optflag("h", "help", "Print this help menu");
    opts.optflag("v", "version", "Display version");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string()),
    };

    if matches.opt_present("h") {
        print_usage(opts);
        return;
    }

    if matches.opt_present("version") {
        print_version();
        return;
    }

    let format = |record: &LogRecord| {
        let level = format!("[{}]", record.level()).to_lowercase();
        format!("{:8} {}", level, record.args())
    };

    let mut builder = LogBuilder::new();
    builder.format(format);
    builder.filter(None, LogLevelFilter::Info);

    if matches.opt_present("debug") {
        builder.filter(None, LogLevelFilter::Debug);
    }

    if matches.opt_present("trace") {
        builder.filter(None, LogLevelFilter::Trace);
    }

    if matches.opt_present("silent") {
        builder.filter(None, LogLevelFilter::Off);
    }

    builder.init().unwrap();

    let config_path = match matches.opt_str("config") {
        Some(config) => config,
        None => "./.cobalt.yml".to_owned(),
    };

    // Fetch config information if available
    let mut config: Config = if fs::metadata(&config_path).is_ok() {
        info!("Using config file {}", &config_path);

        match Config::from_file(&config_path) {
            Ok(config) => config,
            Err(e) => {
                error!("Error reading config file:");
                error!("{}", e);
                std::process::exit(1);
            }
        }
    } else {
        Default::default()
    };

    if let Some(source) = matches.opt_str("s") {
        config.source = source;
    };

    if let Some(dest) = matches.opt_str("d") {
        config.dest = dest;
    };

    if let Some(layouts) = matches.opt_str("layouts") {
        config.layouts = layouts;
    };

    if let Some(posts) = matches.opt_str("posts") {
        config.posts = posts;
    };

    let command = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        print_usage(opts);
        return;
    };

    // Check for port and set port variable to it
    let port = matches.opt_str("port").unwrap_or("3000".to_owned());
    let branch = matches.opt_str("branch").unwrap_or("gh-pages".to_owned());
    let message = matches.opt_str("message").unwrap_or("cobalt site import".to_owned());
    let should_import = matches.opt_present("import");

    match command.as_ref() {
        "build" => {
            build(&config);
            if should_import {
                import(&config, &branch, &message);
            }
        }

        "serve" => {
            build(&config);
            serve(&config.dest, &port);
        }

        "watch" => {
            build(&config);

            let dest = config.dest.clone();
            thread::spawn(move || {
                serve(&dest, &port);
            });

            let (tx, rx) = channel();
            let w: Result<RecommendedWatcher, Error> = Watcher::new(tx);

            match w {
                Ok(mut watcher) => {
                    // TODO: clean up this unwrap
                    watcher.watch(&config.source).unwrap();
                    info!("Watching {:?} for changes", &config.source);

                    loop {
                        match rx.recv() {
                            Ok(val) => {
                                trace!("file changed {:?}", val);
                                if let Some(path) = val.path {
                                    if path.is_absolute() {
                                        // get where process was run from
                                        let cwd = std::env::current_dir().unwrap_or(PathBuf::new());
                                        // strip absolute path
                                        let rel_path = path.strip_prefix(&cwd).unwrap_or(&cwd);

                                        // check if path starts with the build folder.
                                        if !rel_path.starts_with(&config.dest) {
                                            build(&config);
                                        }

                                    } else {
                                        // check if path starts with build folder.
                                        // TODO: may want to check if it starts `./`
                                        if path.to_str() != Some(&config.dest) {
                                            build(&config);
                                        }
                                    }
                                }
                            }

                            Err(e) => {
                                error!("[Notify Error]: {}", e);
                                std::process::exit(1);
                            }
                        }
                    }
                }
                Err(e) => {
                    error!("[Notify Error]: {}", e);
                    std::process::exit(1);
                }
            }
        }

        "import" => {
            import(&config, &branch, &message);
        }

        _ => {
            print_usage(opts);
            return;
        }
    }
}

fn build(config: &Config) {
    info!("Building from {} into {}", config.source, config.dest);
    match cobalt::build(&config) {
        Ok(_) => info!("Build successful"),
        Err(e) => {
            error!("{}", e);
            error!("Build not successful");
            std::process::exit(1);
        }
    };
}

fn serve(dest: &str, port: &str) {
    info!("Serving {:?} through static file server", dest);
    let mut server = Nickel::new();
    server.options = NickelOptions::default().output_on_listen(false);

    server.utilize(StaticFilesHandler::new(dest));

    let ip = "127.0.0.1:".to_owned() + port;
    info!("Server Listening on {}", &ip);
    info!("Ctrl-c to stop the server");
    server.listen(&*ip);
}

fn import(config: &Config, branch: &str, message: &str) {
    info!("Importing {} to {}", config.dest, branch);

    let meta = match fs::metadata(&config.dest) {
        Ok(data) => data,

        Err(e) => {
            error!("{}", e);
            error!("Import not successful");
            std::process::exit(1);
        }
    };

    if meta.is_dir() {
        match import_dir(&config.dest, branch, message) {
            Ok(_) => info!("Import successful"),
            Err(e) => {
                error!("{}", e);
                error!("Import not successful");
                std::process::exit(1);
            }
        }
    } else {
        error!("Build dir is not a directory: {}", config.dest);
        error!("Import not successful");
        std::process::exit(1);
    }
}
<commit_msg>moved to glob path checking from default path checking<commit_after>#![deny(warnings)]

extern crate cobalt;
extern crate getopts;
extern crate env_logger;
extern crate notify;
extern crate glob;
extern crate ghp;

#[macro_use]
extern crate nickel;

#[macro_use]
extern crate log;

use getopts::Options;
use std::env;
use std::fs;
use cobalt::Config;
use log::{LogRecord, LogLevelFilter};
use env_logger::LogBuilder;
use nickel::{Nickel, Options as NickelOptions, StaticFilesHandler};
use ghp::import_dir;
use glob::Pattern;

use notify::{RecommendedWatcher, Error, Watcher};
use std::sync::mpsc::channel;
use std::thread;
use std::path::PathBuf;

fn print_version() {
    println!("0.2.0");
}

fn print_usage(opts: Options) {
    let usage = concat!("\n\tbuild -- build the cobalt project at the source dir",
                        "\n\tserve -- build and serve the cobalt project at the source dir",
                        "\n\twatch -- build, serve, and watch the project at the source dir",
                        "\n\timport -- moves the contents of the dest folder to the gh-pages branch");
    println!("{}", opts.usage(usage));
}

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

    let mut opts = Options::new();

    opts.optopt("s", "source", "Source folder, Default: ./", "");
    opts.optopt("d", "destination", "Destination folder, Default: ./", "");
    opts.optopt("c",
                "config",
                "Config file to use, Default: .cobalt.yml",
                "");
    opts.optopt("l",
                "layouts",
                "\tLayout templates folder, Default: _layouts/",
                "");
    opts.optopt("p", "posts", "Posts folder, Default: _posts/", "");
    opts.optopt("P", "port", "Port to serve from, Default: 3000", "");
    opts.optopt("b", "branch", "Branch that will be used to import the site to, Default: gh-pages", "");
    opts.optopt("m", "message", "Commit message that will be used on import, Default: cobalt site import", "");

    opts.optflag("", "debug", "Log verbose (debug level) information");
    opts.optflag("", "trace", "Log ultra-verbose (trace level) information");
    opts.optflag("", "silent", "Suppress all output");
    opts.optflag("i", "import", "Import after build to gh-pages branch");
    opts.optflag("h", "help", "Print this help menu");
    opts.optflag("v", "version", "Display version");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string()),
    };

    if matches.opt_present("h") {
        print_usage(opts);
        return;
    }

    if matches.opt_present("version") {
        print_version();
        return;
    }

    let format = |record: &LogRecord| {
        let level = format!("[{}]", record.level()).to_lowercase();
        format!("{:8} {}", level, record.args())
    };

    let mut builder = LogBuilder::new();
    builder.format(format);
    builder.filter(None, LogLevelFilter::Info);

    if matches.opt_present("debug") {
        builder.filter(None, LogLevelFilter::Debug);
    }

    if matches.opt_present("trace") {
        builder.filter(None, LogLevelFilter::Trace);
    }

    if matches.opt_present("silent") {
        builder.filter(None, LogLevelFilter::Off);
    }

    builder.init().unwrap();

    let config_path = match matches.opt_str("config") {
        Some(config) => config,
        None => "./.cobalt.yml".to_owned(),
    };

    // Fetch config information if available
    let mut config: Config = if fs::metadata(&config_path).is_ok() {
        info!("Using config file {}", &config_path);

        match Config::from_file(&config_path) {
            Ok(config) => config,
            Err(e) => {
                error!("Error reading config file:");
                error!("{}", e);
                std::process::exit(1);
            }
        }
    } else {
        Default::default()
    };

    if let Some(source) = matches.opt_str("s") {
        config.source = source;
    };

    if let Some(dest) = matches.opt_str("d") {
        config.dest = dest;
    };

    if let Some(layouts) = matches.opt_str("layouts") {
        config.layouts = layouts;
    };

    if let Some(posts) = matches.opt_str("posts") {
        config.posts = posts;
    };

    let command = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        print_usage(opts);
        return;
    };

    // Check for port and set port variable to it
    let port = matches.opt_str("port").unwrap_or("3000".to_owned());
    let branch = matches.opt_str("branch").unwrap_or("gh-pages".to_owned());
    let message = matches.opt_str("message").unwrap_or("cobalt site import".to_owned());
    let should_import = matches.opt_present("import");

    match command.as_ref() {
        "build" => {
            build(&config);
            if should_import {
                import(&config, &branch, &message);
            }
        }

        "serve" => {
            build(&config);
            serve(&config.dest, &port);
        }

        "watch" => {
            build(&config);

            let dest = config.dest.clone();
            thread::spawn(move || {
                serve(&dest, &port);
            });

            let (tx, rx) = channel();
            let w: Result<RecommendedWatcher, Error> = Watcher::new(tx);

            match w {
                Ok(mut watcher) => {
                    // TODO: clean up this unwrap
                    watcher.watch(&config.source).unwrap();
                    info!("Watching {:?} for changes", &config.source);

                    loop {
                        match rx.recv() {
                            Ok(val) => {
                                trace!("file changed {:?}", val);
                                if let Some(path) = val.path {
                                    if path.is_absolute() {
                                        // get where process was run from
                                        let cwd = std::env::current_dir().unwrap_or(PathBuf::new());
                                        // strip absolute path
                                        let rel_path = path.strip_prefix(&cwd).unwrap_or(&cwd);

                                        // check if path starts with the build folder.
                                        if !&config.ignore.iter().any(|pattern| Pattern::matches_path(
                                            pattern,
                                            rel_path)) {
                                            build(&config);
                                        }

                                    } else {
                                        // check if path starts with build folder.
                                        // TODO: may want to check if it starts `./`
                                        if !&config.ignore.iter().any(|pattern| Pattern::matches_path(pattern, &path)) {
                                            build(&config);
                                        }
                                    }
                                }
                            }

                            Err(e) => {
                                error!("[Notify Error]: {}", e);
                                std::process::exit(1);
                            }
                        }
                    }
                }
                Err(e) => {
                    error!("[Notify Error]: {}", e);
                    std::process::exit(1);
                }
            }
        }

        "import" => {
            import(&config, &branch, &message);
        }

        _ => {
            print_usage(opts);
            return;
        }
    }
}

fn build(config: &Config) {
    info!("Building from {} into {}", config.source, config.dest);
    match cobalt::build(&config) {
        Ok(_) => info!("Build successful"),
        Err(e) => {
            error!("{}", e);
            error!("Build not successful");
            std::process::exit(1);
        }
    };
}

fn serve(dest: &str, port: &str) {
    info!("Serving {:?} through static file server", dest);
    let mut server = Nickel::new();
    server.options = NickelOptions::default().output_on_listen(false);

    server.utilize(StaticFilesHandler::new(dest));

    let ip = "127.0.0.1:".to_owned() + port;
    info!("Server Listening on {}", &ip);
    info!("Ctrl-c to stop the server");
    server.listen(&*ip);
}

fn import(config: &Config, branch: &str, message: &str) {
    info!("Importing {} to {}", config.dest, branch);

    let meta = match fs::metadata(&config.dest) {
        Ok(data) => data,

        Err(e) => {
            error!("{}", e);
            error!("Import not successful");
            std::process::exit(1);
        }
    };

    if meta.is_dir() {
        match import_dir(&config.dest, branch, message) {
            Ok(_) => info!("Import successful"),
            Err(e) => {
                error!("{}", e);
                error!("Import not successful");
                std::process::exit(1);
            }
        }
    } else {
        error!("Build dir is not a directory: {}", config.dest);
        error!("Import not successful");
        std::process::exit(1);
    }
}
<|endoftext|>


<commit_before><commit_msg>Proof of concept 2.0.1 (changed paths to use PathBuf)<commit_after><|endoftext|>


<commit_before><commit_msg>adding basic layout for new sites and config file<commit_after><|endoftext|>


<commit_before><commit_msg>can now execute programs that expect a tty<commit_after><|endoftext|>


<commit_before><commit_msg>Added cache headers.<commit_after><|endoftext|>


<commit_before><commit_msg>For consistency, added in another compiler error.<commit_after><|endoftext|>


<commit_before><commit_msg>Update REPL to use the new API<commit_after><|endoftext|>


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

//! This library is derived from rlibc, not intended for general use,
//! and is superseded by a system libc if one is available. In a
//! freestanding context, however, common functions such as memset, memcpy,
//! etc are not implemented. This library provides an implementation of
//! these functions which are either required by libcore or called by rustc
//! implicitly.

#[no_mangle]
pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 {
	let mut i = 0;
	while i < n {
		*dest.offset(i as isize) = *src.offset(i as isize);
		i += 1;
	}
	return dest;
}

#[no_mangle]
pub unsafe extern "C" fn memmove(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 {
	if src < dest as *const u8 {
		// copy from end
		let mut i = n;
		while i != 0 {
			i -= 1;
			*dest.offset(i as isize) = *src.offset(i as isize);
		}
	} else {
		// copy from beginning
		let mut i = 0;
		while i < n {
			*dest.offset(i as isize) = *src.offset(i as isize);
			i += 1;
		}
	}
	return dest;
}

#[no_mangle]
pub unsafe extern "C" fn memset(s: *mut u8, c: i32, n: usize) -> *mut u8 {
	let mut i = 0;
	while i < n {
		*s.offset(i as isize) = c as u8;
		i += 1;
	}
	return s;
}

#[no_mangle]
pub unsafe extern "C" fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 {
	let mut i = 0;
	while i < n {
		let a = *s1.offset(i as isize);
		let b = *s2.offset(i as isize);
		if a != b {
			return a as i32 - b as i32;
		}
		i += 1;
	}
	return 0;
}

#[cfg(test)]
mod test {
	use super::{memcmp, memcpy, memmove, memset};

	#[test]
	fn memcmp_single_byte_pointers() {
		unsafe {
			assert_eq!(memcmp(&0xFAu8, &0xFAu8, 1), 0x00);
			assert!(memcmp(&0xEFu8, &0xFEu8, 1) < 0x00);
		}
	}

	#[test]
	fn memcmp_strings() {
		{
			let (x, z) = ("Hello!", "Good Bye.");
			let l = x.len();
			unsafe {
				assert_eq!(memcmp(x.as_ptr(), x.as_ptr(), l), 0);
				assert!(memcmp(x.as_ptr(), z.as_ptr(), l) > 0);
				assert!(memcmp(z.as_ptr(), x.as_ptr(), l) < 0);
			}
		}
		{
			let (x, z) = ("hey!", "hey.");
			let l = x.len();
			unsafe {
				assert!(memcmp(x.as_ptr(), z.as_ptr(), l) < 0);
			}
		}
	}

	#[test]
	fn memset_single_byte_pointers() {
		let mut x: u8 = 0xFF;
		unsafe {
			memset(&mut x, 0xAA, 1);
			assert_eq!(x, 0xAA);
			memset(&mut x, 0x00, 1);
			assert_eq!(x, 0x00);
			x = 0x01;
			memset(&mut x, 0x12, 0);
			assert_eq!(x, 0x01);
		}
	}

	#[test]
	fn memset_array() {
		let mut buffer = [b'X'; 100];
		unsafe {
			memset(buffer.as_mut_ptr(), b'#' as i32, buffer.len());
		}
		for byte in buffer.iter() {
			assert_eq!(*byte, b'#');
		}
	}

	#[test]
	fn memcpy_and_memcmp_arrays() {
		let (src, mut dst) = ([b'X'; 100], [b'Y'; 100]);
		unsafe {
			assert!(memcmp(src.as_ptr(), dst.as_ptr(), 100) != 0);
			let _ = memcpy(dst.as_mut_ptr(), src.as_ptr(), 100);
			assert_eq!(memcmp(src.as_ptr(), dst.as_ptr(), 100), 0);
		}
	}

	#[test]
	fn memmove_overlapping() {
		{
			let mut buffer = [b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9'];
			unsafe {
				memmove(&mut buffer[4], &buffer[0], 6);
				let mut i = 0;
				for byte in b"0123012345".iter() {
					assert_eq!(buffer[i], *byte);
					i += 1;
				}
			}
		}
		{
			let mut buffer = [b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9'];
			unsafe {
				memmove(&mut buffer[0], &buffer[4], 6);
				let mut i = 0;
				for byte in b"4567896789".iter() {
					assert_eq!(buffer[i], *byte);
					i += 1;
				}
			}
		}
	}
}
<|endoftext|>


<commit_before><commit_msg>add data members<commit_after><|endoftext|>


<commit_before><commit_msg>Update main.rs<commit_after><|endoftext|>


<commit_before><commit_msg>Colored prompt<commit_after><|endoftext|>


<commit_before><commit_msg>flood_fill<commit_after><|endoftext|>


<commit_before><commit_msg>Fixed usage of condvar.<commit_after><|endoftext|>


<commit_before><commit_msg>recursive data type with methods for node graph<commit_after>fn main() {
    let list = ~Node(1, ~Node(2, ~Node(3, ~Empty)));
    println!("Sum of all values in the list: {:i}.", list.sum());
}

enum IntList {
    Node(int, ~IntList),
    Empty
}

impl IntList {
    fn sum(~self) -> int {
        // As in C and C++, pointers are dereferenced with the asterisk `*` operator.
        match *self {
            Node(value, next) => value + next.sum(),
            Empty => 0
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Added tests.rs.<commit_after>use std::time;
use ::{CANSocket, ShouldRetry};

#[test]
fn test_nonexistant_device() {
    assert!(CANSocket::open("invalid").is_err());
}

#[test]
fn vcan0_timeout() {
    let cs = CANSocket::open("vcan1").unwrap();
    cs.set_read_timeout(time::Duration::from_millis(100)).unwrap();
    assert!(cs.read_frame().should_retry());
}
<|endoftext|>


<commit_before><commit_msg>video.reorderAlbums method<commit_after><|endoftext|>


<commit_before><commit_msg>Pick more appropriate int types for hmac<commit_after><|endoftext|>


<commit_before>#![feature(box_syntax)]
#![feature(plugin)]
#![plugin(peg_syntax_ext)]

use std::collections::{BTreeMap, HashMap};
use std::fs::File;
use std::io::{stdout, Read, Write};
use std::env;
use std::process;

use self::to_num::ToNum;
use self::directory_stack::DirectoryStack;
use self::input_editor::readln;
use self::peg::parse;
use self::expansion::expand_variables;

pub mod builtin;
pub mod directory_stack;
pub mod to_num;
pub mod input_editor;
pub mod peg;
pub mod expansion;

pub type Variables = BTreeMap<String, String>;

/// This struct will contain all of the data structures related to this
/// instance of the shell.
pub struct Shell {
    pub variables: Variables,
    pub modes: Vec<Mode>,
    pub directory_stack: DirectoryStack,
}

impl Shell {
    /// Panics if DirectoryStack construction fails
    pub fn new() -> Self {
        Shell {
            variables: BTreeMap::new(),
            modes: vec![],
            directory_stack: DirectoryStack::new().expect(""),
        }
    }
}

/// Structure which represents a Terminal's command.
/// This command structure contains a name, and the code which run the
/// functionnality associated to this one, with zero, one or several argument(s).
/// # Example
/// ```
/// let my_command = Command {
///     name: "my_command",
///     help: "Describe what my_command does followed by a newline showing usage",
///     main: box|args: &[String], &mut Shell| {
///         println!("Say 'hello' to my command! :-D");
///     }
/// }
/// ```
pub struct Command {
    pub name: &'static str,
    pub help: &'static str,
    pub main: Box<Fn(&[String], &mut Shell)>,
}

impl Command {
    /// Return the map from command names to commands
    pub fn map() -> HashMap<&'static str, Self> {
        let mut commands: HashMap<&str, Self> = HashMap::new();

        commands.insert("cd",
                        Command {
                            name: "cd",
                            help: "To change the current directory\n    cd <your_destination>",
                            main: box |args: &[String], _: &mut Shell| {
                                builtin::cd(args);
                            },
                        });

        commands.insert("dirs",
                        Command {
                            name: "dirs",
                            help: "Make a sleep in the current session\n    sleep \
                                   <number_of_seconds>",
                            main: box |args: &[String], shell: &mut Shell| {
                                shell.directory_stack.dirs(args);
                            },
                        });

        commands.insert("exit",
                        Command {
                            name: "exit",
                            help: "To exit the curent session",
                            main: box |_: &[String], _: &mut Shell| {},
                        });

        commands.insert("read",
                        Command {
                            name: "read",
                            help: "To read some variables\n    read <my_variable>",
                            main: box |args: &[String], shell: &mut Shell| {
                                builtin::read(args, &mut shell.variables);
                            },
                        });

        commands.insert("run",
                        Command {
                            name: "run",
                            help: "Run a script\n    run <script>",
                            main: box |args: &[String], shell: &mut Shell| {
                                builtin::run(args, &mut shell.variables);
                            },
                        });

        commands.insert("pushd",
                        Command {
                            name: "pushd",
                            help: "Make a sleep in the current session\n    sleep \
                                   <number_of_seconds>",
                            main: box |args: &[String], shell: &mut Shell| {
                                shell.directory_stack.pushd(args);
                            },
                        });

        commands.insert("popd",
                        Command {
                            name: "popd",
                            help: "Make a sleep in the current session\n    sleep \
                                   <number_of_seconds>",
                            main: box |args: &[String], shell: &mut Shell| {
                                shell.directory_stack.popd(args);
                            },
                        });

        let command_helper: HashMap<String, String> = commands.iter()
                                                              .map(|(k, v)| {
                                                                  (k.to_string(),
                                                                   v.help.to_string())
                                                              })
                                                              .collect();

        commands.insert("help",
                        Command {
                            name: "help",
                            help: "Display a little helper for a given command\n    help ls",
                            main: box move |args: &[String], _: &mut Shell| {
                                if let Some(command) = args.get(1) {
                                    if command_helper.contains_key(command) {
                                        match command_helper.get(command) {
                                            Some(help) => println!("{}", help),
                                            None => {
                                                println!("Command helper not found [run 'help']...")
                                            }
                                        }
                                    } else {
                                        println!("Command helper not found [run 'help']...");
                                    }
                                } else {
                                    for (command, _help) in command_helper.iter() {
                                        println!("{}", command);
                                    }
                                }
                            },
                        });

        commands
    }
}

pub struct Mode {
    value: bool,
}

fn on_command(command_string: &str, commands: &HashMap<&str, Command>, shell: &mut Shell) {
    // Show variables
    if command_string == "$" {
        for (key, value) in shell.variables.iter() {
            println!("{}={}", key, value);
        }
        return;
    }

    let mut jobs = parse(command_string);
    expand_variables(&mut jobs, &shell.variables);

    // Execute commands
    for job in jobs.iter() {
        if job.command == "if" {
            let mut value = false;

            if let Some(left) = job.args.get(0) {
                if let Some(cmp) = job.args.get(1) {
                    if let Some(right) = job.args.get(2) {
                        if cmp == "==" {
                            value = *left == *right;
                        } else if cmp == "!=" {
                            value = *left != *right;
                        } else if cmp == ">" {
                            value = left.to_num_signed() > right.to_num_signed();
                        } else if cmp == ">=" {
                            value = left.to_num_signed() >= right.to_num_signed();
                        } else if cmp == "<" {
                            value = left.to_num_signed() < right.to_num_signed();
                        } else if cmp == "<=" {
                            value = left.to_num_signed() <= right.to_num_signed();
                        } else {
                            println!("Unknown comparison: {}", cmp);
                        }
                    } else {
                        println!("No right hand side");
                    }
                } else {
                    println!("No comparison operator");
                }
            } else {
                println!("No left hand side");
            }

            shell.modes.insert(0, Mode { value: value });
            continue;
        }

        if job.command == "else" {
            if let Some(mode) = shell.modes.get_mut(0) {
                mode.value = !mode.value;
            } else {
                println!("Syntax error: else found with no previous if");
            }
            continue;
        }

        if job.command == "fi" {
            if !shell.modes.is_empty() {
                shell.modes.remove(0);
            } else {
                println!("Syntax error: fi found with no previous if");
            }
            continue;
        }

        let mut skipped: bool = false;
        for mode in shell.modes.iter() {
            if !mode.value {
                skipped = true;
                break;
            }
        }
        if skipped {
            continue;
        }

        // Set variables
        if let Some(i) = job.command.find('=') {
            let name = job.command[0..i].trim();
            let mut value = job.command[i + 1..job.command.len()].trim().to_string();

            for i in 0..job.args.len() {
                if let Some(arg) = job.args.get(i) {
                    value = value + " " + &arg;
                }
            }

            set_var(&mut shell.variables, name, &value);
            continue;
        }

        // Commands
        let mut args = job.args.clone();
        args.insert(0, job.command.clone());
        if let Some(command) = commands.get(&job.command.as_str()) {
            (*command.main)(&args, shell);
        } else {
            run_external_commmand(args, &mut shell.variables);
        }
    }
}

pub fn set_var(variables: &mut Variables, name: &str, value: &str) {
    if name.is_empty() {
        return;
    }

    if value.is_empty() {
        variables.remove(&name.to_string());
    } else {
        variables.insert(name.to_string(), value.to_string());
    }
}

fn print_prompt(modes: &[Mode]) {
    let prompt_prefix = modes.iter().rev().fold(String::new(), |acc, mode| {
        acc +
        if mode.value {
            "+ "
        } else {
            "- "
        }
    });
    print!("{}", prompt_prefix);

    let cwd = env::current_dir().ok().map_or("?".to_string(),
                                             |ref p| p.to_str().unwrap_or("?").to_string());

    print!("ion:{}# ", cwd);
    if let Err(message) = stdout().flush() {
        println!("{}: failed to flush prompt to stdout", message);
    }
}

fn run_external_commmand(args: Vec<String>, variables: &mut Variables) {
    if let Some(path) = args.get(0) {
        let mut command = process::Command::new(path);
        for i in 1..args.len() {
            if let Some(arg) = args.get(i) {
                command.arg(arg);
            }
        }
        match command.spawn() {
            Ok(mut child) => {
                match child.wait() {
                    Ok(status) => {
                        if let Some(code) = status.code() {
                            set_var(variables, "?", &code.to_string());
                        } else {
                            println!("{}: No child exit code", path);
                        }
                    }
                    Err(err) => println!("{}: Failed to wait: {}", path, err),
                }
            }
            Err(err) => println!("{}: Failed to execute: {}", path, err),
        }
    }
}

fn main() {
    let commands = Command::map();
    let mut shell = Shell::new();

    for arg in env::args().skip(1) {
        let mut command_list = String::new();
        if let Ok(mut file) = File::open(&arg) {
            if let Err(message) = file.read_to_string(&mut command_list) {
                println!("{}: Failed to read {}", message, arg);
            }
        }
        on_command(&command_list, &commands, &mut shell);
        return;
    }

    loop {

        print_prompt(&shell.modes);

        if let Some(command_original) = readln() {
            let command = command_original.trim();
            if command == "exit" {
                break;
            } else if !command.is_empty() {
                on_command(&command, &commands, &mut shell);
            }
        } else {
            break;
        }
    }
}
<commit_msg>add history<commit_after>#![feature(box_syntax)]
#![feature(plugin)]
#![plugin(peg_syntax_ext)]

use std::collections::{BTreeMap, HashMap, VecDeque};
use std::fs::File;
use std::io::{stdout, Read, Write};
use std::env;
use std::process;

use self::to_num::ToNum;
use self::directory_stack::DirectoryStack;
use self::input_editor::readln;
use self::peg::parse;
use self::expansion::expand_variables;

pub mod builtin;
pub mod directory_stack;
pub mod to_num;
pub mod input_editor;
pub mod peg;
pub mod expansion;

pub type Variables = BTreeMap<String, String>;

/// This struct will contain all of the data structures related to this
/// instance of the shell.
pub struct Shell {
    pub variables: Variables,
    pub modes: Vec<Mode>,
    pub directory_stack: DirectoryStack,
    pub history: VecDeque<String>,
}

impl Shell {
    /// Panics if DirectoryStack construction fails
    pub fn new() -> Self {
        Shell {
            variables: BTreeMap::new(),
            modes: vec![],
            directory_stack: DirectoryStack::new().expect(""),
            history: VecDeque::new(),
        }
    }
}

/// Structure which represents a Terminal's command.
/// This command structure contains a name, and the code which run the
/// functionnality associated to this one, with zero, one or several argument(s).
/// # Example
/// ```
/// let my_command = Command {
///     name: "my_command",
///     help: "Describe what my_command does followed by a newline showing usage",
///     main: box|args: &[String], &mut Shell| {
///         println!("Say 'hello' to my command! :-D");
///     }
/// }
/// ```
pub struct Command {
    pub name: &'static str,
    pub help: &'static str,
    pub main: Box<Fn(&[String], &mut Shell)>,
}

impl Command {
    /// Return the map from command names to commands
    pub fn map() -> HashMap<&'static str, Self> {
        let mut commands: HashMap<&str, Self> = HashMap::new();

        commands.insert("cd",
                        Command {
                            name: "cd",
                            help: "To change the current directory\n    cd <your_destination>",
                            main: box |args: &[String], _: &mut Shell| {
                                builtin::cd(args);
                            },
                        });

        commands.insert("dirs",
                        Command {
                            name: "dirs",
                            help: "Make a sleep in the current session\n    sleep \
                                   <number_of_seconds>",
                            main: box |args: &[String], shell: &mut Shell| {
                                shell.directory_stack.dirs(args);
                            },
                        });

        commands.insert("exit",
                        Command {
                            name: "exit",
                            help: "To exit the curent session",
                            main: box |_: &[String], _: &mut Shell| {},
                        });

        commands.insert("read",
                        Command {
                            name: "read",
                            help: "To read some variables\n    read <my_variable>",
                            main: box |args: &[String], shell: &mut Shell| {
                                builtin::read(args, &mut shell.variables);
                            },
                        });

        commands.insert("run",
                        Command {
                            name: "run",
                            help: "Run a script\n    run <script>",
                            main: box |args: &[String], shell: &mut Shell| {
                                builtin::run(args, &mut shell.variables);
                            },
                        });

        commands.insert("pushd",
                        Command {
                            name: "pushd",
                            help: "Make a sleep in the current session\n    sleep \
                                   <number_of_seconds>",
                            main: box |args: &[String], shell: &mut Shell| {
                                shell.directory_stack.pushd(args);
                            },
                        });

        commands.insert("popd",
                        Command {
                            name: "popd",
                            help: "Make a sleep in the current session\n    sleep \
                                   <number_of_seconds>",
                            main: box |args: &[String], shell: &mut Shell| {
                                shell.directory_stack.popd(args);
                            },
                        });

        commands.insert("history",
                        Command {
                            name: "history",
                            help: "Display all commands previously executed",
                            main: box |args: &[String], shell: &mut Shell| {
                                for command in shell.history.clone() {
                                    println!("{}", command);
                                }
                            },
                        });

        let command_helper: HashMap<String, String> = commands.iter()
                                                              .map(|(k, v)| {
                                                                  (k.to_string(),
                                                                   v.help.to_string())
                                                              })
                                                              .collect();

        commands.insert("help",
                        Command {
                            name: "help",
                            help: "Display a little helper for a given command\n    help ls",
                            main: box move |args: &[String], _: &mut Shell| {
                                if let Some(command) = args.get(1) {
                                    if command_helper.contains_key(command) {
                                        match command_helper.get(command) {
                                            Some(help) => println!("{}", help),
                                            None => {
                                                println!("Command helper not found [run 'help']...")
                                            }
                                        }
                                    } else {
                                        println!("Command helper not found [run 'help']...");
                                    }
                                } else {
                                    for (command, _help) in command_helper.iter() {
                                        println!("{}", command);
                                    }
                                }
                            },
                        });

        commands
    }
}

pub struct Mode {
    value: bool,
}

fn on_command(command_string: &str, commands: &HashMap<&str, Command>, shell: &mut Shell) {
    let max_history: usize = 1000; // TODO temporary, make this configurable
    if shell.history.len() > max_history {
        shell.history.pop_front();
    }
    shell.history.push_back(command_string.to_string());

    // Show variables
    if command_string == "$" {
        for (key, value) in shell.variables.iter() {
            println!("{}={}", key, value);
        }
        return;
    }

    let mut jobs = parse(command_string);
    expand_variables(&mut jobs, &shell.variables);

    // Execute commands
    for job in jobs.iter() {
        if job.command == "if" {
            let mut value = false;

            if let Some(left) = job.args.get(0) {
                if let Some(cmp) = job.args.get(1) {
                    if let Some(right) = job.args.get(2) {
                        if cmp == "==" {
                            value = *left == *right;
                        } else if cmp == "!=" {
                            value = *left != *right;
                        } else if cmp == ">" {
                            value = left.to_num_signed() > right.to_num_signed();
                        } else if cmp == ">=" {
                            value = left.to_num_signed() >= right.to_num_signed();
                        } else if cmp == "<" {
                            value = left.to_num_signed() < right.to_num_signed();
                        } else if cmp == "<=" {
                            value = left.to_num_signed() <= right.to_num_signed();
                        } else {
                            println!("Unknown comparison: {}", cmp);
                        }
                    } else {
                        println!("No right hand side");
                    }
                } else {
                    println!("No comparison operator");
                }
            } else {
                println!("No left hand side");
            }

            shell.modes.insert(0, Mode { value: value });
            continue;
        }

        if job.command == "else" {
            if let Some(mode) = shell.modes.get_mut(0) {
                mode.value = !mode.value;
            } else {
                println!("Syntax error: else found with no previous if");
            }
            continue;
        }

        if job.command == "fi" {
            if !shell.modes.is_empty() {
                shell.modes.remove(0);
            } else {
                println!("Syntax error: fi found with no previous if");
            }
            continue;
        }

        let mut skipped: bool = false;
        for mode in shell.modes.iter() {
            if !mode.value {
                skipped = true;
                break;
            }
        }
        if skipped {
            continue;
        }

        // Set variables
        if let Some(i) = job.command.find('=') {
            let name = job.command[0..i].trim();
            let mut value = job.command[i + 1..job.command.len()].trim().to_string();

            for i in 0..job.args.len() {
                if let Some(arg) = job.args.get(i) {
                    value = value + " " + &arg;
                }
            }

            set_var(&mut shell.variables, name, &value);
            continue;
        }

        // Commands
        let mut args = job.args.clone();
        args.insert(0, job.command.clone());
        if let Some(command) = commands.get(&job.command.as_str()) {
            (*command.main)(&args, shell);
        } else {
            run_external_commmand(args, &mut shell.variables);
        }
    }
}

pub fn set_var(variables: &mut Variables, name: &str, value: &str) {
    if name.is_empty() {
        return;
    }

    if value.is_empty() {
        variables.remove(&name.to_string());
    } else {
        variables.insert(name.to_string(), value.to_string());
    }
}

fn print_prompt(modes: &[Mode]) {
    let prompt_prefix = modes.iter().rev().fold(String::new(), |acc, mode| {
        acc +
        if mode.value {
            "+ "
        } else {
            "- "
        }
    });
    print!("{}", prompt_prefix);

    let cwd = env::current_dir().ok().map_or("?".to_string(),
                                             |ref p| p.to_str().unwrap_or("?").to_string());

    print!("ion:{}# ", cwd);
    if let Err(message) = stdout().flush() {
        println!("{}: failed to flush prompt to stdout", message);
    }
}

fn run_external_commmand(args: Vec<String>, variables: &mut Variables) {
    if let Some(path) = args.get(0) {
        let mut command = process::Command::new(path);
        for i in 1..args.len() {
            if let Some(arg) = args.get(i) {
                command.arg(arg);
            }
        }
        match command.spawn() {
            Ok(mut child) => {
                match child.wait() {
                    Ok(status) => {
                        if let Some(code) = status.code() {
                            set_var(variables, "?", &code.to_string());
                        } else {
                            println!("{}: No child exit code", path);
                        }
                    }
                    Err(err) => println!("{}: Failed to wait: {}", path, err),
                }
            }
            Err(err) => println!("{}: Failed to execute: {}", path, err),
        }
    }
}

fn main() {
    let commands = Command::map();
    let mut shell = Shell::new();

    for arg in env::args().skip(1) {
        let mut command_list = String::new();
        if let Ok(mut file) = File::open(&arg) {
            if let Err(message) = file.read_to_string(&mut command_list) {
                println!("{}: Failed to read {}", message, arg);
            }
        }
        on_command(&command_list, &commands, &mut shell);
        return;
    }

    loop {

        print_prompt(&shell.modes);

        if let Some(command_original) = readln() {
            let command = command_original.trim();
            if command == "exit" {
                break;
            } else if !command.is_empty() {
                on_command(&command, &commands, &mut shell);
            }
        } else {
            break;
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Lifetimes corrected<commit_after><|endoftext|>


<commit_before><commit_msg>Missed canceling for node process Added<commit_after><|endoftext|>


<commit_before><commit_msg>Removed Span::shift_to_zero because it is inconsistent.<commit_after><|endoftext|>


<commit_before><commit_msg>blank message<commit_after><|endoftext|>


<commit_before><commit_msg>empty message<commit_after><|endoftext|>


<commit_before>use std::fmt::{Debug, Display, Formatter};
use std::fmt;

use yaml_rust::Yaml;

use storage::parser::{FileHeaderParser, ParserError};
use storage::file::header::spec::FileHeaderSpec;
use storage::file::header::data::FileHeaderData;

pub struct YamlHeaderParser {
    spec: Option<FileHeaderSpec>,
}

impl YamlHeaderParser {

    pub fn new(spec: Option<FileHeaderSpec>) -> YamlHeaderParser {
        YamlHeaderParser {
            spec: spec
        }
    }

}

impl Display for YamlHeaderParser {

    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        try!(write!(fmt, "YamlHeaderParser"));
        Ok(())
    }

}

impl Debug for YamlHeaderParser {

    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        try!(write!(fmt, "YamlHeaderParser, Spec: {:?}", self.spec));
        Ok(())
    }

}

impl FileHeaderParser for YamlHeaderParser {

    fn read(&self, string: Option<String>) -> Result<FileHeaderData, ParserError> {
        use yaml_rust::YamlLoader;
        if string.is_some() {
            let s = string.unwrap();
            YamlLoader::load_from_str(&s[..])
                .map(|mut vec_yaml| {
                    vec_yaml.pop().map(|f| {
                        visit_yaml(f)
                    }).unwrap()
                })
                .map_err(|e| {
                    debug!("YAML parser error: {:?}", e);
                    ParserError::short(&s[..], s.clone(), 0)
                })
        } else {
            Ok(FileHeaderData::Null)
        }

    }

    fn write(&self, data: &FileHeaderData) -> Result<String, ParserError> {
        use yaml_rust::YamlEmitter;

        let mut buffer  = String::new();
        let result = {
            let mut emitter = YamlEmitter::new(&mut buffer);
            emitter.dump(&visit_header(data))
        };
        result
            .map_err(|e| {
                error!("Error emitting YAML.");
                debug!("YAML parser error: {:?}", e);
                ParserError::short(&buffer[..], buffer.clone(), 0)
            })
            .map(|_| buffer)
    }

}

fn visit_yaml(v: Yaml) -> FileHeaderData {
    use std::process::exit;

    match v {
        Yaml::Real(_)    => FileHeaderData::Float(v.as_f64().unwrap()),
        Yaml::Integer(i) => {
            if i > 0 {
                debug!("Castring {} : i64 -> u64", i);
                FileHeaderData::UInteger(i as u64)
            } else {
                FileHeaderData::Integer(i)
            }
        },
        Yaml::String(s)  => FileHeaderData::Text(s),
        Yaml::Boolean(b) => FileHeaderData::Bool(b),

        Yaml::Array(vec) => {
            FileHeaderData::Array {
                values: Box::new(vec.clone().into_iter().map(|i| visit_yaml(i)).collect())
            }
        },

        Yaml::Hash(btree) => {
            let btree = btree.clone();
            FileHeaderData::Map{
                keys: btree.into_iter().map(|(k, v)|
                    FileHeaderData::Key {
                        name: String::from(k.as_str().unwrap()),
                        value: Box::new(visit_yaml(v)),
                    }
                ).collect()
            }
        },

        Yaml::Alias(_) => {
            warn!("YAML::ALIAS is not yet fully supported by rust-yaml");
            FileHeaderData::Null
        },

        Yaml::Null => FileHeaderData::Null,

        Yaml::BadValue => {
            warn!("YAML parsing error");
            exit(1);
        },
    }
}

fn visit_header(h: &FileHeaderData) -> Yaml {
    use std::ops::Deref;
    use std::collections::BTreeMap;
    use std::process::exit;

    match h {
        &FileHeaderData::Null               => Yaml::Null,
        &FileHeaderData::Float(f)           => Yaml::Real(format!("{}", f)),
        &FileHeaderData::Integer(i)         => Yaml::Integer(i),
        &FileHeaderData::UInteger(u)        => {
            debug!("Might be losing data now: u64 -> i64 cast");
            Yaml::Integer(u as i64)
        },
        &FileHeaderData::Text(ref s)            => Yaml::String(s.clone()),
        &FileHeaderData::Bool(b)            => Yaml::Boolean(b),

        &FileHeaderData::Array{values: ref a} => {
            Yaml::Array(a.deref().into_iter().map(|e| visit_header(e)).collect())
        },

        &FileHeaderData::Key{name: _, value: _} => {
            error!("Something went terribly wrong when trying to emit YAML");
            exit(1);
        },

        &FileHeaderData::Map{ref keys} => {
            let mut map : BTreeMap<Yaml, Yaml> = BTreeMap::new();

            let failed = keys.into_iter().map(|key| {
                match key {
                    &FileHeaderData::Key{ref name, ref value} => {
                        let k = Yaml::String(name.clone());
                        let v = visit_header(value.deref());

                        map.insert(k, v).is_none()
                    },

                    _ =>  {
                        error!("Something went terribly wrong when trying to emit YAML");
                        exit(1);
                    }
                }
            })
            .fold(0, |acc, succeeded : bool| {
                if !succeeded { acc + 1 } else { acc }
            });

            debug!("Failed to insert {} keys", failed);
            Yaml::Hash(map)
        },
    }
}
<commit_msg>Add simple deserialization test<commit_after>use std::fmt::{Debug, Display, Formatter};
use std::fmt;

use yaml_rust::Yaml;

use storage::parser::{FileHeaderParser, ParserError};
use storage::file::header::spec::FileHeaderSpec;
use storage::file::header::data::FileHeaderData;

pub struct YamlHeaderParser {
    spec: Option<FileHeaderSpec>,
}

impl YamlHeaderParser {

    pub fn new(spec: Option<FileHeaderSpec>) -> YamlHeaderParser {
        YamlHeaderParser {
            spec: spec
        }
    }

}

impl Display for YamlHeaderParser {

    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        try!(write!(fmt, "YamlHeaderParser"));
        Ok(())
    }

}

impl Debug for YamlHeaderParser {

    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        try!(write!(fmt, "YamlHeaderParser, Spec: {:?}", self.spec));
        Ok(())
    }

}

impl FileHeaderParser for YamlHeaderParser {

    fn read(&self, string: Option<String>) -> Result<FileHeaderData, ParserError> {
        use yaml_rust::YamlLoader;
        if string.is_some() {
            let s = string.unwrap();
            YamlLoader::load_from_str(&s[..])
                .map(|mut vec_yaml| {
                    vec_yaml.pop().map(|f| {
                        visit_yaml(f)
                    }).unwrap()
                })
                .map_err(|e| {
                    debug!("YAML parser error: {:?}", e);
                    ParserError::short(&s[..], s.clone(), 0)
                })
        } else {
            Ok(FileHeaderData::Null)
        }

    }

    fn write(&self, data: &FileHeaderData) -> Result<String, ParserError> {
        use yaml_rust::YamlEmitter;

        let mut buffer  = String::new();
        let result = {
            let mut emitter = YamlEmitter::new(&mut buffer);
            emitter.dump(&visit_header(data))
        };
        result
            .map_err(|e| {
                error!("Error emitting YAML.");
                debug!("YAML parser error: {:?}", e);
                ParserError::short(&buffer[..], buffer.clone(), 0)
            })
            .map(|_| buffer)
    }

}

fn visit_yaml(v: Yaml) -> FileHeaderData {
    use std::process::exit;

    match v {
        Yaml::Real(_)    => FileHeaderData::Float(v.as_f64().unwrap()),
        Yaml::Integer(i) => {
            if i > 0 {
                debug!("Castring {} : i64 -> u64", i);
                FileHeaderData::UInteger(i as u64)
            } else {
                FileHeaderData::Integer(i)
            }
        },
        Yaml::String(s)  => FileHeaderData::Text(s),
        Yaml::Boolean(b) => FileHeaderData::Bool(b),

        Yaml::Array(vec) => {
            FileHeaderData::Array {
                values: Box::new(vec.clone().into_iter().map(|i| visit_yaml(i)).collect())
            }
        },

        Yaml::Hash(btree) => {
            let btree = btree.clone();
            FileHeaderData::Map{
                keys: btree.into_iter().map(|(k, v)|
                    FileHeaderData::Key {
                        name: String::from(k.as_str().unwrap()),
                        value: Box::new(visit_yaml(v)),
                    }
                ).collect()
            }
        },

        Yaml::Alias(_) => {
            warn!("YAML::ALIAS is not yet fully supported by rust-yaml");
            FileHeaderData::Null
        },

        Yaml::Null => FileHeaderData::Null,

        Yaml::BadValue => {
            warn!("YAML parsing error");
            exit(1);
        },
    }
}

fn visit_header(h: &FileHeaderData) -> Yaml {
    use std::ops::Deref;
    use std::collections::BTreeMap;
    use std::process::exit;

    match h {
        &FileHeaderData::Null               => Yaml::Null,
        &FileHeaderData::Float(f)           => Yaml::Real(format!("{}", f)),
        &FileHeaderData::Integer(i)         => Yaml::Integer(i),
        &FileHeaderData::UInteger(u)        => {
            debug!("Might be losing data now: u64 -> i64 cast");
            Yaml::Integer(u as i64)
        },
        &FileHeaderData::Text(ref s)            => Yaml::String(s.clone()),
        &FileHeaderData::Bool(b)            => Yaml::Boolean(b),

        &FileHeaderData::Array{values: ref a} => {
            Yaml::Array(a.deref().into_iter().map(|e| visit_header(e)).collect())
        },

        &FileHeaderData::Key{name: _, value: _} => {
            error!("Something went terribly wrong when trying to emit YAML");
            exit(1);
        },

        &FileHeaderData::Map{ref keys} => {
            let mut map : BTreeMap<Yaml, Yaml> = BTreeMap::new();

            let failed = keys.into_iter().map(|key| {
                match key {
                    &FileHeaderData::Key{ref name, ref value} => {
                        let k = Yaml::String(name.clone());
                        let v = visit_header(value.deref());

                        map.insert(k, v).is_none()
                    },

                    _ =>  {
                        error!("Something went terribly wrong when trying to emit YAML");
                        exit(1);
                    }
                }
            })
            .fold(0, |acc, succeeded : bool| {
                if !succeeded { acc + 1 } else { acc }
            });

            debug!("Failed to insert {} keys", failed);
            Yaml::Hash(map)
        },
    }
}

#[cfg(test)]
mod test {
    use std::ops::Deref;

    use super::YamlHeaderParser;
    use storage::parser::FileHeaderParser;
    use storage::file::header::data::FileHeaderData as FHD;
    use storage::file::header::spec::FileHeaderSpec as FHS;

    #[test]
    fn test_deserialization() {
        let text = String::from("a: 1\nb: 2");
        let spec = FHS::Array { allowed_types: vec![
                FHS::Map {
                    keys: vec![
                        FHS::Key {
                            name: String::from("a"),
                            value_type: Box::new(FHS::UInteger)
                        },
                    ]
                }
            ]
        };

        let parser = YamlHeaderParser::new(Some(spec));
        let parsed = parser.read(Some(text));
        assert!(parsed.is_ok(), "Parsed is not ok: {:?}", parsed);
        debug!("Parsed: {:?}", parsed);

        match parsed.ok() {
            Some(FHD::Map{ref keys}) => {
                keys.into_iter().map(|k| {
                    match k {
                        &FHD::Key{ref name, ref value} => {
                            assert!(name == "a" || name == "b", "Key unknown");
                            match value.deref() {
                                &FHD::UInteger(u) => assert!(u == 1 || u == 2),
                                &FHD::Integer(_) => assert!(false, "Found Integer, expected UInteger"),
                                _ => assert!(false, "Integers are not here"),
                            };
                        },
                        _ => assert!(false, "Key is not a Key"),
                    };
                })
                .all(|x| x == ());
            },
            _ => assert!(false, "Map is not a Map"),
        }
    }
}

<|endoftext|>


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

//! Check license of third-party deps by inspecting src/vendor

use std::collections::{BTreeSet, HashSet};
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::process::Command;

use serde_json;

static LICENSES: &'static [&'static str] = &[
    "MIT/Apache-2.0",
    "MIT / Apache-2.0",
    "Apache-2.0/MIT",
    "Apache-2.0 / MIT",
    "MIT OR Apache-2.0",
    "MIT",
    "Unlicense/MIT",
];

/// These are exceptions to Rust's permissive licensing policy, and
/// should be considered bugs. Exceptions are only allowed in Rust
/// tooling. It is _crucial_ that no exception crates be dependencies
/// of the Rust runtime (std / test).
static EXCEPTIONS: &'static [&'static str] = &[
    "mdbook",             // MPL2, mdbook
    "openssl",            // BSD+advertising clause, cargo, mdbook
    "pest",               // MPL2, mdbook via handlebars
    "thread-id",          // Apache-2.0, mdbook
    "toml-query",         // MPL-2.0, mdbook
    "is-match",           // MPL-2.0, mdbook
    "cssparser",          // MPL-2.0, rustdoc
    "smallvec",           // MPL-2.0, rustdoc
    "fuchsia-zircon-sys", // BSD-3-Clause, rustdoc, rustc, cargo
    "fuchsia-zircon",     // BSD-3-Clause, rustdoc, rustc, cargo (jobserver & tempdir)
    "cssparser-macros",   // MPL-2.0, rustdoc
    "selectors",          // MPL-2.0, rustdoc
    "clippy_lints",       // MPL-2.0 rls
];

/// Which crates to check against the whitelist?
static WHITELIST_CRATES: &'static [CrateVersion] = &[
    CrateVersion("rustc", "0.0.0"),
    CrateVersion("rustc_trans", "0.0.0"),
];

/// Whitelist of crates rustc is allowed to depend on. Avoid adding to the list if possible.
static WHITELIST: &'static [Crate] = &[
//    Crate("ar"),
//    Crate("arena"),
//    Crate("backtrace"),
//    Crate("backtrace-sys"),
//    Crate("bitflags"),
//    Crate("build_helper"),
//    Crate("byteorder"),
//    Crate("cc"),
//    Crate("cfg-if"),
//    Crate("cmake"),
//    Crate("filetime"),
//    Crate("flate2"),
//    Crate("fmt_macros"),
//    Crate("fuchsia-zircon"),
//    Crate("fuchsia-zircon-sys"),
//    Crate("graphviz"),
//    Crate("jobserver"),
//    Crate("kernel32-sys"),
//    Crate("lazy_static"),
//    Crate("libc"),
//    Crate("log"),
//    Crate("log_settings"),
//    Crate("miniz-sys"),
//    Crate("num_cpus"),
//    Crate("owning_ref"),
//    Crate("parking_lot"),
//    Crate("parking_lot_core"),
//    Crate("rand"),
//    Crate("redox_syscall"),
//    Crate("rustc"),
//    Crate("rustc-demangle"),
//    Crate("rustc_allocator"),
//    Crate("rustc_apfloat"),
//    Crate("rustc_back"),
//    Crate("rustc_binaryen"),
//    Crate("rustc_const_eval"),
//    Crate("rustc_const_math"),
//    Crate("rustc_cratesio_shim"),
//    Crate("rustc_data_structures"),
//    Crate("rustc_errors"),
//    Crate("rustc_incremental"),
//    Crate("rustc_llvm"),
//    Crate("rustc_mir"),
//    Crate("rustc_platform_intrinsics"),
//    Crate("rustc_trans"),
//    Crate("rustc_trans_utils"),
//    Crate("serialize"),
//    Crate("smallvec"),
//    Crate("stable_deref_trait"),
//    Crate("syntax"),
//    Crate("syntax_pos"),
//    Crate("tempdir"),
//    Crate("unicode-width"),
//    Crate("winapi"),
//    Crate("winapi-build"),
//    Crate("winapi-i686-pc-windows-gnu"),
//    Crate("winapi-x86_64-pc-windows-gnu"),
];

// Some types for Serde to deserialize the output of `cargo metadata` to...

#[derive(Deserialize)]
struct Output {
    resolve: Resolve,
}

#[derive(Deserialize)]
struct Resolve {
    nodes: Vec<ResolveNode>,
}

#[derive(Deserialize)]
struct ResolveNode {
    id: String,
    dependencies: Vec<String>,
}

/// A unique identifier for a crate
#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Debug, Hash)]
struct Crate<'a>(&'a str); // (name,)

#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Debug, Hash)]
struct CrateVersion<'a>(&'a str, &'a str); // (name, version)

impl<'a> Crate<'a> {
    pub fn id_str(&self) -> String {
        format!("{} ", self.0)
    }
}

impl<'a> CrateVersion<'a> {
    pub fn from_str(s: &'a str) -> Self {
        let mut parts = s.split(" ");
        let name = parts.next().unwrap();
        let version = parts.next().unwrap();

        CrateVersion(name, version)
    }

    pub fn id_str(&self) -> String {
        format!("{} {}", self.0, self.1)
    }
}

impl<'a> From<CrateVersion<'a>> for Crate<'a> {
    fn from(cv: CrateVersion<'a>) -> Crate<'a> {
        Crate(cv.0)
    }
}

/// Checks the dependency at the given path. Changes `bad` to `true` if a check failed.
///
/// Specifically, this checks that the license is correct.
pub fn check(path: &Path, bad: &mut bool) {
    // Check licences
    let path = path.join("vendor");
    assert!(path.exists(), "vendor directory missing");
    let mut saw_dir = false;
    for dir in t!(path.read_dir()) {
        saw_dir = true;
        let dir = t!(dir);

        // skip our exceptions
        if EXCEPTIONS.iter().any(|exception| {
            dir.path()
                .to_str()
                .unwrap()
                .contains(&format!("src/vendor/{}", exception))
        }) {
            continue;
        }

        let toml = dir.path().join("Cargo.toml");
        *bad = *bad || !check_license(&toml);
    }
    assert!(saw_dir, "no vendored source");
}

/// Checks the dependency of WHITELIST_CRATES at the given path. Changes `bad` to `true` if a check
/// failed.
///
/// Specifically, this checks that the dependencies are on the WHITELIST.
pub fn check_whitelist(path: &Path, cargo: &Path, bad: &mut bool) {
    // Get dependencies from cargo metadata
    let resolve = get_deps(path, cargo);

    // Get the whitelist into a convenient form
    let whitelist: HashSet<_> = WHITELIST.iter().cloned().collect();

    // Check dependencies
    let mut visited = BTreeSet::new();
    let mut unapproved = BTreeSet::new();
    for &krate in WHITELIST_CRATES.iter() {
        let mut bad = check_crate_whitelist(&whitelist, &resolve, &mut visited, krate);
        unapproved.append(&mut bad);
    }

    if unapproved.len() > 0 {
        println!("Dependencies not on the whitelist:");
        for dep in unapproved {
            println!("* {}", dep.id_str());
        }
        *bad = true;
    }
}

fn check_license(path: &Path) -> bool {
    if !path.exists() {
        panic!("{} does not exist", path.display());
    }
    let mut contents = String::new();
    t!(t!(File::open(path)).read_to_string(&mut contents));

    let mut found_license = false;
    for line in contents.lines() {
        if !line.starts_with("license") {
            continue;
        }
        let license = extract_license(line);
        if !LICENSES.contains(&&*license) {
            println!("invalid license {} in {}", license, path.display());
            return false;
        }
        found_license = true;
        break;
    }
    if !found_license {
        println!("no license in {}", path.display());
        return false;
    }

    true
}

fn extract_license(line: &str) -> String {
    let first_quote = line.find('"');
    let last_quote = line.rfind('"');
    if let (Some(f), Some(l)) = (first_quote, last_quote) {
        let license = &line[f + 1..l];
        license.into()
    } else {
        "bad-license-parse".into()
    }
}

/// Get the dependencies of the crate at the given path using `cargo metadata`.
fn get_deps(path: &Path, cargo: &Path) -> Resolve {
    // Run `cargo metadata` to get the set of dependencies
    let output = Command::new(cargo)
        .arg("metadata")
        .arg("--format-version")
        .arg("1")
        .arg("--manifest-path")
        .arg(path.join("Cargo.toml"))
        .output()
        .expect("Unable to run `cargo metadata`")
        .stdout;
    let output = String::from_utf8_lossy(&output);
    let output: Output = serde_json::from_str(&output).unwrap();

    output.resolve
}

/// Checks the dependencies of the given crate from the given cargo metadata to see if they are on
/// the whitelist. Returns a list of illegal dependencies.
fn check_crate_whitelist<'a, 'b>(
    whitelist: &'a HashSet<Crate>,
    resolve: &'a Resolve,
    visited: &'b mut BTreeSet<CrateVersion<'a>>,
    krate: CrateVersion<'a>,
) -> BTreeSet<Crate<'a>> {
    // Will contain bad deps
    let mut unapproved = BTreeSet::new();

    // Check if we have already visited this crate
    if visited.contains(&krate) {
        return unapproved;
    }

    visited.insert(krate);

    // If this dependency is not on the WHITELIST, add to bad set
    if !whitelist.contains(&krate.into()) {
        unapproved.insert(krate.into());
    }

    // Do a DFS in the crate graph (it's a DAG, so we know we have no cycles!)
    let to_check = resolve
        .nodes
        .iter()
        .find(|n| n.id.starts_with(&krate.id_str()))
        .expect("crate does not exist");

    for dep in to_check.dependencies.iter() {
        let krate = CrateVersion::from_str(dep);
        let mut bad = check_crate_whitelist(whitelist, resolve, visited, krate);

        unapproved.append(&mut bad);
    }

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

//! Check license of third-party deps by inspecting src/vendor

use std::collections::{BTreeSet, HashSet};
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::process::Command;

use serde_json;

static LICENSES: &'static [&'static str] = &[
    "MIT/Apache-2.0",
    "MIT / Apache-2.0",
    "Apache-2.0/MIT",
    "Apache-2.0 / MIT",
    "MIT OR Apache-2.0",
    "MIT",
    "Unlicense/MIT",
];

/// These are exceptions to Rust's permissive licensing policy, and
/// should be considered bugs. Exceptions are only allowed in Rust
/// tooling. It is _crucial_ that no exception crates be dependencies
/// of the Rust runtime (std / test).
static EXCEPTIONS: &'static [&'static str] = &[
    "mdbook",             // MPL2, mdbook
    "openssl",            // BSD+advertising clause, cargo, mdbook
    "pest",               // MPL2, mdbook via handlebars
    "thread-id",          // Apache-2.0, mdbook
    "toml-query",         // MPL-2.0, mdbook
    "is-match",           // MPL-2.0, mdbook
    "cssparser",          // MPL-2.0, rustdoc
    "smallvec",           // MPL-2.0, rustdoc
    "fuchsia-zircon-sys", // BSD-3-Clause, rustdoc, rustc, cargo
    "fuchsia-zircon",     // BSD-3-Clause, rustdoc, rustc, cargo (jobserver & tempdir)
    "cssparser-macros",   // MPL-2.0, rustdoc
    "selectors",          // MPL-2.0, rustdoc
    "clippy_lints",       // MPL-2.0 rls
];

/// Which crates to check against the whitelist?
static WHITELIST_CRATES: &'static [CrateVersion] = &[
    CrateVersion("rustc", "0.0.0"),
    CrateVersion("rustc_trans", "0.0.0"),
];

/// Whitelist of crates rustc is allowed to depend on. Avoid adding to the list if possible.
static WHITELIST: &'static [Crate] = &[
//    Crate("backtrace"),
//    Crate("backtrace-sys"),
//    Crate("bitflags"),
//    Crate("byteorder"),
//    Crate("cc"),
//    Crate("cfg-if"),
//    Crate("flate2"),
//    Crate("fuchsia-zircon"),
//    Crate("fuchsia-zircon-sys"),
//    Crate("jobserver"),
//    Crate("lazy_static"),
//    Crate("libc"),
//    Crate("log"),
//    Crate("miniz-sys"),
//    Crate("num_cpus"),
//    Crate("rand"),
//    Crate("rustc"),
//    Crate("rustc-demangle"),
//    Crate("rustc_trans"),
//    Crate("tempdir"),
//    Crate("winapi"),
//    Crate("winapi-i686-pc-windows-gnu"),
//    Crate("winapi-x86_64-pc-windows-gnu"),
];

// Some types for Serde to deserialize the output of `cargo metadata` to...

#[derive(Deserialize)]
struct Output {
    resolve: Resolve,
}

#[derive(Deserialize)]
struct Resolve {
    nodes: Vec<ResolveNode>,
}

#[derive(Deserialize)]
struct ResolveNode {
    id: String,
    dependencies: Vec<String>,
}

/// A unique identifier for a crate
#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Debug, Hash)]
struct Crate<'a>(&'a str); // (name,)

#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Debug, Hash)]
struct CrateVersion<'a>(&'a str, &'a str); // (name, version)

impl<'a> Crate<'a> {
    pub fn id_str(&self) -> String {
        format!("{} ", self.0)
    }
}

impl<'a> CrateVersion<'a> {
    /// Returns the struct and whether or not the dep is in-tree
    pub fn from_str(s: &'a str) -> (Self, bool) {
        let mut parts = s.split(" ");
        let name = parts.next().unwrap();
        let version = parts.next().unwrap();
        let path = parts.next().unwrap();

        let is_path_dep = path.starts_with("(path+");

        (CrateVersion(name, version), is_path_dep)
    }

    pub fn id_str(&self) -> String {
        format!("{} {}", self.0, self.1)
    }
}

impl<'a> From<CrateVersion<'a>> for Crate<'a> {
    fn from(cv: CrateVersion<'a>) -> Crate<'a> {
        Crate(cv.0)
    }
}

/// Checks the dependency at the given path. Changes `bad` to `true` if a check failed.
///
/// Specifically, this checks that the license is correct.
pub fn check(path: &Path, bad: &mut bool) {
    // Check licences
    let path = path.join("vendor");
    assert!(path.exists(), "vendor directory missing");
    let mut saw_dir = false;
    for dir in t!(path.read_dir()) {
        saw_dir = true;
        let dir = t!(dir);

        // skip our exceptions
        if EXCEPTIONS.iter().any(|exception| {
            dir.path()
                .to_str()
                .unwrap()
                .contains(&format!("src/vendor/{}", exception))
        }) {
            continue;
        }

        let toml = dir.path().join("Cargo.toml");
        *bad = *bad || !check_license(&toml);
    }
    assert!(saw_dir, "no vendored source");
}

/// Checks the dependency of WHITELIST_CRATES at the given path. Changes `bad` to `true` if a check
/// failed.
///
/// Specifically, this checks that the dependencies are on the WHITELIST.
pub fn check_whitelist(path: &Path, cargo: &Path, bad: &mut bool) {
    // Get dependencies from cargo metadata
    let resolve = get_deps(path, cargo);

    // Get the whitelist into a convenient form
    let whitelist: HashSet<_> = WHITELIST.iter().cloned().collect();

    // Check dependencies
    let mut visited = BTreeSet::new();
    let mut unapproved = BTreeSet::new();
    for &krate in WHITELIST_CRATES.iter() {
        let mut bad = check_crate_whitelist(&whitelist, &resolve, &mut visited, krate);
        unapproved.append(&mut bad);
    }

    if unapproved.len() > 0 {
        println!("Dependencies not on the whitelist:");
        for dep in unapproved {
            println!("* {}", dep.id_str());
        }
        *bad = true;
    }
}

fn check_license(path: &Path) -> bool {
    if !path.exists() {
        panic!("{} does not exist", path.display());
    }
    let mut contents = String::new();
    t!(t!(File::open(path)).read_to_string(&mut contents));

    let mut found_license = false;
    for line in contents.lines() {
        if !line.starts_with("license") {
            continue;
        }
        let license = extract_license(line);
        if !LICENSES.contains(&&*license) {
            println!("invalid license {} in {}", license, path.display());
            return false;
        }
        found_license = true;
        break;
    }
    if !found_license {
        println!("no license in {}", path.display());
        return false;
    }

    true
}

fn extract_license(line: &str) -> String {
    let first_quote = line.find('"');
    let last_quote = line.rfind('"');
    if let (Some(f), Some(l)) = (first_quote, last_quote) {
        let license = &line[f + 1..l];
        license.into()
    } else {
        "bad-license-parse".into()
    }
}

/// Get the dependencies of the crate at the given path using `cargo metadata`.
fn get_deps(path: &Path, cargo: &Path) -> Resolve {
    // Run `cargo metadata` to get the set of dependencies
    let output = Command::new(cargo)
        .arg("metadata")
        .arg("--format-version")
        .arg("1")
        .arg("--manifest-path")
        .arg(path.join("Cargo.toml"))
        .output()
        .expect("Unable to run `cargo metadata`")
        .stdout;
    let output = String::from_utf8_lossy(&output);
    let output: Output = serde_json::from_str(&output).unwrap();

    output.resolve
}

/// Checks the dependencies of the given crate from the given cargo metadata to see if they are on
/// the whitelist. Returns a list of illegal dependencies.
fn check_crate_whitelist<'a, 'b>(
    whitelist: &'a HashSet<Crate>,
    resolve: &'a Resolve,
    visited: &'b mut BTreeSet<CrateVersion<'a>>,
    krate: CrateVersion<'a>,
) -> BTreeSet<Crate<'a>> {
    // Will contain bad deps
    let mut unapproved = BTreeSet::new();

    // Check if we have already visited this crate
    if visited.contains(&krate) {
        return unapproved;
    }

    visited.insert(krate);

    // If this dependency is not on the WHITELIST, add to bad set
    if !whitelist.contains(&krate.into()) {
        unapproved.insert(krate.into());
    }

    // Do a DFS in the crate graph (it's a DAG, so we know we have no cycles!)
    let to_check = resolve
        .nodes
        .iter()
        .find(|n| n.id.starts_with(&krate.id_str()))
        .expect("crate does not exist");

    for dep in to_check.dependencies.iter() {
        let (krate, is_path_dep) = CrateVersion::from_str(dep);

        // We don't check in-tree deps
        if !is_path_dep {
            let mut bad = check_crate_whitelist(whitelist, resolve, visited, krate);
            unapproved.append(&mut bad);
        }
    }

    unapproved
}
<|endoftext|>


<commit_before><commit_msg>ZMsgExtended::send_multi() is no longer static<commit_after><|endoftext|>


<commit_before><commit_msg>fix(Error Status): fixes bug where --help and --version return non-zero exit code<commit_after><|endoftext|>


<commit_before><commit_msg>Kill dead code<commit_after><|endoftext|>


<commit_before><commit_msg>Clippy Fix: let_underscore_lock<commit_after><|endoftext|>


<commit_before><commit_msg>Test items from serde_codegen test suite<commit_after>extern crate item;

#[macro_use]
extern crate quote;

/// These are all of the items from serde_codegen's test suite.
/// Obnoxious whitespace has been added in an attempt to fool the parser.
#[test]
fn test_all() {
    for s in ITEMS {
        let ast = item::parse(s);
        let tokens = quote!(#ast).to_string();
        assert_eq!(ast, item::parse(&tokens));
    }

    static ITEMS: &'static [&'static str] = &[
        r#"
        # [ derive ( Serialize ) ]
         #[derive(Deserialize)]
        struct DefaultStruct <A , B, C, D, E> where C : MyDefault , E: MyDefault {
            a1 : A,
            #[serde(default)]
            a2: B,
            #[serde(default = "MyDefault::my_default")]
            a3: C,
            #[serde(skip_deserializing)]
            a4: D,
            #[serde(skip_deserializing, default = "MyDefault::my_default")]
            a5: E,
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        enum DefaultEnum<A, B, C, D, E> where C: MyDefault, E: MyDefault {
            Struct {
                a1: A,
                #[serde(default)]
                a2: B,
                #[serde(default = "MyDefault::my_default")]
                a3: C,
                #[serde(skip_deserializing)]
                a4: D,
                #[serde(skip_deserializing, default = "MyDefault::my_default")]
                a5: E,
            },
        }
        "#,
        r#"
        #[derive(Deserialize)]
        struct NoStdDefault(i8);
        "#,
        r#"
        #[derive(Deserialize)]
        struct ContainsNoStdDefault <A : MyDefault> {
            #[serde(default = "MyDefault::my_default")]
            a: A,
        }
        "#,
        r#"
        #[derive(Deserialize)]
        struct ContainsNotDeserialize<A, B, C: DeserializeWith, E: MyDefault> {
            #[serde(skip_deserializing)]
            a: A,
            #[serde(skip_deserializing, default)]
            b: B,
            #[serde(deserialize_with = "DeserializeWith::deserialize_with", default)]
            c: C,
            #[serde(skip_deserializing, default = "MyDefault::my_default")]
            e: E,
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[serde(deny_unknown_fields)]
        #[derive(Deserialize)]
        struct DenyUnknown {
            a1: i32,
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[serde(rename = "Superhero")]
        #[derive(Deserialize)]
        struct RenameStruct {
            a1: i32,
            #[serde(rename = "a3")]
            a2: i32,
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[serde(rename(serialize = "SuperheroSer", deserialize = "SuperheroDe"))]
        #[derive(Deserialize)]
        struct RenameStructSerializeDeserialize {
            a1: i32,
            #[serde(rename(serialize = "a4", deserialize = "a5"))]
            a2: i32,
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[serde(rename = "Superhero")]
        #[derive(Deserialize)]
        enum RenameEnum {

            #[serde(rename = "bruce_wayne")]
            Batman ,

            #[serde(rename = "clark_kent")]
            Superman ( i8 ) ,

            #[serde(rename = "diana_prince")]
            WonderWoman ( i8 , i8 ) ,

            #[serde(rename = "barry_allan")]
            Flash {
                #[serde(rename = "b")]
                a : i32,
            } ,
        }
        "#,
        r#"
        #[derive(Deserialize)]
        #[serde ( rename ( serialize = "SuperheroSer" , deserialize = "SuperheroDe" ) ) ]
        #[derive(Serialize)]
        enum RenameEnumSerializeDeserialize<A> {

            #[serde(rename(serialize = "dick_grayson", deserialize = "jason_todd"))]
            Robin {
                a: i8,
                #[serde(rename(serialize = "c"))]
                #[serde(rename(deserialize = "d"))]
                b: A,
            },
        }
        "#,
        r#"
        #[derive(Serialize)]
        struct SkipSerializingStruct< 'a , B, C> where C : ShouldSkip {
            a: & 'a i8,
            #[serde(skip_serializing)]
            b: B,
            #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
            c: C,
        }
        "#,
        r#"
        #[derive(Serialize)]
        enum SkipSerializingEnum<'a, B, C> where C: ShouldSkip {
            Struct {
                a: &'a i8,
                #[serde(skip_serializing)]
                _b: B,
                #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
                c: C,
            },
        }
        "#,
        r#"
        #[derive(Serialize)]
        struct ContainsNotSerialize<'a, B, C, D> where B: 'a , D: SerializeWith {
            a: &'a Option<i8>,
            #[serde(skip_serializing)]
            b: &'a B,
            #[serde(skip_serializing)]
            c: Option<C>,
            #[serde(serialize_with = "SerializeWith::serialize_with")]
            d: D,
        }
        "#,
        r#"
        #[derive(Serialize)]
        struct SerializeWithStruct<'a, B> where B: SerializeWith {
            a: &'a i8,
            #[serde(serialize_with = "SerializeWith::serialize_with")]
            b: B,
        }
        "#,
        r#"
        #[derive(Serialize)]
        enum SerializeWithEnum<'a, B> where B: SerializeWith {
            Struct {
                a: &'a i8,
                #[serde(serialize_with = "SerializeWith::serialize_with")]
                b: B,
            },
        }
        "#,
        r#"
        #[derive(Deserialize)]
        struct DeserializeWithStruct<B> where B: DeserializeWith {
            a: i8,
            #[serde(deserialize_with = "DeserializeWith::deserialize_with")]
            b: B,
        }
        "#,
        r#"
        #[derive(Deserialize)]
        enum DeserializeWithEnum<B> where B: DeserializeWith {
            Struct {
                a: i8,
                #[serde(deserialize_with = "DeserializeWith::deserialize_with")]
                b: B,
            },
        }
        "#,
        r#"
        #[derive(Deserialize)]
        enum InvalidLengthEnum {
            A(i32, i32, i32),
            B(
            #[serde(skip_deserializing)]
            i32, i32, i32),
        }
        "#,
        r#"
        #[derive(Deserialize)]
        struct TupleStruct(i32, i32, i32);
        "#,
        r#"
        #[derive(Deserialize)]
        struct Struct {
            a: i32,
            b: i32,
            #[serde(skip_deserializing)]
            c: i32,
        }
        "#,
        r#"
        #[derive(Deserialize)]
        enum Enum {
            Unit,
            Simple(i32),
            Seq(i32, i32, i32),
            Map {
                a: i32,
                b: i32,
                c: i32,
            },
        }
        "#,
        r#"
        #[derive(Deserialize)]
        struct IgnoreBase {
            a: i32,
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        struct With<T> {
            t: T,
            #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
            x: X,
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        struct WithRef<'a, T: 'a> {
            #[serde(skip_deserializing)]
            t: Option<&'a T>,
            #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
            x: X,
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        struct PhantomX {
            x: PhantomData<X>,
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        struct PhantomT<T> {
            t: PhantomData<T>,
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        struct NoBounds<T> {
            t: T,
            option: Option<T>,
            boxed: Box<T>,
            option_boxed: Option<Box<T>>,
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        enum EnumWith<T> {
            Unit,
            Newtype(
                    #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
                    X),
            Tuple(T,
                #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
                X),
            Struct {
                t: T,
                #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
                x: X,
            },
        }
        "#,
        r#"
        #[derive(Serialize)]
        struct MultipleRef<'a, 'b, 'c, T> where T: 'c, 'c: 'b, 'b: 'a {
            t: T,
            rrrt: &'a &'b &'c T,
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        struct Newtype(
                    #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
                    X);
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        struct Tuple<T>(T,
                        #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
                        X);
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        enum TreeNode<D> {
            Split {
                left: Box<TreeNode<D>>,
                right: Box<TreeNode<D>>,
            },
            Leaf {
                data: D,
            },
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        struct ListNode<D> {
            data: D,
            next: Box<ListNode<D>>,
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        struct RecursiveA {
            b: Box<RecursiveB>,
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        enum RecursiveB { A(RecursiveA), }
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        struct RecursiveGenericA<T> {
            t: T,
            b: Box<RecursiveGenericB<T>>,
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        enum RecursiveGenericB<T> { T(T), A(RecursiveGenericA<T>), }
        "#,
        r#"
        #[derive(Serialize)]
        struct OptionStatic<'a> {
            a: Option<&'a str>,
            b: Option<&'static str>,
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[serde(bound = "D: SerializeWith + DeserializeWith")]
        #[derive(Deserialize)]
        struct WithTraits1<D, E> {
            #[serde(serialize_with = "SerializeWith::serialize_with",
                    deserialize_with = "DeserializeWith::deserialize_with")]
            d: D,
            #[serde(serialize_with = "SerializeWith::serialize_with",
                    deserialize_with = "DeserializeWith::deserialize_with",
                    bound = "E: SerializeWith + DeserializeWith")]
            e: E,
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[serde(bound(serialize = "D: SerializeWith",
                    deserialize = "D: DeserializeWith"))]
        #[derive(Deserialize)]
        struct WithTraits2<D, E> {
            #[serde(serialize_with = "SerializeWith::serialize_with",
                    deserialize_with = "DeserializeWith::deserialize_with")]
            d: D,
            #[serde(serialize_with = "SerializeWith::serialize_with",
                    bound(serialize = "E: SerializeWith"))]
            #[serde(deserialize_with = "DeserializeWith::deserialize_with",
                    bound(deserialize = "E: DeserializeWith"))]
            e: E,
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        struct CowStr<'a>(Cow<'a, str>);
        "#,
        r#"
        #[derive(Serialize)]
        #[serde(bound(deserialize = "T::Owned: Deserialize"))]
        #[derive(Deserialize)]
        struct CowT < 'a , T : ? Sized + 'a + ToOwned > ( Cow < 'a , T > ) ;
        "#,
        r#"
        #[derive(Serialize)]
        struct SerNamedTuple<'a, 'b, A: 'a, B: 'b, C>(&'a A, &'b mut B, C);
        "#,
        r#"
        #[derive(Deserialize)]
        struct DeNamedTuple<A, B, C>(A, B, C);
        "#,
        r#"
        #[derive(Serialize)]
        struct SerNamedMap<'a, 'b, A: 'a, B: 'b, C> {
            a: &'a A,
            b: &'b mut B,
            c: C,
        }
        "#,
        r#"
        #[derive(Deserialize)]
        struct DeNamedMap<A, B, C> {
            a: A,
            b: < Vec < T > as a :: b :: Trait > :: AssociatedItem,
            c: < Vec < T > > :: AssociatedItem,
        }
        "#,
        r#"
        #[derive(Serialize)]
        enum SerEnum<'a, B: 'a, C: 'a, D> where for < 'a > D: 'a {
            Unit,
            Seq(i8, B, &'a C, &'a mut D),
            Map {
                a: i8,
                b: B,
                c: &'a C,
                d: &'a mut D,
            },
            _Unit2,
            _Seq2(i8, B, &'a C, &'a mut D),
            _Map2 {
                a: i8,
                b: B,
                c: &'a C,
                d: &'a mut D,
            },
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        enum DeEnum<B, C, D> {
            Unit,
            Seq(i8, B, C, D),
            Map {
                a: i8,
                b: B,
                c: C,
                d: D,
            },
            _Unit2,
            _Seq2(i8, B, C, D),
            _Map2 {
                a: i8,
                b: B,
                c: C,
                d: D,
            },
        }
        "#,
        r#"
        #[derive(Serialize)]
        enum Lifetimes<'a> {
            LifetimeSeq(&'a i32),
            NoLifetimeSeq(i32),
            LifetimeMap {
                a: &'a i32,
            },
            NoLifetimeMap {
                a: i32,
            },
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        pub struct GenericStruct<T> {
            x: T,
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        pub struct GenericNewTypeStruct<T>(T);
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        pub struct GenericTupleStruct<T, U>(T, U);
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        pub enum GenericEnum<T, U: for < 'a > F<'a>> {
            Unit,
            NewType(T),
            Seq(T, U),
            Map {
                x: T,
                y: U,
            },
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        struct DefaultTyParam<T: AssociatedType<X = i32> = i32> {
            phantom: std :: marker :: PhantomData<T>,
        }
        "#,
        r#"
        #[derive(Serialize)]
        struct UnitStruct;
        "#,
        r#"
        #[derive(Serialize)]
        struct TupleStruct(i32, i32, i32);
        "#,
        r#"
        #[derive(Serialize)]
        struct Struct {
            a: i32,
            b: i32,
            c: i32,
        }
        "#,
        r#"
        #[derive(Serialize)]
        enum Enum {
            Unit,
            One(i32),
            Seq(i32, i32),
            Map {
                a: i32,
                b: i32,
            },
        }
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        struct Bounds<T: Serialize + Deserialize> {
            t: T,
            option: Option<T>,
            boxed: Box<T>,
            option_boxed: Option<Box<T>>,
        }
        "#,
        r#"
        #[derive(Deserialize)]
        #[rustc_copy_clone_marker]
        struct UnitStruct;
        "#,
        r#"
        #[derive(Serialize)]
        #[allow(dead_code)]
        #[deny(unused_variables)]
        enum Void { }
        "#,
        r#"
        #[derive(Serialize)]
        #[derive(Deserialize)]
        struct NamedUnit;
        "#,
    ];
}
<|endoftext|>


<commit_before><commit_msg>unbreak collections::vec::IntoIter::drop<commit_after><|endoftext|>


<commit_before><commit_msg>global tick will be stapled to game epoch<commit_after><|endoftext|>


<commit_before><commit_msg>Nicer formatting for DataProcessing instruction<commit_after><|endoftext|>


<commit_before><commit_msg>but and -> and<commit_after><|endoftext|>


<commit_before><commit_msg>Fix the description of --width and --height command-line options<commit_after><|endoftext|>