<commit_before>#![deny(warnings)]

extern crate clap;
extern crate fern;
extern crate rustc_version;
extern crate tempdir;

#[macro_use]
extern crate log;

use std::fs::{self, File};
use std::io::{Read, Write};
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};

use clap::{App, AppSettings, Arg, SubCommand};

// TODO proper error reporting
macro_rules! try {
    ($e:expr) => {
        $e.unwrap_or_else(|_| panic!(stringify!($e)))
    }
}

struct Context<'a> {
    commit_hash: &'a str,
    host: &'a str,
    out_dir: &'a Path,
    release: bool,
    target: &'a str,
}

fn main() {
    let rustc_version::VersionMeta { ref host, ref commit_hash, .. } =
        rustc_version::version_meta();
    let commit_hash = commit_hash.as_ref().unwrap();

    let ref matches = App::new("cargo-sysroot")
                          .bin_name("cargo")
                          .settings(&[AppSettings::SubcommandRequired])
                          .subcommand(SubCommand::with_name("sysroot")
                                          .about("Builds a sysroot with cross compiled standard \
                                                  crates")
                                          .arg(Arg::with_name("triple")
                                                   .help("Target triple to compile for")
                                                   .long("target")
                                                   .required(true)
                                                   .takes_value(true))
                                          .arg(Arg::with_name("release")
                                                   .help("Build artifacts in release mode, \
                                                          with optimizations")
                                                   .long("release"))
                                          .arg(Arg::with_name("out_dir")
                                                   .help("Output directory")
                                                   .required(true))
                                          .author("Jorge Aparicio <japaricious@gmail.com>"))
                          .version(env!("CARGO_PKG_VERSION"))
                          .get_matches();

    if let Some(matches) = matches.subcommand_matches("sysroot") {
        if let (Some(target), Some(out_dir)) = (matches.value_of("triple"),
                                                matches.value_of("out_dir")) {
            if host == target {
                panic!("`cargo sysroot` for host has not been implement yet");
            }

            let ref ctx = Context {
                commit_hash: commit_hash,
                host: host,
                out_dir: Path::new(out_dir),
                release: matches.is_present("release"),
                target: target,
            };

            init_logger();
            fetch_source(ctx);
            symlink_host_crates(ctx);
            build_target_crates(ctx);
        }
    }
}

fn init_logger() {
    let config = fern::DispatchConfig {
        format: Box::new(|msg, level, _| format!("{}: {}", level, msg)),
        output: vec![fern::OutputConfig::stderr()],
        level: log::LogLevelFilter::Trace,
    };

    try!(fern::init_global_logger(config, log::LogLevelFilter::Trace));
}

fn fetch_source(ctx: &Context) {
    let hash = ctx.commit_hash;
    let ref src_dir = ctx.out_dir.join("src");
    let ref hash_file = src_dir.join(".commit-hash");

    if hash_file.exists() {
        let ref mut old_hash = String::with_capacity(hash.len());
        try!(try!(File::open(hash_file)).read_to_string(old_hash));

        if old_hash == hash {
            info!("source up to date");
            return;
        }
    }

    if src_dir.exists() {
        info!("purging the src directory");
        try!(fs::remove_dir_all(src_dir));
    }

    try!(fs::create_dir_all(src_dir));

    // FIXME don't rely on `curl` and `tar`, instead implement this functionality in Rust.
    // Check https://github.com/Diggsey/multirust-rs for a reference implementation of such
    // functionality
    info!("fetching source tarball");
    let ref curl = try!(Command::new("curl")
                            .arg("-L")
                            .arg(format!("https://github.com/rust-lang/rust/tarball/{}", hash))
                            .output());

    assert!(curl.status.success());

    info!("unpacking source tarball");
    let short_hash = &hash[..7];
    let ref mut tar = try!(Command::new("tar")
                               .args(&["-xz", "--strip-components", "2", "-C"])
                               .arg(src_dir)
                               .arg(format!("rust-lang-rust-{}/src", short_hash))
                               .stdin(Stdio::piped())
                               .spawn());
    try!(tar.stdin.as_mut().unwrap().write_all(&curl.stdout));

    info!("creating .commit-hash file");
    try!(try!(File::create(hash_file)).write_all(hash.as_bytes()));
}

fn symlink_host_crates(ctx: &Context) {
    info!("symlinking host crates");

    let sys_root = try!(String::from_utf8(try!(Command::new("rustc")
                                                   .args(&["--print", "sysroot"])
                                                   .output())
                                              .stdout));
    let ref src = Path::new(sys_root.trim_right()).join(format!("lib/rustlib/{}", ctx.host));
    let ref rustlib_dir = ctx.out_dir.join("lib/rustlib");
    let ref dst = rustlib_dir.join(ctx.host);

    try!(fs::create_dir_all(rustlib_dir));

    if dst.exists() {
        try!(fs::remove_file(dst));
    }

    match () {
        #[cfg(unix)]
        () => {
            use std::os::unix::fs;

            try!(fs::symlink(src, dst))
        }
        #[cfg(windows)]
        () => {
            use std::os::windaws::fs;

            try!(fs::symlink_dir(src, dst))
        }
    }
}

// XXX we only build the core crate for now
// TODO build the rest of crates
fn build_target_crates(ctx: &Context) {
    const CARGO_TOML: &'static str = r#"[package]
authors = ["The Rust Project Developers"]
name = "core"
version = "0.0.0"

[lib]
name = "core"
path = "lib.rs""#;

    let ref src_dir = ctx.out_dir.join("src/libcore");

    try!(try!(File::create(src_dir.join("Cargo.toml"))).write_all(CARGO_TOML.as_bytes()));

    let ref temp_dir = try!(tempdir::TempDir::new("core"));
    let temp_dir = temp_dir.path();

    let ref target_json = PathBuf::from(format!("{}.json", ctx.target));
    let mut spec_file = None;

    if target_json.exists() {
        let dst = src_dir.join(target_json);

        info!("copy target specification file");
        try!(fs::copy(target_json, &dst));
        spec_file = Some(dst);
    }

    info!("building the core crate");
    assert!(try!(Command::new("cargo")
                     .args(&["build", "--target"])
                     .arg(ctx.target)
                     .arg(if ctx.release {
                         "--release"
                     } else {
                         // XXX dummy value
                         "--lib"
                     })
                     .current_dir(src_dir)
                     .env("CARGO_TARGET_DIR", temp_dir)
                     .status())
                .success());

    if let Some(spec_file) = spec_file {
        info!("delete target specification file");
        try!(fs::remove_file(spec_file));
    }

    info!("copy the core crate to the sysroot");
    let ref libdir = ctx.out_dir.join(format!("lib/rustlib/{}/lib", ctx.target));
    try!(fs::create_dir_all(libdir));

    let ref src = temp_dir.join(format!("{}/{}/libcore.rlib",
                                        ctx.target,
                                        if ctx.release {
                                            "release"
                                        } else {
                                            "debug"
                                        }));
    let ref dst = libdir.join("libcore.rlib");
    try!(fs::copy(src, dst));
}
<commit_msg>feat: add --verbose flag<commit_after>#![deny(warnings)]

extern crate clap;
extern crate fern;
extern crate rustc_version;
extern crate tempdir;

#[macro_use]
extern crate log;

use std::fs::{self, File};
use std::io::{Read, Write};
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};

use clap::{App, AppSettings, Arg, SubCommand};

// TODO proper error reporting
macro_rules! try {
    ($e:expr) => {
        $e.unwrap_or_else(|_| panic!(stringify!($e)))
    }
}

struct Context<'a> {
    commit_hash: &'a str,
    host: &'a str,
    out_dir: &'a Path,
    release: bool,
    target: &'a str,
    verbose: bool,
}

fn main() {
    let rustc_version::VersionMeta { ref host, ref commit_hash, .. } =
        rustc_version::version_meta();
    let commit_hash = commit_hash.as_ref().unwrap();

    let ref matches = App::new("cargo-sysroot")
                          .bin_name("cargo")
                          .settings(&[AppSettings::SubcommandRequired])
                          .subcommand(SubCommand::with_name("sysroot")
                                          .about("Builds a sysroot with cross compiled standard \
                                                  crates")
                                          .arg(Arg::with_name("triple")
                                                   .help("Target triple to compile for")
                                                   .long("target")
                                                   .required(true)
                                                   .takes_value(true))
                                          .arg(Arg::with_name("release")
                                                   .help("Build artifacts in release mode, \
                                                          with optimizations")
                                                   .long("release"))
                                          .arg(Arg::with_name("out_dir")
                                                   .help("Output directory")
                                                   .required(true))
                                          .arg(Arg::with_name("verbose")
                                                   .help("Verbose cargo builds")
                                                   .long("verbose"))
                                          .author("Jorge Aparicio <japaricious@gmail.com>"))
                          .version(env!("CARGO_PKG_VERSION"))
                          .get_matches();

    if let Some(matches) = matches.subcommand_matches("sysroot") {
        if let (Some(target), Some(out_dir)) = (matches.value_of("triple"),
                                                matches.value_of("out_dir")) {
            if host == target {
                panic!("`cargo sysroot` for host has not been implement yet");
            }

            let ref ctx = Context {
                commit_hash: commit_hash,
                host: host,
                out_dir: Path::new(out_dir),
                release: matches.is_present("release"),
                target: target,
                verbose: matches.is_present("verbose"),
            };

            init_logger();
            fetch_source(ctx);
            symlink_host_crates(ctx);
            build_target_crates(ctx);
        }
    }
}

fn init_logger() {
    let config = fern::DispatchConfig {
        format: Box::new(|msg, level, _| format!("{}: {}", level, msg)),
        output: vec![fern::OutputConfig::stderr()],
        level: log::LogLevelFilter::Trace,
    };

    try!(fern::init_global_logger(config, log::LogLevelFilter::Trace));
}

fn fetch_source(ctx: &Context) {
    let hash = ctx.commit_hash;
    let ref src_dir = ctx.out_dir.join("src");
    let ref hash_file = src_dir.join(".commit-hash");

    if hash_file.exists() {
        let ref mut old_hash = String::with_capacity(hash.len());
        try!(try!(File::open(hash_file)).read_to_string(old_hash));

        if old_hash == hash {
            info!("source up to date");
            return;
        }
    }

    if src_dir.exists() {
        info!("purging the src directory");
        try!(fs::remove_dir_all(src_dir));
    }

    try!(fs::create_dir_all(src_dir));

    // FIXME don't rely on `curl` and `tar`, instead implement this functionality in Rust.
    // Check https://github.com/Diggsey/multirust-rs for a reference implementation of such
    // functionality
    info!("fetching source tarball");
    let ref curl = try!(Command::new("curl")
                            .arg("-L")
                            .arg(format!("https://github.com/rust-lang/rust/tarball/{}", hash))
                            .output());

    assert!(curl.status.success());

    info!("unpacking source tarball");
    let short_hash = &hash[..7];
    let ref mut tar = try!(Command::new("tar")
                               .args(&["-xz", "--strip-components", "2", "-C"])
                               .arg(src_dir)
                               .arg(format!("rust-lang-rust-{}/src", short_hash))
                               .stdin(Stdio::piped())
                               .spawn());
    try!(tar.stdin.as_mut().unwrap().write_all(&curl.stdout));

    info!("creating .commit-hash file");
    try!(try!(File::create(hash_file)).write_all(hash.as_bytes()));
}

fn symlink_host_crates(ctx: &Context) {
    info!("symlinking host crates");

    let sys_root = try!(String::from_utf8(try!(Command::new("rustc")
                                                   .args(&["--print", "sysroot"])
                                                   .output())
                                              .stdout));
    let ref src = Path::new(sys_root.trim_right()).join(format!("lib/rustlib/{}", ctx.host));
    let ref rustlib_dir = ctx.out_dir.join("lib/rustlib");
    let ref dst = rustlib_dir.join(ctx.host);

    try!(fs::create_dir_all(rustlib_dir));

    if dst.exists() {
        try!(fs::remove_file(dst));
    }

    match () {
        #[cfg(unix)]
        () => {
            use std::os::unix::fs;

            try!(fs::symlink(src, dst))
        }
        #[cfg(windows)]
        () => {
            use std::os::windaws::fs;

            try!(fs::symlink_dir(src, dst))
        }
    }
}

// XXX we only build the core crate for now
// TODO build the rest of crates
fn build_target_crates(ctx: &Context) {
    const CARGO_TOML: &'static str = r#"[package]
authors = ["The Rust Project Developers"]
name = "core"
version = "0.0.0"

[lib]
name = "core"
path = "lib.rs""#;

    let ref src_dir = ctx.out_dir.join("src/libcore");

    try!(try!(File::create(src_dir.join("Cargo.toml"))).write_all(CARGO_TOML.as_bytes()));

    let ref temp_dir = try!(tempdir::TempDir::new("core"));
    let temp_dir = temp_dir.path();

    let ref target_json = PathBuf::from(format!("{}.json", ctx.target));
    let mut spec_file = None;

    if target_json.exists() {
        let dst = src_dir.join(target_json);

        info!("copy target specification file");
        try!(fs::copy(target_json, &dst));
        spec_file = Some(dst);
    }

    info!("building the core crate");
    let mut cmd = Command::new("cargo");
    cmd.args(&["build", "--target", ctx.target]);
    if ctx.release {
        cmd.arg("--release");
    }
    if ctx.verbose {
        cmd.arg("--verbose");
    }
    assert!(try!(cmd.current_dir(src_dir).env("CARGO_TARGET_DIR", temp_dir).status()).success());

    if let Some(spec_file) = spec_file {
        info!("delete target specification file");
        try!(fs::remove_file(spec_file));
    }

    info!("copy the core crate to the sysroot");
    let ref libdir = ctx.out_dir.join(format!("lib/rustlib/{}/lib", ctx.target));
    try!(fs::create_dir_all(libdir));

    let ref src = temp_dir.join(format!("{}/{}/libcore.rlib",
                                        ctx.target,
                                        if ctx.release {
                                            "release"
                                        } else {
                                            "debug"
                                        }));
    let ref dst = libdir.join("libcore.rlib");
    try!(fs::copy(src, dst));
}
<|endoftext|>


<commit_before>#![warn(clippy::pedantic)]
#![warn(clippy::cargo)]
#![warn(clippy::nursery)]
#![deny(unsafe_code)]

use std::{
    fmt::{self, Display},
    result::Result as StdResult,
    time::Duration,
};

use anyhow::{anyhow, Context, Error};
use clap::ArgMatches;
use rgol::World;

mod screen;

const TICK_MS: u64 = 50;
const MAPS_MSG: &str = "\
MAPS:
    Maps must be rectangular. Whitespace is ignored.
    '·' (U+00B7 MIDDLE DOT) is a dead cell. Anything else is a living cell.";

type Result<T = ()> = anyhow::Result<T>;

fn main() {
    if let Err(err) = run() {
        eprintln!("error{}", DisplayCauses(err));
        std::process::exit(1);
    }
}

fn run() -> Result {
    use clap::{clap_app, crate_authors, crate_version};

    #[allow(clippy::needless_pass_by_value)]
    fn is_number(s: String) -> StdResult<(), String> {
        if s.chars().all(|c| c.is_digit(10)) {
            Ok(())
        } else {
            Err(format!("expected a number, found \"{}\"", s))
        }
    }

    let matches = clap_app!(rgol =>
        (about: "Conway's game of life for terminal in Rust")
        (author: crate_authors!())
        (version: crate_version!())
        (after_help: MAPS_MSG)
        (@setting ColoredHelp)
        (@setting SubcommandRequiredElseHelp)
        (@setting VersionlessSubcommands)
        (@subcommand genmap =>
            (about: "Prints an empty map")
            (@setting ColoredHelp)
            (@arg NROW: {is_number} * "Number of rows")
            (@arg NCOL: {is_number} * "Number of columns")
            (@arg space: -s --space "Adds spaces to the map"))
        (@subcommand play =>
            (about: "Plays the game (CTRL-c to exit)")
            (@setting ColoredHelp)
            (@arg FILE: * "File containing the map")
            (@arg TICK_MS: {is_number} "Elapsed time between iterations in ms")
        )
    )
    .get_matches();

    match matches.subcommand() {
        ("genmap", Some(args)) => genmap(args),
        ("play", Some(args)) => play(args),
        _ => anyhow::bail!("subcommands failed to match properly"),
    }
}

/// "genmap" subcommand.
///
/// Prints an empty map.
fn genmap(args: &ArgMatches<'_>) -> Result {
    let nrow = args
        .value_of("NROW")
        .ok_or_else(|| anyhow!("NROW has no value"))?
        .parse()
        .context("NROW is not a number")?;
    let ncol = args
        .value_of("NCOL")
        .ok_or_else(|| anyhow!("NCOL has no value"))?
        .parse()
        .context("NCOL is not a number")?;
    if nrow == 0 || ncol == 0 {
        return Ok(());
    }
    let line = if args.is_present("space") {
        let mut line = "· ".repeat(ncol);
        line.pop();
        line
    } else {
        "·".repeat(ncol)
    };
    for _ in 0..nrow {
        println!("{line}");
    }
    Ok(())
}

/// "play" subcommand.
///
/// Loads a map from a file and seeds the world with it, then plays it.
fn play(args: &ArgMatches<'_>) -> Result {
    let filename = args.value_of("FILE").ok_or_else(|| anyhow!("FILE has no value"))?;
    let tick_ms = args
        .value_of("TICK_MS")
        .map_or(Some(TICK_MS), |t_ms| t_ms.parse().ok())
        .ok_or_else(|| anyhow!("TICK_MS is not a number"))?;
    let tick = Duration::from_millis(tick_ms);
    let world = load_world(filename).with_context(|| filename.to_string())?;
    play_world(world, tick)
}

/// Loads and parses the world from a file.
fn load_world(filename: &str) -> Result<World> {
    Ok(std::fs::read_to_string(filename)?.parse()?)
}

/// Plays the world.
///
/// Prints every generation to the terminal screen.
#[cfg(target_os = "linux")]
// The `signal` crate only defines `Trap::wait` for linux, though it should
// work anywhere `sigtimedwait` is defined (which doesn’t include macOS).
fn play_world(mut world: World, tick: Duration) -> Result {
    use std::time::Instant;

    use screen::Screen;
    use signal::{trap::Trap, Signal};

    let sigtrap = Trap::trap(&[Signal::SIGINT]);
    let screen = Screen::init()?;
    let mut deadline = Instant::now();
    loop {
        screen.clear();
        println!("{world}");
        world.next();
        deadline += tick;
        if sigtrap.wait(deadline).is_some() {
            return Ok(());
        }
    }
}

/// Plays the world.
///
/// Prints every generation to the terminal screen.
#[cfg(all(unix, not(target_os = "linux")))]
// Anywhere `Trap::wait` isn’t defined we’ll have to rely on `sigwait`
// (through `Iterator::next`) though presumably some of those targets
// do define `sigtimedwait`.
fn play_world(mut world: World, tick: Duration) -> Result {
    use std::{
        panic,
        sync::mpsc::{channel, RecvTimeoutError},
        thread,
        time::Instant,
    };

    use screen::Screen;
    use signal::{trap::Trap, Signal};

    let sigtrap = Trap::trap(&[Signal::SIGINT]);
    let screen = Screen::init()?;
    let mut deadline = Instant::now();
    let (sender, receiver) = channel();
    let player = thread::spawn(move || {
        loop {
            screen.clear();
            println!("{world}");
            world.next();
            deadline += tick;
            let duration = deadline.saturating_duration_since(Instant::now());
            // TODO Use `Receiver::recv_deadline` when it becomes stable.
            match receiver.recv_timeout(duration) {
                Err(RecvTimeoutError::Timeout) => {}
                Ok(()) | Err(RecvTimeoutError::Disconnected) => return,
            }
        }
    });
    let signal = sigtrap.into_iter().next();
    sender.send(())?;
    if let Err(e) = player.join() {
        panic::resume_unwind(e);
    }
    match signal {
        Some(Signal::SIGINT) => Ok(()),
        Some(_) => anyhow::bail!("`Trap` returned with unexpected {:?} signal", signal),
        None => anyhow::bail!("`Trap` returned but no signal was received"),
    }
}

/// Displays the causes of an `Error` recursively.
struct DisplayCauses(Error);

impl Display for DisplayCauses {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        for cause in self.0.chain() {
            write!(f, ": {}", cause)?;
        }
        Ok(())
    }
}
<commit_msg>Display errors recursively `anyhow` and `Termination`<commit_after>#![warn(clippy::pedantic)]
#![warn(clippy::cargo)]
#![warn(clippy::nursery)]
#![deny(unsafe_code)]

use std::{result::Result as StdResult, time::Duration};

use anyhow::{anyhow, Context};
use clap::ArgMatches;
use rgol::World;

mod screen;

const TICK_MS: u64 = 50;
const MAPS_MSG: &str = "\
MAPS:
    Maps must be rectangular. Whitespace is ignored.
    '·' (U+00B7 MIDDLE DOT) is a dead cell. Anything else is a living cell.";

type Result<T = ()> = anyhow::Result<T>;

fn main() -> Result {
    use clap::{clap_app, crate_authors, crate_version};

    #[allow(clippy::needless_pass_by_value)]
    fn is_number(s: String) -> StdResult<(), String> {
        if s.chars().all(|c| c.is_digit(10)) {
            Ok(())
        } else {
            Err(format!("expected a number, found \"{}\"", s))
        }
    }

    let matches = clap_app!(rgol =>
        (about: "Conway's game of life for terminal in Rust")
        (author: crate_authors!())
        (version: crate_version!())
        (after_help: MAPS_MSG)
        (@setting ColoredHelp)
        (@setting SubcommandRequiredElseHelp)
        (@setting VersionlessSubcommands)
        (@subcommand genmap =>
            (about: "Prints an empty map")
            (@setting ColoredHelp)
            (@arg NROW: {is_number} * "Number of rows")
            (@arg NCOL: {is_number} * "Number of columns")
            (@arg space: -s --space "Adds spaces to the map"))
        (@subcommand play =>
            (about: "Plays the game (CTRL-c to exit)")
            (@setting ColoredHelp)
            (@arg FILE: * "File containing the map")
            (@arg TICK_MS: {is_number} "Elapsed time between iterations in ms")
        )
    )
    .get_matches();

    match matches.subcommand() {
        ("genmap", Some(args)) => genmap(args),
        ("play", Some(args)) => play(args),
        _ => anyhow::bail!("subcommands failed to match properly"),
    }
}

/// "genmap" subcommand.
///
/// Prints an empty map.
fn genmap(args: &ArgMatches<'_>) -> Result {
    let nrow = args
        .value_of("NROW")
        .ok_or_else(|| anyhow!("NROW has no value"))?
        .parse()
        .context("NROW is not a number")?;
    let ncol = args
        .value_of("NCOL")
        .ok_or_else(|| anyhow!("NCOL has no value"))?
        .parse()
        .context("NCOL is not a number")?;
    if nrow == 0 || ncol == 0 {
        return Ok(());
    }
    let line = if args.is_present("space") {
        let mut line = "· ".repeat(ncol);
        line.pop();
        line
    } else {
        "·".repeat(ncol)
    };
    for _ in 0..nrow {
        println!("{line}");
    }
    Ok(())
}

/// "play" subcommand.
///
/// Loads a map from a file and seeds the world with it, then plays it.
fn play(args: &ArgMatches<'_>) -> Result {
    let filename = args.value_of("FILE").ok_or_else(|| anyhow!("FILE has no value"))?;
    let tick_ms = args
        .value_of("TICK_MS")
        .map_or(Some(TICK_MS), |t_ms| t_ms.parse().ok())
        .ok_or_else(|| anyhow!("TICK_MS is not a number"))?;
    let tick = Duration::from_millis(tick_ms);
    let world = load_world(filename).with_context(|| format!("in {}", filename))?;
    play_world(world, tick)
}

/// Loads and parses the world from a file.
fn load_world(filename: &str) -> Result<World> {
    Ok(std::fs::read_to_string(filename)?.parse()?)
}

/// Plays the world.
///
/// Prints every generation to the terminal screen.
#[cfg(target_os = "linux")]
// The `signal` crate only defines `Trap::wait` for linux, though it should
// work anywhere `sigtimedwait` is defined (which doesn’t include macOS).
fn play_world(mut world: World, tick: Duration) -> Result {
    use std::time::Instant;

    use screen::Screen;
    use signal::{trap::Trap, Signal};

    let sigtrap = Trap::trap(&[Signal::SIGINT]);
    let screen = Screen::init()?;
    let mut deadline = Instant::now();
    loop {
        screen.clear();
        println!("{world}");
        world.next();
        deadline += tick;
        if sigtrap.wait(deadline).is_some() {
            return Ok(());
        }
    }
}

/// Plays the world.
///
/// Prints every generation to the terminal screen.
#[cfg(all(unix, not(target_os = "linux")))]
// Anywhere `Trap::wait` isn’t defined we’ll have to rely on `sigwait`
// (through `Iterator::next`) though presumably some of those targets
// do define `sigtimedwait`.
fn play_world(mut world: World, tick: Duration) -> Result {
    use std::{
        panic,
        sync::mpsc::{channel, RecvTimeoutError},
        thread,
        time::Instant,
    };

    use screen::Screen;
    use signal::{trap::Trap, Signal};

    let sigtrap = Trap::trap(&[Signal::SIGINT]);
    let screen = Screen::init()?;
    let mut deadline = Instant::now();
    let (sender, receiver) = channel();
    let player = thread::spawn(move || {
        loop {
            screen.clear();
            println!("{world}");
            world.next();
            deadline += tick;
            let duration = deadline.saturating_duration_since(Instant::now());
            // TODO Use `Receiver::recv_deadline` when it becomes stable.
            match receiver.recv_timeout(duration) {
                Err(RecvTimeoutError::Timeout) => {}
                Ok(()) | Err(RecvTimeoutError::Disconnected) => return,
            }
        }
    });
    let signal = sigtrap.into_iter().next();
    sender.send(())?;
    if let Err(e) = player.join() {
        panic::resume_unwind(e);
    }
    match signal {
        Some(Signal::SIGINT) => Ok(()),
        Some(_) => anyhow::bail!("`Trap` returned with unexpected {:?} signal", signal),
        None => anyhow::bail!("`Trap` returned but no signal was received"),
    }
}
<|endoftext|>


<commit_before>use std::path::Path;
use std::process;
mod lib;

#[macro_use]
extern crate clap;
use clap::App;

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

fn main() {

    env_logger::init().expect("Failed to init env_logger!");

    let cli_yaml = load_yaml!("cli.yml");
    let app = App::from_yaml(cli_yaml);
    let matches = app.get_matches();

    debug!("{:?}", matches);

    // Check aruments
    let path = match matches.value_of("PATH") {
        Some(path) => path,
        None => {
            println!("{}", matches.usage());
            process::exit(1);
        }
    };

    let delimiter = matches.value_of("delimiter").unwrap_or(" - ");
    let depth = matches.value_of("depth").unwrap_or("1").parse::<usize>().unwrap();
    let rgb = matches.is_present("rgb");
    let colors = matches.is_present("colors");
    let num_colors = matches.value_of("NUM_COLORS").unwrap_or("5").parse::<usize>().unwrap();

    let mut pixels = lib::fetch_colors(&Path::new(path), depth);
    pixels = lib::sort_colors(&pixels, num_colors);

    lib::print_colors(pixels, colors, delimiter, rgb);
}
<commit_msg>simplified default<commit_after>use std::path::Path;
use std::process;
mod lib;

#[macro_use]
extern crate clap;
use clap::App;

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

fn main() {

    env_logger::init().expect("Failed to init env_logger!");

    let cli_yaml = load_yaml!("cli.yml");
    let app = App::from_yaml(cli_yaml);
    let matches = app.get_matches();

    debug!("{:?}", matches);

    // Check aruments
    let path = match matches.value_of("PATH") {
        Some(path) => path,
        None => {
            println!("{}", matches.usage());
            process::exit(1);
        }
    };

    let delimiter = matches.value_of("delimiter").unwrap();
    let depth = matches.value_of("depth").unwrap_or("1").parse::<usize>().unwrap();
    let rgb = matches.is_present("rgb");
    let colors = matches.is_present("colors");
    let num_colors = matches.value_of("NUM_COLORS").unwrap_or("5").parse::<usize>().unwrap();

    let mut pixels = lib::fetch_colors(&Path::new(path), depth);
    pixels = lib::sort_colors(&pixels, num_colors);

    lib::print_colors(pixels, colors, delimiter, rgb);
}
<|endoftext|>


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

/*!

Operations on the ubiquitous `Option` type.

Type `Option` represents an optional value.

Every `Option<T>` value can either be `Some(T)` or `None`. Where in other
languages you might use a nullable type, in Rust you would use an option
type.

Options are most commonly used with pattern matching to query the presence
of a value and take action, always accounting for the `None` case.

# Example

~~~
let msg = Some(~"howdy");

// Take a reference to the contained string
match msg {
    Some(ref m) => io::println(m),
    None => ()
}

// Remove the contained string, destroying the Option
let unwrapped_msg = match move msg {
    Some(move m) => m,
    None => ~"default message"
};
~~~

*/

#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];

use cmp::Eq;
use kinds::Copy;
use option;
use ptr;
use str;
use util;
use num::Zero;

/// The option type
#[deriving_eq]
pub enum Option<T> {
    None,
    Some(T),
}

pub pure fn get<T: Copy>(opt: Option<T>) -> T {
    /*!
    Gets the value out of an option

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
    */

    match opt {
      Some(copy x) => return x,
      None => fail ~"option::get none"
    }
}

pub pure fn get_ref<T>(opt: &r/Option<T>) -> &r/T {
    /*!
    Gets an immutable reference to the value inside an option.

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
     */
    match *opt {
        Some(ref x) => x,
        None => fail ~"option::get_ref none"
    }
}

pub pure fn map<T, U>(opt: &Option<T>, f: fn(x: &T) -> U) -> Option<U> {
    //! Maps a `some` value by reference from one type to another

    match *opt { Some(ref x) => Some(f(x)), None => None }
}

pub pure fn map_consume<T, U>(opt: Option<T>,
                              f: fn(v: T) -> U) -> Option<U> {
    /*!
     * As `map`, but consumes the option and gives `f` ownership to avoid
     * copying.
     */
    match opt { None => None, Some(v) => Some(f(v)) }
}

pub pure fn chain<T, U>(opt: Option<T>,
                        f: fn(t: T) -> Option<U>) -> Option<U> {
    /*!
     * Update an optional value by optionally running its content through a
     * function that returns an option.
     */

    match move opt {
        Some(move t) => f(move t),
        None => None
    }
}

pub pure fn chain_ref<T, U>(opt: &Option<T>,
                            f: fn(x: &T) -> Option<U>) -> Option<U> {
    /*!
     * Update an optional value by optionally running its content by reference
     * through a function that returns an option.
     */

    match *opt { Some(ref x) => f(x), None => None }
}

pub pure fn or<T>(opta: Option<T>, optb: Option<T>) -> Option<T> {
    /*!
     * Returns the leftmost some() value, or none if both are none.
     */
    match move opta {
        Some(move opta) => Some(move opta),
        _ => move optb
    }
}

#[inline(always)]
pub pure fn while_some<T>(x: Option<T>, blk: fn(v: T) -> Option<T>) {
    //! Applies a function zero or more times until the result is none.

    let mut opt = move x;
    while opt.is_some() {
        opt = blk(unwrap(move opt));
    }
}

pub pure fn is_none<T>(opt: &Option<T>) -> bool {
    //! Returns true if the option equals `none`

    match *opt { None => true, Some(_) => false }
}

pub pure fn is_some<T>(opt: &Option<T>) -> bool {
    //! Returns true if the option contains some value

    !is_none(opt)
}

pub pure fn get_or_zero<T: Copy Zero>(opt: Option<T>) -> T {
    //! Returns the contained value or zero (for this type)

    match opt { Some(copy x) => x, None => Zero::zero() }
}

pub pure fn get_or_default<T: Copy>(opt: Option<T>, def: T) -> T {
    //! Returns the contained value or a default

    match opt { Some(copy x) => x, None => def }
}

pub pure fn map_default<T, U>(opt: &Option<T>, def: U,
                              f: fn(x: &T) -> U) -> U {
    //! Applies a function to the contained value or returns a default

    match *opt { None => move def, Some(ref t) => f(t) }
}

pub pure fn iter<T>(opt: &Option<T>, f: fn(x: &T)) {
    //! Performs an operation on the contained value by reference
    match *opt { None => (), Some(ref t) => f(t) }
}

#[inline(always)]
pub pure fn unwrap<T>(opt: Option<T>) -> T {
    /*!
    Moves a value out of an option type and returns it.

    Useful primarily for getting strings, vectors and unique pointers out
    of option types without copying them.

    # Failure

    Fails if the value equals `None`.

    # Safety note

    In general, because this function may fail, its use is discouraged.
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
     */
    match move opt {
        Some(move x) => move x,
        None => fail ~"option::unwrap none"
    }
}

#[inline(always)]
pub fn swap_unwrap<T>(opt: &mut Option<T>) -> T {
    /*!
    The option dance. Moves a value out of an option type and returns it,
    replacing the original with `None`.

    # Failure

    Fails if the value equals `None`.
     */
    if opt.is_none() { fail ~"option::swap_unwrap none" }
    unwrap(util::replace(opt, None))
}

pub pure fn expect<T>(opt: Option<T>, reason: &str) -> T {
    //! As unwrap, but with a specified failure message.
    match move opt {
        Some(move val) => val,
        None => fail reason.to_owned(),
    }
}

impl<T> Option<T> {
    /// Returns true if the option equals `none`
    #[inline(always)]
    pure fn is_none(&self) -> bool { is_none(self) }

    /// Returns true if the option contains some value
    #[inline(always)]
    pure fn is_some(&self) -> bool { is_some(self) }

    /**
     * Update an optional value by optionally running its content by reference
     * through a function that returns an option.
     */
    #[inline(always)]
    pure fn chain_ref<U>(&self, f: fn(x: &T) -> Option<U>) -> Option<U> {
        chain_ref(self, f)
    }

    /// Maps a `some` value from one type to another by reference
    #[inline(always)]
    pure fn map<U>(&self, f: fn(x: &T) -> U) -> Option<U> { map(self, f) }

    /// As `map`, but consumes the option and gives `f` ownership to avoid
    /// copying.
    #[inline(always)]
    pure fn map_consume<U>(self, f: fn(v: T) -> U) -> Option<U> {
        map_consume(self, f)
    }

    /// Applies a function to the contained value or returns a default
    #[inline(always)]
    pure fn map_default<U>(&self, def: U, f: fn(x: &T) -> U) -> U {
        map_default(self, move def, f)
    }

    /// As `map_default`, but consumes the option and gives `f`
    /// ownership to avoid copying.
    #[inline(always)]
    pure fn map_consume_default<U>(self, def: U, f: fn(v: T) -> U) -> U {
        match self { None => def, Some(v) => f(v) }
    }

    /// Performs an operation on the contained value by reference
    #[inline(always)]
    pure fn iter(&self, f: fn(x: &T)) { iter(self, f) }

    /**
    Gets an immutable reference to the value inside an option.

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
     */
    #[inline(always)]
    pure fn get_ref(&self) -> &self/T { get_ref(self) }

    /**
     * Gets the value out of an option without copying.
     *
     * # Failure
     *
     * Fails if the value equals `none`
     */
    #[inline(always)]
    pure fn unwrap(self) -> T { unwrap(self) }

    /**
     * The option dance. Moves a value out of an option type and returns it,
     * replacing the original with `None`.
     *
     * # Failure
     *
     * Fails if the value equals `None`.
     */
    #[inline(always)]
    fn swap_unwrap(&mut self) -> T { swap_unwrap(self) }

    /**
     * Gets the value out of an option, printing a specified message on
     * failure
     *
     * # Failure
     *
     * Fails if the value equals `none`
     */
    #[inline(always)]
    pure fn expect(self, reason: &str) -> T { expect(self, reason) }
}

impl<T: Copy> Option<T> {
    /**
    Gets the value out of an option

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
    */
    #[inline(always)]
    pure fn get(self) -> T { get(self) }

    #[inline(always)]
    pure fn get_or_default(self, def: T) -> T { get_or_default(self, def) }

    /// Applies a function zero or more times until the result is none.
    #[inline(always)]
    pure fn while_some(self, blk: fn(v: T) -> Option<T>) {
        while_some(self, blk)
    }
}

impl<T: Copy Zero> Option<T> {
    #[inline(always)]
    pure fn get_or_zero(self) -> T { get_or_zero(self) }
}

#[test]
fn test_unwrap_ptr() {
    let x = ~0;
    let addr_x = ptr::addr_of(&(*x));
    let opt = Some(move x);
    let y = unwrap(move opt);
    let addr_y = ptr::addr_of(&(*y));
    assert addr_x == addr_y;
}

#[test]
fn test_unwrap_str() {
    let x = ~"test";
    let addr_x = str::as_buf(x, |buf, _len| buf);
    let opt = Some(move x);
    let y = unwrap(move opt);
    let addr_y = str::as_buf(y, |buf, _len| buf);
    assert addr_x == addr_y;
}

#[test]
fn test_unwrap_resource() {
    struct R {
       i: @mut int,
       drop { *(self.i) += 1; }
    }

    fn R(i: @mut int) -> R {
        R {
            i: i
        }
    }

    let i = @mut 0;
    {
        let x = R(i);
        let opt = Some(move x);
        let _y = unwrap(move opt);
    }
    assert *i == 1;
}

#[test]
fn test_option_dance() {
    let x = Some(());
    let mut y = Some(5);
    let mut y2 = 0;
    do x.iter |_x| {
        y2 = swap_unwrap(&mut y);
    }
    assert y2 == 5;
    assert y.is_none();
}
#[test] #[should_fail] #[ignore(cfg(windows))]
fn test_option_too_much_dance() {
    let mut y = Some(util::NonCopyable());
    let _y2 = swap_unwrap(&mut y);
    let _y3 = swap_unwrap(&mut y);
}

#[test]
fn test_option_while_some() {
    let mut i = 0;
    do Some(10).while_some |j| {
        i += 1;
        if (j > 0) {
            Some(j-1)
        } else {
            None
        }
    }
    assert i == 11;
}

#[test]
fn test_get_or_zero() {
    let some_stuff = Some(42);
    assert some_stuff.get_or_zero() == 42;
    let no_stuff: Option<int> = None;
    assert no_stuff.get_or_zero() == 0;
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<commit_msg>add Option methods for in-place mutation<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!

Operations on the ubiquitous `Option` type.

Type `Option` represents an optional value.

Every `Option<T>` value can either be `Some(T)` or `None`. Where in other
languages you might use a nullable type, in Rust you would use an option
type.

Options are most commonly used with pattern matching to query the presence
of a value and take action, always accounting for the `None` case.

# Example

~~~
let msg = Some(~"howdy");

// Take a reference to the contained string
match msg {
    Some(ref m) => io::println(m),
    None => ()
}

// Remove the contained string, destroying the Option
let unwrapped_msg = match move msg {
    Some(move m) => m,
    None => ~"default message"
};
~~~

*/

#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];

use cmp::Eq;
use kinds::Copy;
use option;
use ptr;
use str;
use util;
use num::Zero;

/// The option type
#[deriving_eq]
pub enum Option<T> {
    None,
    Some(T),
}

pub pure fn get<T: Copy>(opt: Option<T>) -> T {
    /*!
    Gets the value out of an option

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
    */

    match opt {
      Some(copy x) => return x,
      None => fail ~"option::get none"
    }
}

pub pure fn get_ref<T>(opt: &r/Option<T>) -> &r/T {
    /*!
    Gets an immutable reference to the value inside an option.

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
     */
    match *opt {
        Some(ref x) => x,
        None => fail ~"option::get_ref none"
    }
}

pub pure fn map<T, U>(opt: &Option<T>, f: fn(x: &T) -> U) -> Option<U> {
    //! Maps a `some` value by reference from one type to another

    match *opt { Some(ref x) => Some(f(x)), None => None }
}

pub pure fn map_consume<T, U>(opt: Option<T>,
                              f: fn(v: T) -> U) -> Option<U> {
    /*!
     * As `map`, but consumes the option and gives `f` ownership to avoid
     * copying.
     */
    match opt { None => None, Some(v) => Some(f(v)) }
}

pub pure fn chain<T, U>(opt: Option<T>,
                        f: fn(t: T) -> Option<U>) -> Option<U> {
    /*!
     * Update an optional value by optionally running its content through a
     * function that returns an option.
     */

    match move opt {
        Some(move t) => f(move t),
        None => None
    }
}

pub pure fn chain_ref<T, U>(opt: &Option<T>,
                            f: fn(x: &T) -> Option<U>) -> Option<U> {
    /*!
     * Update an optional value by optionally running its content by reference
     * through a function that returns an option.
     */

    match *opt { Some(ref x) => f(x), None => None }
}

pub pure fn or<T>(opta: Option<T>, optb: Option<T>) -> Option<T> {
    /*!
     * Returns the leftmost some() value, or none if both are none.
     */
    match move opta {
        Some(move opta) => Some(move opta),
        _ => move optb
    }
}

#[inline(always)]
pub pure fn while_some<T>(x: Option<T>, blk: fn(v: T) -> Option<T>) {
    //! Applies a function zero or more times until the result is none.

    let mut opt = move x;
    while opt.is_some() {
        opt = blk(unwrap(move opt));
    }
}

pub pure fn is_none<T>(opt: &Option<T>) -> bool {
    //! Returns true if the option equals `none`

    match *opt { None => true, Some(_) => false }
}

pub pure fn is_some<T>(opt: &Option<T>) -> bool {
    //! Returns true if the option contains some value

    !is_none(opt)
}

pub pure fn get_or_zero<T: Copy Zero>(opt: Option<T>) -> T {
    //! Returns the contained value or zero (for this type)

    match opt { Some(copy x) => x, None => Zero::zero() }
}

pub pure fn get_or_default<T: Copy>(opt: Option<T>, def: T) -> T {
    //! Returns the contained value or a default

    match opt { Some(copy x) => x, None => def }
}

pub pure fn map_default<T, U>(opt: &Option<T>, def: U,
                              f: fn(x: &T) -> U) -> U {
    //! Applies a function to the contained value or returns a default

    match *opt { None => move def, Some(ref t) => f(t) }
}

pub pure fn iter<T>(opt: &Option<T>, f: fn(x: &T)) {
    //! Performs an operation on the contained value by reference
    match *opt { None => (), Some(ref t) => f(t) }
}

#[inline(always)]
pub pure fn unwrap<T>(opt: Option<T>) -> T {
    /*!
    Moves a value out of an option type and returns it.

    Useful primarily for getting strings, vectors and unique pointers out
    of option types without copying them.

    # Failure

    Fails if the value equals `None`.

    # Safety note

    In general, because this function may fail, its use is discouraged.
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
     */
    match move opt {
        Some(move x) => move x,
        None => fail ~"option::unwrap none"
    }
}

#[inline(always)]
pub fn swap_unwrap<T>(opt: &mut Option<T>) -> T {
    /*!
    The option dance. Moves a value out of an option type and returns it,
    replacing the original with `None`.

    # Failure

    Fails if the value equals `None`.
     */
    if opt.is_none() { fail ~"option::swap_unwrap none" }
    unwrap(util::replace(opt, None))
}

pub pure fn expect<T>(opt: Option<T>, reason: &str) -> T {
    //! As unwrap, but with a specified failure message.
    match move opt {
        Some(move val) => val,
        None => fail reason.to_owned(),
    }
}

impl<T> Option<T> {
    /// Returns true if the option equals `none`
    #[inline(always)]
    pure fn is_none(&self) -> bool { is_none(self) }

    /// Returns true if the option contains some value
    #[inline(always)]
    pure fn is_some(&self) -> bool { is_some(self) }

    /**
     * Update an optional value by optionally running its content by reference
     * through a function that returns an option.
     */
    #[inline(always)]
    pure fn chain_ref<U>(&self, f: fn(x: &T) -> Option<U>) -> Option<U> {
        chain_ref(self, f)
    }

    /// Maps a `some` value from one type to another by reference
    #[inline(always)]
    pure fn map<U>(&self, f: fn(x: &T) -> U) -> Option<U> { map(self, f) }

    /// As `map`, but consumes the option and gives `f` ownership to avoid
    /// copying.
    #[inline(always)]
    pure fn map_consume<U>(self, f: fn(v: T) -> U) -> Option<U> {
        map_consume(self, f)
    }

    /// Applies a function to the contained value or returns a default
    #[inline(always)]
    pure fn map_default<U>(&self, def: U, f: fn(x: &T) -> U) -> U {
        map_default(self, move def, f)
    }

    /// As `map_default`, but consumes the option and gives `f`
    /// ownership to avoid copying.
    #[inline(always)]
    pure fn map_consume_default<U>(self, def: U, f: fn(v: T) -> U) -> U {
        match self { None => def, Some(v) => f(v) }
    }

    /// Apply a function to the contained value or do nothing
    fn mutate(&mut self, f: fn(T) -> T) {
        if self.is_some() {
            *self = Some(f(self.swap_unwrap()));
        }
    }

    /// Apply a function to the contained value or set it to a default
    fn mutate_default(&mut self, def: T, f: fn(T) -> T) {
        if self.is_some() {
            *self = Some(f(self.swap_unwrap()));
        } else {
            *self = Some(def);
        }
    }

    /// Performs an operation on the contained value by reference
    #[inline(always)]
    pure fn iter(&self, f: fn(x: &T)) { iter(self, f) }

    /**
    Gets an immutable reference to the value inside an option.

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
     */
    #[inline(always)]
    pure fn get_ref(&self) -> &self/T { get_ref(self) }

    /**
     * Gets the value out of an option without copying.
     *
     * # Failure
     *
     * Fails if the value equals `none`
     */
    #[inline(always)]
    pure fn unwrap(self) -> T { unwrap(self) }

    /**
     * The option dance. Moves a value out of an option type and returns it,
     * replacing the original with `None`.
     *
     * # Failure
     *
     * Fails if the value equals `None`.
     */
    #[inline(always)]
    fn swap_unwrap(&mut self) -> T { swap_unwrap(self) }

    /**
     * Gets the value out of an option, printing a specified message on
     * failure
     *
     * # Failure
     *
     * Fails if the value equals `none`
     */
    #[inline(always)]
    pure fn expect(self, reason: &str) -> T { expect(self, reason) }
}

impl<T: Copy> Option<T> {
    /**
    Gets the value out of an option

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
    */
    #[inline(always)]
    pure fn get(self) -> T { get(self) }

    #[inline(always)]
    pure fn get_or_default(self, def: T) -> T { get_or_default(self, def) }

    /// Applies a function zero or more times until the result is none.
    #[inline(always)]
    pure fn while_some(self, blk: fn(v: T) -> Option<T>) {
        while_some(self, blk)
    }
}

impl<T: Copy Zero> Option<T> {
    #[inline(always)]
    pure fn get_or_zero(self) -> T { get_or_zero(self) }
}

#[test]
fn test_unwrap_ptr() {
    let x = ~0;
    let addr_x = ptr::addr_of(&(*x));
    let opt = Some(move x);
    let y = unwrap(move opt);
    let addr_y = ptr::addr_of(&(*y));
    assert addr_x == addr_y;
}

#[test]
fn test_unwrap_str() {
    let x = ~"test";
    let addr_x = str::as_buf(x, |buf, _len| buf);
    let opt = Some(move x);
    let y = unwrap(move opt);
    let addr_y = str::as_buf(y, |buf, _len| buf);
    assert addr_x == addr_y;
}

#[test]
fn test_unwrap_resource() {
    struct R {
       i: @mut int,
       drop { *(self.i) += 1; }
    }

    fn R(i: @mut int) -> R {
        R {
            i: i
        }
    }

    let i = @mut 0;
    {
        let x = R(i);
        let opt = Some(move x);
        let _y = unwrap(move opt);
    }
    assert *i == 1;
}

#[test]
fn test_option_dance() {
    let x = Some(());
    let mut y = Some(5);
    let mut y2 = 0;
    do x.iter |_x| {
        y2 = swap_unwrap(&mut y);
    }
    assert y2 == 5;
    assert y.is_none();
}
#[test] #[should_fail] #[ignore(cfg(windows))]
fn test_option_too_much_dance() {
    let mut y = Some(util::NonCopyable());
    let _y2 = swap_unwrap(&mut y);
    let _y3 = swap_unwrap(&mut y);
}

#[test]
fn test_option_while_some() {
    let mut i = 0;
    do Some(10).while_some |j| {
        i += 1;
        if (j > 0) {
            Some(j-1)
        } else {
            None
        }
    }
    assert i == 11;
}

#[test]
fn test_get_or_zero() {
    let some_stuff = Some(42);
    assert some_stuff.get_or_zero() == 42;
    let no_stuff: Option<int> = None;
    assert no_stuff.get_or_zero() == 0;
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<|endoftext|>


<commit_before>extern crate sdl;
extern crate rand;

use rand::distributions::{IndependentSample, Range};
use sdl::video::{SurfaceFlag, VideoFlag, Color};
use sdl::event::{Event, Key, Mouse};

#[derive(Copy, Clone)]
struct Spot {
    hidden: bool,
    mine: bool,
    flag: bool,
    n: u8,
}

struct Field {
    empty: bool,
    width: usize,
    height: usize,
    field: Vec<Vec<Spot>>,
}

impl Field {
    fn new(r: f32, w: usize, h: usize, x: usize, y: usize) -> Field {
        let bt = Range::new(0.,1.);
        let mut rng = rand::thread_rng();
        let mut field = Vec::with_capacity(h);
        for i in 0..h {
            field.push(Vec::with_capacity(w));
            for _ in 0..w {
                field[i].push(
                    Spot{hidden: true,
                         mine: bt.ind_sample(&mut rng) < r,
                         flag: false,
                         n: 0}
                );
            }
        }
        let mut f = Field {empty: false, width: w, height: h, field: field};
        f.count_field();
        if f.field[y][x].n != 0 || f.field[y][x].mine {
            f = Field::new(r, w, h, x, y)
        }
        f
    }

    fn empty(w: usize, h: usize) -> Field {
        Field {empty: true, width: w, height: h,
               field: vec![vec![Spot {hidden: true, mine: false, flag: false, n: 0}; h]; w]
        }
    }

    fn swap_mine(&mut self, x: usize, y: usize) {
        let f = &mut self.field[y][x];
        f.mine = !f.mine;
    }

    fn show_spot(&mut self, x: usize, y: usize) {
        if x >= self.width {return;}
        if y >= self.height {return;}
        {
            let f = &mut self.field[y][x];
            if f.flag {return;}
            if f.hidden {
                f.hidden = false;
            }
        }
        if self.field[y][x].n != self.count_flags(x, y) {return;}
        for i in 0..3 {
            if x+i == 0 || x+i > self.width {continue;}
            for j in 0..3 {
                if y+j == 0 || y+j > self.height {continue;}
                if i ==1 && j == 1 {continue;}
                let f = self.field[y+j-1][x+i-1];
                if f.hidden {
                    self.show_spot(x+i-1, y+j-1);
                }
            }
        }
    }

    fn flag_spot(&mut self, x: usize, y: usize) {
        let f = &mut self.field[y][x];
        if f.hidden {
            f.flag = !f.flag;
        }
    }

    fn count_field(&mut self) {
        for i in 0..self.width {
            for j in 0..self.height {
                self.field[j][i].n = self.count_neighbors(i, j);
            }
        }
    }

    fn count_neighbors(&self, x: usize, y: usize) -> u8 {
        let mut n = 0;
        for i in 0..3 {
            if x+i == 0 || x+i > self.width {continue;}
            for j in 0..3 {
                if y+j == 0 || y+j > self.height {continue;}
                if i == 1 && j == 1 {continue;}
                if self.field[y+j-1][x+i-1].mine {n += 1}
            }
        }
        n
    }

    fn count_flags(&self, x: usize, y: usize) -> u8 {
        let mut n = 0;
        for i in 0..3 {
            if x+i == 0 || x+i > self.width {continue;}
            for j in 0..3 {
                if y+j == 0 || y+j > self.height {continue;}
                if i == 1 && j == 1 {continue;}
                if self.field[y+j-1][x+i-1].flag {n += 1}
            }
        }
        n
    }
}

struct Screen {
    width: isize,
    height: isize,
    spot_length: u16,
    surface: sdl::video::Surface,
}

impl Screen {
    fn new(w: isize, h: isize, l: u16) -> Screen {
        sdl::init(&[sdl::InitFlag::Video]);
        sdl::wm::set_caption("mines", "mines");

        let s = match sdl::video::set_video_mode(w, h, 32,
                                                 &[SurfaceFlag::HWSurface],
                                                 &[VideoFlag::DoubleBuf]) {
            Ok(s) => s,
            Err(err) => panic!("failed to set video mode: {}", err)
        };
        Screen {width: w, height: h, spot_length: l, surface: s}
    }

    fn draw_square(&self, x: u16, y: u16, w: u16, (r,g,b): (u8, u8, u8)) {
        self.surface.fill_rect(
            Some(sdl::Rect {x: x as i16, y: y as i16, w: w, h: w}),
            Color::RGB(r, g, b)
        );
    }

    fn draw_num(&self, n: u8, x: u16, y: u16) {
        self.draw_square(x, y, self.spot_length-1,
            (255, 255, 255)
        );
        let mut n = n;
        let sub = (self.spot_length-1)/3;
        let pack = (self.spot_length - sub*3)/2;
        let color = if n == 1 {
            (100,100,255)
        }else if n == 2 {
            (0,255,0)
        }else if n == 3 {
            (255,0,0)
        }else if n == 4 {
            (0,0,255)
        }else if n == 5 {
            (200,50,0)
        }else if n == 6 {
            (0,255,255)
        }else if n == 7 {
            (0,0,0)
        }else {
            (150,150,150)
        };

        loop {
            if n == 0 {break;}
            else if n == 1{
                self.draw_square(sub+x+pack, sub+y+pack, sub-1, color);
                break;
            }else if n == 2{
                self.draw_square(x+pack, y+pack, sub-1,  color);
                self.draw_square(sub*2+x+pack, sub*2+y+pack, sub-1, color);
                break;
            }else if n == 3{
                self.draw_square(sub+x+pack, sub+y+pack, sub-1, color);
                n = 2;
            }else if n == 4{
                self.draw_square(x+pack, sub*2+y+pack, sub-1, color);
                self.draw_square(sub*2+x+pack, y+pack, sub-1, color);
                n = 2;
            }else if n == 5{
                self.draw_square(sub+x+pack, sub+y+pack, sub-1, color);
                n = 4;
            }else if n == 6{
                self.draw_square(x+pack, sub+y+pack, sub-1, color);
                self.draw_square(sub*2+x+pack, sub+y+pack, sub-1, color);
                n = 4;
            }else if n == 7{
                self.draw_square(sub+x+pack, sub+y+pack, sub-1, color);
                n = 6;
            }else if n == 8{
                self.draw_square(sub+x+pack, y+pack, sub-1, color);
                self.draw_square(sub+x+pack, sub*2+y+pack, sub-1, color);
                n = 6;
            }
        }
    }

    fn draw_field(&self, ref field: &Field) {
        let length = self.spot_length;
        let mut n = 0;
        for ref i in field.field.iter() {
            let mut m = 0;
            for ref sq in i.iter() {
                if sq.hidden {
                    self.draw_square(m*length+1,
                        n*length+1,
                        length-1,
                        (180, 180, 180)
                    );
                    if sq.flag {
                        self.draw_square(m*length+4,
                            n*length+4,
                            length-7,
                            (255, 0, 0)
                        );
                    }
                }else{
                    if sq.mine {
                        self.draw_square(m*length+1,
                            n*length+1,
                            length-1,
                            (0, 0, 0)
                        );
                    }else{
                        self.draw_num(
                            sq.n,
                            m*length+1,
                            n*length+1
                        );
                    }
                }
                m += 1;
            }
            n += 1;
        }
    }
}

fn main() {
    const WIDTH: usize = 30;
    const HEIGHT: usize = 20;
    const SIZE: usize = 35;
    const R: f32 = 0.2;

    let mut field = Field::empty(WIDTH, HEIGHT);

    let screen = Screen::new((SIZE*WIDTH) as isize + 1,
                             (SIZE*HEIGHT) as isize + 1, SIZE as u16);

    loop {
        match sdl::event::wait_event() {
            Event::Quit => break,
            Event::MouseButton(b, down, mx, my) => {
                if down {
                    let x = mx as usize/SIZE;
                    let y = my as usize/SIZE;
                    if b == Mouse::Left {
                        if field.empty {
                            field = Field::new(R, WIDTH, HEIGHT, x, y);
                        }
                        field.show_spot(x ,y);

                    }
                    else if b == Mouse::Right {
                        field.flag_spot(x, y);
                    }
                }
            },
            Event::Key(k, down, _, _) => {
                if down {
                    if k == Key::Escape {
                        break;
                    }
                    if k == Key::R {
                        field = Field::empty(WIDTH, HEIGHT);
                    }
                }
            },
            _ => {}
        }
        screen.draw_field(&field);
        screen.surface.flip();
    }

    sdl::quit();
}
<commit_msg>Reset works for x>height; fixed while drunk<commit_after>extern crate sdl;
extern crate rand;

use rand::distributions::{IndependentSample, Range};
use sdl::video::{SurfaceFlag, VideoFlag, Color};
use sdl::event::{Event, Key, Mouse};

#[derive(Copy, Clone)]
struct Spot {
    hidden: bool,
    mine: bool,
    flag: bool,
    n: u8,
}

struct Field {
    empty: bool,
    width: usize,
    height: usize,
    field: Vec<Vec<Spot>>,
}

impl Field {
    fn new(r: f32, w: usize, h: usize, x: usize, y: usize) -> Field {
        let bt = Range::new(0.,1.);
        let mut rng = rand::thread_rng();
        let mut field = Vec::with_capacity(h);
        for i in 0..h {
            field.push(Vec::with_capacity(w));
            for _ in 0..w {
                field[i].push(
                    Spot{hidden: true,
                         mine: bt.ind_sample(&mut rng) < r,
                         flag: false,
                         n: 0}
                );
            }
        }
        let mut f = Field {empty: false, width: w, height: h, field: field};
        f.count_field();
        if f.field[y][x].n != 0 || f.field[y][x].mine {
            f = Field::new(r, w, h, x, y)
        }
        f
    }

    fn empty(w: usize, h: usize) -> Field {
        Field {empty: true, width: w, height: h,
               field: vec![vec![Spot {hidden: true, mine: false, flag: false, n: 0}; w]; h]
        }
    }

    fn swap_mine(&mut self, x: usize, y: usize) {
        let f = &mut self.field[y][x];
        f.mine = !f.mine;
    }

    fn show_spot(&mut self, x: usize, y: usize) {
        if x >= self.width {return;}
        if y >= self.height {return;}
        {
            let f = &mut self.field[y][x];
            if f.flag {return;}
            if f.hidden {
                f.hidden = false;
            }
        }
        if self.field[y][x].n != self.count_flags(x, y) {return;}
        for i in 0..3 {
            if x+i == 0 || x+i > self.width {continue;}
            for j in 0..3 {
                if y+j == 0 || y+j > self.height {continue;}
                if i ==1 && j == 1 {continue;}
                let f = self.field[y+j-1][x+i-1];
                if f.hidden {
                    self.show_spot(x+i-1, y+j-1);
                }
            }
        }
    }

    fn flag_spot(&mut self, x: usize, y: usize) {
        let f = &mut self.field[y][x];
        if f.hidden {
            f.flag = !f.flag;
        }
    }

    fn count_field(&mut self) {
        for i in 0..self.width {
            for j in 0..self.height {
                self.field[j][i].n = self.count_neighbors(i, j);
            }
        }
    }

    fn count_neighbors(&self, x: usize, y: usize) -> u8 {
        let mut n = 0;
        for i in 0..3 {
            if x+i == 0 || x+i > self.width {continue;}
            for j in 0..3 {
                if y+j == 0 || y+j > self.height {continue;}
                if i == 1 && j == 1 {continue;}
                if self.field[y+j-1][x+i-1].mine {n += 1}
            }
        }
        n
    }

    fn count_flags(&self, x: usize, y: usize) -> u8 {
        let mut n = 0;
        for i in 0..3 {
            if x+i == 0 || x+i > self.width {continue;}
            for j in 0..3 {
                if y+j == 0 || y+j > self.height {continue;}
                if i == 1 && j == 1 {continue;}
                if self.field[y+j-1][x+i-1].flag {n += 1}
            }
        }
        n
    }
}

struct Screen {
    width: isize,
    height: isize,
    spot_length: u16,
    surface: sdl::video::Surface,
}

impl Screen {
    fn new(w: isize, h: isize, l: u16) -> Screen {
        sdl::init(&[sdl::InitFlag::Video]);
        sdl::wm::set_caption("mines", "mines");

        let s = match sdl::video::set_video_mode(w, h, 32,
                                                 &[SurfaceFlag::HWSurface],
                                                 &[VideoFlag::DoubleBuf]) {
            Ok(s) => s,
            Err(err) => panic!("failed to set video mode: {}", err)
        };
        Screen {width: w, height: h, spot_length: l, surface: s}
    }

    fn draw_square(&self, x: u16, y: u16, w: u16, (r,g,b): (u8, u8, u8)) {
        self.surface.fill_rect(
            Some(sdl::Rect {x: x as i16, y: y as i16, w: w, h: w}),
            Color::RGB(r, g, b)
        );
    }

    fn draw_num(&self, n: u8, x: u16, y: u16) {
        self.draw_square(x, y, self.spot_length-1,
            (255, 255, 255)
        );
        let mut n = n;
        let sub = (self.spot_length-1)/3;
        let pack = (self.spot_length - sub*3)/2;
        let color = if n == 1 {
            (100,100,255)
        }else if n == 2 {
            (0,255,0)
        }else if n == 3 {
            (255,0,0)
        }else if n == 4 {
            (0,0,255)
        }else if n == 5 {
            (200,50,0)
        }else if n == 6 {
            (0,255,255)
        }else if n == 7 {
            (0,0,0)
        }else {
            (150,150,150)
        };

        loop {
            if n == 0 {break;}
            else if n == 1{
                self.draw_square(sub+x+pack, sub+y+pack, sub-1, color);
                break;
            }else if n == 2{
                self.draw_square(x+pack, y+pack, sub-1,  color);
                self.draw_square(sub*2+x+pack, sub*2+y+pack, sub-1, color);
                break;
            }else if n == 3{
                self.draw_square(sub+x+pack, sub+y+pack, sub-1, color);
                n = 2;
            }else if n == 4{
                self.draw_square(x+pack, sub*2+y+pack, sub-1, color);
                self.draw_square(sub*2+x+pack, y+pack, sub-1, color);
                n = 2;
            }else if n == 5{
                self.draw_square(sub+x+pack, sub+y+pack, sub-1, color);
                n = 4;
            }else if n == 6{
                self.draw_square(x+pack, sub+y+pack, sub-1, color);
                self.draw_square(sub*2+x+pack, sub+y+pack, sub-1, color);
                n = 4;
            }else if n == 7{
                self.draw_square(sub+x+pack, sub+y+pack, sub-1, color);
                n = 6;
            }else if n == 8{
                self.draw_square(sub+x+pack, y+pack, sub-1, color);
                self.draw_square(sub+x+pack, sub*2+y+pack, sub-1, color);
                n = 6;
            }
        }
    }

    fn draw_field(&self, ref field: &Field) {
        let length = self.spot_length;
        let mut n = 0;
        for ref i in field.field.iter() {
            let mut m = 0;
            for ref sq in i.iter() {
                if sq.hidden {
                    self.draw_square(m*length+1,
                        n*length+1,
                        length-1,
                        (180, 180, 180)
                    );
                    if sq.flag {
                        self.draw_square(m*length+4,
                            n*length+4,
                            length-7,
                            (255, 0, 0)
                        );
                    }
                }else{
                    if sq.mine {
                        self.draw_square(m*length+1,
                            n*length+1,
                            length-1,
                            (0, 0, 0)
                        );
                    }else{
                        self.draw_num(
                            sq.n,
                            m*length+1,
                            n*length+1
                        );
                    }
                }
                m += 1;
            }
            n += 1;
        }
    }
}

fn main() {
    const WIDTH: usize = 30;
    const HEIGHT: usize = 20;
    const SIZE: usize = 35;
    const R: f32 = 0.2;

    let mut field = Field::empty(WIDTH, HEIGHT);

    let screen = Screen::new((SIZE*WIDTH) as isize + 1,
                             (SIZE*HEIGHT) as isize + 1, SIZE as u16);

    loop {
        match sdl::event::wait_event() {
            Event::Quit => break,
            Event::MouseButton(b, down, mx, my) => {
                if down {
                    let x = mx as usize/SIZE;
                    let y = my as usize/SIZE;
                    if b == Mouse::Left {
                        if field.empty {
                            field = Field::new(R, WIDTH, HEIGHT, x, y);
                        }
                        field.show_spot(x ,y);

                    }
                    else if b == Mouse::Right {
                        field.flag_spot(x, y);
                    }
                }
            },
            Event::Key(k, down, _, _) => {
                if down {
                    if k == Key::Escape {
                        break;
                    }
                    if k == Key::R {
                        field = Field::empty(WIDTH, HEIGHT);
                    }
                }
            },
            _ => {}
        }
        screen.draw_field(&field);
        screen.surface.flip();
    }

    sdl::quit();
}
<|endoftext|>


<commit_before>//
//	main.rs
//	SweetEngine
//
//	Copyright (c) 2015 Infinite
//	Licensed under the terms of the Apache License, v2
//

#![feature(plugin)]
#[plugin]
extern crate glium_macros;
#[macro_use]
extern crate glium;
extern crate glutin;

use glium::{DisplayBuild, Surface};

fn main()
{
	let display = glutin::WindowBuilder::new()
		.with_vsync()
		.with_gl_version((4, 1))
		.with_dimensions(960, 540)
		.with_title(format!("SweetWindow"))
		.build_glium().unwrap();

	let vertex_buffer = {
		#[vertex_format]
		#[derive(Copy)]
		struct Vertex
		{
			position: [f32; 2],
			color: [f32; 3],
		}

		glium::VertexBuffer::new(&display,
			vec!
			[
				Vertex { position: [-0.5, -0.5], color: [0.0, 1.0, 0.0] },
				Vertex { position: [ 0.0,  0.5], color: [0.0, 0.0, 1.0] },
				Vertex { position: [ 0.5, -0.5], color: [1.0, 0.0, 0.0] },
			]
		)
	};

	let index_buffer = glium::IndexBuffer::new(&display,
		glium::index_buffer::TrianglesList(vec![0u16, 1, 2]));

	let program = glium::Program::from_source(&display,
		"#version 410
		 uniform mat4 matrix;

		 in vec2 position;
		 in vec3 color;

		 out vec3 vColor;

		 void main()
		 {
		 	gl_Position = vec4(position, 0.0, 1.0) * matrix;
		 	vColor = color;
		 }",

		"#version 410
		 in vec3 vColor;

		 out vec4 fragColor;

		 void main()
		 {
		 	fragColor = vec4(vColor, 1.0);
		 }", None).unwrap();

	'main: loop
	{
		let uniforms = uniform!
		{
			matrix:
			[
				[1.0, 0.0, 0.0, 0.0],
				[0.0, 1.0, 0.0, 0.0],
				[0.0, 0.0, 1.0, 0.0],
				[0.0, 0.0, 0.0, 1.0f32]
			]
		};

		let mut target = display.draw();
		target.clear_color(0.0, 0.0, 0.0, 0.0);
		target.draw(&vertex_buffer, &index_buffer, &program, &uniforms, &std::default::Default::default());
		target.finish();

		for event in display.poll_events()
		{
			match event
			{
				glutin::Event::Closed => break 'main,
				_ => ()
			}
		}
	}
}
<commit_msg>Some minor improvements. Actual development should start soon.<commit_after>//
//	main.rs
//	SweetEngine
//
//	Copyright (c) 2015 Infinite
//	Licensed under the terms of the Apache License, v2
//

//----------------------------------------------------------------

//	Feature gates
#![feature(plugin)]
#![feature(core)]

//	Imports
#[plugin] extern crate glium_macros;
#[macro_use] extern crate glium;
extern crate glutin;

//	Global namespace pollution ;P
use std::old_io::timer;
use std::time::Duration;
use glium::{DisplayBuild, Surface};

//----------------------------------------------------------------

//	Our vertex struct
#[vertex_format]
#[derive(Copy)]
struct Vertex
{
	position: [f32; 2],
	color: [f32; 3],
}

//----------------------------------------------------------------

fn main()
{
	let display = glutin::WindowBuilder::new()
		.with_vsync()
		.with_gl_version((4, 1))
		.with_dimensions(960, 540)
		.with_title(format!("SweetWindow"))
		.build_glium().unwrap();

	let vertex_buffer = {
		glium::VertexBuffer::new(&display,
			vec!
			[
				Vertex { position: [-0.5, -0.5], color: [0.0, 1.0, 0.0] },
				Vertex { position: [ 0.0,  0.5], color: [0.0, 0.0, 1.0] },
				Vertex { position: [ 0.5, -0.5], color: [1.0, 0.0, 0.0] },
			]
		)
	};

	let index_buffer = glium::IndexBuffer::new(&display,
		glium::index_buffer::TrianglesList(vec![0u16, 1, 2]));

	let program = glium::Program::from_source(&display,
		"#version 410
		 uniform mat4 matrix;

		 in vec2 position;
		 in vec3 color;

		 out vec3 vColor;

		 void main()
		 {
		 	gl_Position = vec4(position, 0.0, 1.0) * matrix;
		 	vColor = color;
		 }",

		"#version 410
		 in vec3 vColor;

		 out vec4 fragColor;

		 void main()
		 {
		 	fragColor = vec4(vColor, 1.0);
		 }", None).unwrap();

	'main: loop
	{
		let uniforms = uniform!
		{
			matrix:
			[
				[1.0, 0.0, 0.0, 0.0],
				[0.0, 1.0, 0.0, 0.0],
				[0.0, 0.0, 1.0, 0.0],
				[0.0, 0.0, 0.0, 1.0f32]
			]
		};

		let mut target = display.draw();
		target.clear_color(0.0, 0.0, 0.0, 0.0);
		target.draw(&vertex_buffer, &index_buffer, &program, &uniforms, &std::default::Default::default());
		target.finish();

        timer::sleep(Duration::milliseconds(10));

        for event in display.poll_events()
        {
            match event
            {
                glutin::Event::Closed => break 'main,
                _ => ()
            }
        }
	}
}

//----------------------------------------------------------------
<|endoftext|>


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

// Some basic logging
macro_rules! rtdebug (
    ($( $arg:expr),+) => ( {
        dumb_println(fmt!( $($arg),+ ));

        fn dumb_println(s: &str) {
            use str::as_c_str;
            use libc::c_char;

            extern {
                fn printf(s: *c_char);
            }

            do as_c_str(s.to_str() + "\n") |s| {
                unsafe { printf(s); }
            }
        }

    } )
)

// An alternate version with no output, for turning off logging
macro_rules! rtdebug_ (
    ($( $arg:expr),+) => ( $(let _ = $arg)*; )
)

mod sched;
mod io;
mod uvio;
mod uv;
// FIXME #5248: The import in `sched` doesn't resolve unless this is pub!
pub mod thread_local_storage;
mod work_queue;
mod stack;
mod context;
mod thread;
<commit_msg>core: Turn off rtdebug logging<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Some basic logging
macro_rules! rtdebug_ (
    ($( $arg:expr),+) => ( {
        dumb_println(fmt!( $($arg),+ ));

        fn dumb_println(s: &str) {
            use str::as_c_str;
            use libc::c_char;

            extern {
                fn printf(s: *c_char);
            }

            do as_c_str(s.to_str() + "\n") |s| {
                unsafe { printf(s); }
            }
        }

    } )
)

// An alternate version with no output, for turning off logging
macro_rules! rtdebug (
    ($( $arg:expr),+) => ( $(let _ = $arg)*; )
)

mod sched;
mod io;
mod uvio;
mod uv;
// FIXME #5248: The import in `sched` doesn't resolve unless this is pub!
pub mod thread_local_storage;
mod work_queue;
mod stack;
mod context;
mod thread;
<|endoftext|>