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

pub mod setup {
    use std::io::{self, Write};
    use std::path::Path;
    use std::process;

    use ansi_term::Colour::{Cyan, Green, White};
    use hcore::crypto::SigKeyPair;
    use hcore::env;

    use analytics;
    use command;
    use config;
    use error::Result;

    pub fn start(cache_path: &Path, analytics_path: &Path) -> Result<()> {
        let mut generated_origin = false;

        println!("");
        title("Habitat CLI Setup");
        para("Welcome to hab setup. Let's get started.");

        heading("Set up a default origin");
        para("Every package in Habitat belongs to an origin, which indicates the person or \
              organization responsible for maintaining that package. Each origin also has \
              a key used to cryptographically sign packages in that origin.");
        para("Selecting a default origin tells package building operations such as 'hab pkg \
              build' what key should be used to sign the packages produced. If you do not \
              set a default origin now, you will have to tell package building commands each \
              time what origin to use.");
        para("For more information on origins and how they are used in building packages, \
              please consult the docs at https://www.habitat.sh/docs/create-packages-build/");
        if try!(ask_default_origin()) {
            println!("");
            para("Enter the name of your origin. If you plan to publish your packages publicly, \
                  we recommend that you select one that is not already in use on the Habitat \
                  build service found at https://app.habitat.sh/.");
            let origin = try!(prompt_origin());
            try!(write_cli_config_origin(&origin));
            println!("");
            if is_origin_in_cache(&origin, cache_path) {
                para(&format!("You already have an origin key for {} created and installed. \
                              Great work!",
                              &origin));
            } else {
                heading("Create origin key pair");
                para(&format!("It doesn't look like you have a signing key for the origin `{}'. \
                               Without it, you won't be able to build new packages successfully.",
                              &origin));
                para("You can either create a new signing key now, or, if you are building \
                      packages for an origin that already exists, ask the owner to give you the \
                      signing key.");
                para("For more information on the use of origin keys, please consult the \
                      documentation at https://www.habitat.sh/docs/concepts-keys/#origin-keys");
                if try!(ask_create_origin(&origin)) {
                    try!(create_origin(&origin, cache_path));
                    generated_origin = true;
                } else {
                    para(&format!("You might want to create an origin key later with: `hab \
                                  origin key generate {}'",
                                  &origin));
                }
            }
        } else {
            para("Okay, maybe another time.");
        }
        heading("GitHub Access Token");
        para("While you can build and run Habitat packages without sharing them on the public \
              depot, doing so allows you to collaborate with the Habitat community. In addition, \
              it is how you can perform continuous deployment with Habitat.");
        para("The depot uses GitHub authentication with an access token \
              (https://help.github.com/articles/creating-an-access-token-for-command-line-use/).");
        para("If you would like to share your packages on the depot, please enter your GitHub \
              access token. Otherwise, just enter No.");
        para("For more information on sharing packages on the depot, please read the \
              documentation at https://www.habitat.sh/docs/share-packages-overview/");
        if try!(ask_default_auth_token()) {
            println!("");
            para("Enter your GitHub access token.");
            let auth_token = try!(prompt_auth_token());
            try!(write_cli_config_auth_token(&auth_token));
        } else {
            para("Okay, maybe another time.");
        }
        heading("Analytics");
        para("The `hab` command-line tool will optionally send anonymous usage data to Habitat's \
             Google Analytics account. This is a strictly opt-in activity and no tracking will \
             occur unless you respond affirmatively to the question below.");
        para("We collect this data to help improve Habitat's user experience. For example, we \
              would like to know the category of tasks users are performing, and which ones they \
              are having trouble with (e.g. mistyping command line arguments).");
        para("To see what kinds of data are sent and how they are anonymized, please read more \
             about our analytics here: https://www.habitat.sh/docs/about-analytics/");
        if try!(ask_enable_analytics(analytics_path)) {
            try!(opt_in_analytics(analytics_path, generated_origin));
        } else {
            try!(opt_out_analytics(analytics_path));
        }
        heading("CLI Setup Complete");
        para("That's all for now. Thanks for using Habitat!");
        Ok(())
    }

    fn ask_default_origin() -> Result<bool> {
        prompt_yes_no("Set up a default origin?", Some(true))
    }

    fn ask_create_origin(origin: &str) -> Result<bool> {
        prompt_yes_no(&format!("Create an origin key for `{}'?", origin),
                      Some(true))
    }

    fn write_cli_config_origin(origin: &str) -> Result<()> {
        let mut config = try!(config::load());
        config.origin = Some(origin.to_string());
        config::save(&config)
    }

    fn write_cli_config_auth_token(auth_token: &str) -> Result<()> {
        let mut config = try!(config::load());
        config.auth_token = Some(auth_token.to_string());
        config::save(&config)
    }

    fn is_origin_in_cache(origin: &str, cache_path: &Path) -> bool {
        match SigKeyPair::get_latest_pair_for(origin, cache_path) {
            Ok(pair) => {
                match pair.secret() {
                    Ok(_) => true,
                    _ => false,
                }
            }
            _ => false,
        }
    }

    fn create_origin(origin: &str, cache_path: &Path) -> Result<()> {
        let result = command::origin::key::generate::start(&origin, cache_path);
        println!("");
        result
    }

    fn prompt_origin() -> Result<String> {
        let config = try!(config::load());
        let default = match config.origin {
            Some(o) => {
                para(&format!("You already have a default origin set up as `{}', but feel free \
                               to change it if you wish.",
                              &o));
                Some(o)
            }
            None => env::var("USER").ok(),
        };
        prompt_ask("Default origin name", default.as_ref().map(|x| &**x))
    }

    fn ask_default_auth_token() -> Result<bool> {
        prompt_yes_no("Set up a default GitHub access token?", Some(true))
    }

    fn prompt_auth_token() -> Result<String> {
        let config = try!(config::load());
        let default = match config.auth_token {
            Some(o) => {
                para("You already have a default auth token set up, but feel free to change it \
                      if you wish.");
                Some(o)
            }
            None => None,
        };
        prompt_ask("GitHub access token", default.as_ref().map(|x| &**x))
    }

    fn ask_enable_analytics(analytics_path: &Path) -> Result<bool> {
        let default = match analytics::is_opted_in(analytics_path) {
            Some(val) => Some(val),
            None => Some(true),
        };
        prompt_yes_no("Enable analytics?", default)
    }

    fn opt_in_analytics(analytics_path: &Path, generated_origin: bool) -> Result<()> {
        let result = analytics::opt_in(analytics_path, generated_origin);
        println!("");
        result
    }

    fn opt_out_analytics(analytics_path: &Path) -> Result<()> {
        let result = analytics::opt_out(analytics_path);
        println!("");
        result
    }

    fn title(text: &str) {
        println!("{}", Green.bold().paint(text));
        println!("{}\n",
                 Green.bold().paint(format!("{:=<width$}", "", width = text.chars().count())));
    }

    fn heading(text: &str) {
        println!("{}\n", Green.bold().paint(text));
    }

    fn para(text: &str) {
        print_wrapped(text, 75, 2)
    }

    fn print_wrapped(text: &str, wrap_width: usize, left_indent: usize) {
        for line in text.split("\n\n") {
            let mut buffer = String::new();
            let mut width = 0;
            for word in line.split_whitespace() {
                let wl = word.chars().count();
                if (width + wl + 1) > (wrap_width - left_indent) {
                    println!("{:<width$}{}", " ", buffer, width = left_indent);
                    buffer.clear();
                    width = 0;
                }
                width = width + wl + 1;
                buffer.push_str(word);
                buffer.push(' ');
            }
            if !buffer.is_empty() {
                println!("{:<width$}{}", " ", buffer, width = left_indent);
            }
            println!("");
        }
    }

    fn prompt_yes_no(question: &str, default: Option<bool>) -> Result<bool> {
        let choice = match default {
            Some(yes) => {
                if yes {
                    format!("{}{}{}",
                            White.paint("["),
                            White.bold().paint("Yes"),
                            White.paint("/no/quit]"))
                } else {
                    format!("{}{}{}",
                            White.paint("[yes/"),
                            White.bold().paint("No"),
                            White.paint("/quit]"))
                }
            }
            None => format!("{}", White.paint("[yes/no/quit]")),
        };
        loop {
            try!(io::stdout().flush());
            print!("{} {} ", Cyan.paint(question), choice);
            try!(io::stdout().flush());
            let mut response = String::new();
            try!(io::stdin().read_line(&mut response));
            match response.trim().chars().next().unwrap_or('\n') {
                'y' | 'Y' => return Ok(true),
                'n' | 'N' => return Ok(false),
                'q' | 'Q' => process::exit(0),
                '\n' => {
                    match default {
                        Some(default) => return Ok(default),
                        None => continue,
                    }
                }
                _ => continue,
            }
        }
    }

    fn prompt_ask(question: &str, default: Option<&str>) -> Result<String> {
        let choice = match default {
            Some(d) => {
                format!(" {}{}{}",
                        White.paint("[default: "),
                        White.bold().paint(d),
                        White.paint("]"))
            }
            None => "".to_string(),
        };
        loop {
            try!(io::stdout().flush());
            print!("{}{} ", Cyan.paint(format!("{}:", question)), choice);
            try!(io::stdout().flush());
            let mut response = String::new();
            try!(io::stdin().read_line(&mut response));
            if response.trim().is_empty() {
                match default {
                    Some(d) => return Ok(d.to_string()),
                    None => continue,
                }
            }
            return Ok(response.trim().to_string());
        }
    }
}
<commit_msg>Adds access token scope to CLI<commit_after>// Copyright (c) 2016 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

pub mod setup {
    use std::io::{self, Write};
    use std::path::Path;
    use std::process;

    use ansi_term::Colour::{Cyan, Green, White};
    use hcore::crypto::SigKeyPair;
    use hcore::env;

    use analytics;
    use command;
    use config;
    use error::Result;

    pub fn start(cache_path: &Path, analytics_path: &Path) -> Result<()> {
        let mut generated_origin = false;

        println!("");
        title("Habitat CLI Setup");
        para("Welcome to hab setup. Let's get started.");

        heading("Set up a default origin");
        para("Every package in Habitat belongs to an origin, which indicates the person or \
              organization responsible for maintaining that package. Each origin also has \
              a key used to cryptographically sign packages in that origin.");
        para("Selecting a default origin tells package building operations such as 'hab pkg \
              build' what key should be used to sign the packages produced. If you do not \
              set a default origin now, you will have to tell package building commands each \
              time what origin to use.");
        para("For more information on origins and how they are used in building packages, \
              please consult the docs at https://www.habitat.sh/docs/create-packages-build/");
        if try!(ask_default_origin()) {
            println!("");
            para("Enter the name of your origin. If you plan to publish your packages publicly, \
                  we recommend that you select one that is not already in use on the Habitat \
                  build service found at https://app.habitat.sh/.");
            let origin = try!(prompt_origin());
            try!(write_cli_config_origin(&origin));
            println!("");
            if is_origin_in_cache(&origin, cache_path) {
                para(&format!("You already have an origin key for {} created and installed. \
                              Great work!",
                              &origin));
            } else {
                heading("Create origin key pair");
                para(&format!("It doesn't look like you have a signing key for the origin `{}'. \
                               Without it, you won't be able to build new packages successfully.",
                              &origin));
                para("You can either create a new signing key now, or, if you are building \
                      packages for an origin that already exists, ask the owner to give you the \
                      signing key.");
                para("For more information on the use of origin keys, please consult the \
                      documentation at https://www.habitat.sh/docs/concepts-keys/#origin-keys");
                if try!(ask_create_origin(&origin)) {
                    try!(create_origin(&origin, cache_path));
                    generated_origin = true;
                } else {
                    para(&format!("You might want to create an origin key later with: `hab \
                                  origin key generate {}'",
                                  &origin));
                }
            }
        } else {
            para("Okay, maybe another time.");
        }
        heading("GitHub Access Token");
        para("While you can build and run Habitat packages without sharing them on the public \
              depot, doing so allows you to collaborate with the Habitat community. In addition, \
              it is how you can perform continuous deployment with Habitat.");
        para("The depot uses GitHub authentication with an access token with the user:email scope \
              (https://help.github.com/articles/creating-an-access-token-for-command-line-use/).");
        para("If you would like to share your packages on the depot, please enter your GitHub \
              access token. Otherwise, just enter No.");
        para("For more information on sharing packages on the depot, please read the \
              documentation at https://www.habitat.sh/docs/share-packages-overview/");
        if try!(ask_default_auth_token()) {
            println!("");
            para("Enter your GitHub access token.");
            let auth_token = try!(prompt_auth_token());
            try!(write_cli_config_auth_token(&auth_token));
        } else {
            para("Okay, maybe another time.");
        }
        heading("Analytics");
        para("The `hab` command-line tool will optionally send anonymous usage data to Habitat's \
             Google Analytics account. This is a strictly opt-in activity and no tracking will \
             occur unless you respond affirmatively to the question below.");
        para("We collect this data to help improve Habitat's user experience. For example, we \
              would like to know the category of tasks users are performing, and which ones they \
              are having trouble with (e.g. mistyping command line arguments).");
        para("To see what kinds of data are sent and how they are anonymized, please read more \
             about our analytics here: https://www.habitat.sh/docs/about-analytics/");
        if try!(ask_enable_analytics(analytics_path)) {
            try!(opt_in_analytics(analytics_path, generated_origin));
        } else {
            try!(opt_out_analytics(analytics_path));
        }
        heading("CLI Setup Complete");
        para("That's all for now. Thanks for using Habitat!");
        Ok(())
    }

    fn ask_default_origin() -> Result<bool> {
        prompt_yes_no("Set up a default origin?", Some(true))
    }

    fn ask_create_origin(origin: &str) -> Result<bool> {
        prompt_yes_no(&format!("Create an origin key for `{}'?", origin),
                      Some(true))
    }

    fn write_cli_config_origin(origin: &str) -> Result<()> {
        let mut config = try!(config::load());
        config.origin = Some(origin.to_string());
        config::save(&config)
    }

    fn write_cli_config_auth_token(auth_token: &str) -> Result<()> {
        let mut config = try!(config::load());
        config.auth_token = Some(auth_token.to_string());
        config::save(&config)
    }

    fn is_origin_in_cache(origin: &str, cache_path: &Path) -> bool {
        match SigKeyPair::get_latest_pair_for(origin, cache_path) {
            Ok(pair) => {
                match pair.secret() {
                    Ok(_) => true,
                    _ => false,
                }
            }
            _ => false,
        }
    }

    fn create_origin(origin: &str, cache_path: &Path) -> Result<()> {
        let result = command::origin::key::generate::start(&origin, cache_path);
        println!("");
        result
    }

    fn prompt_origin() -> Result<String> {
        let config = try!(config::load());
        let default = match config.origin {
            Some(o) => {
                para(&format!("You already have a default origin set up as `{}', but feel free \
                               to change it if you wish.",
                              &o));
                Some(o)
            }
            None => env::var("USER").ok(),
        };
        prompt_ask("Default origin name", default.as_ref().map(|x| &**x))
    }

    fn ask_default_auth_token() -> Result<bool> {
        prompt_yes_no("Set up a default GitHub access token?", Some(true))
    }

    fn prompt_auth_token() -> Result<String> {
        let config = try!(config::load());
        let default = match config.auth_token {
            Some(o) => {
                para("You already have a default auth token set up, but feel free to change it \
                      if you wish.");
                Some(o)
            }
            None => None,
        };
        prompt_ask("GitHub access token", default.as_ref().map(|x| &**x))
    }

    fn ask_enable_analytics(analytics_path: &Path) -> Result<bool> {
        let default = match analytics::is_opted_in(analytics_path) {
            Some(val) => Some(val),
            None => Some(true),
        };
        prompt_yes_no("Enable analytics?", default)
    }

    fn opt_in_analytics(analytics_path: &Path, generated_origin: bool) -> Result<()> {
        let result = analytics::opt_in(analytics_path, generated_origin);
        println!("");
        result
    }

    fn opt_out_analytics(analytics_path: &Path) -> Result<()> {
        let result = analytics::opt_out(analytics_path);
        println!("");
        result
    }

    fn title(text: &str) {
        println!("{}", Green.bold().paint(text));
        println!("{}\n",
                 Green.bold().paint(format!("{:=<width$}", "", width = text.chars().count())));
    }

    fn heading(text: &str) {
        println!("{}\n", Green.bold().paint(text));
    }

    fn para(text: &str) {
        print_wrapped(text, 75, 2)
    }

    fn print_wrapped(text: &str, wrap_width: usize, left_indent: usize) {
        for line in text.split("\n\n") {
            let mut buffer = String::new();
            let mut width = 0;
            for word in line.split_whitespace() {
                let wl = word.chars().count();
                if (width + wl + 1) > (wrap_width - left_indent) {
                    println!("{:<width$}{}", " ", buffer, width = left_indent);
                    buffer.clear();
                    width = 0;
                }
                width = width + wl + 1;
                buffer.push_str(word);
                buffer.push(' ');
            }
            if !buffer.is_empty() {
                println!("{:<width$}{}", " ", buffer, width = left_indent);
            }
            println!("");
        }
    }

    fn prompt_yes_no(question: &str, default: Option<bool>) -> Result<bool> {
        let choice = match default {
            Some(yes) => {
                if yes {
                    format!("{}{}{}",
                            White.paint("["),
                            White.bold().paint("Yes"),
                            White.paint("/no/quit]"))
                } else {
                    format!("{}{}{}",
                            White.paint("[yes/"),
                            White.bold().paint("No"),
                            White.paint("/quit]"))
                }
            }
            None => format!("{}", White.paint("[yes/no/quit]")),
        };
        loop {
            try!(io::stdout().flush());
            print!("{} {} ", Cyan.paint(question), choice);
            try!(io::stdout().flush());
            let mut response = String::new();
            try!(io::stdin().read_line(&mut response));
            match response.trim().chars().next().unwrap_or('\n') {
                'y' | 'Y' => return Ok(true),
                'n' | 'N' => return Ok(false),
                'q' | 'Q' => process::exit(0),
                '\n' => {
                    match default {
                        Some(default) => return Ok(default),
                        None => continue,
                    }
                }
                _ => continue,
            }
        }
    }

    fn prompt_ask(question: &str, default: Option<&str>) -> Result<String> {
        let choice = match default {
            Some(d) => {
                format!(" {}{}{}",
                        White.paint("[default: "),
                        White.bold().paint(d),
                        White.paint("]"))
            }
            None => "".to_string(),
        };
        loop {
            try!(io::stdout().flush());
            print!("{}{} ", Cyan.paint(format!("{}:", question)), choice);
            try!(io::stdout().flush());
            let mut response = String::new();
            try!(io::stdin().read_line(&mut response));
            if response.trim().is_empty() {
                match default {
                    Some(d) => return Ok(d.to_string()),
                    None => continue,
                }
            }
            return Ok(response.trim().to_string());
        }
    }
}
<|endoftext|>


<commit_before>// Copyright:: Copyright (c) 2015-2016 The Habitat Maintainers
//
// The terms of the Evaluation Agreement (Habitat) between Chef Software Inc.
// and the party accessing this file ("Licensee") apply to Licensee's use of
// the Software until such time that the Software is made available under an
// open source license such as the Apache 2.0 License.

use std::ffi::OsString;

use error::Result;

pub fn start(args: Vec<OsString>) -> Result<()> {
    inner::start(args)
}

#[cfg(target_os = "linux")]
mod inner {
    use std::ffi::OsString;
    use std::path::PathBuf;
    use std::str::FromStr;

    use hcore::crypto::{init, default_cache_key_path};
    use hcore::env as henv;
    use hcore::fs::find_command;
    use hcore::package::PackageIdent;

    use error::{Error, Result};
    use exec;

    const SUP_CMD: &'static str = "hab-sup";
    const SUP_CMD_ENVVAR: &'static str = "HAB_SUP_BINARY";
    const SUP_PACKAGE_IDENT: &'static str = "core/hab-sup";

    pub fn start(args: Vec<OsString>) -> Result<()> {
        let command = match henv::var(SUP_CMD_ENVVAR) {
            Ok(command) => PathBuf::from(command),
            Err(_) => {
                init();
                let ident = try!(PackageIdent::from_str(SUP_PACKAGE_IDENT));
                try!(exec::command_from_pkg(SUP_CMD, &ident, &default_cache_key_path(None), 0))
            }
        };

        if let Some(cmd) = find_command(command.to_string_lossy().as_ref()) {
            exec::exec_command(cmd, args)
        } else {
            Err(Error::ExecCommandNotFound(command.to_string_lossy().into_owned()))
        }
    }
}

#[cfg(not(target_os = "linux"))]
mod inner {
    use std::env;
    use std::ffi::OsString;

    use ansi_term::Colour::Yellow;

    use error::{Error, Result};

    pub fn start(_args: Vec<OsString>) -> Result<()> {
        let subcmd = env::args().nth(1).unwrap_or("<unknown>".to_string());
        let msg = format!("∅ Launching a native Supervisor on this operating system is not yet \
                           supported. Try running this command again on a 64-bit Linux \
                           operating system.\n");
        println!("{}", Yellow.bold().paint(msg));
        Err(Error::SubcommandNotSupported(subcmd))
    }
}
<commit_msg>[hab] Add a simple feature toggle to use a static Supervisor.<commit_after>// Copyright:: Copyright (c) 2015-2016 The Habitat Maintainers
//
// The terms of the Evaluation Agreement (Habitat) between Chef Software Inc.
// and the party accessing this file ("Licensee") apply to Licensee's use of
// the Software until such time that the Software is made available under an
// open source license such as the Apache 2.0 License.

use std::ffi::OsString;

use error::Result;

pub fn start(args: Vec<OsString>) -> Result<()> {
    inner::start(args)
}

#[cfg(target_os = "linux")]
mod inner {
    use std::ffi::OsString;
    use std::path::PathBuf;
    use std::str::FromStr;

    use hcore::crypto::{init, default_cache_key_path};
    use hcore::env as henv;
    use hcore::fs::find_command;
    use hcore::package::PackageIdent;

    use error::{Error, Result};
    use exec;

    const SUP_CMD: &'static str = "hab-sup";
    const SUP_CMD_ENVVAR: &'static str = "HAB_SUP_BINARY";
    const SUP_PACKAGE_IDENT: &'static str = "core/hab-sup";

    const FEAT_STATIC: &'static str = "HAB_FEAT_SUP_STATIC";
    const SUP_STATIC_PACKAGE_IDENT: &'static str = "core/hab-sup-static";

    pub fn start(args: Vec<OsString>) -> Result<()> {
        let sup_ident = match henv::var(FEAT_STATIC) {
            Ok(_) => {
                debug!("Enabling statically compiled Supervisor from {}",
                       SUP_STATIC_PACKAGE_IDENT);
                SUP_STATIC_PACKAGE_IDENT
            }
            Err(_) => SUP_PACKAGE_IDENT,
        };
        let command = match henv::var(SUP_CMD_ENVVAR) {
            Ok(command) => PathBuf::from(command),
            Err(_) => {
                init();
                let ident = try!(PackageIdent::from_str(sup_ident));
                try!(exec::command_from_pkg(SUP_CMD, &ident, &default_cache_key_path(None), 0))
            }
        };

        if let Some(cmd) = find_command(command.to_string_lossy().as_ref()) {
            exec::exec_command(cmd, args)
        } else {
            Err(Error::ExecCommandNotFound(command.to_string_lossy().into_owned()))
        }
    }
}

#[cfg(not(target_os = "linux"))]
mod inner {
    use std::env;
    use std::ffi::OsString;

    use ansi_term::Colour::Yellow;

    use error::{Error, Result};

    pub fn start(_args: Vec<OsString>) -> Result<()> {
        let subcmd = env::args().nth(1).unwrap_or("<unknown>".to_string());
        let msg = format!("∅ Launching a native Supervisor on this operating system is not yet \
                           supported. Try running this command again on a 64-bit Linux \
                           operating system.\n");
        println!("{}", Yellow.bold().paint(msg));
        Err(Error::SubcommandNotSupported(subcmd))
    }
}
<|endoftext|>


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

use LinkerFlavor;
use target::{Target, TargetOptions, TargetResult};

pub fn target() -> TargetResult {
    let base = super::linux_base::opts();
    Ok(Target {
        llvm_target: "armv5te-unknown-linux-gnueabi".to_string(),
        target_endian: "little".to_string(),
        target_pointer_width: "32".to_string(),
        data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
        arch: "arm".to_string(),
        target_os: "linux".to_string(),
        target_env: "gnu".to_string(),
        target_vendor: "unknown".to_string(),
        linker_flavor: LinkerFlavor::Gcc,

        options: TargetOptions {
            features: "+soft-float".to_string(),
            // No atomic instructions on ARMv5
            max_atomic_width: Some(0),
            abi_blacklist: super::arm_base::abi_blacklist(),
            .. base
        }
    })
}
<commit_msg>Rollup merge of #42314 - jannic:patch-1, r=japaric<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use LinkerFlavor;
use target::{Target, TargetOptions, TargetResult};

pub fn target() -> TargetResult {
    let base = super::linux_base::opts();
    Ok(Target {
        llvm_target: "armv5te-unknown-linux-gnueabi".to_string(),
        target_endian: "little".to_string(),
        target_pointer_width: "32".to_string(),
        data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
        arch: "arm".to_string(),
        target_os: "linux".to_string(),
        target_env: "gnu".to_string(),
        target_vendor: "unknown".to_string(),
        linker_flavor: LinkerFlavor::Gcc,

        options: TargetOptions {
            features: "+soft-float,+strict-align".to_string(),
            // No atomic instructions on ARMv5
            max_atomic_width: Some(0),
            abi_blacklist: super::arm_base::abi_blacklist(),
            .. base
        }
    })
}
<|endoftext|>


<commit_before>// Copyright 2013-2014 Jeffery Olson
//
// Licensed under the 3-Clause BSD License, see LICENSE.txt
// at the top-level of this repository.
// This file may not be copied, modified, or distributed
// except according to those terms.
use std::io::timer;
use std::comm::channel;
use std::mem::transmute_copy;
use time::precise_time_ns;
use std::time::duration::Duration;

use sdl2::event::{Event, NoEvent, poll_event};

use gfx::GameDisplay;

pub mod prefab;

pub fn throttle(fps: uint, cb: || -> bool) {
    let target_fps = (1000 / fps) as u64;
    loop {
        let next_frame = (precise_time_ns() / 1000000) + target_fps;
        match cb() {
            false => break,
            _ => {}
        }
        let now_time = precise_time_ns() / 1000000;
        if  now_time < next_frame {
            let sleep_gap = next_frame - now_time;
            timer::sleep(Duration::milliseconds(sleep_gap as i64));
        }
    }
}

pub trait DisplayViewContext {
    fn get_display<'a>(&'a self) -> &'a GameDisplay;
}

pub trait ActiveView<TViewCtx: DisplayViewContext, TOut: Send> : PassiveView<TViewCtx> {
    fn active_update<'a>(&'a mut self, ctx: &TViewCtx, events: &[Event], ms_time: u64,
                         passives: & mut Vec<& mut PassiveView<TViewCtx> >)
                         -> Option<TOut>;
    fn yield_to<'a, TOut: Send>(&'a mut self, ctx: &TViewCtx,
                                active: &mut ActiveView<TViewCtx, TOut>,
                                passives: &mut Vec<&mut PassiveView<TViewCtx> >) -> TOut {
        let (sender, receiver) = channel();
        let mut cont = true;
        while cont {
            let time = precise_time_ns() / 1000000;

            // eh heh heh heh
            unsafe {
                //previously had a `&mut PassiveView<TViewCtx>)` cast in this transmute...
                let yielding = transmute_copy(self);
                //passives.push(yielding);
                passives.push(yielding);
            }
            let mut events = Vec::new();
            {
                for view in passives.iter_mut() {
                    view.passive_update(ctx, time);
                }
            }
            active.passive_update(ctx, time);
            loop {
                match poll_event() {
                    NoEvent => { break; },
                    event => { events.push(event); }
                }
            }
            let result = active.active_update(ctx, events.as_slice(), time, passives);
            ctx.get_display().renderer.present();
            passives.pop();
            if result.is_some() {
                cont = false;
                sender.send(result.expect("definitely gonna be something!"));
            }
            /*
            match self._yield_inner(ctx, active, passives) {
                Some(out) => {
                    sender.send(out);
                    cont = false;
                },
                None => {
                    cont = true;
                }
            }
            */
        }
        receiver.recv()
    }
}

pub trait PassiveView<TViewCtx: DisplayViewContext> {
    fn passive_update(&mut self, ctx: &TViewCtx, ms_time: u64);
}
<commit_msg>more trying to get UX to work.. might be broke and at a dead end..<commit_after>// Copyright 2013-2014 Jeffery Olson
//
// Licensed under the 3-Clause BSD License, see LICENSE.txt
// at the top-level of this repository.
// This file may not be copied, modified, or distributed
// except according to those terms.
use std::io::timer;
use std::comm::channel;
use std::mem::transmute_copy;
use time::precise_time_ns;
use std::time::duration::Duration;

use sdl2::event::{Event, NoEvent, poll_event};

use gfx::GameDisplay;

pub mod prefab;

pub fn throttle(fps: uint, cb: || -> bool) {
    let target_fps = (1000 / fps) as u64;
    loop {
        let next_frame = (precise_time_ns() / 1000000) + target_fps;
        match cb() {
            false => break,
            _ => {}
        }
        let now_time = precise_time_ns() / 1000000;
        if  now_time < next_frame {
            let sleep_gap = next_frame - now_time;
            timer::sleep(Duration::milliseconds(sleep_gap as i64));
        }
    }
}

pub trait DisplayViewContext {
    fn get_display<'a>(&'a self) -> &'a GameDisplay;
}

// ViewManager API exploration
pub trait ActiveView<TViewCtx: DisplayViewContext, TOut: Send> : PassiveView<TViewCtx> {
    fn active_update<'a>(&'a mut self, ctx: &TViewCtx, events: &[Event], ms_time: u64,
                         passives: & mut Vec<& mut PassiveView<TViewCtx> >)
                         -> Option<TOut>;
    fn yield_to<'a, TOut: Send, TActive: ActiveView<TViewCtx, TOut>>(&'a mut self, ctx: &TViewCtx,
                                active: &mut TActive,
                                passives: &mut Vec<&mut PassiveView<TViewCtx> >) -> TOut {
        let (sender, receiver) = channel();
        let mut cont = true;
        while cont {
            let time = precise_time_ns() / 1000000;

            // eh heh heh heh
            unsafe {
                //previously had a `&mut PassiveView<TViewCtx>)` cast in this transmute...
                let yielding = transmute_copy(self);
                //passives.push(yielding);
                passives.push(yielding);
            }
            let mut events = Vec::new();
            {
                for view in passives.iter_mut() {
                    view.passive_update(ctx, time);
                }
            }
            active.passive_update(ctx, time);
            loop {
                match poll_event() {
                    NoEvent => { break; },
                    event => { events.push(event); }
                }
            }
            let result = active.active_update(ctx, events.as_slice(), time, passives);
            ctx.get_display().renderer.present();
            passives.pop();
            if result.is_some() {
                cont = false;
                sender.send(result.expect("definitely gonna be something!"));
            }
        }
        receiver.recv()
    }
}

pub trait PassiveView<TViewCtx: DisplayViewContext> {
    fn passive_update(&mut self, ctx: &TViewCtx, ms_time: u64);
}
<|endoftext|>


<commit_before>// Copyright 2013-2014 Jeffery Olson
//
// Licensed under the 3-Clause BSD License, see LICENSE.txt
// at the top-level of this repository.
// This file may not be copied, modified, or distributed
// except according to those terms.
use std::io::timer;
use std::comm::channel;
use std::mem::transmute;
use time::precise_time_ns;
use std::time::duration::Duration;

use sdl2::event::{Event, NoEvent, poll_event};

use gfx::GameDisplay;

pub mod prefab;

pub fn throttle(fps: uint, cb: || -> bool) {
    let target_fps = (1000 / fps) as u64;
    loop {
        let next_frame = (precise_time_ns() / 1000000) + target_fps;
        match cb() {
            false => break,
            _ => {}
        }
        let now_time = precise_time_ns() / 1000000;
        if  now_time < next_frame {
            let sleep_gap = next_frame - now_time;
            timer::sleep(Duration::milliseconds(sleep_gap as i64));
        }
    }
}

fn cb_loop(cb: || -> bool) {
    loop {
        match cb() {
            false => break,
            _ => {}
        }
    }
}

pub trait DisplayViewContext {
    fn get_display<'a>(&'a self) -> &'a GameDisplay;
}

// ViewManager API exploration
pub trait ActiveView<TViewCtx: DisplayViewContext, TOut: Send> : PassiveView<TViewCtx> {
    fn active_update<'a>(&'a mut self, ctx: &TViewCtx, events: &[Event], ms_time: u64,
                         passives: & mut Vec<& mut PassiveView<TViewCtx> >)
                         -> Option<TOut>;
    fn yield_to<'a, TOut: Send>(&'a mut self, ctx: &TViewCtx,
                                active: &mut ActiveView<TViewCtx, TOut>,
                                passives: &mut Vec<&mut PassiveView<TViewCtx> >) -> TOut {
        let (sender, receiver) = channel();
        cb_loop(|| {
            match self._yield_inner(ctx, active, passives) {
                Some(out) => { sender.send(out); false },
                None => true
            }
        });
        receiver.recv()
    }
}

pub trait PassiveView<TViewCtx: DisplayViewContext> {
    fn passive_update(&mut self, ctx: &TViewCtx, ms_time: u64);
    fn _yield_inner<TOut: Send>(&mut self, ctx: &TViewCtx,
                         active: & mut ActiveView<TViewCtx, TOut>,
                         passives: & mut Vec<& mut PassiveView<TViewCtx> >) -> Option<TOut> {
        let time = precise_time_ns() / 1000000;

        // eh heh heh heh
        unsafe {
            let yielding = transmute(self as &mut PassiveView<TViewCtx>);
            passives.push(yielding);
        }
        let mut events = Vec::new();
        {
            for view in passives.mut_iter() {
                view.passive_update(ctx, time);
            }
        }
        active.passive_update(ctx, time);
        ctx.get_display().renderer.present();
        loop {
            match poll_event() {
                NoEvent => { break; },
                event => { events.push(event); }
            }
        }
        let result = active.active_update(ctx, events.as_slice(), time, passives);
        passives.pop();
        result
    }
}
<commit_msg>move renderer update to active active_update() call<commit_after>// Copyright 2013-2014 Jeffery Olson
//
// Licensed under the 3-Clause BSD License, see LICENSE.txt
// at the top-level of this repository.
// This file may not be copied, modified, or distributed
// except according to those terms.
use std::io::timer;
use std::comm::channel;
use std::mem::transmute;
use time::precise_time_ns;
use std::time::duration::Duration;

use sdl2::event::{Event, NoEvent, poll_event};

use gfx::GameDisplay;

pub mod prefab;

pub fn throttle(fps: uint, cb: || -> bool) {
    let target_fps = (1000 / fps) as u64;
    loop {
        let next_frame = (precise_time_ns() / 1000000) + target_fps;
        match cb() {
            false => break,
            _ => {}
        }
        let now_time = precise_time_ns() / 1000000;
        if  now_time < next_frame {
            let sleep_gap = next_frame - now_time;
            timer::sleep(Duration::milliseconds(sleep_gap as i64));
        }
    }
}

fn cb_loop(cb: || -> bool) {
    loop {
        match cb() {
            false => break,
            _ => {}
        }
    }
}

pub trait DisplayViewContext {
    fn get_display<'a>(&'a self) -> &'a GameDisplay;
}

// ViewManager API exploration
pub trait ActiveView<TViewCtx: DisplayViewContext, TOut: Send> : PassiveView<TViewCtx> {
    fn active_update<'a>(&'a mut self, ctx: &TViewCtx, events: &[Event], ms_time: u64,
                         passives: & mut Vec<& mut PassiveView<TViewCtx> >)
                         -> Option<TOut>;
    fn yield_to<'a, TOut: Send>(&'a mut self, ctx: &TViewCtx,
                                active: &mut ActiveView<TViewCtx, TOut>,
                                passives: &mut Vec<&mut PassiveView<TViewCtx> >) -> TOut {
        let (sender, receiver) = channel();
        cb_loop(|| {
            match self._yield_inner(ctx, active, passives) {
                Some(out) => { sender.send(out); false },
                None => true
            }
        });
        receiver.recv()
    }
}

pub trait PassiveView<TViewCtx: DisplayViewContext> {
    fn passive_update(&mut self, ctx: &TViewCtx, ms_time: u64);
    fn _yield_inner<TOut: Send>(&mut self, ctx: &TViewCtx,
                         active: & mut ActiveView<TViewCtx, TOut>,
                         passives: & mut Vec<& mut PassiveView<TViewCtx> >) -> Option<TOut> {
        let time = precise_time_ns() / 1000000;

        // eh heh heh heh
        unsafe {
            let yielding = transmute(self as &mut PassiveView<TViewCtx>);
            passives.push(yielding);
        }
        let mut events = Vec::new();
        {
            for view in passives.mut_iter() {
                view.passive_update(ctx, time);
            }
        }
        active.passive_update(ctx, time);
        loop {
            match poll_event() {
                NoEvent => { break; },
                event => { events.push(event); }
            }
        }
        let result = active.active_update(ctx, events.as_slice(), time, passives);
        ctx.get_display().renderer.present();
        passives.pop();
        result
    }
}
<|endoftext|>


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

// https://tools.ietf.org/html/draft-thomson-http-mice-03

use std::collections::VecDeque;
use ::sha2::{Sha256, Digest};

pub fn calculate(input: &[u8], record_size: usize) -> (Vec<u8>, Vec<u8>) {
    let record_size = std::cmp::min(record_size, input.len());
    let records: Vec<_> = if record_size > 0 {
        input.chunks(record_size).collect()
    } else {
        vec![input]
    };
    let mut proofs: VecDeque<Vec<u8>> = VecDeque::new();
    for record in records.iter().rev() {
        let mut hasher = Sha256::new();
        hasher.update(record);
        if let Some(f) = proofs.front() {
            hasher.update(f);
            hasher.update(&[1u8]);
        } else {
            hasher.update(&[0u8]);
        }
        proofs.push_front(hasher.finalize().to_vec());
    }
    let mut message = Vec::new();
    message.extend_from_slice(&(record_size as u64).to_be_bytes());
    for i in 0..records.len() {
        if i > 0 {
            message.extend_from_slice(&proofs[i]);
        }
        message.extend_from_slice(&records[i]);
    }
    let integrity = proofs.pop_front().unwrap();
    (integrity, message)
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn it_works() {
        // https://tools.ietf.org/html/draft-thomson-http-mice-03#section-4.1
        let input = "When I grow up, I want to be a watermelon".as_bytes();
        assert_eq!(
            calculate(input, 1000000),
            (
                ::base64::decode("dcRDgR2GM35DluAV13PzgnG6+pvQwPywfFvAu1UeFrs=").unwrap(),
                [&0x29_u64.to_be_bytes(), input].concat(),
            ),
        );
        // https://tools.ietf.org/html/draft-thomson-http-mice-03#section-4.2
        assert_eq!(
            calculate(input, 16),
            (
                ::base64::decode("IVa9shfs0nyKEhHqtB3WVNANJ2Njm5KjQLjRtnbkYJ4=").unwrap(),
                [
                    &0x10_u64.to_be_bytes(),
                    &input[0..16],
                    &::base64::decode("OElbplJlPK+Rv6JNK6p5/515IaoPoZo+2elWL7OQ60A=").unwrap(),
                    &input[16..32],
                    &::base64::decode("iPMpmgExHPrbEX3/RvwP4d16fWlK4l++p75PUu/KyN0=").unwrap(),
                    &input[32..],
                ].concat(),
            ),
        );
    }
}
<commit_msg>Add a special case for zero-length mice payload (#23)<commit_after>// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// https://tools.ietf.org/html/draft-thomson-http-mice-03

use std::collections::VecDeque;
use ::sha2::{Sha256, Digest};

pub fn calculate(input: &[u8], record_size: usize) -> (Vec<u8>, Vec<u8>) {
    if input.len() == 0 {
        return (
            crate::utils::get_sha(&[0]),
            vec![],
        );
    }
    let record_size = std::cmp::min(record_size, input.len());
    let records: Vec<_> = if record_size > 0 {
        input.chunks(record_size).collect()
    } else {
        vec![input]
    };
    let mut proofs: VecDeque<Vec<u8>> = VecDeque::new();
    for record in records.iter().rev() {
        let mut hasher = Sha256::new();
        hasher.update(record);
        if let Some(f) = proofs.front() {
            hasher.update(f);
            hasher.update(&[1u8]);
        } else {
            hasher.update(&[0u8]);
        }
        proofs.push_front(hasher.finalize().to_vec());
    }
    let mut message = Vec::new();
    message.extend_from_slice(&(record_size as u64).to_be_bytes());
    for i in 0..records.len() {
        if i > 0 {
            message.extend_from_slice(&proofs[i]);
        }
        message.extend_from_slice(&records[i]);
    }
    let integrity = proofs.pop_front().unwrap();
    (integrity, message)
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn it_works() {
        // https://tools.ietf.org/html/draft-thomson-http-mice-03#section-4.1
        let input = "When I grow up, I want to be a watermelon".as_bytes();
        assert_eq!(
            calculate(input, 1000000),
            (
                ::base64::decode("dcRDgR2GM35DluAV13PzgnG6+pvQwPywfFvAu1UeFrs=").unwrap(),
                [&0x29_u64.to_be_bytes(), input].concat(),
            ),
        );
        // https://tools.ietf.org/html/draft-thomson-http-mice-03#section-4.2
        assert_eq!(
            calculate(input, 16),
            (
                ::base64::decode("IVa9shfs0nyKEhHqtB3WVNANJ2Njm5KjQLjRtnbkYJ4=").unwrap(),
                [
                    &0x10_u64.to_be_bytes(),
                    &input[0..16],
                    &::base64::decode("OElbplJlPK+Rv6JNK6p5/515IaoPoZo+2elWL7OQ60A=").unwrap(),
                    &input[16..32],
                    &::base64::decode("iPMpmgExHPrbEX3/RvwP4d16fWlK4l++p75PUu/KyN0=").unwrap(),
                    &input[32..],
                ].concat(),
            ),
        );
    }
    #[test]
    fn empty_payload() {
        assert_eq!(
            calculate(b"", 16384),
            (
                ::base64::decode("bjQLnP+zepicpUTmu3gKLHiQHT+zNzh2hRGjBhevoB0=").unwrap(),
                vec![],
            ),
        );
    }
}
<|endoftext|>


<commit_before>#[cfg(target_os = "android")]
#[macro_use]
extern crate android_glue;

extern crate glutin;

mod support;

#[cfg(target_os = "android")]
android_start!(main);

#[cfg(not(feature = "window"))]
fn main() { println!("This example requires glutin to be compiled with the `window` feature"); }

#[cfg(feature = "window")]
fn resize_callback(width: u32, height: u32) {
    println!("Window resized to {}x{}", width, height);
}

#[cfg(feature = "window")]
fn main() {
    let mut window = glutin::Window::new().unwrap();
    window.set_title("A fantastic window!");
    window.set_window_resize_callback(Some(resize_callback as fn(u32, u32)));
    unsafe { window.make_current() };

    let context = support::load(&window);

    while !window.is_closed() {
        context.draw_frame((0.0, 1.0, 0.0, 1.0));
        window.swap_buffers();

        println!("{:?}", window.wait_events().next());
    }
}
<commit_msg>Print the pixel format in the `window` example<commit_after>#[cfg(target_os = "android")]
#[macro_use]
extern crate android_glue;

extern crate glutin;

mod support;

#[cfg(target_os = "android")]
android_start!(main);

#[cfg(not(feature = "window"))]
fn main() { println!("This example requires glutin to be compiled with the `window` feature"); }

#[cfg(feature = "window")]
fn resize_callback(width: u32, height: u32) {
    println!("Window resized to {}x{}", width, height);
}

#[cfg(feature = "window")]
fn main() {
    let mut window = glutin::Window::new().unwrap();
    window.set_title("A fantastic window!");
    window.set_window_resize_callback(Some(resize_callback as fn(u32, u32)));
    unsafe { window.make_current() };

    println!("Pixel format of the window: {:?}", window.get_pixel_format());

    let context = support::load(&window);

    while !window.is_closed() {
        context.draw_frame((0.0, 1.0, 0.0, 1.0));
        window.swap_buffers();

        println!("{:?}", window.wait_events().next());
    }
}
<|endoftext|>


<commit_before>//! Endpoints for yanking and unyanking specific versions of crates

use swirl::Job;

use super::{extract_crate_name_and_semver, version_and_crate};
use crate::controllers::cargo_prelude::*;
use crate::models::Rights;
use crate::models::{insert_version_owner_action, VersionAction};
use crate::schema::versions;
use crate::worker;

/// Handles the `DELETE /crates/:crate_id/:version/yank` route.
/// This does not delete a crate version, it makes the crate
/// version accessible only to crates that already have a
/// `Cargo.lock` containing this version.
///
/// Notes:
/// Crate deletion is not implemented to avoid breaking builds,
/// and the goal of yanking a crate is to prevent crates
/// beginning to depend on the yanked crate version.
pub fn yank(req: &mut dyn RequestExt) -> EndpointResult {
    modify_yank(req, true)
}

/// Handles the `PUT /crates/:crate_id/:version/unyank` route.
pub fn unyank(req: &mut dyn RequestExt) -> EndpointResult {
    modify_yank(req, false)
}

/// Changes `yanked` flag on a crate version record
fn modify_yank(req: &mut dyn RequestExt, yanked: bool) -> EndpointResult {
    // FIXME: Should reject bad requests before authentication, but can't due to
    // lifetime issues with `req`.
    let authenticated_user = req.authenticate()?;
    let (crate_name, semver) = extract_crate_name_and_semver(req)?;

    let conn = req.db_conn()?;
    let (version, krate) = version_and_crate(&conn, crate_name, semver)?;
    let api_token_id = authenticated_user.api_token_id();
    let user = authenticated_user.user();
    let owners = krate.owners(&conn)?;

    if user.rights(req.app(), &owners)? < Rights::Publish {
        return Err(cargo_err("must already be an owner to yank or unyank"));
    }

    if version.yanked == yanked {
        // The crate is alread in the state requested, nothing to do
        return ok_true();
    }

    diesel::update(&version)
        .set(versions::yanked.eq(yanked))
        .execute(&*conn)?;

    let action = if yanked {
        VersionAction::Yank
    } else {
        VersionAction::Unyank
    };

    insert_version_owner_action(&conn, version.id, user.id, api_token_id, action)?;

    worker::yank(krate.name, version, yanked).enqueue(&conn)?;

    ok_true()
}
<commit_msg>controllers::version::yank: Fix typo<commit_after>//! Endpoints for yanking and unyanking specific versions of crates

use swirl::Job;

use super::{extract_crate_name_and_semver, version_and_crate};
use crate::controllers::cargo_prelude::*;
use crate::models::Rights;
use crate::models::{insert_version_owner_action, VersionAction};
use crate::schema::versions;
use crate::worker;

/// Handles the `DELETE /crates/:crate_id/:version/yank` route.
/// This does not delete a crate version, it makes the crate
/// version accessible only to crates that already have a
/// `Cargo.lock` containing this version.
///
/// Notes:
/// Crate deletion is not implemented to avoid breaking builds,
/// and the goal of yanking a crate is to prevent crates
/// beginning to depend on the yanked crate version.
pub fn yank(req: &mut dyn RequestExt) -> EndpointResult {
    modify_yank(req, true)
}

/// Handles the `PUT /crates/:crate_id/:version/unyank` route.
pub fn unyank(req: &mut dyn RequestExt) -> EndpointResult {
    modify_yank(req, false)
}

/// Changes `yanked` flag on a crate version record
fn modify_yank(req: &mut dyn RequestExt, yanked: bool) -> EndpointResult {
    // FIXME: Should reject bad requests before authentication, but can't due to
    // lifetime issues with `req`.
    let authenticated_user = req.authenticate()?;
    let (crate_name, semver) = extract_crate_name_and_semver(req)?;

    let conn = req.db_conn()?;
    let (version, krate) = version_and_crate(&conn, crate_name, semver)?;
    let api_token_id = authenticated_user.api_token_id();
    let user = authenticated_user.user();
    let owners = krate.owners(&conn)?;

    if user.rights(req.app(), &owners)? < Rights::Publish {
        return Err(cargo_err("must already be an owner to yank or unyank"));
    }

    if version.yanked == yanked {
        // The crate is already in the state requested, nothing to do
        return ok_true();
    }

    diesel::update(&version)
        .set(versions::yanked.eq(yanked))
        .execute(&*conn)?;

    let action = if yanked {
        VersionAction::Yank
    } else {
        VersionAction::Unyank
    };

    insert_version_owner_action(&conn, version.id, user.id, api_token_id, action)?;

    worker::yank(krate.name, version, yanked).enqueue(&conn)?;

    ok_true()
}
<|endoftext|>


<commit_before>use rocket::State;
use rocket_contrib::Json;
use validation::user::UserLogin;
use diesel::prelude::*;
use diesel;
use serde_json::Value;

use models::user::{UserModel, NewUser};
use schema::users;
use schema::users::dsl::*;
use helpers::db::DB;
use responses::{APIResponse, ok, created, conflict, unauthorized, unprocessable_entity,
                internal_server_error};
use config::Config;

/// Log the user in and return a response with an auth token.
///
/// Return UNAUTHORIZED in case the user can't be found or if the password is incorrect.
#[post("/login", data = "<user_in>", format = "application/json")]
pub fn login(
    user_in: Json<UserLogin>,
    db: DB,
    config: State<Config>,
) -> Result<APIResponse, APIResponse> {
    let user_q = users
        .filter(email.eq(&user_in.email))
        .first::<UserModel>(&*db)
        .optional()?;

    // For privacy reasons, we'll not provide the exact reason for failure here (although this
    // could probably be timing attacked to find out whether users exist or not.
    let mut user = user_q.ok_or_else(|| {
        unauthorized().message("Username or password incorrect.")
    })?;

    if !user.verify_password(user_in.password.as_str()) {
        return Err(unauthorized().message("Username or password incorrect."));
    }

    let token = if user.has_valid_auth_token(config.auth_token_timeout_days) {
        user.current_auth_token.ok_or_else(internal_server_error)?
    } else {
        user.generate_auth_token(&db)?
    };

    Ok(ok().data(json!({
        "user_id": user.id,
        "token": token,
    })))
}

/// Register a new user using email and password.
///
/// Return CONFLICT is a user with the same email already exists.
#[post("/register", data = "<user>", format = "application/json")]
pub fn register(user: Result<UserLogin, Value>, db: DB) -> Result<APIResponse, APIResponse> {
    let user_data = user.map_err(unprocessable_entity)?;
    let results = users
        .filter(email.eq(user_data.email.clone()))
        .first::<UserModel>(&*db);
    if results.is_ok() {
        return Err(conflict().message("User already exists."));
    }

    let new_password_hash = UserModel::make_password_hash(user_data.password.as_str());
    let new_user = NewUser {
        email: user_data.email.clone(),
        password_hash: new_password_hash,
    };

    let user = diesel::insert(&new_user)
        .into(users::table)
        .get_result::<UserModel>(&*db)?;

    Ok(created().data(json!(&user)))
}
<commit_msg>Let the database check whether user already exists<commit_after>use rocket::State;
use rocket_contrib::Json;
use validation::user::UserLogin;
use diesel::prelude::*;
use diesel;
use serde_json::Value;

use models::user::{UserModel, NewUser};
use schema::users;
use schema::users::dsl::*;
use helpers::db::DB;
use responses::{APIResponse, ok, created, conflict, unauthorized, unprocessable_entity,
internal_server_error};
use config::Config;

/// Log the user in and return a response with an auth token.
///
/// Return UNAUTHORIZED in case the user can't be found or if the password is incorrect.
#[post("/login", data = "<user_in>", format = "application/json")]
pub fn login(
    user_in: Json<UserLogin>,
    db: DB,
    config: State<Config>,
    ) -> Result<APIResponse, APIResponse> {
    let user_q = users
        .filter(email.eq(&user_in.email))
        .first::<UserModel>(&*db)
        .optional()?;

    // For privacy reasons, we'll not provide the exact reason for failure here (although this
    // could probably be timing attacked to find out whether users exist or not.
    let mut user = user_q.ok_or_else(|| {
        unauthorized().message("Username or password incorrect.")
    })?;

    if !user.verify_password(user_in.password.as_str()) {
        return Err(unauthorized().message("Username or password incorrect."));
    }

    let token = if user.has_valid_auth_token(config.auth_token_timeout_days) {
        user.current_auth_token.ok_or_else(internal_server_error)?
    } else {
        user.generate_auth_token(&db)?
    };

    Ok(ok().data(json!({
        "user_id": user.id,
        "token": token,
    })))
}

/// Register a new user using email and password.
///
/// Return CONFLICT is a user with the same email already exists.
#[post("/register", data = "<user>", format = "application/json")]
pub fn register(user: Result<UserLogin, Value>, db: DB) -> Result<APIResponse, APIResponse> {
    let user_data = user.map_err(unprocessable_entity)?;

    let new_password_hash = UserModel::make_password_hash(user_data.password.as_str());
    let new_user = NewUser {
        email: user_data.email.clone(),
        password_hash: new_password_hash,
    };

    let insert_result = diesel::insert(&new_user)
        .into(users::table)
        .get_result::<UserModel>(&*db);
    if let Err(diesel::result::Error::DatabaseError(diesel::result::DatabaseErrorKind::UniqueViolation, _)) = insert_result {
        return Err(conflict().message("User already exists."));
    }

    let user = insert_result?;
    Ok(created().data(json!(&user)))
}
<|endoftext|>


<commit_before>use bits;
use consts;

#[derive(Copy, Clone)]
pub struct Decoder {
    pos: usize,
    decider: Decider,
}

impl Decoder {
    pub fn new(decider: Decider) -> Decoder {
        Decoder {
            // Decoder is created after first sample of first symbol after sync has
            // already been read.
            pos: 1,
            decider: decider,
        }
    }

    pub fn feed(&mut self, s: f32) -> Option<bits::Dibit> {
        self.pos += 1;
        self.pos %= consts::PERIOD;

        if self.pos == 0 {
            Some(self.decider.decide(s))
        } else {
            None
        }
    }
}

#[derive(Copy, Clone)]
pub struct Decider {
    pthresh: f32,
    mthresh: f32,
    nthresh: f32,
}

impl Decider {
    pub fn new(pthresh: f32, mthresh: f32, nthresh: f32) -> Decider {
        Decider {
            pthresh: pthresh,
            mthresh: mthresh,
            nthresh: nthresh,
        }
    }

    pub fn decide(&self, sample: f32) -> bits::Dibit {
        if sample > self.pthresh {
            bits::Dibit::new(0b01)
        } else if sample > self.mthresh && sample <= self.pthresh {
            bits::Dibit::new(0b00)
        } else if sample <= self.mthresh && sample > self.nthresh {
            bits::Dibit::new(0b10)
        } else {
            bits::Dibit::new(0b11)
        }
    }
}

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

    #[test]
    fn test_decider() {
        let d = Decider::new(-0.004, -0.1, -0.196);

        assert_eq!(d.decide(0.044).bits(), 0b01);
        assert_eq!(d.decide(-0.052).bits(), 0b00);
        assert_eq!(d.decide(-0.148).bits(), 0b10);
        assert_eq!(d.decide(-0.244).bits(), 0b11);
    }

    #[test]
    fn test_decoder() {
        let mut d = Decoder::new(Decider::new(0.0, 0.0, 0.0));

        assert!(d.feed(0.2099609375000000).is_none());
        assert!(d.feed(0.2165222167968750).is_none());
        assert!(d.feed(0.2179870605468750).is_none());
        assert!(d.feed(0.2152709960937500).is_none());
        assert!(d.feed(0.2094726562500000).is_none());
        assert!(d.feed(0.2018737792968750).is_none());
        assert!(d.feed(0.1937255859375000).is_none());
        assert!(d.feed(0.1861572265625000).is_none());
        assert!(d.feed(0.1799926757812500).is_some());

        assert!(d.feed(0.1752929687500000).is_none());
        assert!(d.feed(0.1726684570312500).is_none());
        assert!(d.feed(0.1720886230468750).is_none());
        assert!(d.feed(0.1732177734375000).is_none());
        assert!(d.feed(0.1754455566406250).is_none());
        assert!(d.feed(0.1780395507812500).is_none());
        assert!(d.feed(0.1803588867187500).is_none());
        assert!(d.feed(0.1817321777343750).is_none());
        assert!(d.feed(0.1816711425781250).is_none());
        assert!(d.feed(0.1799926757812500).is_some());
    }
}
<commit_msg>Add some docs to baseband<commit_after>use bits;
use consts;

/// Decodes symbol from sample at each symbol instant.
#[derive(Copy, Clone)]
pub struct Decoder {
    pos: usize,
    decider: Decider,
}

impl Decoder {
    /// Create a new Decoder with the given symbol decider.
    pub fn new(decider: Decider) -> Decoder {
        Decoder {
            // Decoder is created after first sample of first symbol after sync has
            // already been read.
            pos: 1,
            decider: decider,
        }
    }

    /// Examine the given sample and, based on the symbol clock, decode it a symbol or
    /// do nothing.
    pub fn feed(&mut self, s: f32) -> Option<bits::Dibit> {
        self.pos += 1;
        self.pos %= consts::PERIOD;

        if self.pos == 0 {
            Some(self.decider.decide(s))
        } else {
            None
        }
    }
}

/// Decides which symbol a sample represents with a threshold method.
#[derive(Copy, Clone)]
pub struct Decider {
    pthresh: f32,
    mthresh: f32,
    nthresh: f32,
}

impl Decider {
    /// Create a new Decider with the given positive threshold, mid threshold, and
    /// negative threshold.
    pub fn new(pthresh: f32, mthresh: f32, nthresh: f32) -> Decider {
        Decider {
            pthresh: pthresh,
            mthresh: mthresh,
            nthresh: nthresh,
        }
    }

    /// Decide with symbol the given sample looks closest to.
    pub fn decide(&self, sample: f32) -> bits::Dibit {
        if sample > self.pthresh {
            bits::Dibit::new(0b01)
        } else if sample > self.mthresh && sample <= self.pthresh {
            bits::Dibit::new(0b00)
        } else if sample <= self.mthresh && sample > self.nthresh {
            bits::Dibit::new(0b10)
        } else {
            bits::Dibit::new(0b11)
        }
    }
}

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

    #[test]
    fn test_decider() {
        let d = Decider::new(-0.004, -0.1, -0.196);

        assert_eq!(d.decide(0.044).bits(), 0b01);
        assert_eq!(d.decide(-0.052).bits(), 0b00);
        assert_eq!(d.decide(-0.148).bits(), 0b10);
        assert_eq!(d.decide(-0.244).bits(), 0b11);
    }

    #[test]
    fn test_decoder() {
        let mut d = Decoder::new(Decider::new(0.0, 0.0, 0.0));

        assert!(d.feed(0.2099609375000000).is_none());
        assert!(d.feed(0.2165222167968750).is_none());
        assert!(d.feed(0.2179870605468750).is_none());
        assert!(d.feed(0.2152709960937500).is_none());
        assert!(d.feed(0.2094726562500000).is_none());
        assert!(d.feed(0.2018737792968750).is_none());
        assert!(d.feed(0.1937255859375000).is_none());
        assert!(d.feed(0.1861572265625000).is_none());
        assert!(d.feed(0.1799926757812500).is_some());

        assert!(d.feed(0.1752929687500000).is_none());
        assert!(d.feed(0.1726684570312500).is_none());
        assert!(d.feed(0.1720886230468750).is_none());
        assert!(d.feed(0.1732177734375000).is_none());
        assert!(d.feed(0.1754455566406250).is_none());
        assert!(d.feed(0.1780395507812500).is_none());
        assert!(d.feed(0.1803588867187500).is_none());
        assert!(d.feed(0.1817321777343750).is_none());
        assert!(d.feed(0.1816711425781250).is_none());
        assert!(d.feed(0.1799926757812500).is_some());
    }
}
<|endoftext|>


<commit_before>extern crate sqlib;

use sqlib::{Connection, ChannelList, ClientList};
use sqlib::map::*;

fn main() {
    let mut conn = Connection::new("127.0.0.1:10011".to_string()).unwrap();
    conn.send_command("use 1").unwrap();
    conn.send_command("login serveradmin hqjI+wn7").unwrap();
    let mut clients = conn.send_command("clientlist").unwrap().parse::<ClientList>().unwrap();

    for client in clients.get_mut().iter_mut() {
        let command = format!("clientinfo clid={}", client.clid);
        let str = conn.send_command(command).unwrap();
        let map = to_map(&str);
        client.mut_from_map(&map);
    }

    let mut channels = conn.send_command("channellist").unwrap().parse::<ChannelList>().unwrap();
    channels.merge_clients(&clients);
    for channel in channels.iter() {
        println!("{}", channel);
    }
    let _ = conn.quit();
}
<commit_msg>updating the testing main<commit_after>extern crate sqlib;

use sqlib::Connection;

fn main() {
    let mut conn = Connection::new("127.0.0.1:10011".to_string()).unwrap();
    conn.send_command("use 1").unwrap();
    conn.send_command("login serveradmin hqjI+wn7").unwrap();

    let channels = conn.channellist_with_clients().unwrap();

    for channel in channels.iter() {
        if !channel.is_empty() {
            println!("{}", channel);
        }
    }
    let _ = conn.quit();
}
<|endoftext|>


<commit_before>use cargo::ops;
use cargo::util::{CargoError, CliResult, Config};

#[derive(Deserialize)]
pub struct Options {
    arg_crate: Option<String>,
    flag_token: Option<String>,
    flag_vers: Option<String>,
    flag_index: Option<String>,
    flag_verbose: u32,
    flag_quiet: Option<bool>,
    flag_color: Option<String>,
    flag_undo: bool,
    flag_frozen: bool,
    flag_locked: bool,
    #[serde(rename = "flag_Z")]
    flag_z: Vec<String>,
    flag_registry: Option<String>,
}

pub static USAGE: &'static str = "
Remove a pushed crate from the index

Usage:
    cargo yank [options] [<crate>]

Options:
    -h, --help          Print this message
    --vers VERSION      The version to yank or un-yank
    --undo              Undo a yank, putting a version back into the index
    --index INDEX       Registry index to yank from
    --token TOKEN       API token to use when authenticating
    -v, --verbose ...   Use verbose output (-vv very verbose/build.rs output)
    -q, --quiet         No output printed to stdout
    --color WHEN        Coloring: auto, always, never
    --frozen            Require Cargo.lock and cache are up to date
    --locked            Require Cargo.lock is up to date
    -Z FLAG ...         Unstable (nightly-only) flags to Cargo
    --registry REGISTRY Registry to use

The yank command removes a previously pushed crate's version from the server's
index. This command does not delete any data, and the crate will still be
available for download via the registry's download link.

Note that existing crates locked to a yanked version will still be able to
download the yanked version to use it. Cargo will, however, not allow any new
crates to be locked to any yanked version.
";

pub fn execute(options: Options, config: &mut Config) -> CliResult {
    config.configure(options.flag_verbose,
                     options.flag_quiet,
                     &options.flag_color,
                     options.flag_frozen,
                     options.flag_locked,
                     &options.flag_z)?;

    if options.flag_registry.is_some() && !config.cli_unstable().unstable_options {
        return Err(CargoError::from("registry option is an unstable feature and requires -Zunstable-options to use.").into());
    }

    ops::yank(config,
              options.arg_crate,
              options.flag_vers,
              options.flag_token,
              options.flag_index,
              options.flag_undo,
              options.flag_registry)?;
    Ok(())
}

<commit_msg>Fix yank help.<commit_after>use cargo::ops;
use cargo::util::{CargoError, CliResult, Config};

#[derive(Deserialize)]
pub struct Options {
    arg_crate: Option<String>,
    flag_token: Option<String>,
    flag_vers: Option<String>,
    flag_index: Option<String>,
    flag_verbose: u32,
    flag_quiet: Option<bool>,
    flag_color: Option<String>,
    flag_undo: bool,
    flag_frozen: bool,
    flag_locked: bool,
    #[serde(rename = "flag_Z")]
    flag_z: Vec<String>,
    flag_registry: Option<String>,
}

pub static USAGE: &'static str = "
Remove a pushed crate from the index

Usage:
    cargo yank [options] [<crate>]

Options:
    -h, --help               Print this message
    --vers VERSION           The version to yank or un-yank
    --undo                   Undo a yank, putting a version back into the index
    --index INDEX            Registry index to yank from
    --token TOKEN            API token to use when authenticating
    -v, --verbose ...        Use verbose output (-vv very verbose/build.rs output)
    -q, --quiet              No output printed to stdout
    --color WHEN             Coloring: auto, always, never
    --frozen                 Require Cargo.lock and cache are up to date
    --locked                 Require Cargo.lock is up to date
    -Z FLAG ...              Unstable (nightly-only) flags to Cargo
    --registry REGISTRY      Registry to use

The yank command removes a previously pushed crate's version from the server's
index. This command does not delete any data, and the crate will still be
available for download via the registry's download link.

Note that existing crates locked to a yanked version will still be able to
download the yanked version to use it. Cargo will, however, not allow any new
crates to be locked to any yanked version.
";

pub fn execute(options: Options, config: &mut Config) -> CliResult {
    config.configure(options.flag_verbose,
                     options.flag_quiet,
                     &options.flag_color,
                     options.flag_frozen,
                     options.flag_locked,
                     &options.flag_z)?;

    if options.flag_registry.is_some() && !config.cli_unstable().unstable_options {
        return Err(CargoError::from("registry option is an unstable feature and requires -Zunstable-options to use.").into());
    }

    ops::yank(config,
              options.arg_crate,
              options.flag_vers,
              options.flag_token,
              options.flag_index,
              options.flag_undo,
              options.flag_registry)?;
    Ok(())
}

<|endoftext|>


<commit_before>use libc;
use std::ptr;
use std::ffi::CStr;
use constants::*;
use csh;
use ffi::{cs_close, cs_open, cs_disasm, cs_reg_name, cs_insn_name, cs_errno};
use instruction::{Insn, Instructions};

pub struct Capstone {
    csh: csh, // Opaque handle to cs_engine
}

pub type CsResult<T> = Result<T, CsErr>;

impl Capstone {
    pub fn new(arch: CsArch, mode: CsMode) -> CsResult<Capstone> {
        let mut handle = 0;
        let err = unsafe { cs_open(arch, mode, &mut handle) };

        if CsErr::CS_ERR_OK == err {
            Ok(Capstone { csh: handle })
        } else {
            Err(err)
        }
    }

    pub fn disasm(&self, code: &[u8], addr: u64, count: isize) -> CsResult<Instructions> {
        let mut ptr: *const Insn = ptr::null();
        let insn_count = unsafe {
            cs_disasm(self.csh,
                      code.as_ptr(),
                      code.len() as libc::size_t,
                      addr,
                      count as libc::size_t,
                      &mut ptr)
        };
        if insn_count == 0 {
            return Err(unsafe { cs_errno(self.csh) })
        }

        Ok(Instructions::from_raw_parts(ptr, insn_count as isize))
    }

    pub fn reg_name(&self, reg_id: u64) -> CsResult<String> {
        let reg_name = unsafe {
            let _reg_name = cs_reg_name(self.csh, reg_id as libc::size_t);
            if _reg_name == ptr::null() {
                return Err(cs_errno(self.csh))
            }

            CStr::from_ptr(_reg_name).to_string_lossy().into_owned()
        };

        Ok(reg_name)
    }

    pub fn insn_name(&self, reg_id: u64) -> CsResult<String> {
        let reg_name = unsafe {
            let _reg_name = cs_insn_name(self.csh, reg_id as libc::size_t);
            if _reg_name == ptr::null() {
                return Err(cs_errno(self.csh))
            }

            CStr::from_ptr(_reg_name).to_string_lossy().into_owned()
        };

        Ok(reg_name)
    }
}

impl Drop for Capstone {
    fn drop(&mut self) {
        unsafe { cs_close(&mut self.csh) };
    }
}
<commit_msg>cs_reg_name and cs_insn_name do not set cs_errno<commit_after>use libc;
use std::ptr;
use std::ffi::CStr;
use constants::*;
use csh;
use ffi::{cs_close, cs_open, cs_disasm, cs_reg_name, cs_insn_name, cs_errno};
use instruction::{Insn, Instructions};

pub struct Capstone {
    csh: csh, // Opaque handle to cs_engine
}

pub type CsResult<T> = Result<T, CsErr>;

impl Capstone {
    pub fn new(arch: CsArch, mode: CsMode) -> CsResult<Capstone> {
        let mut handle = 0;
        let err = unsafe { cs_open(arch, mode, &mut handle) };

        if CsErr::CS_ERR_OK == err {
            Ok(Capstone { csh: handle })
        } else {
            Err(err)
        }
    }

    pub fn disasm(&self, code: &[u8], addr: u64, count: isize) -> CsResult<Instructions> {
        let mut ptr: *const Insn = ptr::null();
        let insn_count = unsafe {
            cs_disasm(self.csh,
                      code.as_ptr(),
                      code.len() as libc::size_t,
                      addr,
                      count as libc::size_t,
                      &mut ptr)
        };
        if insn_count == 0 {
            return Err(unsafe { cs_errno(self.csh) })
        }

        Ok(Instructions::from_raw_parts(ptr, insn_count as isize))
    }

    pub fn reg_name(&self, reg_id: u64) -> Option<String> {
        let reg_name = unsafe {
            let _reg_name = cs_reg_name(self.csh, reg_id as libc::size_t);
            if _reg_name == ptr::null() {
                return None
            }

            CStr::from_ptr(_reg_name).to_string_lossy().into_owned()
        };

        Some(reg_name)
    }

    pub fn insn_name(&self, reg_id: u64) -> Option<String> {
        let reg_name = unsafe {
            let _reg_name = cs_insn_name(self.csh, reg_id as libc::size_t);
            if _reg_name == ptr::null() {
                return None
            }

            CStr::from_ptr(_reg_name).to_string_lossy().into_owned()
        };

        Some(reg_name)
    }
}

impl Drop for Capstone {
    fn drop(&mut self) {
        unsafe { cs_close(&mut self.csh) };
    }
}
<|endoftext|>


<commit_before>use kay::{ID, Recipient, Fate, Actor};
use compact::CDict;
use descartes::{N, Band, Path, FiniteCurve};
use monet::{Thing, Instance};
use core::geometry::band_to_thing;
use super::{CurrentPlan, SelectableStrokeRef};
use super::super::plan::{PlanDelta, BuiltStrokes, PlanResultDelta};
use super::super::lane_stroke::LaneStroke;

use monet::SetupInScene;

impl Recipient<SetupInScene> for CurrentPlan {
    fn receive(&mut self, _msg: &SetupInScene) -> Fate {
        Fate::Live
    }
}

use monet::RenderToScene;
use monet::UpdateThing;

impl Recipient<RenderToScene> for CurrentPlan {
    fn receive(&mut self, msg: &RenderToScene) -> Fate {
        match *msg {
            RenderToScene { renderer_id, scene_id } => {
                if self.preview.is_none() {
                    let preview = self.update_preview();
                    render_strokes(&preview.plan_delta, renderer_id, scene_id);

                }
                if !self.interactables_valid {
                    self.update_interactables();
                }
                if let Some(ref result_delta) = self.preview_result_delta {
                    // TODO: add something like prepare-render to monet to make sure
                    // we have new state in time
                    if !self.preview_result_delta_rendered {
                        self.preview_result_delta_rendered = true;

                        render_trimmed_strokes(result_delta, renderer_id, scene_id);
                        render_intersections(result_delta, renderer_id, scene_id);
                        render_transfer_lanes(result_delta, renderer_id, scene_id);
                    }
                }
                if let Some(ref built_strokes) = self.built_strokes {
                    render_selections(&self.preview.as_ref().unwrap().selections,
                                      &self.preview.as_ref().unwrap().plan_delta,
                                      built_strokes,
                                      renderer_id,
                                      scene_id);
                }

                Fate::Live
            }
        }
    }
}

fn render_strokes(delta: &PlanDelta, renderer_id: ID, scene_id: usize) {
    let destroyed_strokes_thing: Thing = delta.strokes_to_destroy
        .pairs()
        .filter(|&(_, stroke)| stroke.nodes().len() > 1)
        .map(|(_, stroke)| band_to_thing(&Band::new(stroke.path().clone(), 5.0), 0.1))
        .sum();
    renderer_id <<
    UpdateThing {
        scene_id: scene_id,
        thing_id: 5496,
        thing: destroyed_strokes_thing,
        instance: Instance::with_color([1.0, 0.0, 0.0]),
        is_decal: true,
    };
    let stroke_base_thing: Thing = delta.new_strokes
        .iter()
        .filter(|stroke| stroke.nodes().len() > 1)
        .map(|stroke| band_to_thing(&Band::new(stroke.path().clone(), 6.0), 0.1))
        .sum();
    renderer_id <<
    UpdateThing {
        scene_id: scene_id,
        thing_id: 5498,
        thing: stroke_base_thing,
        instance: Instance::with_color([1.0, 1.0, 1.0]),
        is_decal: true,
    };
    let stroke_thing: Thing = delta.new_strokes
        .iter()
        .filter(|stroke| stroke.nodes().len() > 1)
        .map(LaneStroke::preview_thing)
        .sum();
    renderer_id <<
    UpdateThing {
        scene_id: scene_id,
        thing_id: 5499,
        thing: stroke_thing,
        instance: Instance::with_color([0.6, 0.6, 0.6]),
        is_decal: true,
    };
}

fn render_trimmed_strokes(result_delta: &PlanResultDelta, renderer_id: ID, scene_id: usize) {
    let trimmed_stroke_thing: Thing = result_delta.trimmed_strokes
        .to_create
        .values()
        .filter(|stroke| stroke.nodes().len() > 1)
        .map(LaneStroke::preview_thing)
        .sum();
    renderer_id <<
    UpdateThing {
        scene_id: scene_id,
        thing_id: 5500,
        thing: trimmed_stroke_thing,
        instance: Instance::with_color([0.3, 0.3, 0.5]),
        is_decal: true,
    };
}

fn render_intersections(result_delta: &PlanResultDelta, renderer_id: ID, scene_id: usize) {
    let intersections_thing: Thing = result_delta.intersections
        .to_create
        .values()
        .filter(|i| i.shape.segments().len() > 0)
        .map(|i| band_to_thing(&Band::new(i.shape.clone(), 0.4), 0.5))
        .sum();
    renderer_id <<
    UpdateThing {
        scene_id: scene_id,
        thing_id: 5501,
        thing: intersections_thing,
        instance: Instance::with_color([0.0, 0.0, 1.0]),
        is_decal: true,
    };
    let connecting_strokes_thing: Thing = result_delta.intersections
        .to_create
        .values()
        .filter(|i| !i.strokes.is_empty())
        .map(|i| -> Thing { i.strokes.iter().map(LaneStroke::preview_thing).sum() })
        .sum();
    renderer_id <<
    UpdateThing {
        scene_id: scene_id,
        thing_id: 5502,
        thing: connecting_strokes_thing,
        instance: Instance::with_color([0.5, 0.5, 1.0]),
        is_decal: true,
    };
}

fn render_transfer_lanes(result_delta: &PlanResultDelta, renderer_id: ID, scene_id: usize) {
    let transfer_strokes_thing: Thing = result_delta.transfer_strokes
        .to_create
        .values()
        .map(|lane_stroke| band_to_thing(&Band::new(lane_stroke.path().clone(), 0.3), 0.1))
        .sum();
    renderer_id <<
    UpdateThing {
        scene_id: scene_id,
        thing_id: 5503,
        thing: transfer_strokes_thing,
        instance: Instance::with_color([1.0, 0.5, 0.0]),
        is_decal: true,
    };
}

fn render_selections(selections: &CDict<SelectableStrokeRef, (N, N)>,
                     plan_delta: &PlanDelta,
                     built_strokes: &BuiltStrokes,
                     renderer_id: ID,
                     scene_id: usize) {
    let addable_thing = selections.pairs()
        .filter_map(|(&selection_ref, &(start, end))| {
            let stroke = selection_ref.get_stroke(plan_delta, built_strokes);
            stroke.path().shift_orthogonally(5.0).and_then(|shifted_path| {
                shifted_path.subsection(start, end)
                    .map(|subsection| band_to_thing(&Band::new(subsection, 5.0), 0.1))
            })
        })
        .sum();
    renderer_id <<
    UpdateThing {
        scene_id: scene_id,
        thing_id: 5497,
        thing: addable_thing,
        instance: Instance::with_color([0.8, 0.8, 1.0]),
        is_decal: true,
    };
    let selection_thing = selections.pairs()
        .filter_map(|(&selection_ref, &(start, end))| {
            let stroke = selection_ref.get_stroke(plan_delta, built_strokes);
            stroke.path()
                .subsection(start, end)
                .map(|subsection| band_to_thing(&Band::new(subsection, 5.0), 0.1))
        })
        .sum();
    renderer_id <<
    UpdateThing {
        scene_id: scene_id,
        thing_id: 5504,
        thing: selection_thing,
        instance: Instance::with_color([0.0, 0.0, 1.0]),
        is_decal: true,
    };
}

pub fn setup() {
    CurrentPlan::handle::<SetupInScene>();
    CurrentPlan::handle::<RenderToScene>();
}
<commit_msg>Geometry fix for rendered addable<commit_after>use kay::{ID, Recipient, Fate, Actor};
use compact::CDict;
use descartes::{N, Band, Path, FiniteCurve};
use monet::{Thing, Instance};
use core::geometry::band_to_thing;
use super::{CurrentPlan, SelectableStrokeRef};
use super::super::plan::{PlanDelta, BuiltStrokes, PlanResultDelta};
use super::super::lane_stroke::LaneStroke;

use monet::SetupInScene;

impl Recipient<SetupInScene> for CurrentPlan {
    fn receive(&mut self, _msg: &SetupInScene) -> Fate {
        Fate::Live
    }
}

use monet::RenderToScene;
use monet::UpdateThing;

impl Recipient<RenderToScene> for CurrentPlan {
    fn receive(&mut self, msg: &RenderToScene) -> Fate {
        match *msg {
            RenderToScene { renderer_id, scene_id } => {
                if self.preview.is_none() {
                    let preview = self.update_preview();
                    render_strokes(&preview.plan_delta, renderer_id, scene_id);

                }
                if !self.interactables_valid {
                    self.update_interactables();
                }
                if let Some(ref result_delta) = self.preview_result_delta {
                    // TODO: add something like prepare-render to monet to make sure
                    // we have new state in time
                    if !self.preview_result_delta_rendered {
                        self.preview_result_delta_rendered = true;

                        render_trimmed_strokes(result_delta, renderer_id, scene_id);
                        render_intersections(result_delta, renderer_id, scene_id);
                        render_transfer_lanes(result_delta, renderer_id, scene_id);
                    }
                }
                if let Some(ref built_strokes) = self.built_strokes {
                    render_selections(&self.preview.as_ref().unwrap().selections,
                                      &self.preview.as_ref().unwrap().plan_delta,
                                      built_strokes,
                                      renderer_id,
                                      scene_id);
                }

                Fate::Live
            }
        }
    }
}

fn render_strokes(delta: &PlanDelta, renderer_id: ID, scene_id: usize) {
    let destroyed_strokes_thing: Thing = delta.strokes_to_destroy
        .pairs()
        .filter(|&(_, stroke)| stroke.nodes().len() > 1)
        .map(|(_, stroke)| band_to_thing(&Band::new(stroke.path().clone(), 5.0), 0.1))
        .sum();
    renderer_id <<
    UpdateThing {
        scene_id: scene_id,
        thing_id: 5496,
        thing: destroyed_strokes_thing,
        instance: Instance::with_color([1.0, 0.0, 0.0]),
        is_decal: true,
    };
    let stroke_base_thing: Thing = delta.new_strokes
        .iter()
        .filter(|stroke| stroke.nodes().len() > 1)
        .map(|stroke| band_to_thing(&Band::new(stroke.path().clone(), 6.0), 0.1))
        .sum();
    renderer_id <<
    UpdateThing {
        scene_id: scene_id,
        thing_id: 5498,
        thing: stroke_base_thing,
        instance: Instance::with_color([1.0, 1.0, 1.0]),
        is_decal: true,
    };
    let stroke_thing: Thing = delta.new_strokes
        .iter()
        .filter(|stroke| stroke.nodes().len() > 1)
        .map(LaneStroke::preview_thing)
        .sum();
    renderer_id <<
    UpdateThing {
        scene_id: scene_id,
        thing_id: 5499,
        thing: stroke_thing,
        instance: Instance::with_color([0.6, 0.6, 0.6]),
        is_decal: true,
    };
}

fn render_trimmed_strokes(result_delta: &PlanResultDelta, renderer_id: ID, scene_id: usize) {
    let trimmed_stroke_thing: Thing = result_delta.trimmed_strokes
        .to_create
        .values()
        .filter(|stroke| stroke.nodes().len() > 1)
        .map(LaneStroke::preview_thing)
        .sum();
    renderer_id <<
    UpdateThing {
        scene_id: scene_id,
        thing_id: 5500,
        thing: trimmed_stroke_thing,
        instance: Instance::with_color([0.3, 0.3, 0.5]),
        is_decal: true,
    };
}

fn render_intersections(result_delta: &PlanResultDelta, renderer_id: ID, scene_id: usize) {
    let intersections_thing: Thing = result_delta.intersections
        .to_create
        .values()
        .filter(|i| i.shape.segments().len() > 0)
        .map(|i| band_to_thing(&Band::new(i.shape.clone(), 0.4), 0.5))
        .sum();
    renderer_id <<
    UpdateThing {
        scene_id: scene_id,
        thing_id: 5501,
        thing: intersections_thing,
        instance: Instance::with_color([0.0, 0.0, 1.0]),
        is_decal: true,
    };
    let connecting_strokes_thing: Thing = result_delta.intersections
        .to_create
        .values()
        .filter(|i| !i.strokes.is_empty())
        .map(|i| -> Thing { i.strokes.iter().map(LaneStroke::preview_thing).sum() })
        .sum();
    renderer_id <<
    UpdateThing {
        scene_id: scene_id,
        thing_id: 5502,
        thing: connecting_strokes_thing,
        instance: Instance::with_color([0.5, 0.5, 1.0]),
        is_decal: true,
    };
}

fn render_transfer_lanes(result_delta: &PlanResultDelta, renderer_id: ID, scene_id: usize) {
    let transfer_strokes_thing: Thing = result_delta.transfer_strokes
        .to_create
        .values()
        .map(|lane_stroke| band_to_thing(&Band::new(lane_stroke.path().clone(), 0.3), 0.1))
        .sum();
    renderer_id <<
    UpdateThing {
        scene_id: scene_id,
        thing_id: 5503,
        thing: transfer_strokes_thing,
        instance: Instance::with_color([1.0, 0.5, 0.0]),
        is_decal: true,
    };
}

fn render_selections(selections: &CDict<SelectableStrokeRef, (N, N)>,
                     plan_delta: &PlanDelta,
                     built_strokes: &BuiltStrokes,
                     renderer_id: ID,
                     scene_id: usize) {
    let addable_thing = selections.pairs()
        .filter_map(|(&selection_ref, &(start, end))| {
            let stroke = selection_ref.get_stroke(plan_delta, built_strokes);
            stroke.path().subsection(start, end).and_then(|subsection| {
                subsection.shift_orthogonally(5.0).map(|shifted_subsection| {
                    band_to_thing(&Band::new(shifted_subsection, 5.0), 0.1)
                })
            })
        })
        .sum();
    renderer_id <<
    UpdateThing {
        scene_id: scene_id,
        thing_id: 5497,
        thing: addable_thing,
        instance: Instance::with_color([0.8, 0.8, 1.0]),
        is_decal: true,
    };
    let selection_thing = selections.pairs()
        .filter_map(|(&selection_ref, &(start, end))| {
            let stroke = selection_ref.get_stroke(plan_delta, built_strokes);
            stroke.path()
                .subsection(start, end)
                .map(|subsection| band_to_thing(&Band::new(subsection, 5.0), 0.1))
        })
        .sum();
    renderer_id <<
    UpdateThing {
        scene_id: scene_id,
        thing_id: 5504,
        thing: selection_thing,
        instance: Instance::with_color([0.0, 0.0, 1.0]),
        is_decal: true,
    };
}

pub fn setup() {
    CurrentPlan::handle::<SetupInScene>();
    CurrentPlan::handle::<RenderToScene>();
}
<|endoftext|>