<commit_before>use clap::{App, AppSettings, Arg, SubCommand};
use std::path::Path;

pub fn app<'a, 'b>() -> App<'a, 'b> {
    App::new("homers")
        .version(crate_version!())
        .author("Jacob Helwig <jacob@technosorcery.net>")
        .about("Manage dotfiles in your home directory.")
        .setting(AppSettings::SubcommandRequiredElseHelp)
        .setting(AppSettings::VersionlessSubcommands)
        .arg(Arg::with_name("quiet")
                 .short("q")
                 .long("quiet")
                 .help("Suppress output"))
        .arg(Arg::with_name("verbose")
                 .short("v")
                 .long("verbose")
                 .multiple(true)
                 .overrides_with("quiet")
                 .help("Sets the level of verbosity"))
        .arg(Arg::with_name("pretend")
                 .short("p")
                 .long("pretend")
                 .help("Show what would be done, instead of making changes"))
        .arg(Arg::with_name("homers-dir")
                 .short("d")
                 .long("homers-dir")
                 .help("Path to where the repositories are stored (Default: ~/.homers)")
                 .takes_value(true)
                 .validator(|val: String| -> Result<(), String> {
                     if Path::new(&val).exists() {
                         Ok(())
                     } else {
                         Err(format!("Path does not exist for --homers-dir: {}", val))
                     }
                 }))
        .subcommand(command_cd())
        .subcommand(command_clone())
        .subcommand(command_commit())
        .subcommand(command_destroy())
        .subcommand(command_diff())
        .subcommand(command_edit())
        .subcommand(command_exec())
        .subcommand(command_exec_all())
        .subcommand(command_generate())
        .subcommand(command_link())
        .subcommand(command_list())
        .subcommand(command_path())
        .subcommand(command_pull())
        .subcommand(command_push())
        .subcommand(command_rc())
        .subcommand(command_status())
        .subcommand(command_track())
        .subcommand(command_unlink())
}

fn command_cd<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("cd")
        .about("Open a shell at the root of the given repository")
        .arg(Arg::with_name("repository")
                 .help("The repository to open a shell in")
                 .index(1)
                 .required(true))
}

fn command_clone<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("clone")
        .about("Clone <uri>")
        .arg(Arg::with_name("uri")
                 .help("URI of the repository to clone")
                 .index(1)
                 .required(true))
        .arg(Arg::with_name("name")
                 .help("The name to use for the repository locally")
                 .index(2)
                 .required(true))
}

fn command_commit<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("commit")
        .about("Comment changes in the given repository")
        .arg(Arg::with_name("repository")
                 .help("Name of the repository in which to commit changes")
                 .index(1)
                 .required(true))
        .arg(Arg::with_name("message")
                 .help("The commit message to use")
                 .index(2)
                 .required(true))
}

fn command_destroy<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("destroy")
        .about("Delete all symlinks and remove the repository")
        .arg(Arg::with_name("repository")
                 .help("Name of the repository to destroy")
                 .index(1)
                 .required(true))
}

fn command_diff<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("diff")
        .about("Show the \"git diff\" of uncommitted changes in the repository")
        .arg(Arg::with_name("repository")
                 .help("Name of the repository to \"git diff\"")
                 .index(1)
                 .required(true))
}

fn command_edit<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("edit")
        .about("Open $EDITOR in the root of the given repository")
        .arg(Arg::with_name("repository")
                 .help("The repository to open in $EDITOR")
                 .index(1)
                 .required(true))
}

fn command_exec<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("exec")
        .about("Execute the given command in the root of the specified repository")
        .arg(Arg::with_name("repository")
                 .help("Name of the repository in which to execute the command")
                 .index(1)
                 .required(true))
        .arg(Arg::with_name("command")
                 .help("The command to execute")
                 .index(2)
                 .required(true))
}

fn command_exec_all<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("exec_all")
        .about("Execute the given command in the root of the specified repository")
        .arg(Arg::with_name("command")
                 .help("The command to execute")
                 .index(1)
                 .required(true))
}

fn command_generate<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("generate")
        .about("Create a homers compatible git repository at the specified path")
        .arg(Arg::with_name("path")
                 .help("The path to initialize with a new repository")
                 .index(1)
                 .required(true))
}

fn command_link<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("link")
    //Runtime options:
    //-f, [--force]                    # Overwrite files that already exist
    //-s, [--skip], [--no-skip]        # Skip files that already exist
    .about("Symlink all dotfiles from the specified repository")
    .arg(Arg::with_name("repository")
         .help("The repository to create the symlinks for")
         .index(1)
         .required(true))
}

fn command_list<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("list").about("List all cloned repositories")
}

fn command_path<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("path")
        .about("Print the path to the specified repository")
        .arg(Arg::with_name("repository")
                 .help("The name of the repository to show the path to")
                 .index(1)
                 .required(true))
}

fn command_pull<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("pull")
        .about("Run \"git pull\" in the specified repository")
        .arg(Arg::with_name("repository")
                 .help("The name of the repository to run \"git pull\" in")
                 .index(1)
                 .required(true))
}

fn command_push<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("push")
        .about("Run \"git push\" in the specified repository")
        .arg(Arg::with_name("repository")
                 .help("The name of the repository to run \"git push\" in")
                 .index(1)
                 .required(true))
}

fn command_rc<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("rc")
        .about("Run the .homersrc from the specified repository")
        .arg(Arg::with_name("repository")
                 .help("The name of the repository to run the .homersrc from")
                 .index(1)
                 .required(true))
}

fn command_status<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("status")
        .about("Run \"git status\" in the specified repository")
        .arg(Arg::with_name("repository")
                 .help("The name of the repository to run \"git status\" in")
                 .index(1)
                 .required(true))
}

fn command_track<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("track")
        .about("Add a file to the specified repository")
        .arg(Arg::with_name("path")
                 .help("The path to add to the repository and make a symlink")
                 .index(1)
                 .required(true))
        .arg(Arg::with_name("repository")
                 .help("The name of the repository to add the path to")
                 .index(2)
                 .required(true))
}

fn command_unlink<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("unlink")
        .about("Remove all symlinks to the specified repository")
        .arg(Arg::with_name("repository")
                 .help("The name of the repository to remove the symlinks for")
                 .index(1)
                 .required(true))
}
<commit_msg>Specify value name for --homers-dir option<commit_after>use clap::{App, AppSettings, Arg, SubCommand};
use std::path::Path;

pub fn app<'a, 'b>() -> App<'a, 'b> {
    App::new("homers")
        .version(crate_version!())
        .author("Jacob Helwig <jacob@technosorcery.net>")
        .about("Manage dotfiles in your home directory.")
        .setting(AppSettings::SubcommandRequiredElseHelp)
        .setting(AppSettings::VersionlessSubcommands)
        .arg(Arg::with_name("quiet")
                 .short("q")
                 .long("quiet")
                 .help("Suppress output"))
        .arg(Arg::with_name("verbose")
                 .short("v")
                 .long("verbose")
                 .multiple(true)
                 .overrides_with("quiet")
                 .help("Sets the level of verbosity"))
        .arg(Arg::with_name("pretend")
                 .short("p")
                 .long("pretend")
                 .help("Show what would be done, instead of making changes"))
        .arg(Arg::with_name("homers-dir")
                 .short("d")
                 .long("homers-dir")
                 .help("Path to where the repositories are stored (Default: ~/.homers)")
                 .takes_value(true)
                 .value_name("dir")
                 .validator(|val: String| -> Result<(), String> {
                     if Path::new(&val).exists() {
                         Ok(())
                     } else {
                         Err(format!("Path does not exist for --homers-dir: {}", val))
                     }
                 }))
        .subcommand(command_cd())
        .subcommand(command_clone())
        .subcommand(command_commit())
        .subcommand(command_destroy())
        .subcommand(command_diff())
        .subcommand(command_edit())
        .subcommand(command_exec())
        .subcommand(command_exec_all())
        .subcommand(command_generate())
        .subcommand(command_link())
        .subcommand(command_list())
        .subcommand(command_path())
        .subcommand(command_pull())
        .subcommand(command_push())
        .subcommand(command_rc())
        .subcommand(command_status())
        .subcommand(command_track())
        .subcommand(command_unlink())
}

fn command_cd<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("cd")
        .about("Open a shell at the root of the given repository")
        .arg(Arg::with_name("repository")
                 .help("The repository to open a shell in")
                 .index(1)
                 .required(true))
}

fn command_clone<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("clone")
        .about("Clone <uri>")
        .arg(Arg::with_name("uri")
                 .help("URI of the repository to clone")
                 .index(1)
                 .required(true))
        .arg(Arg::with_name("name")
                 .help("The name to use for the repository locally")
                 .index(2)
                 .required(true))
}

fn command_commit<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("commit")
        .about("Comment changes in the given repository")
        .arg(Arg::with_name("repository")
                 .help("Name of the repository in which to commit changes")
                 .index(1)
                 .required(true))
        .arg(Arg::with_name("message")
                 .help("The commit message to use")
                 .index(2)
                 .required(true))
}

fn command_destroy<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("destroy")
        .about("Delete all symlinks and remove the repository")
        .arg(Arg::with_name("repository")
                 .help("Name of the repository to destroy")
                 .index(1)
                 .required(true))
}

fn command_diff<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("diff")
        .about("Show the \"git diff\" of uncommitted changes in the repository")
        .arg(Arg::with_name("repository")
                 .help("Name of the repository to \"git diff\"")
                 .index(1)
                 .required(true))
}

fn command_edit<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("edit")
        .about("Open $EDITOR in the root of the given repository")
        .arg(Arg::with_name("repository")
                 .help("The repository to open in $EDITOR")
                 .index(1)
                 .required(true))
}

fn command_exec<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("exec")
        .about("Execute the given command in the root of the specified repository")
        .arg(Arg::with_name("repository")
                 .help("Name of the repository in which to execute the command")
                 .index(1)
                 .required(true))
        .arg(Arg::with_name("command")
                 .help("The command to execute")
                 .index(2)
                 .required(true))
}

fn command_exec_all<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("exec_all")
        .about("Execute the given command in the root of the specified repository")
        .arg(Arg::with_name("command")
                 .help("The command to execute")
                 .index(1)
                 .required(true))
}

fn command_generate<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("generate")
        .about("Create a homers compatible git repository at the specified path")
        .arg(Arg::with_name("path")
                 .help("The path to initialize with a new repository")
                 .index(1)
                 .required(true))
}

fn command_link<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("link")
    //Runtime options:
    //-f, [--force]                    # Overwrite files that already exist
    //-s, [--skip], [--no-skip]        # Skip files that already exist
    .about("Symlink all dotfiles from the specified repository")
    .arg(Arg::with_name("repository")
         .help("The repository to create the symlinks for")
         .index(1)
         .required(true))
}

fn command_list<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("list").about("List all cloned repositories")
}

fn command_path<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("path")
        .about("Print the path to the specified repository")
        .arg(Arg::with_name("repository")
                 .help("The name of the repository to show the path to")
                 .index(1)
                 .required(true))
}

fn command_pull<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("pull")
        .about("Run \"git pull\" in the specified repository")
        .arg(Arg::with_name("repository")
                 .help("The name of the repository to run \"git pull\" in")
                 .index(1)
                 .required(true))
}

fn command_push<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("push")
        .about("Run \"git push\" in the specified repository")
        .arg(Arg::with_name("repository")
                 .help("The name of the repository to run \"git push\" in")
                 .index(1)
                 .required(true))
}

fn command_rc<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("rc")
        .about("Run the .homersrc from the specified repository")
        .arg(Arg::with_name("repository")
                 .help("The name of the repository to run the .homersrc from")
                 .index(1)
                 .required(true))
}

fn command_status<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("status")
        .about("Run \"git status\" in the specified repository")
        .arg(Arg::with_name("repository")
                 .help("The name of the repository to run \"git status\" in")
                 .index(1)
                 .required(true))
}

fn command_track<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("track")
        .about("Add a file to the specified repository")
        .arg(Arg::with_name("path")
                 .help("The path to add to the repository and make a symlink")
                 .index(1)
                 .required(true))
        .arg(Arg::with_name("repository")
                 .help("The name of the repository to add the path to")
                 .index(2)
                 .required(true))
}

fn command_unlink<'a, 'b>() -> App<'a, 'b> {
    SubCommand::with_name("unlink")
        .about("Remove all symlinks to the specified repository")
        .arg(Arg::with_name("repository")
                 .help("The name of the repository to remove the symlinks for")
                 .index(1)
                 .required(true))
}
<|endoftext|>


<commit_before>// Copyright 2016 Joe Wilm, The Alacritty Project 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.
extern crate log;
use clap::{Arg, App};
use index::{Line, Column};
use config::{Dimensions, Shell};
use std::path::{Path, PathBuf};
use std::borrow::Cow;

const DEFAULT_TITLE: &'static str = "Alacritty";

/// Options specified on the command line
pub struct Options {
    pub live_config_reload: Option<bool>,
    pub print_events: bool,
    pub ref_test: bool,
    pub dimensions: Option<Dimensions>,
    pub title: String,
    pub log_level: log::LogLevelFilter,
    pub command: Option<Shell<'static>>,
    pub working_dir: Option<PathBuf>,
    pub config: Option<PathBuf>,
}

impl Default for Options {
    fn default() -> Options {
        Options {
            live_config_reload: None,
            print_events: false,
            ref_test: false,
            dimensions: None,
            title: DEFAULT_TITLE.to_owned(),
            log_level: log::LogLevelFilter::Warn,
            command: None,
            working_dir: None,
            config: None,
        }
    }
}

impl Options {
    /// Build `Options` from command line arguments
    pub fn load() -> Options {
        let mut options = Options::default();

        let matches = App::new(crate_name!())
            .version(crate_version!())
            .author(crate_authors!("\n"))
            .about(crate_description!())
            .arg(Arg::with_name("ref-test")
                .long("ref-test")
                .help("Generates ref test"))
            .arg(Arg::with_name("live-config-reload")
                .long("live-config-reload")
                .help("Live configuration reload")
                .takes_value(true)
                .use_delimiter(false))
            .arg(Arg::with_name("print-events")
                .long("print-events"))
            .arg(Arg::with_name("dimensions")
                .long("dimensions")
                .short("d")
                .value_names(&["columns", "lines"])
                .help("Defines the window dimensions [default: 80x24]"))
            .arg(Arg::with_name("title")
                .long("title")
                .short("t")
                .default_value(DEFAULT_TITLE)
                .help("Defines the window title"))
            .arg(Arg::with_name("q")
                .short("q")
                .multiple(true)
                .conflicts_with("v")
                .help("Reduces the level of verbosity (the min level is -qq)"))
            .arg(Arg::with_name("v")
                .short("v")
                .multiple(true)
                .conflicts_with("q")
                .help("Increases the level of verbosity (the max level is -vvv)"))
            .arg(Arg::with_name("working-directory")
                 .long("working-directory")
                 .takes_value(true)
                 .help("Start the shell in the specified working directory"))
            .arg(Arg::with_name("config-file")
                 .long("config-file")
                 .takes_value(true)
                 .help("Specify alternative configuration file [default: $XDG_CONFIG_HOME/alacritty/alacritty.yml]"))
            .arg(Arg::with_name("command")
                .long("command")
                .short("e")
                .multiple(true)
                .takes_value(true)
                .min_values(1)
                .allow_hyphen_values(true)
                .help("Command and args to execute (must be last argument)"))
            .get_matches();

        if matches.is_present("ref-test") {
            options.ref_test = true;
        }

        if matches.is_present("print-events") {
            options.print_events = true;
        }

        if let Some(val) = matches.value_of("live-config-reload") {
            match val {
                "y" | "yes" => options.live_config_reload = Some(true),
                "n" | "no"  => options.live_config_reload = Some(false),
                _           => options.live_config_reload = None,
            }
        }

        if let Some(mut dimensions) = matches.values_of("dimensions") {
            let width = dimensions.next().map(|w| w.parse().map(|w| Column(w)));
            let height = dimensions.next().map(|h| h.parse().map(|h| Line(h)));
            if let (Some(Ok(width)), Some(Ok(height))) = (width, height) {
                options.dimensions = Some(Dimensions::new(width, height));
            }
        }

        if let Some(title) = matches.value_of("title") {
            options.title = title.to_owned();
        }

        match matches.occurrences_of("q") {
            0 => {},
            1 => options.log_level = log::LogLevelFilter::Error,
            2 | _ => options.log_level = log::LogLevelFilter::Off
        }

        match matches.occurrences_of("v") {
            0 => {},
            1 => options.log_level = log::LogLevelFilter::Info,
            2 => options.log_level = log::LogLevelFilter::Debug,
            3 | _ => options.log_level = log::LogLevelFilter::Trace
        }

        if let Some(dir) = matches.value_of("working-directory") {
            options.working_dir = Some(PathBuf::from(dir.to_string()));
        }

        if let Some(path) = matches.value_of("config-file") {
            options.config = Some(PathBuf::from(path.to_string()));
        }

        if let Some(mut args) = matches.values_of("command") {
            // The following unwrap is guaranteed to succeed.
            // If 'command' exists it must also have a first item since
            // Arg::min_values(1) is set.
            let command = String::from(args.next().unwrap());
            let args = args.map(String::from).collect();
            options.command = Some(Shell::new_with_args(command, args));
        }

        options
    }

    pub fn dimensions(&self) -> Option<Dimensions> {
        self.dimensions
    }

    pub fn command(&self) -> Option<&Shell> {
        self.command.as_ref()
    }

    pub fn config_path(&self) -> Option<Cow<Path>> {
        self.config.as_ref().map(|p| Cow::Borrowed(p.as_path()))
    }
}
<commit_msg>Change CLI live-config-reload options into flags<commit_after>// Copyright 2016 Joe Wilm, The Alacritty Project 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.
extern crate log;
use clap::{Arg, App};
use index::{Line, Column};
use config::{Dimensions, Shell};
use std::path::{Path, PathBuf};
use std::borrow::Cow;

const DEFAULT_TITLE: &'static str = "Alacritty";

/// Options specified on the command line
pub struct Options {
    pub live_config_reload: Option<bool>,
    pub print_events: bool,
    pub ref_test: bool,
    pub dimensions: Option<Dimensions>,
    pub title: String,
    pub log_level: log::LogLevelFilter,
    pub command: Option<Shell<'static>>,
    pub working_dir: Option<PathBuf>,
    pub config: Option<PathBuf>,
}

impl Default for Options {
    fn default() -> Options {
        Options {
            live_config_reload: None,
            print_events: false,
            ref_test: false,
            dimensions: None,
            title: DEFAULT_TITLE.to_owned(),
            log_level: log::LogLevelFilter::Warn,
            command: None,
            working_dir: None,
            config: None,
        }
    }
}

impl Options {
    /// Build `Options` from command line arguments
    pub fn load() -> Options {
        let mut options = Options::default();

        let matches = App::new(crate_name!())
            .version(crate_version!())
            .author(crate_authors!("\n"))
            .about(crate_description!())
            .arg(Arg::with_name("ref-test")
                .long("ref-test")
                .help("Generates ref test"))
            .arg(Arg::with_name("live-config-reload")
                .long("live-config-reload")
                .help("Enable automatic config reloading"))
            .arg(Arg::with_name("no-live-config-reload")
                 .long("no-live-config-reload")
                 .help("Disable automatic config reloading")
                 .conflicts_with("live-config-reload"))
            .arg(Arg::with_name("print-events")
                .long("print-events"))
            .arg(Arg::with_name("dimensions")
                .long("dimensions")
                .short("d")
                .value_names(&["columns", "lines"])
                .help("Defines the window dimensions [default: 80x24]"))
            .arg(Arg::with_name("title")
                .long("title")
                .short("t")
                .default_value(DEFAULT_TITLE)
                .help("Defines the window title"))
            .arg(Arg::with_name("q")
                .short("q")
                .multiple(true)
                .conflicts_with("v")
                .help("Reduces the level of verbosity (the min level is -qq)"))
            .arg(Arg::with_name("v")
                .short("v")
                .multiple(true)
                .conflicts_with("q")
                .help("Increases the level of verbosity (the max level is -vvv)"))
            .arg(Arg::with_name("working-directory")
                 .long("working-directory")
                 .takes_value(true)
                 .help("Start the shell in the specified working directory"))
            .arg(Arg::with_name("config-file")
                 .long("config-file")
                 .takes_value(true)
                 .help("Specify alternative configuration file [default: $XDG_CONFIG_HOME/alacritty/alacritty.yml]"))
            .arg(Arg::with_name("command")
                .long("command")
                .short("e")
                .multiple(true)
                .takes_value(true)
                .min_values(1)
                .allow_hyphen_values(true)
                .help("Command and args to execute (must be last argument)"))
            .get_matches();

        if matches.is_present("ref-test") {
            options.ref_test = true;
        }

        if matches.is_present("print-events") {
            options.print_events = true;
        }

        if matches.is_present("live-config-reload") {
            options.live_config_reload = Some(true);
        } else if matches.is_present("no-live-config-reload") {
            options.live_config_reload = Some(false);
        }

        if let Some(mut dimensions) = matches.values_of("dimensions") {
            let width = dimensions.next().map(|w| w.parse().map(|w| Column(w)));
            let height = dimensions.next().map(|h| h.parse().map(|h| Line(h)));
            if let (Some(Ok(width)), Some(Ok(height))) = (width, height) {
                options.dimensions = Some(Dimensions::new(width, height));
            }
        }

        if let Some(title) = matches.value_of("title") {
            options.title = title.to_owned();
        }

        match matches.occurrences_of("q") {
            0 => {},
            1 => options.log_level = log::LogLevelFilter::Error,
            2 | _ => options.log_level = log::LogLevelFilter::Off
        }

        match matches.occurrences_of("v") {
            0 => {},
            1 => options.log_level = log::LogLevelFilter::Info,
            2 => options.log_level = log::LogLevelFilter::Debug,
            3 | _ => options.log_level = log::LogLevelFilter::Trace
        }

        if let Some(dir) = matches.value_of("working-directory") {
            options.working_dir = Some(PathBuf::from(dir.to_string()));
        }

        if let Some(path) = matches.value_of("config-file") {
            options.config = Some(PathBuf::from(path.to_string()));
        }

        if let Some(mut args) = matches.values_of("command") {
            // The following unwrap is guaranteed to succeed.
            // If 'command' exists it must also have a first item since
            // Arg::min_values(1) is set.
            let command = String::from(args.next().unwrap());
            let args = args.map(String::from).collect();
            options.command = Some(Shell::new_with_args(command, args));
        }

        options
    }

    pub fn dimensions(&self) -> Option<Dimensions> {
        self.dimensions
    }

    pub fn command(&self) -> Option<&Shell> {
        self.command.as_ref()
    }

    pub fn config_path(&self) -> Option<Cow<Path>> {
        self.config.as_ref().map(|p| Cow::Borrowed(p.as_path()))
    }
}
<|endoftext|>


<commit_before>//! Definitions of integer that is known not to equal zero.

use crate::fmt;
use crate::ops::{BitOr, BitOrAssign, Div, Rem};
use crate::str::FromStr;

use super::from_str_radix;
use super::{IntErrorKind, ParseIntError};
use crate::intrinsics;

macro_rules! impl_nonzero_fmt {
    ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
        $(
            #[$stability]
            impl fmt::$Trait for $Ty {
                #[inline]
                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                    self.get().fmt(f)
                }
            }
        )+
    }
}

macro_rules! nonzero_integers {
    ( $( #[$stability: meta] $Ty: ident($Int: ty); )+ ) => {
        $(
            /// An integer that is known not to equal zero.
            ///
            /// This enables some memory layout optimization.
            #[doc = concat!("For example, `Option<", stringify!($Ty), ">` is the same size as `", stringify!($Int), "`:")]
            ///
            /// ```rust
            /// use std::mem::size_of;
            #[doc = concat!("assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", stringify!($Int), ">());")]
            /// ```
            #[$stability]
            #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
            #[repr(transparent)]
            #[rustc_layout_scalar_valid_range_start(1)]
            #[rustc_nonnull_optimization_guaranteed]
            pub struct $Ty($Int);

            impl $Ty {
                /// Creates a non-zero without checking the value.
                ///
                /// # Safety
                ///
                /// The value must not be zero.
                #[$stability]
                #[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
                #[inline]
                pub const unsafe fn new_unchecked(n: $Int) -> Self {
                    // SAFETY: this is guaranteed to be safe by the caller.
                    unsafe { Self(n) }
                }

                /// Creates a non-zero if the given value is not zero.
                #[$stability]
                #[rustc_const_stable(feature = "const_nonzero_int_methods", since = "1.47.0")]
                #[inline]
                pub const fn new(n: $Int) -> Option<Self> {
                    if n != 0 {
                        // SAFETY: we just checked that there's no `0`
                        Some(unsafe { Self(n) })
                    } else {
                        None
                    }
                }

                /// Returns the value as a primitive type.
                #[$stability]
                #[inline]
                #[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
                pub const fn get(self) -> $Int {
                    self.0
                }

            }

            #[stable(feature = "from_nonzero", since = "1.31.0")]
            impl From<$Ty> for $Int {
                #[doc = concat!("Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`")]
                #[inline]
                fn from(nonzero: $Ty) -> Self {
                    nonzero.0
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr for $Ty {
                type Output = Self;
                #[inline]
                fn bitor(self, rhs: Self) -> Self::Output {
                    // SAFETY: since `self` and `rhs` are both nonzero, the
                    // result of the bitwise-or will be nonzero.
                    unsafe { $Ty::new_unchecked(self.get() | rhs.get()) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr<$Int> for $Ty {
                type Output = Self;
                #[inline]
                fn bitor(self, rhs: $Int) -> Self::Output {
                    // SAFETY: since `self` is nonzero, the result of the
                    // bitwise-or will be nonzero regardless of the value of
                    // `rhs`.
                    unsafe { $Ty::new_unchecked(self.get() | rhs) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr<$Ty> for $Int {
                type Output = $Ty;
                #[inline]
                fn bitor(self, rhs: $Ty) -> Self::Output {
                    // SAFETY: since `rhs` is nonzero, the result of the
                    // bitwise-or will be nonzero regardless of the value of
                    // `self`.
                    unsafe { $Ty::new_unchecked(self | rhs.get()) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOrAssign for $Ty {
                #[inline]
                fn bitor_assign(&mut self, rhs: Self) {
                    *self = *self | rhs;
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOrAssign<$Int> for $Ty {
                #[inline]
                fn bitor_assign(&mut self, rhs: $Int) {
                    *self = *self | rhs;
                }
            }

            impl_nonzero_fmt! {
                #[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
            }
        )+
    }
}

nonzero_integers! {
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU8(u8);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU16(u16);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU32(u32);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU64(u64);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU128(u128);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroUsize(usize);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI8(i8);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI16(i16);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI32(i32);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI64(i64);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI128(i128);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize);
}

macro_rules! from_str_radix_nzint_impl {
    ($($t:ty)*) => {$(
        #[stable(feature = "nonzero_parse", since = "1.35.0")]
        impl FromStr for $t {
            type Err = ParseIntError;
            fn from_str(src: &str) -> Result<Self, Self::Err> {
                Self::new(from_str_radix(src, 10)?)
                    .ok_or(ParseIntError {
                        kind: IntErrorKind::Zero
                    })
            }
        }
    )*}
}

from_str_radix_nzint_impl! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize
NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize }

macro_rules! nonzero_leading_trailing_zeros {
    ( $( $Ty: ident($Uint: ty) , $LeadingTestExpr:expr ;)+ ) => {
        $(
            impl $Ty {
                /// Returns the number of leading zeros in the binary representation of `self`.
                ///
                /// On many architectures, this function can perform better than `leading_zeros()` on the underlying integer type, as special handling of zero can be avoided.
                ///
                /// # Examples
                ///
                /// Basic usage:
                ///
                /// ```
                #[doc = concat!("let n = std::num::", stringify!($Ty), "::new(", stringify!($LeadingTestExpr), ").unwrap();")]
                ///
                /// assert_eq!(n.leading_zeros(), 0);
                /// ```
                #[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
                #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
                #[inline]
                pub const fn leading_zeros(self) -> u32 {
                    // SAFETY: since `self` can not be zero it is safe to call ctlz_nonzero
                    unsafe { intrinsics::ctlz_nonzero(self.0 as $Uint) as u32 }
                }

                /// Returns the number of trailing zeros in the binary representation
                /// of `self`.
                ///
                /// On many architectures, this function can perform better than `trailing_zeros()` on the underlying integer type, as special handling of zero can be avoided.
                ///
                /// # Examples
                ///
                /// Basic usage:
                ///
                /// ```
                #[doc = concat!("let n = std::num::", stringify!($Ty), "::new(0b0101000).unwrap();")]
                ///
                /// assert_eq!(n.trailing_zeros(), 3);
                /// ```
                #[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
                #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
                #[inline]
                pub const fn trailing_zeros(self) -> u32 {
                    // SAFETY: since `self` can not be zero it is safe to call cttz_nonzero
                    unsafe { intrinsics::cttz_nonzero(self.0 as $Uint) as u32 }
                }

            }
        )+
    }
}

nonzero_leading_trailing_zeros! {
    NonZeroU8(u8), u8::MAX;
    NonZeroU16(u16), u16::MAX;
    NonZeroU32(u32), u32::MAX;
    NonZeroU64(u64), u64::MAX;
    NonZeroU128(u128), u128::MAX;
    NonZeroUsize(usize), usize::MAX;
    NonZeroI8(u8), -1i8;
    NonZeroI16(u16), -1i16;
    NonZeroI32(u32), -1i32;
    NonZeroI64(u64), -1i64;
    NonZeroI128(u128), -1i128;
    NonZeroIsize(usize), -1isize;
}

macro_rules! nonzero_integers_div {
    ( $( $Ty: ident($Int: ty); )+ ) => {
        $(
            #[stable(feature = "nonzero_div", since = "1.51.0")]
            impl Div<$Ty> for $Int {
                type Output = $Int;
                /// This operation rounds towards zero,
                /// truncating any fractional part of the exact result, and cannot panic.
                #[inline]
                fn div(self, other: $Ty) -> $Int {
                    // SAFETY: div by zero is checked because `other` is a nonzero,
                    // and MIN/-1 is checked because `self` is an unsigned int.
                    unsafe { crate::intrinsics::unchecked_div(self, other.get()) }
                }
            }

            #[stable(feature = "nonzero_div", since = "1.51.0")]
            impl Rem<$Ty> for $Int {
                type Output = $Int;
                /// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic.
                #[inline]
                fn rem(self, other: $Ty) -> $Int {
                    // SAFETY: rem by zero is checked because `other` is a nonzero,
                    // and MIN/-1 is checked because `self` is an unsigned int.
                    unsafe { crate::intrinsics::unchecked_rem(self, other.get()) }
                }
            }
        )+
    }
}

nonzero_integers_div! {
    NonZeroU8(u8);
    NonZeroU16(u16);
    NonZeroU32(u32);
    NonZeroU64(u64);
    NonZeroU128(u128);
    NonZeroUsize(usize);
}

macro_rules! nonzero_unsigned_is_power_of_two {
    ( $( $Ty: ident )+ ) => {
        $(
            impl $Ty {

                /// Returns `true` if and only if `self == (1 << k)` for some `k`.
                ///
                /// On many architectures, this function can perform better than `is_power_of_two()`
                /// on the underlying integer type, as special handling of zero can be avoided.
                ///
                /// # Examples
                ///
                /// Basic usage:
                ///
                /// ```
                /// #![feature(nonzero_is_power_of_two)]
                ///
                #[doc = concat!("let eight = std::num::", stringify!($Ty), "::new(8).unwrap();")]
                /// assert!(eight.is_power_of_two());
                #[doc = concat!("let ten = std::num::", stringify!($Ty), "::new(10).unwrap();")]
                /// assert!(!ten.is_power_of_two());
                /// ```
                #[unstable(feature = "nonzero_is_power_of_two", issue = "81106")]
                #[inline]
                pub const fn is_power_of_two(self) -> bool {
                    // LLVM 11 normalizes `unchecked_sub(x, 1) & x == 0` to the implementation seen here.
                    // On the basic x86-64 target, this saves 3 instructions for the zero check.
                    // On x86_64 with BMI1, being nonzero lets it codegen to `BLSR`, which saves an instruction
                    // compared to the `POPCNT` implementation on the underlying integer type.

                    intrinsics::ctpop(self.get()) < 2
                }

            }
        )+
    }
}

nonzero_unsigned_is_power_of_two! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize }
<commit_msg>fix 'const-stable since' for NonZeroU*::new_unchecked<commit_after>//! Definitions of integer that is known not to equal zero.

use crate::fmt;
use crate::ops::{BitOr, BitOrAssign, Div, Rem};
use crate::str::FromStr;

use super::from_str_radix;
use super::{IntErrorKind, ParseIntError};
use crate::intrinsics;

macro_rules! impl_nonzero_fmt {
    ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
        $(
            #[$stability]
            impl fmt::$Trait for $Ty {
                #[inline]
                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                    self.get().fmt(f)
                }
            }
        )+
    }
}

macro_rules! nonzero_integers {
    ( $( #[$stability: meta] #[$const_new_unchecked_stability: meta] $Ty: ident($Int: ty); )+ ) => {
        $(
            /// An integer that is known not to equal zero.
            ///
            /// This enables some memory layout optimization.
            #[doc = concat!("For example, `Option<", stringify!($Ty), ">` is the same size as `", stringify!($Int), "`:")]
            ///
            /// ```rust
            /// use std::mem::size_of;
            #[doc = concat!("assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", stringify!($Int), ">());")]
            /// ```
            #[$stability]
            #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
            #[repr(transparent)]
            #[rustc_layout_scalar_valid_range_start(1)]
            #[rustc_nonnull_optimization_guaranteed]
            pub struct $Ty($Int);

            impl $Ty {
                /// Creates a non-zero without checking the value.
                ///
                /// # Safety
                ///
                /// The value must not be zero.
                #[$stability]
                #[$const_new_unchecked_stability]
                #[inline]
                pub const unsafe fn new_unchecked(n: $Int) -> Self {
                    // SAFETY: this is guaranteed to be safe by the caller.
                    unsafe { Self(n) }
                }

                /// Creates a non-zero if the given value is not zero.
                #[$stability]
                #[rustc_const_stable(feature = "const_nonzero_int_methods", since = "1.47.0")]
                #[inline]
                pub const fn new(n: $Int) -> Option<Self> {
                    if n != 0 {
                        // SAFETY: we just checked that there's no `0`
                        Some(unsafe { Self(n) })
                    } else {
                        None
                    }
                }

                /// Returns the value as a primitive type.
                #[$stability]
                #[inline]
                #[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
                pub const fn get(self) -> $Int {
                    self.0
                }

            }

            #[stable(feature = "from_nonzero", since = "1.31.0")]
            impl From<$Ty> for $Int {
                #[doc = concat!("Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`")]
                #[inline]
                fn from(nonzero: $Ty) -> Self {
                    nonzero.0
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr for $Ty {
                type Output = Self;
                #[inline]
                fn bitor(self, rhs: Self) -> Self::Output {
                    // SAFETY: since `self` and `rhs` are both nonzero, the
                    // result of the bitwise-or will be nonzero.
                    unsafe { $Ty::new_unchecked(self.get() | rhs.get()) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr<$Int> for $Ty {
                type Output = Self;
                #[inline]
                fn bitor(self, rhs: $Int) -> Self::Output {
                    // SAFETY: since `self` is nonzero, the result of the
                    // bitwise-or will be nonzero regardless of the value of
                    // `rhs`.
                    unsafe { $Ty::new_unchecked(self.get() | rhs) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr<$Ty> for $Int {
                type Output = $Ty;
                #[inline]
                fn bitor(self, rhs: $Ty) -> Self::Output {
                    // SAFETY: since `rhs` is nonzero, the result of the
                    // bitwise-or will be nonzero regardless of the value of
                    // `self`.
                    unsafe { $Ty::new_unchecked(self | rhs.get()) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOrAssign for $Ty {
                #[inline]
                fn bitor_assign(&mut self, rhs: Self) {
                    *self = *self | rhs;
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOrAssign<$Int> for $Ty {
                #[inline]
                fn bitor_assign(&mut self, rhs: $Int) {
                    *self = *self | rhs;
                }
            }

            impl_nonzero_fmt! {
                #[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
            }
        )+
    }
}

nonzero_integers! {
    #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU8(u8);
    #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU16(u16);
    #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU32(u32);
    #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU64(u64);
    #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU128(u128);
    #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroUsize(usize);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI8(i8);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI16(i16);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI32(i32);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI64(i64);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI128(i128);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize);
}

macro_rules! from_str_radix_nzint_impl {
    ($($t:ty)*) => {$(
        #[stable(feature = "nonzero_parse", since = "1.35.0")]
        impl FromStr for $t {
            type Err = ParseIntError;
            fn from_str(src: &str) -> Result<Self, Self::Err> {
                Self::new(from_str_radix(src, 10)?)
                    .ok_or(ParseIntError {
                        kind: IntErrorKind::Zero
                    })
            }
        }
    )*}
}

from_str_radix_nzint_impl! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize
NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize }

macro_rules! nonzero_leading_trailing_zeros {
    ( $( $Ty: ident($Uint: ty) , $LeadingTestExpr:expr ;)+ ) => {
        $(
            impl $Ty {
                /// Returns the number of leading zeros in the binary representation of `self`.
                ///
                /// On many architectures, this function can perform better than `leading_zeros()` on the underlying integer type, as special handling of zero can be avoided.
                ///
                /// # Examples
                ///
                /// Basic usage:
                ///
                /// ```
                #[doc = concat!("let n = std::num::", stringify!($Ty), "::new(", stringify!($LeadingTestExpr), ").unwrap();")]
                ///
                /// assert_eq!(n.leading_zeros(), 0);
                /// ```
                #[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
                #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
                #[inline]
                pub const fn leading_zeros(self) -> u32 {
                    // SAFETY: since `self` can not be zero it is safe to call ctlz_nonzero
                    unsafe { intrinsics::ctlz_nonzero(self.0 as $Uint) as u32 }
                }

                /// Returns the number of trailing zeros in the binary representation
                /// of `self`.
                ///
                /// On many architectures, this function can perform better than `trailing_zeros()` on the underlying integer type, as special handling of zero can be avoided.
                ///
                /// # Examples
                ///
                /// Basic usage:
                ///
                /// ```
                #[doc = concat!("let n = std::num::", stringify!($Ty), "::new(0b0101000).unwrap();")]
                ///
                /// assert_eq!(n.trailing_zeros(), 3);
                /// ```
                #[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
                #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
                #[inline]
                pub const fn trailing_zeros(self) -> u32 {
                    // SAFETY: since `self` can not be zero it is safe to call cttz_nonzero
                    unsafe { intrinsics::cttz_nonzero(self.0 as $Uint) as u32 }
                }

            }
        )+
    }
}

nonzero_leading_trailing_zeros! {
    NonZeroU8(u8), u8::MAX;
    NonZeroU16(u16), u16::MAX;
    NonZeroU32(u32), u32::MAX;
    NonZeroU64(u64), u64::MAX;
    NonZeroU128(u128), u128::MAX;
    NonZeroUsize(usize), usize::MAX;
    NonZeroI8(u8), -1i8;
    NonZeroI16(u16), -1i16;
    NonZeroI32(u32), -1i32;
    NonZeroI64(u64), -1i64;
    NonZeroI128(u128), -1i128;
    NonZeroIsize(usize), -1isize;
}

macro_rules! nonzero_integers_div {
    ( $( $Ty: ident($Int: ty); )+ ) => {
        $(
            #[stable(feature = "nonzero_div", since = "1.51.0")]
            impl Div<$Ty> for $Int {
                type Output = $Int;
                /// This operation rounds towards zero,
                /// truncating any fractional part of the exact result, and cannot panic.
                #[inline]
                fn div(self, other: $Ty) -> $Int {
                    // SAFETY: div by zero is checked because `other` is a nonzero,
                    // and MIN/-1 is checked because `self` is an unsigned int.
                    unsafe { crate::intrinsics::unchecked_div(self, other.get()) }
                }
            }

            #[stable(feature = "nonzero_div", since = "1.51.0")]
            impl Rem<$Ty> for $Int {
                type Output = $Int;
                /// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic.
                #[inline]
                fn rem(self, other: $Ty) -> $Int {
                    // SAFETY: rem by zero is checked because `other` is a nonzero,
                    // and MIN/-1 is checked because `self` is an unsigned int.
                    unsafe { crate::intrinsics::unchecked_rem(self, other.get()) }
                }
            }
        )+
    }
}

nonzero_integers_div! {
    NonZeroU8(u8);
    NonZeroU16(u16);
    NonZeroU32(u32);
    NonZeroU64(u64);
    NonZeroU128(u128);
    NonZeroUsize(usize);
}

macro_rules! nonzero_unsigned_is_power_of_two {
    ( $( $Ty: ident )+ ) => {
        $(
            impl $Ty {

                /// Returns `true` if and only if `self == (1 << k)` for some `k`.
                ///
                /// On many architectures, this function can perform better than `is_power_of_two()`
                /// on the underlying integer type, as special handling of zero can be avoided.
                ///
                /// # Examples
                ///
                /// Basic usage:
                ///
                /// ```
                /// #![feature(nonzero_is_power_of_two)]
                ///
                #[doc = concat!("let eight = std::num::", stringify!($Ty), "::new(8).unwrap();")]
                /// assert!(eight.is_power_of_two());
                #[doc = concat!("let ten = std::num::", stringify!($Ty), "::new(10).unwrap();")]
                /// assert!(!ten.is_power_of_two());
                /// ```
                #[unstable(feature = "nonzero_is_power_of_two", issue = "81106")]
                #[inline]
                pub const fn is_power_of_two(self) -> bool {
                    // LLVM 11 normalizes `unchecked_sub(x, 1) & x == 0` to the implementation seen here.
                    // On the basic x86-64 target, this saves 3 instructions for the zero check.
                    // On x86_64 with BMI1, being nonzero lets it codegen to `BLSR`, which saves an instruction
                    // compared to the `POPCNT` implementation on the underlying integer type.

                    intrinsics::ctpop(self.get()) < 2
                }

            }
        )+
    }
}

nonzero_unsigned_is_power_of_two! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize }
<|endoftext|>


<commit_before>extern crate libc;
use std::str;
use std::ffi;

#[repr(C)]
struct memcached_st;

#[link(name = "memcached")]
extern {
    fn memcached(string: *const libc::c_char, string_length: libc::size_t) -> *const memcached_st;
    fn memcached_last_error_message(client: *const memcached_st) -> *const libc::c_char;
}

#[test]
fn test_memcaced() {
    unsafe {
        let s = "--SERVER=localhost";
        let string = ffi::CString::new(s).unwrap();
        let client = memcached(string.as_ptr(), 18);
        println!("{:?}", client);
    }
}

#[test]
fn test_memcached_last_error_message() {
    unsafe {
        let string = ffi::CString::new("foo").unwrap();
        let client = memcached(string.as_ptr(), 3);
        let error = memcached_last_error_message(client);
        let slice = ffi::CStr::from_ptr(error);
        println!("string returned: {}", str::from_utf8(slice.to_bytes()).unwrap());
    }
}
<commit_msg>add memcached_set<commit_after>extern crate libc;
use std::str;
use std::ffi;
use self::libc::{size_t, c_char, time_t, uint32_t};

#[repr(C)]
struct memcached_st;

#[repr(C)]
struct memcached_return_t;

#[link(name = "memcached")]
extern {
    fn memcached(string: *const c_char, string_length: size_t) -> *const memcached_st;
    fn memcached_last_error_message(client: *const memcached_st) -> *const c_char;
    fn memcached_set(client: *const memcached_st, key: *const c_char, key_length: size_t, value: *const c_char, value_length: size_t, expire: time_t, flag: uint32_t);
}

#[test]
fn test_memcaced() {
    unsafe {
        let s = "--SERVER=localhost";
        let string = ffi::CString::new(s).unwrap();
        let client = memcached(string.as_ptr(), 18);
        println!("{:?}", client);
        assert!(!client.is_null());
    }
}

#[test]
fn test_memcached_last_error_message() {
    unsafe {
        let string = ffi::CString::new("foo").unwrap();
        let client = memcached(string.as_ptr(), 3);
        let error = memcached_last_error_message(client);
        let slice = ffi::CStr::from_ptr(error);
        println!("string returned: {}", str::from_utf8(slice.to_bytes()).unwrap());
        assert!(!error.is_null());
    }
}

#[test]
fn test_memcached_set() {
    unsafe{
        let s = "--SERVER=localhost";
        let string = ffi::CString::new(s).unwrap();
        let client = memcached(string.as_ptr(), 18);
        assert!(!client.is_null());

        let key = ffi::CString::new("foo").unwrap().as_ptr();
        let key_length = 3;
        let value = ffi::CString::new("bar").unwrap().as_ptr();
        let value_length = 3;
        let r = memcached_set(client, key, key_length, value, value_length, 0, 0);
        println!("{:?}", r);

        let error = memcached_last_error_message(client);
        let slice = ffi::CStr::from_ptr(error);
        println!("string returned: {}", str::from_utf8(slice.to_bytes()).unwrap());
    }
}
<|endoftext|>


<commit_before>use x86_64::{
    VirtAddr,
    structures::gdt::{GlobalDescriptorTable, Descriptor, SegmentSelector},
    structures::tss::TaskStateSegment,
    instructions::segmentation::set_cs,
    instructions::tables::load_tss,
};

pub const DOUBLE_FAULT_IST_INDEX: u16 = 0;

lazy_static! {
    static ref TSS: TaskStateSegment = {
        let mut tss = TaskStateSegment::new();
        tss.interrupt_stack_table[DOUBLE_FAULT_IST_INDEX as usize] = {
            const STACK_SIZE: usize = 4096;
            static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];

            let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
            let stack_end = stack_start + STACK_SIZE;
            stack_end
        };
        tss
    };

    static ref GDT: (GlobalDescriptorTable, Selectors) = {
        let mut gdt = GlobalDescriptorTable::new();
        let code_selector = gdt.add_entry(Descriptor::kernel_code_segment());
        let tss_selector = gdt.add_entry(Descriptor::tss_segment(&TSS));
        (gdt, Selectors { code_selector, tss_selector })
    };
}

struct Selectors {
    code_selector: SegmentSelector,
    tss_selector: SegmentSelector,
}

pub fn init() {
    GDT.0.load();
    unsafe {
        set_cs(GDT.1.code_selector);
        load_tss(GDT.1.tss_selector);
    }
}
<commit_msg>Use same import structure as in post<commit_after>use x86_64::structures::gdt::{Descriptor, GlobalDescriptorTable, SegmentSelector};
use x86_64::structures::tss::TaskStateSegment;
use x86_64::VirtAddr;

pub const DOUBLE_FAULT_IST_INDEX: u16 = 0;

lazy_static! {
    static ref TSS: TaskStateSegment = {
        let mut tss = TaskStateSegment::new();
        tss.interrupt_stack_table[DOUBLE_FAULT_IST_INDEX as usize] = {
            const STACK_SIZE: usize = 4096;
            static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];

            let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
            let stack_end = stack_start + STACK_SIZE;
            stack_end
        };
        tss
    };

    static ref GDT: (GlobalDescriptorTable, Selectors) = {
        let mut gdt = GlobalDescriptorTable::new();
        let code_selector = gdt.add_entry(Descriptor::kernel_code_segment());
        let tss_selector = gdt.add_entry(Descriptor::tss_segment(&TSS));
        (gdt, Selectors { code_selector, tss_selector })
    };
}

struct Selectors {
    code_selector: SegmentSelector,
    tss_selector: SegmentSelector,
}

pub fn init() {
    use x86_64::instructions::segmentation::set_cs;
    use x86_64::instructions::tables::load_tss;

    GDT.0.load();
    unsafe {
        set_cs(GDT.1.code_selector);
        load_tss(GDT.1.tss_selector);
    }
}
<|endoftext|>


<commit_before>use std::io::{Read, Result, Write};

/// An adapter for readers whose inputs
/// are written to a "tee"'d writer
pub struct TeeReader<R: Read, W: Write> {
    reader: R,
    writer: W,
}

impl<R: Read, W: Write> TeeReader<R, W> {
    /// Returns a TeeReader which can be used as Read whose
    /// reads delegate bytes read to the provided reader and write to the provided
    /// writer. The write operation must complete before the read completes.
    ///
    /// Errors reported by the write operation will be interpreted as errors for the read
    pub fn new(reader: R, writer: W) -> TeeReader<R, W> {
        TeeReader {
            reader: reader,
            writer: writer,
        }
    }
}

impl<R: Read, W: Write> Read for TeeReader<R, W> {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        let n = try!(self.reader.read(buf));
        try!(self.writer.write_all(&buf[..n]));
        Ok(n)
    }
}

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

    #[test]
    fn tee() {
        let mut reader = "It's over 9000!".as_bytes();
        let mut teeout = Vec::new();
        let mut stdout = Vec::new();
        {
            let mut tee = TeeReader::new(&mut reader, &mut teeout);
            let _ = tee.read_to_end(&mut stdout);
        }
        assert_eq!(teeout, stdout);
    }
}
<commit_msg>Add into_inner() to retrieve wrapped Read and Write<commit_after>use std::io::{Read, Result, Write};

/// An adapter for readers whose inputs
/// are written to a "tee"'d writer
pub struct TeeReader<R: Read, W: Write> {
    reader: R,
    writer: W,
}

impl<R: Read, W: Write> TeeReader<R, W> {
    /// Returns a TeeReader which can be used as Read whose
    /// reads delegate bytes read to the provided reader and write to the provided
    /// writer. The write operation must complete before the read completes.
    ///
    /// Errors reported by the write operation will be interpreted as errors for the read
    pub fn new(reader: R, writer: W) -> TeeReader<R, W> {
        TeeReader {
            reader: reader,
            writer: writer,
        }
    }

    /// Consumes the `TeeReader`, returning the wrapped reader and writer.
    pub fn into_inner(self) -> (R, W) {
        (self.reader, self.writer)
    }
}

impl<R: Read, W: Write> Read for TeeReader<R, W> {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        let n = try!(self.reader.read(buf));
        try!(self.writer.write_all(&buf[..n]));
        Ok(n)
    }
}

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

    #[test]
    fn tee() {
        let mut reader = "It's over 9000!".as_bytes();
        let mut teeout = Vec::new();
        let mut stdout = Vec::new();
        {
            let mut tee = TeeReader::new(&mut reader, &mut teeout);
            let _ = tee.read_to_end(&mut stdout);
        }
        assert_eq!(teeout, stdout);
    }
}
<|endoftext|>


<commit_before>//! Fancy pure Rust crypto and hash library.
//!
//! The main reason this exists is so I can learn about cryptography.
//!
//! If you're asking "We have rust-crypto, why the hell do we need a new
//! library?"), `rust-crypto` was (at the time of Octavo's creation) big pile of… mess. To be honest
//! I doesn't hate `rust-crypto` but I wanted something that will be organized in fancy way, not
//! another OpenSSL (but written in Rust, so probably less buggy).
//!
//! Anther reason is that I want Octavo to became highly configurable via Cargo features. Each
//! cipher, hash family, MAC, etc. should be behind a feature.
//!
//! Oh… one more thing. I want to create C wrapper for Octavo (maybe even OpenSSL compatible), so
//! that you could use this beautiful peace of crap.
//!
//! Happy coding!
//!
//! ## Examples
//!
//!

#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![cfg_attr(not(feature = "lints"), allow(unknown_lints))]

#![deny(unreachable_code, while_true, unused_mut, unused_variables, unused_imports)]
#![cfg_attr(not(test), deny(trivial_casts))]
#![warn(missing_docs)]

#[cfg(test)] extern crate quickcheck;
#[cfg(test)] extern crate openssl;

extern crate byteorder;
#[cfg(feature = "num")] extern crate num;
#[cfg(feature = "rand")] extern crate rand;

pub mod crypto;
pub mod digest;
pub mod mac;
pub mod kdf;

mod utils;
<commit_msg>feat(): Add Redox support<commit_after>//! Fancy pure Rust crypto and hash library.
//!
//! The main reason this exists is so I can learn about cryptography.
//!
//! If you're asking "We have rust-crypto, why the hell do we need a new
//! library?"), `rust-crypto` was (at the time of Octavo's creation) big pile of… mess. To be honest
//! I doesn't hate `rust-crypto` but I wanted something that will be organized in fancy way, not
//! another OpenSSL (but written in Rust, so probably less buggy).
//!
//! Anther reason is that I want Octavo to became highly configurable via Cargo features. Each
//! cipher, hash family, MAC, etc. should be behind a feature.
//!
//! Oh… one more thing. I want to create C wrapper for Octavo (maybe even OpenSSL compatible), so
//! that you could use this beautiful peace of crap.
//!
//! Happy coding!
//!
//! ## Examples
//!
//!

#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![cfg_attr(not(feature = "lints"), allow(unknown_lints))]

#![deny(unreachable_code, while_true, unused_mut, unused_variables, unused_imports)]
#![cfg_attr(not(test), deny(trivial_casts))]
#![warn(missing_docs)]

// Support Redox (http://www.redox-os.org/). This is temporary fix until `redox` crate will be
// renamed as `std`.
#![cfg_attr(feature = "no-std", no_std)]
#[cfg(target_os = "redox")] extern crate redox as std;

#[cfg(test)] extern crate quickcheck;
#[cfg(test)] extern crate openssl;

extern crate byteorder;
#[cfg(feature = "num")] extern crate num;
#[cfg(feature = "rand")] extern crate rand;

pub mod crypto;
pub mod digest;
pub mod mac;
pub mod kdf;

mod utils;
<|endoftext|>


<commit_before>#![feature(question_mark)]

#[macro_use]
extern crate hyper;
extern crate url;
extern crate xml;

pub mod webdav;
pub mod error;

pub use error::Error;
<commit_msg>drop question mark feature for stable compatibility<commit_after>#[macro_use]
extern crate hyper;
extern crate url;
extern crate xml;

pub mod webdav;
pub mod error;

pub use error::Error;
<|endoftext|>


<commit_before>extern crate regex;

extern crate rusoto_core;
extern crate rusoto_sts;
extern crate rusoto_dynamodb;

pub mod SessionHandler {
    use std::fs::{File, OpenOptions};
    use std::io::{BufReader, Error};
    use std::io;
    use std::io::prelude::*;
    use std::io::{stdin, stdout};
    use std::env;
    use rusoto_core::{DefaultCredentialsProvider, ProfileProvider,
        ProvideAwsCredentials, Region, default_tls_client};
    use rusoto_sts::{Sts, StsClient, GetSessionTokenRequest, GetSessionTokenResponse, GetSessionTokenError, Credentials};
    use rusoto_dynamodb::{DynamoDb, DynamoDbClient, ListTablesInput};
    use regex::Regex;
    use std::collections::HashMap;

    pub struct SessionHandler {
        AWSConfig: AWSConfig,
    }

    struct AWSConfig {
        profiles: HashMap<String, AWSProfile>,
    }

    #[derive(Debug)]
    struct AWSProfile {
        source_profile: Option<String>,
        region: Option<String>,
        output: Option<String>,
        role_arn: Option<String>,
        mfa_serial: Option<String>,
        ot_session_name: Option<String>,
        ot_expiration: Option<String>,
        ot_source_profile: Option<String>,
        ot_role_arn: Option<String>,
    }

    impl AWSConfig {
        fn get_profile(&self, name: &str) -> &AWSProfile {
            &self.profiles[name]
        }
    }

    impl SessionHandler {
        pub fn load_config(&mut self) {
            let aws_config_file = read_aws_config_file();
            let profiles = split_config_file(aws_config_file);

            // Create an instance of the AWSConfig struct
            let mut aws_config = AWSConfig {
                profiles: HashMap::new()
            };

            // Iterate over profile chunks
            for profile in profiles {
                // Create a vector of string that holds each line
                let split = profile.split("\n");
                let lines: Vec<String> = split.map(|s| s.to_string()).collect();

                // Get the profile name from the first line
                let profile_line = lines[0].to_owned();

                // Lets ignore the default for now
                if profile_line == "[default]" {
                    continue;
                }

                let split2 = profile_line.split(" ");
                let mut words: Vec<String> = split2.map(|s| s.to_string()).collect();
                let mut profile_name = String::new();
                if words.len() > 1 {
                    words[1].pop();
                    profile_name = words[1].trim_right().to_owned();
                }

                let mut aws_profile = AWSProfile{
                    source_profile: None,
                    region: None,
                    output: None,
                    role_arn: None,
                    mfa_serial: None,
                    ot_expiration: None,
                    ot_session_name: None,
                    ot_source_profile: None,
                    ot_role_arn: None,
                };

                for i in 1..lines.len() {
                    let split = lines[i].split(" = ");
                    let config: Vec<String> = split.map(|s| s.to_string()).collect();
                    let key = &config[0];
                    let value = config[1].to_owned();
                    match key.as_ref() {
                        "mfa_serial" => aws_profile.mfa_serial = Some(value),
                        "output" => aws_profile.output = Some(value),
                        "region" => aws_profile.region = Some(value),
                        "role_arn" => aws_profile.role_arn = Some(value),
                        "source_profile" => aws_profile.source_profile = Some(value),
                        "ot_session_name" => aws_profile.ot_session_name = Some(value),
                        "ot_expiration" => aws_profile.ot_expiration = Some(value),
                        "ot_source_profile" => aws_profile.ot_source_profile = Some(value),
                        "ot_role_arn" => aws_profile.ot_role_arn = Some(value),
                        _ => (),
                    }
                }

                if profile_name != "" {
                    aws_config.profiles.insert(profile_name.clone(), aws_profile);
                }
            }

            self.AWSConfig = aws_config;
        }

        pub fn create(&self, profile_name: &str) {
            println!("Creating session for profile \"{}\"...", profile_name);
            //let aws_profile = &self.AWSConfig.profiles[profile_name];
            let aws_profile = &self.AWSConfig.get_profile(profile_name);

            let mut provider = ProfileProvider::new().unwrap();
            provider.set_profile(profile_name);
            // let region = &aws_profile.region;
            // match region {
            //     &Some(ref region) => region,
            //     &None => panic!("You must specify a region for profile {}", profile_name)
            // };
            // println!("Region: {:?}", region.as_ref().unwrap());
            let client = StsClient::new(default_tls_client().unwrap(), provider, Region::EuWest1);

            let mfa_serial = &aws_profile.mfa_serial;
            if mfa_serial.is_some() {
                print!("Enter AWS MFA code for profile [{}]: ", profile_name);
                stdout().flush();
                let mut token_code = String::new();
                stdin().read_line(&mut token_code)
                    .ok()
                    .expect("Couldn't read line");
                token_code.pop(); // Remove newline

                let request = GetSessionTokenRequest {
                    duration_seconds: None,
                    serial_number: Some(mfa_serial.as_ref().unwrap().to_owned()),
                    token_code: Some(token_code),
                };
                let response = client.get_session_token(&request);
                match response {
                    Ok(response) => {
                        let credentials = response.credentials.unwrap();
                        println!("{:?}", credentials);
                        match save_credentials(credentials) {
                            Ok(_) => println!("Saved to credentials file."),
                            Err(err) => println!("Error saving credentials to file: {:?}", err)
                        };
                    },
                    Err(err) => panic!("Failed to get session token for profile {}: {:?}", profile_name, err),
                };
            }
        }

        pub fn show(&self, profile_name: &str) {
            println!("Showing config for profile {}...", profile_name);
            println!("{:?}", self.AWSConfig.profiles[profile_name]);
        }
    }

    pub fn create(profile_name: &str) {
        println!("Creating session for profile \"{}\"...", profile_name);

    }

    pub fn new() -> SessionHandler {
            SessionHandler {
                AWSConfig: AWSConfig {
                    profiles: HashMap::new()
                }
            }
    }

    pub fn refresh() {
        println!("Refreshing sessions...");
    }

    pub fn clean() {
        println!("Cleaning sessions...");
    }

    fn read_aws_config_file() -> String {
        let path = match env::home_dir() {
            Some(path) => path,
            None => panic!("Could not retrieve user's home directory."),
        };
        let config_file_path = format!("{}/.aws/config", path.display());

        let f = File::open(config_file_path).expect("Could not find AWS config file.");
        let mut buf_reader = BufReader::new(f);
        let mut contents = String::new();
        buf_reader.read_to_string(&mut contents).expect("Found config file but could not read it.");

        contents
    }

    fn split_config_file(aws_config: String) -> Vec<String> {
        let split = aws_config.split("\n\n");
        let mut profiles: Vec<String> = split.map(|s| s.to_string()).collect();;

        profiles.pop(); // Remove last element as it is always empty
        profiles
    }

    fn save_credentials(credentials: Credentials) -> Result<(), io::Error> {
        let mut aws_credentials_path = env::home_dir().unwrap().display().to_string();
        aws_credentials_path.push_str("/.aws/credentials");
        let mut file = OpenOptions::new()
                       .write(true)
                       .append(true)
                       .open(aws_credentials_path)
                       .unwrap();

        try!(file.write_all("Hi from Bluenine!\n".as_bytes()));
        Ok(())
    }
}
<commit_msg>Update save credentials function<commit_after>extern crate regex;

extern crate rusoto_core;
extern crate rusoto_sts;
extern crate rusoto_dynamodb;

pub mod SessionHandler {
    use std::fs::{File, OpenOptions};
    use std::io::{BufReader, Error};
    use std::io;
    use std::io::prelude::*;
    use std::io::{stdin, stdout};
    use std::env;
    use rusoto_core::{DefaultCredentialsProvider, ProfileProvider,
        ProvideAwsCredentials, Region, default_tls_client};
    use rusoto_sts::{Sts, StsClient, GetSessionTokenRequest, GetSessionTokenResponse, GetSessionTokenError, Credentials};
    use rusoto_dynamodb::{DynamoDb, DynamoDbClient, ListTablesInput};
    use regex::Regex;
    use std::collections::HashMap;

    pub struct SessionHandler {
        AWSConfig: AWSConfig,
    }

    struct AWSConfig {
        profiles: HashMap<String, AWSProfile>,
    }

    #[derive(Debug)]
    struct AWSProfile {
        source_profile: Option<String>,
        region: Option<String>,
        output: Option<String>,
        role_arn: Option<String>,
        mfa_serial: Option<String>,
        ot_session_name: Option<String>,
        ot_expiration: Option<String>,
        ot_source_profile: Option<String>,
        ot_role_arn: Option<String>,
    }

    impl AWSConfig {
        fn get_profile(&self, name: &str) -> &AWSProfile {
            &self.profiles[name]
        }
    }

    impl SessionHandler {
        pub fn load_config(&mut self) {
            let aws_config_file = read_aws_config_file();
            let profiles = split_config_file(aws_config_file);

            // Create an instance of the AWSConfig struct
            let mut aws_config = AWSConfig {
                profiles: HashMap::new()
            };

            // Iterate over profile chunks
            for profile in profiles {
                // Create a vector of string that holds each line
                let split = profile.split("\n");
                let lines: Vec<String> = split.map(|s| s.to_string()).collect();

                // Get the profile name from the first line
                let profile_line = lines[0].to_owned();

                // Lets ignore the default for now
                if profile_line == "[default]" {
                    continue;
                }

                let split2 = profile_line.split(" ");
                let mut words: Vec<String> = split2.map(|s| s.to_string()).collect();
                let mut profile_name = String::new();
                if words.len() > 1 {
                    words[1].pop();
                    profile_name = words[1].trim_right().to_owned();
                }

                let mut aws_profile = AWSProfile{
                    source_profile: None,
                    region: None,
                    output: None,
                    role_arn: None,
                    mfa_serial: None,
                    ot_expiration: None,
                    ot_session_name: None,
                    ot_source_profile: None,
                    ot_role_arn: None,
                };

                for i in 1..lines.len() {
                    let split = lines[i].split(" = ");
                    let config: Vec<String> = split.map(|s| s.to_string()).collect();
                    let key = &config[0];
                    let value = config[1].to_owned();
                    match key.as_ref() {
                        "mfa_serial" => aws_profile.mfa_serial = Some(value),
                        "output" => aws_profile.output = Some(value),
                        "region" => aws_profile.region = Some(value),
                        "role_arn" => aws_profile.role_arn = Some(value),
                        "source_profile" => aws_profile.source_profile = Some(value),
                        "ot_session_name" => aws_profile.ot_session_name = Some(value),
                        "ot_expiration" => aws_profile.ot_expiration = Some(value),
                        "ot_source_profile" => aws_profile.ot_source_profile = Some(value),
                        "ot_role_arn" => aws_profile.ot_role_arn = Some(value),
                        _ => (),
                    }
                }

                if profile_name != "" {
                    aws_config.profiles.insert(profile_name.clone(), aws_profile);
                }
            }

            self.AWSConfig = aws_config;
        }

        pub fn create(&self, profile_name: &str) {
            println!("Creating session for profile \"{}\"...", profile_name);
            //let aws_profile = &self.AWSConfig.profiles[profile_name];
            let aws_profile = &self.AWSConfig.get_profile(profile_name);

            let mut provider = ProfileProvider::new().unwrap();
            provider.set_profile(profile_name);
            // let region = &aws_profile.region;
            // match region {
            //     &Some(ref region) => region,
            //     &None => panic!("You must specify a region for profile {}", profile_name)
            // };
            // println!("Region: {:?}", region.as_ref().unwrap());
            let client = StsClient::new(default_tls_client().unwrap(), provider, Region::EuWest1);

            let mfa_serial = &aws_profile.mfa_serial;
            if mfa_serial.is_some() {
                print!("Enter AWS MFA code for profile [{}]: ", profile_name);
                stdout().flush();
                let mut token_code = String::new();
                stdin().read_line(&mut token_code)
                    .ok()
                    .expect("Couldn't read line");
                token_code.pop(); // Remove newline

                let request = GetSessionTokenRequest {
                    duration_seconds: None,
                    serial_number: Some(mfa_serial.as_ref().unwrap().to_owned()),
                    token_code: Some(token_code),
                };
                let response = client.get_session_token(&request);
                match response {
                    Ok(response) => {
                        let credentials = response.credentials.unwrap();
                        match save_credentials(profile_name, credentials) {
                            Ok(_) => println!("Saved to credentials file."),
                            Err(err) => println!("Error saving credentials to file: {:?}", err)
                        };
                    },
                    Err(err) => panic!("Failed to get session token for profile {}: {:?}", profile_name, err),
                };
            }
        }

        pub fn show(&self, profile_name: &str) {
            println!("Showing config for profile {}...", profile_name);
            println!("{:?}", self.AWSConfig.profiles[profile_name]);
        }
    }

    pub fn create(profile_name: &str) {
        println!("Creating session for profile \"{}\"...", profile_name);

    }

    pub fn new() -> SessionHandler {
            SessionHandler {
                AWSConfig: AWSConfig {
                    profiles: HashMap::new()
                }
            }
    }

    pub fn refresh() {
        println!("Refreshing sessions...");
    }

    pub fn clean() {
        println!("Cleaning sessions...");
    }

    fn read_aws_config_file() -> String {
        let path = match env::home_dir() {
            Some(path) => path,
            None => panic!("Could not retrieve user's home directory."),
        };
        let config_file_path = format!("{}/.aws/config", path.display());

        let f = File::open(config_file_path).expect("Could not find AWS config file.");
        let mut buf_reader = BufReader::new(f);
        let mut contents = String::new();
        buf_reader.read_to_string(&mut contents).expect("Found config file but could not read it.");

        contents
    }

    fn split_config_file(aws_config: String) -> Vec<String> {
        let split = aws_config.split("\n\n");
        let mut profiles: Vec<String> = split.map(|s| s.to_string()).collect();;

        profiles.pop(); // Remove last element as it is always empty
        profiles
    }

    fn save_credentials(profile_name: &str, credentials: Credentials) -> Result<(), io::Error> {
        let mut aws_credentials_path = env::home_dir().unwrap().display().to_string();
        aws_credentials_path.push_str("/.aws/credentials");
        let mut file = OpenOptions::new()
                       .write(true)
                       .append(true)
                       .open(aws_credentials_path)
                       .unwrap();

        let mut creds = String::new();
        creds.push_str(&format!("[{}-session]\n", profile_name));
        creds.push_str(&format!("access_key_id = {}\n", credentials.access_key_id));
        creds.push_str(&format!("expiration = {}\n", credentials.expiration));
        creds.push_str(&format!("secret_access_key = {}\n", credentials.secret_access_key));
        creds.push_str(&format!("session_token = {}\n", credentials.session_token));
        try!(file.write_all(creds.as_bytes()));
        Ok(())
    }
}
<|endoftext|>


<commit_before>pub mod base62 {
    const BASE: i32 = 62;
    const ALPHABET: [char; BASE as usize] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
                                               'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b',
                                               'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
                                               'v', 'w', 'x', 'y', 'z'];

    pub fn encode(mut num: i32) -> String {
        let mut result: String = "".to_string();

        while num > 0 {
            let char_holder = ALPHABET.get((num % BASE) as usize).unwrap().to_string();
            result = char_holder + &result;
            num /= BASE
        }

        return result.to_string();
    }

    pub fn decode(string: &str) -> i32 {
        let mut result = 0;

        for (i, c) in string.chars().rev().enumerate() {
            let num = BASE.pow(i as u32);
            result += ALPHABET.iter().position(|x| *x == c).unwrap() as i32 * num;
        }

        return result;
    }
}

#[test]
fn it_encodes() {
    assert_eq!(base62::encode(1337), "LZ");
}

#[test]
fn it_decodes() {
    assert_eq!(base62::decode("LZ"), 1337);
}
<commit_msg>minor improvements<commit_after>pub mod base62 {
    const BASE: u64 = 62;
    const ALPHABET: [char; BASE as usize] =
        ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
        'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b',
        'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
        'v', 'w', 'x', 'y', 'z'];

    pub fn encode(mut num: u64) -> String {
        if num == 0 { return "0".to_string() }
        let mut result  = String::new();

        while num > 0 {
            let char_holder = ALPHABET[(num % BASE) as usize].to_string();
            result = char_holder + &result;
            num /= BASE
        }

        return result.to_string();
    }

    pub fn decode(string: &str) -> u64 {
        let mut result = 0;

        for (i, c) in string.chars().rev().enumerate() {
            let num = BASE.pow(i as u32);
            result += ALPHABET.iter().position(|x| *x == c).unwrap() as u64 * num;
        }

        return result;
    }
}

#[test]
fn it_encodes() {
    assert_eq!(base62::encode(1337), "LZ");
}

#[test]
fn it_decodes() {
    assert_eq!(base62::decode("LZ"), 1337);
}
<|endoftext|>