<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.

use container::Container;
use from_str::FromStr;
use libc;
use option::{Some, None};
use os;
use str::StrSlice;
use unstable::atomics::{AtomicInt, INIT_ATOMIC_INT, SeqCst};

#[cfg(target_os="macos")]
use unstable::running_on_valgrind;

// Indicates whether we should perform expensive sanity checks, including rtassert!
pub static ENFORCE_SANITY: bool = !cfg!(rtopt) || cfg!(rtdebug) || cfg!(rtassert);

/// Get the number of cores available
pub fn num_cpus() -> uint {
    #[fixed_stack_segment]; #[inline(never)];

    unsafe {
        return rust_get_num_cpus();
    }

    extern {
        fn rust_get_num_cpus() -> libc::uintptr_t;
    }
}

/// Valgrind has a fixed-sized array (size around 2000) of segment descriptors wired into it; this
/// is a hard limit and requires rebuilding valgrind if you want to go beyond it. Normally this is
/// not a problem, but in some tests, we produce a lot of threads casually. Making lots of threads
/// alone might not be a problem _either_, except on OSX, the segments produced for new threads
/// _take a while_ to get reclaimed by the OS. Combined with the fact that libuv schedulers fork off
/// a separate thread for polling fsevents on OSX, we get a perfect storm of creating "too many
/// mappings" for valgrind to handle when running certain stress tests in the runtime.
#[cfg(target_os="macos")]
pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool {
    running_on_valgrind()
}

#[cfg(not(target_os="macos"))]
pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool {
    false
}

/// Get's the number of scheduler threads requested by the environment
/// either `RUST_THREADS` or `num_cpus`.
pub fn default_sched_threads() -> uint {
    match os::getenv("RUST_THREADS") {
        Some(nstr) => FromStr::from_str(nstr).unwrap(),
        None => {
            if limit_thread_creation_due_to_osx_and_valgrind() {
                1
            } else {
                num_cpus()
            }
        }
    }
}

pub fn dumb_println(s: &str) {
    use io::WriterUtil;
    let dbg = ::libc::STDERR_FILENO as ::io::fd_t;
    dbg.write_str(s + "\n");
}

pub fn abort(msg: &str) -> ! {
    let msg = if !msg.is_empty() { msg } else { "aborted" };
    let hash = msg.iter().fold(0, |accum, val| accum + (val as uint) );
    let quote = match hash % 10 {
        0 => "
It was from the artists and poets that the pertinent answers came, and I
know that panic would have broken loose had they been able to compare notes.
As it was, lacking their original letters, I half suspected the compiler of
having asked leading questions, or of having edited the correspondence in
corroboration of what he had latently resolved to see.",
        1 => "
There are not many persons who know what wonders are opened to them in the
stories and visions of their youth; for when as children we listen and dream,
we think but half-formed thoughts, and when as men we try to remember, we are
dulled and prosaic with the poison of life. But some of us awake in the night
with strange phantasms of enchanted hills and gardens, of fountains that sing
in the sun, of golden cliffs overhanging murmuring seas, of plains that stretch
down to sleeping cities of bronze and stone, and of shadowy companies of heroes
that ride caparisoned white horses along the edges of thick forests; and then
we know that we have looked back through the ivory gates into that world of
wonder which was ours before we were wise and unhappy.",
        2 => "
Instead of the poems I had hoped for, there came only a shuddering blackness
and ineffable loneliness; and I saw at last a fearful truth which no one had
ever dared to breathe before — the unwhisperable secret of secrets — The fact
that this city of stone and stridor is not a sentient perpetuation of Old New
York as London is of Old London and Paris of Old Paris, but that it is in fact
quite dead, its sprawling body imperfectly embalmed and infested with queer
animate things which have nothing to do with it as it was in life.",
        3 => "
The ocean ate the last of the land and poured into the smoking gulf, thereby
giving up all it had ever conquered. From the new-flooded lands it flowed
again, uncovering death and decay; and from its ancient and immemorial bed it
trickled loathsomely, uncovering nighted secrets of the years when Time was
young and the gods unborn. Above the waves rose weedy remembered spires. The
moon laid pale lilies of light on dead London, and Paris stood up from its damp
grave to be sanctified with star-dust. Then rose spires and monoliths that were
weedy but not remembered; terrible spires and monoliths of lands that men never
knew were lands...",
        4 => "
There was a night when winds from unknown spaces whirled us irresistibly into
limitless vacum beyond all thought and entity. Perceptions of the most
maddeningly untransmissible sort thronged upon us; perceptions of infinity
which at the time convulsed us with joy, yet which are now partly lost to my
memory and partly incapable of presentation to others.",
        _ => "You've met with a terrible fate, haven't you?"
    };
    rterrln!("%s", "");
    rterrln!("%s", quote);
    rterrln!("%s", "");
    rterrln!("fatal runtime error: %s", msg);

    abort();

    fn abort() -> ! {
        #[fixed_stack_segment]; #[inline(never)];
        unsafe { libc::abort() }
    }
}

static mut EXIT_STATUS: AtomicInt = INIT_ATOMIC_INT;

pub fn set_exit_status(code: int) {
    unsafe { EXIT_STATUS.store(code, SeqCst) }
}

pub fn get_exit_status() -> int {
    unsafe { EXIT_STATUS.load(SeqCst) }
}
<commit_msg>std::rt: Enforce sanity a while longer<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.

use container::Container;
use from_str::FromStr;
use libc;
use option::{Some, None};
use os;
use str::StrSlice;
use unstable::atomics::{AtomicInt, INIT_ATOMIC_INT, SeqCst};

#[cfg(target_os="macos")]
use unstable::running_on_valgrind;

// Indicates whether we should perform expensive sanity checks, including rtassert!
// XXX: Once the runtime matures remove the `true` below to turn off rtassert, etc.
pub static ENFORCE_SANITY: bool = true || !cfg!(rtopt) || cfg!(rtdebug) || cfg!(rtassert);

/// Get the number of cores available
pub fn num_cpus() -> uint {
    #[fixed_stack_segment]; #[inline(never)];

    unsafe {
        return rust_get_num_cpus();
    }

    extern {
        fn rust_get_num_cpus() -> libc::uintptr_t;
    }
}

/// Valgrind has a fixed-sized array (size around 2000) of segment descriptors wired into it; this
/// is a hard limit and requires rebuilding valgrind if you want to go beyond it. Normally this is
/// not a problem, but in some tests, we produce a lot of threads casually. Making lots of threads
/// alone might not be a problem _either_, except on OSX, the segments produced for new threads
/// _take a while_ to get reclaimed by the OS. Combined with the fact that libuv schedulers fork off
/// a separate thread for polling fsevents on OSX, we get a perfect storm of creating "too many
/// mappings" for valgrind to handle when running certain stress tests in the runtime.
#[cfg(target_os="macos")]
pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool {
    running_on_valgrind()
}

#[cfg(not(target_os="macos"))]
pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool {
    false
}

/// Get's the number of scheduler threads requested by the environment
/// either `RUST_THREADS` or `num_cpus`.
pub fn default_sched_threads() -> uint {
    match os::getenv("RUST_THREADS") {
        Some(nstr) => FromStr::from_str(nstr).unwrap(),
        None => {
            if limit_thread_creation_due_to_osx_and_valgrind() {
                1
            } else {
                num_cpus()
            }
        }
    }
}

pub fn dumb_println(s: &str) {
    use io::WriterUtil;
    let dbg = ::libc::STDERR_FILENO as ::io::fd_t;
    dbg.write_str(s + "\n");
}

pub fn abort(msg: &str) -> ! {
    let msg = if !msg.is_empty() { msg } else { "aborted" };
    let hash = msg.iter().fold(0, |accum, val| accum + (val as uint) );
    let quote = match hash % 10 {
        0 => "
It was from the artists and poets that the pertinent answers came, and I
know that panic would have broken loose had they been able to compare notes.
As it was, lacking their original letters, I half suspected the compiler of
having asked leading questions, or of having edited the correspondence in
corroboration of what he had latently resolved to see.",
        1 => "
There are not many persons who know what wonders are opened to them in the
stories and visions of their youth; for when as children we listen and dream,
we think but half-formed thoughts, and when as men we try to remember, we are
dulled and prosaic with the poison of life. But some of us awake in the night
with strange phantasms of enchanted hills and gardens, of fountains that sing
in the sun, of golden cliffs overhanging murmuring seas, of plains that stretch
down to sleeping cities of bronze and stone, and of shadowy companies of heroes
that ride caparisoned white horses along the edges of thick forests; and then
we know that we have looked back through the ivory gates into that world of
wonder which was ours before we were wise and unhappy.",
        2 => "
Instead of the poems I had hoped for, there came only a shuddering blackness
and ineffable loneliness; and I saw at last a fearful truth which no one had
ever dared to breathe before — the unwhisperable secret of secrets — The fact
that this city of stone and stridor is not a sentient perpetuation of Old New
York as London is of Old London and Paris of Old Paris, but that it is in fact
quite dead, its sprawling body imperfectly embalmed and infested with queer
animate things which have nothing to do with it as it was in life.",
        3 => "
The ocean ate the last of the land and poured into the smoking gulf, thereby
giving up all it had ever conquered. From the new-flooded lands it flowed
again, uncovering death and decay; and from its ancient and immemorial bed it
trickled loathsomely, uncovering nighted secrets of the years when Time was
young and the gods unborn. Above the waves rose weedy remembered spires. The
moon laid pale lilies of light on dead London, and Paris stood up from its damp
grave to be sanctified with star-dust. Then rose spires and monoliths that were
weedy but not remembered; terrible spires and monoliths of lands that men never
knew were lands...",
        4 => "
There was a night when winds from unknown spaces whirled us irresistibly into
limitless vacum beyond all thought and entity. Perceptions of the most
maddeningly untransmissible sort thronged upon us; perceptions of infinity
which at the time convulsed us with joy, yet which are now partly lost to my
memory and partly incapable of presentation to others.",
        _ => "You've met with a terrible fate, haven't you?"
    };
    rterrln!("%s", "");
    rterrln!("%s", quote);
    rterrln!("%s", "");
    rterrln!("fatal runtime error: %s", msg);

    abort();

    fn abort() -> ! {
        #[fixed_stack_segment]; #[inline(never)];
        unsafe { libc::abort() }
    }
}

static mut EXIT_STATUS: AtomicInt = INIT_ATOMIC_INT;

pub fn set_exit_status(code: int) {
    unsafe { EXIT_STATUS.store(code, SeqCst) }
}

pub fn get_exit_status() -> int {
    unsafe { EXIT_STATUS.load(SeqCst) }
}
<|endoftext|>


<commit_before>use clap::{App, Arg, AppSettings, SubCommand, ArgMatches};
use common;
use multirust::{Result, Cfg, Error};
use multirust_dist::manifest::Component;
use multirust_utils::utils;
use self_update;
use std::path::Path;

pub fn main() -> Result<()> {
    try!(::self_update::cleanup_self_updater());

    let ref matches = cli().get_matches();
    let verbose = matches.is_present("verbose");
    let ref cfg = try!(common::set_globals(verbose));

    if try!(maybe_upgrade_data(cfg, matches)) {
        return Ok(())
    }

    try!(cfg.check_metadata_version());

    match matches.subcommand() {
        ("default", Some(m)) => try!(default_(cfg, m)),
        ("update", Some(m)) => try!(update(cfg, m)),
        ("run", Some(m)) => try!(run(cfg, m)),
        ("target", Some(c)) => {
            match c.subcommand() {
                ("list", Some(_)) => try!(target_list(cfg)),
                ("add", Some(m)) => try!(target_add(cfg, m)),
                ("remove", Some(m)) => try!(target_remove(cfg, m)),
                (_, _) => unreachable!(),
            }
        }
        ("toolchain", Some(c)) => {
            match c.subcommand() {
                ("list", Some(_)) => try!(common::list_toolchains(cfg)),
                ("link", Some(m)) => try!(toolchain_link(cfg, m)),
                ("remove", Some(m)) => try!(toolchain_remove(cfg, m)),
                (_, _) => unreachable!(),
            }
        }
        ("override", Some(c)) => {
            match c.subcommand() {
                ("list", Some(_)) => try!(common::list_overrides(cfg)),
                ("add", Some(m)) => try!(override_add(cfg, m)),
                ("remove", Some(_)) => try!(override_remove(cfg)),
                (_ ,_) => unreachable!(),
            }
        }
        ("doc", Some(m)) => try!(doc(cfg, m)),
        ("self", Some(c)) => {
            match c.subcommand() {
                ("update", Some(_)) => try!(self_update::update()),
                ("uninstall", Some(m)) => try!(self_uninstall(m)),
                (_ ,_) => unreachable!(),
            }
        }
        (_, _) => {
            try!(update_all_channels(cfg, &matches));
        }
    }

    Ok(())
}

pub fn cli() -> App<'static, 'static> {
    App::new("rustup")
        .version("0.0.5")
        .author("Diggory Blake")
        .about("The Rust toolchain installer")
        .setting(AppSettings::VersionlessSubcommands)
        .setting(AppSettings::DeriveDisplayOrder)
        .arg(Arg::with_name("verbose")
            .help("Enable verbose output")
            .short("v")
            .long("verbose"))
        .arg(Arg::with_name("no-self-update")
            .help("Don't perform self update when running the `rustup` command")
            .long("no-self-update")
            .takes_value(false)
            .hidden(true))
        .subcommand(SubCommand::with_name("default")
            .about("Set the default toolchain")
            .arg(Arg::with_name("toolchain")
                .required(true)))
        .subcommand(SubCommand::with_name("update")
            .about("Install or update a toolchain from a Rust distribution channel")
            .arg(Arg::with_name("toolchain")
                .required(false)))
        .subcommand(SubCommand::with_name("run")
            .about("Run a command with an environment configured for a given toolchain")
            .setting(AppSettings::TrailingVarArg)
            .arg(Arg::with_name("toolchain")
                .required(true))
            .arg(Arg::with_name("command")
                .required(true).multiple(true)))
        .subcommand(SubCommand::with_name("target")
            .about("Modify a toolchain's supported targets")
            .subcommand(SubCommand::with_name("list")
                .about("List installed and available targets"))
            .subcommand(SubCommand::with_name("add")
                .about("Add a target to a Rust toolchain")
                .arg(Arg::with_name("target")
                    .required(true)))
            .subcommand(SubCommand::with_name("remove")
                .about("Remove a target  from a Rust toolchain")
                .arg(Arg::with_name("target")
                    .required(true))
                .arg(Arg::with_name("toolchain"))))
        .subcommand(SubCommand::with_name("toolchain")
            .about("Modify the installed toolchains")
            .subcommand(SubCommand::with_name("list")
                .about("List installed toolchains"))
            .subcommand(SubCommand::with_name("link")
                .about("Create a custom toolchain by symlinking to a directory")
                .arg(Arg::with_name("toolchain")
                    .required(true))
                .arg(Arg::with_name("path")
                    .required(true)))
            .subcommand(SubCommand::with_name("remove")
                .about("Uninstall a toolchain")
                .arg(Arg::with_name("toolchain")
                     .required(true))))
        .subcommand(SubCommand::with_name("override")
            .about("Modify directory toolchain overrides")
            .subcommand(SubCommand::with_name("list")
                .about("List directory toolchain overrides"))
            .subcommand(SubCommand::with_name("add")
                .about("Set the override toolchain for a directory")
                .arg(Arg::with_name("toolchain")
                     .required(true)))
            .subcommand(SubCommand::with_name("remove")
                .about("Remove the override toolchain for a directory")))
        .subcommand(SubCommand::with_name("self")
            .about("Modify the rustup installation")
            .subcommand(SubCommand::with_name("update")
                .about("Downloadand and install updates to rustup"))
            .subcommand(SubCommand::with_name("uninstall")
                .about("Uninstall rustup.")
                .arg(Arg::with_name("no-prompt")
                     .short("y")))
            .subcommand(SubCommand::with_name("upgrade-data")
                .about("Upgrade the internal data format.")))
}

fn maybe_upgrade_data(cfg: &Cfg, m: &ArgMatches) -> Result<bool> {
    match m.subcommand() {
        ("self", Some(c)) => {
            match c.subcommand() {
                ("upgrade-data", Some(_)) => {
                    try!(cfg.upgrade_data());
                    Ok(true)
                }
                _ => Ok(false),
            }
        }
        _ => Ok(false)
    }
}

fn update_all_channels(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
    common::update_all_channels(cfg, !m.is_present("no-self-update"))
}

fn default_(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
    let ref toolchain = m.value_of("toolchain").expect("");
    let ref toolchain = try!(cfg.get_toolchain(toolchain, false));

    let status = if !toolchain.is_custom() {
        Some(try!(toolchain.install_from_dist_if_not_installed()))
    } else if !toolchain.exists() {
        return Err(Error::ToolchainNotInstalled(toolchain.name().to_string()));
    } else {
        None
    };

    try!(toolchain.make_default());

    if let Some(status) = status {
        println!("");
        try!(common::show_channel_update(cfg, toolchain.name(), Ok(status)));
    }

    Ok(())
}

fn update(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
    let toolchain = if let Some(name) = m.value_of("toolchain") {
        try!(cfg.get_toolchain(name, false))
    } else {
        let ref cwd = try!(utils::current_dir());
        let (toolchain, _) = try!(cfg.toolchain_for_dir(cwd));
        toolchain
    };

    let status = if !toolchain.is_custom() {
        Some(try!(toolchain.install_from_dist()))
    } else if !toolchain.exists() {
        return Err(Error::ToolchainNotInstalled(toolchain.name().to_string()));
    } else {
        None
    };

    if let Some(status) = status {
        println!("");
        try!(common::show_channel_update(cfg, toolchain.name(), Ok(status)));
    }

    Ok(())
}

fn run(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
    let ref toolchain = m.value_of("toolchain").expect("");
    let ref toolchain = try!(cfg.get_toolchain(toolchain, false));
    let args = m.values_of("command").unwrap();
    let args: Vec<_> = args.collect();
    let cmd = try!(toolchain.create_command(args[0]));

    common::run_inner(cmd, &args)
}

fn target_list(cfg: &Cfg) -> Result<()> {
    let ref cwd = try!(utils::current_dir());
    let (toolchain, _) = try!(cfg.toolchain_for_dir(cwd));

    common::list_targets(&toolchain)
}

fn target_add(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
    let target = m.value_of("target").expect("");
    let ref cwd = try!(utils::current_dir());
    let (toolchain, _) = try!(cfg.toolchain_for_dir(cwd));
    let new_component = Component {
        pkg: "rust-std".to_string(),
        target: target.to_string(),
    };

    toolchain.add_component(new_component)
}

fn target_remove(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
    let target = m.value_of("target").expect("");
    let ref cwd = try!(utils::current_dir());
    let (toolchain, _) = try!(cfg.toolchain_for_dir(cwd));
    let new_component = Component {
        pkg: "rust-std".to_string(),
        target: target.to_string(),
    };

    toolchain.remove_component(new_component)
}

fn toolchain_link(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
    let ref toolchain = m.value_of("toolchain").expect("");
    let ref path = m.value_of("path").expect("");
    let toolchain = try!(cfg.get_toolchain(toolchain, true));

    toolchain.install_from_dir(Path::new(path), true)
}

fn toolchain_remove(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
    let ref toolchain = m.value_of("toolchain").expect("");
    let toolchain = try!(cfg.get_toolchain(toolchain, false));

    toolchain.remove()
}

fn override_add(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
    let ref toolchain = m.value_of("toolchain").expect("");
    let toolchain = try!(cfg.get_toolchain(toolchain, false));

    let status = if !toolchain.is_custom() {
        Some(try!(toolchain.install_from_dist_if_not_installed()))
    } else if !toolchain.exists() {
        return Err(Error::ToolchainNotInstalled(toolchain.name().to_string()));
    } else {
        None
    };

    try!(toolchain.make_override(&try!(utils::current_dir())));

    if let Some(status) = status {
        println!("");
        try!(common::show_channel_update(cfg, toolchain.name(), Ok(status)));
    }

    Ok(())
}

fn override_remove(cfg: &Cfg) -> Result<()> {
    let ref path = try!(utils::current_dir());

    let ref override_db = cfg.override_db;
    let notify_handler = cfg.notify_handler.as_ref();

    if try!(override_db.find(path, notify_handler)).is_none() {
        info!("no override toolchain for '{}'", path.display());
        return Ok(());
    }

    try!(override_db.remove(path, &cfg.temp_cfg, notify_handler));
    info!("override toolchain for '{}' removed", path.display());
    Ok(())
}

fn doc(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
    let doc_url = if m.is_present("book") {
        "book/index.html"
    } else if m.is_present("std") {
        "std/index.html"
    } else {
        "index.html"
    };

    cfg.open_docs_for_dir(&try!(utils::current_dir()), doc_url)
}

fn self_uninstall(m: &ArgMatches) -> Result<()> {
    let no_prompt = m.is_present("no-prompt");

    self_update::uninstall(no_prompt)
}
<commit_msg>Add `rustup which`<commit_after>use clap::{App, Arg, AppSettings, SubCommand, ArgMatches};
use common;
use multirust::{Result, Cfg, Error};
use multirust_dist::manifest::Component;
use multirust_utils::utils;
use self_update;
use std::path::Path;

pub fn main() -> Result<()> {
    try!(::self_update::cleanup_self_updater());

    let ref matches = cli().get_matches();
    let verbose = matches.is_present("verbose");
    let ref cfg = try!(common::set_globals(verbose));

    if try!(maybe_upgrade_data(cfg, matches)) {
        return Ok(())
    }

    try!(cfg.check_metadata_version());

    match matches.subcommand() {
        ("default", Some(m)) => try!(default_(cfg, m)),
        ("update", Some(m)) => try!(update(cfg, m)),
        ("run", Some(m)) => try!(run(cfg, m)),
        ("which", Some(m)) => try!(which(cfg, m)),
        ("target", Some(c)) => {
            match c.subcommand() {
                ("list", Some(_)) => try!(target_list(cfg)),
                ("add", Some(m)) => try!(target_add(cfg, m)),
                ("remove", Some(m)) => try!(target_remove(cfg, m)),
                (_, _) => unreachable!(),
            }
        }
        ("toolchain", Some(c)) => {
            match c.subcommand() {
                ("list", Some(_)) => try!(common::list_toolchains(cfg)),
                ("link", Some(m)) => try!(toolchain_link(cfg, m)),
                ("remove", Some(m)) => try!(toolchain_remove(cfg, m)),
                (_, _) => unreachable!(),
            }
        }
        ("override", Some(c)) => {
            match c.subcommand() {
                ("list", Some(_)) => try!(common::list_overrides(cfg)),
                ("add", Some(m)) => try!(override_add(cfg, m)),
                ("remove", Some(_)) => try!(override_remove(cfg)),
                (_ ,_) => unreachable!(),
            }
        }
        ("doc", Some(m)) => try!(doc(cfg, m)),
        ("self", Some(c)) => {
            match c.subcommand() {
                ("update", Some(_)) => try!(self_update::update()),
                ("uninstall", Some(m)) => try!(self_uninstall(m)),
                (_ ,_) => unreachable!(),
            }
        }
        (_, _) => {
            try!(update_all_channels(cfg, &matches));
        }
    }

    Ok(())
}

pub fn cli() -> App<'static, 'static> {
    App::new("rustup")
        .version("0.0.5")
        .author("Diggory Blake")
        .about("The Rust toolchain installer")
        .setting(AppSettings::VersionlessSubcommands)
        .setting(AppSettings::DeriveDisplayOrder)
        .arg(Arg::with_name("verbose")
            .help("Enable verbose output")
            .short("v")
            .long("verbose"))
        .arg(Arg::with_name("no-self-update")
            .help("Don't perform self update when running the `rustup` command")
            .long("no-self-update")
            .takes_value(false)
            .hidden(true))
        .subcommand(SubCommand::with_name("default")
            .about("Set the default toolchain")
            .arg(Arg::with_name("toolchain")
                .required(true)))
        .subcommand(SubCommand::with_name("update")
            .about("Install or update a toolchain from a Rust distribution channel")
            .arg(Arg::with_name("toolchain")
                .required(false)))
        .subcommand(SubCommand::with_name("run")
            .about("Run a command with an environment configured for a given toolchain")
            .setting(AppSettings::TrailingVarArg)
            .arg(Arg::with_name("toolchain")
                .required(true))
            .arg(Arg::with_name("command")
                .required(true).multiple(true)))
        .subcommand(SubCommand::with_name("which")
            .about("Display which binary will be run for a given command")
            .arg(Arg::with_name("command")
                .required(true)))
        .subcommand(SubCommand::with_name("target")
            .about("Modify a toolchain's supported targets")
            .subcommand(SubCommand::with_name("list")
                .about("List installed and available targets"))
            .subcommand(SubCommand::with_name("add")
                .about("Add a target to a Rust toolchain")
                .arg(Arg::with_name("target")
                    .required(true)))
            .subcommand(SubCommand::with_name("remove")
                .about("Remove a target  from a Rust toolchain")
                .arg(Arg::with_name("target")
                    .required(true))
                .arg(Arg::with_name("toolchain"))))
        .subcommand(SubCommand::with_name("toolchain")
            .about("Modify the installed toolchains")
            .subcommand(SubCommand::with_name("list")
                .about("List installed toolchains"))
            .subcommand(SubCommand::with_name("link")
                .about("Create a custom toolchain by symlinking to a directory")
                .arg(Arg::with_name("toolchain")
                    .required(true))
                .arg(Arg::with_name("path")
                    .required(true)))
            .subcommand(SubCommand::with_name("remove")
                .about("Uninstall a toolchain")
                .arg(Arg::with_name("toolchain")
                     .required(true))))
        .subcommand(SubCommand::with_name("override")
            .about("Modify directory toolchain overrides")
            .subcommand(SubCommand::with_name("list")
                .about("List directory toolchain overrides"))
            .subcommand(SubCommand::with_name("add")
                .about("Set the override toolchain for a directory")
                .arg(Arg::with_name("toolchain")
                     .required(true)))
            .subcommand(SubCommand::with_name("remove")
                .about("Remove the override toolchain for a directory")))
        .subcommand(SubCommand::with_name("self")
            .about("Modify the rustup installation")
            .subcommand(SubCommand::with_name("update")
                .about("Downloadand and install updates to rustup"))
            .subcommand(SubCommand::with_name("uninstall")
                .about("Uninstall rustup.")
                .arg(Arg::with_name("no-prompt")
                     .short("y")))
            .subcommand(SubCommand::with_name("upgrade-data")
                .about("Upgrade the internal data format.")))
}

fn maybe_upgrade_data(cfg: &Cfg, m: &ArgMatches) -> Result<bool> {
    match m.subcommand() {
        ("self", Some(c)) => {
            match c.subcommand() {
                ("upgrade-data", Some(_)) => {
                    try!(cfg.upgrade_data());
                    Ok(true)
                }
                _ => Ok(false),
            }
        }
        _ => Ok(false)
    }
}

fn update_all_channels(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
    common::update_all_channels(cfg, !m.is_present("no-self-update"))
}

fn default_(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
    let ref toolchain = m.value_of("toolchain").expect("");
    let ref toolchain = try!(cfg.get_toolchain(toolchain, false));

    let status = if !toolchain.is_custom() {
        Some(try!(toolchain.install_from_dist_if_not_installed()))
    } else if !toolchain.exists() {
        return Err(Error::ToolchainNotInstalled(toolchain.name().to_string()));
    } else {
        None
    };

    try!(toolchain.make_default());

    if let Some(status) = status {
        println!("");
        try!(common::show_channel_update(cfg, toolchain.name(), Ok(status)));
    }

    Ok(())
}

fn update(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
    let toolchain = if let Some(name) = m.value_of("toolchain") {
        try!(cfg.get_toolchain(name, false))
    } else {
        let ref cwd = try!(utils::current_dir());
        let (toolchain, _) = try!(cfg.toolchain_for_dir(cwd));
        toolchain
    };

    let status = if !toolchain.is_custom() {
        Some(try!(toolchain.install_from_dist()))
    } else if !toolchain.exists() {
        return Err(Error::ToolchainNotInstalled(toolchain.name().to_string()));
    } else {
        None
    };

    if let Some(status) = status {
        println!("");
        try!(common::show_channel_update(cfg, toolchain.name(), Ok(status)));
    }

    Ok(())
}

fn run(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
    let ref toolchain = m.value_of("toolchain").expect("");
    let ref toolchain = try!(cfg.get_toolchain(toolchain, false));
    let args = m.values_of("command").unwrap();
    let args: Vec<_> = args.collect();
    let cmd = try!(toolchain.create_command(args[0]));

    common::run_inner(cmd, &args)
}

fn which(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
    let binary = m.value_of("command").expect("");

    let binary_path = try!(cfg.which_binary(&try!(utils::current_dir()), binary))
                          .expect("binary not found");

    try!(utils::assert_is_file(&binary_path));

    println!("{}", binary_path.display());
    Ok(())
}

fn target_list(cfg: &Cfg) -> Result<()> {
    let ref cwd = try!(utils::current_dir());
    let (toolchain, _) = try!(cfg.toolchain_for_dir(cwd));

    common::list_targets(&toolchain)
}

fn target_add(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
    let target = m.value_of("target").expect("");
    let ref cwd = try!(utils::current_dir());
    let (toolchain, _) = try!(cfg.toolchain_for_dir(cwd));
    let new_component = Component {
        pkg: "rust-std".to_string(),
        target: target.to_string(),
    };

    toolchain.add_component(new_component)
}

fn target_remove(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
    let target = m.value_of("target").expect("");
    let ref cwd = try!(utils::current_dir());
    let (toolchain, _) = try!(cfg.toolchain_for_dir(cwd));
    let new_component = Component {
        pkg: "rust-std".to_string(),
        target: target.to_string(),
    };

    toolchain.remove_component(new_component)
}

fn toolchain_link(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
    let ref toolchain = m.value_of("toolchain").expect("");
    let ref path = m.value_of("path").expect("");
    let toolchain = try!(cfg.get_toolchain(toolchain, true));

    toolchain.install_from_dir(Path::new(path), true)
}

fn toolchain_remove(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
    let ref toolchain = m.value_of("toolchain").expect("");
    let toolchain = try!(cfg.get_toolchain(toolchain, false));

    toolchain.remove()
}

fn override_add(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
    let ref toolchain = m.value_of("toolchain").expect("");
    let toolchain = try!(cfg.get_toolchain(toolchain, false));

    let status = if !toolchain.is_custom() {
        Some(try!(toolchain.install_from_dist_if_not_installed()))
    } else if !toolchain.exists() {
        return Err(Error::ToolchainNotInstalled(toolchain.name().to_string()));
    } else {
        None
    };

    try!(toolchain.make_override(&try!(utils::current_dir())));

    if let Some(status) = status {
        println!("");
        try!(common::show_channel_update(cfg, toolchain.name(), Ok(status)));
    }

    Ok(())
}

fn override_remove(cfg: &Cfg) -> Result<()> {
    let ref path = try!(utils::current_dir());

    let ref override_db = cfg.override_db;
    let notify_handler = cfg.notify_handler.as_ref();

    if try!(override_db.find(path, notify_handler)).is_none() {
        info!("no override toolchain for '{}'", path.display());
        return Ok(());
    }

    try!(override_db.remove(path, &cfg.temp_cfg, notify_handler));
    info!("override toolchain for '{}' removed", path.display());
    Ok(())
}

fn doc(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
    let doc_url = if m.is_present("book") {
        "book/index.html"
    } else if m.is_present("std") {
        "std/index.html"
    } else {
        "index.html"
    };

    cfg.open_docs_for_dir(&try!(utils::current_dir()), doc_url)
}

fn self_uninstall(m: &ArgMatches) -> Result<()> {
    let no_prompt = m.is_present("no-prompt");

    self_update::uninstall(no_prompt)
}
<|endoftext|>


<commit_before>// Copyright (C) 2019, Cloudflare, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

//! Reno Congestion Control
//!
//! Note that Slow Start can use HyStart++ when enabled.

use std::cmp;
use std::time::Instant;

use crate::packet;
use crate::recovery;

use crate::recovery::Acked;
use crate::recovery::CongestionControlOps;
use crate::recovery::Recovery;

pub static RENO: CongestionControlOps = CongestionControlOps {
    on_init,
    on_packet_sent,
    on_packet_acked,
    congestion_event,
    collapse_cwnd,
    checkpoint,
    rollback,
    has_custom_pacing,
    debug_fmt,
};

pub fn on_init(_r: &mut Recovery) {}

pub fn on_packet_sent(r: &mut Recovery, sent_bytes: usize, _now: Instant) {
    r.bytes_in_flight += sent_bytes;
}

fn on_packet_acked(
    r: &mut Recovery, packet: &Acked, epoch: packet::Epoch, now: Instant,
) {
    r.bytes_in_flight = r.bytes_in_flight.saturating_sub(packet.size);

    if r.in_congestion_recovery(packet.time_sent) {
        return;
    }

    if r.app_limited {
        return;
    }

    if r.congestion_window < r.ssthresh {
        // In Slow slart, bytes_acked_sl is used for counting
        // acknowledged bytes.
        r.bytes_acked_sl += packet.size;

        if r.hystart.in_css(epoch) {
            r.congestion_window += r.hystart.css_cwnd_inc(r.max_datagram_size);
        } else {
            r.congestion_window += r.max_datagram_size;
        }

        if r.hystart.on_packet_acked(
            epoch,
            packet,
            r.latest_rtt,
            r.congestion_window,
            now,
            r.max_datagram_size,
        ) {
            // Exit to congestion avoidance if CSS ends.
            r.ssthresh = r.congestion_window;
        }
    } else {
        // Congestion avoidance.
        r.bytes_acked_ca += packet.size;

        if r.bytes_acked_ca >= r.congestion_window {
            r.congestion_window += r.max_datagram_size;
            r.bytes_acked_ca -= r.congestion_window;
        }
    }
}

fn congestion_event(
    r: &mut Recovery, time_sent: Instant, epoch: packet::Epoch, now: Instant,
) {
    // Start a new congestion event if packet was sent after the
    // start of the previous congestion recovery period.
    if !r.in_congestion_recovery(time_sent) {
        r.congestion_recovery_start_time = Some(now);

        r.congestion_window = (r.congestion_window as f64 *
            recovery::LOSS_REDUCTION_FACTOR)
            as usize;

        r.congestion_window = cmp::max(
            r.congestion_window,
            r.max_datagram_size * recovery::MINIMUM_WINDOW_PACKETS,
        );

        r.bytes_acked_ca = (r.congestion_window as f64 *
            recovery::LOSS_REDUCTION_FACTOR) as usize;

        r.ssthresh = r.congestion_window;

        if r.hystart.in_css(epoch) {
            r.hystart.congestion_event();
        }
    }
}

pub fn collapse_cwnd(r: &mut Recovery) {
    r.congestion_window = r.max_datagram_size * recovery::MINIMUM_WINDOW_PACKETS;
    r.bytes_acked_sl = 0;
    r.bytes_acked_ca = 0;

    if r.hystart.enabled() {
        r.hystart.reset();
    }
}

fn checkpoint(_r: &mut Recovery) {}

fn rollback(_r: &mut Recovery) -> bool {
    true
}

fn has_custom_pacing() -> bool {
    false
}

fn debug_fmt(_r: &Recovery, _f: &mut std::fmt::Formatter) -> std::fmt::Result {
    Ok(())
}

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

    use std::time::Duration;

    #[test]
    fn reno_init() {
        let mut cfg = crate::Config::new(crate::PROTOCOL_VERSION).unwrap();
        cfg.set_cc_algorithm(recovery::CongestionControlAlgorithm::Reno);

        let r = Recovery::new(&cfg);

        assert!(r.cwnd() > 0);
        assert_eq!(r.bytes_in_flight, 0);
    }

    #[test]
    fn reno_send() {
        let mut cfg = crate::Config::new(crate::PROTOCOL_VERSION).unwrap();
        cfg.set_cc_algorithm(recovery::CongestionControlAlgorithm::Reno);

        let mut r = Recovery::new(&cfg);

        let now = Instant::now();

        r.on_packet_sent_cc(1000, now);

        assert_eq!(r.bytes_in_flight, 1000);
    }

    #[test]
    fn reno_slow_start() {
        let mut cfg = crate::Config::new(crate::PROTOCOL_VERSION).unwrap();
        cfg.set_cc_algorithm(recovery::CongestionControlAlgorithm::Reno);

        let mut r = Recovery::new(&cfg);

        let now = Instant::now();

        let p = recovery::Sent {
            pkt_num: 0,
            frames: vec![],
            time_sent: now,
            time_acked: None,
            time_lost: None,
            size: r.max_datagram_size,
            ack_eliciting: true,
            in_flight: true,
            delivered: 0,
            delivered_time: std::time::Instant::now(),
            recent_delivered_packet_sent_time: std::time::Instant::now(),
            is_app_limited: false,
            has_data: false,
        };

        // Send initcwnd full MSS packets to become no longer app limited
        for _ in 0..recovery::INITIAL_WINDOW_PACKETS {
            r.on_packet_sent_cc(p.size, now);
        }

        let cwnd_prev = r.cwnd();

        let acked = vec![Acked {
            pkt_num: p.pkt_num,
            time_sent: p.time_sent,
            size: p.size,
        }];

        r.on_packets_acked(acked, packet::EPOCH_APPLICATION, now);

        // Check if cwnd increased by packet size (slow start).
        assert_eq!(r.cwnd(), cwnd_prev + p.size);
    }

    #[test]
    fn reno_slow_start_multi_acks() {
        let mut cfg = crate::Config::new(crate::PROTOCOL_VERSION).unwrap();
        cfg.set_cc_algorithm(recovery::CongestionControlAlgorithm::Reno);

        let mut r = Recovery::new(&cfg);

        let now = Instant::now();

        let p = recovery::Sent {
            pkt_num: 0,
            frames: vec![],
            time_sent: now,
            time_acked: None,
            time_lost: None,
            size: r.max_datagram_size,
            ack_eliciting: true,
            in_flight: true,
            delivered: 0,
            delivered_time: std::time::Instant::now(),
            recent_delivered_packet_sent_time: std::time::Instant::now(),
            is_app_limited: false,
            has_data: false,
        };

        // Send initcwnd full MSS packets to become no longer app limited
        for _ in 0..recovery::INITIAL_WINDOW_PACKETS {
            r.on_packet_sent_cc(p.size, now);
        }

        let cwnd_prev = r.cwnd();

        let acked = vec![
            Acked {
                pkt_num: p.pkt_num,
                time_sent: p.time_sent,
                size: p.size,
            },
            Acked {
                pkt_num: p.pkt_num,
                time_sent: p.time_sent,
                size: p.size,
            },
            Acked {
                pkt_num: p.pkt_num,
                time_sent: p.time_sent,
                size: p.size,
            },
        ];

        r.on_packets_acked(acked, packet::EPOCH_APPLICATION, now);

        // Acked 3 packets.
        assert_eq!(r.cwnd(), cwnd_prev + p.size * 3);
    }

    #[test]
    fn reno_congestion_event() {
        let mut cfg = crate::Config::new(crate::PROTOCOL_VERSION).unwrap();
        cfg.set_cc_algorithm(recovery::CongestionControlAlgorithm::Reno);

        let mut r = Recovery::new(&cfg);

        let prev_cwnd = r.cwnd();

        let now = Instant::now();

        r.congestion_event(now, packet::EPOCH_APPLICATION, now);

        // In Reno, after congestion event, cwnd will be cut in half.
        assert_eq!(prev_cwnd / 2, r.cwnd());
    }

    #[test]
    fn reno_congestion_avoidance() {
        let mut cfg = crate::Config::new(crate::PROTOCOL_VERSION).unwrap();
        cfg.set_cc_algorithm(recovery::CongestionControlAlgorithm::Reno);

        let mut r = Recovery::new(&cfg);
        let now = Instant::now();
        let prev_cwnd = r.cwnd();

        // Fill up bytes_in_flight to avoid app_limited=true
        r.on_packet_sent_cc(20000, now);

        // Trigger congestion event to update ssthresh
        r.congestion_event(now, packet::EPOCH_APPLICATION, now);

        // After congestion event, cwnd will be reduced.
        let cur_cwnd =
            (prev_cwnd as f64 * recovery::LOSS_REDUCTION_FACTOR) as usize;
        assert_eq!(r.cwnd(), cur_cwnd);

        let rtt = Duration::from_millis(100);

        let acked = vec![Acked {
            pkt_num: 0,
            // To exit from recovery
            time_sent: now + rtt,
            // More than cur_cwnd to increase cwnd
            size: 8000,
        }];

        // Ack more than cwnd bytes with rtt=100ms
        r.update_rtt(rtt, Duration::from_millis(0), now);
        r.on_packets_acked(acked, packet::EPOCH_APPLICATION, now + rtt * 2);

        // After acking more than cwnd, expect cwnd increased by MSS
        assert_eq!(r.cwnd(), cur_cwnd + r.max_datagram_size);
    }
}
<commit_msg>reno: fix overflow<commit_after>// Copyright (C) 2019, Cloudflare, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

//! Reno Congestion Control
//!
//! Note that Slow Start can use HyStart++ when enabled.

use std::cmp;
use std::time::Instant;

use crate::packet;
use crate::recovery;

use crate::recovery::Acked;
use crate::recovery::CongestionControlOps;
use crate::recovery::Recovery;

pub static RENO: CongestionControlOps = CongestionControlOps {
    on_init,
    on_packet_sent,
    on_packet_acked,
    congestion_event,
    collapse_cwnd,
    checkpoint,
    rollback,
    has_custom_pacing,
    debug_fmt,
};

pub fn on_init(_r: &mut Recovery) {}

pub fn on_packet_sent(r: &mut Recovery, sent_bytes: usize, _now: Instant) {
    r.bytes_in_flight += sent_bytes;
}

fn on_packet_acked(
    r: &mut Recovery, packet: &Acked, epoch: packet::Epoch, now: Instant,
) {
    r.bytes_in_flight = r.bytes_in_flight.saturating_sub(packet.size);

    if r.in_congestion_recovery(packet.time_sent) {
        return;
    }

    if r.app_limited {
        return;
    }

    if r.congestion_window < r.ssthresh {
        // In Slow slart, bytes_acked_sl is used for counting
        // acknowledged bytes.
        r.bytes_acked_sl += packet.size;

        if r.hystart.in_css(epoch) {
            r.congestion_window += r.hystart.css_cwnd_inc(r.max_datagram_size);
        } else {
            r.congestion_window += r.max_datagram_size;
        }

        if r.hystart.on_packet_acked(
            epoch,
            packet,
            r.latest_rtt,
            r.congestion_window,
            now,
            r.max_datagram_size,
        ) {
            // Exit to congestion avoidance if CSS ends.
            r.ssthresh = r.congestion_window;
        }
    } else {
        // Congestion avoidance.
        r.bytes_acked_ca += packet.size;

        if r.bytes_acked_ca >= r.congestion_window {
            r.bytes_acked_ca -= r.congestion_window;
            r.congestion_window += r.max_datagram_size;
        }
    }
}

fn congestion_event(
    r: &mut Recovery, time_sent: Instant, epoch: packet::Epoch, now: Instant,
) {
    // Start a new congestion event if packet was sent after the
    // start of the previous congestion recovery period.
    if !r.in_congestion_recovery(time_sent) {
        r.congestion_recovery_start_time = Some(now);

        r.congestion_window = (r.congestion_window as f64 *
            recovery::LOSS_REDUCTION_FACTOR)
            as usize;

        r.congestion_window = cmp::max(
            r.congestion_window,
            r.max_datagram_size * recovery::MINIMUM_WINDOW_PACKETS,
        );

        r.bytes_acked_ca = (r.congestion_window as f64 *
            recovery::LOSS_REDUCTION_FACTOR) as usize;

        r.ssthresh = r.congestion_window;

        if r.hystart.in_css(epoch) {
            r.hystart.congestion_event();
        }
    }
}

pub fn collapse_cwnd(r: &mut Recovery) {
    r.congestion_window = r.max_datagram_size * recovery::MINIMUM_WINDOW_PACKETS;
    r.bytes_acked_sl = 0;
    r.bytes_acked_ca = 0;

    if r.hystart.enabled() {
        r.hystart.reset();
    }
}

fn checkpoint(_r: &mut Recovery) {}

fn rollback(_r: &mut Recovery) -> bool {
    true
}

fn has_custom_pacing() -> bool {
    false
}

fn debug_fmt(_r: &Recovery, _f: &mut std::fmt::Formatter) -> std::fmt::Result {
    Ok(())
}

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

    use std::time::Duration;

    #[test]
    fn reno_init() {
        let mut cfg = crate::Config::new(crate::PROTOCOL_VERSION).unwrap();
        cfg.set_cc_algorithm(recovery::CongestionControlAlgorithm::Reno);

        let r = Recovery::new(&cfg);

        assert!(r.cwnd() > 0);
        assert_eq!(r.bytes_in_flight, 0);
    }

    #[test]
    fn reno_send() {
        let mut cfg = crate::Config::new(crate::PROTOCOL_VERSION).unwrap();
        cfg.set_cc_algorithm(recovery::CongestionControlAlgorithm::Reno);

        let mut r = Recovery::new(&cfg);

        let now = Instant::now();

        r.on_packet_sent_cc(1000, now);

        assert_eq!(r.bytes_in_flight, 1000);
    }

    #[test]
    fn reno_slow_start() {
        let mut cfg = crate::Config::new(crate::PROTOCOL_VERSION).unwrap();
        cfg.set_cc_algorithm(recovery::CongestionControlAlgorithm::Reno);

        let mut r = Recovery::new(&cfg);

        let now = Instant::now();

        let p = recovery::Sent {
            pkt_num: 0,
            frames: vec![],
            time_sent: now,
            time_acked: None,
            time_lost: None,
            size: r.max_datagram_size,
            ack_eliciting: true,
            in_flight: true,
            delivered: 0,
            delivered_time: std::time::Instant::now(),
            recent_delivered_packet_sent_time: std::time::Instant::now(),
            is_app_limited: false,
            has_data: false,
        };

        // Send initcwnd full MSS packets to become no longer app limited
        for _ in 0..recovery::INITIAL_WINDOW_PACKETS {
            r.on_packet_sent_cc(p.size, now);
        }

        let cwnd_prev = r.cwnd();

        let acked = vec![Acked {
            pkt_num: p.pkt_num,
            time_sent: p.time_sent,
            size: p.size,
        }];

        r.on_packets_acked(acked, packet::EPOCH_APPLICATION, now);

        // Check if cwnd increased by packet size (slow start).
        assert_eq!(r.cwnd(), cwnd_prev + p.size);
    }

    #[test]
    fn reno_slow_start_multi_acks() {
        let mut cfg = crate::Config::new(crate::PROTOCOL_VERSION).unwrap();
        cfg.set_cc_algorithm(recovery::CongestionControlAlgorithm::Reno);

        let mut r = Recovery::new(&cfg);

        let now = Instant::now();

        let p = recovery::Sent {
            pkt_num: 0,
            frames: vec![],
            time_sent: now,
            time_acked: None,
            time_lost: None,
            size: r.max_datagram_size,
            ack_eliciting: true,
            in_flight: true,
            delivered: 0,
            delivered_time: std::time::Instant::now(),
            recent_delivered_packet_sent_time: std::time::Instant::now(),
            is_app_limited: false,
            has_data: false,
        };

        // Send initcwnd full MSS packets to become no longer app limited
        for _ in 0..recovery::INITIAL_WINDOW_PACKETS {
            r.on_packet_sent_cc(p.size, now);
        }

        let cwnd_prev = r.cwnd();

        let acked = vec![
            Acked {
                pkt_num: p.pkt_num,
                time_sent: p.time_sent,
                size: p.size,
            },
            Acked {
                pkt_num: p.pkt_num,
                time_sent: p.time_sent,
                size: p.size,
            },
            Acked {
                pkt_num: p.pkt_num,
                time_sent: p.time_sent,
                size: p.size,
            },
        ];

        r.on_packets_acked(acked, packet::EPOCH_APPLICATION, now);

        // Acked 3 packets.
        assert_eq!(r.cwnd(), cwnd_prev + p.size * 3);
    }

    #[test]
    fn reno_congestion_event() {
        let mut cfg = crate::Config::new(crate::PROTOCOL_VERSION).unwrap();
        cfg.set_cc_algorithm(recovery::CongestionControlAlgorithm::Reno);

        let mut r = Recovery::new(&cfg);

        let prev_cwnd = r.cwnd();

        let now = Instant::now();

        r.congestion_event(now, packet::EPOCH_APPLICATION, now);

        // In Reno, after congestion event, cwnd will be cut in half.
        assert_eq!(prev_cwnd / 2, r.cwnd());
    }

    #[test]
    fn reno_congestion_avoidance() {
        let mut cfg = crate::Config::new(crate::PROTOCOL_VERSION).unwrap();
        cfg.set_cc_algorithm(recovery::CongestionControlAlgorithm::Reno);

        let mut r = Recovery::new(&cfg);
        let now = Instant::now();
        let prev_cwnd = r.cwnd();

        // Fill up bytes_in_flight to avoid app_limited=true
        r.on_packet_sent_cc(20000, now);

        // Trigger congestion event to update ssthresh
        r.congestion_event(now, packet::EPOCH_APPLICATION, now);

        // After congestion event, cwnd will be reduced.
        let cur_cwnd =
            (prev_cwnd as f64 * recovery::LOSS_REDUCTION_FACTOR) as usize;
        assert_eq!(r.cwnd(), cur_cwnd);

        let rtt = Duration::from_millis(100);

        let acked = vec![Acked {
            pkt_num: 0,
            // To exit from recovery
            time_sent: now + rtt,
            // More than cur_cwnd to increase cwnd
            size: 8000,
        }];

        // Ack more than cwnd bytes with rtt=100ms
        r.update_rtt(rtt, Duration::from_millis(0), now);
        r.on_packets_acked(acked, packet::EPOCH_APPLICATION, now + rtt * 2);

        // After acking more than cwnd, expect cwnd increased by MSS
        assert_eq!(r.cwnd(), cur_cwnd + r.max_datagram_size);
    }
}
<|endoftext|>


<commit_before>use alloc::boxed::Box;

use core::str;

pub use self::dsdt::DSDT;
pub use self::fadt::FADT;
pub use self::rsdt::RSDT;
pub use self::sdt::SDTHeader;
pub use self::ssdt::SSDT;

pub mod aml;
pub mod dsdt;
pub mod fadt;
pub mod rsdt;
pub mod sdt;
pub mod ssdt;

pub struct Acpi {
    rsdt: RSDT,
    fadt: Option<FADT>,
    dsdt: Option<DSDT>,
    ssdt: Option<SSDT>,
}

impl Acpi {
    pub fn new() -> Option<Box<Self>> {
        match RSDT::new() {
            Some(rsdt) => {
                //debugln!("{:#?}", rsdt);

                let mut acpi = box Acpi {
                    rsdt: rsdt,
                    fadt: None,
                    dsdt: None,
                    ssdt: None,
                };

                for addr in acpi.rsdt.addrs.iter() {
                    let header = *addr as *const SDTHeader;

                    if let Some(fadt) = FADT::new(header) {
                        //Why does this hang? debugln!("{:#?}", fadt);
                        if let Some(dsdt) = DSDT::new(fadt.Dsdt as *const SDTHeader) {
                            debugln!("DSDT:");
                            aml::parse(dsdt.data);
                            acpi.dsdt = Some(dsdt);
                        }
                        acpi.fadt = Some(fadt);
                    } else if let Some(ssdt) = SSDT::new(header) {
                        //debugln!("SSDT:");
                        //aml::parse(ssdt.data);
                        acpi.ssdt = Some(ssdt);
                    } else {
                        //debugln!("{:X}: {:#?}", addr, unsafe { *header });
                    }
                }

                Some(acpi)
            },
            None => {
                debugln!("Did not find RSDT");
                None
            }
        }
    }
}
<commit_msg>Add in SSDT<commit_after>use alloc::boxed::Box;

use core::str;

pub use self::dsdt::DSDT;
pub use self::fadt::FADT;
pub use self::rsdt::RSDT;
pub use self::sdt::SDTHeader;
pub use self::ssdt::SSDT;

pub mod aml;
pub mod dsdt;
pub mod fadt;
pub mod rsdt;
pub mod sdt;
pub mod ssdt;

pub struct Acpi {
    rsdt: RSDT,
    fadt: Option<FADT>,
    dsdt: Option<DSDT>,
    ssdt: Option<SSDT>,
}

impl Acpi {
    pub fn new() -> Option<Box<Self>> {
        match RSDT::new() {
            Some(rsdt) => {
                //debugln!("{:#?}", rsdt);

                let mut acpi = box Acpi {
                    rsdt: rsdt,
                    fadt: None,
                    dsdt: None,
                    ssdt: None,
                };

                for addr in acpi.rsdt.addrs.iter() {
                    let header = *addr as *const SDTHeader;

                    if let Some(fadt) = FADT::new(header) {
                        //Why does this hang? debugln!("{:#?}", fadt);
                        if let Some(dsdt) = DSDT::new(fadt.Dsdt as *const SDTHeader) {
                            debugln!("DSDT:");
                            aml::parse(dsdt.data);
                            acpi.dsdt = Some(dsdt);
                        }
                        acpi.fadt = Some(fadt);
                    } else if let Some(ssdt) = SSDT::new(header) {
                        debugln!("SSDT:");
                        aml::parse(ssdt.data);
                        acpi.ssdt = Some(ssdt);
                    } else {
                        //debugln!("{:X}: {:#?}", addr, unsafe { *header });
                    }
                }

                Some(acpi)
            },
            None => {
                debugln!("Did not find RSDT");
                None
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate crowbook;

use self::crowbook::{Parser, Token};

fn parse_from_str(doc: &str) -> Vec<Token> {
    let mut parser = Parser::new();
    parser.parse(doc).unwrap()
}

#[test]
fn h_p_em() {
    let doc = "
Test
====

some *emphasis* required
";
    let mut parser = Parser::new();
    let res = parser.parse(doc).unwrap();

    assert_eq!(res, vec!(
        Token::Header(1, vec!(
            Token::Str(String::from("Test")))),
        Token::Paragraph(vec!(
            Token::Str(String::from("some ")),
            Token::Emphasis(vec!(
                Token::Str(String::from("emphasis")))),
            Token::Str(String::from(" required"))))));
}

#[test]
fn link_inline() {
    let doc = "[a link](http://foo.bar)";
    let mut parser = Parser::new();
    let res = parser.parse(doc).unwrap();

    assert_eq!(res,
               vec!(
                   Token::Paragraph(vec!(
                       Token::Link(String::from("http://foo.bar"),
                                   String::from(""),
                                   vec!(
                                       Token::Str(String::from("a link"))))))));
}

#[test]
fn reference_link() {
    let doc = "
[reference link][1]

[1]: http://foo.bar
";
    let expected = r#"[Paragraph([Link("http://foo.bar", "", [Str("reference link")])])]"#;
    let result = format!("{:?}", parse_from_str(doc));
    assert_eq!(&result, expected);
}

#[test]
fn rule() {
    let doc = "a paragraph
****
another one";
    let expected = r#"[Paragraph([Str("a paragraph")]), Rule, Paragraph([Str("another one")])]"#;
    let result = format!("{:?}", parse_from_str(doc));
    assert_eq!(&result, expected);
}

#[test]
fn lists() {
    let doc = "
* banana
    3. 3
    -  4
* apple
* orange
";
    let expected = r#"[List([Item([Str("banana"), OrderedList(3, [Item([Str("3")])]), List([Item([Str("4")])])]), Item([Str("apple")]), Item([Str("orange")])])]"#;
    let result = format!("{:?}", parse_from_str(doc));
    assert_eq!(result, expected);
}

#[test]
fn blockquote() {
    let doc = "
normal paragraph

> some
> blockquote
";
    let expected = "[Paragraph([Str(\"normal paragraph\")]), BlockQuote([Paragraph([Str(\"some\"), SoftBreak, Str(\"blockquote\")])])]";
    let result = format!("{:?}", parse_from_str(doc));
    assert_eq!(result, expected);
}

#[test]
fn code_block() {
        let doc = "
normal paragraph

```
code block
```

```rust
rust code block
```
";
    let expected = r#"[Paragraph([Str("normal paragraph")]), CodeBlock("", [Str("code block\n")]), CodeBlock("rust", [Str("rust code block\n")])]"#;
    let result = format!("{:?}", parse_from_str(doc));
    assert_eq!(result, expected);
}

#[test]
fn strong_emphasis() {
    let doc = "
*normal emphasis*

**strong emphasis**
";
    let expected = r#"[Paragraph([Emphasis([Str("normal emphasis")])]), Paragraph([Strong([Str("strong emphasis")])])]"#;
    let result = format!("{:?}", parse_from_str(doc));
    assert_eq!(result, expected);
}

#[test]
fn code() {
    let doc = "some `code` inlined";
    let expected = r#"[Paragraph([Str("some "), Code([Str("code")]), Str(" inlined")])]"#;
    let result = format!("{:?}", parse_from_str(doc));
    assert_eq!(result, expected);
}

#[test]
fn image_reference() {
    let doc = "
![alt text][logo]

[logo]: http://foo.bar/baz.png \"Title\"
";
    let expected = r#"[Paragraph([Image("http://foo.bar/baz.png", "Title", [Str("alt text")])])]"#;
    let result = format!("{:?}", parse_from_str(doc));
    assert_eq!(result, expected);
}

#[test]
fn image_inline() {
    let doc = "![alt text](http://foo.bar/baz.png \"Title\")";
    let expected = r#"[Paragraph([Image("http://foo.bar/baz.png", "Title", [Str("alt text")])])]"#;
    let result = format!("{:?}", parse_from_str(doc));
    assert_eq!(result, expected);
}
<commit_msg>added tests for parser for footnotes and tables<commit_after>extern crate crowbook;

use self::crowbook::{Parser, Token};

fn parse_from_str(doc: &str) -> Vec<Token> {
    let mut parser = Parser::new();
    parser.parse(doc).unwrap()
}

#[test]
fn h_p_em() {
    let doc = "
Test
====

some *emphasis* required
";
    let mut parser = Parser::new();
    let res = parser.parse(doc).unwrap();

    assert_eq!(res, vec!(
        Token::Header(1, vec!(
            Token::Str(String::from("Test")))),
        Token::Paragraph(vec!(
            Token::Str(String::from("some ")),
            Token::Emphasis(vec!(
                Token::Str(String::from("emphasis")))),
            Token::Str(String::from(" required"))))));
}

#[test]
fn link_inline() {
    let doc = "[a link](http://foo.bar)";
    let mut parser = Parser::new();
    let res = parser.parse(doc).unwrap();

    assert_eq!(res,
               vec!(
                   Token::Paragraph(vec!(
                       Token::Link(String::from("http://foo.bar"),
                                   String::from(""),
                                   vec!(
                                       Token::Str(String::from("a link"))))))));
}

#[test]
fn reference_link() {
    let doc = "
[reference link][1]

[1]: http://foo.bar
";
    let expected = r#"[Paragraph([Link("http://foo.bar", "", [Str("reference link")])])]"#;
    let result = format!("{:?}", parse_from_str(doc));
    assert_eq!(&result, expected);
}

#[test]
fn rule() {
    let doc = "a paragraph
****
another one";
    let expected = r#"[Paragraph([Str("a paragraph")]), Rule, Paragraph([Str("another one")])]"#;
    let result = format!("{:?}", parse_from_str(doc));
    assert_eq!(&result, expected);
}

#[test]
fn lists() {
    let doc = "
* banana
    3. 3
    -  4
* apple
* orange
";
    let expected = r#"[List([Item([Str("banana"), OrderedList(3, [Item([Str("3")])]), List([Item([Str("4")])])]), Item([Str("apple")]), Item([Str("orange")])])]"#;
    let result = format!("{:?}", parse_from_str(doc));
    assert_eq!(result, expected);
}

#[test]
fn blockquote() {
    let doc = "
normal paragraph

> some
> blockquote
";
    let expected = "[Paragraph([Str(\"normal paragraph\")]), BlockQuote([Paragraph([Str(\"some\"), SoftBreak, Str(\"blockquote\")])])]";
    let result = format!("{:?}", parse_from_str(doc));
    assert_eq!(result, expected);
}

#[test]
fn code_block() {
        let doc = "
normal paragraph

```
code block
```

```rust
rust code block
```
";
    let expected = r#"[Paragraph([Str("normal paragraph")]), CodeBlock("", [Str("code block\n")]), CodeBlock("rust", [Str("rust code block\n")])]"#;
    let result = format!("{:?}", parse_from_str(doc));
    assert_eq!(result, expected);
}

#[test]
fn strong_emphasis() {
    let doc = "
*normal emphasis*

**strong emphasis**
";
    let expected = r#"[Paragraph([Emphasis([Str("normal emphasis")])]), Paragraph([Strong([Str("strong emphasis")])])]"#;
    let result = format!("{:?}", parse_from_str(doc));
    assert_eq!(result, expected);
}

#[test]
fn code() {
    let doc = "some `code` inlined";
    let expected = r#"[Paragraph([Str("some "), Code([Str("code")]), Str(" inlined")])]"#;
    let result = format!("{:?}", parse_from_str(doc));
    assert_eq!(result, expected);
}

#[test]
fn image_reference() {
    let doc = "
![alt text][logo]

[logo]: http://foo.bar/baz.png \"Title\"
";
    let expected = r#"[Paragraph([Image("http://foo.bar/baz.png", "Title", [Str("alt text")])])]"#;
    let result = format!("{:?}", parse_from_str(doc));
    assert_eq!(result, expected);
}

#[test]
fn image_inline() {
    let doc = "![alt text](http://foo.bar/baz.png \"Title\")";
    let expected = r#"[Paragraph([Image("http://foo.bar/baz.png", "Title", [Str("alt text")])])]"#;
    let result = format!("{:?}", parse_from_str(doc));
    assert_eq!(result, expected);
}

#[test]
fn table_simple() {
    let doc = "
| A             | Simple        | Table |
| ------------- |---------------| ------|
| bla           | bla           |  bla  |
| bla           | bla           |  bla  |
";
    let expected = "[Table(3, [TableHead([TableCell([Str(\" A             \")]), TableCell([Str(\" Simple        \")]), TableCell([Str(\" Table \")])]), TableRow([TableCell([Str(\" bla           \")]), TableCell([Str(\" bla           \")]), TableCell([Str(\"  bla  \")])]), TableRow([TableCell([Str(\" bla           \")]), TableCell([Str(\" bla           \")]), TableCell([Str(\"  bla  \")])])])]";
    let result = format!("{:?}", parse_from_str(doc));
    assert_eq!(result, expected);
}

#[test]
fn foonote_correct() {
    let doc = "A foonote[^1]...

[^1]: with a valid definition";
    let expected = "[Paragraph([Str(\"A foonote\"), Footnote([Paragraph([Str(\"with a valid definition\")])]), Str(\"...\")]), SoftBreak]";
    let result = format!("{:?}", parse_from_str(doc));
    assert_eq!(result, expected);
}

#[test]
fn footnote_incorrect() {
    let doc = "A foonote[^1]...

[^2]: without a valid definition";

    let mut parser = Parser::new();
    let result = parser.parse(doc);
    assert!(result.is_err());
}
<|endoftext|>


<commit_before>#![allow(
    dead_code,
    non_snake_case,
    non_camel_case_types,
    non_upper_case_globals
)]
#![cfg(target_os = "macos")]

#[macro_use]
extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
#[repr(transparent)]
#[derive(Clone)]
pub struct Foo(pub id);
impl std::ops::Deref for Foo {
    type Target = objc::runtime::Object;
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.0 }
    }
}
unsafe impl objc::Message for Foo {}
impl Foo {
    pub fn alloc() -> Self {
        Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
    }
}
impl IFoo for Foo {}
pub trait IFoo: Sized + std::ops::Deref {}
#[repr(transparent)]
#[derive(Clone)]
pub struct Bar(pub id);
impl std::ops::Deref for Bar {
    type Target = objc::runtime::Object;
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.0 }
    }
}
unsafe impl objc::Message for Bar {}
impl Bar {
    pub fn alloc() -> Self {
        Self(unsafe { msg_send!(objc::class!(Bar), alloc) })
    }
}
impl IFoo for Bar {}
impl From<Bar> for Foo {
    fn from(child: Bar) -> Foo {
        Foo(child.0)
    }
}
impl std::convert::TryFrom<Foo> for Bar {
    type Error = &'static str;
    fn try_from(parent: Foo) -> Result<Bar, Self::Error> {
        let is_kind_of: bool =
            unsafe { msg_send!(parent, isKindOfClass: class!(Bar)) };
        if is_kind_of {
            Ok(Bar(parent.0))
        } else {
            Err("This Foo cannot be downcasted to Bar")
        }
    }
}
impl IBar for Bar {}
pub trait IBar: Sized + std::ops::Deref {}
#[repr(transparent)]
#[derive(Clone)]
pub struct Baz(pub id);
impl std::ops::Deref for Baz {
    type Target = objc::runtime::Object;
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.0 }
    }
}
unsafe impl objc::Message for Baz {}
impl Baz {
    pub fn alloc() -> Self {
        Self(unsafe { msg_send!(objc::class!(Baz), alloc) })
    }
}
impl From<Baz> for Bar {
    fn from(child: Baz) -> Bar {
        Bar(child.0)
    }
}
impl std::convert::TryFrom<Bar> for Baz {
    type Error = &'static str;
    fn try_from(parent: Bar) -> Result<Baz, Self::Error> {
        let is_kind_of: bool =
            unsafe { msg_send!(parent, isKindOfClass: class!(Baz)) };
        if is_kind_of {
            Ok(Baz(parent.0))
        } else {
            Err("This Bar cannot be downcasted to Baz")
        }
    }
}
impl IFoo for Baz {}
impl From<Baz> for Foo {
    fn from(child: Baz) -> Foo {
        Foo(child.0)
    }
}
impl std::convert::TryFrom<Foo> for Baz {
    type Error = &'static str;
    fn try_from(parent: Foo) -> Result<Baz, Self::Error> {
        let is_kind_of: bool =
            unsafe { msg_send!(parent, isKindOfClass: class!(Baz)) };
        if is_kind_of {
            Ok(Baz(parent.0))
        } else {
            Err("This Foo cannot be downcasted to Baz")
        }
    }
}
impl IBaz for Baz {}
pub trait IBaz: Sized + std::ops::Deref {}
<commit_msg>Fix test for CI<commit_after>#![allow(
    dead_code,
    non_snake_case,
    non_camel_case_types,
    non_upper_case_globals
)]
#![cfg(target_os = "macos")]

#[macro_use]
extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
#[repr(transparent)]
#[derive(Clone)]
pub struct Foo(pub id);
impl std::ops::Deref for Foo {
    type Target = objc::runtime::Object;
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.0 }
    }
}
unsafe impl objc::Message for Foo {}
impl Foo {
    pub fn alloc() -> Self {
        Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
    }
}
impl IFoo for Foo {}
pub trait IFoo: Sized + std::ops::Deref {}
#[repr(transparent)]
#[derive(Clone)]
pub struct Bar(pub id);
impl std::ops::Deref for Bar {
    type Target = objc::runtime::Object;
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.0 }
    }
}
unsafe impl objc::Message for Bar {}
impl Bar {
    pub fn alloc() -> Self {
        Self(unsafe { msg_send!(objc::class!(Bar), alloc) })
    }
}
impl IFoo for Bar {}
impl From<Bar> for Foo {
    fn from(child: Bar) -> Foo {
        Foo(child.0)
    }
}
impl std::convert::TryFrom<Foo> for Bar {
    type Error = &'static str;
    fn try_from(parent: Foo) -> Result<Bar, Self::Error> {
        let is_kind_of: bool =
            unsafe { msg_send!(parent, isKindOfClass: class!(Bar)) };
        if is_kind_of {
            Ok(Bar(parent.0))
        } else {
            Err("This Foo cannot be downcasted to Bar")
        }
    }
}
impl IBar for Bar {}
pub trait IBar: Sized + std::ops::Deref {}
#[repr(transparent)]
#[derive(Clone)]
pub struct Baz(pub id);
impl std::ops::Deref for Baz {
    type Target = objc::runtime::Object;
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.0 }
    }
}
unsafe impl objc::Message for Baz {}
impl Baz {
    pub fn alloc() -> Self {
        Self(unsafe { msg_send!(objc::class!(Baz), alloc) })
    }
}
impl IBar for Baz {}
impl From<Baz> for Bar {
    fn from(child: Baz) -> Bar {
        Bar(child.0)
    }
}
impl std::convert::TryFrom<Bar> for Baz {
    type Error = &'static str;
    fn try_from(parent: Bar) -> Result<Baz, Self::Error> {
        let is_kind_of: bool =
            unsafe { msg_send!(parent, isKindOfClass: class!(Baz)) };
        if is_kind_of {
            Ok(Baz(parent.0))
        } else {
            Err("This Bar cannot be downcasted to Baz")
        }
    }
}
impl IFoo for Baz {}
impl From<Baz> for Foo {
    fn from(child: Baz) -> Foo {
        Foo(child.0)
    }
}
impl std::convert::TryFrom<Foo> for Baz {
    type Error = &'static str;
    fn try_from(parent: Foo) -> Result<Baz, Self::Error> {
        let is_kind_of: bool =
            unsafe { msg_send!(parent, isKindOfClass: class!(Baz)) };
        if is_kind_of {
            Ok(Baz(parent.0))
        } else {
            Err("This Foo cannot be downcasted to Baz")
        }
    }
}
impl IBaz for Baz {}
pub trait IBaz: Sized + std::ops::Deref {}
<|endoftext|>


<commit_before>#![crate_type="bin"]

use std::io::BufferedReader;
use std::io;

use std::iter::{AdditiveIterator, FromIterator, Rev};
use std::str::Chars;

fn main() {
    let mut reader = BufferedReader::new(io::stdin());

    for line in reader.lines().skip(1) {
        let tragic_line_rev: String = FromIterator::from_iter::<Rev<Chars>>(
            line.unwrap().as_slice().trim().chars().rev());
        let comedic_sum_str: String = FromIterator::from_iter::<Rev<Chars>>(
            tragic_line_rev
            .as_slice()
            .split(' ')
            .map(|x| from_str::<int>(x).unwrap())
            .sum()
            .to_string()
            .as_slice()
            .chars().rev());
        let comedic_sum = from_str::<int>(comedic_sum_str.as_slice()).unwrap();
        println!("{}", comedic_sum);

        /*
         * Another Solution, I think all are ugly...
         *
        let mut char_vec = line.unwrap().into_bytes();
        char_vec.reverse();
        let mut tragic_sum_vec = String::from_utf8(char_vec)
            .unwrap()
            .as_slice()
            .trim()
            .split(' ')
            .sum()
            .to_string()
            .into_byte();
        tragic_sum_vec.reverse();
        let comedic_sum = from_str::<int>(String::from_utf8(tragic_sum_vec).unwrap().as_slice()).unwrap();
        println!("{}", comedic_sum);
        */
    }
}
<commit_msg>cleanup code on adding reversed numbers<commit_after>#![crate_type="bin"]

// final version cleaned up with help from: https://github.com/Kimundi

use std::io::BufferedReader;
use std::io;
use std::iter::AdditiveIterator;

fn main() {
    let mut reader = BufferedReader::new(io::stdin());

    for line in reader.lines().skip(1) {
        let tragic_line_rev: String = line.unwrap().as_slice().chars().rev().collect();
        let comedic_sum_str: String = tragic_line_rev.as_slice()
            .words()
            .map(|x| from_str::<int>(x).unwrap())
            .sum()
            .to_string()
            .as_slice()
            .chars()
            .rev()
            .collect();
        let comedic_sum = from_str::<int>(comedic_sum_str.as_slice()).unwrap();
        println!("{}", comedic_sum);
    }
}
<|endoftext|>