<commit_before>use std::fs::File;
use std::io::Read;
use std::io::Write;
use std::io::{Error, ErrorKind};
use std::path::{Path, PathBuf};
use std::string::String;

const MAX_BRIGHTNESS_BASENAME: &str = "max_brightness";
const BRIGHTNESS_BASENAME: &str = "brightness";

// Defines the apparent path to the directory containing both
// the brightness and the max_brightness files.
const BRIGHTNESS_CONTAINING_DIR: &str = "/sys/class/backlight/intel_backlight/";

// Reads the file named by |path| and returns the integral contents.
fn sysfs_file_to_int(path: &PathBuf) -> std::result::Result<i32, Error> {
    let mut file = File::open(path)?;
    let mut raw_contents = String::new();
    file.read_to_string(&mut raw_contents)?;

    let contents = raw_contents.trim();

    match contents.parse::<i32>() {
        Ok(value) => Ok(value),
        Err(why) => Err(Error::new(
            ErrorKind::InvalidInput,
            format!("parse failure ({:#?}): {}", path, why),
        )),
    }
}

// Stringifies and writes |value| into file named by |path|.
fn write_int(path: &PathBuf, value: i32) -> std::io::Result<()> {
    let mut file = File::create(&path)?;
    file.write_all(&value.to_string().as_bytes())?;
    file.flush()
}

// Reads the current and max brightness; returns the new target
// brightness.
fn target_brightness(current: i32, max: i32) -> Result<i32, std::io::Error> {
    let args: Vec<String> = std::env::args().collect();
    let delta_as_string = &args[1];
    let delta = delta_as_string.parse::<i32>();

    if !delta.is_ok() {
        return Err(Error::new(
            ErrorKind::InvalidInput,
            format!("bad arg: {}", delta_as_string),
        ));
    }

    let tentative = current + delta.unwrap();
    if tentative >= max {
        return Ok(max);
    } else if tentative < 0 {
        // For kicks, set the brightness all the way up if caller is
        // trying to take it below 0.
        if current == 0 {
            return Ok(max);
        }
        return Ok(0);
    }
    Ok(tentative)
}

fn main() -> Result<(), std::io::Error> {
    let base_dir = Path::new(BRIGHTNESS_CONTAINING_DIR);
    let brightness_path: PathBuf = base_dir.join(BRIGHTNESS_BASENAME);

    let current = sysfs_file_to_int(&brightness_path)?;
    let max = sysfs_file_to_int(&base_dir.join(MAX_BRIGHTNESS_BASENAME))?;

    let new = target_brightness(current, max)?;
    write_int(&brightness_path, new)
}
<commit_msg>avocado-attenborough: improve error handling<commit_after>use std::fs::File;
use std::io::Read;
use std::io::Write;
use std::io::{Error, ErrorKind};
use std::path::{Path, PathBuf};
use std::string::String;

const MAX_BRIGHTNESS_BASENAME: &str = "max_brightness";
const BRIGHTNESS_BASENAME: &str = "brightness";

// Defines the apparent path to the directory containing both
// the brightness and the max_brightness files.
const BRIGHTNESS_CONTAINING_DIR: &str = "/sys/class/backlight/intel_backlight/";

// Reads the file named by |path| and returns the integral contents.
fn sysfs_file_to_int(path: &PathBuf) -> std::result::Result<i32, Error> {
    let mut file = File::open(path)?;
    let mut raw_contents = String::new();
    file.read_to_string(&mut raw_contents)?;

    let contents = raw_contents.trim();

    match contents.parse::<i32>() {
        Ok(value) => Ok(value),
        Err(why) => Err(Error::new(
            ErrorKind::InvalidInput,
            format!("parse failure ({:#?}): {}", path, why),
        )),
    }
}

// Stringifies and writes |value| into file named by |path|.
fn write_int(path: &PathBuf, value: i32) -> std::io::Result<()> {
    let mut file = File::create(&path)?;
    file.write_all(&value.to_string().as_bytes())?;
    file.flush()
}

// Reads the current and max brightness; returns the new target
// brightness.
fn target_brightness(current: i32, max: i32) -> Result<i32, std::io::Error> {
    let args: Vec<String> = std::env::args().collect();
    if args.len() < 2 {
        return Err(Error::new(ErrorKind::InvalidInput, "missing delta arg"));
    }
    // We expect a integral value, like ``-312'' or ``520.''
    let delta_as_string = &args[1];
    let delta = delta_as_string.parse::<i32>();

    if !delta.is_ok() {
        return Err(Error::new(
            ErrorKind::InvalidData,
            format!("bad arg: {}", delta_as_string),
        ));
    }

    let tentative = current + delta.unwrap();
    if tentative >= max {
        return Ok(max);
    } else if tentative < 0 {
        // For kicks, set the brightness all the way up if caller is
        // trying to take it below 0.
        if current == 0 {
            return Ok(max);
        }
        return Ok(0);
    }
    Ok(tentative)
}

fn main() -> Result<(), std::io::Error> {
    let base_dir = Path::new(BRIGHTNESS_CONTAINING_DIR);
    let brightness_path: PathBuf = base_dir.join(BRIGHTNESS_BASENAME);

    let current = sysfs_file_to_int(&brightness_path)?;
    let max = sysfs_file_to_int(&base_dir.join(MAX_BRIGHTNESS_BASENAME))?;

    let new = target_brightness(current, max)?;
    write_int(&brightness_path, new)
}
<|endoftext|>


<commit_before>#![deny(unused_import_braces)]

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

mod utils;

pub use utils::bigint::{U256, M256, MI256};
pub use utils::gas::Gas;
pub use utils::address::Address;
pub use utils::opcode::Opcode;
pub use utils::read_hex;
<commit_msg>Problem: common checks lint should deny Solution: add critical ones<commit_after>#![deny(unused_import_braces, unused_imports,
        unused_comparisons, unused_must_use,
        unused_variables)]

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

mod utils;

pub use utils::bigint::{U256, M256, MI256};
pub use utils::gas::Gas;
pub use utils::address::Address;
pub use utils::opcode::Opcode;
pub use utils::read_hex;
<|endoftext|>


<commit_before>use gtk::{ self, WidgetExt, MenuShellExt, GtkMenuItemExt };
use libappindicator::{AppIndicator,
                      AppIndicatorStatus_APP_INDICATOR_STATUS_ACTIVE};
use std::cell::{RefCell};
use std::collections::HashMap;
use {SystrayEvent, SystrayError};
use glib;
use std;
use std::thread;
use std::sync::mpsc::{channel, Sender};

// Gtk specific struct that will live only in the Gtk thread, since a lot of the
// base types involved don't implement Send (for good reason).
pub struct GtkSystrayApp {
    menu: gtk::Menu,
    ai: RefCell<AppIndicator>,
    menu_items: RefCell<HashMap<u32, gtk::MenuItem>>,
    event_tx: Sender<SystrayEvent>
}

thread_local!(static GTK_STASH: RefCell<Option<GtkSystrayApp>> = RefCell::new(None));

pub struct MenuItemInfo {
    mid: u32,
    title: String,
    tooltip: String,
    disabled: bool,
    checked: bool
}

type Callback = Box<(Fn(&GtkSystrayApp) -> () + 'static)>;

// Convenience function to clean up thread local unwrapping
fn run_on_gtk_thread<F>(f: F)
    where F: std::ops::Fn(&GtkSystrayApp) -> () + Send + 'static {
    // Note this is glib, not gtk. Calling gtk::idle_add will panic us due to
    // being on different threads. glib::idle_add can run across threads.
    glib::idle_add(move || {
        GTK_STASH.with(|stash| {
            let stash = stash.borrow();
            let stash = stash.as_ref();
            if let Some(stash) = stash {
                f(stash);
            }
        });
        gtk::prelude::Continue(false)
    });
}

impl GtkSystrayApp {
    pub fn new(event_tx: Sender<SystrayEvent>) -> Result<GtkSystrayApp, SystrayError> {
        if let Err(e) = gtk::init() {
            return Err(SystrayError::OsError(format!("{}", "Gtk init error!")));
        }
        let mut m = gtk::Menu::new();
        let mut ai = AppIndicator::new("", "");
        ai.set_status(AppIndicatorStatus_APP_INDICATOR_STATUS_ACTIVE);
        ai.set_menu(&mut m);
        Ok(GtkSystrayApp {
            menu: m,
            ai: RefCell::new(ai),
            menu_items: RefCell::new(HashMap::new()),
            event_tx: event_tx
        })
    }

    pub fn systray_menu_selected(&self, menu_id: u32) {
        self.event_tx.send(SystrayEvent {
            menu_index: menu_id as u32,
        }).ok();
    }

    pub fn add_menu_separator(&self, item_idx: u32) {
        //let mut menu_items = self.menu_items.borrow_mut();
        let m = gtk::SeparatorMenuItem::new();
        self.menu.append(&m);
        //menu_items.insert(item_idx, m);
        self.menu.show_all();
    }

    pub fn add_menu_entry(&self, item_idx: u32, item_name: &String) {
        let mut menu_items = self.menu_items.borrow_mut();
        if menu_items.contains_key(&item_idx) {
            let m : &gtk::MenuItem = menu_items.get(&item_idx).unwrap();
            m.set_label(item_name);
            self.menu.show_all();
            return;
        }
        let m = gtk::MenuItem::new_with_label(item_name);
        self.menu.append(&m);
        m.connect_activate(move |_| {
            run_on_gtk_thread(move |stash : &GtkSystrayApp| {
                stash.systray_menu_selected(item_idx);
            });
        });
        menu_items.insert(item_idx, m);
        self.menu.show_all();
    }

    pub fn set_icon_from_file(&self, file: &String) {
        let mut ai = self.ai.borrow_mut();
        ai.set_icon_full(file, "icon");
    }
}

pub struct Window {
    gtk_loop: Option<thread::JoinHandle<()>>
}

impl Window {
    pub fn new(event_tx: Sender<SystrayEvent>) -> Result<Window, SystrayError> {
        let (tx, rx) = channel();
        let gtk_loop = thread::spawn(move || {
            GTK_STASH.with(|stash| {
                match GtkSystrayApp::new(event_tx) {
                    Ok(data) => {
                        (*stash.borrow_mut()) = Some(data);
                        tx.send(Ok(()));
                    }
                    Err(e) => {
                        tx.send(Err(e));
                        return;
                    }
                }
            });
            gtk::main();
        });
        match rx.recv().unwrap() {
            Ok(()) => Ok(Window {
                gtk_loop: Some(gtk_loop)
            }),
            Err(e) => {
                Err(e)
            }
        }
    }

    pub fn add_menu_entry(&self, item_idx: u32, item_name: &String) -> Result<(), SystrayError> {
        let n = item_name.clone();
        run_on_gtk_thread(move |stash : &GtkSystrayApp| {
            stash.add_menu_entry(item_idx, &n);
        });
        Ok(())
    }

    pub fn add_menu_separator(&self, item_idx: u32) -> Result<(), SystrayError> {
        run_on_gtk_thread(move |stash : &GtkSystrayApp| {
            stash.add_menu_separator(item_idx);
        });
        Ok(())
    }

    pub fn set_icon_from_file(&self, file: &String) -> Result<(), SystrayError> {
        let n : String = file.clone();
        run_on_gtk_thread(move |stash : &GtkSystrayApp| {
            stash.set_icon_from_file(&n);
        });
        Ok(())
    }

    pub fn set_icon_from_resource(&self, resource: &str) -> Result<(), SystrayError> {
        panic!("Not implemented on this platform!");
    }

    pub fn shutdown(&self) -> Result<(), SystrayError> {
        Ok(())
    }

    pub fn set_tooltip(&self, tooltip: &str) -> Result<(), SystrayError> {
        panic!("Not implemented on this platform!");
    }

    pub fn quit(&self) {
        glib::idle_add(|| {
            gtk::main_quit();
            glib::Continue(false)
        });
    }

}
<commit_msg>Fix compilation for linux implementation<commit_after>use gtk::{ self, WidgetExt, MenuShellExt, GtkMenuItemExt };
use libappindicator::{AppIndicator, AppIndicatorStatus};
use std::cell::{RefCell};
use std::collections::HashMap;
use {SystrayEvent, SystrayError};
use glib;
use std;
use std::thread;
use std::sync::mpsc::{channel, Sender};

// Gtk specific struct that will live only in the Gtk thread, since a lot of the
// base types involved don't implement Send (for good reason).
pub struct GtkSystrayApp {
    menu: gtk::Menu,
    ai: RefCell<AppIndicator>,
    menu_items: RefCell<HashMap<u32, gtk::MenuItem>>,
    event_tx: Sender<SystrayEvent>
}

thread_local!(static GTK_STASH: RefCell<Option<GtkSystrayApp>> = RefCell::new(None));

pub struct MenuItemInfo {
    mid: u32,
    title: String,
    tooltip: String,
    disabled: bool,
    checked: bool
}

type Callback = Box<(Fn(&GtkSystrayApp) -> () + 'static)>;

// Convenience function to clean up thread local unwrapping
fn run_on_gtk_thread<F>(f: F)
    where F: std::ops::Fn(&GtkSystrayApp) -> () + Send + 'static {
    // Note this is glib, not gtk. Calling gtk::idle_add will panic us due to
    // being on different threads. glib::idle_add can run across threads.
    glib::idle_add(move || {
        GTK_STASH.with(|stash| {
            let stash = stash.borrow();
            let stash = stash.as_ref();
            if let Some(stash) = stash {
                f(stash);
            }
        });
        gtk::prelude::Continue(false)
    });
}

impl GtkSystrayApp {
    pub fn new(event_tx: Sender<SystrayEvent>) -> Result<GtkSystrayApp, SystrayError> {
        if let Err(e) = gtk::init() {
            return Err(SystrayError::OsError(format!("{}", "Gtk init error!")));
        }
        let mut m = gtk::Menu::new();
        let mut ai = AppIndicator::new("", "");
        ai.set_status(AppIndicatorStatus::Active);
        ai.set_menu(&mut m);
        Ok(GtkSystrayApp {
            menu: m,
            ai: RefCell::new(ai),
            menu_items: RefCell::new(HashMap::new()),
            event_tx: event_tx
        })
    }

    pub fn systray_menu_selected(&self, menu_id: u32) {
        self.event_tx.send(SystrayEvent {
            menu_index: menu_id as u32,
        }).ok();
    }

    pub fn add_menu_separator(&self, item_idx: u32) {
        //let mut menu_items = self.menu_items.borrow_mut();
        let m = gtk::SeparatorMenuItem::new();
        self.menu.append(&m);
        //menu_items.insert(item_idx, m);
        self.menu.show_all();
    }

    pub fn add_menu_entry(&self, item_idx: u32, item_name: &String) {
        let mut menu_items = self.menu_items.borrow_mut();
        if menu_items.contains_key(&item_idx) {
            let m : &gtk::MenuItem = menu_items.get(&item_idx).unwrap();
            m.set_label(item_name);
            self.menu.show_all();
            return;
        }
        let m = gtk::MenuItem::new_with_label(item_name);
        self.menu.append(&m);
        m.connect_activate(move |_| {
            run_on_gtk_thread(move |stash : &GtkSystrayApp| {
                stash.systray_menu_selected(item_idx);
            });
        });
        menu_items.insert(item_idx, m);
        self.menu.show_all();
    }

    pub fn set_icon_from_file(&self, file: &String) {
        let mut ai = self.ai.borrow_mut();
        ai.set_icon_full(file, "icon");
    }
}

pub struct Window {
    gtk_loop: Option<thread::JoinHandle<()>>
}

impl Window {
    pub fn new(event_tx: Sender<SystrayEvent>) -> Result<Window, SystrayError> {
        let (tx, rx) = channel();
        let gtk_loop = thread::spawn(move || {
            GTK_STASH.with(|stash| {
                match GtkSystrayApp::new(event_tx) {
                    Ok(data) => {
                        (*stash.borrow_mut()) = Some(data);
                        tx.send(Ok(()));
                    }
                    Err(e) => {
                        tx.send(Err(e));
                        return;
                    }
                }
            });
            gtk::main();
        });
        match rx.recv().unwrap() {
            Ok(()) => Ok(Window {
                gtk_loop: Some(gtk_loop)
            }),
            Err(e) => {
                Err(e)
            }
        }
    }

    pub fn add_menu_entry(&self, item_idx: u32, item_name: &String) -> Result<(), SystrayError> {
        let n = item_name.clone();
        run_on_gtk_thread(move |stash : &GtkSystrayApp| {
            stash.add_menu_entry(item_idx, &n);
        });
        Ok(())
    }

    pub fn add_menu_separator(&self, item_idx: u32) -> Result<(), SystrayError> {
        run_on_gtk_thread(move |stash : &GtkSystrayApp| {
            stash.add_menu_separator(item_idx);
        });
        Ok(())
    }

    pub fn set_icon_from_file(&self, file: &String) -> Result<(), SystrayError> {
        let n : String = file.clone();
        run_on_gtk_thread(move |stash : &GtkSystrayApp| {
            stash.set_icon_from_file(&n);
        });
        Ok(())
    }

    pub fn set_icon_from_resource(&self, resource: &str) -> Result<(), SystrayError> {
        panic!("Not implemented on this platform!");
    }

    pub fn shutdown(&self) -> Result<(), SystrayError> {
        Ok(())
    }

    pub fn set_tooltip(&self, tooltip: &str) -> Result<(), SystrayError> {
        panic!("Not implemented on this platform!");
    }

    pub fn quit(&self) {
        glib::idle_add(|| {
            gtk::main_quit();
            glib::Continue(false)
        });
    }

}
<|endoftext|>


<commit_before>//! See https://github.com/matklad/cargo-xtask/.
//!
//! This binary defines various auxiliary build commands, which are not
//! expressible with just `cargo`. Notably, it provides `cargo xtask codegen`
//! for code generation and `cargo xtask install` for installation of
//! rust-analyzer server and client.
//!
//! This binary is integrated into the `cargo` command line by using an alias in
//! `.cargo/config`.

use std::env;

use codegen::CodegenCmd;
use pico_args::Arguments;
use xshell::pushd;
use xtask::{
    codegen::{self, Mode},
    dist::DistCmd,
    install::{InstallCmd, Malloc, ServerOpt},
    metrics::MetricsCmd,
    pre_cache::PreCacheCmd,
    pre_commit, project_root,
    release::{PromoteCmd, ReleaseCmd},
    run_clippy, run_fuzzer, run_rustfmt, Result,
};

fn main() -> Result<()> {
    if env::args().next().map(|it| it.contains("pre-commit")) == Some(true) {
        return pre_commit::run_hook();
    }

    let _d = pushd(project_root())?;

    let mut args = Arguments::from_env();
    let subcommand = args.subcommand()?.unwrap_or_default();

    match subcommand.as_str() {
        "install" => {
            if args.contains(["-h", "--help"]) {
                eprintln!(
                    "\
cargo xtask install
Install rust-analyzer server or editor plugin.

USAGE:
    cargo xtask install [FLAGS]

FLAGS:
        --client[=CLIENT] Install only VS Code plugin.
                          CLIENT is one of 'code', 'code-exploration', 'code-insiders', 'codium', or 'code-oss'
        --server          Install only the language server
        --mimalloc        Use mimalloc for server
    -h, --help            Prints help information
        "
                );
                return Ok(());
            }
            let server = args.contains("--server");
            let client_code = args.contains("--client");
            if server && client_code {
                eprintln!(
                    "error: The argument `--server` cannot be used with `--client`\n\n\
                     For more information try --help"
                );
                return Ok(());
            }

            let malloc =
                if args.contains("--mimalloc") { Malloc::Mimalloc } else { Malloc::System };

            let client_opt = args.opt_value_from_str("--client")?;

            args.finish()?;

            InstallCmd {
                client: if server { None } else { Some(client_opt.unwrap_or_default()) },
                server: if client_code { None } else { Some(ServerOpt { malloc }) },
            }
            .run()
        }
        "codegen" => {
            let features = args.contains("--features");
            args.finish()?;
            CodegenCmd { features }.run()
        }
        "format" => {
            args.finish()?;
            run_rustfmt(Mode::Overwrite)
        }
        "install-pre-commit-hook" => {
            args.finish()?;
            pre_commit::install_hook()
        }
        "lint" => {
            args.finish()?;
            run_clippy()
        }
        "fuzz-tests" => {
            args.finish()?;
            run_fuzzer()
        }
        "pre-cache" => {
            args.finish()?;
            PreCacheCmd.run()
        }
        "release" => {
            let dry_run = args.contains("--dry-run");
            args.finish()?;
            ReleaseCmd { dry_run }.run()
        }
        "promote" => {
            let dry_run = args.contains("--dry-run");
            args.finish()?;
            PromoteCmd { dry_run }.run()
        }
        "dist" => {
            let nightly = args.contains("--nightly");
            let client_version: Option<String> = args.opt_value_from_str("--client")?;
            args.finish()?;
            DistCmd { nightly, client_version }.run()
        }
        "metrics" => {
            let dry_run = args.contains("--dry-run");
            args.finish()?;
            MetricsCmd { dry_run }.run()
        }
        _ => {
            eprintln!(
                "\
cargo xtask
Run custom build command.

USAGE:
    cargo xtask <SUBCOMMAND>

SUBCOMMANDS:
    format
    install-pre-commit-hook
    fuzz-tests
    codegen
    install
    lint
    dist
    promote"
            );
            Ok(())
        }
    }
}
<commit_msg>Add build benchmark xtask command<commit_after>//! See https://github.com/matklad/cargo-xtask/.
//!
//! This binary defines various auxiliary build commands, which are not
//! expressible with just `cargo`. Notably, it provides `cargo xtask codegen`
//! for code generation and `cargo xtask install` for installation of
//! rust-analyzer server and client.
//!
//! This binary is integrated into the `cargo` command line by using an alias in
//! `.cargo/config`.

use std::env;

use codegen::CodegenCmd;
use pico_args::Arguments;
use xshell::{cmd, cp, pushd};
use xtask::{
    codegen::{self, Mode},
    dist::DistCmd,
    install::{InstallCmd, Malloc, ServerOpt},
    metrics::MetricsCmd,
    pre_cache::PreCacheCmd,
    pre_commit, project_root,
    release::{PromoteCmd, ReleaseCmd},
    run_clippy, run_fuzzer, run_rustfmt, Result,
};

fn main() -> Result<()> {
    if env::args().next().map(|it| it.contains("pre-commit")) == Some(true) {
        return pre_commit::run_hook();
    }

    let _d = pushd(project_root())?;

    let mut args = Arguments::from_env();
    let subcommand = args.subcommand()?.unwrap_or_default();

    match subcommand.as_str() {
        "install" => {
            if args.contains(["-h", "--help"]) {
                eprintln!(
                    "\
cargo xtask install
Install rust-analyzer server or editor plugin.

USAGE:
    cargo xtask install [FLAGS]

FLAGS:
        --client[=CLIENT] Install only VS Code plugin.
                          CLIENT is one of 'code', 'code-exploration', 'code-insiders', 'codium', or 'code-oss'
        --server          Install only the language server
        --mimalloc        Use mimalloc for server
    -h, --help            Prints help information
        "
                );
                return Ok(());
            }
            let server = args.contains("--server");
            let client_code = args.contains("--client");
            if server && client_code {
                eprintln!(
                    "error: The argument `--server` cannot be used with `--client`\n\n\
                     For more information try --help"
                );
                return Ok(());
            }

            let malloc =
                if args.contains("--mimalloc") { Malloc::Mimalloc } else { Malloc::System };

            let client_opt = args.opt_value_from_str("--client")?;

            args.finish()?;

            InstallCmd {
                client: if server { None } else { Some(client_opt.unwrap_or_default()) },
                server: if client_code { None } else { Some(ServerOpt { malloc }) },
            }
            .run()
        }
        "codegen" => {
            let features = args.contains("--features");
            args.finish()?;
            CodegenCmd { features }.run()
        }
        "format" => {
            args.finish()?;
            run_rustfmt(Mode::Overwrite)
        }
        "install-pre-commit-hook" => {
            args.finish()?;
            pre_commit::install_hook()
        }
        "lint" => {
            args.finish()?;
            run_clippy()
        }
        "fuzz-tests" => {
            args.finish()?;
            run_fuzzer()
        }
        "pre-cache" => {
            args.finish()?;
            PreCacheCmd.run()
        }
        "release" => {
            let dry_run = args.contains("--dry-run");
            args.finish()?;
            ReleaseCmd { dry_run }.run()
        }
        "promote" => {
            let dry_run = args.contains("--dry-run");
            args.finish()?;
            PromoteCmd { dry_run }.run()
        }
        "dist" => {
            let nightly = args.contains("--nightly");
            let client_version: Option<String> = args.opt_value_from_str("--client")?;
            args.finish()?;
            DistCmd { nightly, client_version }.run()
        }
        "metrics" => {
            let dry_run = args.contains("--dry-run");
            args.finish()?;
            MetricsCmd { dry_run }.run()
        }
        "bb" => {
            let suffix: String = args.free_from_str()?.unwrap();
            args.finish()?;
            cmd!("cargo build --release").run()?;
            cp("./target/release/rust-analyzer", format!("./target/rust-analyzer-{}", suffix))?;
            Ok(())
        }
        _ => {
            eprintln!(
                "\
cargo xtask
Run custom build command.

USAGE:
    cargo xtask <SUBCOMMAND>

SUBCOMMANDS:
    format
    install-pre-commit-hook
    fuzz-tests
    codegen
    install
    lint
    dist
    promote
    bb"
            );
            Ok(())
        }
    }
}
<|endoftext|>


<commit_before>use serde_json::*;

use super::super::lex::*;

///
/// Creates a lexing tool for the scripting language
///
pub fn create_lex_script_tool() -> StringLexingTool {
    // Parse the lexer
    let script_json = from_str::<Vec<LexToolSymbol>>(include_str!("syntax_lexer.json")).unwrap();

    // The name isn't used here, but define it anyway
    let lex_defn = LexToolInput {
        new_tool_name:  String::from("lex-script"),
        symbols:        script_json
    };

    // Create the lexing tool with this definition
    StringLexingTool::from_lex_tool_input(&lex_defn)
}

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

    fn lex_tokens(input: &str) -> Vec<String> {
        let lex_tool = create_lex_script_tool();

        lex_tool
            .lex(input)
            .iter()
            .map(|x| x.token.clone())
            .collect()
    }

    #[test]
    fn can_parse_syntax_json() {
        let script_json = from_str::<Value>(include_str!("syntax_lexer.json"));

        if script_json.is_err() {
            println!("{:?}", script_json);
            println!("{:?}", script_json.unwrap_err().description());

            assert!(false);
        }
    }

    #[test]
    fn json_can_be_deserialized() {
        let script_json = from_str::<Vec<LexToolSymbol>>(include_str!("syntax_lexer.json"));

        if script_json.is_err() {
            println!("{:?}", script_json);
        }

        script_json.unwrap();
    }

    #[test]
    fn can_create_tool() {
        let _tool = create_lex_script_tool();
    }

    #[test]
    fn can_lex_identifier() {
        assert!(lex_tokens("something") == vec![ String::from("Identifier") ]);
    }

    #[test]
    fn can_lex_let_keyword() {
        assert!(lex_tokens("let") == vec![ String::from("let") ]);
    }

    #[test]
    fn can_lex_whitespace() {
        assert!(lex_tokens(" ") == vec![ String::from("Whitespace") ]);
    }

    #[test]
    fn can_lex_plus_symbol() {
        assert!(lex_tokens("+") == vec![ String::from("+") ]);
    }

    #[test]
    fn can_lex_dot_symbol() {
        assert!(lex_tokens(".") == vec![ String::from(".") ]);
    }

    #[test]
    fn can_lex_newline() {
        assert!(lex_tokens("\n") == vec![ String::from("Newline") ]);
    }

    #[test]
    fn can_lex_simple_number() {
        assert!(lex_tokens("1") == vec![ String::from("Number") ]);
    }

    #[test]
    fn can_lex_longer_number() {
        assert!(lex_tokens("123") == vec![ String::from("Number") ]);
    }

    #[test]
    fn can_lex_decimal_number() {
        assert!(lex_tokens("1.21") == vec![ String::from("Number") ]);
    }

    #[test]
    fn can_lex_decimal_with_exponent() {
        assert!(lex_tokens("1.2e10") == vec![ String::from("Number") ]);
    }

    #[test]
    fn can_lex_integer_with_exponent() {
        assert!(lex_tokens("1e10") == vec![ String::from("Number") ]);
    }

    #[test]
    fn can_lex_decimal_number_beginning_with_dot() {
        assert!(lex_tokens(".21") == vec![ String::from("Number") ]);
    }
}
<commit_msg>Add test for identifier with ‘-‘ in it<commit_after>use serde_json::*;

use super::super::lex::*;

///
/// Creates a lexing tool for the scripting language
///
pub fn create_lex_script_tool() -> StringLexingTool {
    // Parse the lexer
    let script_json = from_str::<Vec<LexToolSymbol>>(include_str!("syntax_lexer.json")).unwrap();

    // The name isn't used here, but define it anyway
    let lex_defn = LexToolInput {
        new_tool_name:  String::from("lex-script"),
        symbols:        script_json
    };

    // Create the lexing tool with this definition
    StringLexingTool::from_lex_tool_input(&lex_defn)
}

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

    fn lex_tokens(input: &str) -> Vec<String> {
        let lex_tool = create_lex_script_tool();

        lex_tool
            .lex(input)
            .iter()
            .map(|x| x.token.clone())
            .collect()
    }

    #[test]
    fn can_parse_syntax_json() {
        let script_json = from_str::<Value>(include_str!("syntax_lexer.json"));

        if script_json.is_err() {
            println!("{:?}", script_json);
            println!("{:?}", script_json.unwrap_err().description());

            assert!(false);
        }
    }

    #[test]
    fn json_can_be_deserialized() {
        let script_json = from_str::<Vec<LexToolSymbol>>(include_str!("syntax_lexer.json"));

        if script_json.is_err() {
            println!("{:?}", script_json);
        }

        script_json.unwrap();
    }

    #[test]
    fn can_create_tool() {
        let _tool = create_lex_script_tool();
    }

    #[test]
    fn can_lex_identifier() {
        assert!(lex_tokens("something") == vec![ String::from("Identifier") ]);
    }

    #[test]
    fn can_lex_identifier_with_hyphen() {
        assert!(lex_tokens("something-something") == vec![ String::from("Identifier") ]);
    }

    #[test]
    fn can_lex_let_keyword() {
        assert!(lex_tokens("let") == vec![ String::from("let") ]);
    }

    #[test]
    fn can_lex_whitespace() {
        assert!(lex_tokens(" ") == vec![ String::from("Whitespace") ]);
    }

    #[test]
    fn can_lex_plus_symbol() {
        assert!(lex_tokens("+") == vec![ String::from("+") ]);
    }

    #[test]
    fn can_lex_dot_symbol() {
        assert!(lex_tokens(".") == vec![ String::from(".") ]);
    }

    #[test]
    fn can_lex_newline() {
        assert!(lex_tokens("\n") == vec![ String::from("Newline") ]);
    }

    #[test]
    fn can_lex_simple_number() {
        assert!(lex_tokens("1") == vec![ String::from("Number") ]);
    }

    #[test]
    fn can_lex_longer_number() {
        assert!(lex_tokens("123") == vec![ String::from("Number") ]);
    }

    #[test]
    fn can_lex_decimal_number() {
        assert!(lex_tokens("1.21") == vec![ String::from("Number") ]);
    }

    #[test]
    fn can_lex_decimal_with_exponent() {
        assert!(lex_tokens("1.2e10") == vec![ String::from("Number") ]);
    }

    #[test]
    fn can_lex_integer_with_exponent() {
        assert!(lex_tokens("1e10") == vec![ String::from("Number") ]);
    }

    #[test]
    fn can_lex_decimal_number_beginning_with_dot() {
        assert!(lex_tokens(".21") == vec![ String::from("Number") ]);
    }
}
<|endoftext|>


<commit_before>// This file was generated by gir (5e8c56e) from gir-files (71d73f0)
// DO NOT EDIT

use StyleProvider;
use ffi;
use gdk;
use glib::translate::*;

glib_wrapper! {
    pub struct Settings(Object<ffi::GtkSettings>): StyleProvider;

    match fn {
        get_type => || ffi::gtk_settings_get_type(),
    }
}

impl Settings {
    #[cfg(feature = "v3_20")]
    pub fn reset_property(&self, name: &str) {
        unsafe {
            ffi::gtk_settings_reset_property(self.to_glib_none().0, name.to_glib_none().0);
        }
    }

    pub fn set_double_property(&self, name: &str, v_double: f64, origin: &str) {
        unsafe {
            ffi::gtk_settings_set_double_property(self.to_glib_none().0, name.to_glib_none().0, v_double, origin.to_glib_none().0);
        }
    }

    //pub fn set_long_property(&self, name: &str, v_long: /*Unimplemented*/Fundamental: Long, origin: &str) {
    //    unsafe { TODO: call ffi::gtk_settings_set_long_property() }
    //}

    //pub fn set_property_value(&self, name: &str, svalue: /*Ignored*/&SettingsValue) {
    //    unsafe { TODO: call ffi::gtk_settings_set_property_value() }
    //}

    pub fn set_string_property(&self, name: &str, v_string: &str, origin: &str) {
        unsafe {
            ffi::gtk_settings_set_string_property(self.to_glib_none().0, name.to_glib_none().0, v_string.to_glib_none().0, origin.to_glib_none().0);
        }
    }

    pub fn get_default() -> Option<Settings> {
        assert_initialized_main_thread!();
        unsafe {
            from_glib_none(ffi::gtk_settings_get_default())
        }
    }

    pub fn get_for_screen(screen: &gdk::Screen) -> Option<Settings> {
        assert_initialized_main_thread!();
        unsafe {
            from_glib_none(ffi::gtk_settings_get_for_screen(screen.to_glib_none().0))
        }
    }

    //pub fn install_property<T: IsA</*Ignored*/glib::ParamSpec>>(pspec: &T) {
    //    unsafe { TODO: call ffi::gtk_settings_install_property() }
    //}

    //pub fn install_property_parser<T: IsA</*Ignored*/glib::ParamSpec>>(pspec: &T, parser: /*Unknown conversion*//*Unimplemented*/RcPropertyParser) {
    //    unsafe { TODO: call ffi::gtk_settings_install_property_parser() }
    //}
}
<commit_msg>Regen test<commit_after>// This file was generated by gir (08d13ff) from gir-files (71d73f0)
// DO NOT EDIT

use StyleProvider;
use ffi;
use gdk;
use glib::translate::*;
use libc;

glib_wrapper! {
    pub struct Settings(Object<ffi::GtkSettings>): StyleProvider;

    match fn {
        get_type => || ffi::gtk_settings_get_type(),
    }
}

impl Settings {
    #[cfg(feature = "v3_20")]
    pub fn reset_property(&self, name: &str) {
        unsafe {
            ffi::gtk_settings_reset_property(self.to_glib_none().0, name.to_glib_none().0);
        }
    }

    pub fn set_double_property(&self, name: &str, v_double: f64, origin: &str) {
        unsafe {
            ffi::gtk_settings_set_double_property(self.to_glib_none().0, name.to_glib_none().0, v_double, origin.to_glib_none().0);
        }
    }

    pub fn set_long_property(&self, name: &str, v_long: libc::c_long, origin: &str) {
        unsafe {
            ffi::gtk_settings_set_long_property(self.to_glib_none().0, name.to_glib_none().0, v_long, origin.to_glib_none().0);
        }
    }

    //pub fn set_property_value(&self, name: &str, svalue: /*Ignored*/&SettingsValue) {
    //    unsafe { TODO: call ffi::gtk_settings_set_property_value() }
    //}

    pub fn set_string_property(&self, name: &str, v_string: &str, origin: &str) {
        unsafe {
            ffi::gtk_settings_set_string_property(self.to_glib_none().0, name.to_glib_none().0, v_string.to_glib_none().0, origin.to_glib_none().0);
        }
    }

    pub fn get_default() -> Option<Settings> {
        assert_initialized_main_thread!();
        unsafe {
            from_glib_none(ffi::gtk_settings_get_default())
        }
    }

    pub fn get_for_screen(screen: &gdk::Screen) -> Option<Settings> {
        assert_initialized_main_thread!();
        unsafe {
            from_glib_none(ffi::gtk_settings_get_for_screen(screen.to_glib_none().0))
        }
    }

    //pub fn install_property<T: IsA</*Ignored*/glib::ParamSpec>>(pspec: &T) {
    //    unsafe { TODO: call ffi::gtk_settings_install_property() }
    //}

    //pub fn install_property_parser<T: IsA</*Ignored*/glib::ParamSpec>>(pspec: &T, parser: /*Unknown conversion*//*Unimplemented*/RcPropertyParser) {
    //    unsafe { TODO: call ffi::gtk_settings_install_property_parser() }
    //}
}
<|endoftext|>


<commit_before>mod utils;

use clap::{App, Arg, ArgGroup, ErrorKind};

static CONFLICT_ERR: &str = "error: The argument '-F' cannot be used with '--flag'

USAGE:
    clap-test <positional> <positional2> --flag --long-option-2 <option2>

For more information try --help";

static CONFLICT_ERR_REV: &str = "error: The argument '--flag' cannot be used with '-F'

USAGE:
    clap-test <positional> <positional2> -F --long-option-2 <option2>

For more information try --help";

#[test]
fn flag_conflict() {
    let result = App::new("flag_conflict")
        .arg(Arg::from("-f, --flag 'some flag'").conflicts_with("other"))
        .arg(Arg::from("-o, --other 'some flag'"))
        .try_get_matches_from(vec!["myprog", "-f", "-o"]);
    assert!(result.is_err());
    let err = result.err().unwrap();
    assert_eq!(err.kind, ErrorKind::ArgumentConflict);
}

#[test]
fn flag_conflict_2() {
    let result = App::new("flag_conflict")
        .arg(Arg::from("-f, --flag 'some flag'").conflicts_with("other"))
        .arg(Arg::from("-o, --other 'some flag'"))
        .try_get_matches_from(vec!["myprog", "-o", "-f"]);
    assert!(result.is_err());
    let err = result.err().unwrap();
    assert_eq!(err.kind, ErrorKind::ArgumentConflict);
}

#[test]
fn flag_conflict_with_all() {
    let result = App::new("flag_conflict")
        .arg(Arg::from("-f, --flag 'some flag'").conflicts_with_all(&["other"]))
        .arg(Arg::from("-o, --other 'some flag'"))
        .try_get_matches_from(vec!["myprog", "-o", "-f"]);
    assert!(result.is_err());
    let err = result.err().unwrap();
    assert_eq!(err.kind, ErrorKind::ArgumentConflict);
}

#[test]
fn flag_conflict_with_everything() {
    let result = App::new("flag_conflict")
        .arg(Arg::from("-f, --flag 'some flag'").exclusive(true))
        .arg(Arg::from("-o, --other 'some flag'"))
        .try_get_matches_from(vec!["myprog", "-o", "-f"]);
    assert!(result.is_err());
    let err = result.err().unwrap();
    assert_eq!(err.kind, ErrorKind::ArgumentConflict);
}

#[test]
fn group_conflict() {
    let result = App::new("group_conflict")
        .arg(Arg::from("-f, --flag 'some flag'").conflicts_with("gr"))
        .group(
            ArgGroup::with_name("gr")
                .required(true)
                .arg("some")
                .arg("other"),
        )
        .arg(Arg::from("--some 'some arg'"))
        .arg(Arg::from("--other 'other arg'"))
        .try_get_matches_from(vec!["myprog", "--other", "-f"]);
    assert!(result.is_err());
    let err = result.err().unwrap();
    assert_eq!(err.kind, ErrorKind::ArgumentConflict);
}

#[test]
fn group_conflict_2() {
    let result = App::new("group_conflict")
        .arg(Arg::from("-f, --flag 'some flag'").conflicts_with("gr"))
        .group(
            ArgGroup::with_name("gr")
                .required(true)
                .arg("some")
                .arg("other"),
        )
        .arg(Arg::from("--some 'some arg'"))
        .arg(Arg::from("--other 'other arg'"))
        .try_get_matches_from(vec!["myprog", "-f", "--some"]);
    assert!(result.is_err());
    let err = result.err().unwrap();
    assert_eq!(err.kind, ErrorKind::ArgumentConflict);
}

#[test]
fn conflict_output() {
    utils::compare_output(
        utils::complex_app(),
        "clap-test val1 --flag --long-option-2 val2 -F",
        CONFLICT_ERR,
        true,
    );
}

#[test]
fn conflict_output_rev() {
    utils::compare_output(
        utils::complex_app(),
        "clap-test val1 -F --long-option-2 val2 --flag",
        CONFLICT_ERR_REV,
        true,
    );
}

#[test]
fn conflict_with_unused_default_value() {
    let result = App::new("conflict")
        .arg(Arg::from("-o, --opt=[opt] 'some opt'").default_value("default"))
        .arg(Arg::from("-f, --flag 'some flag'").conflicts_with("opt"))
        .try_get_matches_from(vec!["myprog", "-f"]);
    assert!(result.is_ok());
    let m = result.unwrap();
    assert_eq!(m.value_of("opt"), Some("default"));
    assert!(m.is_present("flag"));
}

#[test]
fn two_conflicting_arguments() {
    let a = App::new("two_conflicting_arguments")
        .arg(
            Arg::with_name("develop")
                .long("develop")
                .conflicts_with("production"),
        )
        .arg(
            Arg::with_name("production")
                .long("production")
                .conflicts_with("develop"),
        )
        .try_get_matches_from(vec!["", "--develop", "--production"]);

    assert!(a.is_err());
    let a = a.unwrap_err();
    assert_eq!(
        a.cause,
        "The argument \'--develop\' cannot be used with \'--production\'"
    );
}

#[test]
fn three_conflicting_arguments() {
    let a = App::new("two_conflicting_arguments")
        .arg(
            Arg::with_name("one")
                .long("one")
                .conflicts_with_all(&["two", "three"]),
        )
        .arg(
            Arg::with_name("two")
                .long("two")
                .conflicts_with_all(&["one", "three"]),
        )
        .arg(
            Arg::with_name("three")
                .long("three")
                .conflicts_with_all(&["one", "two"]),
        )
        .try_get_matches_from(vec!["", "--one", "--two", "--three"]);

    assert!(a.is_err());
    let a = a.unwrap_err();
    assert_eq!(
        a.cause,
        "The argument \'--one\' cannot be used with \'--two\'"
    );
}

#[cfg(debug_assertions)]
#[test]
#[should_panic = "Argument 'config' cannot conflict with itself"]
fn self_conflicting_arg() {
    let _ = App::new("prog")
        .arg(
            Arg::with_name("config")
                .long("config")
                .conflicts_with("config"),
        )
        .try_get_matches_from(vec!["", "--config"]);
}

#[cfg(debug_assertions)]
#[test]
#[should_panic = "Argument or group 'extra' specified in 'conflicts_with*' for 'config' does not exist"]
fn conflicts_with_invalid_arg() {
    let _ = App::new("prog")
        .arg(
            Arg::with_name("config")
                .long("config")
                .conflicts_with("extra"),
        )
        .try_get_matches_from(vec!["", "--config"]);
}
<commit_msg>Add a test<commit_after>mod utils;

use clap::{App, Arg, ArgGroup, ErrorKind};

static CONFLICT_ERR: &str = "error: The argument '-F' cannot be used with '--flag'

USAGE:
    clap-test <positional> <positional2> --flag --long-option-2 <option2>

For more information try --help";

static CONFLICT_ERR_REV: &str = "error: The argument '--flag' cannot be used with '-F'

USAGE:
    clap-test <positional> <positional2> -F --long-option-2 <option2>

For more information try --help";

#[test]
fn flag_conflict() {
    let result = App::new("flag_conflict")
        .arg(Arg::from("-f, --flag 'some flag'").conflicts_with("other"))
        .arg(Arg::from("-o, --other 'some flag'"))
        .try_get_matches_from(vec!["myprog", "-f", "-o"]);
    assert!(result.is_err());
    let err = result.err().unwrap();
    assert_eq!(err.kind, ErrorKind::ArgumentConflict);
}

#[test]
fn flag_conflict_2() {
    let result = App::new("flag_conflict")
        .arg(Arg::from("-f, --flag 'some flag'").conflicts_with("other"))
        .arg(Arg::from("-o, --other 'some flag'"))
        .try_get_matches_from(vec!["myprog", "-o", "-f"]);
    assert!(result.is_err());
    let err = result.err().unwrap();
    assert_eq!(err.kind, ErrorKind::ArgumentConflict);
}

#[test]
fn flag_conflict_with_all() {
    let result = App::new("flag_conflict")
        .arg(Arg::from("-f, --flag 'some flag'").conflicts_with_all(&["other"]))
        .arg(Arg::from("-o, --other 'some flag'"))
        .try_get_matches_from(vec!["myprog", "-o", "-f"]);
    assert!(result.is_err());
    let err = result.err().unwrap();
    assert_eq!(err.kind, ErrorKind::ArgumentConflict);
}

#[test]
fn flag_conflict_with_everything() {
    let result = App::new("flag_conflict")
        .arg(Arg::from("-f, --flag 'some flag'").exclusive(true))
        .arg(Arg::from("-o, --other 'some flag'"))
        .try_get_matches_from(vec!["myprog", "-o", "-f"]);
    assert!(result.is_err());
    let err = result.err().unwrap();
    assert_eq!(err.kind, ErrorKind::ArgumentConflict);
}

#[test]
fn group_conflict() {
    let result = App::new("group_conflict")
        .arg(Arg::from("-f, --flag 'some flag'").conflicts_with("gr"))
        .group(
            ArgGroup::with_name("gr")
                .required(true)
                .arg("some")
                .arg("other"),
        )
        .arg(Arg::from("--some 'some arg'"))
        .arg(Arg::from("--other 'other arg'"))
        .try_get_matches_from(vec!["myprog", "--other", "-f"]);
    assert!(result.is_err());
    let err = result.err().unwrap();
    assert_eq!(err.kind, ErrorKind::ArgumentConflict);
}

#[test]
fn group_conflict_2() {
    let result = App::new("group_conflict")
        .arg(Arg::from("-f, --flag 'some flag'").conflicts_with("gr"))
        .group(
            ArgGroup::with_name("gr")
                .required(true)
                .arg("some")
                .arg("other"),
        )
        .arg(Arg::from("--some 'some arg'"))
        .arg(Arg::from("--other 'other arg'"))
        .try_get_matches_from(vec!["myprog", "-f", "--some"]);
    assert!(result.is_err());
    let err = result.err().unwrap();
    assert_eq!(err.kind, ErrorKind::ArgumentConflict);
}

#[test]
fn conflict_output() {
    utils::compare_output(
        utils::complex_app(),
        "clap-test val1 --flag --long-option-2 val2 -F",
        CONFLICT_ERR,
        true,
    );
}

#[test]
fn conflict_output_rev() {
    utils::compare_output(
        utils::complex_app(),
        "clap-test val1 -F --long-option-2 val2 --flag",
        CONFLICT_ERR_REV,
        true,
    );
}

#[test]
fn conflict_with_unused_default_value() {
    let result = App::new("conflict")
        .arg(Arg::from("-o, --opt=[opt] 'some opt'").default_value("default"))
        .arg(Arg::from("-f, --flag 'some flag'").conflicts_with("opt"))
        .try_get_matches_from(vec!["myprog", "-f"]);
    assert!(result.is_ok());
    let m = result.unwrap();
    assert_eq!(m.value_of("opt"), Some("default"));
    assert!(m.is_present("flag"));
}

#[test]
fn two_conflicting_arguments() {
    let a = App::new("two_conflicting_arguments")
        .arg(
            Arg::with_name("develop")
                .long("develop")
                .conflicts_with("production"),
        )
        .arg(
            Arg::with_name("production")
                .long("production")
                .conflicts_with("develop"),
        )
        .try_get_matches_from(vec!["", "--develop", "--production"]);

    assert!(a.is_err());
    let a = a.unwrap_err();
    assert_eq!(
        a.cause,
        "The argument \'--develop\' cannot be used with \'--production\'"
    );
}

#[test]
fn three_conflicting_arguments() {
    let a = App::new("two_conflicting_arguments")
        .arg(
            Arg::with_name("one")
                .long("one")
                .conflicts_with_all(&["two", "three"]),
        )
        .arg(
            Arg::with_name("two")
                .long("two")
                .conflicts_with_all(&["one", "three"]),
        )
        .arg(
            Arg::with_name("three")
                .long("three")
                .conflicts_with_all(&["one", "two"]),
        )
        .try_get_matches_from(vec!["", "--one", "--two", "--three"]);

    assert!(a.is_err());
    let a = a.unwrap_err();
    assert_eq!(
        a.cause,
        "The argument \'--one\' cannot be used with \'--two\'"
    );
}

#[cfg(debug_assertions)]
#[test]
#[should_panic = "Argument 'config' cannot conflict with itself"]
fn self_conflicting_arg() {
    let _ = App::new("prog")
        .arg(
            Arg::with_name("config")
                .long("config")
                .conflicts_with("config"),
        )
        .try_get_matches_from(vec!["", "--config"]);
}

#[cfg(debug_assertions)]
#[test]
#[should_panic = "Argument or group 'extra' specified in 'conflicts_with*' for 'config' does not exist"]
fn conflicts_with_invalid_arg() {
    let _ = App::new("prog")
        .arg(
            Arg::with_name("config")
                .long("config")
                .conflicts_with("extra"),
        )
        .try_get_matches_from(vec!["", "--config"]);
}

#[test]
fn conflicts_with_default() {
    let result = App::new("conflict")
        .arg(
            Arg::from("-o, --opt=[opt] 'some opt'")
                .default_value("default")
                .conflicts_with("flag"),
        )
        .arg(Arg::from("-f, --flag 'some flag'").conflicts_with("opt"))
        .try_get_matches_from(vec!["myprog", "-f"]);

    assert!(result.is_ok(), "{:?}", result.unwrap());
    let m = result.unwrap();

    assert_eq!(m.value_of("opt"), Some("default"));
    assert!(m.is_present("flag"));
}
<|endoftext|>


<commit_before>
use std::str::CharIndices;
use std::iter::Peekable;

#[derive(PartialEq, Debug)]
pub enum Token<'a> {
  Eof,
  Punctuator(Punctuator, usize, usize),
  Name(&'a str, usize, usize),
  IntValue(&'a str, usize, usize),
  FloatValue(&'a str, usize, usize),
  StringValue(&'a str, usize, usize),
}

#[derive(PartialEq, Debug)]
pub enum Punctuator {
  Bang,
  Dollar,
  LeftParen,
  RightParen,
  Spread,
  Colon,
  Equals,
  At,
  LeftBracket,
  RightBracket,
  LeftBrace,
  RightBrace,
  Pipe,
}

macro_rules! take {
  ($lexer: ident, $($p: pat)|*) => ({
    let mut is_taken = false;
    if let Some(&(p, c)) = $lexer.iter.peek() {
      match c {
        $(
          $p => {
            $lexer.iter.next();
            $lexer.hi = p;
            is_taken = true;
          }
        )*
        _ => {}
      }
    }
    is_taken
  });
}

macro_rules! take_while {
  ($lexer: ident, $($p: pat)|*) => ({
    let mut is_taken = false;
    while let Some(&(p, c)) = $lexer.iter.peek() {
      match c {
        $(
          $p => {
            $lexer.iter.next();
            is_taken = true;
          }
        )*
        _ => {
          $lexer.hi = p;
          break;
        }
      }
    }
    is_taken
  });
}

macro_rules! take_while_not {
  ($lexer: ident, $($p: pat)|*) => ({
    let mut is_taken = false;
    while let Some(&(p, c)) = $lexer.iter.peek() {
      match c {
        $(
          $p => {
            $lexer.hi = p;
            break;
          }
        )*
        _ => {
            $lexer.iter.next();
            is_taken = true;
        }
      }
    }
    is_taken
  });
}

macro_rules! peek {
  ($lexer: ident, $($p: pat)|*) => ({
    let mut is_match = false;
    if let Some(&(_, c)) = $lexer.iter.peek() {
      match c {
        $(
          $p => {
            is_match = true;
          }
        )*
        _ => {}
      }
    }
    is_match
  });
}

macro_rules! take_eof {
  ($lexer: ident) => ({
    if $lexer.iter.peek().is_none() {
      $lexer.hi = $lexer.input_len;
      true
    } else {
      false
    }
  });
}

pub struct Lexer<'a> {
  input: &'a str,
  input_len: usize,
  iter: Peekable<CharIndices<'a>>,
  is_eof: bool,
  lo: usize,
  hi: usize,
}

impl<'a> Lexer<'a> {
  pub fn new(input: &'a str) -> Lexer<'a> {
    Lexer {
      input: input,
      input_len: input.len(),
      iter: input.char_indices().peekable(),
      is_eof: false,
      lo: 0,
      hi: 0,
    }
  }
}

fn skip_ignored_token(lexer: &mut Lexer) {
  loop {
    if take!(lexer, '#') {
      take_while_not!(lexer, '\r' | '\n');
    }
    if !take_while!(lexer, '\u{feff}' | ' ' | '\t' | '\r' | '\n' | ',') {
      break;
    }
  }
}

fn scan_spread(lexer: &mut Lexer) -> bool {
  if take!(lexer, '.') {
    if take!(lexer, '.') {
      if take!(lexer, '.') {
        return true;
      }
    }
  }
  return false;
}

fn scan_name(lexer: &mut Lexer) {
  take_while!(lexer, '_' | 'a'...'z' | 'A'...'Z' | '0'...'9');
  take_eof!(lexer);
}

// Return the raw string without unescape character
fn scan_string(lexer: &mut Lexer) -> (bool, bool) {
  let mut is_bad_escape = false;
  let mut is_terminated = false;
  if take!(lexer, '"') {
    lexer.lo = lexer.lo + 1;
  }
  loop {
    if take!(lexer, '\\') {
      if !take!(lexer, '\\' | '"' | 'b' | 'f' | 'n' | 'r' | 't' | '/' | 'u') {
        is_bad_escape = true;
        break;
      }
    }
    take_while_not!(lexer, '"' | '\\');
    if take!(lexer, '"') {
      is_terminated = true;
      break;
    }
  }
  (is_terminated, is_bad_escape)
}

// IntValue:   (+|-)?(0|[1-9][0-9]*)
// FloatValue: (+|-)?(0|[1-9][0-9]*)(\.[0-9]+)?((E|e)(+|-)?[0-9]+)?
fn scan_number(lexer: &mut Lexer) -> (bool, bool) {
  let mut is_float = false;
  take!(lexer, '+' | '-');
  // Integer part
  if take!(lexer, '1'...'9') {
    take_while!(lexer, '0'...'9');
    if take!(lexer, ' ' | '\t' | '\r' | '\n' | ',') || take_eof!(lexer) {
      return (true, is_float);
    }
  } else if take!(lexer, '0') {
    if take!(lexer, ' ' | '\t' | '\r' | '\n' | ',') || take_eof!(lexer) {
      return (true, is_float);
    }
  }
  // Fractional part
  if take!(lexer, '.') {
    if !take_while!(lexer, '0'...'9') {
      return (false, is_float);
    }
    is_float = true;
  }
  // Exponent part
  if !is_float && peek!(lexer, 'E' | 'e') {
    return (false, is_float);
  }
  if take!(lexer, 'E' | 'e') {
    if take!(lexer, '+' | '-') {
      if !take_while!(lexer, '0'...'9') {
        return (false, is_float);
      }
    } else {
      take_while!(lexer, '0'...'9');
    }
  }

  if take!(lexer, ' ' | '\t' | '\r' | '\n' | ',') || take_eof!(lexer) {
    return (true, is_float);
  }
  return (false, is_float);
}

impl<'a> Iterator for Lexer<'a> {
  type Item = Result<Token<'a>, &'a str>;
  fn next(&mut self) -> Option<Result<Token<'a>, &'a str>> {
    use self::Token::*;
    use self::Punctuator::*;

    if !self.is_eof && take_eof!(self) {
      self.is_eof = true;
      return Some(Ok(Token::Eof));
    }
    if self.is_eof {
      return None;
    }
    skip_ignored_token(self);

    let mut item = None;
    if let Some(&(p, c)) = self.iter.peek() {
      self.lo = p;
      self.hi = p;
      item = match c {
        '!' => {
          self.iter.next();
          Some(Ok(Punctuator(Bang, self.lo, self.hi)))
        }
        '$' => {
          self.iter.next();
          Some(Ok(Punctuator(Dollar, self.lo, self.hi)))
        }
        '(' => {
          self.iter.next();
          Some(Ok(Punctuator(LeftParen, self.lo, self.hi)))
        }
        ')' => {
          self.iter.next();
          Some(Ok(Punctuator(RightParen, self.lo, self.hi)))
        }
        ':' => {
          self.iter.next();
          Some(Ok(Punctuator(Colon, self.lo, self.hi)))
        }
        '=' => {
          self.iter.next();
          Some(Ok(Punctuator(Equals, self.lo, self.hi)))
        }
        '@' => {
          self.iter.next();
          Some(Ok(Punctuator(At, self.lo, self.hi)))
        }
        '[' => {
          self.iter.next();
          Some(Ok(Punctuator(LeftBracket, self.lo, self.hi)))
        }
        ']' => {
          self.iter.next();
          Some(Ok(Punctuator(RightBracket, self.lo, self.hi)))
        }
        '{' => {
          self.iter.next();
          Some(Ok(Punctuator(LeftBrace, self.lo, self.hi)))
        }
        '}' => {
          self.iter.next();
          Some(Ok(Punctuator(RightBrace, self.lo, self.hi)))
        }
        '|' => {
          self.iter.next();
          Some(Ok(Punctuator(Pipe, self.lo, self.hi)))
        }
        '.' => {
          if scan_spread(self) {
            Some(Ok(Punctuator(Spread, self.lo, self.hi)))
          } else {
            Some(Err("Unexpected character."))
          }
        }
        '_' | 'a'...'z' | 'A'...'Z' => {
          scan_name(self);
          Some(Ok(Name(&self.input[self.lo..self.hi], self.lo, self.hi)))
        }
        '-' | '0'...'9' => {
          match scan_number(self) {
            (false, false) => Some(Err("Invalid integer number.")),
            (false, true) => Some(Err("Invalid float number.")),
            (true, false) => Some(Ok(IntValue(&self.input[self.lo..self.hi], self.lo, self.hi))),
            (true, true) => Some(Ok(FloatValue(&self.input[self.lo..self.hi], self.lo, self.hi))),
          }
        }
        '"' => {
          match scan_string(self) {
            (false, _) => Some(Err("Unterminated string.")),
            (_, true) => Some(Err("Bad character escape sequence.")),
            _ => Some(Ok(StringValue(&self.input[self.lo..self.hi], self.lo, self.hi))),
          }
        }
        _ => Some(Err("Unexpected character.")),
      }
    }
    item
  }
}

#[cfg(test)]
mod tests {
  use super::Punctuator::*;
  use super::Token::*;
  use super::{Lexer, Token};

  fn test_next_token(lexer: &mut Lexer, expected: Token) {
    let next = lexer.next();
    assert_eq!(Some(Ok(expected)), next);
  }

  fn test_with_lex(input: &str, expeced: Token) {
    let mut lexer = Lexer::new(&input);
    test_next_token(&mut lexer, expeced);
  }

  fn test_str(input: &str, expeced: &str) {
    let len = expeced.len();
    test_with_lex(input, StringValue(expeced, 1, len + 1))
  }

  #[test]
  fn test_string() {
    test_str(r#""simple""#, r#"simple"#);
    test_str(r#"" white space ""#, r#" white space "#);
    test_str(r#""quote \"""#, r#"quote \""#);
    test_str(r#""slashes \\ \/""#, r#"slashes \\ \/"#);
    test_str(r#""unicode \u1234\u5678\u90AB\uCDEF""#,
             r#"unicode \u1234\u5678\u90AB\uCDEF"#);
  }

  #[test]
  fn test_name() {
    let mut lexer = Lexer::new("     name1    name2   \"simple\" \"  white space   \" other_name");
    test_next_token(&mut lexer, Name("name1", 5, 10));
    test_next_token(&mut lexer, Name("name2", 14, 19));
    test_next_token(&mut lexer, StringValue("simple", 23, 29));
    test_next_token(&mut lexer, StringValue("  white space   ", 32, 48));
    test_next_token(&mut lexer, Name("other_name", 50, 60));
    test_next_token(&mut lexer, Eof);
    assert_eq!(None, lexer.next());
  }

  #[test]
  fn test_number() {
    let mut lexer = Lexer::new("-9 0 9 -0 -9 1234 -1234 0.0 -0.0 1.0 -1.012 -0.101 1.0e2 -1.0E2 \
                                0.00e-002 -0.00E+002 9.1E+0");
    test_next_token(&mut lexer, IntValue("-9", 0, 2));
    test_next_token(&mut lexer, IntValue("0", 3, 4));
    test_next_token(&mut lexer, IntValue("9", 5, 6));
    test_next_token(&mut lexer, IntValue("-0", 7, 9));
    test_next_token(&mut lexer, IntValue("-9", 10, 12));
    test_next_token(&mut lexer, IntValue("1234", 13, 17));
    test_next_token(&mut lexer, IntValue("-1234", 18, 23));
    test_next_token(&mut lexer, FloatValue("0.0", 24, 27));
    test_next_token(&mut lexer, FloatValue("-0.0", 28, 32));
    test_next_token(&mut lexer, FloatValue("1.0", 33, 36));
    test_next_token(&mut lexer, FloatValue("-1.012", 37, 43));
    test_next_token(&mut lexer, FloatValue("-0.101", 44, 50));
    test_next_token(&mut lexer, FloatValue("1.0e2", 51, 56));
    test_next_token(&mut lexer, FloatValue("-1.0E2", 57, 63));
    test_next_token(&mut lexer, FloatValue("0.00e-002", 64, 73));
    test_next_token(&mut lexer, FloatValue("-0.00E+002", 74, 84));
    test_next_token(&mut lexer, FloatValue("9.1E+0", 85, 91));
    test_next_token(&mut lexer, Eof);
    assert_eq!(None, lexer.next());
  }

  #[test]
  fn test_symbol() {
    let mut lexer = Lexer::new("@ !  :$ =    [  {   (|] } )      ...");
    test_next_token(&mut lexer, Punctuator(At, 0, 0));
    test_next_token(&mut lexer, Punctuator(Bang, 2, 2));
    test_next_token(&mut lexer, Punctuator(Colon, 5, 5));
    test_next_token(&mut lexer, Punctuator(Dollar, 6, 6));
    test_next_token(&mut lexer, Punctuator(Equals, 8, 8));
    test_next_token(&mut lexer, Punctuator(LeftBracket, 13, 13));
    test_next_token(&mut lexer, Punctuator(LeftBrace, 16, 16));
    test_next_token(&mut lexer, Punctuator(LeftParen, 20, 20));
    test_next_token(&mut lexer, Punctuator(Pipe, 21, 21));
    test_next_token(&mut lexer, Punctuator(RightBracket, 22, 22));
    test_next_token(&mut lexer, Punctuator(RightBrace, 24, 24));
    test_next_token(&mut lexer, Punctuator(RightParen, 26, 26));
    test_next_token(&mut lexer, Punctuator(Spread, 33, 35));
    test_next_token(&mut lexer, Eof);
    assert_eq!(None, lexer.next());
  }
}
<commit_msg>feat: spread `+ 1` where needed<commit_after>
use std::str::CharIndices;
use std::iter::Peekable;

#[derive(PartialEq, Debug)]
pub enum Token<'a> {
  Eof,
  Punctuator(Punctuator, usize, usize),
  Name(&'a str, usize, usize),
  IntValue(&'a str, usize, usize),
  FloatValue(&'a str, usize, usize),
  StringValue(&'a str, usize, usize),
}

#[derive(PartialEq, Debug)]
pub enum Punctuator {
  Bang,
  Dollar,
  LeftParen,
  RightParen,
  Spread,
  Colon,
  Equals,
  At,
  LeftBracket,
  RightBracket,
  LeftBrace,
  RightBrace,
  Pipe,
}

macro_rules! take {
  ($lexer: ident, $($p: pat)|*) => ({
    let mut is_taken = false;
    if let Some(&(p, c)) = $lexer.iter.peek() {
      match c {
        $(
          $p => {
            $lexer.iter.next();
            $lexer.hi = p;
            is_taken = true;
          }
        )*
        _ => {}
      }
    }
    is_taken
  });
}

macro_rules! take_while {
  ($lexer: ident, $($p: pat)|*) => ({
    let mut is_taken = false;
    while let Some(&(p, c)) = $lexer.iter.peek() {
      match c {
        $(
          $p => {
            $lexer.iter.next();
            is_taken = true;
          }
        )*
        _ => {
          $lexer.hi = p;
          break;
        }
      }
    }
    is_taken
  });
}

macro_rules! take_while_not {
  ($lexer: ident, $($p: pat)|*) => ({
    let mut is_taken = false;
    while let Some(&(p, c)) = $lexer.iter.peek() {
      match c {
        $(
          $p => {
            $lexer.hi = p;
            break;
          }
        )*
        _ => {
            $lexer.iter.next();
            is_taken = true;
        }
      }
    }
    is_taken
  });
}

macro_rules! peek {
  ($lexer: ident, $($p: pat)|*) => ({
    let mut is_match = false;
    if let Some(&(_, c)) = $lexer.iter.peek() {
      match c {
        $(
          $p => {
            is_match = true;
          }
        )*
        _ => {}
      }
    }
    is_match
  });
}

macro_rules! take_eof {
  ($lexer: ident) => ({
    if $lexer.iter.peek().is_none() {
      $lexer.hi = $lexer.input_len;
      true
    } else {
      false
    }
  });
}

pub struct Lexer<'a> {
  input: &'a str,
  input_len: usize,
  iter: Peekable<CharIndices<'a>>,
  is_eof: bool,
  lo: usize,
  hi: usize,
}

impl<'a> Lexer<'a> {
  pub fn new(input: &'a str) -> Lexer<'a> {
    Lexer {
      input: input,
      input_len: input.len(),
      iter: input.char_indices().peekable(),
      is_eof: false,
      lo: 0,
      hi: 0,
    }
  }
}

fn skip_ignored_token(lexer: &mut Lexer) {
  loop {
    if take!(lexer, '#') {
      take_while_not!(lexer, '\r' | '\n');
    }
    if !take_while!(lexer, '\u{feff}' | ' ' | '\t' | '\r' | '\n' | ',') {
      break;
    }
  }
}

fn scan_spread(lexer: &mut Lexer) -> bool {
  if take!(lexer, '.') {
    if take!(lexer, '.') {
      if take!(lexer, '.') {
        return true;
      }
    }
  }
  return false;
}

fn scan_name(lexer: &mut Lexer) {
  take_while!(lexer, '_' | 'a'...'z' | 'A'...'Z' | '0'...'9');
  take_eof!(lexer);
}

// Return the raw string without unescape character
fn scan_string(lexer: &mut Lexer) -> (bool, bool) {
  let mut is_bad_escape = false;
  let mut is_terminated = false;
  if take!(lexer, '"') {
    lexer.lo = lexer.lo + 1;
  }
  loop {
    if take!(lexer, '\\') {
      if !take!(lexer, '\\' | '"' | 'b' | 'f' | 'n' | 'r' | 't' | '/' | 'u') {
        is_bad_escape = true;
        break;
      }
    }
    take_while_not!(lexer, '"' | '\\');
    if take!(lexer, '"') {
      is_terminated = true;
      break;
    }
  }
  (is_terminated, is_bad_escape)
}

// IntValue:   (+|-)?(0|[1-9][0-9]*)
// FloatValue: (+|-)?(0|[1-9][0-9]*)(\.[0-9]+)?((E|e)(+|-)?[0-9]+)?
fn scan_number(lexer: &mut Lexer) -> (bool, bool) {
  let mut is_float = false;
  take!(lexer, '+' | '-');
  // Integer part
  if take!(lexer, '1'...'9') {
    take_while!(lexer, '0'...'9');
    if take!(lexer, ' ' | '\t' | '\r' | '\n' | ',') || take_eof!(lexer) {
      return (true, is_float);
    }
  } else if take!(lexer, '0') {
    if take!(lexer, ' ' | '\t' | '\r' | '\n' | ',') || take_eof!(lexer) {
      return (true, is_float);
    }
  }
  // Fractional part
  if take!(lexer, '.') {
    if !take_while!(lexer, '0'...'9') {
      return (false, is_float);
    }
    is_float = true;
  }
  // Exponent part
  if !is_float && peek!(lexer, 'E' | 'e') {
    return (false, is_float);
  }
  if take!(lexer, 'E' | 'e') {
    if take!(lexer, '+' | '-') {
      if !take_while!(lexer, '0'...'9') {
        return (false, is_float);
      }
    } else {
      take_while!(lexer, '0'...'9');
    }
  }

  if take!(lexer, ' ' | '\t' | '\r' | '\n' | ',') || take_eof!(lexer) {
    return (true, is_float);
  }
  return (false, is_float);
}

impl<'a> Iterator for Lexer<'a> {
  type Item = Result<Token<'a>, &'a str>;
  fn next(&mut self) -> Option<Result<Token<'a>, &'a str>> {
    use self::Token::*;
    use self::Punctuator::*;

    if !self.is_eof && take_eof!(self) {
      self.is_eof = true;
      return Some(Ok(Token::Eof));
    }
    if self.is_eof {
      return None;
    }
    skip_ignored_token(self);

    let mut item = None;
    if let Some(&(p, c)) = self.iter.peek() {
      self.lo = p;
      self.hi = p + 1;
      item = match c {
        '!' => {
          self.iter.next();
          Some(Ok(Punctuator(Bang, self.lo, self.hi)))
        }
        '$' => {
          self.iter.next();
          Some(Ok(Punctuator(Dollar, self.lo, self.hi)))
        }
        '(' => {
          self.iter.next();
          Some(Ok(Punctuator(LeftParen, self.lo, self.hi)))
        }
        ')' => {
          self.iter.next();
          Some(Ok(Punctuator(RightParen, self.lo, self.hi)))
        }
        ':' => {
          self.iter.next();
          Some(Ok(Punctuator(Colon, self.lo, self.hi)))
        }
        '=' => {
          self.iter.next();
          Some(Ok(Punctuator(Equals, self.lo, self.hi)))
        }
        '@' => {
          self.iter.next();
          Some(Ok(Punctuator(At, self.lo, self.hi)))
        }
        '[' => {
          self.iter.next();
          Some(Ok(Punctuator(LeftBracket, self.lo, self.hi)))
        }
        ']' => {
          self.iter.next();
          Some(Ok(Punctuator(RightBracket, self.lo, self.hi)))
        }
        '{' => {
          self.iter.next();
          Some(Ok(Punctuator(LeftBrace, self.lo, self.hi)))
        }
        '}' => {
          self.iter.next();
          Some(Ok(Punctuator(RightBrace, self.lo, self.hi)))
        }
        '|' => {
          self.iter.next();
          Some(Ok(Punctuator(Pipe, self.lo, self.hi)))
        }
        '.' => {
          if scan_spread(self) {
            Some(Ok(Punctuator(Spread, self.lo, self.hi + 1)))
          } else {
            Some(Err("Unexpected character."))
          }
        }
        '_' | 'a'...'z' | 'A'...'Z' => {
          scan_name(self);
          Some(Ok(Name(&self.input[self.lo..self.hi], self.lo, self.hi)))
        }
        '-' | '0'...'9' => {
          match scan_number(self) {
            (false, false) => Some(Err("Invalid integer number.")),
            (false, true) => Some(Err("Invalid float number.")),
            (true, false) => Some(Ok(IntValue(&self.input[self.lo..self.hi], self.lo, self.hi))),
            (true, true) => Some(Ok(FloatValue(&self.input[self.lo..self.hi], self.lo, self.hi))),
          }
        }
        '"' => {
          match scan_string(self) {
            (false, _) => Some(Err("Unterminated string.")),
            (_, true) => Some(Err("Bad character escape sequence.")),
            _ => Some(Ok(StringValue(&self.input[self.lo..self.hi], self.lo, self.hi))),
          }
        }
        _ => Some(Err("Unexpected character.")),
      }
    }
    item
  }
}

#[cfg(test)]
mod tests {
  use super::Punctuator::*;
  use super::Token::*;
  use super::{Lexer, Token};

  fn test_next_token(lexer: &mut Lexer, expected: Token) {
    let next = lexer.next();
    assert_eq!(Some(Ok(expected)), next);
  }

  fn test_with_lex(input: &str, expeced: Token) {
    let mut lexer = Lexer::new(&input);
    test_next_token(&mut lexer, expeced);
  }

  fn test_str(input: &str, expeced: &str) {
    let len = expeced.len();
    test_with_lex(input, StringValue(expeced, 1, len + 1))
  }

  #[test]
  fn test_string() {
    test_str(r#""simple""#, r#"simple"#);
    test_str(r#"" white space ""#, r#" white space "#);
    test_str(r#""quote \"""#, r#"quote \""#);
    test_str(r#""slashes \\ \/""#, r#"slashes \\ \/"#);
    test_str(r#""unicode \u1234\u5678\u90AB\uCDEF""#,
             r#"unicode \u1234\u5678\u90AB\uCDEF"#);
  }

  #[test]
  fn test_name() {
    let mut lexer = Lexer::new("     name1    name2   \"simple\" \"  white space   \" other_name");
    test_next_token(&mut lexer, Name("name1", 5, 10));
    test_next_token(&mut lexer, Name("name2", 14, 19));
    test_next_token(&mut lexer, StringValue("simple", 23, 29));
    test_next_token(&mut lexer, StringValue("  white space   ", 32, 48));
    test_next_token(&mut lexer, Name("other_name", 50, 60));
    test_next_token(&mut lexer, Eof);
    assert_eq!(None, lexer.next());
  }

  #[test]
  fn test_number() {
    let mut lexer = Lexer::new("-9 0 9 -0 -9 1234 -1234 0.0 -0.0 1.0 -1.012 -0.101 1.0e2 -1.0E2 \
                                0.00e-002 -0.00E+002 9.1E+0");
    test_next_token(&mut lexer, IntValue("-9", 0, 2));
    test_next_token(&mut lexer, IntValue("0", 3, 4));
    test_next_token(&mut lexer, IntValue("9", 5, 6));
    test_next_token(&mut lexer, IntValue("-0", 7, 9));
    test_next_token(&mut lexer, IntValue("-9", 10, 12));
    test_next_token(&mut lexer, IntValue("1234", 13, 17));
    test_next_token(&mut lexer, IntValue("-1234", 18, 23));
    test_next_token(&mut lexer, FloatValue("0.0", 24, 27));
    test_next_token(&mut lexer, FloatValue("-0.0", 28, 32));
    test_next_token(&mut lexer, FloatValue("1.0", 33, 36));
    test_next_token(&mut lexer, FloatValue("-1.012", 37, 43));
    test_next_token(&mut lexer, FloatValue("-0.101", 44, 50));
    test_next_token(&mut lexer, FloatValue("1.0e2", 51, 56));
    test_next_token(&mut lexer, FloatValue("-1.0E2", 57, 63));
    test_next_token(&mut lexer, FloatValue("0.00e-002", 64, 73));
    test_next_token(&mut lexer, FloatValue("-0.00E+002", 74, 84));
    test_next_token(&mut lexer, FloatValue("9.1E+0", 85, 91));
    test_next_token(&mut lexer, Eof);
    assert_eq!(None, lexer.next());
  }

  #[test]
  fn test_symbol() {
    let mut lexer = Lexer::new("@ !  :$ =    [  {   (|] } )      ...");
    test_next_token(&mut lexer, Punctuator(At, 0, 1));
    test_next_token(&mut lexer, Punctuator(Bang, 2, 3));
    test_next_token(&mut lexer, Punctuator(Colon, 5, 6));
    test_next_token(&mut lexer, Punctuator(Dollar, 6, 7));
    test_next_token(&mut lexer, Punctuator(Equals, 8, 9));
    test_next_token(&mut lexer, Punctuator(LeftBracket, 13, 14));
    test_next_token(&mut lexer, Punctuator(LeftBrace, 16, 17));
    test_next_token(&mut lexer, Punctuator(LeftParen, 20, 21));
    test_next_token(&mut lexer, Punctuator(Pipe, 21, 22));
    test_next_token(&mut lexer, Punctuator(RightBracket, 22, 23));
    test_next_token(&mut lexer, Punctuator(RightBrace, 24, 25));
    test_next_token(&mut lexer, Punctuator(RightParen, 26, 27));
    test_next_token(&mut lexer, Punctuator(Spread, 33, 36));
    test_next_token(&mut lexer, Eof);
    assert_eq!(None, lexer.next());
  }
}
<|endoftext|>


<commit_before>use std::fmt::{mod, Show, Formatter};
use std::num::{Zero, cast};
use {success,Matcher,MatchResult};

pub struct CloseTo<T> {
  expected: T,
  epsilon: T
}

impl<T: Show> Show for CloseTo<T> {
  fn fmt(&self, f: &mut Formatter) -> fmt::Result {
      self.expected.fmt(f)
  }
}

impl<T : Float + Zero + PartialEq + Show> Matcher<T> for CloseTo<T> {
  fn matches(&self, actual: T) -> MatchResult {
    let d = (self.expected - actual).abs();

    let close = self.expected == actual
        || ((self.expected == Zero::zero() || actual == Zero::zero() || d < Float::min_pos_value(None)) &&
            d < self.epsilon * Float::min_pos_value(None))
        || d / (self.expected.abs() + actual.abs()) < self.epsilon;

    if close {
      success()
    }
    else {
      Err(format!("was {}", actual))
    }
  }
}

pub fn close_to<T: Float + Zero + PartialEq + NumCast + Show>(expected: T) -> CloseTo<T> {
    close_to_eps(expected, cast::<f32, T>(0.00001).unwrap())
}

pub fn close_to_eps<T: Float + Zero + PartialEq + Show>(expected: T, epsilon: T) -> CloseTo<T> {
  CloseTo { expected: expected, epsilon: epsilon }
}

#[cfg(test)]
mod test {
 use std::task;
  use {assert_that,is,close_to,close_to_eps};

  #[test]
  fn test_equality_of_floats() {
      let inf: f32 = Float::infinity();
      let nan: f32 = Float::nan();

    // Successful match
    assert_that(1.0f32, is(close_to(1.0)));
    assert_that(inf, is(close_to(inf)));
    assert_that(1e-40f32, is(close_to_eps(0.0, 0.01)));

    // Unsuccessful match
    assert!(task::try(proc() {
      assert_that(2.0, is(close_to(1.0f32)));
    }).is_err());
    assert!(task::try(proc() {
      assert_that(nan, is(close_to(nan)));
    }).is_err());
    assert!(task::try(proc() {
      assert_that(1e-40f32, is(close_to_eps(0.0, 0.000001)));
    }).is_err());
  }
}
<commit_msg>Adopting num reform<commit_after>use std::fmt::{mod, Show, Formatter};
use std::num::{Float, NumCast, cast};
use {success,Matcher,MatchResult};

pub struct CloseTo<T> {
  expected: T,
  epsilon: T
}

impl<T: Show> Show for CloseTo<T> {
  fn fmt(&self, f: &mut Formatter) -> fmt::Result {
      self.expected.fmt(f)
  }
}

impl<T : Float + PartialEq + Show> Matcher<T> for CloseTo<T> {
  fn matches(&self, actual: T) -> MatchResult {
    let d = (self.expected - actual).abs();

    let close = self.expected == actual
        || ((self.expected == Float::zero() || actual == Float::zero() || d < Float::min_pos_value(None)) &&
            d < self.epsilon * Float::min_pos_value(None))
        || d / (self.expected.abs() + actual.abs()) < self.epsilon;

    if close {
      success()
    }
    else {
      Err(format!("was {}", actual))
    }
  }
}

pub fn close_to<T: Float + PartialEq + NumCast + Show>(expected: T) -> CloseTo<T> {
    close_to_eps(expected, cast::<f32, T>(0.00001).unwrap())
}

pub fn close_to_eps<T: Float + PartialEq + Show>(expected: T, epsilon: T) -> CloseTo<T> {
  CloseTo { expected: expected, epsilon: epsilon }
}

#[cfg(test)]
mod test {
  use std::num::Float;
  use std::task;
  use {assert_that,is,close_to,close_to_eps};

  #[test]
  fn test_equality_of_floats() {
      let inf: f32 = Float::infinity();
      let nan: f32 = Float::nan();

    // Successful match
    assert_that(1.0f32, is(close_to(1.0)));
    assert_that(inf, is(close_to(inf)));
    assert_that(1e-40f32, is(close_to_eps(0.0, 0.01)));

    // Unsuccessful match
    assert!(task::try(proc() {
      assert_that(2.0, is(close_to(1.0f32)));
    }).is_err());
    assert!(task::try(proc() {
      assert_that(nan, is(close_to(nan)));
    }).is_err());
    assert!(task::try(proc() {
      assert_that(1e-40f32, is(close_to_eps(0.0, 0.000001)));
    }).is_err());
  }
}
<|endoftext|>


<commit_before>use mime::Mime;

header! {
    /// `Content-Type` header, defined in
    /// [RFC7231](http://tools.ietf.org/html/rfc7231#section-3.1.1.5)
    ///
    /// The `Content-Type` header field indicates the media type of the
    /// associated representation: either the representation enclosed in the
    /// message payload or the selected representation, as determined by the
    /// message semantics.  The indicated media type defines both the data
    /// format and how that data is intended to be processed by a recipient,
    /// within the scope of the received message semantics, after any content
    /// codings indicated by Content-Encoding are decoded.
    ///
    /// Although the `mime` crate allows the mime options to be any slice, this crate
    /// forces the use of Vec. This is to make sure the same header can't have more than 1 type. If
    /// this is an issue, it's possible to implement `Header` on a custom struct.
    ///
    /// # ABNF
    /// ```plain
    /// Content-Type = media-type
    /// ```
    ///
    /// # Example values
    /// * `text/html; charset=ISO-8859-4`
    ///
    /// # Examples
    /// ```
    /// use hyper::header::{Headers, ContentType};
    ///
    /// let mut headers = Headers::new();
    ///
    /// headers.set(
    ///     ContentType::json()
    /// );
    /// ```
    /// ```
    /// use hyper::header::{Headers, ContentType};
    /// use hyper::mime::{Mime, TopLevel, SubLevel, Attr, Value};
    ///
    /// let mut headers = Headers::new();
    ///
    /// headers.set(
    ///     ContentType(Mime(TopLevel::Text, SubLevel::Html,
    ///                      vec![(Attr::Charset, Value::Utf8)]))
    /// );
    /// ```
    (ContentType, "Content-Type") => [Mime]

    test_content_type {
        test_header!(
            test1,
            // FIXME: Should be b"text/html; charset=ISO-8859-4" but mime crate lowercases
            // the whole value so parsing and formatting the value gives a different result
            vec![b"text/html; charset=iso-8859-4"],
            Some(HeaderField(Mime(
                TopLevel::Text,
                SubLevel::Html,
                vec![(Attr::Charset, Value::Ext("iso-8859-4".to_owned()))]))));
    }
}

impl ContentType {
    /// A constructor  to easily create a `Content-Type: application/json` header.
    #[inline]
    pub fn json() -> ContentType {
        ContentType(mime!(Application/Json))
    }

    /// A constructor  to easily create a `Content-Type: text/plain; charset=utf-8` header.
    #[inline]
    pub fn plaintext() -> ContentType {
        ContentType(mime!(Text/Plain; Charset=Utf8))
    }

    /// A constructor  to easily create a `Content-Type: text/html; charset=utf-8` header.
    #[inline]
    pub fn html() -> ContentType {
        ContentType(mime!(Text/Html; Charset=Utf8))
    }

    /// A constructor  to easily create a `Content-Type: application/www-form-url-encoded` header.
    #[inline]
    pub fn form_url_encoded() -> ContentType {
        ContentType(mime!(Application/WwwFormUrlEncoded))
    }
    /// A constructor  to easily create a `Content-Type: image/jpeg` header.
    #[inline]
    pub fn jpeg() -> ContentType {
        ContentType(mime!(Image/Jpeg))
    }

    /// A constructor  to easily create a `Content-Type: image/png` header.
    #[inline]
    pub fn png() -> ContentType {
        ContentType(mime!(Image/Png))
    }
}

impl Eq for ContentType {}

bench_header!(bench, ContentType, { vec![b"application/json; charset=utf-8".to_vec()] });
<commit_msg>feat(headers): add ContentType::octet_stream() constructor<commit_after>use mime::Mime;

header! {
    /// `Content-Type` header, defined in
    /// [RFC7231](http://tools.ietf.org/html/rfc7231#section-3.1.1.5)
    ///
    /// The `Content-Type` header field indicates the media type of the
    /// associated representation: either the representation enclosed in the
    /// message payload or the selected representation, as determined by the
    /// message semantics.  The indicated media type defines both the data
    /// format and how that data is intended to be processed by a recipient,
    /// within the scope of the received message semantics, after any content
    /// codings indicated by Content-Encoding are decoded.
    ///
    /// Although the `mime` crate allows the mime options to be any slice, this crate
    /// forces the use of Vec. This is to make sure the same header can't have more than 1 type. If
    /// this is an issue, it's possible to implement `Header` on a custom struct.
    ///
    /// # ABNF
    /// ```plain
    /// Content-Type = media-type
    /// ```
    ///
    /// # Example values
    /// * `text/html; charset=ISO-8859-4`
    ///
    /// # Examples
    /// ```
    /// use hyper::header::{Headers, ContentType};
    ///
    /// let mut headers = Headers::new();
    ///
    /// headers.set(
    ///     ContentType::json()
    /// );
    /// ```
    /// ```
    /// use hyper::header::{Headers, ContentType};
    /// use hyper::mime::{Mime, TopLevel, SubLevel, Attr, Value};
    ///
    /// let mut headers = Headers::new();
    ///
    /// headers.set(
    ///     ContentType(Mime(TopLevel::Text, SubLevel::Html,
    ///                      vec![(Attr::Charset, Value::Utf8)]))
    /// );
    /// ```
    (ContentType, "Content-Type") => [Mime]

    test_content_type {
        test_header!(
            test1,
            // FIXME: Should be b"text/html; charset=ISO-8859-4" but mime crate lowercases
            // the whole value so parsing and formatting the value gives a different result
            vec![b"text/html; charset=iso-8859-4"],
            Some(HeaderField(Mime(
                TopLevel::Text,
                SubLevel::Html,
                vec![(Attr::Charset, Value::Ext("iso-8859-4".to_owned()))]))));
    }
}

impl ContentType {
    /// A constructor  to easily create a `Content-Type: application/json` header.
    #[inline]
    pub fn json() -> ContentType {
        ContentType(mime!(Application/Json))
    }

    /// A constructor  to easily create a `Content-Type: text/plain; charset=utf-8` header.
    #[inline]
    pub fn plaintext() -> ContentType {
        ContentType(mime!(Text/Plain; Charset=Utf8))
    }

    /// A constructor  to easily create a `Content-Type: text/html; charset=utf-8` header.
    #[inline]
    pub fn html() -> ContentType {
        ContentType(mime!(Text/Html; Charset=Utf8))
    }

    /// A constructor  to easily create a `Content-Type: application/www-form-url-encoded` header.
    #[inline]
    pub fn form_url_encoded() -> ContentType {
        ContentType(mime!(Application/WwwFormUrlEncoded))
    }
    /// A constructor  to easily create a `Content-Type: image/jpeg` header.
    #[inline]
    pub fn jpeg() -> ContentType {
        ContentType(mime!(Image/Jpeg))
    }

    /// A constructor  to easily create a `Content-Type: image/png` header.
    #[inline]
    pub fn png() -> ContentType {
        ContentType(mime!(Image/Png))
    }

    /// A constructor  to easily create a `Content-Type: application/octet-stream` header.
    #[inline]
    pub fn octet_stream() -> ContentType {
        ContentType(mime!(Application/OctetStream))
    }
}

impl Eq for ContentType {}

bench_header!(bench, ContentType, { vec![b"application/json; charset=utf-8".to_vec()] });
<|endoftext|>


<commit_before>use glium;
use glium::Surface;
use glium::index::PrimitiveType;

#[derive(Copy, Clone)]
struct Vertex {
    position: [f32; 2],
    tex_coords: [f32; 2],
}

implement_vertex!(Vertex, position, tex_coords);

pub struct GliumDrawer<'a, F: 'a> {
    display: &'a F,
    vertex_buffer: glium::VertexBuffer<Vertex>,
    index_buffer: glium::IndexBuffer<u16>,
    program: glium::Program,
}

impl<'a, F: glium::backend::Facade + 'a> GliumDrawer<'a, F> {
    pub fn new(display: &'a F) -> GliumDrawer<'a, F> {

        // building the vertex buffer, which contains all the vertices that we will draw
        let vertex_buffer = glium::VertexBuffer::new(display,
                                                     &[Vertex {
                                                           position: [0.0, 0.0],
                                                           tex_coords: [0.0, 0.0],
                                                       },
                                                       Vertex {
                                                           position: [0.0, 1.0],
                                                           tex_coords: [0.0, 1.0],
                                                       },
                                                       Vertex {
                                                           position: [1.0, 1.0],
                                                           tex_coords: [1.0, 1.0],
                                                       },
                                                       Vertex {
                                                           position: [1.0, 0.0],
                                                           tex_coords: [1.0, 0.0],
                                                       }]).unwrap();

        // building the index buffer
        let index_buffer =
            glium::IndexBuffer::new(display, PrimitiveType::TriangleStrip, &[1 as u16, 2, 0, 3]).unwrap();

        // compiling shaders and linking them together
        let program = program!(display,
			100 => {
				vertex: "
					#version 100
					uniform lowp mat4 matrix;
					attribute lowp vec2 position;
					attribute lowp vec2 tex_coords;
					varying lowp vec2 v_tex_coords;
					void main() {
						gl_Position = matrix * vec4(position, 0.0, 1.0);
						v_tex_coords = tex_coords;
					}
				",

				fragment: "
					#version 100
					uniform lowp sampler2D tex;
					varying lowp vec2 v_tex_coords;
					void main() {
	                    lowp vec4 color = texture2D(tex, v_tex_coords);
						gl_FragColor.r = color.z;
                        gl_FragColor.g = color.y;
                        gl_FragColor.b = color.x;
                        gl_FragColor.a = color.w;
					}
				",
			},
        ).unwrap();

        GliumDrawer {
            display,
            vertex_buffer,
            index_buffer,
            program,
        }
    }

    pub fn draw(&self, target: &mut glium::Frame, contents: &[u8], surface_dimensions: (u32, u32),
                surface_location: (i32, i32), screen_size: (u32, u32)) {

        let image = glium::texture::RawImage2d {
            data: contents.into(),
            width: surface_dimensions.0,
            height: surface_dimensions.1,
            format: glium::texture::ClientFormat::U8U8U8U8,
        };
        let opengl_texture = glium::texture::CompressedSrgbTexture2d::new(self.display, image).unwrap();

        let xscale = 2.0 * (surface_dimensions.0 as f32) / (screen_size.0 as f32);
        let yscale = -2.0 * (surface_dimensions.1 as f32) / (screen_size.1 as f32);

        let x = 2.0 * (surface_location.0 as f32) / (screen_size.0 as f32) - 1.0;
        let y = 1.0 - 2.0 * (surface_location.1 as f32) / (screen_size.1 as f32);

        let uniforms =
            uniform! {
            matrix: [
                [xscale,   0.0  , 0.0, 0.0],
                [  0.0 , yscale , 0.0, 0.0],
                [  0.0 ,   0.0  , 1.0, 0.0],
                [   x  ,    y   , 0.0, 1.0]
            ],
            tex: &opengl_texture
        };

        target
            .draw(&self.vertex_buffer,
                  &self.index_buffer,
                  &self.program,
                  &uniforms,
                  &Default::default())
            .unwrap();

    }
}
<commit_msg>example: use Texture2d to have correct gamma correction<commit_after>use glium;
use glium::Surface;
use glium::index::PrimitiveType;

#[derive(Copy, Clone)]
struct Vertex {
    position: [f32; 2],
    tex_coords: [f32; 2],
}

implement_vertex!(Vertex, position, tex_coords);

pub struct GliumDrawer<'a, F: 'a> {
    display: &'a F,
    vertex_buffer: glium::VertexBuffer<Vertex>,
    index_buffer: glium::IndexBuffer<u16>,
    program: glium::Program,
}

impl<'a, F: glium::backend::Facade + 'a> GliumDrawer<'a, F> {
    pub fn new(display: &'a F) -> GliumDrawer<'a, F> {

        // building the vertex buffer, which contains all the vertices that we will draw
        let vertex_buffer = glium::VertexBuffer::new(display,
                                                     &[Vertex {
                                                           position: [0.0, 0.0],
                                                           tex_coords: [0.0, 0.0],
                                                       },
                                                       Vertex {
                                                           position: [0.0, 1.0],
                                                           tex_coords: [0.0, 1.0],
                                                       },
                                                       Vertex {
                                                           position: [1.0, 1.0],
                                                           tex_coords: [1.0, 1.0],
                                                       },
                                                       Vertex {
                                                           position: [1.0, 0.0],
                                                           tex_coords: [1.0, 0.0],
                                                       }]).unwrap();

        // building the index buffer
        let index_buffer =
            glium::IndexBuffer::new(display, PrimitiveType::TriangleStrip, &[1 as u16, 2, 0, 3]).unwrap();

        // compiling shaders and linking them together
        let program = program!(display,
			100 => {
				vertex: "
					#version 100
					uniform lowp mat4 matrix;
					attribute lowp vec2 position;
					attribute lowp vec2 tex_coords;
					varying lowp vec2 v_tex_coords;
					void main() {
						gl_Position = matrix * vec4(position, 0.0, 1.0);
						v_tex_coords = tex_coords;
					}
				",

				fragment: "
					#version 100
					uniform lowp sampler2D tex;
					varying lowp vec2 v_tex_coords;
					void main() {
	                    lowp vec4 color = texture2D(tex, v_tex_coords);
						gl_FragColor.r = color.z;
                        gl_FragColor.g = color.y;
                        gl_FragColor.b = color.x;
                        gl_FragColor.a = color.w;
					}
				",
			},
        ).unwrap();

        GliumDrawer {
            display,
            vertex_buffer,
            index_buffer,
            program,
        }
    }

    pub fn draw(&self, target: &mut glium::Frame, contents: &[u8], surface_dimensions: (u32, u32),
                surface_location: (i32, i32), screen_size: (u32, u32)) {

        let image = glium::texture::RawImage2d {
            data: contents.into(),
            width: surface_dimensions.0,
            height: surface_dimensions.1,
            format: glium::texture::ClientFormat::U8U8U8U8,
        };
        let opengl_texture = glium::texture::Texture2d::new(self.display, image).unwrap();

        let xscale = 2.0 * (surface_dimensions.0 as f32) / (screen_size.0 as f32);
        let yscale = -2.0 * (surface_dimensions.1 as f32) / (screen_size.1 as f32);

        let x = 2.0 * (surface_location.0 as f32) / (screen_size.0 as f32) - 1.0;
        let y = 1.0 - 2.0 * (surface_location.1 as f32) / (screen_size.1 as f32);

        let uniforms =
            uniform! {
            matrix: [
                [xscale,   0.0  , 0.0, 0.0],
                [  0.0 , yscale , 0.0, 0.0],
                [  0.0 ,   0.0  , 1.0, 0.0],
                [   x  ,    y   , 0.0, 1.0]
            ],
            tex: &opengl_texture
        };

        target
            .draw(&self.vertex_buffer,
                  &self.index_buffer,
                  &self.program,
                  &uniforms,
                  &Default::default())
            .unwrap();

    }
}
<|endoftext|>