<commit_before>#![crate_name = "uu_env"]
/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

/* last synced with: env (GNU coreutils) 8.13 */

#[macro_use]
extern crate uucore;

use std::env;
use std::io::{stdout, Write};
use std::process::Command;

static NAME: &str = "env";
static SYNTAX: &str = "[OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]";
static SUMMARY: &str = "Set each NAME to VALUE in the environment and run COMMAND";
static LONG_HELP: &str = "
 A mere - implies -i. If no COMMAND, print the resulting environment
";

struct Options {
    ignore_env: bool,
    null: bool,
    unsets: Vec<String>,
    sets: Vec<(String, String)>,
    program: Vec<String>,
}

// print name=value env pairs on screen
// if null is true, separate pairs with a \0, \n otherwise
fn print_env(null: bool) {
    for (n, v) in env::vars() {
        print!("{}={}{}", n, v, if null { '\0' } else { '\n' });
    }
}

pub fn uumain(args: Vec<String>) -> i32 {
    let mut core_opts = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP);
    core_opts
        .optflag("i", "ignore-environment", "start with an empty environment")
        .optflag(
            "0",
            "null",
            "end each output line with a 0 byte rather than newline (only valid when printing the environment)",
        )
        .optopt("u", "unset", "remove variable from the environment", "NAME");

    let mut opts = Box::new(Options {
        ignore_env: false,
        null: false,
        unsets: vec![],
        sets: vec![],
        program: vec![],
    });

    let mut wait_cmd = false;
    let mut iter = args.iter();
    iter.next(); // skip program
    let mut item = iter.next();

    // the for loop doesn't work here,
    // because we need sometimes to read 2 items forward,
    // and the iter can't be borrowed twice
    while item != None {
        let opt = item.unwrap();

        if wait_cmd {
            // we still accept NAME=VAL here but not other options
            let mut sp = opt.splitn(2, '=');
            let name = sp.next();
            let value = sp.next();

            match (name, value) {
                (Some(n), Some(v)) => {
                    opts.sets.push((n.to_owned(), v.to_owned()));
                }
                _ => {
                    // read the program now
                    opts.program.push(opt.to_owned());
                    break;
                }
            }
        } else if opt.starts_with("--") {
            match opt.as_ref() {
                "--help" => {
                    core_opts.parse(vec![String::new(), String::from("--help")]);
                    return 0;
                }
                "--version" => {
                    core_opts.parse(vec![String::new(), String::from("--version")]);
                    return 0;
                }

                "--ignore-environment" => opts.ignore_env = true,
                "--null" => opts.null = true,
                "--unset" => {
                    let var = iter.next();

                    match var {
                        None => eprintln!("{}: this option requires an argument: {}", NAME, opt),
                        Some(s) => opts.unsets.push(s.to_owned()),
                    }
                }

                _ => {
                    eprintln!("{}: invalid option \"{}\"", NAME, *opt);
                    eprintln!("Type \"{} --help\" for detailed information", NAME);
                    return 1;
                }
            }
        } else if opt.starts_with("-") {
            if opt.len() == 1 {
                // implies -i and stop parsing opts
                wait_cmd = true;
                opts.ignore_env = true;
                continue;
            }

            let mut chars = opt.chars();
            chars.next();

            for c in chars {
                // short versions of options
                match c {
                    'i' => opts.ignore_env = true,
                    '0' => opts.null = true,
                    'u' => {
                        let var = iter.next();

                        match var {
                            None => eprintln!("{}: this option requires an argument: {}", NAME, opt),
                            Some(s) => opts.unsets.push(s.to_owned()),
                        }
                    }
                    _ => {
                        eprintln!("{}: illegal option -- {}", NAME, c);
                        eprintln!("Type \"{} --help\" for detailed information", NAME);
                        return 1;
                    }
                }
            }
        } else {
            // is it a NAME=VALUE like opt ?
            let mut sp = opt.splitn(2, '=');
            let name = sp.next();
            let value = sp.next();

            match (name, value) {
                (Some(n), Some(v)) => {
                    // yes
                    opts.sets.push((n.to_owned(), v.to_owned()));
                    wait_cmd = true;
                }
                // no, its a program-like opt
                _ => {
                    if opts.null {
                        eprintln!("{}: cannot specify --null (-0) with command", NAME);
                        eprintln!("Type \"{} --help\" for detailed information", NAME);
                        return 1;
                    }
                    opts.program.push(opt.clone());
                    break;
                }
            }
        }

        item = iter.next();
    }

    // read program arguments
    for opt in iter {
        if opts.null {
            eprintln!("{}: cannot specify --null (-0) with command", NAME);
            eprintln!("Type \"{} --help\" for detailed information", NAME);
            return 1;
        }
        opts.program.push(opt.clone())
    }

    if opts.ignore_env {
        for (ref name, _) in env::vars() {
            env::remove_var(name);
        }
    }

    for name in &opts.unsets {
        env::remove_var(name);
    }

    for &(ref name, ref val) in &opts.sets {
        env::set_var(name, val);
    }

    if !opts.program.is_empty() {
        let prog = opts.program[0].clone();
        let args = &opts.program[1..];
        match Command::new(prog).args(args).status() {
            Ok(exit) => {
                return if exit.success() {
                    0
                } else {
                    exit.code().unwrap()
                }
            }
            Err(_) => return 1,
        }
    } else {
        // no program provided
        print_env(opts.null);
        return_if_err!(1, stdout().flush());
    }

    0
}
<commit_msg>env: enhance support for windows commands (BAT/CMD, builtins)<commit_after>#![crate_name = "uu_env"]
/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

/* last synced with: env (GNU coreutils) 8.13 */

#[macro_use]
extern crate uucore;

use std::env;
use std::io::{stdout, Write};
use std::process::Command;

static NAME: &str = "env";
static SYNTAX: &str = "[OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]";
static SUMMARY: &str = "Set each NAME to VALUE in the environment and run COMMAND";
static LONG_HELP: &str = "
 A mere - implies -i. If no COMMAND, print the resulting environment
";

struct Options {
    ignore_env: bool,
    null: bool,
    unsets: Vec<String>,
    sets: Vec<(String, String)>,
    program: Vec<String>,
}

// print name=value env pairs on screen
// if null is true, separate pairs with a \0, \n otherwise
fn print_env(null: bool) {
    for (n, v) in env::vars() {
        print!("{}={}{}", n, v, if null { '\0' } else { '\n' });
    }
}

#[cfg(not(windows))]
fn build_command(mut args: Vec<String>) -> (String, Vec<String>) {
    (args.remove(0), args)
}

#[cfg(windows)]
fn build_command(mut args: Vec<String>) -> (String, Vec<String>) {
    args.insert(0, "/d/c".to_string());
    (env::var("ComSpec").unwrap_or("cmd".to_string()), args)
}

pub fn uumain(args: Vec<String>) -> i32 {
    let mut core_opts = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP);
    core_opts
        .optflag("i", "ignore-environment", "start with an empty environment")
        .optflag(
            "0",
            "null",
            "end each output line with a 0 byte rather than newline (only valid when printing the environment)",
        )
        .optopt("u", "unset", "remove variable from the environment", "NAME");

    let mut opts = Box::new(Options {
        ignore_env: false,
        null: false,
        unsets: vec![],
        sets: vec![],
        program: vec![],
    });

    let mut wait_cmd = false;
    let mut iter = args.iter();
    iter.next(); // skip program
    let mut item = iter.next();

    // the for loop doesn't work here,
    // because we need sometimes to read 2 items forward,
    // and the iter can't be borrowed twice
    while item != None {
        let opt = item.unwrap();

        if wait_cmd {
            // we still accept NAME=VAL here but not other options
            let mut sp = opt.splitn(2, '=');
            let name = sp.next();
            let value = sp.next();

            match (name, value) {
                (Some(n), Some(v)) => {
                    opts.sets.push((n.to_owned(), v.to_owned()));
                }
                _ => {
                    // read the program now
                    opts.program.push(opt.to_owned());
                    break;
                }
            }
        } else if opt.starts_with("--") {
            match opt.as_ref() {
                "--help" => {
                    core_opts.parse(vec![String::new(), String::from("--help")]);
                    return 0;
                }
                "--version" => {
                    core_opts.parse(vec![String::new(), String::from("--version")]);
                    return 0;
                }

                "--ignore-environment" => opts.ignore_env = true,
                "--null" => opts.null = true,
                "--unset" => {
                    let var = iter.next();

                    match var {
                        None => eprintln!("{}: this option requires an argument: {}", NAME, opt),
                        Some(s) => opts.unsets.push(s.to_owned()),
                    }
                }

                _ => {
                    eprintln!("{}: invalid option \"{}\"", NAME, *opt);
                    eprintln!("Type \"{} --help\" for detailed information", NAME);
                    return 1;
                }
            }
        } else if opt.starts_with("-") {
            if opt.len() == 1 {
                // implies -i and stop parsing opts
                wait_cmd = true;
                opts.ignore_env = true;
                continue;
            }

            let mut chars = opt.chars();
            chars.next();

            for c in chars {
                // short versions of options
                match c {
                    'i' => opts.ignore_env = true,
                    '0' => opts.null = true,
                    'u' => {
                        let var = iter.next();

                        match var {
                            None => eprintln!("{}: this option requires an argument: {}", NAME, opt),
                            Some(s) => opts.unsets.push(s.to_owned()),
                        }
                    }
                    _ => {
                        eprintln!("{}: illegal option -- {}", NAME, c);
                        eprintln!("Type \"{} --help\" for detailed information", NAME);
                        return 1;
                    }
                }
            }
        } else {
            // is it a NAME=VALUE like opt ?
            let mut sp = opt.splitn(2, '=');
            let name = sp.next();
            let value = sp.next();

            match (name, value) {
                (Some(n), Some(v)) => {
                    // yes
                    opts.sets.push((n.to_owned(), v.to_owned()));
                    wait_cmd = true;
                }
                // no, its a program-like opt
                _ => {
                    if opts.null {
                        eprintln!("{}: cannot specify --null (-0) with command", NAME);
                        eprintln!("Type \"{} --help\" for detailed information", NAME);
                        return 1;
                    }
                    opts.program.push(opt.clone());
                    break;
                }
            }
        }

        item = iter.next();
    }

    // read program arguments
    for opt in iter {
        if opts.null {
            eprintln!("{}: cannot specify --null (-0) with command", NAME);
            eprintln!("Type \"{} --help\" for detailed information", NAME);
            return 1;
        }
        opts.program.push(opt.clone())
    }

    if opts.ignore_env {
        for (ref name, _) in env::vars() {
            env::remove_var(name);
        }
    }

    for name in &opts.unsets {
        env::remove_var(name);
    }

    for &(ref name, ref val) in &opts.sets {
        env::set_var(name, val);
    }

    if !opts.program.is_empty() {
        let (prog, args) = build_command(opts.program);
        match Command::new(prog).args(args).status() {
            Ok(exit) => {
                return if exit.success() {
                    0
                } else {
                    exit.code().unwrap()
                }
            }
            Err(_) => return 1,
        }
    } else {
        // no program provided
        print_env(opts.null);
        return_if_err!(1, stdout().flush());
    }

    0
}
<|endoftext|>


<commit_before>use scaii_defs::{Backend, BackendSupported, Module};
use scaii_defs::protos::{MultiMessage, RustFfiConfig, ScaiiPacket};

use std::error::Error;
use std::ops::{Deref, DerefMut};

use super::LoadedAs;

pub fn init_ffi(args: RustFfiConfig) -> Result<LoadedAs, Box<Error>> {
    use libloading::Library;
    use scaii_defs::protos::init_as::InitAs;
    use scaii_defs::protos::ModuleInit;

    let mu = &::internal::OPEN_LIBS;
    {
        let mut lib_map = mu.lock()?;
        let plugin_path = args.plugin_path.clone();

        //rclib = rust-call lib
        let lib = lib_map
            .entry(plugin_path.clone())
            .or_insert(Library::new(&plugin_path)?);

        match args.clone()
            .init_as
            .init_as
            .ok_or_else::<Box<Error>, _>(|| {
                From::from(format!("Malformed InitAs field in RustFfi {:?}", args))
            })? {
            InitAs::Backend(_) => {
                let lib = unsafe { lib.get::<fn() -> Box<Backend>>(b"new_backend\0")? };
                Ok(LoadedAs::Backend(Box::new(RustDynamicBackend {
                    backend: lib(),
                    plugin_path: plugin_path,
                })))
            }
            InitAs::Module(ModuleInit { name }) => {
                let lib = unsafe { lib.get::<fn(&str) -> Box<Module>>(b"new\0")? };
                Ok(LoadedAs::Module(
                    Box::new(RustDynamicModule {
                        module: lib(&name),
                        plugin_path: plugin_path,
                    }),
                    name,
                ))
            }
        }
    }
}

/// A backend loaded using FFI and
/// Rust calling conventions. See the
/// `Module` trait in `scaii_defs` for API info.
struct RustDynamicBackend {
    backend: Box<Backend>,
    pub plugin_path: String,
}

impl RustDynamicBackend {}

impl Deref for RustDynamicBackend {
    type Target = Backend;
    fn deref(&self) -> &Self::Target {
        &*self.backend
    }
}

impl DerefMut for RustDynamicBackend {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut *self.backend
    }
}

impl Module for RustDynamicBackend {
    fn process_msg(&mut self, msg: &ScaiiPacket) -> Result<(), Box<Error>> {
        self.backend.process_msg(msg)
    }

    fn get_messages(&mut self) -> MultiMessage {
        self.backend.get_messages()
    }
}

impl Backend for RustDynamicBackend {
    fn supported_behavior(&self) -> BackendSupported {
        self.backend.supported_behavior()
    }

    fn serialize(&mut self, into: Option<Vec<u8>>) -> Result<Vec<u8>, Box<Error>> {
        self.backend.serialize(into)
    }

    fn deserialize(&mut self, buf: &[u8]) -> Result<(), Box<Error>> {
        self.backend.deserialize(buf)
    }

    fn serialize_diverging(&mut self, into: Option<Vec<u8>>) -> Result<Vec<u8>, Box<Error>> {
        self.backend.serialize_diverging(into)
    }

    fn deserialize_diverging(&mut self, buf: &[u8]) -> Result<(), Box<Error>> {
        self.backend.deserialize_diverging(buf)
    }
}

struct RustDynamicModule {
    module: Box<Module>,
    pub plugin_path: String,
}

impl Deref for RustDynamicModule {
    type Target = Module;
    fn deref(&self) -> &Self::Target {
        &*self.module
    }
}

impl DerefMut for RustDynamicModule {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut *self.module
    }
}

impl Module for RustDynamicModule {
    fn process_msg(&mut self, msg: &ScaiiPacket) -> Result<(), Box<Error>> {
        self.module.process_msg(msg)
    }

    fn get_messages(&mut self) -> MultiMessage {
        self.module.get_messages()
    }
}

#[test]
fn load_destroy() {
    use scaii_defs::protos::{BackendInit, InitAs};
    use scaii_defs::protos::init_as;

    let args = RustFfiConfig {
        init_as: InitAs {
            init_as: Some(init_as::InitAs::Backend(BackendInit {})),
        },
        plugin_path: "../../sky-rts/backend/target/debug/backend.dll".to_string(),
    };

    init_ffi(args).unwrap();

    println!("Initialized")
}
<commit_msg>Change plugin path to be relative<commit_after>use scaii_defs::{Backend, BackendSupported, Module};
use scaii_defs::protos::{MultiMessage, RustFfiConfig, ScaiiPacket};

use std::error::Error;
use std::ops::{Deref, DerefMut};

use super::LoadedAs;

pub fn init_ffi(args: RustFfiConfig) -> Result<LoadedAs, Box<Error>> {
    use std::env;
    use libloading::Library;
    use scaii_defs::protos::init_as::InitAs;
    use scaii_defs::protos::ModuleInit;

    let mu = &::internal::OPEN_LIBS;
    {
        let mut lib_map = mu.lock()?;
        let plugin_path = format!(
            "{}/.scaii/{}",
            env::var("HOME").expect("No home dir?"),
            args.plugin_path,
        );

        //rclib = rust-call lib
        let lib = lib_map
            .entry(plugin_path.clone())
            .or_insert(Library::new(&plugin_path).expect("Invalid library path"));

        match args.clone()
            .init_as
            .init_as
            .ok_or_else::<Box<Error>, _>(|| {
                From::from(format!("Malformed InitAs field in RustFfi {:?}", args))
            })? {
            InitAs::Backend(_) => {
                let lib = unsafe { lib.get::<fn() -> Box<Backend>>(b"new_backend\0")? };
                Ok(LoadedAs::Backend(Box::new(RustDynamicBackend {
                    backend: lib(),
                    plugin_path: plugin_path,
                })))
            }
            InitAs::Module(ModuleInit { name }) => {
                let lib = unsafe { lib.get::<fn(&str) -> Box<Module>>(b"new\0")? };
                Ok(LoadedAs::Module(
                    Box::new(RustDynamicModule {
                        module: lib(&name),
                        plugin_path: plugin_path,
                    }),
                    name,
                ))
            }
        }
    }
}

/// A backend loaded using FFI and
/// Rust calling conventions. See the
/// `Module` trait in `scaii_defs` for API info.
struct RustDynamicBackend {
    backend: Box<Backend>,
    pub plugin_path: String,
}

impl RustDynamicBackend {}

impl Deref for RustDynamicBackend {
    type Target = Backend;
    fn deref(&self) -> &Self::Target {
        &*self.backend
    }
}

impl DerefMut for RustDynamicBackend {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut *self.backend
    }
}

impl Module for RustDynamicBackend {
    fn process_msg(&mut self, msg: &ScaiiPacket) -> Result<(), Box<Error>> {
        self.backend.process_msg(msg)
    }

    fn get_messages(&mut self) -> MultiMessage {
        self.backend.get_messages()
    }
}

impl Backend for RustDynamicBackend {
    fn supported_behavior(&self) -> BackendSupported {
        self.backend.supported_behavior()
    }

    fn serialize(&mut self, into: Option<Vec<u8>>) -> Result<Vec<u8>, Box<Error>> {
        self.backend.serialize(into)
    }

    fn deserialize(&mut self, buf: &[u8]) -> Result<(), Box<Error>> {
        self.backend.deserialize(buf)
    }

    fn serialize_diverging(&mut self, into: Option<Vec<u8>>) -> Result<Vec<u8>, Box<Error>> {
        self.backend.serialize_diverging(into)
    }

    fn deserialize_diverging(&mut self, buf: &[u8]) -> Result<(), Box<Error>> {
        self.backend.deserialize_diverging(buf)
    }
}

struct RustDynamicModule {
    module: Box<Module>,
    pub plugin_path: String,
}

impl Deref for RustDynamicModule {
    type Target = Module;
    fn deref(&self) -> &Self::Target {
        &*self.module
    }
}

impl DerefMut for RustDynamicModule {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut *self.module
    }
}

impl Module for RustDynamicModule {
    fn process_msg(&mut self, msg: &ScaiiPacket) -> Result<(), Box<Error>> {
        self.module.process_msg(msg)
    }

    fn get_messages(&mut self) -> MultiMessage {
        self.module.get_messages()
    }
}

#[test]
fn load_destroy() {
    use scaii_defs::protos::{BackendInit, InitAs};
    use scaii_defs::protos::init_as;

    let args = RustFfiConfig {
        init_as: InitAs {
            init_as: Some(init_as::InitAs::Backend(BackendInit {})),
        },
        plugin_path: "../../sky-rts/backend/target/debug/backend.dll".to_string(),
    };

    init_ffi(args).unwrap();

    println!("Initialized")
}
<|endoftext|>


<commit_before>macro_rules! impl_uint_arith {
    ($(($name:ident, $n:ident)),+) => {
        $( impl<const LANES: usize> $name<LANES> where Self: crate::LanesAtMost32 {

            /// Lanewise saturating add.
            ///
            /// # Examples
            /// ```
            /// # use core_simd::*;
            #[doc = concat!("# use core::", stringify!($n), "::MAX;")]
            #[doc = concat!("let x = ", stringify!($name), "::from_array([2, 1, 0, MAX]);")]
            #[doc = concat!("let max = ", stringify!($name), "::splat(MAX);")]
            /// let unsat = x + max;
            /// let sat = x.saturating_add(max);
            /// assert_eq!(x - 1, unsat);
            /// assert_eq!(sat, max);
            /// ```
            #[inline]
            pub fn saturating_add(self, second: Self) -> Self {
                unsafe { crate::intrinsics::simd_saturating_add(self, second) }
            }

            /// Lanewise saturating subtract.
            ///
            /// # Examples
            /// ```
            /// # use core_simd::*;
            #[doc = concat!("# use core::", stringify!($n), "::MAX;")]
            #[doc = concat!("let x = ", stringify!($name), "::from_array([2, 1, 0, MAX]);")]
            #[doc = concat!("let max = ", stringify!($name), "::splat(MAX);")]
            /// let unsat = x - max;
            /// let sat = x.saturating_sub(max);
            /// assert_eq!(unsat, x + 1);
            #[doc = concat!("assert_eq!(sat, ", stringify!($name), "::splat(0));")]
            #[inline]
            pub fn saturating_sub(self, second: Self) -> Self {
                unsafe { crate::intrinsics::simd_saturating_sub(self, second) }
            }
        })+
    }
}

macro_rules! impl_int_arith {
    ($(($name:ident, $n:ident)),+) => {
        $( impl<const LANES: usize> $name<LANES> where Self: crate::LanesAtMost32 {

            /// Lanewise saturating add.
            ///
            /// # Examples
            /// ```
            /// # use core_simd::*;
            #[doc = concat!("# use core::", stringify!($n), "::{MIN, MAX};")]
            #[doc = concat!("let x = ", stringify!($name), "::from_array([MIN, 0, 1, MAX]);")]
            #[doc = concat!("let max = ", stringify!($name), "::splat(MAX);")]
            /// let unsat = x + max;
            /// let sat = x.saturating_add(max);
            #[doc = concat!("assert_eq!(unsat, ", stringify!($name), "::from_array([-1, MAX, MIN, -2]));")]
            #[doc = concat!("assert_eq!(sat, ", stringify!($name), "::from_array([-1, MAX, MAX, MAX]));")]
            /// ```
            #[inline]
            pub fn saturating_add(self, second: Self) -> Self {
                unsafe { crate::intrinsics::simd_saturating_add(self, second) }
            }

            /// Lanewise saturating subtract.
            ///
            /// # Examples
            /// ```
            /// # use core_simd::*;
            #[doc = concat!("# use core::", stringify!($n), "::{MIN, MAX};")]
            #[doc = concat!("let x = ", stringify!($name), "::from_array([MIN, -2, -1, MAX]);")]
            #[doc = concat!("let max = ", stringify!($name), "::splat(MAX);")]
            /// let unsat = x - max;
            /// let sat = x.saturating_sub(max);
            #[doc = concat!("assert_eq!(unsat, ", stringify!($name), "::from_array([1, MAX, MIN, 0]));")]
            #[doc = concat!("assert_eq!(sat, ", stringify!($name), "::from_array([MIN, MIN, MIN, 0]));")]
            #[inline]
            pub fn saturating_sub(self, second: Self) -> Self {
                unsafe { crate::intrinsics::simd_saturating_sub(self, second) }
            }

            /// Lanewise saturating absolute value, implemented in Rust.
            /// As abs(), except the MIN value becomes MAX instead of itself.
            ///
            /// # Examples
            /// ```
            /// # use core_simd::*;
            #[doc = concat!("# use core::", stringify!($n), "::{MIN, MAX};")]
            #[doc = concat!("let x = ", stringify!($name), "::from_array([MIN, -2, 0, 3]);")]
            /// let abs = x.saturating_abs();
            #[doc = concat!("assert_eq!(abs, ", stringify!($name), "::from_array([MAX, 2, 0, 3]));")]
            /// ```
            #[inline]
            pub fn saturating_abs(self) -> Self {
                // arith shift for -1 or 0 mask based on sign bit, giving 2s complement
                const SHR: $n = <$n>::BITS as $n - 1;
                let m = self >> SHR;
                (self^m).saturating_sub(m)
            }

            /// Lanewise saturating negation, implemented in Rust.
            /// As neg(), except the MIN value becomes MAX instead of itself.
            ///
            /// # Examples
            /// ```
            /// # use core_simd::*;
            #[doc = concat!("# use core::", stringify!($n), "::{MIN, MAX};")]
            #[doc = concat!("let x = ", stringify!($name), "::from_array([MIN, -2, 3, MAX]);")]
            /// let unsat = -x;
            /// let sat = x.saturating_neg();
            #[doc = concat!("assert_eq!(unsat, ", stringify!($name), "::from_array([MIN, 2, -3, MIN + 1]));")]
            #[doc = concat!("assert_eq!(sat, ", stringify!($name), "::from_array([MAX, 2, -3, MIN + 1]));")]
            /// ```
            #[inline]
            pub fn saturating_neg(self) -> Self {
                Self::splat(0).saturating_sub(self)
            }
        })+
    }
}

use crate::vector::*;

impl_uint_arith! { (SimdU8, u8), (SimdU16, u16), (SimdU32, u32), (SimdU64, u64), (SimdU128, u128), (SimdUsize, usize) }
impl_int_arith! { (SimdI8, i8), (SimdI16, i16), (SimdI32, i32), (SimdI64, i64), (SimdI128, i128), (SimdIsize, isize) }
<commit_msg>Finish fixing up abs docs<commit_after>macro_rules! impl_uint_arith {
    ($(($name:ident, $n:ident)),+) => {
        $( impl<const LANES: usize> $name<LANES> where Self: crate::LanesAtMost32 {

            /// Lanewise saturating add.
            ///
            /// # Examples
            /// ```
            /// # use core_simd::*;
            #[doc = concat!("# use core::", stringify!($n), "::MAX;")]
            #[doc = concat!("let x = ", stringify!($name), "::from_array([2, 1, 0, MAX]);")]
            #[doc = concat!("let max = ", stringify!($name), "::splat(MAX);")]
            /// let unsat = x + max;
            /// let sat = x.saturating_add(max);
            /// assert_eq!(x - 1, unsat);
            /// assert_eq!(sat, max);
            /// ```
            #[inline]
            pub fn saturating_add(self, second: Self) -> Self {
                unsafe { crate::intrinsics::simd_saturating_add(self, second) }
            }

            /// Lanewise saturating subtract.
            ///
            /// # Examples
            /// ```
            /// # use core_simd::*;
            #[doc = concat!("# use core::", stringify!($n), "::MAX;")]
            #[doc = concat!("let x = ", stringify!($name), "::from_array([2, 1, 0, MAX]);")]
            #[doc = concat!("let max = ", stringify!($name), "::splat(MAX);")]
            /// let unsat = x - max;
            /// let sat = x.saturating_sub(max);
            /// assert_eq!(unsat, x + 1);
            #[doc = concat!("assert_eq!(sat, ", stringify!($name), "::splat(0));")]
            #[inline]
            pub fn saturating_sub(self, second: Self) -> Self {
                unsafe { crate::intrinsics::simd_saturating_sub(self, second) }
            }
        })+
    }
}

macro_rules! impl_int_arith {
    ($(($name:ident, $n:ident)),+) => {
        $( impl<const LANES: usize> $name<LANES> where Self: crate::LanesAtMost32 {

            /// Lanewise saturating add.
            ///
            /// # Examples
            /// ```
            /// # use core_simd::*;
            #[doc = concat!("# use core::", stringify!($n), "::{MIN, MAX};")]
            #[doc = concat!("let x = ", stringify!($name), "::from_array([MIN, 0, 1, MAX]);")]
            #[doc = concat!("let max = ", stringify!($name), "::splat(MAX);")]
            /// let unsat = x + max;
            /// let sat = x.saturating_add(max);
            #[doc = concat!("assert_eq!(unsat, ", stringify!($name), "::from_array([-1, MAX, MIN, -2]));")]
            #[doc = concat!("assert_eq!(sat, ", stringify!($name), "::from_array([-1, MAX, MAX, MAX]));")]
            /// ```
            #[inline]
            pub fn saturating_add(self, second: Self) -> Self {
                unsafe { crate::intrinsics::simd_saturating_add(self, second) }
            }

            /// Lanewise saturating subtract.
            ///
            /// # Examples
            /// ```
            /// # use core_simd::*;
            #[doc = concat!("# use core::", stringify!($n), "::{MIN, MAX};")]
            #[doc = concat!("let x = ", stringify!($name), "::from_array([MIN, -2, -1, MAX]);")]
            #[doc = concat!("let max = ", stringify!($name), "::splat(MAX);")]
            /// let unsat = x - max;
            /// let sat = x.saturating_sub(max);
            #[doc = concat!("assert_eq!(unsat, ", stringify!($name), "::from_array([1, MAX, MIN, 0]));")]
            #[doc = concat!("assert_eq!(sat, ", stringify!($name), "::from_array([MIN, MIN, MIN, 0]));")]
            #[inline]
            pub fn saturating_sub(self, second: Self) -> Self {
                unsafe { crate::intrinsics::simd_saturating_sub(self, second) }
            }

            /// Lanewise absolute value, implemented in Rust.
            /// Every lane becomes its absolute value.
            ///
            /// # Examples
            /// ```
            /// # use core_simd::*;
            #[doc = concat!("# use core::", stringify!($n), "::{MIN, MAX};")]
            #[doc = concat!("let xs = ", stringify!($name), "::from_array([MIN, MIN +1, -5, 0]);")]
            #[doc = concat!("assert_eq!(xs.abs(), ", stringify!($name), "::from_array([MIN, MAX, 5, 0]));")]
            /// ```
            #[inline]
            pub fn abs(self) -> Self {
                let mut xs = self.to_array();
                for (i, x) in xs.clone().iter().enumerate() {
                    xs[i] = x.wrapping_abs()
                }
                $name::from_array(xs)
            }

            /// Lanewise saturating absolute value, implemented in Rust.
            /// As abs(), except the MIN value becomes MAX instead of itself.
            ///
            /// # Examples
            /// ```
            /// # use core_simd::*;
            #[doc = concat!("# use core::", stringify!($n), "::{MIN, MAX};")]
            #[doc = concat!("let xs = ", stringify!($name), "::from_array([MIN, -2, 0, 3]);")]
            /// let unsat = xs.abs();
            /// let sat = xs.saturating_abs();
            #[doc = concat!("assert_eq!(unsat, ", stringify!($name), "::from_array([MIN, 2, 0, 3]));")]
            #[doc = concat!("assert_eq!(sat, ", stringify!($name), "::from_array([MAX, 2, 0, 3]));")]
            /// ```
            #[inline]
            pub fn saturating_abs(self) -> Self {
                // arith shift for -1 or 0 mask based on sign bit, giving 2s complement
                const SHR: $n = <$n>::BITS as $n - 1;
                let m = self >> SHR;
                (self^m).saturating_sub(m)
            }

            /// Lanewise saturating negation, implemented in Rust.
            /// As neg(), except the MIN value becomes MAX instead of itself.
            ///
            /// # Examples
            /// ```
            /// # use core_simd::*;
            #[doc = concat!("# use core::", stringify!($n), "::{MIN, MAX};")]
            #[doc = concat!("let x = ", stringify!($name), "::from_array([MIN, -2, 3, MAX]);")]
            /// let unsat = -x;
            /// let sat = x.saturating_neg();
            #[doc = concat!("assert_eq!(unsat, ", stringify!($name), "::from_array([MIN, 2, -3, MIN + 1]));")]
            #[doc = concat!("assert_eq!(sat, ", stringify!($name), "::from_array([MAX, 2, -3, MIN + 1]));")]
            /// ```
            #[inline]
            pub fn saturating_neg(self) -> Self {
                Self::splat(0).saturating_sub(self)
            }
        })+
    }
}

use crate::vector::*;

impl_uint_arith! { (SimdU8, u8), (SimdU16, u16), (SimdU32, u32), (SimdU64, u64), (SimdU128, u128), (SimdUsize, usize) }
impl_int_arith! { (SimdI8, i8), (SimdI16, i16), (SimdI32, i32), (SimdI64, i64), (SimdI128, i128), (SimdIsize, isize) }
<|endoftext|>


<commit_before>use std::error;
use std::fmt;

/// An error returned from the [`send`] method.
///
/// The message could not be sent because the channel is disconnected.
///
/// The error contains the message so it can be recovered.
///
/// [`send`]: struct.Sender.html#method.send
#[derive(PartialEq, Eq, Clone, Copy)]
pub struct SendError<T>(pub T);

/// An error returned from the [`try_send`] method.
///
/// The error contains the message being sent so it can be recovered.
///
/// [`try_send`]: struct.Sender.html#method.try_send
#[derive(PartialEq, Eq, Clone, Copy)]
pub enum TrySendError<T> {
    /// The message could not be sent because the channel is full.
    ///
    /// If this is a zero-capacity channel, then the error indicates that there was no receiver
    /// available to receive the message at the time.
    Full(T),

    /// The message could not be sent because the channel is disconnected.
    Disconnected(T),
}

/// An error returned from the [`send_timeout`] method.
///
/// The error contains the message being sent so it can be recovered.
///
/// [`send_timeout`]: struct.Sender.html#method.send_timeout
#[derive(PartialEq, Eq, Clone, Copy)]
pub enum SendTimeoutError<T> {
    /// The message could not be sent because the channel is full and the operation timed out.
    ///
    /// If this is a zero-capacity channel, then the error indicates that there was no receiver
    /// available to receive the message and the operation timed out.
    Timeout(T),

    /// The message could not be sent because the channel is disconnected.
    Disconnected(T),
}

/// An error returned from the [`recv`] method.
///
/// A message could not be received because the channel is empty and disconnected.
///
/// [`recv`]: struct.Receiver.html#method.recv
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct RecvError;

/// An error returned from the [`try_recv`] method.
///
/// [`try_recv`]: struct.Receiver.html#method.recv
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum TryRecvError {
    /// A message could not be received because the channel is empty.
    ///
    /// If this is a zero-capacity channel, then the error indicates that there was no sender
    /// available to send a message at the time.
    Empty,

    /// The message could not be received because the channel is empty and disconnected.
    Disconnected,
}

/// An error returned from the [`recv_timeout`] method.
///
/// [`recv_timeout`]: struct.Receiver.html#method.recv_timeout
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum RecvTimeoutError {
    /// A message could not be received because the channel is empty and the operation timed out.
    ///
    /// If this is a zero-capacity channel, then the error indicates that there was no sender
    /// available to send a message and the operation timed out.
    Timeout,

    /// The message could not be received because the channel is empty and disconnected.
    Disconnected,
}

/// An error returned from the [`try_select`] method.
///
/// Failed because none of the channel operations were ready.
///
/// [`try_select`]: struct.Select.html#method.try_select
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct TrySelectError;

/// An error returned from the [`select_timeout`] method.
///
/// Failed because none of the channel operations became ready before the timeout.
///
/// [`select_timeout`]: struct.Select.html#method.select_timeout
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct SelectTimeoutError;

impl<T> fmt::Debug for SendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "SendError(..)".fmt(f)
    }
}

impl<T> fmt::Display for SendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "sending on a disconnected channel".fmt(f)
    }
}

impl<T: Send> error::Error for SendError<T> {
    fn description(&self) -> &str {
        "sending on a disconnected channel"
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl<T> SendError<T> {
    /// Unwraps the message.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use crossbeam_channel::unbounded;
    ///
    /// let (s, r) = unbounded();
    /// drop(r);
    ///
    /// if let Err(err) = s.send("foo") {
    ///     assert_eq!(err.into_inner(), "foo");
    /// }
    /// ```
    pub fn into_inner(self) -> T {
        self.0
    }
}

impl<T> fmt::Debug for TrySendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            TrySendError::Full(..) => "Full(..)".fmt(f),
            TrySendError::Disconnected(..) => "Disconnected(..)".fmt(f),
        }
    }
}

impl<T> fmt::Display for TrySendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            TrySendError::Full(..) => "sending on a full channel".fmt(f),
            TrySendError::Disconnected(..) => "sending on a disconnected channel".fmt(f),
        }
    }
}

impl<T: Send> error::Error for TrySendError<T> {
    fn description(&self) -> &str {
        match *self {
            TrySendError::Full(..) => "sending on a full channel",
            TrySendError::Disconnected(..) => "sending on a disconnected channel",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl<T> From<SendError<T>> for TrySendError<T> {
    fn from(err: SendError<T>) -> TrySendError<T> {
        match err {
            SendError(t) => TrySendError::Disconnected(t),
        }
    }
}

impl<T> TrySendError<T> {
    /// Unwraps the message.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use crossbeam_channel::bounded;
    ///
    /// let (s, r) = bounded(0);
    ///
    /// if let Err(err) = s.try_send("foo") {
    ///     assert_eq!(err.into_inner(), "foo");
    /// }
    /// ```
    pub fn into_inner(self) -> T {
        match self {
            TrySendError::Full(v) => v,
            TrySendError::Disconnected(v) => v,
        }
    }
}

impl<T> fmt::Debug for SendTimeoutError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "SendTimeoutError(..)".fmt(f)
    }
}

impl<T> fmt::Display for SendTimeoutError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            SendTimeoutError::Timeout(..) => "timed out waiting on send operation".fmt(f),
            SendTimeoutError::Disconnected(..) => "sending on a disconnected channel".fmt(f),
        }
    }
}

impl<T: Send> error::Error for SendTimeoutError<T> {
    fn description(&self) -> &str {
        "sending on an empty and disconnected channel"
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl<T> From<SendError<T>> for SendTimeoutError<T> {
    fn from(err: SendError<T>) -> SendTimeoutError<T> {
        match err {
            SendError(e) => SendTimeoutError::Disconnected(e),
        }
    }
}

impl<T> SendTimeoutError<T> {
    /// Unwraps the message.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use std::time::Duration;
    /// use crossbeam_channel::unbounded;
    ///
    /// let (s, r) = unbounded();
    ///
    /// if let Err(err) = s.send_timeout("foo", Duration::from_secs(1)) {
    ///     assert_eq!(err.into_inner(), "foo");
    /// }
    /// ```
    pub fn into_inner(self) -> T {
        match self {
            SendTimeoutError::Timeout(v) => v,
            SendTimeoutError::Disconnected(v) => v,
        }
    }
}

impl fmt::Display for RecvError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "receiving on an empty and disconnected channel".fmt(f)
    }
}

impl error::Error for RecvError {
    fn description(&self) -> &str {
        "receiving on an empty and disconnected channel"
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl fmt::Display for TryRecvError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            TryRecvError::Empty => "receiving on an empty channel".fmt(f),
            TryRecvError::Disconnected => "receiving on an empty and disconnected channel".fmt(f),
        }
    }
}

impl error::Error for TryRecvError {
    fn description(&self) -> &str {
        match *self {
            TryRecvError::Empty => "receiving on an empty channel",
            TryRecvError::Disconnected => "receiving on an empty and disconnected channel",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl From<RecvError> for TryRecvError {
    fn from(err: RecvError) -> TryRecvError {
        match err {
            RecvError => TryRecvError::Disconnected,
        }
    }
}

impl fmt::Display for RecvTimeoutError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            RecvTimeoutError::Timeout => "timed out waiting on receive operation".fmt(f),
            RecvTimeoutError::Disconnected => "channel is empty and disconnected".fmt(f),
        }
    }
}

impl error::Error for RecvTimeoutError {
    fn description(&self) -> &str {
        match *self {
            RecvTimeoutError::Timeout => "timed out waiting on receive operation",
            RecvTimeoutError::Disconnected => "channel is empty and disconnected",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl From<RecvError> for RecvTimeoutError {
    fn from(err: RecvError) -> RecvTimeoutError {
        match err {
            RecvError => RecvTimeoutError::Disconnected,
        }
    }
}

impl fmt::Display for TrySelectError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "all operations in select would block".fmt(f)
    }
}

impl error::Error for TrySelectError {
    fn description(&self) -> &str {
        "all operations in select would block"
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl fmt::Display for SelectTimeoutError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "timed out waiting on select".fmt(f)
    }
}

impl error::Error for SelectTimeoutError {
    fn description(&self) -> &str {
        "timed out waiting on select"
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}
<commit_msg>Add additional is_* methods to error types<commit_after>use std::error;
use std::fmt;

/// An error returned from the [`send`] method.
///
/// The message could not be sent because the channel is disconnected.
///
/// The error contains the message so it can be recovered.
///
/// [`send`]: struct.Sender.html#method.send
#[derive(PartialEq, Eq, Clone, Copy)]
pub struct SendError<T>(pub T);

/// An error returned from the [`try_send`] method.
///
/// The error contains the message being sent so it can be recovered.
///
/// [`try_send`]: struct.Sender.html#method.try_send
#[derive(PartialEq, Eq, Clone, Copy)]
pub enum TrySendError<T> {
    /// The message could not be sent because the channel is full.
    ///
    /// If this is a zero-capacity channel, then the error indicates that there was no receiver
    /// available to receive the message at the time.
    Full(T),

    /// The message could not be sent because the channel is disconnected.
    Disconnected(T),
}

/// An error returned from the [`send_timeout`] method.
///
/// The error contains the message being sent so it can be recovered.
///
/// [`send_timeout`]: struct.Sender.html#method.send_timeout
#[derive(PartialEq, Eq, Clone, Copy)]
pub enum SendTimeoutError<T> {
    /// The message could not be sent because the channel is full and the operation timed out.
    ///
    /// If this is a zero-capacity channel, then the error indicates that there was no receiver
    /// available to receive the message and the operation timed out.
    Timeout(T),

    /// The message could not be sent because the channel is disconnected.
    Disconnected(T),
}

/// An error returned from the [`recv`] method.
///
/// A message could not be received because the channel is empty and disconnected.
///
/// [`recv`]: struct.Receiver.html#method.recv
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct RecvError;

/// An error returned from the [`try_recv`] method.
///
/// [`try_recv`]: struct.Receiver.html#method.recv
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum TryRecvError {
    /// A message could not be received because the channel is empty.
    ///
    /// If this is a zero-capacity channel, then the error indicates that there was no sender
    /// available to send a message at the time.
    Empty,

    /// The message could not be received because the channel is empty and disconnected.
    Disconnected,
}

/// An error returned from the [`recv_timeout`] method.
///
/// [`recv_timeout`]: struct.Receiver.html#method.recv_timeout
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum RecvTimeoutError {
    /// A message could not be received because the channel is empty and the operation timed out.
    ///
    /// If this is a zero-capacity channel, then the error indicates that there was no sender
    /// available to send a message and the operation timed out.
    Timeout,

    /// The message could not be received because the channel is empty and disconnected.
    Disconnected,
}

/// An error returned from the [`try_select`] method.
///
/// Failed because none of the channel operations were ready.
///
/// [`try_select`]: struct.Select.html#method.try_select
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct TrySelectError;

/// An error returned from the [`select_timeout`] method.
///
/// Failed because none of the channel operations became ready before the timeout.
///
/// [`select_timeout`]: struct.Select.html#method.select_timeout
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct SelectTimeoutError;

impl<T> fmt::Debug for SendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "SendError(..)".fmt(f)
    }
}

impl<T> fmt::Display for SendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "sending on a disconnected channel".fmt(f)
    }
}

impl<T: Send> error::Error for SendError<T> {
    fn description(&self) -> &str {
        "sending on a disconnected channel"
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl<T> SendError<T> {
    /// Unwraps the message.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use crossbeam_channel::unbounded;
    ///
    /// let (s, r) = unbounded();
    /// drop(r);
    ///
    /// if let Err(err) = s.send("foo") {
    ///     assert_eq!(err.into_inner(), "foo");
    /// }
    /// ```
    pub fn into_inner(self) -> T {
        self.0
    }
}

impl<T> fmt::Debug for TrySendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            TrySendError::Full(..) => "Full(..)".fmt(f),
            TrySendError::Disconnected(..) => "Disconnected(..)".fmt(f),
        }
    }
}

impl<T> fmt::Display for TrySendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            TrySendError::Full(..) => "sending on a full channel".fmt(f),
            TrySendError::Disconnected(..) => "sending on a disconnected channel".fmt(f),
        }
    }
}

impl<T: Send> error::Error for TrySendError<T> {
    fn description(&self) -> &str {
        match *self {
            TrySendError::Full(..) => "sending on a full channel",
            TrySendError::Disconnected(..) => "sending on a disconnected channel",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl<T> From<SendError<T>> for TrySendError<T> {
    fn from(err: SendError<T>) -> TrySendError<T> {
        match err {
            SendError(t) => TrySendError::Disconnected(t),
        }
    }
}

impl<T> TrySendError<T> {
    /// Unwraps the message.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use crossbeam_channel::bounded;
    ///
    /// let (s, r) = bounded(0);
    ///
    /// if let Err(err) = s.try_send("foo") {
    ///     assert_eq!(err.into_inner(), "foo");
    /// }
    /// ```
    pub fn into_inner(self) -> T {
        match self {
            TrySendError::Full(v) => v,
            TrySendError::Disconnected(v) => v,
        }
    }

    /// Returns `true` if the send operation failed because the channel is full.
    pub fn is_full(&self) -> bool {
        match self {
            TrySendError::Full(_) => true,
            _ => false,
        }
    }

    /// Returns `true` if the send operation failed because the channel is disconnected.
    pub fn is_disconnected(&self) -> bool {
        match self {
            TrySendError::Disconnected(_) => true,
            _ => false,
        }
    }
}

impl<T> fmt::Debug for SendTimeoutError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "SendTimeoutError(..)".fmt(f)
    }
}

impl<T> fmt::Display for SendTimeoutError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            SendTimeoutError::Timeout(..) => "timed out waiting on send operation".fmt(f),
            SendTimeoutError::Disconnected(..) => "sending on a disconnected channel".fmt(f),
        }
    }
}

impl<T: Send> error::Error for SendTimeoutError<T> {
    fn description(&self) -> &str {
        "sending on an empty and disconnected channel"
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl<T> From<SendError<T>> for SendTimeoutError<T> {
    fn from(err: SendError<T>) -> SendTimeoutError<T> {
        match err {
            SendError(e) => SendTimeoutError::Disconnected(e),
        }
    }
}

impl<T> SendTimeoutError<T> {
    /// Unwraps the message.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use std::time::Duration;
    /// use crossbeam_channel::unbounded;
    ///
    /// let (s, r) = unbounded();
    ///
    /// if let Err(err) = s.send_timeout("foo", Duration::from_secs(1)) {
    ///     assert_eq!(err.into_inner(), "foo");
    /// }
    /// ```
    pub fn into_inner(self) -> T {
        match self {
            SendTimeoutError::Timeout(v) => v,
            SendTimeoutError::Disconnected(v) => v,
        }
    }

    /// Returns `true` if the send operation timed out.
    pub fn is_timeout(&self) -> bool {
        match self {
            SendTimeoutError::Timeout(_) => true,
            _ => false,
        }
    }

    /// Returns `true` if the send operation failed because the channel is disconnected.
    pub fn is_disconnected(&self) -> bool {
        match self {
            SendTimeoutError::Disconnected(_) => true,
            _ => false,
        }
    }
}

impl fmt::Display for RecvError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "receiving on an empty and disconnected channel".fmt(f)
    }
}

impl error::Error for RecvError {
    fn description(&self) -> &str {
        "receiving on an empty and disconnected channel"
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl fmt::Display for TryRecvError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            TryRecvError::Empty => "receiving on an empty channel".fmt(f),
            TryRecvError::Disconnected => "receiving on an empty and disconnected channel".fmt(f),
        }
    }
}

impl error::Error for TryRecvError {
    fn description(&self) -> &str {
        match *self {
            TryRecvError::Empty => "receiving on an empty channel",
            TryRecvError::Disconnected => "receiving on an empty and disconnected channel",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl From<RecvError> for TryRecvError {
    fn from(err: RecvError) -> TryRecvError {
        match err {
            RecvError => TryRecvError::Disconnected,
        }
    }
}

impl TryRecvError {
    /// Returns `true` if the receive operation failed because the channel is empty.
    pub fn is_empty(&self) -> bool {
        match self {
            TryRecvError::Empty => true,
            _ => false,
        }
    }

    /// Returns `true` if the receive operation failed because the channel is disconnected.
    pub fn is_disconnected(&self) -> bool {
        match self {
            TryRecvError::Disconnected => true,
            _ => false,
        }
    }
}

impl fmt::Display for RecvTimeoutError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            RecvTimeoutError::Timeout => "timed out waiting on receive operation".fmt(f),
            RecvTimeoutError::Disconnected => "channel is empty and disconnected".fmt(f),
        }
    }
}

impl error::Error for RecvTimeoutError {
    fn description(&self) -> &str {
        match *self {
            RecvTimeoutError::Timeout => "timed out waiting on receive operation",
            RecvTimeoutError::Disconnected => "channel is empty and disconnected",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl From<RecvError> for RecvTimeoutError {
    fn from(err: RecvError) -> RecvTimeoutError {
        match err {
            RecvError => RecvTimeoutError::Disconnected,
        }
    }
}

impl RecvTimeoutError {
    /// Returns `true` if the receive operation timed out.
    pub fn is_timeout(&self) -> bool {
        match self {
            RecvTimeoutError::Timeout => true,
            _ => false,
        }
    }

    /// Returns `true` if the receive operation failed because the channel is disconnected.
    pub fn is_disconnected(&self) -> bool {
        match self {
            RecvTimeoutError::Disconnected => true,
            _ => false,
        }
    }
}

impl fmt::Display for TrySelectError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "all operations in select would block".fmt(f)
    }
}

impl error::Error for TrySelectError {
    fn description(&self) -> &str {
        "all operations in select would block"
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl fmt::Display for SelectTimeoutError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "timed out waiting on select".fmt(f)
    }
}

impl error::Error for SelectTimeoutError {
    fn description(&self) -> &str {
        "timed out waiting on select"
    }

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}
<|endoftext|>


<commit_before>//! The `conductor new` command, and any other file generators.

use handlebars as hb;
use rustc_serialize::json::{Json, ToJson};
use std::collections::BTreeMap;
#[cfg(test)]
use std::env;
use std::fmt::Debug;
use std::fs;
use std::path::{PathBuf, Path};

use project::Project;
use util::{ConductorPathExt, Error};

/// Interface to various file-generation commands.
pub trait CommandGenerate {
    /// Create a new conductor project skeleton, returning the path of the
    /// generated project.
    ///
    /// ```text
    /// <name>
    /// └── pods
    ///   ├── common.env
    ///   ├── frontend.yml
    ///   └── overrides
    ///       ├── development
    ///       │   └── common.env
    ///       ├── production
    ///       │   ├── common.env
    ///       └── test
    ///           └── common.env
    /// ```
    fn generate(parent_dir: &Path, name: &str) -> Result<PathBuf, Error>;
}

impl CommandGenerate for Project {
    fn generate(parent_dir: &Path, name: &str) -> Result<PathBuf, Error> {
        let proj_dir = parent_dir.join(name);
        let pods_dir = proj_dir.join("pods");

        // Create a template engine to generate our files.
        let mut renderer: hb::Handlebars = hb::Handlebars::new();
        renderer.register_escape_fn(escape_double_quotes);

        // Generate our top-level files.
        let proj_info = ProjectInfo { name: name };
        try!(generate(&mut renderer, &COMMON_ENV, &proj_info,
                      &pods_dir.join("common.env")));
        try!(generate(&mut renderer, &FRONTEND_YML, &proj_info,
                      &pods_dir.join("frontend.yml")));
        try!(generate(&mut renderer, &DB_YML, &proj_info,
                      &pods_dir.join("db.yml")));

        // Generate files for each override.
        let overrides_dir: PathBuf = pods_dir.join("overrides");
        for ovr in OVERRIDES {
            let ovr_info = OverrideInfo {
                project: &proj_info,
                name: ovr,
            };
            let dir = overrides_dir.join(ovr);
            try!(generate(&mut renderer, &OVERRIDE_ENV, &ovr_info,
                          &dir.join("common.env")));
        }

        Ok(proj_dir)
    }
}

#[test]
fn create_project_default() {
    let cwd = env::current_dir().unwrap();
    Project::generate(&cwd, "test_project").unwrap();
    let proj_dir = env::current_dir().unwrap().join("test_project");

    assert!(proj_dir.exists());
    assert!(proj_dir.join("pods/common.env").exists());
    assert!(proj_dir.join("pods/frontend.yml").exists());
    assert!(proj_dir.join("pods/db.yml").exists());
    assert!(proj_dir.join("pods/overrides/development/common.env").exists());
    assert!(proj_dir.join("pods/overrides/production/common.env").exists());
    assert!(proj_dir.join("pods/overrides/test/common.env").exists());

    fs::remove_dir_all(&proj_dir.as_path()).unwrap();
}

/// Escape double quotes in a string that we're rendering, which should
/// work well more-or-less well enough for all the formats we're generating.
fn escape_double_quotes(data: &str) -> String {
    data.replace(r#"""#, r#"\""#)
}

/// Generate a template and write it to the specified file.
fn generate<T>(renderer: &mut hb::Handlebars,
               template: &str,
               data: &T,
               path: &Path) ->
    Result<(), Error>
    where T: ToJson + Debug
{
    debug!("Generating {} with {:?}", path.display(), data);
    println!("Generating {}", path.display());

    // Make sure our parent directory exists.
    try!(path.with_guaranteed_parent());

    // Create our output file.
    let mut out = try!(fs::File::create(path).map_err(|e| {
        err!("Unable to create file {}: {}", path.display(), &e)
    }));

    // Render our template to the file.
    let ctx = hb::Context::wraps(data);
    renderer.template_renderw(template, &ctx, &mut out).map_err(|e| {
        err!("Unable to generate {}: {}", path.display(), &e)
    })
}

/// Information about the project we're generating.  This will be passed to
/// our templates.
#[derive(Debug)]
struct ProjectInfo<'a> {
    /// The name of this project.
    name: &'a str,
}

// Convert to JSON for use in a Handlebars template.  We could get
// Handlebars and serde to convert to JSON automatically, but it's less
// work to define it by hand.
impl<'a> ToJson for ProjectInfo<'a> {
    fn to_json(&self) -> Json {
        let mut info: BTreeMap<String, Json> = BTreeMap::new();
        info.insert("name".to_string(), self.name.to_json());
        info.to_json()
    }
}

/// Information about the override we're generating.  This will be passed
/// to our templates.
#[derive(Debug)]
struct OverrideInfo<'a> {
    /// The project in which this override appears.
    project: &'a ProjectInfo<'a>,
    /// The name of this override.
    name: &'a str,
}

impl<'a> ToJson for OverrideInfo<'a> {
    fn to_json(&self) -> Json {
        let mut info: BTreeMap<String, Json> = BTreeMap::new();
        info.insert("project".to_string(), self.project.to_json());
        info.insert("name".to_string(), self.name.to_json());
        info.to_json()
    }
}

//fn write_to_file<F, W>(path: &Path,   ->
//    Result<(), Error>
//    where W: Write
//{
//    println!("Writing file {:?}", path.to_str());
//
//    // Make sure our parent directory exists.
//    try!(path.with_guaranteed_parent());
//
//    // Create our output file and copy data into it.
//    let mut out = try!(fs::File::create(path).map_err(|e| {
//        err!("Unable to create file {}: {}", path.display(), &e)
//    }));
//    try!(io::copy(content, out).map_err(|e| {
//        err!("Unable to write to file {}: {}", path.display(), &e)
//    }));
//    Ok(())
//}

// Standard overrides that we'll use for new projects.
const OVERRIDES: &'static [ &'static str ] = &["development", "production", "test"];

static FRONTEND_YML: &'static str = include_str!("generate/new/frontend.yml");
static DB_YML: &'static str = include_str!("generate/new/db.yml");
static COMMON_ENV: &'static str = include_str!("generate/new/common.env");
static OVERRIDE_ENV: &'static str = include_str!("generate/new/overrides/common.env");
<commit_msg>Remove some unused generate code<commit_after>//! The `conductor new` command, and any other file generators.

use handlebars as hb;
use rustc_serialize::json::{Json, ToJson};
use std::collections::BTreeMap;
#[cfg(test)]
use std::env;
use std::fmt::Debug;
use std::fs;
use std::path::{PathBuf, Path};

use project::Project;
use util::{ConductorPathExt, Error};

/// Interface to various file-generation commands.
pub trait CommandGenerate {
    /// Create a new conductor project skeleton, returning the path of the
    /// generated project.
    ///
    /// ```text
    /// <name>
    /// └── pods
    ///   ├── common.env
    ///   ├── frontend.yml
    ///   └── overrides
    ///       ├── development
    ///       │   └── common.env
    ///       ├── production
    ///       │   ├── common.env
    ///       └── test
    ///           └── common.env
    /// ```
    fn generate(parent_dir: &Path, name: &str) -> Result<PathBuf, Error>;
}

impl CommandGenerate for Project {
    fn generate(parent_dir: &Path, name: &str) -> Result<PathBuf, Error> {
        let proj_dir = parent_dir.join(name);
        let pods_dir = proj_dir.join("pods");

        // Create a template engine to generate our files.
        let mut renderer: hb::Handlebars = hb::Handlebars::new();
        renderer.register_escape_fn(escape_double_quotes);

        // Generate our top-level files.
        let proj_info = ProjectInfo { name: name };
        try!(generate(&mut renderer, &COMMON_ENV, &proj_info,
                      &pods_dir.join("common.env")));
        try!(generate(&mut renderer, &FRONTEND_YML, &proj_info,
                      &pods_dir.join("frontend.yml")));
        try!(generate(&mut renderer, &DB_YML, &proj_info,
                      &pods_dir.join("db.yml")));

        // Generate files for each override.
        let overrides_dir: PathBuf = pods_dir.join("overrides");
        for ovr in OVERRIDES {
            let ovr_info = OverrideInfo {
                project: &proj_info,
                name: ovr,
            };
            let dir = overrides_dir.join(ovr);
            try!(generate(&mut renderer, &OVERRIDE_ENV, &ovr_info,
                          &dir.join("common.env")));
        }

        Ok(proj_dir)
    }
}

#[test]
fn create_project_default() {
    let cwd = env::current_dir().unwrap();
    Project::generate(&cwd, "test_project").unwrap();
    let proj_dir = env::current_dir().unwrap().join("test_project");

    assert!(proj_dir.exists());
    assert!(proj_dir.join("pods/common.env").exists());
    assert!(proj_dir.join("pods/frontend.yml").exists());
    assert!(proj_dir.join("pods/db.yml").exists());
    assert!(proj_dir.join("pods/overrides/development/common.env").exists());
    assert!(proj_dir.join("pods/overrides/production/common.env").exists());
    assert!(proj_dir.join("pods/overrides/test/common.env").exists());

    fs::remove_dir_all(&proj_dir.as_path()).unwrap();
}

/// Escape double quotes in a string that we're rendering, which should
/// work well more-or-less well enough for all the formats we're generating.
fn escape_double_quotes(data: &str) -> String {
    data.replace(r#"""#, r#"\""#)
}

/// Generate a template and write it to the specified file.
fn generate<T>(renderer: &mut hb::Handlebars,
               template: &str,
               data: &T,
               path: &Path) ->
    Result<(), Error>
    where T: ToJson + Debug
{
    debug!("Generating {} with {:?}", path.display(), data);
    println!("Generating {}", path.display());

    // Make sure our parent directory exists.
    try!(path.with_guaranteed_parent());

    // Create our output file.
    let mut out = try!(fs::File::create(path).map_err(|e| {
        err!("Unable to create file {}: {}", path.display(), &e)
    }));

    // Render our template to the file.
    let ctx = hb::Context::wraps(data);
    renderer.template_renderw(template, &ctx, &mut out).map_err(|e| {
        err!("Unable to generate {}: {}", path.display(), &e)
    })
}

/// Information about the project we're generating.  This will be passed to
/// our templates.
#[derive(Debug)]
struct ProjectInfo<'a> {
    /// The name of this project.
    name: &'a str,
}

// Convert to JSON for use in a Handlebars template.  We could get
// Handlebars and serde to convert to JSON automatically, but it's less
// work to define it by hand.
impl<'a> ToJson for ProjectInfo<'a> {
    fn to_json(&self) -> Json {
        let mut info: BTreeMap<String, Json> = BTreeMap::new();
        info.insert("name".to_string(), self.name.to_json());
        info.to_json()
    }
}

/// Information about the override we're generating.  This will be passed
/// to our templates.
#[derive(Debug)]
struct OverrideInfo<'a> {
    /// The project in which this override appears.
    project: &'a ProjectInfo<'a>,
    /// The name of this override.
    name: &'a str,
}

impl<'a> ToJson for OverrideInfo<'a> {
    fn to_json(&self) -> Json {
        let mut info: BTreeMap<String, Json> = BTreeMap::new();
        info.insert("project".to_string(), self.project.to_json());
        info.insert("name".to_string(), self.name.to_json());
        info.to_json()
    }
}

// Standard overrides that we'll use for new projects.
const OVERRIDES: &'static [ &'static str ] = &["development", "production", "test"];

static FRONTEND_YML: &'static str = include_str!("generate/new/frontend.yml");
static DB_YML: &'static str = include_str!("generate/new/db.yml");
static COMMON_ENV: &'static str = include_str!("generate/new/common.env");
static OVERRIDE_ENV: &'static str = include_str!("generate/new/overrides/common.env");
<|endoftext|>


<commit_before>#![macro_use]

macro_rules! Root {
    () => {None as Option<&Command<types::Null, ()>>}
}

macro_rules! NoArg {
    () => {None as Option<types::Null>}
}

pub mod db;
pub mod table;
pub mod uuid;
pub mod get;
pub mod get_all;
pub mod changes;
pub mod map;
pub mod get_field;
pub mod rem;

use std::string::String as StdString;

use types;

use serde_json::value::{ToJson, Value};

use proto::{
    Term_TermType as TermType,
};

use types::Command as Cmd;

include!(concat!(env!("OUT_DIR"), "/serde_types.rs"));

#[allow(non_upper_case_globals)]
pub const r: Client = Client;

impl RootCommand for Client {}

pub trait RootCommand {
    fn table<T>(&self, arg: T) -> Command<types::Table, TableOpts> where
        T: Into<types::String>
        {
            r.db("test").table(arg)
        }
}

#[derive(Debug, Clone)]
pub struct Command<T, O>(T, Option<O>);

pub struct Client;

impl Cmd {
    pub fn make<A, T, O, PT, PO>(typ: TermType, arg: Option<A>, opts: Option<O>, cmd: Option<&Command<PT, PO>>) -> Command<T, O>
        where
        A: types::DataType,
        T: types::DataType,
        O: ToJson + Clone,
        PT: types::DataType,
        PO: ToJson + Clone
        {
            let (prev_cmd, prev_opts) = match cmd {
                Some(cmd) => (Some(cmd.0.clone().into()), cmd.1.clone()),
                None => (None, None),
            };
            let mut dt = Cmd::new(typ, prev_cmd);
            if let Some(arg) = arg {
                dt = dt.with_args(arg.into());
            }
            if let Some(opt) = prev_opts {
                let obj = types::Object::from(opt);
                dt = dt.with_opts(obj);
            }
            Command(dt.into(), opts)
        }
}
<commit_msg>Make Client an alias of Command<commit_after>#![macro_use]

macro_rules! Root {
    () => {None as Option<&Command<types::Null, ()>>}
}

macro_rules! NoArg {
    () => {None as Option<types::Null>}
}

pub mod db;
pub mod table;
pub mod uuid;
pub mod get;
pub mod get_all;
pub mod changes;
pub mod map;
pub mod get_field;
pub mod rem;

use std::string::String as StdString;

use types;

use serde_json::value::{ToJson, Value};

use proto::{
    Term_TermType as TermType,
};

use types::Command as Cmd;

include!(concat!(env!("OUT_DIR"), "/serde_types.rs"));

#[allow(non_upper_case_globals)]
pub const r: Client = Command((), None);

impl RootCommand for Client {}

pub trait RootCommand {
    fn table<T>(&self, arg: T) -> Command<types::Table, TableOpts> where
        T: Into<types::String>
        {
            r.db("test").table(arg)
        }
}

#[derive(Debug)]
pub struct Command<T, O>(T, Option<O>);

pub type Client = Command<(), ()>;

impl Cmd {
    pub fn make<A, T, O, PT, PO>(typ: TermType, arg: Option<A>, opts: Option<O>, cmd: Option<&Command<PT, PO>>) -> Command<T, O>
        where
        A: types::DataType,
        T: types::DataType,
        O: ToJson + Clone,
        PT: types::DataType,
        PO: ToJson + Clone
        {
            let (prev_cmd, prev_opts) = match cmd {
                Some(cmd) => (Some(cmd.0.clone().into()), cmd.1.clone()),
                None => (None, None),
            };
            let mut dt = Cmd::new(typ, prev_cmd);
            if let Some(arg) = arg {
                dt = dt.with_args(arg.into());
            }
            if let Some(opt) = prev_opts {
                let obj = types::Object::from(opt);
                dt = dt.with_opts(obj);
            }
            Command(dt.into(), opts)
        }
}
<|endoftext|>