<commit_before>extern crate arguments;
extern crate configuration;
extern crate term;

#[macro_use] extern crate log;
#[macro_use] extern crate streamer;

use configuration::format::TOML;
use log::LogLevel;
use streamer::{Result, platform, schedule, system, traffic, workload};
use streamer::output::{self, Output};

mod logger;

use logger::Logger;

type System = system::System<traffic::Fractal,
                             workload::Random,
                             platform::Thermal,
                             schedule::Impartial>;

const USAGE: &'static str = "
Usage: example [options]

Options:
    --config <path>          Configuration file (required).
    --length <time>          Time span to synthesize in seconds [default: 10].
    --output <path>          Output file for power and temperature profiles.

    --verbose                Display progress information.
    --help                   Display this message.
";

#[allow(unused_must_use)]
fn main() {
    if let Err(error) = start() {
        use std::io::Write;
        if let Some(mut output) = term::stderr() {
            output.fg(term::color::RED);
            output.write_fmt(format_args!("Error: {}.\n", error));
            output.reset();
        }
        std::process::exit(1);
    }
}

fn start() -> Result<()> {
    let arguments = ok!(arguments::parse(std::env::args()));
    if arguments.get::<bool>("help").unwrap_or(false) {
        println!("{}", USAGE.trim());
        return Ok(());
    }
    if arguments.get::<bool>("verbose").unwrap_or(false) {
        Logger::install(LogLevel::Info);
    } else {
        Logger::install(LogLevel::Warn);
    }

    let mut system = {
        let config = ok!(TOML::open(some!(arguments.get::<String>("config"),
                                          "a configuration file is required")));
        macro_rules! branch(($name:expr) => (config.branch($name).as_ref().unwrap_or(&config)));
        let source = streamer::source(&config);
        let traffic = try!(traffic::Fractal::new(branch!("traffic"), &source));
        let workload = try!(workload::Random::new(branch!("workload"), &source));
        let platform = try!(platform::Thermal::new(branch!("platform")));
        let schedule = try!(schedule::Impartial::new(branch!("schedule"), &platform));
        try!(System::new(traffic, workload, platform, schedule))
    };
    let mut output = match arguments.get::<String>("output") {
        Some(path) => Some(try!(output::Thermal::new(system.platform(), path))),
        _ => None,
    };

    let length = arguments.get::<f64>("length").unwrap_or(10.0);
    info!(target: "Example", "Synthesizing {} seconds...", length);
    while let Some((event, data)) = try!(system.next()) {
        if let Some(ref mut output) = output {
            try!(output.next(&event, &data));
        }
        if event.time > length {
            break;
        }
    }
    info!(target: "Example", "Well done.");

    Ok(())
}
<commit_msg>Display the progress<commit_after>extern crate arguments;
extern crate configuration;
extern crate term;

#[macro_use] extern crate log;
#[macro_use] extern crate streamer;

use configuration::format::TOML;
use log::LogLevel;
use streamer::{Result, platform, schedule, traffic, workload};
use streamer::output::{self, Output};
use streamer::system::{self, Event};

mod logger;

use logger::Logger;

type System = system::System<traffic::Fractal,
                             workload::Random,
                             platform::Thermal,
                             schedule::Impartial>;

const USAGE: &'static str = "
Usage: example [options]

Options:
    --config <path>          Configuration file (required).
    --length <time>          Time span to synthesize in seconds [default: 10].
    --output <path>          Output file for power and temperature profiles.

    --verbose                Display progress information.
    --help                   Display this message.
";

#[allow(unused_must_use)]
fn main() {
    if let Err(error) = start() {
        use std::io::Write;
        if let Some(mut output) = term::stderr() {
            output.fg(term::color::RED);
            output.write_fmt(format_args!("Error: {}.\n", error));
            output.reset();
        }
        std::process::exit(1);
    }
}

fn start() -> Result<()> {
    let arguments = ok!(arguments::parse(std::env::args()));
    if arguments.get::<bool>("help").unwrap_or(false) {
        println!("{}", USAGE.trim());
        return Ok(());
    }
    if arguments.get::<bool>("verbose").unwrap_or(false) {
        Logger::install(LogLevel::Info);
    } else {
        Logger::install(LogLevel::Warn);
    }

    let mut system = {
        let config = ok!(TOML::open(some!(arguments.get::<String>("config"),
                                          "a configuration file is required")));
        macro_rules! branch(($name:expr) => (config.branch($name).as_ref().unwrap_or(&config)));
        let source = streamer::source(&config);
        let traffic = try!(traffic::Fractal::new(branch!("traffic"), &source));
        let workload = try!(workload::Random::new(branch!("workload"), &source));
        let platform = try!(platform::Thermal::new(branch!("platform")));
        let schedule = try!(schedule::Impartial::new(branch!("schedule"), &platform));
        try!(System::new(traffic, workload, platform, schedule))
    };
    let mut output = match arguments.get::<String>("output") {
        Some(path) => Some(try!(output::Thermal::new(system.platform(), path))),
        _ => None,
    };

    let length = arguments.get::<f64>("length").unwrap_or(10.0);
    info!(target: "Example", "Synthesizing {} seconds...", length);
    while let Some((event, data)) = try!(system.next()) {
        display(&system, &event);
        if let Some(ref mut output) = output {
            try!(output.next(&event, &data));
        }
        if event.time > length {
            break;
        }
    }
    info!(target: "Example", "Well done.");

    Ok(())
}

fn display(system: &System, event: &Event) {
    use streamer::system::EventKind;

    let (job, kind) = match &event.kind {
        &EventKind::Arrived(ref job) => (job, "arrived"),
        &EventKind::Started(ref job) => (job, "started"),
        &EventKind::Finished(ref job) => (job, "finished"),
    };
    info!(target: "Example",
          "{:8.2} s | job #{:4} ( {:20} | {:2} units | {:6.2} s ) {:8} | {:2} queued",
          event.time, job.id, job.name, job.units, job.duration(), kind,
          system.history().arrived - system.history().started);
}
<|endoftext|>


<commit_before>mod logger;
mod toml_file;
mod git;
extern crate toml;
extern crate regex;
extern crate semver;
extern crate argparse;
extern crate commit_walker;
extern crate commit_analyzer;
extern crate git2_commit;
extern crate git2;

use argparse::{ArgumentParser, StoreTrue, Store};
use commit_analyzer::CommitType;

fn version_bump(version: Version, bump: CommitType) -> Option<Version> {
    let mut version = version.clone();
    match bump {
        CommitType::Unknown => return None,
        CommitType::Patch => version.increment_patch(),
        CommitType::Minor => version.increment_minor(),
        CommitType::Major => version.increment_major(),
    }

    Some(version)
}

use std::process;
use semver::Version;

fn get_repository_path() -> String {
    let mut path = ".".to_string();
    {
        let mut ap = ArgumentParser::new();
        ap.refer(&mut path)
            .add_option(&["-p", "--path"], Store,
                        "Specifies the repository path. If ommitted it defaults to current directory");
        ap.parse_args_or_exit();
    }
    path
}

fn main() {
    println!("semantic.rs 🚀");

    logger::stdout("Analyzing your repository");
    let repository_path = get_repository_path();

    match git2::Repository::open(&repository_path) {
        Ok(_) => { },
        Err(e) => {
            logger::stderr(format!("Could not open the git repository: {:?}", e));
            process::exit(1);
        }
    };

    let version = match toml_file::read_from_file(&repository_path) {
        Ok(toml) => toml,
        Err(e) => {
            logger::stderr(format!("Reading `Cargo.toml` failed: {:?}", e));
            process::exit(1);
        }
    };

    let version = Version::parse(&version).expect("Not a valid version");
    logger::stdout(format!("Current version: {}", version.to_string()));

    logger::stdout("Analyzing commits");

    let bump = commit_walker::version_bump_since_latest(&repository_path);
    logger::stdout(format!("Commits analyzed. Bump will be {:?}", bump));

    let new_version = match version_bump(version, bump) {
        Some(new_version) => new_version,
        None => {
            logger::stdout("No version bump. Nothing to do.");
            process::exit(0);
        }
    };

    logger::stdout(format!("New version: {}", new_version.to_string()));
    match toml_file::write_new_version(&repository_path, new_version.to_string()) {
        Ok(_)    => { },
        Err(err) => logger::stderr(format!("Writing `Cargo.toml` failed: {:?}", err))
    }

    match git::commit_files(&repository_path, new_version.to_string()) {
        Ok(_)    => { },
        Err(err) => logger::stderr(format!("Committing `Cargo.toml` and `Cargo.lock` failed: {:?}", err))
    }
}
<commit_msg>fix: Exit with error code on failure<commit_after>mod logger;
mod toml_file;
mod git;
extern crate toml;
extern crate regex;
extern crate semver;
extern crate argparse;
extern crate commit_walker;
extern crate commit_analyzer;
extern crate git2_commit;
extern crate git2;

use argparse::{ArgumentParser, StoreTrue, Store};
use commit_analyzer::CommitType;

fn version_bump(version: Version, bump: CommitType) -> Option<Version> {
    let mut version = version.clone();
    match bump {
        CommitType::Unknown => return None,
        CommitType::Patch => version.increment_patch(),
        CommitType::Minor => version.increment_minor(),
        CommitType::Major => version.increment_major(),
    }

    Some(version)
}

use std::process;
use semver::Version;

fn get_repository_path() -> String {
    let mut path = ".".to_string();
    {
        let mut ap = ArgumentParser::new();
        ap.refer(&mut path)
            .add_option(&["-p", "--path"], Store,
                        "Specifies the repository path. If ommitted it defaults to current directory");
        ap.parse_args_or_exit();
    }
    path
}

fn main() {
    println!("semantic.rs 🚀");

    logger::stdout("Analyzing your repository");
    let repository_path = get_repository_path();

    match git2::Repository::open(&repository_path) {
        Ok(_) => { },
        Err(e) => {
            logger::stderr(format!("Could not open the git repository: {:?}", e));
            process::exit(1);
        }
    };

    let version = match toml_file::read_from_file(&repository_path) {
        Ok(toml) => toml,
        Err(e) => {
            logger::stderr(format!("Reading `Cargo.toml` failed: {:?}", e));
            process::exit(1);
        }
    };

    let version = Version::parse(&version).expect("Not a valid version");
    logger::stdout(format!("Current version: {}", version.to_string()));

    logger::stdout("Analyzing commits");

    let bump = commit_walker::version_bump_since_latest(&repository_path);
    logger::stdout(format!("Commits analyzed. Bump will be {:?}", bump));

    let new_version = match version_bump(version, bump) {
        Some(new_version) => new_version,
        None => {
            logger::stdout("No version bump. Nothing to do.");
            process::exit(0);
        }
    };

    logger::stdout(format!("New version: {}", new_version.to_string()));
    match toml_file::write_new_version(&repository_path, new_version.to_string()) {
        Ok(_)    => { },
        Err(err) => {
            logger::stderr(format!("Writing `Cargo.toml` failed: {:?}", err));
            process::exit(1);
        }
    }

    match git::commit_files(&repository_path, new_version.to_string()) {
        Ok(_)    => { },
        Err(err) => {
            logger::stderr(format!("Committing `Cargo.toml` and `Cargo.lock` failed: {:?}", err));
            process::exit(1);
        }
    }
}
<|endoftext|>


<commit_before>#[macro_use] extern crate serde_derive;
extern crate serde;
extern crate serde_yaml;
extern crate csv;
extern crate tina;
#[macro_use] extern crate slog;
#[macro_use] extern crate slog_scope;
extern crate slog_term;

mod config;

use std::io::stdout;
use std::env;
use std::sync::Arc;
use std::fs::OpenOptions;

use slog::{Drain, Logger, Discard, Duplicate};
use slog_scope::set_global_logger;
use slog_term::{PlainSyncDecorator, FullFormat};

use tina::*;
use config::*;

const ENV_VAR_NAME: &'static str = "TINA_CONF_PATH";
const DEFAULT_CONFIG_PATH: &'static str = "config/tina.yaml";

fn build_specific_logger(log_path: &Option<String>, duplication: bool, default: &Logger) -> Logger
{
	if let Some(ref path) = *log_path {

		let file = OpenOptions::new().append(true).create(true).open(path).unwrap();
		let drain = FullFormat::new(PlainSyncDecorator::new(file)).build();

		if duplication {
			Logger::root(Duplicate(drain, default.clone()).fuse(), o!())
		} else {
			Logger::root(drain.fuse(), o!())
		}

	} else {

		if duplication { default.clone() } else { Logger::root(Discard, o!()) }
	}
}

fn main()
{
	let cmd_args: Vec<String> = env::args().collect();
	let env_arg_string = env::var(ENV_VAR_NAME).ok();

	let cmd_arg = cmd_args.get(1).map(|s| s.as_str());
	let env_arg = env_arg_string.as_ref().map(|s| s.as_str());
	let conf_path = cmd_arg.or(env_arg).unwrap_or(DEFAULT_CONFIG_PATH);

	let conf = match Config::load_config(conf_path) {
		Err(err) => {
			println!("Error while loading config ({:?})", err);
			return;
		},
		Ok(c) => c
	};

	let stdout_drain = FullFormat::new(PlainSyncDecorator::new(stdout())).build();
	let stdout_logger = Logger::root(stdout_drain.fuse(), o!());

	let root_drain = stdout_logger.clone().filter_level(conf.log.log_level);
	let root_logger = Logger::root(root_drain.fuse(), o!());
	set_global_logger(root_logger).cancel_reset();

	let eew_logger = build_specific_logger(&conf.log.eew_log_path, conf.log.eew_stdout_log, &stdout_logger);
	let wni_logger = build_specific_logger(&conf.log.wni_log_path, conf.log.wni_stdout_log, &stdout_logger);

	let wni_client = WNIClient::new(conf.wni.id.clone(), conf.wni.password.clone(), Some(wni_logger));
	let mut socks: Vec<EEWSocket> = Vec::new();

	socks.push(EEWSocket::new(Logging::new(eew_logger)));
	info!("Enabled: EEW Logging");

	if conf.twitter.is_some() {
		let t = &conf.twitter.unwrap();
		let tw = Twitter::new(
			t.consumer_token.clone(), t.consumer_secret.clone(),
			t.access_token.clone(), t.access_secret.clone(), t.in_reply_to_enabled);
		if ! tw.is_valid() {
			warn!("Twitter: Invalid tokens");
		} else {
			socks.push(EEWSocket::new(tw));
			info!("Enabled: Twitter");
		}
	}

	let mut moderator = Moderator::new();

	loop {

		let mut connection = match wni_client.connect() {
			Ok(v) => v,
			Err(e) => {
				error!("ConnectionError: {:?}", e);
				moderator.wait_for_retry();
				moderator.add_count();
				continue;
			}
		};

		moderator.reset();

		loop {

			let eew = match connection.wait_for_telegram(&conf.epicenter_dict, &conf.area_dict) {
				Err(e) => {
					error!("StreamingError: {:?}", e);
					break;
				},
				Ok(eew) => Arc::new(eew)
			};

			for s in socks.iter() {
				s.emit(eew.clone());
			}
		}
	}
}
<commit_msg>Add a log message shown when a connection to WNI is established<commit_after>#[macro_use] extern crate serde_derive;
extern crate serde;
extern crate serde_yaml;
extern crate csv;
extern crate tina;
#[macro_use] extern crate slog;
#[macro_use] extern crate slog_scope;
extern crate slog_term;

mod config;

use std::io::stdout;
use std::env;
use std::sync::Arc;
use std::fs::OpenOptions;

use slog::{Drain, Logger, Discard, Duplicate};
use slog_scope::set_global_logger;
use slog_term::{PlainSyncDecorator, FullFormat};

use tina::*;
use config::*;

const ENV_VAR_NAME: &'static str = "TINA_CONF_PATH";
const DEFAULT_CONFIG_PATH: &'static str = "config/tina.yaml";

fn build_specific_logger(log_path: &Option<String>, duplication: bool, default: &Logger) -> Logger
{
	if let Some(ref path) = *log_path {

		let file = OpenOptions::new().append(true).create(true).open(path).unwrap();
		let drain = FullFormat::new(PlainSyncDecorator::new(file)).build();

		if duplication {
			Logger::root(Duplicate(drain, default.clone()).fuse(), o!())
		} else {
			Logger::root(drain.fuse(), o!())
		}

	} else {

		if duplication { default.clone() } else { Logger::root(Discard, o!()) }
	}
}

fn main()
{
	let cmd_args: Vec<String> = env::args().collect();
	let env_arg_string = env::var(ENV_VAR_NAME).ok();

	let cmd_arg = cmd_args.get(1).map(|s| s.as_str());
	let env_arg = env_arg_string.as_ref().map(|s| s.as_str());
	let conf_path = cmd_arg.or(env_arg).unwrap_or(DEFAULT_CONFIG_PATH);

	let conf = match Config::load_config(conf_path) {
		Err(err) => {
			println!("Error while loading config ({:?})", err);
			return;
		},
		Ok(c) => c
	};

	let stdout_drain = FullFormat::new(PlainSyncDecorator::new(stdout())).build();
	let stdout_logger = Logger::root(stdout_drain.fuse(), o!());

	let root_drain = stdout_logger.clone().filter_level(conf.log.log_level);
	let root_logger = Logger::root(root_drain.fuse(), o!());
	set_global_logger(root_logger).cancel_reset();

	let eew_logger = build_specific_logger(&conf.log.eew_log_path, conf.log.eew_stdout_log, &stdout_logger);
	let wni_logger = build_specific_logger(&conf.log.wni_log_path, conf.log.wni_stdout_log, &stdout_logger);

	let wni_client = WNIClient::new(conf.wni.id.clone(), conf.wni.password.clone(), Some(wni_logger));
	let mut socks: Vec<EEWSocket> = Vec::new();

	socks.push(EEWSocket::new(Logging::new(eew_logger)));
	info!("Enabled: EEW Logging");

	if conf.twitter.is_some() {
		let t = &conf.twitter.unwrap();
		let tw = Twitter::new(
			t.consumer_token.clone(), t.consumer_secret.clone(),
			t.access_token.clone(), t.access_secret.clone(), t.in_reply_to_enabled);
		if ! tw.is_valid() {
			warn!("Twitter: Invalid tokens");
		} else {
			socks.push(EEWSocket::new(tw));
			info!("Enabled: Twitter");
		}
	}

	let mut moderator = Moderator::new();

	loop {

		let mut connection = match wni_client.connect() {
			Ok(v) => v,
			Err(e) => {
				error!("ConnectionError: {:?}", e);
				moderator.wait_for_retry();
				moderator.add_count();
				continue;
			}
		};

		moderator.reset();
		info!("Connected: WNI");

		loop {

			let eew = match connection.wait_for_telegram(&conf.epicenter_dict, &conf.area_dict) {
				Err(e) => {
					error!("StreamingError: {:?}", e);
					break;
				},
				Ok(eew) => Arc::new(eew)
			};

			for s in socks.iter() {
				s.emit(eew.clone());
			}
		}
	}
}
<|endoftext|>


<commit_before>use std::collections::BTreeSet;
use std::fmt;
use std::io;
use std::io::prelude::*;
use std::path;
use std::str;

use anyhow::Result;
use cargo::core::dependency::DepKind;
use cargo::core::package::PackageSet;
use cargo::core::{Package, Resolve, Workspace};
use cargo::ops;
use cargo::util::Config;
use cargo::CargoResult;
use structopt::StructOpt;

#[derive(StructOpt)]
#[structopt(bin_name = "cargo")]
enum Opts {
    #[structopt(name = "bom")]
    /// Display a Bill-of-Materials for Rust project
    Bom(Args),
}

#[derive(StructOpt)]
struct Args {
    /// List all dependencies instead of only top level ones
    #[structopt(long = "all", short = "a")]
    all: bool,
    /// Directory for all generated artifacts
    #[structopt(long = "target-dir", value_name = "DIRECTORY", parse(from_os_str))]
    target_dir: Option<path::PathBuf>,
    #[structopt(long = "manifest-path", value_name = "PATH", parse(from_os_str))]
    /// Path to Cargo.toml
    manifest_path: Option<path::PathBuf>,
    #[structopt(long = "verbose", short = "v", parse(from_occurrences))]
    /// Use verbose output (-vv very verbose/build.rs output)
    verbose: u32,
    #[structopt(long = "quiet", short = "q")]
    /// No output printed to stdout other than the tree
    quiet: bool,
    #[structopt(long = "color", value_name = "WHEN")]
    /// Coloring: auto, always, never
    color: Option<String>,
    #[structopt(long = "frozen")]
    /// Require Cargo.lock and cache are up to date
    frozen: bool,
    #[structopt(long = "locked")]
    /// Require Cargo.lock is up to date
    locked: bool,
    #[structopt(long = "offline")]
    /// Run without accessing the network
    offline: bool,
    #[structopt(short = "Z", value_name = "FLAG")]
    /// Unstable (nightly-only) flags to Cargo
    unstable_flags: Vec<String>,
}

fn main() -> Result<()> {
    let mut config = Config::default()?;
    let Opts::Bom(args) = Opts::from_args();
    real_main(&mut config, args)
}

fn real_main(config: &mut Config, args: Args) -> Result<()> {
    config.configure(
        args.verbose,
        args.quiet,
        args.color.as_deref(),
        args.frozen,
        args.locked,
        args.offline,
        &args.target_dir,
        &args.unstable_flags,
        &[],
    )?;

    let manifest = args
        .manifest_path
        .unwrap_or_else(|| config.cwd().join("Cargo.toml"));
    let ws = Workspace::new(&manifest, &config)?;
    let members: Vec<Package> = ws.members().cloned().collect();
    let (package_ids, resolve) = ops::resolve_ws(&ws)?;

    let dependencies = if args.all {
        all_dependencies(&members, package_ids, resolve)?
    } else {
        top_level_dependencies(&members, package_ids)?
    };

    let mut packages = BTreeSet::new();
    for package in &dependencies {
        let name = package.name().to_owned();
        let version = format!("{}", package.version());
        let licenses = format!("{}", package_licenses(package));
        let license_files = package_license_files(package)?;
        packages.insert((name, version, licenses, license_files));
    }

    let stdout = io::stdout();
    let mut out = stdout.lock();

    {
        let mut tw = tabwriter::TabWriter::new(&mut out);
        writeln!(tw, "Name\t| Version\t| Licenses")?;
        writeln!(tw, "----\t| -------\t| --------")?;
        for (name, version, licenses, _) in &packages {
            writeln!(tw, "{}\t| {}\t| {}", &name, &version, &licenses)?;
        }

        // TabWriter flush() makes the actual write to stdout.
        tw.flush()?;
    }

    writeln!(out)?;
    out.flush()?;

    for (name, version, _, license_files) in packages {
        if license_files.is_empty() {
            continue;
        }

        writeln!(out, "-----BEGIN {} {} LICENSES-----", name, version)?;

        let mut buf = Vec::new();
        let mut licenses_to_print = license_files.len();
        for file in license_files {
            let mut fs = std::fs::File::open(file)?;
            fs.read_to_end(&mut buf)?;
            out.write_all(&buf)?;
            buf.clear();
            if licenses_to_print > 1 {
                out.write_all(b"\n-----NEXT LICENSE-----\n")?;
                licenses_to_print -= 1;
            }
        }

        writeln!(out, "-----END {} {} LICENSES-----", name, version)?;
        writeln!(out)?;
    }

    out.flush()?;
    Ok(())
}

fn top_level_dependencies(
    members: &[Package],
    package_ids: PackageSet<'_>,
) -> CargoResult<BTreeSet<Package>> {
    let mut dependencies = BTreeSet::new();

    for member in members {
        for dependency in member.dependencies() {
            // Filter out Build and Development dependencies
            match dependency.kind() {
                DepKind::Normal => (),
                DepKind::Build | DepKind::Development => continue,
            }
            if let Some(dep) = package_ids
                .package_ids()
                .find(|id| dependency.matches_id(*id))
            {
                let package = package_ids.get_one(dep)?;
                dependencies.insert(package.to_owned());
            }
        }
    }

    // Filter out our own workspace crates from dependency list
    for member in members {
        dependencies.remove(member);
    }

    Ok(dependencies)
}

fn all_dependencies(
    members: &[Package],
    package_ids: PackageSet<'_>,
    resolve: Resolve,
) -> CargoResult<BTreeSet<Package>> {
    let mut dependencies = BTreeSet::new();

    for package_id in resolve.iter() {
        let package = package_ids.get_one(package_id)?;
        if members.contains(&package) {
            // Skip listing our own packages in our workspace
            continue;
        }
        dependencies.insert(package.to_owned());
    }

    Ok(dependencies)
}

fn package_licenses(package: &Package) -> Licenses<'_> {
    let metadata = package.manifest().metadata();

    if let Some(ref license_str) = metadata.license {
        let licenses: BTreeSet<&str> = license_str
            .split("OR")
            .map(|s| s.split("AND"))
            .flatten()
            .map(|s| s.split('/'))
            .flatten()
            .map(str::trim)
            .collect();
        return Licenses::Licenses(licenses);
    }

    if let Some(ref license_file) = metadata.license_file {
        return Licenses::File(license_file);
    }

    Licenses::Missing
}

static LICENCE_FILE_NAMES: &[&str] = &["LICENSE", "UNLICENSE"];

fn package_license_files(package: &Package) -> io::Result<Vec<path::PathBuf>> {
    let mut result = Vec::new();

    if let Some(path) = package.manifest_path().parent() {
        for entry in path.read_dir()? {
            if let Ok(entry) = entry {
                if let Ok(name) = entry.file_name().into_string() {
                    for license_name in LICENCE_FILE_NAMES {
                        if name.starts_with(license_name) {
                            result.push(entry.path())
                        }
                    }
                }
            }
        }
    }

    Ok(result)
}

#[derive(Debug)]
enum Licenses<'a> {
    Licenses(BTreeSet<&'a str>),
    File(&'a str),
    Missing,
}

impl<'a> fmt::Display for Licenses<'a> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
        match *self {
            Licenses::File(_) => write!(f, "Specified in license file"),
            Licenses::Missing => write!(f, "Missing"),
            Licenses::Licenses(ref lic_names) => {
                let lics: Vec<String> = lic_names.iter().map(|s| String::from(*s)).collect();
                write!(f, "{}", lics.join(", "))
            }
        }
    }
}
<commit_msg>Fix Clippy nag<commit_after>use std::collections::BTreeSet;
use std::fmt;
use std::io;
use std::io::prelude::*;
use std::path;
use std::str;

use anyhow::Result;
use cargo::core::dependency::DepKind;
use cargo::core::package::PackageSet;
use cargo::core::{Package, Resolve, Workspace};
use cargo::ops;
use cargo::util::Config;
use cargo::CargoResult;
use structopt::StructOpt;

#[derive(StructOpt)]
#[structopt(bin_name = "cargo")]
enum Opts {
    #[structopt(name = "bom")]
    /// Display a Bill-of-Materials for Rust project
    Bom(Args),
}

#[derive(StructOpt)]
struct Args {
    /// List all dependencies instead of only top level ones
    #[structopt(long = "all", short = "a")]
    all: bool,
    /// Directory for all generated artifacts
    #[structopt(long = "target-dir", value_name = "DIRECTORY", parse(from_os_str))]
    target_dir: Option<path::PathBuf>,
    #[structopt(long = "manifest-path", value_name = "PATH", parse(from_os_str))]
    /// Path to Cargo.toml
    manifest_path: Option<path::PathBuf>,
    #[structopt(long = "verbose", short = "v", parse(from_occurrences))]
    /// Use verbose output (-vv very verbose/build.rs output)
    verbose: u32,
    #[structopt(long = "quiet", short = "q")]
    /// No output printed to stdout other than the tree
    quiet: bool,
    #[structopt(long = "color", value_name = "WHEN")]
    /// Coloring: auto, always, never
    color: Option<String>,
    #[structopt(long = "frozen")]
    /// Require Cargo.lock and cache are up to date
    frozen: bool,
    #[structopt(long = "locked")]
    /// Require Cargo.lock is up to date
    locked: bool,
    #[structopt(long = "offline")]
    /// Run without accessing the network
    offline: bool,
    #[structopt(short = "Z", value_name = "FLAG")]
    /// Unstable (nightly-only) flags to Cargo
    unstable_flags: Vec<String>,
}

fn main() -> Result<()> {
    let mut config = Config::default()?;
    let Opts::Bom(args) = Opts::from_args();
    real_main(&mut config, args)
}

fn real_main(config: &mut Config, args: Args) -> Result<()> {
    config.configure(
        args.verbose,
        args.quiet,
        args.color.as_deref(),
        args.frozen,
        args.locked,
        args.offline,
        &args.target_dir,
        &args.unstable_flags,
        &[],
    )?;

    let manifest = args
        .manifest_path
        .unwrap_or_else(|| config.cwd().join("Cargo.toml"));
    let ws = Workspace::new(&manifest, &config)?;
    let members: Vec<Package> = ws.members().cloned().collect();
    let (package_ids, resolve) = ops::resolve_ws(&ws)?;

    let dependencies = if args.all {
        all_dependencies(&members, package_ids, resolve)?
    } else {
        top_level_dependencies(&members, package_ids)?
    };

    let mut packages = BTreeSet::new();
    for package in &dependencies {
        let name = package.name().to_owned();
        let version = format!("{}", package.version());
        let licenses = format!("{}", package_licenses(package));
        let license_files = package_license_files(package)?;
        packages.insert((name, version, licenses, license_files));
    }

    let stdout = io::stdout();
    let mut out = stdout.lock();

    {
        let mut tw = tabwriter::TabWriter::new(&mut out);
        writeln!(tw, "Name\t| Version\t| Licenses")?;
        writeln!(tw, "----\t| -------\t| --------")?;
        for (name, version, licenses, _) in &packages {
            writeln!(tw, "{}\t| {}\t| {}", &name, &version, &licenses)?;
        }

        // TabWriter flush() makes the actual write to stdout.
        tw.flush()?;
    }

    writeln!(out)?;
    out.flush()?;

    for (name, version, _, license_files) in packages {
        if license_files.is_empty() {
            continue;
        }

        writeln!(out, "-----BEGIN {} {} LICENSES-----", name, version)?;

        let mut buf = Vec::new();
        let mut licenses_to_print = license_files.len();
        for file in license_files {
            let mut fs = std::fs::File::open(file)?;
            fs.read_to_end(&mut buf)?;
            out.write_all(&buf)?;
            buf.clear();
            if licenses_to_print > 1 {
                out.write_all(b"\n-----NEXT LICENSE-----\n")?;
                licenses_to_print -= 1;
            }
        }

        writeln!(out, "-----END {} {} LICENSES-----", name, version)?;
        writeln!(out)?;
    }

    out.flush()?;
    Ok(())
}

fn top_level_dependencies(
    members: &[Package],
    package_ids: PackageSet<'_>,
) -> CargoResult<BTreeSet<Package>> {
    let mut dependencies = BTreeSet::new();

    for member in members {
        for dependency in member.dependencies() {
            // Filter out Build and Development dependencies
            match dependency.kind() {
                DepKind::Normal => (),
                DepKind::Build | DepKind::Development => continue,
            }
            if let Some(dep) = package_ids
                .package_ids()
                .find(|id| dependency.matches_id(*id))
            {
                let package = package_ids.get_one(dep)?;
                dependencies.insert(package.to_owned());
            }
        }
    }

    // Filter out our own workspace crates from dependency list
    for member in members {
        dependencies.remove(member);
    }

    Ok(dependencies)
}

fn all_dependencies(
    members: &[Package],
    package_ids: PackageSet<'_>,
    resolve: Resolve,
) -> CargoResult<BTreeSet<Package>> {
    let mut dependencies = BTreeSet::new();

    for package_id in resolve.iter() {
        let package = package_ids.get_one(package_id)?;
        if members.contains(&package) {
            // Skip listing our own packages in our workspace
            continue;
        }
        dependencies.insert(package.to_owned());
    }

    Ok(dependencies)
}

fn package_licenses(package: &Package) -> Licenses<'_> {
    let metadata = package.manifest().metadata();

    if let Some(ref license_str) = metadata.license {
        let licenses: BTreeSet<&str> = license_str
            .split("OR")
            .map(|s| s.split("AND"))
            .flatten()
            .map(|s| s.split('/'))
            .flatten()
            .map(str::trim)
            .collect();
        return Licenses::Licenses(licenses);
    }

    if let Some(ref license_file) = metadata.license_file {
        return Licenses::File(license_file);
    }

    Licenses::Missing
}

static LICENCE_FILE_NAMES: &[&str] = &["LICENSE", "UNLICENSE"];

fn package_license_files(package: &Package) -> io::Result<Vec<path::PathBuf>> {
    let mut result = Vec::new();

    if let Some(path) = package.manifest_path().parent() {
        for entry in path.read_dir()?.flatten() {
            if let Ok(name) = entry.file_name().into_string() {
                for license_name in LICENCE_FILE_NAMES {
                    if name.starts_with(license_name) {
                        result.push(entry.path())
                    }
                }
            }
        }
    }

    Ok(result)
}

#[derive(Debug)]
enum Licenses<'a> {
    Licenses(BTreeSet<&'a str>),
    File(&'a str),
    Missing,
}

impl<'a> fmt::Display for Licenses<'a> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
        match *self {
            Licenses::File(_) => write!(f, "Specified in license file"),
            Licenses::Missing => write!(f, "Missing"),
            Licenses::Licenses(ref lic_names) => {
                let lics: Vec<String> = lic_names.iter().map(|s| String::from(*s)).collect();
                write!(f, "{}", lics.join(", "))
            }
        }
    }
}
<|endoftext|>


<commit_before>#![allow(unused_must_use)]
extern crate curl;
extern crate docopt;
extern crate rustc_serialize;
extern crate term;

use std::str;

use curl::http;
use docopt::Docopt;
use rustc_serialize::json;

#[macro_use]
mod macros;

const USAGE: &'static str = "
Scrutch - Crates Search

Usage:
  scrutch [--info] <query>
  scrutch (-h | --help)
  scrutch --version

Options:
  -h --help     Show this screen.
  --version     Show version.
  --info        Show complete details of the crates.
";

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_info: bool,
    arg_query: String
}

#[derive(Debug, RustcDecodable, RustcEncodable)]
struct Meta {
  total: i32,
}

#[derive(Debug, RustcDecodable, RustcEncodable)]
struct Response {
  crates: Vec<EncodableCrate>,
  meta: Meta,
}

// structs from crates.io backend

#[derive(Debug, RustcDecodable, RustcEncodable)]
struct EncodableCrate {
  id: String,
  name: String,
  updated_at: String,
  versions: Option<Vec<i32>>,
  created_at: String,
  downloads: i32,
  max_version: String,
  description: Option<String>,
  homepage: Option<String>,
  documentation: Option<String>,
  keywords: Vec<String>,
  license: Option<String>,
  repository: Option<String>,
  links: CrateLinks,
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
struct CrateLinks {
  version_downloads: String,
  versions: Option<String>,
  owners: Option<String>,
  reverse_dependencies: String,
}

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

  let mut t = term::stdout().unwrap();

  // TODO: think about implementing page and per_page via an option, maybe
  let url = format!(
    "https://crates.io/api/v1/crates?q={}&page=1&per_page=10",
    args.arg_query
  );
  let res = match http::handle().get(url).exec() {
      Ok(res) => res,
      Err(e) => { p_red!(t, "{}\n", e); return; }
  };
  let body = str::from_utf8(res.get_body()).unwrap();
  let mut data:Response = json::decode(&body).unwrap();

  // TODO: Add decoding of updated_at and allow to use it for sorting
  let mut crates = &mut data.crates[..];
  crates.sort_by(|c1, c2| {c2.downloads.cmp(&c1.downloads)});

  p_white!(t, "scrutch: {} crates found with query: {}\n\n", crates.len(), args.arg_query);
  for cr in crates {
    show_crate(&mut t, cr, args.flag_info);
  }
  t.reset().unwrap();
}

fn show_crate(t: &mut Box<term::StdoutTerminal>, cr: &EncodableCrate, info: bool) {
  p_green!(t, "{} ", cr.id);
  p_white!(t, "(downloads: {})\n", cr.downloads);

  if info {
    if_some!(&cr.description, p_yellow!(t, " -> {}\n", &cr.description.clone().unwrap()));

    if_some!(&cr.documentation, p_white!(t, "    docs: {}\n", &cr.documentation.clone().unwrap()));
    if_some!(&cr.homepage, p_white!(t, "    home: {}\n", &cr.homepage.clone().unwrap()));
    p_white!(t, "\n");
  }
}

// fn print_if_present(prefix: &str, label: &str, data: &Option<String>) -> String {
//   match data {
//     &Some(ref info) => format!("{}{}{}\n", prefix, label, info),
//     &None => format!("")
//   }
// }<commit_msg>Code cleaned<commit_after>#![allow(unused_must_use)]
extern crate curl;
extern crate docopt;
extern crate rustc_serialize;
extern crate term;

use std::str;

use curl::http;
use docopt::Docopt;
use rustc_serialize::json;

#[macro_use]
mod macros;

const USAGE: &'static str = "
Scrutch - Crates Search

Usage:
  scrutch [--info] <query>
  scrutch (-h | --help)
  scrutch --version

Options:
  -h --help     Show this screen.
  --version     Show version.
  --info        Show complete details of the crates.
";

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_info: bool,
    arg_query: String
}

#[derive(Debug, RustcDecodable, RustcEncodable)]
struct Meta {
  total: i32,
}

#[derive(Debug, RustcDecodable, RustcEncodable)]
struct Response {
  crates: Vec<EncodableCrate>,
  meta: Meta,
}

// structs from crates.io backend

#[derive(Debug, RustcDecodable, RustcEncodable)]
struct EncodableCrate {
  id: String,
  name: String,
  updated_at: String,
  versions: Option<Vec<i32>>,
  created_at: String,
  downloads: i32,
  max_version: String,
  description: Option<String>,
  homepage: Option<String>,
  documentation: Option<String>,
  keywords: Vec<String>,
  license: Option<String>,
  repository: Option<String>,
  links: CrateLinks,
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
struct CrateLinks {
  version_downloads: String,
  versions: Option<String>,
  owners: Option<String>,
  reverse_dependencies: String,
}

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

  let mut t = term::stdout().unwrap();

  // TODO: think about implementing page and per_page via an option, maybe
  let url = format!(
    "https://crates.io/api/v1/crates?q={}&page=1&per_page=10",
    args.arg_query
  );
  let res = match http::handle().get(url).exec() {
      Ok(res) => res,
      Err(e) => { p_red!(t, "{}\n", e); return; }
  };
  let body = str::from_utf8(res.get_body()).unwrap();
  let mut data:Response = json::decode(&body).unwrap();

  // TODO: Add decoding of updated_at and allow to use it for sorting
  let mut crates = &mut data.crates[..];
  crates.sort_by(|c1, c2| {c2.downloads.cmp(&c1.downloads)});

  p_white!(t, "scrutch: {} crates found with query: {}\n\n", crates.len(), args.arg_query);
  for cr in crates {
    show_crate(&mut t, cr, args.flag_info);
  }
  t.reset().unwrap();
}

fn show_crate(t: &mut Box<term::StdoutTerminal>, cr: &EncodableCrate, info: bool) {
  p_green!(t, "{} ", cr.id);
  p_white!(t, "(downloads: {})\n", cr.downloads);

  if info {
    if_some!(&cr.description, p_yellow!(t, " -> {}\n", &cr.description.clone().unwrap()));

    if_some!(&cr.documentation, p_white!(t, "    docs: {}\n", &cr.documentation.clone().unwrap()));
    if_some!(&cr.homepage, p_white!(t, "    home: {}\n", &cr.homepage.clone().unwrap()));
    p_white!(t, "\n");
  }
}<|endoftext|>


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

#![feature(iter_arith, zero_one, custom_derive,
           custom_attribute, plugin, const_fn)]
#![plugin(serde_macros)]
#![plugin(clippy)]

#![allow(match_same_arms)] // we seem to have instances where same arms are good
#![allow(dead_code)] // only temporary, until more stuff is filled in

extern crate devicemapper;
#[macro_use] extern crate clap;
#[macro_use] extern crate nix;
extern crate crc;
extern crate byteorder;
extern crate uuid;
extern crate time;
extern crate serde;
extern crate serde_json;
extern crate bytesize;
extern crate dbus;
extern crate term;

#[macro_use] extern crate custom_derive;
#[macro_use] extern crate newtype_derive;

pub static mut debug: bool = false;

macro_rules! dbgp {
    ($($arg:tt)*) => (
        unsafe {
            if ::debug {
                println!($($arg)*)
            }
        })
}

mod types;
mod consts;
mod froyo;
mod blockdev;
mod raid;
mod thin;
mod util;
mod dbus_api;

use std::io::Write;
use std::error::Error;
use std::process::exit;
use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::cell::RefCell;

use clap::{App, Arg, SubCommand, ArgMatches};
use bytesize::ByteSize;
use dbus::{Connection, BusType};

use types::{FroyoResult, FroyoError, InternalError};
use consts::SECTOR_SIZE;
use froyo::{Froyo, FroyoStatus};

// We are given BlockDevs to start.
// We allocate LinearDevs from each for the meta and data devices.
// We use all these to make RaidDevs.
// We create two RaidLinearDevs from these for meta and data devices.
// We use these to make a ThinPoolDev.
// From that, we allocate a ThinDev.

fn list(_args: &ArgMatches) -> FroyoResult<()> {
    let froyos = try!(Froyo::find_all());
    for f in &froyos {
        println!("{}", f.name);
    }

    Ok(())
}

fn status(args: &ArgMatches) -> FroyoResult<()> {
    let name = args.value_of("froyodevname").unwrap();
    match try!(Froyo::find(&name)) {
        Some(f) => {
            let status = match try!(f.status()) {
                FroyoStatus::Good(_) => "good",
                FroyoStatus::RaidFailed => "RAID failed",
                FroyoStatus::ThinPoolFailed => "Thin pool failed",
                FroyoStatus::ThinFailed => "Thin device failed",
            };

            let space = *try!(f.avail_redundant_space()) * SECTOR_SIZE;
            let total = *f.total_redundant_space() * SECTOR_SIZE;

            let percent = ((total-space) * 100) / total;

            println!("Status: {}, {}% used ({} of {} free)",
                     status, percent,
                     ByteSize::b(space as usize).to_string(true),
                     ByteSize::b(total as usize).to_string(true));
        },
        None => return Err(FroyoError::Froyo(InternalError(
            format!("Froyodev \"{}\" not found", name)))),
    }
    Ok(())
}

fn add(args: &ArgMatches) -> FroyoResult<()> {
    let name = args.value_of("froyodevname").unwrap();
    let dev_paths: Vec<_> = args.values_of("devices").unwrap().into_iter()
        .map(|dev| {
            if Path::new(dev).is_absolute() {
                PathBuf::from(dev)
            } else {
                PathBuf::from(format!("/dev/{}", dev))
            }})
        .collect();
    let force = args.is_present("force");

    let mut froyo = match try!(Froyo::find(&name)) {
        Some(f) => f,
        None => return Err(FroyoError::Froyo(InternalError(
            format!("Froyodev \"{}\" not found", name)))),
    };

    for path in &dev_paths {
        try!(froyo.add_block_device(path, force))
    }
    try!(froyo.save_state());

    Ok(())
}

fn remove(args: &ArgMatches) -> FroyoResult<()> {
    let name = args.value_of("froyodevname").unwrap();
    let bd_path = {
        let dev = args.value_of("blockdev").unwrap();
        if Path::new(dev).is_absolute() {
            PathBuf::from(dev)
        } else {
            PathBuf::from(format!("/dev/{}", dev))
        }
    };

    let mut froyo = match try!(Froyo::find(&name)) {
        Some(f) => f,
        None => return Err(FroyoError::Froyo(InternalError(
            format!("Froyodev \"{}\" not found", name)))),
    };

    try!(froyo.remove_block_device(&bd_path));
    try!(froyo.save_state());

    Ok(())
}

fn create(args: &ArgMatches) -> FroyoResult<()> {
    let name = args.value_of("froyodevname").unwrap();
    let dev_paths: Vec<_> = args.values_of("devices").unwrap().into_iter()
        .map(|dev| {
            if Path::new(dev).is_absolute() {
                PathBuf::from(dev)
            } else {
                PathBuf::from(format!("/dev/{}", dev))
            }})
        .collect();
    let force = args.is_present("force");

    let froyo = try!(Froyo::new(name, &dev_paths, force));

    try!(froyo.save_state());

    dbgp!("Froyodev {} created", froyo.name);

    Ok(())
}

fn rename(args: &ArgMatches) -> FroyoResult<()> {
    let old_name = args.value_of("froyodev_old_name").unwrap();
    let new_name = args.value_of("froyodev_new_name").unwrap();

    match try!(Froyo::find(&old_name)) {
        Some(mut f) => {
            f.name = new_name.to_owned();
            try!(f.save_state());
            dbgp!("Froyodev name {} changed to {}", old_name, new_name);
        },
        None => return Err(FroyoError::Froyo(InternalError(
            format!("Froyodev \"{}\" not found", old_name)))),
    }

    Ok(())
}

fn destroy(args: &ArgMatches) -> FroyoResult<()> {
    let name = args.value_of("froyodev").unwrap();

    match try!(Froyo::find(&name)) {
        Some(f) => {
            try!(f.destroy());
            dbgp!("Froyodev {} destroyed", name);
        },
        None => return Err(FroyoError::Froyo(InternalError(
            format!("Froyodev \"{}\" not found", name)))),
    }

    Ok(())
}

fn dump_meta(args: &ArgMatches) -> FroyoResult<()> {
    let name = args.value_of("froyodevname").unwrap();
    match try!(Froyo::find(&name)) {
        Some(f) =>
            println!("{}", try!(f.to_metadata_pretty())),
        None => return Err(FroyoError::Froyo(InternalError(
            format!("Froyodev \"{}\" not found", name)))),
    }

    Ok(())
}

fn dbus_server(_args: &ArgMatches) -> FroyoResult<()> {
    let c = Connection::get_private(BusType::Session).unwrap();
    let froyos = try!(Froyo::find_all());
    let froyos = froyos.into_iter()
        .map(|f| Rc::new(RefCell::new(f)))
        .collect::<Vec<_>>();
    let mut froyos = Rc::new(RefCell::new(froyos));
    let tree = try!(dbus_api::get_tree(&c, &mut froyos));

    // TODO: event loop needs to handle dbus and also dm events (or polling)
    // so we can extend/reshape/delay/whatever in a timely fashion
    for _ in tree.run(&c, c.iter(1000)) {

        let froyos = RefCell::borrow(&*froyos);
        for froyo in &*froyos {
            let mut froyo = RefCell::borrow_mut(froyo);
            try!(froyo.check_status());
            try!(froyo.dump_status());
        }
    }

    Ok(())
}

fn teardown(args: &ArgMatches) -> FroyoResult<()> {
    let name = args.value_of("froyodevname").unwrap();
    match try!(Froyo::find(&name)) {
        Some(mut f) => try!(f.teardown()),
        None => return Err(FroyoError::Froyo(InternalError(
            format!("Froyodev \"{}\" not found", name)))),
    }

    Ok(())
}

fn write_err(err: FroyoError) -> FroyoResult<()> {
    let mut out = term::stderr().expect("could not get stderr");

    try!(out.fg(term::color::RED));
    try!(writeln!(out, "{}", err.description()));
    try!(out.reset());
    Ok(())
}

fn main() {

    let matches = App::new("froyo")
        .version(&crate_version!())
        .author("Andy Grover <andy@groveronline.com>")
        .about("Drobo + Free + YOLO")
        .arg(Arg::with_name("debug")
             .short("d")
             .long("debug")
             .help("Print additional output for debugging")
             )
        .subcommand(SubCommand::with_name("list")
                    .about("List all froyodevs")
                    .arg(Arg::with_name("long")
                         .short("l")
                         .long("long")
                         .help("Use a long listing format")
                         )
                    )
        .subcommand(SubCommand::with_name("status")
                    .about("Get the status of a single froyodev")
                    .arg(Arg::with_name("froyodevname")
                         .required(true)
                         .help("Froyodev to get info on")
                         .index(1)
                         )
                    )
        .subcommand(SubCommand::with_name("add")
                    .about("Add one or more additional block devices to a froyodev")
                    .arg(Arg::with_name("force")
                         .short("f")
                         .long("force")
                         .help("Force")
                    )
                    .arg(Arg::with_name("froyodevname")
                         .help("Froyodev to add the device to")
                         .required(true)
                         .index(1)
                         )
                    .arg(Arg::with_name("devices")
                         .help("device(s) to add")
                         .multiple(true)
                         .required(true)
                         .index(2)
                         )
                    )
        .subcommand(SubCommand::with_name("remove")
                    .about("Remove a block device from a froyodev")
                    .arg(Arg::with_name("froyodevname")
                         .help("Froyodev to remove the device from")
                         .required(true)
                         .index(1)
                         )
                    .arg(Arg::with_name("blockdev")
                         .help("Block device to remove")
                         .required(true)
                         .index(2)
                         )
                    )
        .subcommand(SubCommand::with_name("create")
                    .about("Create a new froyodev")
                    .arg(Arg::with_name("force")
                         .short("f")
                         .long("force")
                         .help("Force")
                         )
                    .arg(Arg::with_name("froyodevname")
                         .help("Name of the new froyodev")
                         .required(true)
                         .index(1)
                         )
                    .arg(Arg::with_name("devices")
                         .help("Initial block device(s) to use")
                         .multiple(true)
                         .required(true)
                         .index(2)
                         )
                    )
        .subcommand(SubCommand::with_name("rename")
                    .about("Rename a froyodev")
                    .arg(Arg::with_name("froyodev_old_name")
                         .help("Old name of froyodev")
                         .required(true)
                         .index(1)
                    )
                    .arg(Arg::with_name("froyodev_new_name")
                         .help("New name of froyodev")
                         .required(true)
                         .index(2)
                    )
        )
        .subcommand(SubCommand::with_name("destroy")
                    .about("Destroy a froyodev")
                    .arg(Arg::with_name("froyodev")
                         .help("Froyodev to destroy")
                         .required(true)
                         .index(1)
                    )
        )
        .subcommand(SubCommand::with_name("dev")
                    .about("Developer/debug commands")
                    .subcommand(SubCommand::with_name("dump_meta")
                                .about("Output the JSON metadata for a froyodev")
                                .arg(Arg::with_name("froyodevname")
                                     .help("Name of the froyodev")
                                     .required(true)
                                     .index(1)
                                     )
                                )
                    .subcommand(SubCommand::with_name("teardown")
                                .about("Remove the DM mappings for a froyodev")
                                .arg(Arg::with_name("froyodevname")
                                     .help("Name of the froyodev")
                                     .required(true)
                                     .index(1)
                                     )
                                )
                    .subcommand(SubCommand::with_name("dbus_server")
                                .about("Serve the Froyo DBus API")
                                )
                    )
        .get_matches();

    if matches.is_present("debug") {
        // must use unsafe to change a mut static, sigh
        unsafe { debug = true };
    }

    let r = match matches.subcommand() {
        ("list", Some(matches)) => list(matches),
        ("status", Some(matches)) => status(matches),
        ("add", Some(matches)) => add(matches),
        ("remove", Some(matches)) => remove(matches),
        ("create", Some(matches)) => create(matches),
        ("rename", Some(matches)) => rename(matches),
        ("destroy", Some(matches)) => destroy(matches),
        ("dev", Some(matches)) => match matches.subcommand() {
            ("dump_meta", Some(matches)) => dump_meta(matches),
            ("dbus_server", Some(matches)) => dbus_server(matches),
            ("teardown", Some(matches)) => teardown(matches),
            ("", None) => {
                println!("No command given, try \"help\"");
                Ok(())
            }
            _ => unreachable!(),
        },
        ("", None) => {
            println!("No command given, try \"help\"");
            Ok(())
        }
        _ => unreachable!(),
    };

    if let Err(r) = r {
        if let Err(e) = write_err(r) {
            panic!("Unable to write to stderr: {}", e)
        }

        exit(1);
    }
}
<commit_msg>Change dbus_server poll interval to 10 seconds<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#![feature(iter_arith, zero_one, custom_derive,
           custom_attribute, plugin, const_fn)]
#![plugin(serde_macros)]
#![plugin(clippy)]

#![allow(match_same_arms)] // we seem to have instances where same arms are good
#![allow(dead_code)] // only temporary, until more stuff is filled in

extern crate devicemapper;
#[macro_use] extern crate clap;
#[macro_use] extern crate nix;
extern crate crc;
extern crate byteorder;
extern crate uuid;
extern crate time;
extern crate serde;
extern crate serde_json;
extern crate bytesize;
extern crate dbus;
extern crate term;

#[macro_use] extern crate custom_derive;
#[macro_use] extern crate newtype_derive;

pub static mut debug: bool = false;

macro_rules! dbgp {
    ($($arg:tt)*) => (
        unsafe {
            if ::debug {
                println!($($arg)*)
            }
        })
}

mod types;
mod consts;
mod froyo;
mod blockdev;
mod raid;
mod thin;
mod util;
mod dbus_api;

use std::io::Write;
use std::error::Error;
use std::process::exit;
use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::cell::RefCell;

use clap::{App, Arg, SubCommand, ArgMatches};
use bytesize::ByteSize;
use dbus::{Connection, BusType};

use types::{FroyoResult, FroyoError, InternalError};
use consts::SECTOR_SIZE;
use froyo::{Froyo, FroyoStatus};

// We are given BlockDevs to start.
// We allocate LinearDevs from each for the meta and data devices.
// We use all these to make RaidDevs.
// We create two RaidLinearDevs from these for meta and data devices.
// We use these to make a ThinPoolDev.
// From that, we allocate a ThinDev.

fn list(_args: &ArgMatches) -> FroyoResult<()> {
    let froyos = try!(Froyo::find_all());
    for f in &froyos {
        println!("{}", f.name);
    }

    Ok(())
}

fn status(args: &ArgMatches) -> FroyoResult<()> {
    let name = args.value_of("froyodevname").unwrap();
    match try!(Froyo::find(&name)) {
        Some(f) => {
            let status = match try!(f.status()) {
                FroyoStatus::Good(_) => "good",
                FroyoStatus::RaidFailed => "RAID failed",
                FroyoStatus::ThinPoolFailed => "Thin pool failed",
                FroyoStatus::ThinFailed => "Thin device failed",
            };

            let space = *try!(f.avail_redundant_space()) * SECTOR_SIZE;
            let total = *f.total_redundant_space() * SECTOR_SIZE;

            let percent = ((total-space) * 100) / total;

            println!("Status: {}, {}% used ({} of {} free)",
                     status, percent,
                     ByteSize::b(space as usize).to_string(true),
                     ByteSize::b(total as usize).to_string(true));
        },
        None => return Err(FroyoError::Froyo(InternalError(
            format!("Froyodev \"{}\" not found", name)))),
    }
    Ok(())
}

fn add(args: &ArgMatches) -> FroyoResult<()> {
    let name = args.value_of("froyodevname").unwrap();
    let dev_paths: Vec<_> = args.values_of("devices").unwrap().into_iter()
        .map(|dev| {
            if Path::new(dev).is_absolute() {
                PathBuf::from(dev)
            } else {
                PathBuf::from(format!("/dev/{}", dev))
            }})
        .collect();
    let force = args.is_present("force");

    let mut froyo = match try!(Froyo::find(&name)) {
        Some(f) => f,
        None => return Err(FroyoError::Froyo(InternalError(
            format!("Froyodev \"{}\" not found", name)))),
    };

    for path in &dev_paths {
        try!(froyo.add_block_device(path, force))
    }
    try!(froyo.save_state());

    Ok(())
}

fn remove(args: &ArgMatches) -> FroyoResult<()> {
    let name = args.value_of("froyodevname").unwrap();
    let bd_path = {
        let dev = args.value_of("blockdev").unwrap();
        if Path::new(dev).is_absolute() {
            PathBuf::from(dev)
        } else {
            PathBuf::from(format!("/dev/{}", dev))
        }
    };

    let mut froyo = match try!(Froyo::find(&name)) {
        Some(f) => f,
        None => return Err(FroyoError::Froyo(InternalError(
            format!("Froyodev \"{}\" not found", name)))),
    };

    try!(froyo.remove_block_device(&bd_path));
    try!(froyo.save_state());

    Ok(())
}

fn create(args: &ArgMatches) -> FroyoResult<()> {
    let name = args.value_of("froyodevname").unwrap();
    let dev_paths: Vec<_> = args.values_of("devices").unwrap().into_iter()
        .map(|dev| {
            if Path::new(dev).is_absolute() {
                PathBuf::from(dev)
            } else {
                PathBuf::from(format!("/dev/{}", dev))
            }})
        .collect();
    let force = args.is_present("force");

    let froyo = try!(Froyo::new(name, &dev_paths, force));

    try!(froyo.save_state());

    dbgp!("Froyodev {} created", froyo.name);

    Ok(())
}

fn rename(args: &ArgMatches) -> FroyoResult<()> {
    let old_name = args.value_of("froyodev_old_name").unwrap();
    let new_name = args.value_of("froyodev_new_name").unwrap();

    match try!(Froyo::find(&old_name)) {
        Some(mut f) => {
            f.name = new_name.to_owned();
            try!(f.save_state());
            dbgp!("Froyodev name {} changed to {}", old_name, new_name);
        },
        None => return Err(FroyoError::Froyo(InternalError(
            format!("Froyodev \"{}\" not found", old_name)))),
    }

    Ok(())
}

fn destroy(args: &ArgMatches) -> FroyoResult<()> {
    let name = args.value_of("froyodev").unwrap();

    match try!(Froyo::find(&name)) {
        Some(f) => {
            try!(f.destroy());
            dbgp!("Froyodev {} destroyed", name);
        },
        None => return Err(FroyoError::Froyo(InternalError(
            format!("Froyodev \"{}\" not found", name)))),
    }

    Ok(())
}

fn dump_meta(args: &ArgMatches) -> FroyoResult<()> {
    let name = args.value_of("froyodevname").unwrap();
    match try!(Froyo::find(&name)) {
        Some(f) =>
            println!("{}", try!(f.to_metadata_pretty())),
        None => return Err(FroyoError::Froyo(InternalError(
            format!("Froyodev \"{}\" not found", name)))),
    }

    Ok(())
}

fn dbus_server(_args: &ArgMatches) -> FroyoResult<()> {
    let c = Connection::get_private(BusType::Session).unwrap();
    let froyos = try!(Froyo::find_all());
    let froyos = froyos.into_iter()
        .map(|f| Rc::new(RefCell::new(f)))
        .collect::<Vec<_>>();
    let mut froyos = Rc::new(RefCell::new(froyos));
    let tree = try!(dbus_api::get_tree(&c, &mut froyos));

    // TODO: event loop needs to handle dbus and also dm events (or polling)
    // so we can extend/reshape/delay/whatever in a timely fashion
    for _ in tree.run(&c, c.iter(10000)) {

        let froyos = RefCell::borrow(&*froyos);
        for froyo in &*froyos {
            let mut froyo = RefCell::borrow_mut(froyo);
            try!(froyo.check_status());
            try!(froyo.dump_status());
        }
    }

    Ok(())
}

fn teardown(args: &ArgMatches) -> FroyoResult<()> {
    let name = args.value_of("froyodevname").unwrap();
    match try!(Froyo::find(&name)) {
        Some(mut f) => try!(f.teardown()),
        None => return Err(FroyoError::Froyo(InternalError(
            format!("Froyodev \"{}\" not found", name)))),
    }

    Ok(())
}

fn write_err(err: FroyoError) -> FroyoResult<()> {
    let mut out = term::stderr().expect("could not get stderr");

    try!(out.fg(term::color::RED));
    try!(writeln!(out, "{}", err.description()));
    try!(out.reset());
    Ok(())
}

fn main() {

    let matches = App::new("froyo")
        .version(&crate_version!())
        .author("Andy Grover <andy@groveronline.com>")
        .about("Drobo + Free + YOLO")
        .arg(Arg::with_name("debug")
             .short("d")
             .long("debug")
             .help("Print additional output for debugging")
             )
        .subcommand(SubCommand::with_name("list")
                    .about("List all froyodevs")
                    .arg(Arg::with_name("long")
                         .short("l")
                         .long("long")
                         .help("Use a long listing format")
                         )
                    )
        .subcommand(SubCommand::with_name("status")
                    .about("Get the status of a single froyodev")
                    .arg(Arg::with_name("froyodevname")
                         .required(true)
                         .help("Froyodev to get info on")
                         .index(1)
                         )
                    )
        .subcommand(SubCommand::with_name("add")
                    .about("Add one or more additional block devices to a froyodev")
                    .arg(Arg::with_name("force")
                         .short("f")
                         .long("force")
                         .help("Force")
                    )
                    .arg(Arg::with_name("froyodevname")
                         .help("Froyodev to add the device to")
                         .required(true)
                         .index(1)
                         )
                    .arg(Arg::with_name("devices")
                         .help("device(s) to add")
                         .multiple(true)
                         .required(true)
                         .index(2)
                         )
                    )
        .subcommand(SubCommand::with_name("remove")
                    .about("Remove a block device from a froyodev")
                    .arg(Arg::with_name("froyodevname")
                         .help("Froyodev to remove the device from")
                         .required(true)
                         .index(1)
                         )
                    .arg(Arg::with_name("blockdev")
                         .help("Block device to remove")
                         .required(true)
                         .index(2)
                         )
                    )
        .subcommand(SubCommand::with_name("create")
                    .about("Create a new froyodev")
                    .arg(Arg::with_name("force")
                         .short("f")
                         .long("force")
                         .help("Force")
                         )
                    .arg(Arg::with_name("froyodevname")
                         .help("Name of the new froyodev")
                         .required(true)
                         .index(1)
                         )
                    .arg(Arg::with_name("devices")
                         .help("Initial block device(s) to use")
                         .multiple(true)
                         .required(true)
                         .index(2)
                         )
                    )
        .subcommand(SubCommand::with_name("rename")
                    .about("Rename a froyodev")
                    .arg(Arg::with_name("froyodev_old_name")
                         .help("Old name of froyodev")
                         .required(true)
                         .index(1)
                    )
                    .arg(Arg::with_name("froyodev_new_name")
                         .help("New name of froyodev")
                         .required(true)
                         .index(2)
                    )
        )
        .subcommand(SubCommand::with_name("destroy")
                    .about("Destroy a froyodev")
                    .arg(Arg::with_name("froyodev")
                         .help("Froyodev to destroy")
                         .required(true)
                         .index(1)
                    )
        )
        .subcommand(SubCommand::with_name("dev")
                    .about("Developer/debug commands")
                    .subcommand(SubCommand::with_name("dump_meta")
                                .about("Output the JSON metadata for a froyodev")
                                .arg(Arg::with_name("froyodevname")
                                     .help("Name of the froyodev")
                                     .required(true)
                                     .index(1)
                                     )
                                )
                    .subcommand(SubCommand::with_name("teardown")
                                .about("Remove the DM mappings for a froyodev")
                                .arg(Arg::with_name("froyodevname")
                                     .help("Name of the froyodev")
                                     .required(true)
                                     .index(1)
                                     )
                                )
                    .subcommand(SubCommand::with_name("dbus_server")
                                .about("Serve the Froyo DBus API")
                                )
                    )
        .get_matches();

    if matches.is_present("debug") {
        // must use unsafe to change a mut static, sigh
        unsafe { debug = true };
    }

    let r = match matches.subcommand() {
        ("list", Some(matches)) => list(matches),
        ("status", Some(matches)) => status(matches),
        ("add", Some(matches)) => add(matches),
        ("remove", Some(matches)) => remove(matches),
        ("create", Some(matches)) => create(matches),
        ("rename", Some(matches)) => rename(matches),
        ("destroy", Some(matches)) => destroy(matches),
        ("dev", Some(matches)) => match matches.subcommand() {
            ("dump_meta", Some(matches)) => dump_meta(matches),
            ("dbus_server", Some(matches)) => dbus_server(matches),
            ("teardown", Some(matches)) => teardown(matches),
            ("", None) => {
                println!("No command given, try \"help\"");
                Ok(())
            }
            _ => unreachable!(),
        },
        ("", None) => {
            println!("No command given, try \"help\"");
            Ok(())
        }
        _ => unreachable!(),
    };

    if let Err(r) = r {
        if let Err(e) = write_err(r) {
            panic!("Unable to write to stderr: {}", e)
        }

        exit(1);
    }
}
<|endoftext|>


<commit_before>extern crate getopts;
extern crate rayon;
extern crate libc;
extern crate rff;

mod interface;

use std::env;
use std::io::{self, BufRead, Write, BufWriter};
use std::process;
use rayon::prelude::*;
use getopts::{Options, Fail};
use rff::Choice;
use interface::{Interface, Error};

fn main() {
    let code = run();
    process::exit(code);
}

fn run() -> i32 {
    let args = env::args().skip(1).collect::<Vec<String>>();
    let mut opts = Options::new();

    opts.optopt("s", "search", "Output sorted matches of QUERY", "QUERY");
    opts.optopt("q", "query", "Use QUERY as the initial search string", "QUERY");
    opts.optflag("", "benchmark", "Run search in benchmark mode");
    opts.optflag("h", "help", "Display this help and exit");
    opts.optflag("v", "version", "Display version information and exit");

    let matches = match opts.parse(args).map_err(translate_parse_error) {
        Ok(matches) => matches,
        Err(err) => {
            println!("{}", err);
            print_usage(opts);
            return 1;
        }
    };

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

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

    let choices = get_choices();

    if matches.opt_present("benchmark") {
        if !matches.opt_present("s") {
            println!("Must specify -s/--search with --benchmark");
            return 1;
        }

        let search = matches.opt_str("s").unwrap();

        for _ in 0..100 {
            choices.
                par_iter().
                filter_map(|choice| Choice::new(&search, choice)).
                collect::<Vec<Choice>>().
                sort_by(|a, b| a.partial_cmp(b).unwrap().reverse());
        }
    } else if matches.opt_present("s") {
        let search = matches.opt_str("s").unwrap();

        let mut choices = choices.
            par_iter().
            filter_map(|choice| Choice::new(&search, choice)).
            collect::<Vec<Choice>>();

        choices.sort_by(|a, b| a.partial_cmp(b).unwrap().reverse());

        let stdout = io::stdout();
        let mut stdout = BufWriter::new(stdout.lock());

        for choice in choices {
            writeln!(stdout, "{}", choice.0).unwrap();
        }
    } else {
        let choices = choices.iter().map(|x| &x[..]).collect::<Vec<&str>>();

        let opts = interface::Options {
            choices: choices,
            initial: matches.opt_str("q").unwrap_or_default()
        };

        let mut interface = Interface::from_opts(opts);

        match interface.run() {
            Ok(result) => println!("{}", result),
            Err(Error::Exit) => return 1,
            Err(e) => {
                println!("error: {:?}", e);
                return 1;
            }
        }
    }

    0
}

fn get_choices() -> Vec<String> {
    let mut lines = vec![];

    let stdin = io::stdin();

    for line in stdin.lock().lines() {
        lines.push(line.unwrap());
    }

    lines
}

fn translate_parse_error(err: Fail) -> String {
    match err {
        Fail::ArgumentMissing(opt) => format!("Argument missing: {}", opt),
        Fail::UnrecognizedOption(opt) => format!("Invalid option: {}", opt),
        Fail::OptionMissing(opt) => format!("Missing option: {}", opt),
        Fail::OptionDuplicated(opt) => format!("Duplicated option: {}", opt),
        Fail::UnexpectedArgument(opt) => format!("Unexpected argument: {}", opt)
    }
}

fn print_usage(opts: Options) {
    let prelude = format!("Usage: {} [options]", env!("CARGO_PKG_NAME"));
    print!("{}", opts.usage(&prelude));
}

fn print_version() {
    println!("{}", env!("CARGO_PKG_VERSION"));
}
<commit_msg>Simplify process of getting choices from stdin<commit_after>extern crate getopts;
extern crate rayon;
extern crate libc;
extern crate rff;

mod interface;

use std::env;
use std::io::{self, BufRead, Write, BufWriter};
use std::process;
use rayon::prelude::*;
use getopts::{Options, Fail};
use rff::Choice;
use interface::{Interface, Error};

fn main() {
    let code = run();
    process::exit(code);
}

fn run() -> i32 {
    let args = env::args().skip(1).collect::<Vec<String>>();
    let mut opts = Options::new();

    opts.optopt("s", "search", "Output sorted matches of QUERY", "QUERY");
    opts.optopt("q", "query", "Use QUERY as the initial search string", "QUERY");
    opts.optflag("", "benchmark", "Run search in benchmark mode");
    opts.optflag("h", "help", "Display this help and exit");
    opts.optflag("v", "version", "Display version information and exit");

    let matches = match opts.parse(args).map_err(translate_parse_error) {
        Ok(matches) => matches,
        Err(err) => {
            println!("{}", err);
            print_usage(opts);
            return 1;
        }
    };

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

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

    let choices = get_choices();

    if matches.opt_present("benchmark") {
        if !matches.opt_present("s") {
            println!("Must specify -s/--search with --benchmark");
            return 1;
        }

        let search = matches.opt_str("s").unwrap();

        for _ in 0..100 {
            choices.
                par_iter().
                filter_map(|choice| Choice::new(&search, choice)).
                collect::<Vec<Choice>>().
                sort_by(|a, b| a.partial_cmp(b).unwrap().reverse());
        }
    } else if matches.opt_present("s") {
        let search = matches.opt_str("s").unwrap();

        let mut choices = choices.
            par_iter().
            filter_map(|choice| Choice::new(&search, choice)).
            collect::<Vec<Choice>>();

        choices.sort_by(|a, b| a.partial_cmp(b).unwrap().reverse());

        let stdout = io::stdout();
        let mut stdout = BufWriter::new(stdout.lock());

        for choice in choices {
            writeln!(stdout, "{}", choice.0).unwrap();
        }
    } else {
        let choices = choices.iter().map(|x| &x[..]).collect::<Vec<&str>>();

        let opts = interface::Options {
            choices: choices,
            initial: matches.opt_str("q").unwrap_or_default()
        };

        let mut interface = Interface::from_opts(opts);

        match interface.run() {
            Ok(result) => println!("{}", result),
            Err(Error::Exit) => return 1,
            Err(e) => {
                println!("error: {:?}", e);
                return 1;
            }
        }
    }

    0
}

fn get_choices() -> Vec<String> {
    let stdin = io::stdin();
    let lines = stdin.lock().lines().map(Result::unwrap).collect();
    lines
}

fn translate_parse_error(err: Fail) -> String {
    match err {
        Fail::ArgumentMissing(opt) => format!("Argument missing: {}", opt),
        Fail::UnrecognizedOption(opt) => format!("Invalid option: {}", opt),
        Fail::OptionMissing(opt) => format!("Missing option: {}", opt),
        Fail::OptionDuplicated(opt) => format!("Duplicated option: {}", opt),
        Fail::UnexpectedArgument(opt) => format!("Unexpected argument: {}", opt)
    }
}

fn print_usage(opts: Options) {
    let prelude = format!("Usage: {} [options]", env!("CARGO_PKG_NAME"));
    print!("{}", opts.usage(&prelude));
}

fn print_version() {
    println!("{}", env!("CARGO_PKG_VERSION"));
}
<|endoftext|>


<commit_before>fn main() {
    println!("Hello, world!");
}
<commit_msg>Renders black screen<commit_after>extern crate piston;
extern crate graphics;
extern crate glutin_window;
extern crate opengl_graphics;

use piston::window::WindowSettings;
use piston::event::*;
use glutin_window::GlutinWindow as Window;
use opengl_graphics::{ GlGraphics, OpenGL };

pub struct App {
	gl: GlGraphics
}

impl App {
	fn render(&mut self, args: &RenderArgs) {
		use graphics::*;

		const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 0.0];

		self.gl.draw(args.viewport(), |c, gl| {
			clear(BLACK, gl);
		});
	}
}

fn main() {
	let opengl = OpenGL::_3_2;

	let window = Window::new(
		WindowSettings::new(
			"rusty-smash",
			[1280, 720]
		)
		.exit_on_esc(true)
	);

	let mut app = App {
		gl: GlGraphics::new(opengl)
	};

	for e in window.events() {
		if let Some(r) = e.render_args() {
			app.render(&r);
		}
	}
}<|endoftext|>


<commit_before>extern crate piston;
extern crate glutin_window;
extern crate graphics;
extern crate opengl_graphics;
extern crate rand;

use piston::window::WindowSettings;
use glutin_window::GlutinWindow as Window;
use opengl_graphics::{GlGraphics, OpenGL};
use rand::thread_rng;
use std::cell::RefCell;
use std::rc::Rc;

mod actors;
mod intersect;
mod scene;
use scene::{MainScene, Scene};

fn main() {
    let opengl = OpenGL::V3_2;
    const WIDTH: f64 = 200.0;
    const HEIGHT: f64 = 200.0;

    let window = Rc::new(RefCell::new(Window::new(
        WindowSettings::new(
            "vs-game",
            [WIDTH as u32, HEIGHT as u32],
        )
        .exit_on_esc(true)
    ).unwrap()));

    let mut gl = GlGraphics::new(opengl);
    let mut rng = rand::thread_rng();

    let mut scene: Box<Scene> = Box::new(MainScene::new(1, &mut rng));
    while let Some(new_scene) = scene.events(&mut rng, window.clone(), &mut gl, (WIDTH, HEIGHT)) {
        scene = new_scene;
    }
}
<commit_msg>Begun using config object<commit_after>extern crate piston;
extern crate glutin_window;
extern crate graphics;
extern crate opengl_graphics;
extern crate rand;

use piston::window::WindowSettings;
use glutin_window::GlutinWindow as Window;
use opengl_graphics::{GlGraphics, OpenGL};
use rand::thread_rng;
use std::cell::RefCell;
use std::rc::Rc;

mod actors;
mod intersect;
mod scene;
mod config;
use scene::{MainScene, Scene};
use config::Config;

fn main() {
    let opengl = OpenGL::V3_2;
    let config = Config::new();

    let window = Rc::new(RefCell::new(Window::new(
        WindowSettings::new(
            "vs-game",
            [config.width() as u32, config.height() as u32],
        )
        .exit_on_esc(true)
    ).unwrap()));

    let mut gl = GlGraphics::new(opengl);
    let mut rng = rand::thread_rng();

    let mut scene: Box<Scene> = Box::new(MainScene::new(1, &mut rng));
    while let Some(new_scene) = scene.events(&mut rng, window.clone(), &mut gl, (config.width(), config.height())) {
        scene = new_scene;
    }
}
<|endoftext|>


<commit_before>extern crate rand;

use std::cmp::min;
use std::vec::Vec;
use rand::Rng;

fn main() {
    let mut rng = rand::thread_rng();
    let mut bv = [0; 65536];
    for i in 0..65536 {
        bv[i] = (rng.gen::<usize>()%2) as u8;
    }
    let fid = Fid::new(&bv);

    let s = std::time::Instant::now();
    for i in 0..10000 {
        fid.rank(rng.gen::<usize>()%65536);
    }
    let e = s.elapsed();
    let elapsed = e.as_secs()*1_000_000_000 + e.subsec_nanos() as u64;
    println!("FID:");
    println!("{:?}ms", elapsed/1_000_000);
    println!("{:?}us/query", elapsed/10000/1000);

    let s = std::time::Instant::now();
    for i in 0..10000 {
        rank_mock(&bv, rng.gen::<usize>()%65536);
    }
    let e = s.elapsed();
    let elapsed = e.as_secs()*1_000_000_000 + e.subsec_nanos() as u64;
    println!("normal:");
    println!("{:?}ms", elapsed/1_000_000);
    println!("{:?}us/query", elapsed/10000/1000);
}

struct Fid<'a> {
    raw: &'a [u8]
    ,big_block_size: usize
    ,big_blocks: Vec<usize>
    ,small_block_size: usize
    ,small_blocks: Vec<usize>
}

impl<'a> Fid<'a> {
    fn new(bv: &[u8]) -> Fid{
        let mut ret = Fid {
            raw: bv
            ,big_block_size: 0
            ,big_blocks: Vec::new()
            ,small_block_size: 0
            ,small_blocks: Vec::new()
        };
        ret.build();
        ret
    }

    fn build(&mut self) {
        let n = self.raw.len();
        let big_block_size = (n as f64).log2().powi(2).floor() as usize; // (lg(n))^2
        let small_block_size = ((n as f64).log2()/2.0).floor() as usize; // lg(n)/2
        self.big_block_size = big_block_size;
        self.small_block_size = small_block_size;

        let mut cntb = 0;
        let mut cnts = 0;
        for i in 0..n {
            if i%big_block_size==0 {
                self.big_blocks.push(cntb);
            }
            if i%small_block_size==0 {
                let s = cnts - self.big_blocks.last().unwrap();
                self.small_blocks.push(s);
            }
            if self.raw[i]==1 {
                cntb = cntb + 1;
                cnts = cnts + 1;
            }
        }
    }

    fn rank(&self, idx: usize) -> usize {
        let mut rank = 0;

        let p = idx % self.big_block_size;
        let pos = min((idx-p)/self.big_block_size, self.big_blocks.len()-1);
        rank += self.big_blocks[pos];

        let sp = p % self.small_block_size;
        let spos = pos*self.big_block_size/self.small_block_size + (p-sp)/self.small_block_size;
        rank += self.small_blocks[spos];

        for i in (pos*self.big_block_size+spos*self.small_block_size)..min(idx,self.raw.len()) {
            if self.raw[i]== 1 {
                rank += 1;
            }
        }
        rank
    }
}

fn rank_mock(bv: &[u8], idx: usize) -> usize {
    let mut ret = 0;
    let len = min(bv.len(), idx);

    for i in 0..len {
        if bv[i]==1 {
            ret = ret + 1;
        }
    }

    ret
}

fn select_mock(bv: &[u8], idx: usize) -> usize {
    let mut cnt = 0;
    for i in 0..bv.len() {
        if bv[i]==1 {
            cnt = cnt+1;
        }
        if cnt==idx+1 {
            return i;
        }
    }
    return 0;
}

#[test]
fn rank_test() {
    let bv = [0,1,0,1];
    let fid = Fid::new(&bv);

    assert_eq!(rank_mock(&bv, 0), 0);
    assert_eq!(rank_mock(&bv, 1), 0);
    assert_eq!(rank_mock(&bv, 2), 1);
    assert_eq!(rank_mock(&bv, 3), 1);
    assert_eq!(rank_mock(&bv, 4), 2);
    assert_eq!(rank_mock(&bv, 5), 2);

    assert_eq!(rank_mock(&bv, 0), fid.rank(0));
    assert_eq!(rank_mock(&bv, 1), fid.rank(1));
    assert_eq!(rank_mock(&bv, 2), fid.rank(2));
    assert_eq!(rank_mock(&bv, 3), fid.rank(3));
    assert_eq!(rank_mock(&bv, 4), fid.rank(4));
    assert_eq!(rank_mock(&bv, 5), fid.rank(5));

    let mut bv = [0; 64];
    bv[50] = 1;
    let fid = Fid::new(&bv);
    assert_eq!(rank_mock(&bv, 64), fid.rank(64));
}

#[test]
fn select_test() {
    let bv = [0,1,0,1];
    assert_eq!(select_mock(&bv, 0), 1);
    assert_eq!(select_mock(&bv, 1), 3);
    assert_eq!(select_mock(&bv, 2), 0);
}
<commit_msg>selectの実装<commit_after>extern crate rand;

use std::cmp::min;
use std::vec::Vec;
use rand::Rng;

fn main() {
    let mut rng = rand::thread_rng();
    let mut bv = [0; 65536];
    for i in 0..65536 {
        bv[i] = (rng.gen::<usize>()%2) as u8;
    }
    let fid = Fid::new(&bv);

    let s = std::time::Instant::now();
    for i in 0..10000 {
        fid.rank(rng.gen::<usize>()%65536);
    }
    let e = s.elapsed();
    let elapsed = e.as_secs()*1_000_000_000 + e.subsec_nanos() as u64;
    println!("FID:");
    println!("{:?}ms", elapsed/1_000_000);
    println!("{:?}us/query", elapsed/10000/1000);

    let s = std::time::Instant::now();
    for i in 0..10000 {
        rank_mock(&bv, rng.gen::<usize>()%65536);
    }
    let e = s.elapsed();
    let elapsed = e.as_secs()*1_000_000_000 + e.subsec_nanos() as u64;
    println!("normal:");
    println!("{:?}ms", elapsed/1_000_000);
    println!("{:?}us/query", elapsed/10000/1000);
}

struct Fid<'a> {
    raw: &'a [u8]
    ,big_block_size: usize
    ,big_blocks: Vec<usize>
    ,small_block_size: usize
    ,small_blocks: Vec<usize>
}

impl<'a> Fid<'a> {
    fn new(bv: &[u8]) -> Fid{
        let mut ret = Fid {
            raw: bv
            ,big_block_size: 0
            ,big_blocks: Vec::new()
            ,small_block_size: 0
            ,small_blocks: Vec::new()
        };
        ret.build();
        ret
    }

    fn build(&mut self) {
        let n = self.raw.len();
        let big_block_size = (n as f64).log2().powi(2).floor() as usize; // (lg(n))^2
        let small_block_size = ((n as f64).log2()/2.0).floor() as usize; // lg(n)/2
        self.big_block_size = big_block_size;
        self.small_block_size = small_block_size;

        let mut cntb = 0;
        let mut cnts = 0;
        for i in 0..n {
            if i%big_block_size==0 {
                self.big_blocks.push(cntb);
            }
            if i%small_block_size==0 {
                let s = cnts - self.big_blocks.last().unwrap();
                self.small_blocks.push(s);
            }
            if self.raw[i]==1 {
                cntb = cntb + 1;
                cnts = cnts + 1;
            }
        }
    }

    fn rank(&self, idx: usize) -> usize {
        let mut rank = 0;

        let p = idx % self.big_block_size;
        let pos = min((idx-p)/self.big_block_size, self.big_blocks.len()-1);
        rank += self.big_blocks[pos];

        let sp = p % self.small_block_size;
        let spos = pos*self.big_block_size/self.small_block_size + (p-sp)/self.small_block_size;
        rank += self.small_blocks[spos];

        for i in (pos*self.big_block_size+spos*self.small_block_size)..min(idx,self.raw.len()) {
            if self.raw[i]== 1 {
                rank += 1;
            }
        }
        rank
    }

    fn select(&self, n: usize) -> usize {
        let mut l = 0;
        let mut u = self.raw.len();

        while u-l>1 {
            let m = (((l+u) as f32)/2.0).floor() as usize;
            if n < self.rank(m) {
                u = m;
            } else {
                l = m;
            }
        }
        if n==self.rank(l) {
            l
        } else {
            self.raw.len()
        }
    }
}

fn rank_mock(bv: &[u8], idx: usize) -> usize {
    let mut ret = 0;
    let len = min(bv.len(), idx);

    for i in 0..len {
        if bv[i]==1 {
            ret = ret + 1;
        }
    }

    ret
}

fn select_mock(bv: &[u8], idx: usize) -> usize {
    let mut cnt = 0;
    for i in 0..bv.len() {
        if bv[i]==1 {
            cnt = cnt+1;
        }
        if cnt==idx+1 {
            return i;
        }
    }
    return bv.len()
}

#[test]
fn rank_test() {
    let bv = [0,1,0,1];
    let fid = Fid::new(&bv);

    assert_eq!(rank_mock(&bv, 0), 0);
    assert_eq!(rank_mock(&bv, 1), 0);
    assert_eq!(rank_mock(&bv, 2), 1);
    assert_eq!(rank_mock(&bv, 3), 1);
    assert_eq!(rank_mock(&bv, 4), 2);
    assert_eq!(rank_mock(&bv, 5), 2);

    assert_eq!(rank_mock(&bv, 0), fid.rank(0));
    assert_eq!(rank_mock(&bv, 1), fid.rank(1));
    assert_eq!(rank_mock(&bv, 2), fid.rank(2));
    assert_eq!(rank_mock(&bv, 3), fid.rank(3));
    assert_eq!(rank_mock(&bv, 4), fid.rank(4));
    assert_eq!(rank_mock(&bv, 5), fid.rank(5));

    let mut bv = [0; 64];
    bv[50] = 1;
    let fid = Fid::new(&bv);
    assert_eq!(rank_mock(&bv, 64), fid.rank(64));
}

#[test]
fn select_test() {
    let bv = [0,1,0,1];
    let fid = Fid::new(&bv);
    assert_eq!(select_mock(&bv, 0), 1);
    assert_eq!(select_mock(&bv, 1), 3);
    assert_eq!(select_mock(&bv, 2), 4);

    assert_eq!(select_mock(&bv, 0), fid.select(0));
    assert_eq!(select_mock(&bv, 1), fid.select(1));
    assert_eq!(select_mock(&bv, 2), fid.select(2));

    let mut bv = [0; 64];
    bv[30] = 1;
    bv[50] = 1;
    let fid = Fid::new(&bv);
    assert_eq!(select_mock(&bv, 0), fid.select(0));
    assert_eq!(select_mock(&bv, 1), fid.select(1));
}
<|endoftext|>