<commit_before>#![feature(std_misc, collections, core, exit_status, os, libc)]

extern crate libc;
extern crate rand;

use libc::funcs::posix88::unistd;
use std::ffi::CString;
use std::cmp;
use std::env;
use std::os;
use std::ptr;
use rand::Rng;

static VERSION: &'static str = "0.1.0";

fn main() {
    let args: Vec<String> = env::args().skip(1).collect();
    match parse_args(args.as_slice()) {
        Err(Exit::Usage) => {
            die_usage();
        }
        Err(Exit::Help) =>
            print_usage(),
        Err(Exit::Version) =>
            print_version(),
        Ok(opts) => {
            if whack(&opts) {
                env::set_exit_status(1);
            } else {
                opts.exe.map_or((), |exe| {
                    execvp(exe.name, exe.args)
                });
            }
        }
    }
}

type ArgParse<T> = Result<T, Exit>;

#[derive(Debug)]
struct Options<'a> {
    chance: i32,
    exe: Option<Exe<'a>>,
}

#[derive(Debug)]
struct Exe<'a> {
    name: &'a str,
    args: &'a[String],
}

#[derive(Debug)]
enum Exit {
    Usage,
    Help,
    Version,
}

fn parse_args(args: &[String]) -> ArgParse<Options> {
    args.uncons().map_or(Err(Exit::Usage), |(s, args)| {
        match s.as_slice() {
            "--help"    | "-h" => Err(Exit::Help),
            "--version" | "-v" => Err(Exit::Version),
            "--chance"  | "-c" => {
                args.uncons().map_or(Err(Exit::Usage), |(s, args)| {
                    s.parse().ok().map_or(Err(Exit::Usage), |val| {
                        args.skip("--").uncons().map_or(
                            Ok(Options {
                                chance: val,
                                exe: None
                            }), |(exe, args)| {
                                Ok(Options {
                                    chance: val,
                                    exe: Some(Exe {
                                        name: exe.as_slice(),
                                        args: args,
                                    })
                                })
                            })
                        })
                    })
                }
            _ => Err(Exit::Usage),
        }
    })
}

trait Uncons<'a, A> { fn uncons(&self) -> Option<(&'a A, &'a [A])>; }
trait Skip<'a, A, B> { fn skip(&self, x: A) -> &'a [B]; }

impl<'a, A> Uncons<'a, A> for &'a [A] {
    fn uncons(&self) -> Option<(&'a A, &'a [A])> {
        self.first().map(|x| (x, self.tail()))
    }
}

impl<'a > Skip<'a, &'a str, String> for &'a [String] {
    fn skip(&self, x: &'a str) -> &'a [String] {
        self.uncons().map_or(*self, |(y, ys)| { if x == y.as_slice() { ys } else { *self } })
    }
}

fn whack(opts: &Options) -> bool {
    rand::thread_rng().gen_range(0, 100) > cmp::min(cmp::max(opts.chance, 0), 100)
}

fn execvp(name: &str, args: &[String]) {
    let c_name = CString::new(name).unwrap(); // should be safe, the string is genuine
    let c_args: Vec<CString> =
        args.iter().map(|tmp| CString::new(tmp.as_slice()).unwrap()).collect(); // likewise

    let mut xs: Vec<*const libc::c_char> = Vec::with_capacity(args.len() + 2);

    xs.push(c_name.as_ptr());
    xs.extend(c_args.iter().map(|tmp| tmp.as_ptr()));
    xs.push(ptr::null());

    let c_arg0 = xs[0];
    let c_argv = xs.as_mut_ptr();

    unsafe {
        unistd::execvp(c_arg0, c_argv);
    };

    panic!("execvp(3) failed with: {}", os::last_os_error());
}

fn die_usage() {
    env::set_exit_status(1);
    print_usage();
}

fn print_usage() {
    print_version();
    println!("\n\
        Usage: whacky (-c PERCENTAGE|--chance PERCENTAGE) [[--] COMMAND]\n\
          whacky, yet another randomly failing program\n\
        \n\
        Available options:\n\
          -h,--help           show this help text\n\
          -c,--chance         set success chance");
}

fn print_version() {
    println!("whacky {}", VERSION);
}
<commit_msg>Eschew warnings<commit_after>#![feature(collections, core, exit_status, os, libc)]

extern crate libc;
extern crate rand;

use libc::funcs::posix88::unistd;
use std::ffi::CString;
use std::cmp;
use std::env;
use std::os;
use std::ptr;
use rand::Rng;

static VERSION: &'static str = "0.1.0";

fn main() {
    let args: Vec<String> = env::args().skip(1).collect();
    match parse_args(args.as_slice()) {
        Err(Exit::Usage) => {
            die_usage();
        }
        Err(Exit::Help) =>
            print_usage(),
        Err(Exit::Version) =>
            print_version(),
        Ok(opts) => {
            if whack(&opts) {
                env::set_exit_status(1);
            } else {
                opts.exe.map_or((), |exe| {
                    execvp(exe.name, exe.args)
                });
            }
        }
    }
}

type ArgParse<T> = Result<T, Exit>;

#[derive(Debug)]
struct Options<'a> {
    chance: i32,
    exe: Option<Exe<'a>>,
}

#[derive(Debug)]
struct Exe<'a> {
    name: &'a str,
    args: &'a[String],
}

#[derive(Debug)]
enum Exit {
    Usage,
    Help,
    Version,
}

fn parse_args(args: &[String]) -> ArgParse<Options> {
    args.uncons().map_or(Err(Exit::Usage), |(s, args)| {
        match s.as_slice() {
            "--help"    | "-h" => Err(Exit::Help),
            "--version" | "-v" => Err(Exit::Version),
            "--chance"  | "-c" => {
                args.uncons().map_or(Err(Exit::Usage), |(s, args)| {
                    s.parse().ok().map_or(Err(Exit::Usage), |val| {
                        args.skip("--").uncons().map_or(
                            Ok(Options {
                                chance: val,
                                exe: None
                            }), |(exe, args)| {
                                Ok(Options {
                                    chance: val,
                                    exe: Some(Exe {
                                        name: exe.as_slice(),
                                        args: args,
                                    })
                                })
                            })
                        })
                    })
                }
            _ => Err(Exit::Usage),
        }
    })
}

trait Uncons<'a, A> { fn uncons(&self) -> Option<(&'a A, &'a [A])>; }
trait Skip<'a, A, B> { fn skip(&self, x: A) -> &'a [B]; }

impl<'a, A> Uncons<'a, A> for &'a [A] {
    fn uncons(&self) -> Option<(&'a A, &'a [A])> {
        self.first().map(|x| (x, self.tail()))
    }
}

impl<'a > Skip<'a, &'a str, String> for &'a [String] {
    fn skip(&self, x: &'a str) -> &'a [String] {
        self.uncons().map_or(*self, |(y, ys)| { if x == y.as_slice() { ys } else { *self } })
    }
}

fn whack(opts: &Options) -> bool {
    rand::thread_rng().gen_range(0, 100) > cmp::min(cmp::max(opts.chance, 0), 100)
}

fn execvp(name: &str, args: &[String]) {
    let c_name = CString::new(name).unwrap(); // should be safe, the string is genuine
    let c_args: Vec<CString> =
        args.iter().map(|tmp| CString::new(tmp.as_slice()).unwrap()).collect(); // likewise

    let mut xs: Vec<*const libc::c_char> = Vec::with_capacity(args.len() + 2);

    xs.push(c_name.as_ptr());
    xs.extend(c_args.iter().map(|tmp| tmp.as_ptr()));
    xs.push(ptr::null());

    let c_arg0 = xs[0];
    let c_argv = xs.as_mut_ptr();

    unsafe {
        unistd::execvp(c_arg0, c_argv);
    };

    panic!("execvp(3) failed with: {}", os::last_os_error());
}

fn die_usage() {
    env::set_exit_status(1);
    print_usage();
}

fn print_usage() {
    print_version();
    println!("\n\
        Usage: whacky (-c PERCENTAGE|--chance PERCENTAGE) [[--] COMMAND]\n\
          whacky, yet another randomly failing program\n\
        \n\
        Available options:\n\
          -h,--help           show this help text\n\
          -c,--chance         set success chance");
}

fn print_version() {
    println!("whacky {}", VERSION);
}
<|endoftext|>


<commit_before>// Copyright 2015-2016 Intecture Developers. See the COPYRIGHT file at the
// top-level directory of this distribution and at
// https://intecture.io/COPYRIGHT.
//
// Licensed under the Mozilla Public License 2.0 <LICENSE or
// https://www.tldrlegal.com/l/mpl-2.0>. This file may not be copied,
// modified, or distributed except according to those terms.

extern crate czmq;
extern crate docopt;
extern crate rustc_serialize;
#[cfg(test)]
extern crate tempdir;
extern crate time;
extern crate zdaemon;

mod auth;
mod cert;
mod config;
mod error;
mod language;
mod project;

use auth::Auth;
use docopt::Docopt;
use error::Result;
use project::Project;
use std::{env, io};
use std::error::Error;
use std::path::Path;
use std::process::exit;

const VERSION: &'static str = "0.1.0";

static USAGE: &'static str = "
Intecture CLI.

Usage:
  incli [(-v | --verbose)] run [<arg>...]
  incli [(-v | --verbose)] init [(-b | --blank)] (<name> <lang>)
  incli [(-v | --verbose)] host (add | delete | bootstrap) <hostname>
  incli [(-v | --verbose)] host list
  incli [(-v | --verbose)] user (add | delete) <username>
  incli [(-v | --verbose)] user list
  incli (-h | --help)
  incli --version

Options:
  -b --blank    Create a blank project.
  -h --help     Show this screen.
  -v --verbose  Verbose output.
  --version     Show version.
";

#[derive(Debug, RustcDecodable)]
struct Args {
    cmd_add: bool,
    cmd_bootstrap: bool,
    cmd_delete: bool,
    cmd_host: bool,
    cmd_init: bool,
    cmd_list: bool,
    cmd_run: bool,
    cmd_user: bool,
    flag_h: bool,
    flag_help: bool,
    flag_v: bool,
    flag_verbose: bool,
    flag_b: bool,
    flag_blank: bool,
    flag_version: bool,
    arg_arg: Vec<String>,
    arg_name: String,
    arg_lang: String,
    arg_hostname: String,
    arg_username: String,
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());

    if args.flag_version {
        println!("{}", VERSION);
    }
    else if args.cmd_run {
        let project = try_exit(Project::load(&mut env::current_dir().unwrap()), args.flag_v || args.flag_verbose);
        try_exit(project.run(&args.arg_arg), args.flag_v || args.flag_verbose);
    }
    else if args.cmd_init {
        try_exit(Project::create(&Path::new(&args.arg_name), &args.arg_lang, args.flag_b || args.flag_blank), args.flag_v || args.flag_verbose);
    }
    else if args.cmd_host || args.cmd_user {
        let cert_type = if args.cmd_host { "host" } else { "user" };
        let name = if args.cmd_host { &args.arg_hostname } else { &args.arg_username };

        let auth = try_exit(Auth::new(&env::current_dir().unwrap()), args.flag_v || args.flag_verbose);

        if args.cmd_add {
            let cert = try_exit(auth.add(cert_type, name), args.flag_v || args.flag_verbose);
            println!("Please distribute this certificate securely.

------------------------COPY BELOW THIS LINE-------------------------
{}
------------------------COPY ABOVE THIS LINE-------------------------", cert.public());
        }
        else if args.cmd_delete {
            println!("Are you sure you want to delete this certificate?");
            loop {
                println!("Please enter [y/n]: ");
                let mut input = String::new();
                match io::stdin().read_line(&mut input) {
                    Ok(_) => match { input.as_ref() as &str }.trim() {
                        "y" => {
                            try_exit(auth.delete(name), args.flag_v || args.flag_verbose);
                            break;
                        },
                        "n" => break,
                        _ => (),
                    },
                    Err(e) => {
                        println!("Stdin error: {}", e);
                        exit(1);
                    },
                }
            }
        }
        else if args.cmd_list {
            let names = try_exit(auth.list(cert_type), args.flag_v || args.flag_verbose);

            for name in names {
                println!("{}", name);
            }
        }
        else if args.cmd_bootstrap && args.cmd_host {
            unimplemented!();
        }
    }
}

fn try_exit<T>(r: Result<T>, verbose: bool) -> T {
    if let Err(e) = r {
        println!("{}", e);

        if verbose {
            println!("{:?}", e.cause());
        }

        exit(1);
    }

    r.unwrap()
}
<commit_msg>Remove unnecessary verbose flag from usage<commit_after>// Copyright 2015-2016 Intecture Developers. See the COPYRIGHT file at the
// top-level directory of this distribution and at
// https://intecture.io/COPYRIGHT.
//
// Licensed under the Mozilla Public License 2.0 <LICENSE or
// https://www.tldrlegal.com/l/mpl-2.0>. This file may not be copied,
// modified, or distributed except according to those terms.

extern crate czmq;
extern crate docopt;
extern crate rustc_serialize;
#[cfg(test)]
extern crate tempdir;
extern crate time;
extern crate zdaemon;

mod auth;
mod cert;
mod config;
mod error;
mod language;
mod project;

use auth::Auth;
use docopt::Docopt;
use error::Result;
use project::Project;
use std::{env, io};
use std::error::Error;
use std::path::Path;
use std::process::exit;

const VERSION: &'static str = "0.1.0";

static USAGE: &'static str = "
Intecture CLI.

Usage:
  incli run [<arg>...]
  incli init [(-b | --blank)] (<name> <lang>)
  incli host (add | delete | bootstrap) <hostname>
  incli host list
  incli user (add | delete) <username>
  incli user list
  incli (-h | --help)
  incli --version

Options:
  -b --blank    Create a blank project.
  -h --help     Show this screen.
  -v --verbose  Verbose output.
  --version     Show version.
";

#[derive(Debug, RustcDecodable)]
struct Args {
    cmd_add: bool,
    cmd_bootstrap: bool,
    cmd_delete: bool,
    cmd_host: bool,
    cmd_init: bool,
    cmd_list: bool,
    cmd_run: bool,
    cmd_user: bool,
    flag_h: bool,
    flag_help: bool,
    flag_v: bool,
    flag_verbose: bool,
    flag_b: bool,
    flag_blank: bool,
    flag_version: bool,
    arg_arg: Vec<String>,
    arg_name: String,
    arg_lang: String,
    arg_hostname: String,
    arg_username: String,
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());

    if args.flag_version {
        println!("{}", VERSION);
    }
    else if args.cmd_run {
        let project = try_exit(Project::load(&mut env::current_dir().unwrap()), args.flag_v || args.flag_verbose);
        try_exit(project.run(&args.arg_arg), args.flag_v || args.flag_verbose);
    }
    else if args.cmd_init {
        try_exit(Project::create(&Path::new(&args.arg_name), &args.arg_lang, args.flag_b || args.flag_blank), args.flag_v || args.flag_verbose);
    }
    else if args.cmd_host || args.cmd_user {
        let cert_type = if args.cmd_host { "host" } else { "user" };
        let name = if args.cmd_host { &args.arg_hostname } else { &args.arg_username };

        let auth = try_exit(Auth::new(&env::current_dir().unwrap()), args.flag_v || args.flag_verbose);

        if args.cmd_add {
            let cert = try_exit(auth.add(cert_type, name), args.flag_v || args.flag_verbose);
            println!("Please distribute this certificate securely.

------------------------COPY BELOW THIS LINE-------------------------
{}
------------------------COPY ABOVE THIS LINE-------------------------", cert.public());
        }
        else if args.cmd_delete {
            println!("Are you sure you want to delete this certificate?");
            loop {
                println!("Please enter [y/n]: ");
                let mut input = String::new();
                match io::stdin().read_line(&mut input) {
                    Ok(_) => match { input.as_ref() as &str }.trim() {
                        "y" => {
                            try_exit(auth.delete(name), args.flag_v || args.flag_verbose);
                            break;
                        },
                        "n" => break,
                        _ => (),
                    },
                    Err(e) => {
                        println!("Stdin error: {}", e);
                        exit(1);
                    },
                }
            }
        }
        else if args.cmd_list {
            let names = try_exit(auth.list(cert_type), args.flag_v || args.flag_verbose);

            for name in names {
                println!("{}", name);
            }
        }
        else if args.cmd_bootstrap && args.cmd_host {
            unimplemented!();
        }
    }
}

fn try_exit<T>(r: Result<T>, verbose: bool) -> T {
    if let Err(e) = r {
        println!("{}", e);

        if verbose {
            println!("{:?}", e.cause());
        }

        exit(1);
    }

    r.unwrap()
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate log;
extern crate fern;
extern crate uuid;
extern crate hyper;
extern crate url;
extern crate rustc_serialize;
extern crate websocket;
extern crate rustbox;
extern crate time;

mod game;
mod ui;
mod lila;

fn main() {
    let _session = lila::Session::sign_in("username".to_owned(), "passwordlol".to_owned()).unwrap();
    setup_logger(true);
    debug!("Init");
    let session = lila::Session::anonymous();
    let mut ui = ui::UI::new(session);
    ui.start();
    debug!("Exit");
}

// levels: trace, debug, info, warn, error
fn setup_logger(debug: bool) {
    let output = vec![fern::OutputConfig::file("./liru.log")];
    let level = match debug {
        true  => log::LogLevelFilter::Debug,
        false => log::LogLevelFilter::Warn,
    };

    let config = fern::DispatchConfig {
        format: Box::new(|msg, level, location| {
            let now = time::now_utc();
            format!("{}.{}Z [{}] [{}] {}",
                    now.strftime("%Y-%m-%dT%H:%M:%S").unwrap(), now.tm_nsec,
                    level, location.module_path(), msg)
        }),
        output: output,
        level: level,
    };

    if let Err(e) = fern::init_global_logger(config, log::LogLevelFilter::Trace) {
        println!("Failed to initialize global logger: {}", e);
    };
}
<commit_msg>allow sign in without recomplie :) fixes #2<commit_after>#[macro_use]
extern crate log;
extern crate fern;
extern crate uuid;
extern crate hyper;
extern crate url;
extern crate rustc_serialize;
extern crate websocket;
extern crate rustbox;
extern crate time;

use std::io;
use std::io::Write;

mod game;
mod ui;
mod lila;

fn main() {
    let session = setup_session("Press Enter for anonymous");
    //setup_logger(matches.is_present("debug"));
    setup_logger(true);
    debug!("Init");
    let mut ui = ui::UI::new(session);
    ui.start();
    debug!("Exit");
}

/// Recursively asks for valid credentials
/// or using anonymous with blank username
fn setup_session(message: &str) -> lila::Session {
    println!("{}", message);
    match acquire("Username") {
        ref u if u.is_empty() => lila::Session::anonymous(),
        username =>
            lila::Session::sign_in(username, acquire("Password"))
            .unwrap_or_else(|e| setup_session(e))
    }
}

/// Prints first argument to stdout and
/// expects the user to input one line,
/// which is returned excluding newline
fn acquire(what: &str) -> String {
    print!("{}: ", what);
    io::stdout().flush().unwrap();
    let mut input = String::new();
    io::stdin().read_line(&mut input).unwrap();
    input.pop();
    input
}

// levels: trace, debug, info, warn, error
fn setup_logger(debug: bool) {
    let output = vec![fern::OutputConfig::file("./liru.log")];
    let level = match debug {
        true  => log::LogLevelFilter::Debug,
        false => log::LogLevelFilter::Warn,
    };

    let config = fern::DispatchConfig {
        format: Box::new(|msg, level, location| {
            let now = time::now_utc();
            format!("{}.{}Z [{}] [{}] {}",
                    now.strftime("%Y-%m-%dT%H:%M:%S").unwrap(), now.tm_nsec,
                    level, location.module_path(), msg)
        }),
        output: output,
        level: level,
    };

    if let Err(e) = fern::init_global_logger(config, log::LogLevelFilter::Trace) {
        println!("Failed to initialize global logger: {}", e);
    };
}
<|endoftext|>


<commit_before>use std::env;
use std::io::prelude::*;
use std::fs::File;
use std::path::PathBuf;
extern crate uuid;
use uuid::Uuid;
extern crate getopts;
use getopts::Options;
use std::io;

fn print_usage(program: &str, opts: Options) {
    let path = PathBuf::from(program);
    let command = path.file_name().unwrap().to_string_lossy();

    let brief = format!("Usage: {} FILE [options]", command);
    let info = "Safely rewrite contents of FILE with stdin, even\nwhere FILE is being read by \
                upstream command";
    print!("{}", opts.usage(&[&brief, info].join("\n")));
}

fn redirect_to_file(outfile: &str) -> Result<(), io::Error> {
    // create the temporary file in the same directory as outfile
    // this lets us guarantee a rename (instead of a move) on completion
    let mut tempfile = PathBuf::from(outfile);
    tempfile.pop(); //now refers to parent, which might be nothing
    tempfile.push(Uuid::new_v4().hyphenated().to_string());
    // println!("{}", tempfile.display());

    {
        let mut buffer = [0; 512];
        let mut stdin = io::stdin();
        let mut f = File::create(&tempfile).expect("Failed to create temporary file!");

        loop {
            let read_bytes = stdin.read(&mut buffer).expect("Error reading from stdin!");
            if read_bytes == 0 {
                break;
            }

            let write_bytes = f.write(&buffer[0..read_bytes])
                .expect("Failed to write to temporary file!");

            assert!(write_bytes == read_bytes);
        }
    }

    match std::fs::rename(&tempfile, &outfile) {
        Ok(m) => m,
        _ => {
            // fs::rename does not support cross-device linking
            // copy and delete instead
            std::fs::copy(&tempfile, &outfile).expect("Failed to create output file!");
            std::fs::remove_file(&tempfile)
                .unwrap_or_else(|e| print!("Failed to delete temporary file!\n{:?}", e));
        }
    };

    return Ok(());
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let mut opts = Options::new();
    opts.optflag("h", "help", "prints this help info");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string()),
    };
    if matches.opt_present("h") {
        print_usage(&program, opts);
        return;
    }
    let infile = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        print_usage(&program, opts);
        return;
    };

    assert!(redirect_to_file(&infile).is_ok());
}
<commit_msg>Macro to print nicer error messages<commit_after>use std::env;
use std::io::prelude::*;
use std::fs::File;
use std::path::PathBuf;
extern crate uuid;
use uuid::Uuid;
extern crate getopts;
use getopts::Options;
use std::io;

macro_rules! exit_with_exception {
	($error:ident, $extra:tt) => {
		let _ = write!(&mut std::io::stderr(), "{}\n", $extra);
		let _ = write!(&mut std::io::stderr(), "{}\n", $error);
		std::process::exit(-1);
	};
}

fn print_usage(program: &str, opts: Options, include_info: bool) {
    let path = PathBuf::from(program);
    let command = path.file_name().unwrap().to_string_lossy();

    let brief = format!("Usage: {} FILE [options]", command);
    let info = "Safely rewrite contents of FILE with stdin, even where FILE is being read by \
                upstream command";
    let full = &[&brief, info];
    if include_info {
        print!("{}", opts.usage(&full.join("\n")));
    } else {
        print!("{}", opts.usage(&brief));
    }
}

fn redirect_to_file(outfile: &str) -> Result<(), &str> {
    // create the temporary file in the same directory as outfile
    // this lets us guarantee a rename (instead of a move) on completion
    let mut tempfile = PathBuf::from(outfile);
    tempfile.pop(); //now refers to parent, which might be nothing
    tempfile.push(Uuid::new_v4().hyphenated().to_string());
    // println!("{}", tempfile.display());

    {
        let mut buffer = [0; 512];
        let mut stdin = io::stdin();
        let mut f = File::create(&tempfile).unwrap_or_else(|e| {
            exit_with_exception!(e, "Failed to create output file!");
        });

        loop {
            let read_bytes = stdin.read(&mut buffer).unwrap_or_else(|e| {
                exit_with_exception!(e, "Error reading from stdin!");
            });
            if read_bytes == 0 {
                break;
            }

            let write_bytes = f.write(&buffer[0..read_bytes]).unwrap_or_else(|e| {
                exit_with_exception!(e, "Failed to write to temporary file!");
            });

            assert!(write_bytes == read_bytes);
        }
    }

    std::fs::rename(&tempfile, &outfile).unwrap_or_else(|_x| {
        // fs::rename does not support cross-device linking
        // copy and delete instead
        std::fs::copy(&tempfile, &outfile).unwrap_or_else(|e| {
            exit_with_exception!(e, "Failed to create output file!");
        });
        std::fs::remove_file(&tempfile).unwrap_or_else(|e| {
            exit_with_exception!(e, "Failed to delete temporary file!");
        });
    });

    return Ok(());
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let mut opts = Options::new();
    opts.optflag("h", "help", "prints this help info");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(e) => {
            print!("{}\n", e);
            print_usage(&program, opts, false);
            return;
        }
    };
    if matches.opt_present("h") {
        print_usage(&program, opts, true);
        return;
    }
    let infile = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        print_usage(&program, opts, true);
        return;
    };

    assert!(redirect_to_file(&infile).is_ok());
}
<|endoftext|>


<commit_before>// Copyright 2015 Gomez Guillaume
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::fs::{self, File, OpenOptions};
use std::io::{BufRead, Write, Read};
use std::fmt::{Display, Formatter, Error};
use std::ops::Deref;

enum EventType {
    Comment(String),
    FileComment(String),
    Type(TypeStruct),
    InScope,
    OutScope,
}

struct TypeStruct {
    ty: Type,
    parent: Option<Box<TypeStruct>>,
    name: String,
    args: Vec<String>,
}

impl TypeStruct {
    fn new(ty: Type, name: &str) -> TypeStruct {
        TypeStruct {
            ty: ty,
            name: name.to_owned(),
            args: vec!(),
            parent: None,
        }
    }

    fn from_args(ty: Type, args: Vec<String>) -> TypeStruct {
        TypeStruct {
            ty: ty,
            name: String::new(),
            args: args,
            parent: None,
        }
    }

    fn empty() -> TypeStruct {
        TypeStruct {
            ty: Type::Unknown,
            name: String::new(),
            args: Vec::new(),
            parent: None,
        }
    }
}

impl Clone for TypeStruct {
    fn clone(&self) -> TypeStruct {
        TypeStruct {
            ty: self.ty,
            name: self.name.clone(),
            args: self.args.clone(),
            parent: match self.parent {
                Some(ref p) => Some(Box::new(p.deref().clone())),
                None => None,
            }
        }
    }

    fn clone_from(&mut self, source: &TypeStruct) {
        self.ty = source.ty;
        self.name = source.name.clone();
        self.args = source.args.clone();
        self.parent = match source.parent {
            Some(ref p) => Some(Box::new(p.deref().clone())),
            None => None,
        };
    }
}

impl Display for TypeStruct {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        let parent = &self.parent;
        match parent {
            &Some(ref p) => write!(f, "{}({} {}{})", p, self.ty, self.name, self.args.join(" ")),
            &None => write!(f, "{} {}{}", self.ty, self.name, self.args.join(" ")),
        }
    }
}

#[derive(Debug, Copy, Clone, PartialEq)]
enum Type {
    Struct,
    Mod,
    Enum,
    Fn,
    Const,
    Static,
    Type,
    Variant,
    Impl,
    Use,
    Macro,
    Trait,
    Unknown,
}

impl Type {
    fn from(s: &str) -> Type {
        match s {
            "struct" => Type::Struct,
            "mod" => Type::Mod,
            "enum" => Type::Enum,
            "fn" => Type::Fn,
            "const" => Type::Const,
            "static" => Type::Static,
            "type" => Type::Type,
            "impl" => Type::Impl,
            "use" => Type::Use,
            "trait" => Type::Trait,
            "macro" | "macro_rules" | "macro_rules!" => Type::Macro,
            _ => Type::Variant,
        }
    }
}

impl Display for Type {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        match *self {
            Type::Struct => write!(f, "struct"),
            Type::Mod => write!(f, "mod"),
            Type::Enum => write!(f, "enum"),
            Type::Fn => write!(f, "fn"),
            Type::Const => write!(f, "const"),
            Type::Static => write!(f, "static"),
            Type::Type => write!(f, "type"),
            Type::Variant => write!(f, "variant"),
            Type::Impl => write!(f, "impl"),
            Type::Use => write!(f, "use"),
            Type::Trait => write!(f, "trait"),
            Type::Macro => write!(f, "macro"),
            _ => write!(f, "?"),
        }
    }
}

fn loop_over_files(path: &str, f: &mut File) {
    match fs::read_dir(path) {
        Ok(it) => {
            for entry in it {
                check_path_type(entry.unwrap().path().to_str().unwrap(), f);
            }
        }
        Err(e) => {
            println!("Error while trying to iterate over {}: {}", path, e);
        }
    }
}

fn move_to(words: &[&str], it: &mut usize, limit: &str, line: &mut usize) {
    while (*it + 1) < words.len() && limit.contains(words[*it + 1]) == false {
        if words[*it] == "\n" {
            *line += 1;
        }
        *it += 1;
    }
    if words[*it] == "\n" {
        *line += 1;
    }
}

fn move_until(words: &[&str], it: &mut usize, limit: &str, line: &mut usize) {
    while (*it + 1) < words.len() && limit != words[*it] {
        if words[*it] == "\n" {
            *line += 1;
        }
        *it += 1;
    }
}

fn get_impl(words: &[&str], it: &mut usize, line: &mut usize) -> Vec<String> {
    let mut v = vec!();

    while (*it + 1) < words.len() {
        if words[*it] == "\n" {
            *line += 1;
        }
        if words[(*it + 1)] == "{" || words[(*it + 1)] == ";" {
            break;
        }
        *it += 1;
        v.push(words[*it].to_owned());
    }
    v
}

fn add_to_type_scope(current: &Option<TypeStruct>, e: &Option<TypeStruct>) -> Option<TypeStruct> {
    match current {
        &Some(ref c) => {
            match e {
                &Some(ref t) => {
                    let mut tmp = t.clone();
                    tmp.parent = Some(Box::new(c.clone()));
                    Some(tmp)
                }
                &None => {
                    let mut tmp = TypeStruct::empty();
                    tmp.parent = Some(Box::new(c.clone()));
                    Some(tmp)
                }
            }
        },
        &None => match e {
            &Some(ref t) => Some(t.clone()),
            &None => None,
        }
    }
}

fn type_out_scope(current: &Option<TypeStruct>) -> Option<TypeStruct> {
    match current {
        &Some(ref c) => match c.parent {
            Some(ref p) => Some(p.deref().clone()),
            None => None,
        },
        &None => None,
    }
}

fn strip_comments(path: &str, out_file: &mut File) {
    match File::open(path) {
        Ok(mut f) => {
            let mut b_content = String::new();
            f.read_to_string(&mut b_content).unwrap();
            let content = b_content.replace("{", " { ")
                                   .replace("}", " } ")
                                   .replace("///", "/// ")
                                   .replace("//!", "//! ")
                                   .replace("/*!", "/*! ")
                                   .replace(":", " : ")
                                   .replace("*/", " */")
                                   .replace("\n", " \n ")
                                   .replace("!(", " !! (")
                                   .replace(",", ", ")
                                   .replace("(", " (");
            let b_content : Vec<&str> = b_content.split('\n').collect();
            let words : Vec<&str> = content.split(' ').filter(|s| s.len() > 0).collect();
            let mut it = 0;
            let mut line = 0;
            let mut event_list = vec!();
            let mut comments = 0;

            while it < words.len() {
                match words[it] {
                    "///" => {
                        event_list.push(EventType::Comment(b_content[line].to_owned()));
                        move_to(&words, &mut it, "\n", &mut line);
                        comments += 1;
                    }
                    "//!" => {
                        event_list.push(EventType::FileComment(b_content[line].to_owned()));
                        move_to(&words, &mut it, "\n", &mut line);
                        comments += 1;
                    }
                    "/*!" => {
                        let mark = line;
                        move_until(&words, &mut it, "*/", &mut line);
                        for pos in mark..line {
                            event_list.push(EventType::FileComment(b_content[pos].to_owned()));
                        }
                        event_list.push(EventType::FileComment("*/".to_owned()));
                        comments += 1;
                    }
                    "struct" | "mod" | "fn" | "enum" | "const" | "static" | "type" | "use" | "trait" | "macro_rules!" => {
                        event_list.push(EventType::Type(TypeStruct::new(Type::from(words[it]), words[it + 1])));
                        it += 1;
                    }
                    "!!" => {
                        event_list.push(EventType::Type(TypeStruct::new(Type::from("macro"), &format!("{}!{}", words[it - 1], words[it + 1]))));
                        it += 1;
                    }
                    "impl" => {
                        event_list.push(EventType::Type(TypeStruct::from_args(Type::Impl, get_impl(&words, &mut it, &mut line))));
                    }
                    "{" => {
                        event_list.push(EventType::InScope);
                    }
                    "}" => {
                        event_list.push(EventType::OutScope);
                    }
                    "\n" => {
                        line += 1;
                    }
                    _ => {
                        event_list.push(EventType::Type(TypeStruct::new(Type::Unknown, words[it])));
                    }
                }
                it += 1;
            }
            if comments < 1 {
                return;
            }
            writeln!(out_file, "=! {}", path).unwrap();
            let mut current : Option<TypeStruct> = None;
            let mut waiting_type : Option<TypeStruct> = None;

            it = 0;
            while it < event_list.len() {
                match event_list[it] {
                    EventType::Type(ref t) => {
                        if t.ty != Type::Unknown {
                            waiting_type = Some(t.clone());
                            //println!("current : {}", t);
                        }
                    }
                    EventType::InScope => {
                        current = add_to_type_scope(&current, &waiting_type);
                        /*if waiting_type.is_some() {
                            println!("in : {}", waiting_type.unwrap());
                        }*/
                        waiting_type = None;
                    }
                    EventType::OutScope => {
                        /*if current.is_some() {
                            println!("out : {}", current.clone().unwrap());
                        }*/
                        current = type_out_scope(&current);
                        waiting_type = None;
                    }
                    EventType::FileComment(ref c) => {
                        let mut comments = format!("=/ {}\n", c);

                        it += 1;
                        while match event_list[it] {
                            EventType::FileComment(ref c) => {
                                comments.push_str(&format!("=/ {}\n", c));
                                true
                            }
                            _ => false,
                        } {
                            it += 1;
                        }
                        write!(out_file, "{}", comments).unwrap();
                    }
                    EventType::Comment(ref c) => {
                        let mut comments = format!("{}\n", c);

                        it += 1;
                        while match event_list[it] {
                            EventType::Comment(ref c) => {
                                comments.push_str(&format!("{}\n", c));
                                true
                            }
                            EventType::Type(_) => {
                                false
                            }
                            _ => panic!("Comments cannot be written everywhere"),
                        } {
                            it += 1;
                        }
                        while match event_list[it] {
                            EventType::Type(ref t) => {
                                match t.ty {
                                    Type::Unknown => {
                                        match current {
                                            Some(ref cur) => {
                                                if cur.ty == Type::Enum || cur.ty == Type::Struct || cur.ty == Type::Use {
                                                    if t.name == "pub" {
                                                        true
                                                    } else {
                                                        let mut copy = t.clone();
                                                        copy.ty = Type::Variant;
                                                        let tmp = add_to_type_scope(&current, &Some(copy));
                                                        write!(out_file, "=| {}\n{}", tmp.unwrap(), comments).unwrap();
                                                        false
                                                    }
                                                } else {
                                                    false
                                                }
                                            }
                                            None => false,
                                        }
                                    },
                                    _ => {
                                        let tmp = add_to_type_scope(&current, &Some(t.clone()));
                                        write!(out_file, "=| {}\n{}", tmp.unwrap(), comments).unwrap();
                                        false
                                    }
                                }
                            }
                            _ => panic!("An item was expected for this comment: {}", comments),
                        } {
                            it += 1;
                        }
                        it -= 1;
                    }
                }
                it += 1;
            }
        }
        Err(e) => {
            println!("Unable to open \"{}\": {}", path, e);
        }
    }
}

fn check_path_type(path: &str, f: &mut File) {
    match fs::metadata(path) {
        Ok(m) => {
            if m.is_dir() {
                if path == ".." || path == "." {
                    return;
                }
                loop_over_files(path, f);
            } else {
                if path == "./comments.cmts" {
                    return;
                }
                println!("-> {}", path);
                strip_comments(path, f);
            }
        }
        Err(e) => {
            println!("An error occurred: {}", e);
        }
    }
}

fn main() {
    println!("Starting...");
    match fs::remove_file("comments.cmts") { _ => {} }
    match OpenOptions::new().write(true).create(true).truncate(true).open("comments.cmts") {
        Ok(mut f) => {
            loop_over_files(".", &mut f);
            /*for com_entry in comments {
                write!(f, "{}", com_entry).unwrap();
            }*/
            println!("Done !");
        }
        Err(e) => {
            println!("Error while opening \"{}\": {}", "comments.cmts", e);
        }
    }
}

// au lieu de splitter le fichier via '\n', lis le sur "une seule ligne".
// quand tu croises un "///", tu stockes ça comme un commentaire, un "mod", comme un module, etc...
// il faudra compter les '{' / '}' pour voir si t'es toujours danns le truc courant ou non<commit_msg>Change hierarchiaation<commit_after>// Copyright 2015 Gomez Guillaume
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::fs::{self, File, OpenOptions};
use std::io::{BufRead, Write, Read};
use std::fmt::{Display, Formatter, Error};
use std::ops::Deref;

enum EventType {
    Comment(String),
    FileComment(String),
    Type(TypeStruct),
    InScope,
    OutScope,
}

struct TypeStruct {
    ty: Type,
    parent: Option<Box<TypeStruct>>,
    name: String,
    args: Vec<String>,
}

impl TypeStruct {
    fn new(ty: Type, name: &str) -> TypeStruct {
        TypeStruct {
            ty: ty,
            name: name.to_owned(),
            args: vec!(),
            parent: None,
        }
    }

    fn from_args(ty: Type, args: Vec<String>) -> TypeStruct {
        TypeStruct {
            ty: ty,
            name: String::new(),
            args: args,
            parent: None,
        }
    }

    fn empty() -> TypeStruct {
        TypeStruct {
            ty: Type::Unknown,
            name: String::new(),
            args: Vec::new(),
            parent: None,
        }
    }
}

impl Clone for TypeStruct {
    fn clone(&self) -> TypeStruct {
        TypeStruct {
            ty: self.ty,
            name: self.name.clone(),
            args: self.args.clone(),
            parent: match self.parent {
                Some(ref p) => Some(Box::new(p.deref().clone())),
                None => None,
            }
        }
    }

    fn clone_from(&mut self, source: &TypeStruct) {
        self.ty = source.ty;
        self.name = source.name.clone();
        self.args = source.args.clone();
        self.parent = match source.parent {
            Some(ref p) => Some(Box::new(p.deref().clone())),
            None => None,
        };
    }
}

impl Display for TypeStruct {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        let parent = &self.parent;
        match parent {
            &Some(ref p) => write!(f, "{}>{} {}{}", p, self.ty, self.name, self.args.join(" ")),
            &None => write!(f, "{} {}{}", self.ty, self.name, self.args.join(" ")),
        }
    }
}

#[derive(Debug, Copy, Clone, PartialEq)]
enum Type {
    Struct,
    Mod,
    Enum,
    Fn,
    Const,
    Static,
    Type,
    Variant,
    Impl,
    Use,
    Macro,
    Trait,
    Unknown,
}

impl Type {
    fn from(s: &str) -> Type {
        match s {
            "struct" => Type::Struct,
            "mod" => Type::Mod,
            "enum" => Type::Enum,
            "fn" => Type::Fn,
            "const" => Type::Const,
            "static" => Type::Static,
            "type" => Type::Type,
            "impl" => Type::Impl,
            "use" => Type::Use,
            "trait" => Type::Trait,
            "macro" | "macro_rules" | "macro_rules!" => Type::Macro,
            _ => Type::Variant,
        }
    }
}

impl Display for Type {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        match *self {
            Type::Struct => write!(f, "struct"),
            Type::Mod => write!(f, "mod"),
            Type::Enum => write!(f, "enum"),
            Type::Fn => write!(f, "fn"),
            Type::Const => write!(f, "const"),
            Type::Static => write!(f, "static"),
            Type::Type => write!(f, "type"),
            Type::Variant => write!(f, "variant"),
            Type::Impl => write!(f, "impl"),
            Type::Use => write!(f, "use"),
            Type::Trait => write!(f, "trait"),
            Type::Macro => write!(f, "macro"),
            _ => write!(f, "?"),
        }
    }
}

fn loop_over_files(path: &str, f: &mut File) {
    match fs::read_dir(path) {
        Ok(it) => {
            for entry in it {
                check_path_type(entry.unwrap().path().to_str().unwrap(), f);
            }
        }
        Err(e) => {
            println!("Error while trying to iterate over {}: {}", path, e);
        }
    }
}

fn move_to(words: &[&str], it: &mut usize, limit: &str, line: &mut usize) {
    while (*it + 1) < words.len() && limit.contains(words[*it + 1]) == false {
        if words[*it] == "\n" {
            *line += 1;
        }
        *it += 1;
    }
    if words[*it] == "\n" {
        *line += 1;
    }
}

fn move_until(words: &[&str], it: &mut usize, limit: &str, line: &mut usize) {
    while (*it + 1) < words.len() && limit != words[*it] {
        if words[*it] == "\n" {
            *line += 1;
        }
        *it += 1;
    }
}

fn get_impl(words: &[&str], it: &mut usize, line: &mut usize) -> Vec<String> {
    let mut v = vec!();

    while (*it + 1) < words.len() {
        if words[*it] == "\n" {
            *line += 1;
        }
        if words[(*it + 1)] == "{" || words[(*it + 1)] == ";" {
            break;
        }
        *it += 1;
        v.push(words[*it].to_owned());
    }
    v
}

fn add_to_type_scope(current: &Option<TypeStruct>, e: &Option<TypeStruct>) -> Option<TypeStruct> {
    match current {
        &Some(ref c) => {
            match e {
                &Some(ref t) => {
                    let mut tmp = t.clone();
                    tmp.parent = Some(Box::new(c.clone()));
                    Some(tmp)
                }
                &None => {
                    let mut tmp = TypeStruct::empty();
                    tmp.parent = Some(Box::new(c.clone()));
                    Some(tmp)
                }
            }
        },
        &None => match e {
            &Some(ref t) => Some(t.clone()),
            &None => None,
        }
    }
}

fn type_out_scope(current: &Option<TypeStruct>) -> Option<TypeStruct> {
    match current {
        &Some(ref c) => match c.parent {
            Some(ref p) => Some(p.deref().clone()),
            None => None,
        },
        &None => None,
    }
}

fn strip_comments(path: &str, out_file: &mut File) {
    match File::open(path) {
        Ok(mut f) => {
            let mut b_content = String::new();
            f.read_to_string(&mut b_content).unwrap();
            let content = b_content.replace("{", " { ")
                                   .replace("}", " } ")
                                   .replace("///", "/// ")
                                   .replace("//!", "//! ")
                                   .replace("/*!", "/*! ")
                                   .replace(":", " : ")
                                   .replace("*/", " */")
                                   .replace("\n", " \n ")
                                   .replace("!(", " !! (")
                                   .replace(",", ", ")
                                   .replace("(", " (");
            let b_content : Vec<&str> = b_content.split('\n').collect();
            let words : Vec<&str> = content.split(' ').filter(|s| s.len() > 0).collect();
            let mut it = 0;
            let mut line = 0;
            let mut event_list = vec!();
            let mut comments = 0;

            while it < words.len() {
                match words[it] {
                    "///" => {
                        event_list.push(EventType::Comment(b_content[line].to_owned()));
                        move_to(&words, &mut it, "\n", &mut line);
                        comments += 1;
                    }
                    "//!" => {
                        event_list.push(EventType::FileComment(b_content[line].to_owned()));
                        move_to(&words, &mut it, "\n", &mut line);
                        comments += 1;
                    }
                    "/*!" => {
                        let mark = line;
                        move_until(&words, &mut it, "*/", &mut line);
                        for pos in mark..line {
                            event_list.push(EventType::FileComment(b_content[pos].to_owned()));
                        }
                        event_list.push(EventType::FileComment("*/".to_owned()));
                        comments += 1;
                    }
                    "struct" | "mod" | "fn" | "enum" | "const" | "static" | "type" | "use" | "trait" | "macro_rules!" => {
                        event_list.push(EventType::Type(TypeStruct::new(Type::from(words[it]), words[it + 1])));
                        it += 1;
                    }
                    "!!" => {
                        event_list.push(EventType::Type(TypeStruct::new(Type::from("macro"), &format!("{}!{}", words[it - 1], words[it + 1]))));
                        it += 1;
                    }
                    "impl" => {
                        event_list.push(EventType::Type(TypeStruct::from_args(Type::Impl, get_impl(&words, &mut it, &mut line))));
                    }
                    "{" => {
                        event_list.push(EventType::InScope);
                    }
                    "}" => {
                        event_list.push(EventType::OutScope);
                    }
                    "\n" => {
                        line += 1;
                    }
                    _ => {
                        event_list.push(EventType::Type(TypeStruct::new(Type::Unknown, words[it])));
                    }
                }
                it += 1;
            }
            if comments < 1 {
                return;
            }
            writeln!(out_file, "=! {}", path).unwrap();
            let mut current : Option<TypeStruct> = None;
            let mut waiting_type : Option<TypeStruct> = None;

            it = 0;
            while it < event_list.len() {
                match event_list[it] {
                    EventType::Type(ref t) => {
                        if t.ty != Type::Unknown {
                            waiting_type = Some(t.clone());
                            //println!("current : {}", t);
                        }
                    }
                    EventType::InScope => {
                        current = add_to_type_scope(&current, &waiting_type);
                        /*if waiting_type.is_some() {
                            println!("in : {}", waiting_type.unwrap());
                        }*/
                        waiting_type = None;
                    }
                    EventType::OutScope => {
                        /*if current.is_some() {
                            println!("out : {}", current.clone().unwrap());
                        }*/
                        current = type_out_scope(&current);
                        waiting_type = None;
                    }
                    EventType::FileComment(ref c) => {
                        let mut comments = format!("=/ {}\n", c);

                        it += 1;
                        while match event_list[it] {
                            EventType::FileComment(ref c) => {
                                comments.push_str(&format!("=/ {}\n", c));
                                true
                            }
                            _ => false,
                        } {
                            it += 1;
                        }
                        write!(out_file, "{}", comments).unwrap();
                    }
                    EventType::Comment(ref c) => {
                        let mut comments = format!("{}\n", c);

                        it += 1;
                        while match event_list[it] {
                            EventType::Comment(ref c) => {
                                comments.push_str(&format!("{}\n", c));
                                true
                            }
                            EventType::Type(_) => {
                                false
                            }
                            _ => panic!("Comments cannot be written everywhere"),
                        } {
                            it += 1;
                        }
                        while match event_list[it] {
                            EventType::Type(ref t) => {
                                match t.ty {
                                    Type::Unknown => {
                                        match current {
                                            Some(ref cur) => {
                                                if cur.ty == Type::Enum || cur.ty == Type::Struct || cur.ty == Type::Use {
                                                    if t.name == "pub" {
                                                        true
                                                    } else {
                                                        let mut copy = t.clone();
                                                        copy.ty = Type::Variant;
                                                        let tmp = add_to_type_scope(&current, &Some(copy));
                                                        write!(out_file, "=| {}\n{}", tmp.unwrap(), comments).unwrap();
                                                        false
                                                    }
                                                } else {
                                                    false
                                                }
                                            }
                                            None => false,
                                        }
                                    },
                                    _ => {
                                        let tmp = add_to_type_scope(&current, &Some(t.clone()));
                                        write!(out_file, "=| {}\n{}", tmp.unwrap(), comments).unwrap();
                                        false
                                    }
                                }
                            }
                            _ => panic!("An item was expected for this comment: {}", comments),
                        } {
                            it += 1;
                        }
                        it -= 1;
                    }
                }
                it += 1;
            }
        }
        Err(e) => {
            println!("Unable to open \"{}\": {}", path, e);
        }
    }
}

fn check_path_type(path: &str, f: &mut File) {
    match fs::metadata(path) {
        Ok(m) => {
            if m.is_dir() {
                if path == ".." || path == "." {
                    return;
                }
                loop_over_files(path, f);
            } else {
                if path == "./comments.cmts" {
                    return;
                }
                println!("-> {}", path);
                strip_comments(path, f);
            }
        }
        Err(e) => {
            println!("An error occurred: {}", e);
        }
    }
}

fn main() {
    println!("Starting...");
    //match fs::remove_file("comments.cmts") { _ => {} }
    match OpenOptions::new().write(true).create(true).truncate(true).open("comments.cmts") {
        Ok(mut f) => {
            loop_over_files(".", &mut f);
            /*for com_entry in comments {
                write!(f, "{}", com_entry).unwrap();
            }*/
            println!("Done !");
        }
        Err(e) => {
            println!("Error while opening \"{}\": {}", "comments.cmts", e);
        }
    }
}
<|endoftext|>


<commit_before>extern crate regex;
#[macro_use]
extern crate log;
extern crate tini;
extern crate colored;

mod parser;
mod base;
mod extra;
mod logger;

use std::fs::File;
use std::io::Read;
use std::env::{self, args};
use std::process::exit;
use extra::*;
use regex::Regex;
use tini::Ini;
use colored::*;

static USAGE_STRING: &'static str = "\
>> доступные команды:
 -{n}       -- номер серии -n { стандартное значение = 1 }
 +{n}       -- номер серии +n { стандартное значение = 1 }
 a          -- добавить элемент [ a/имя | a/\"имя\" ]
 d          -- удалить элементы { найденые элементы параметром f }
 i          -- вывести весь список
 f{??}      -- поиск по параметру
   f        -- поиск по названию [ f/\"имя или regex\" ]
   fs{??}   -- по статусу { ?? -- буква статуса }
     где ??: c -- complete, d -- drop, h -- hold, p -- plan, w -- watch
   fp{??}   -- по номеру серии { ?? -- номер серии }
   fm{??}   -- по количеству серий в сезоне { ?? -- количество серий в сезоне }
   fr{??}   -- по оценке { ?? -- оценка }
 x{??}      -- фильтровать список полученный после f{??}
   xs{??}   -- по статусу { ?? -- буква статуса }
     где ??: c -- complete, d -- drop, h -- hold, p -- plan, w -- watch
   xp{??}   -- по номеру серии { ?? -- номер серии }
   xm{??}   -- по количеству серий в сезоне { ?? -- количество серий в сезоне }
   xr{??}   -- по оценке { ?? -- оценка }
 s{??}      -- установить параметр
  sn        -- изменить имя на новое [ sn/имя | sn/\"имя\" ]
  sm{число} -- изменить максимальный номер серии { ? в случае онгоинга }
  sp{число} -- изменить номер серии на { число }
  sr{число} -- изменить рейтинг на { число }
  ss{??}    -- изменить статуc на { ?? -- буква статуса }
    где ??: c -- complete, d -- drop, h -- hold, p -- plan, w -- watch
 w          -- записать изменения в базу
>> example: 'f/\"One Piece\"/sm?/+5/-/sr7/sp23/ssc/sn/d.gray-man/sm24/w'";

fn main() {
    let mut config_file = env::home_dir().unwrap();
    config_file.push(".config/watch-list/config.ini");
    let config = Ini::from_file(config_file.as_path()).unwrap();

    let log_level: String = config.get("main", "log_level").unwrap();
    let filename: String = config.get("main", "open_file").unwrap();
    logger::init(&log_level).unwrap();

    let arg_line = match args().nth(1) {
        Some(value) => value,
        None => {
            let app_name = args().nth(0).unwrap();
            println!("usage: {} '<regex>'\n{}", app_name, USAGE_STRING);
            exit(0);
        }
    };

    let mut update_flag = false;
    let mut save_flag = false;
    let mut parity_item = 0;

    debug!("read list from file `{}`", filename);
    let mut anime_base = AnimeBase::new();
    let mut file = File::open(&filename).unwrap();
    let mut buffer = String::new();
    file.read_to_string(&mut buffer).unwrap();
    for string in buffer.lines() {
        anime_base.push(base::Item::new(string));
    }

    let mut colorizer = |s: String| -> ColoredString {
        parity_item = (parity_item + 1) % 2;
        if parity_item % 2 == 0 {
            s.white().bold()
        } else {
            s.green().bold()
        }
    };

    debug!("command list:");
    let mut iterator = parser::Splitter::new(&arg_line, parser::SplitFormat::Commands);
    let mut anime_list: Vec<usize> = Vec::new();
    while let Some(cmd) = iterator.next() {
        match ExecCmd::get(cmd, &mut iterator) {
            ExecCmd::Increment(value) => {
                debug!("command inc by `{}`", value);
                for index in &anime_list {
                    anime_base.progress_increment_by(*index, value).unwrap();
                }
                update_flag = true;
            }
            ExecCmd::Decrement(value) => {
                debug!("command dec by `{}`", value);
                for index in &anime_list {
                    anime_base.progress_decrement_by(*index, value).unwrap();
                }
                update_flag = true;
            }
            ExecCmd::Append(name) => {
                debug!("command new anime `{}`", name);
                let new_item = anime_base.append(&name);
                anime_list.push(new_item);
                let result = format!("> append: {}", anime_base.format_by_index(new_item)).red();
                println!("{}", result);
            }
            ExecCmd::Delete => {
                debug!("command delete item");
                // TODO: implement
            }
            ExecCmd::Info => {
                debug!("command print list");
                for item in &anime_base.list {
                    let item = format!("{}", anime_base.format(item));
                    println!("{}", colorizer(item));
                }
            }
            ExecCmd::Find(regex) => {
                debug!("command find `{}`", regex);
                let re = Regex::new(&regex).unwrap();
                for (index, item) in anime_base.list.iter().enumerate() {
                    if re.is_match(&item.name) {
                        anime_list.push(index);
                        let item = format!(">  found: {}", anime_base.format(item));
                        println!("{}", colorizer(item));
                    }
                }
            }
            ExecCmd::FindParam(param) => {
                debug!("command find by param `{:?}`", param);
                for (index, item) in anime_base.list.iter().enumerate() {
                    let is_match = match param {
                        ParamType::Status(value) => item.status == value,
                        ParamType::Progress(value) => item.progress == value,
                        ParamType::Maximum(value) => item.maximum == value,
                        ParamType::Rate(value) => item.rate == value,
                    };
                    if is_match {
                        anime_list.push(index);
                        let item = format!(">  found: {}", anime_base.format(item));
                        println!("{}", colorizer(item));
                    }
                }
            }
            ExecCmd::FilterParam(param) => {
                debug!("command filter by param `{:?}`", param);
                let mut new_anime_list = Vec::new();
                for index in anime_list.into_iter() {
                    let item = anime_base.get_item(index).unwrap();
                    let is_match = match param {
                        ParamType::Status(value) => item.status == value,
                        ParamType::Progress(value) => item.progress == value,
                        ParamType::Maximum(value) => item.maximum == value,
                        ParamType::Rate(value) => item.rate == value,
                    };
                    if is_match {
                        new_anime_list.push(index);
                        let item = format!("> filter: {}", anime_base.format(item));
                        println!("{}", colorizer(item));
                    }
                }
                anime_list = new_anime_list;
            }
            ExecCmd::Maximum(value) => {
                debug!("command series limit to `{}`", value);
                for index in &anime_list {
                    anime_base.set_maximum(*index, value).unwrap();
                }
                update_flag = true;
            }
            ExecCmd::Rename(new_name) => {
                debug!("command new name `{}`", new_name);
                for index in &anime_list {
                    anime_base.set_name(*index, &new_name).unwrap();
                }
                update_flag = true;
            }
            ExecCmd::Progress(value) => {
                debug!("command progress `{}`", value);
                for index in &anime_list {
                    anime_base.set_progress(*index, value).unwrap();
                }
                update_flag = true;
            }
            ExecCmd::Status(status) => {
                debug!("command status `{:?}`", status);
                for index in &anime_list {
                    anime_base.set_status(*index, status).unwrap();
                }
                update_flag = true;
            }
            ExecCmd::Rate(value) => {
                debug!("command rate `{}`", value);
                for index in &anime_list {
                    anime_base.set_rate(*index, value).unwrap();
                }
                update_flag = true;
            }
            ExecCmd::Write => {
                debug!("command write changes");
                let mut file = File::create(&filename).unwrap();
                anime_base.write_to_file(&mut file).expect("Can't write to file!");
                save_flag = true;
            }
            ExecCmd::Error(kind) => warn!("`{}`: {:?}", cmd, kind),
        };
    }
    if update_flag {
        for index in &anime_list {
            let item = format!("> update: {}", anime_base.format_by_index(*index));
            println!("{}", colorizer(item))
        }
    }
    if save_flag {
        println!("{}", if update_flag {
            "> changes saved".red()
        } else {
            "> nothing to save".red()
        });
    }
}
<commit_msg>[upd] list output if use filter<commit_after>extern crate regex;
#[macro_use]
extern crate log;
extern crate tini;
extern crate colored;

mod parser;
mod base;
mod extra;
mod logger;

use std::fs::File;
use std::io::Read;
use std::env::{self, args};
use std::process::exit;
use extra::*;
use regex::Regex;
use tini::Ini;
use colored::*;

static USAGE_STRING: &'static str = "\
>> доступные команды:
 -{n}       -- номер серии -n { стандартное значение = 1 }
 +{n}       -- номер серии +n { стандартное значение = 1 }
 a          -- добавить элемент [ a/имя | a/\"имя\" ]
 d          -- удалить элементы { найденые элементы параметром f }
 i          -- вывести весь список
 f{??}      -- поиск по параметру
   f        -- поиск по названию [ f/\"имя или regex\" ]
   fs{??}   -- по статусу { ?? -- буква статуса }
     где ??: c -- complete, d -- drop, h -- hold, p -- plan, w -- watch
   fp{??}   -- по номеру серии { ?? -- номер серии }
   fm{??}   -- по количеству серий в сезоне { ?? -- количество серий в сезоне }
   fr{??}   -- по оценке { ?? -- оценка }
 x{??}      -- фильтровать список полученный после f{??}
   xs{??}   -- по статусу { ?? -- буква статуса }
     где ??: c -- complete, d -- drop, h -- hold, p -- plan, w -- watch
   xp{??}   -- по номеру серии { ?? -- номер серии }
   xm{??}   -- по количеству серий в сезоне { ?? -- количество серий в сезоне }
   xr{??}   -- по оценке { ?? -- оценка }
 s{??}      -- установить параметр
  sn        -- изменить имя на новое [ sn/имя | sn/\"имя\" ]
  sm{число} -- изменить максимальный номер серии { ? в случае онгоинга }
  sp{число} -- изменить номер серии на { число }
  sr{число} -- изменить рейтинг на { число }
  ss{??}    -- изменить статуc на { ?? -- буква статуса }
    где ??: c -- complete, d -- drop, h -- hold, p -- plan, w -- watch
 w          -- записать изменения в базу
>> example: 'f/\"One Piece\"/sm?/+5/-/sr7/sp23/ssc/sn/d.gray-man/sm24/w'";

fn main() {
    let mut config_file = env::home_dir().unwrap();
    config_file.push(".config/watch-list/config.ini");
    let config = Ini::from_file(config_file.as_path()).unwrap();

    let log_level: String = config.get("main", "log_level").unwrap();
    let filename: String = config.get("main", "open_file").unwrap();
    logger::init(&log_level).unwrap();

    let arg_line = match args().nth(1) {
        Some(value) => value,
        None => {
            let app_name = args().nth(0).unwrap();
            println!("usage: {} '<regex>'\n{}", app_name, USAGE_STRING);
            exit(0);
        }
    };

    let mut update_flag = false;
    let mut save_flag = false;
    let mut parity_item = 0;

    debug!("read list from file `{}`", filename);
    let mut anime_base = AnimeBase::new();
    let mut file = File::open(&filename).unwrap();
    let mut buffer = String::new();
    file.read_to_string(&mut buffer).unwrap();
    for string in buffer.lines() {
        anime_base.push(base::Item::new(string));
    }

    let mut colorizer = |s: String| -> ColoredString {
        parity_item = (parity_item + 1) % 2;
        if parity_item % 2 == 0 {
            s.white().bold()
        } else {
            s.green().bold()
        }
    };

    debug!("command list:");
    let mut iterator = parser::Splitter::new(&arg_line, parser::SplitFormat::Commands);
    let mut anime_list: Vec<usize> = Vec::new();
    // I have no idea how to check ExecCmd::Filter
    let filter_command = arg_line.contains('x');
    while let Some(cmd) = iterator.next() {
        match ExecCmd::get(cmd, &mut iterator) {
            ExecCmd::Increment(value) => {
                debug!("command inc by `{}`", value);
                for index in &anime_list {
                    anime_base.progress_increment_by(*index, value).unwrap();
                }
                update_flag = true;
            }
            ExecCmd::Decrement(value) => {
                debug!("command dec by `{}`", value);
                for index in &anime_list {
                    anime_base.progress_decrement_by(*index, value).unwrap();
                }
                update_flag = true;
            }
            ExecCmd::Append(name) => {
                debug!("command new anime `{}`", name);
                let new_item = anime_base.append(&name);
                anime_list.push(new_item);
                let result = format!("> append: {}", anime_base.format_by_index(new_item)).red();
                println!("{}", result);
            }
            ExecCmd::Delete => {
                debug!("command delete item");
                // TODO: implement
            }
            ExecCmd::Info => {
                debug!("command print list");
                for item in &anime_base.list {
                    let item = format!("{}", anime_base.format(item));
                    println!("{}", colorizer(item));
                }
            }
            ExecCmd::Find(regex) => {
                debug!("command find `{}`", regex);
                let re = Regex::new(&regex).unwrap();
                for (index, item) in anime_base.list.iter().enumerate() {
                    if re.is_match(&item.name) {
                        anime_list.push(index);
                        if !filter_command {
                            let item = format!(">  found: {}", anime_base.format(item));
                            println!("{}", colorizer(item));
                        }
                    }
                }
            }
            ExecCmd::FindParam(param) => {
                debug!("command find by param `{:?}`", param);
                for (index, item) in anime_base.list.iter().enumerate() {
                    let is_match = match param {
                        ParamType::Status(value) => item.status == value,
                        ParamType::Progress(value) => item.progress == value,
                        ParamType::Maximum(value) => item.maximum == value,
                        ParamType::Rate(value) => item.rate == value,
                    };
                    if is_match {
                        anime_list.push(index);
                        if !filter_command {
                            let item = format!(">  found: {}", anime_base.format(item));
                            println!("{}", colorizer(item));
                        }
                    }
                }
            }
            ExecCmd::FilterParam(param) => {
                debug!("command filter by param `{:?}`", param);
                let mut new_anime_list = Vec::new();
                for index in anime_list.into_iter() {
                    let item = anime_base.get_item(index).unwrap();
                    let is_match = match param {
                        ParamType::Status(value) => item.status == value,
                        ParamType::Progress(value) => item.progress == value,
                        ParamType::Maximum(value) => item.maximum == value,
                        ParamType::Rate(value) => item.rate == value,
                    };
                    if is_match {
                        new_anime_list.push(index);
                        let item = format!("> filter: {}", anime_base.format(item));
                        println!("{}", colorizer(item));
                    }
                }
                anime_list = new_anime_list;
            }
            ExecCmd::Maximum(value) => {
                debug!("command series limit to `{}`", value);
                for index in &anime_list {
                    anime_base.set_maximum(*index, value).unwrap();
                }
                update_flag = true;
            }
            ExecCmd::Rename(new_name) => {
                debug!("command new name `{}`", new_name);
                for index in &anime_list {
                    anime_base.set_name(*index, &new_name).unwrap();
                }
                update_flag = true;
            }
            ExecCmd::Progress(value) => {
                debug!("command progress `{}`", value);
                for index in &anime_list {
                    anime_base.set_progress(*index, value).unwrap();
                }
                update_flag = true;
            }
            ExecCmd::Status(status) => {
                debug!("command status `{:?}`", status);
                for index in &anime_list {
                    anime_base.set_status(*index, status).unwrap();
                }
                update_flag = true;
            }
            ExecCmd::Rate(value) => {
                debug!("command rate `{}`", value);
                for index in &anime_list {
                    anime_base.set_rate(*index, value).unwrap();
                }
                update_flag = true;
            }
            ExecCmd::Write => {
                debug!("command write changes");
                let mut file = File::create(&filename).unwrap();
                anime_base.write_to_file(&mut file).expect("Can't write to file!");
                save_flag = true;
            }
            ExecCmd::Error(kind) => warn!("`{}`: {:?}", cmd, kind),
        };
    }
    if update_flag {
        for index in &anime_list {
            let item = format!("> update: {}", anime_base.format_by_index(*index));
            println!("{}", colorizer(item))
        }
    }
    if save_flag {
        println!("{}", if update_flag {
            "> changes saved".red()
        } else {
            "> nothing to save".red()
        });
    }
}
<|endoftext|>


<commit_before>extern crate notify;
extern crate libc;

use libc::system;
use notify::{RecommendedWatcher, Watcher};
use std::ffi::CString;
use std::string::String;
use std::sync::mpsc::channel;

fn invoke(cmd: &String) {
    let s = CString::new(cmd.clone()).unwrap();
    unsafe {
      system(s.as_ptr());
    }
}

fn main() {
    let cmd = std::env::args().nth(1).expect("Argument 1 needs to be a command");

    let (tx, rx) = channel();
    let mut watcher: RecommendedWatcher = Watcher::new(tx)
        .expect("unable to create watcher");
    watcher.watch(".")
        .expect("unable to start watching directory");

    loop {
        match rx.recv() {
            Ok(notify::Event{ path: Some(path), op:Ok(op) }) => {
                println!("{:?} {:?}", op, path);
                invoke(&cmd);
            },
            Ok(event) => println!("broken event: {:?}", event),
            Err(e) => println!("watch error: {}", e),
        }
    }
}
<commit_msg>Simple screen clear & debounce<commit_after>extern crate notify;
extern crate libc;

use std::io;
use std::io::Write;
use libc::system;
use notify::{Event, RecommendedWatcher, Watcher};
use std::ffi::CString;
use std::string::String;
use std::sync::mpsc::{channel, Receiver, RecvError};
use std::{thread, time};

fn clear() {
    let s = CString::new("clear").unwrap();
    unsafe {
        system(s.as_ptr());
    }

}

fn invoke(cmd: &String) {
    let s = CString::new(cmd.clone()).unwrap();
    unsafe {
      system(s.as_ptr());
    }
}

fn wait(rx: &Receiver<Event>) -> Result<Event, RecvError> {
    let e = try!(rx.recv());

    thread::sleep(time::Duration::from_millis(250));

    loop {
        match rx.try_recv() {
            Ok(_) => continue,
            Err(_) => break,
        }
    }

    Ok(e)
}

fn main() {
    let cmd = std::env::args().nth(1).expect("Argument 1 needs to be a command");

    let (tx, rx) = channel();
    let mut watcher: RecommendedWatcher = Watcher::new(tx)
        .expect("unable to create watcher");
    watcher.watch(".")
        .expect("unable to start watching directory");

    loop {
        //clear();
        let e = wait(&rx)
            .expect("error when waiting for filesystem changes");

        println!("{:?} {:?}", e.op, e.path);
        invoke(&cmd);
    }
}
<|endoftext|>


<commit_before>extern crate walkdir;

use std::ffi::OsString;
use std::env;
use std::path::PathBuf;
use std::process::Command;
use walkdir::{DirEntry, WalkDir, WalkDirIterator};

struct MultiCmd {
    command: Command,
    banner: String,
    top_directory: PathBuf,
    directories: Vec<PathBuf>,
}

impl MultiCmd {
    fn new(cmd: &str, args: Vec<String>) -> Self {

        let mut command = Command::new(cmd);
        let mut banner = String::from("Executing ") + &cmd ;
        for arg in args {
            command.arg(OsString::from(&arg));
            banner = banner + " " + &arg;
        }

        MultiCmd {
            command: command,
            banner: banner,
            top_directory: PathBuf::new(),
            directories: Vec::new(),
        }
    }

    fn set_top_dir(&mut self, dir: PathBuf) -> &mut Self {
        self.top_directory = dir;
        self
    }

    fn collect_crate_candidates(&mut self) -> &mut Self {
        self.directories = WalkDir::new(&self.top_directory)
                               .min_depth(1)
                               .max_depth(1)
                               .into_iter()
                               .filter_entry(|e| is_crate(e))
                               .map(|e| e.ok().unwrap().path().to_path_buf())
                               .collect::<Vec<_>>();
        self
    }

    fn announce(&self) -> &Self {
        let mut line = String::new();
        for _ in 0..self.banner.len() {
            line.push('-');
        }
        println!("{}", line);
        println!("{}", self.banner);
        println!("{}", line);
        self
    }

    fn dispatch(&mut self) -> &Self {
        for dir in &self.directories {
            println!("{}:", dir.display());
            let out = self.command
                          .current_dir(dir)
                          .output()
                          .unwrap_or_else(|e| panic!("failed to execute process: {}", e));
            if out.status.success() {
                print_ident(out.stdout);
            } else {
                print_ident(out.stderr);
            }
            println!("");
        }
        self
    }
}

fn print_ident(buf: Vec<u8>)
{
    // ::<'a>(v: &'a [u8])
    for line in String::from_utf8_lossy(&buf[..]).lines() {
        println!("        {}", line);
    }
}

fn is_crate(entry: &DirEntry) -> bool {
    entry.path().join("Cargo.toml").exists()
}

fn main() {
    let args = env::args().skip(2).collect();
    let cwd = env::current_dir().unwrap();
    let mut multi = MultiCmd::new("cargo", args);

    multi.set_top_dir(cwd);
    multi.collect_crate_candidates();
    multi.announce();
    multi.dispatch();
}
<commit_msg>Small optimization<commit_after>extern crate walkdir;

use std::ffi::OsString;
use std::env;
use std::path::PathBuf;
use std::process::Command;
use walkdir::{DirEntry, WalkDir, WalkDirIterator};

struct MultiCmd {
    command: Command,
    banner: String,
    top_directory: PathBuf,
    directories: Vec<PathBuf>,
}

impl MultiCmd {
    fn new(cmd: &str, args: Vec<String>) -> Self {

        let mut command = Command::new(cmd);
        let mut banner = String::from("Executing ") + &cmd;
        for arg in args {
            command.arg(OsString::from(&arg));
            banner = banner + " " + &arg;
        }

        MultiCmd {
            command: command,
            banner: banner,
            top_directory: PathBuf::new(),
            directories: Vec::new(),
        }
    }

    fn set_top_dir(&mut self, dir: PathBuf) -> &mut Self {
        self.top_directory = dir;
        self
    }

    fn collect_crate_candidates(&mut self) -> &mut Self {
        self.directories = WalkDir::new(&self.top_directory)
                               .min_depth(1)
                               .max_depth(1)
                               .into_iter()
                               .filter_entry(|e| is_crate(e))
                               .map(|e| e.ok().unwrap().path().to_path_buf())
                               .collect::<Vec<_>>();
        self
    }

    fn announce(&self) -> &Self {
        let mut line = String::new();
        for _ in 0..self.banner.len() {
            line.push('-');
        }
        println!("{}", line);
        println!("{}", self.banner);
        println!("{}", line);
        self
    }

    fn dispatch(&mut self) -> &Self {
        for dir in &self.directories {
            println!("{}:", dir.display());
            let out = self.command
                          .current_dir(dir)
                          .output()
                          .unwrap_or_else(|e| panic!("failed to execute process: {}", e));
            if out.status.success() {
                print_ident(out.stdout);
            } else {
                print_ident(out.stderr);
            }
            println!("");
        }
        self
    }
}

fn print_ident(buf: Vec<u8>)
{
    // ::<'a>(v: &'a [u8])
    for line in String::from_utf8_lossy(&buf[..]).lines() {
        println!("        {}", line);
    }
}

fn is_crate(entry: &DirEntry) -> bool {
    entry.path().join("Cargo.toml").exists()
}

fn main() {
    let args = env::args().skip(2).collect();
    let cwd = env::current_dir().unwrap();
    let mut multi = MultiCmd::new("cargo", args);

    multi.set_top_dir(cwd);
    multi.collect_crate_candidates();
    multi.announce();
    multi.dispatch();
}
<|endoftext|>


<commit_before>
extern crate walkdir;

use std::ffi::OsString;
use std::env;
use std::path::PathBuf;
use std::process::Command;
use walkdir::{DirEntry, WalkDir, WalkDirIterator};

struct CargoMultiCmd {
    command: Command,
    banner: String,
    top_directory: PathBuf,
    directories: Vec<PathBuf>,
}

impl CargoMultiCmd {
    fn new(cmd: &str, args: Vec<String>) -> Self {

        let mut command = Command::new(cmd);
        let mut banner = String::from("Executing ");
        banner.push_str(cmd);
        for arg in args {
            command.arg(OsString::from(&arg));
            banner = banner + " " + &arg;
        }

        CargoMultiCmd {
            command: command,
            banner: banner,
            top_directory: PathBuf::new(),
            directories: Vec::new(),
        }
    }

    fn set_top_dir(&mut self, dir: PathBuf) -> &mut Self {
        self.top_directory = dir;
        self
    }

    fn collect_crate_candidates(&mut self) -> &mut Self {
        self.directories = WalkDir::new(&self.top_directory)
                               .min_depth(1)
                               .max_depth(1)
                               .into_iter()
                               .filter_entry(|e| is_crate(e))
                               .map(|e| e.ok().unwrap().path().to_path_buf())
                               .collect::<Vec<_>>();
        self
    }

    fn announce(&self) -> &Self {
        println!("Executing cargo {}", self.banner);
        self
    }

    fn dispatch(&mut self) -> &Self {
        for dir in &self.directories {
            println!("{}:", dir.display());
            let out = self.command
                          .current_dir(dir)
                          .output()
                          .unwrap_or_else(|e| panic!("failed to execute process: {}", e));
            if out.status.success() {
                println!("{}",
                         ident_text(String::from_utf8_lossy(&out.stdout).into_owned()));
            } else {
                println!("{}",
                         ident_text(String::from_utf8_lossy(&out.stderr).into_owned()));
            }
            println!("");
        }
        self
    }
}

fn ident_text(text: String) -> String {
    let mut out = String::new();

    for line in text.lines() {
        out.push_str("        ");
        out.push_str(line);
    }
    out
}

fn is_crate(entry: &DirEntry) -> bool {
    entry.path().join("Cargo.toml").exists()
}

fn main() {
    let args = env::args().skip(1).collect();
    let cwd = env::current_dir().unwrap().join("..");
    let mut multi = CargoMultiCmd::new("cargo", args);

    multi.set_top_dir(cwd);
    multi.collect_crate_candidates();
    multi.announce();
    multi.dispatch();
}
<commit_msg>Fix lines<commit_after>
extern crate walkdir;

use std::ffi::OsString;
use std::env;
use std::path::PathBuf;
use std::process::Command;
use walkdir::{DirEntry, WalkDir, WalkDirIterator};

struct CargoMultiCmd {
    command: Command,
    banner: String,
    top_directory: PathBuf,
    directories: Vec<PathBuf>,
}

impl CargoMultiCmd {
    fn new(cmd: &str, args: Vec<String>) -> Self {

        let mut command = Command::new(cmd);
        let mut banner = String::from("Executing ");
        banner.push_str(cmd);
        for arg in args {
            command.arg(OsString::from(&arg));
            banner = banner + " " + &arg;
        }

        CargoMultiCmd {
            command: command,
            banner: banner,
            top_directory: PathBuf::new(),
            directories: Vec::new(),
        }
    }

    fn set_top_dir(&mut self, dir: PathBuf) -> &mut Self {
        self.top_directory = dir;
        self
    }

    fn collect_crate_candidates(&mut self) -> &mut Self {
        self.directories = WalkDir::new(&self.top_directory)
                               .min_depth(1)
                               .max_depth(1)
                               .into_iter()
                               .filter_entry(|e| is_crate(e))
                               .map(|e| e.ok().unwrap().path().to_path_buf())
                               .collect::<Vec<_>>();
        self
    }

    fn announce(&self) -> &Self {
        let mut line = String::new();
        for _ in 0..self.banner.len() {
            line.push('-');
        }
        println!("{}", line);
        println!("{}", self.banner);
        println!("{}", line);
        self
    }

    fn dispatch(&mut self) -> &Self {
        for dir in &self.directories {
            println!("{}:", dir.display());
            let out = self.command
                          .current_dir(dir)
                          .output()
                          .unwrap_or_else(|e| panic!("failed to execute process: {}", e));
            if out.status.success() {
                println!("{}",
                         ident_text(String::from_utf8_lossy(&out.stdout).into_owned()));
            } else {
                println!("{}",
                         ident_text(String::from_utf8_lossy(&out.stderr).into_owned()));
            }
            println!("");
        }
        self
    }
}

fn ident_text(text: String) -> String {
    let mut out = String::new();

    for line in text.lines() {
        out.push_str("        ");
        out.push_str(line);
        out.push('\n');
    }
    out
}

fn is_crate(entry: &DirEntry) -> bool {
    entry.path().join("Cargo.toml").exists()
}

fn main() {
    let args = env::args().skip(2).collect();
    let cwd = env::current_dir().unwrap();
    let mut multi = CargoMultiCmd::new("cargo", args);

    multi.set_top_dir(cwd);
    multi.collect_crate_candidates();
    multi.announce();
    multi.dispatch();
}
<|endoftext|>


<commit_before>//! SEGIMAP is an IMAP server implementation.
#![feature(macro_rules)]
#![deny(non_camel_case_types)]
#![feature(phase)]

extern crate "rust-crypto" as crypto;
extern crate regex;
#[phase(plugin)] extern crate regex_macros;
#[phase(plugin, link)] extern crate log;
#[phase(plugin)] extern crate peg_syntax_ext;
extern crate serialize;
extern crate time;
extern crate toml;

pub use config::Config;
pub use email::Email;
pub use login::LoginData;
pub use message::Message;
pub use server::Server;
pub use session::Session;
pub use user::User;

use std::io::{Listener, Acceptor, BufferedStream};
use std::sync::Arc;

mod auth;
mod command;
mod config;
mod email;
mod error;
mod folder;
mod parser;
mod login;
mod message;
mod server;
mod session;
mod user;

/// The file in which user data is stored.
// TODO: add the ability for the user to specify the user data file as an
// argument.
static USER_DATA_FILE: &'static str = "./users.json";

fn main() {
    // Load configuration.
    let config = Config::new();

    // let mut users = Vec::new();
    // users.push(User::new(Email::new("will".to_string(), "xqz.ca".to_string()), "54321".to_string(), "./maildir".to_string()));
    // users.push(User::new(Email::new("nikitapekin".to_string(), "gmail.com".to_string()), "12345".to_string(), "./maildir".to_string()));

    // user::save_users(USER_DATA_FILE.to_string(), users);

    // Load the user data from the user data file.
    // TODO: figure out what to do for error handling.
    let users = user::load_users(USER_DATA_FILE.to_string()).unwrap();

    let multipart_message = Message::parse(&Path::new("maildir/new/12345")).unwrap();
    let html_message = Message::parse(&Path::new("maildir/cur/54321:2,FS")).unwrap();

    // Avoid unused variable notices temporarily.
    //println!("Config: {}", config);
    //println!("Users: {}", users);
    //println!("Message: {}", multipart_message);
    //println!("Message: {}", html_message);

    let serv = Arc::new(Server::new(config, users));
    match serv.imap_listener() {
        Err(e) => {
            error!("Error listening on IMAP port: {}", e);
        }
        Ok(v) => {
            let mut acceptor = v.listen();
            for stream in acceptor.incoming() {
                match stream {
                    Err(e) => {
                        error!("Error accepting incoming connection: {}", e)
                    }
                    Ok(stream) => {
                        let session_serv = serv.clone();
                        spawn(proc() {
                            let mut session = Session::new(BufferedStream::new(stream), session_serv);
                            session.handle();
                        });
                    }
                }
            }
            drop(acceptor);
        }
    }
}

<commit_msg>Remove unused debugging lines<commit_after>//! SEGIMAP is an IMAP server implementation.
#![feature(macro_rules)]
#![deny(non_camel_case_types)]
#![feature(phase)]

extern crate "rust-crypto" as crypto;
extern crate regex;
#[phase(plugin)] extern crate regex_macros;
#[phase(plugin, link)] extern crate log;
#[phase(plugin)] extern crate peg_syntax_ext;
extern crate serialize;
extern crate time;
extern crate toml;

pub use config::Config;
pub use email::Email;
pub use login::LoginData;
pub use message::Message;
pub use server::Server;
pub use session::Session;
pub use user::User;

use std::io::{Listener, Acceptor, BufferedStream};
use std::sync::Arc;

mod auth;
mod command;
mod config;
mod email;
mod error;
mod folder;
mod parser;
mod login;
mod message;
mod server;
mod session;
mod user;

/// The file in which user data is stored.
// TODO: add the ability for the user to specify the user data file as an
// argument.
static USER_DATA_FILE: &'static str = "./users.json";

fn main() {
    // Load configuration.
    let config = Config::new();

    // let mut users = Vec::new();
    // users.push(User::new(Email::new("will".to_string(), "xqz.ca".to_string()), "54321".to_string(), "./maildir".to_string()));
    // users.push(User::new(Email::new("nikitapekin".to_string(), "gmail.com".to_string()), "12345".to_string(), "./maildir".to_string()));

    // user::save_users(USER_DATA_FILE.to_string(), users);

    // Load the user data from the user data file.
    // TODO: figure out what to do for error handling.
    let users = user::load_users(USER_DATA_FILE.to_string()).unwrap();

    let serv = Arc::new(Server::new(config, users));
    match serv.imap_listener() {
        Err(e) => {
            error!("Error listening on IMAP port: {}", e);
        }
        Ok(v) => {
            let mut acceptor = v.listen();
            for stream in acceptor.incoming() {
                match stream {
                    Err(e) => {
                        error!("Error accepting incoming connection: {}", e)
                    }
                    Ok(stream) => {
                        let session_serv = serv.clone();
                        spawn(proc() {
                            let mut session = Session::new(BufferedStream::new(stream), session_serv);
                            session.handle();
                        });
                    }
                }
            }
            drop(acceptor);
        }
    }
}

<|endoftext|>