<commit_before>//! Module providing the TermLogger Implementation

use log::{
    set_boxed_logger, set_max_level, Level, LevelFilter, Log, Metadata, Record, SetLoggerError,
};
use std::error;
use std::fmt;
use std::io::{Error, Write};
use std::sync::Mutex;
use term;
use term::{color, StderrTerminal, StdoutTerminal, Terminal};

use self::TermLogError::{SetLogger, Term};
use super::logging::*;

use crate::{Config, SharedLogger};

/// TermLogger error type.
#[derive(Debug)]
pub enum TermLogError {
    ///The type returned by set_logger if set_logger has already been called.
    SetLogger(SetLoggerError),

    ///TermLogger initialization might also fail if stdout or stderr could not be opened,
    ///e.g. when no tty is attached to the process, it runs detached in the background, etc
    /// This is represented by the `Term` Kind
    Term,
}

impl fmt::Display for TermLogError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        use std::error::Error as FmtError;

        write!(f, "{}", self.description())
    }
}

impl error::Error for TermLogError {
    fn description(&self) -> &str {
        match *self {
            SetLogger(ref err) => err.description(),
            Term => "A terminal could not be opened",
        }
    }

    fn cause(&self) -> Option<&dyn error::Error> {
        match *self {
            SetLogger(ref err) => Some(err),
            Term => None,
        }
    }
}

impl From<SetLoggerError> for TermLogError {
    fn from(error: SetLoggerError) -> Self {
        SetLogger(error)
    }
}

enum StdTerminal {
    Stderr(Box<StderrTerminal>),
    Stdout(Box<StdoutTerminal>),
}

impl StdTerminal {
    fn flush(&mut self) -> Result<(), Error> {
        match self {
            StdTerminal::Stderr(term) => term.flush(),
            StdTerminal::Stdout(term) => term.flush(),
        }
    }
}

struct OutputStreams {
    err: StdTerminal,
    out: StdTerminal,
}

/// Specifies which streams should be used when logging
pub enum TerminalMode {
    /// Only use Stdout
    Stdout,
    /// Only use Stderr
    Stderr,
    /// Use Stderr for Errors and Stdout otherwise
    Mixed,
}

impl Default for TerminalMode {
    fn default() -> TerminalMode {
        TerminalMode::Mixed
    }
}

/// The TermLogger struct. Provides a stderr/out based Logger implementation
///
/// Supports colored output
pub struct TermLogger {
    level: LevelFilter,
    config: Config,
    streams: Mutex<OutputStreams>,
}

impl TermLogger {
    /// init function. Globally initializes the TermLogger as the one and only used log facility.
    ///
    /// Takes the desired `Level` and `Config` as arguments. They cannot be changed later on.
    /// Fails if another Logger was already initialized.
    ///
    /// # Examples
    /// ```
    /// # extern crate simplelog;
    /// # use simplelog::*;
    /// # fn main() {
    /// let _ = TermLogger::init(LevelFilter::Info, Config::default(), TerminalMode::Mixed);
    /// # }
    /// ```
    pub fn init(
        log_level: LevelFilter,
        config: Config,
        mode: TerminalMode,
    ) -> Result<(), TermLogError> {
        let logger = TermLogger::new(log_level, config, mode).ok_or(Term)?;
        set_max_level(log_level.clone());
        set_boxed_logger(logger)?;
        Ok(())
    }

    /// allows to create a new logger, that can be independently used, no matter whats globally set.
    ///
    /// no macros are provided for this case and you probably
    /// dont want to use this function, but `init()`, if you dont want to build a `CombinedLogger`.
    ///
    /// Takes the desired `Level` and `Config` as arguments. They cannot be changed later on.
    ///
    /// # Examples
    /// ```
    /// # extern crate simplelog;
    /// # use simplelog::*;
    /// # fn main() {
    /// let term_logger = TermLogger::new(LevelFilter::Info, Config::default(), TerminalMode::Mixed).unwrap();
    /// # }
    /// ```
    pub fn new(
        log_level: LevelFilter,
        config: Config,
        mode: TerminalMode,
    ) -> Option<Box<TermLogger>> {
        let streams = match mode {
            TerminalMode::Stdout => term::stdout().and_then(|stdout| {
                term::stdout().map(|stdout2| {
                    Mutex::new(OutputStreams {
                        err: StdTerminal::Stdout(stdout),
                        out: StdTerminal::Stdout(stdout2),
                    })
                })
            }),
            TerminalMode::Stderr => term::stderr().and_then(|stderr| {
                term::stderr().map(|stderr2| {
                    Mutex::new(OutputStreams {
                        err: StdTerminal::Stderr(stderr),
                        out: StdTerminal::Stderr(stderr2),
                    })
                })
            }),
            TerminalMode::Mixed => term::stderr().and_then(|stderr| {
                term::stdout().map(|stdout| {
                    Mutex::new(OutputStreams {
                        err: StdTerminal::Stderr(stderr),
                        out: StdTerminal::Stdout(stdout),
                    })
                })
            }),
        };

        streams.map(|streams| {
            Box::new(TermLogger {
                level: log_level,
                config: config,
                streams: streams,
            })
        })
    }

    fn try_log_term<W>(
        &self,
        record: &Record<'_>,
        term_lock: &mut Box<dyn Terminal<Output = W> + Send>,
    ) -> Result<(), Error>
    where
        W: Write + Sized,
    {
        let color = match record.level() {
            Level::Error => color::RED,
            Level::Warn => color::YELLOW,
            Level::Info => color::BLUE,
            Level::Debug => color::CYAN,
            Level::Trace => color::WHITE,
        };

        if let Some(time) = self.config.time {
            if time <= record.level() {
                write_time(&mut *term_lock, &self.config)?;
            }
        }

        if let Some(level) = self.config.level {
            if level <= record.level() {
                term_lock.fg(color)?;
                write_level(record, &mut *term_lock)?;
                term_lock.reset()?;
            }
        }

        if let Some(thread) = self.config.thread {
            if thread <= record.level() {
                write_thread_id(&mut *term_lock)?;
            }
        }

        if let Some(target) = self.config.target {
            if target <= record.level() {
                write_target(record, &mut *term_lock)?;
            }
        }

        if let Some(location) = self.config.location {
            if location <= record.level() {
                write_location(record, &mut *term_lock)?;
            }
        }

        write_args(record, &mut *term_lock)
    }

    fn try_log(&self, record: &Record<'_>) -> Result<(), Error> {
        if self.enabled(record.metadata()) {
            if should_skip(&self.config, record) {
                return Ok(());
            }

            let mut streams = self.streams.lock().unwrap();

            if record.level() == Level::Error {
                match streams.err {
                    StdTerminal::Stderr(ref mut term) => self.try_log_term(record, term),
                    StdTerminal::Stdout(ref mut term) => self.try_log_term(record, term),
                }
            } else {
                match streams.out {
                    StdTerminal::Stderr(ref mut term) => self.try_log_term(record, term),
                    StdTerminal::Stdout(ref mut term) => self.try_log_term(record, term),
                }
            }
        } else {
            Ok(())
        }
    }
}

impl Log for TermLogger {
    fn enabled(&self, metadata: &Metadata<'_>) -> bool {
        metadata.level() <= self.level
    }

    fn log(&self, record: &Record<'_>) {
        let _ = self.try_log(record);
    }

    fn flush(&self) {
        let mut streams = self.streams.lock().unwrap();
        let _ = streams.out.flush();
        let _ = streams.err.flush();
    }
}

impl SharedLogger for TermLogger {
    fn level(&self) -> LevelFilter {
        self.level
    }

    fn config(&self) -> Option<&Config> {
        Some(&self.config)
    }

    fn as_log(self: Box<Self>) -> Box<dyn Log> {
        Box::new(*self)
    }
}
<commit_msg>Document why TermLogger::new could return None<commit_after>//! Module providing the TermLogger Implementation

use log::{
    set_boxed_logger, set_max_level, Level, LevelFilter, Log, Metadata, Record, SetLoggerError,
};
use std::error;
use std::fmt;
use std::io::{Error, Write};
use std::sync::Mutex;
use term;
use term::{color, StderrTerminal, StdoutTerminal, Terminal};

use self::TermLogError::{SetLogger, Term};
use super::logging::*;

use crate::{Config, SharedLogger};

/// TermLogger error type.
#[derive(Debug)]
pub enum TermLogError {
    ///The type returned by set_logger if set_logger has already been called.
    SetLogger(SetLoggerError),

    ///TermLogger initialization might also fail if stdout or stderr could not be opened,
    ///e.g. when no tty is attached to the process, it runs detached in the background, etc
    /// This is represented by the `Term` Kind
    Term,
}

impl fmt::Display for TermLogError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        use std::error::Error as FmtError;

        write!(f, "{}", self.description())
    }
}

impl error::Error for TermLogError {
    fn description(&self) -> &str {
        match *self {
            SetLogger(ref err) => err.description(),
            Term => "A terminal could not be opened",
        }
    }

    fn cause(&self) -> Option<&dyn error::Error> {
        match *self {
            SetLogger(ref err) => Some(err),
            Term => None,
        }
    }
}

impl From<SetLoggerError> for TermLogError {
    fn from(error: SetLoggerError) -> Self {
        SetLogger(error)
    }
}

enum StdTerminal {
    Stderr(Box<StderrTerminal>),
    Stdout(Box<StdoutTerminal>),
}

impl StdTerminal {
    fn flush(&mut self) -> Result<(), Error> {
        match self {
            StdTerminal::Stderr(term) => term.flush(),
            StdTerminal::Stdout(term) => term.flush(),
        }
    }
}

struct OutputStreams {
    err: StdTerminal,
    out: StdTerminal,
}

/// Specifies which streams should be used when logging
pub enum TerminalMode {
    /// Only use Stdout
    Stdout,
    /// Only use Stderr
    Stderr,
    /// Use Stderr for Errors and Stdout otherwise
    Mixed,
}

impl Default for TerminalMode {
    fn default() -> TerminalMode {
        TerminalMode::Mixed
    }
}

/// The TermLogger struct. Provides a stderr/out based Logger implementation
///
/// Supports colored output
pub struct TermLogger {
    level: LevelFilter,
    config: Config,
    streams: Mutex<OutputStreams>,
}

impl TermLogger {
    /// init function. Globally initializes the TermLogger as the one and only used log facility.
    ///
    /// Takes the desired `Level` and `Config` as arguments. They cannot be changed later on.
    /// Fails if another Logger was already initialized.
    ///
    /// # Examples
    /// ```
    /// # extern crate simplelog;
    /// # use simplelog::*;
    /// # fn main() {
    /// let _ = TermLogger::init(LevelFilter::Info, Config::default(), TerminalMode::Mixed);
    /// # }
    /// ```
    pub fn init(
        log_level: LevelFilter,
        config: Config,
        mode: TerminalMode,
    ) -> Result<(), TermLogError> {
        let logger = TermLogger::new(log_level, config, mode).ok_or(Term)?;
        set_max_level(log_level.clone());
        set_boxed_logger(logger)?;
        Ok(())
    }

    /// allows to create a new logger, that can be independently used, no matter whats globally set.
    ///
    /// no macros are provided for this case and you probably
    /// dont want to use this function, but `init()`, if you dont want to build a `CombinedLogger`.
    ///
    /// Takes the desired `Level` and `Config` as arguments. They cannot be changed later on.
    ///
    /// Returns a `Box`ed TermLogger, or None if a terminal couldn't be opened.
    ///
    /// # Examples
    /// ```
    /// # extern crate simplelog;
    /// # use simplelog::*;
    /// # fn main() {
    /// let term_logger = TermLogger::new(LevelFilter::Info, Config::default(), TerminalMode::Mixed).unwrap();
    /// # }
    /// ```
    pub fn new(
        log_level: LevelFilter,
        config: Config,
        mode: TerminalMode,
    ) -> Option<Box<TermLogger>> {
        let streams = match mode {
            TerminalMode::Stdout => term::stdout().and_then(|stdout| {
                term::stdout().map(|stdout2| {
                    Mutex::new(OutputStreams {
                        err: StdTerminal::Stdout(stdout),
                        out: StdTerminal::Stdout(stdout2),
                    })
                })
            }),
            TerminalMode::Stderr => term::stderr().and_then(|stderr| {
                term::stderr().map(|stderr2| {
                    Mutex::new(OutputStreams {
                        err: StdTerminal::Stderr(stderr),
                        out: StdTerminal::Stderr(stderr2),
                    })
                })
            }),
            TerminalMode::Mixed => term::stderr().and_then(|stderr| {
                term::stdout().map(|stdout| {
                    Mutex::new(OutputStreams {
                        err: StdTerminal::Stderr(stderr),
                        out: StdTerminal::Stdout(stdout),
                    })
                })
            }),
        };

        streams.map(|streams| {
            Box::new(TermLogger {
                level: log_level,
                config: config,
                streams: streams,
            })
        })
    }

    fn try_log_term<W>(
        &self,
        record: &Record<'_>,
        term_lock: &mut Box<dyn Terminal<Output = W> + Send>,
    ) -> Result<(), Error>
    where
        W: Write + Sized,
    {
        let color = match record.level() {
            Level::Error => color::RED,
            Level::Warn => color::YELLOW,
            Level::Info => color::BLUE,
            Level::Debug => color::CYAN,
            Level::Trace => color::WHITE,
        };

        if let Some(time) = self.config.time {
            if time <= record.level() {
                write_time(&mut *term_lock, &self.config)?;
            }
        }

        if let Some(level) = self.config.level {
            if level <= record.level() {
                term_lock.fg(color)?;
                write_level(record, &mut *term_lock)?;
                term_lock.reset()?;
            }
        }

        if let Some(thread) = self.config.thread {
            if thread <= record.level() {
                write_thread_id(&mut *term_lock)?;
            }
        }

        if let Some(target) = self.config.target {
            if target <= record.level() {
                write_target(record, &mut *term_lock)?;
            }
        }

        if let Some(location) = self.config.location {
            if location <= record.level() {
                write_location(record, &mut *term_lock)?;
            }
        }

        write_args(record, &mut *term_lock)
    }

    fn try_log(&self, record: &Record<'_>) -> Result<(), Error> {
        if self.enabled(record.metadata()) {
            if should_skip(&self.config, record) {
                return Ok(());
            }

            let mut streams = self.streams.lock().unwrap();

            if record.level() == Level::Error {
                match streams.err {
                    StdTerminal::Stderr(ref mut term) => self.try_log_term(record, term),
                    StdTerminal::Stdout(ref mut term) => self.try_log_term(record, term),
                }
            } else {
                match streams.out {
                    StdTerminal::Stderr(ref mut term) => self.try_log_term(record, term),
                    StdTerminal::Stdout(ref mut term) => self.try_log_term(record, term),
                }
            }
        } else {
            Ok(())
        }
    }
}

impl Log for TermLogger {
    fn enabled(&self, metadata: &Metadata<'_>) -> bool {
        metadata.level() <= self.level
    }

    fn log(&self, record: &Record<'_>) {
        let _ = self.try_log(record);
    }

    fn flush(&self) {
        let mut streams = self.streams.lock().unwrap();
        let _ = streams.out.flush();
        let _ = streams.err.flush();
    }
}

impl SharedLogger for TermLogger {
    fn level(&self) -> LevelFilter {
        self.level
    }

    fn config(&self) -> Option<&Config> {
        Some(&self.config)
    }

    fn as_log(self: Box<Self>) -> Box<dyn Log> {
        Box::new(*self)
    }
}
<|endoftext|>


<commit_before>
// Copyright 2017 The gltf Library Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::collections::HashMap;
use v2::{accessor, material, Extras, Index, Root};

enum_number! {
    Mode {
        Points = 0,
        Lines = 1,
        LineLoop = 2,
        LineStrip = 3,
        Triangles = 4,
        TriangleStrip = 5,
        TriangleFan = 6,
    }
}

/// Extension specific data for `Mesh`.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct MeshExtensions {
    #[serde(default)]
    _allow_extra_fields: (),
}

/// A set of primitives to be rendered.
///
/// A node can contain one or more meshes and its transform places the meshes in
/// the scene.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct Mesh {
    /// Extension specific data.
    #[serde(default)]
    pub extensions: MeshExtensions,

    /// Optional application specific data.
    #[serde(default)]
    pub extras: Extras,

    /// Optional user-defined name for this object.
    pub name: Option<String>,

    /// Defines the geometry to be renderered with a material.
    pub primitives: Vec<Primitive>,

    /// Defines the weights to be applied to the morph targets.
    #[serde(default)]
    pub weights: Vec<f32>,
}

/// Geometry to be rendered with the given material.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct Primitive {
    /// Maps attribute semantic names to the `Accessor`s containing the
    /// corresponding attribute data.
    #[serde(default)]
    pub attributes: HashMap<String, Index<accessor::Accessor>>,

    /// Extension specific data.
    #[serde(default)]
    pub extensions: PrimitiveExtensions,

    /// Optional application specific data.
    #[serde(default)]
    pub extras: Extras,

    /// The `Accessor` that contains the indices.
    pub indices: Option<Index<accessor::Accessor>>,

    /// The material to apply to this primitive when rendering.
    pub material: Index<material::Material>,

    /// The type of primitives to render.
    #[serde(default)]
    pub mode: Mode,

    /// Maps attribute names (only `"POSITION"` and `"NORMAL"`) to their
    /// deviations in the morph target.
    // TODO: Confirm that this the correct implementation.
    #[serde(default)]
    pub targets: Vec<HashMap<String, Index<accessor::Accessor>>>,
}

/// Extension specific data for `Primitive`.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct PrimitiveExtensions {
    #[serde(default)]
    _allow_extra_fields: (),
}

impl Mesh {
    #[doc(hidden)]
    pub fn range_check(&self, root: &Root) -> Result<(), ()> {
        for primitive in &self.primitives {
            for accessor in primitive.attributes.values() {
                let _ = root.try_get(accessor)?;
            }
            if let Some(ref indices) = primitive.indices {
                let _ = root.try_get(indices)?;
            }
            let _ = root.try_get(&primitive.material)?;
            for map in &primitive.targets {
                for accessor in map.values() {
                    let _ = root.try_get(accessor)?;
                }
            }
        }
        Ok(())
    }
}

impl Default for Mode {
    fn default() -> Self {
        Mode::Triangles
    }
}
<commit_msg>make material on primitive optional<commit_after>
// Copyright 2017 The gltf Library Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::collections::HashMap;
use v2::{accessor, material, Extras, Index, Root};

enum_number! {
    Mode {
        Points = 0,
        Lines = 1,
        LineLoop = 2,
        LineStrip = 3,
        Triangles = 4,
        TriangleStrip = 5,
        TriangleFan = 6,
    }
}

/// Extension specific data for `Mesh`.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct MeshExtensions {
    #[serde(default)]
    _allow_extra_fields: (),
}

/// A set of primitives to be rendered.
///
/// A node can contain one or more meshes and its transform places the meshes in
/// the scene.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct Mesh {
    /// Extension specific data.
    #[serde(default)]
    pub extensions: MeshExtensions,

    /// Optional application specific data.
    #[serde(default)]
    pub extras: Extras,

    /// Optional user-defined name for this object.
    pub name: Option<String>,

    /// Defines the geometry to be renderered with a material.
    pub primitives: Vec<Primitive>,

    /// Defines the weights to be applied to the morph targets.
    #[serde(default)]
    pub weights: Vec<f32>,
}

/// Geometry to be rendered with the given material.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct Primitive {
    /// Maps attribute semantic names to the `Accessor`s containing the
    /// corresponding attribute data.
    #[serde(default)]
    pub attributes: HashMap<String, Index<accessor::Accessor>>,

    /// Extension specific data.
    #[serde(default)]
    pub extensions: PrimitiveExtensions,

    /// Optional application specific data.
    #[serde(default)]
    pub extras: Extras,

    /// The `Accessor` that contains the indices.
    pub indices: Option<Index<accessor::Accessor>>,

    /// The material to apply to this primitive when rendering.
    pub material: Option<Index<material::Material>>,

    /// The type of primitives to render.
    #[serde(default)]
    pub mode: Mode,

    /// Maps attribute names (only `"POSITION"` and `"NORMAL"`) to their
    /// deviations in the morph target.
    // TODO: Confirm that this the correct implementation.
    #[serde(default)]
    pub targets: Vec<HashMap<String, Index<accessor::Accessor>>>,
}

/// Extension specific data for `Primitive`.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct PrimitiveExtensions {
    #[serde(default)]
    _allow_extra_fields: (),
}

impl Mesh {
    #[doc(hidden)]
    pub fn range_check(&self, root: &Root) -> Result<(), ()> {
        for primitive in &self.primitives {
            for accessor in primitive.attributes.values() {
                let _ = root.try_get(accessor)?;
            }
            if let Some(ref indices) = primitive.indices {
                let _ = root.try_get(indices)?;
            }
            if let Some(ref material) = primitive.material {
                let _ = root.try_get(&material)?;
            }
            for map in &primitive.targets {
                for accessor in map.values() {
                    let _ = root.try_get(accessor)?;
                }
            }
        }
        Ok(())
    }
}

impl Default for Mode {
    fn default() -> Self {
        Mode::Triangles
    }
}
<|endoftext|>


<commit_before>use std::path::Path;

use find_package;

pub fn upgrade_package(name: &str, path: &Path) {
    let package = find_package::select_package(name, path);
    //Oops, looks like I need to record the version of downloaded package
}<commit_msg>Package upgrade function implemented.<commit_after>use std::path::Path;

use find_package;
use package::{ installation, uninstallation };
use package_version;

pub fn upgrade_package(name: &str, path: &Path) -> Result<bool, String> {
    let selected_package = find_package::select_package(name, path)?;
    let version = match package_version::get_version(&selected_package.name, path) {
        Some(x) => x,
        None => return Err("The package is not available.".to_string())
    };

    if selected_package.version > version {
        uninstallation::uninstall(name, path)?;
        installation::install_package(name, path)?;
        package_version::update_version(name, selected_package.version, path)?;
        return Ok(true)
    } else {
        return Ok(false)
    }
}<|endoftext|>


<commit_before>/* automatically generated by rust-bindgen */

use std::libc::*;
pub type __u_char = c_uchar;
pub type __u_short = c_ushort;
pub type __u_int = c_uint;
pub type __u_long = c_ulong;
pub type __int8_t = c_schar;
pub type __uint8_t = c_uchar;
pub type __int16_t = c_short;
pub type __uint16_t = c_ushort;
pub type __int32_t = c_int;
pub type __uint32_t = c_uint;
pub type __int64_t = c_long;
pub type __uint64_t = c_ulong;
pub type __quad_t = c_long;
pub type __u_quad_t = c_ulong;
pub type __dev_t = c_ulong;
pub type __uid_t = c_uint;
pub type __gid_t = c_uint;
pub type __ino_t = c_ulong;
pub type __ino64_t = c_ulong;
pub type __mode_t = c_uint;
pub type __nlink_t = c_ulong;
pub type __off_t = c_long;
pub type __off64_t = c_long;
pub type __pid_t = c_int;
pub struct __fsid_t {
    __val: [c_int, ..2u],
}
pub type __clock_t = c_long;
pub type __rlim_t = c_ulong;
pub type __rlim64_t = c_ulong;
pub type __id_t = c_uint;
pub type __time_t = c_long;
pub type __useconds_t = c_uint;
pub type __suseconds_t = c_long;
pub type __daddr_t = c_int;
pub type __key_t = c_int;
pub type __clockid_t = c_int;
pub type __timer_t = *mut c_void;
pub type __blksize_t = c_long;
pub type __blkcnt_t = c_long;
pub type __blkcnt64_t = c_long;
pub type __fsblkcnt_t = c_ulong;
pub type __fsblkcnt64_t = c_ulong;
pub type __fsfilcnt_t = c_ulong;
pub type __fsfilcnt64_t = c_ulong;
pub type __fsword_t = c_long;
pub type __ssize_t = c_long;
pub type __syscall_slong_t = c_long;
pub type __syscall_ulong_t = c_ulong;
pub type __loff_t = __off64_t;
pub type __qaddr_t = *mut __quad_t;
pub type __caddr_t = *mut c_schar;
pub type __intptr_t = c_long;
pub type __socklen_t = c_uint;
pub struct Struct_flock {
    l_type: c_short,
    l_whence: c_short,
    l_start: __off64_t,
    l_len: __off64_t,
    l_pid: __pid_t,
}
pub type mode_t = __mode_t;
pub type off_t = __off64_t;
pub type pid_t = __pid_t;
pub struct Struct_timespec {
    tv_sec: __time_t,
    tv_nsec: __syscall_slong_t,
}
pub struct Struct_stat {
    st_dev: __dev_t,
    st_ino: __ino_t,
    st_nlink: __nlink_t,
    st_mode: __mode_t,
    st_uid: __uid_t,
    st_gid: __gid_t,
    __pad0: c_int,
    st_rdev: __dev_t,
    st_size: __off_t,
    st_blksize: __blksize_t,
    st_blocks: __blkcnt_t,
    st_atim: Struct_timespec,
    st_mtim: Struct_timespec,
    st_ctim: Struct_timespec,
    __unused: [__syscall_slong_t, ..3u],
}
extern "C" {
    pub fn fcntl(__fd: c_int, __cmd: c_int) -> c_int;
    pub fn open(__file: *c_schar, __oflag: c_int) -> c_int;
    pub fn openat(__fd: c_int, __file: *c_schar, __oflag: c_int) -> c_int;
    pub fn creat(__file: *c_schar, __mode: mode_t) -> c_int;
    pub fn lockf(__fd: c_int, __cmd: c_int, __len: __off64_t) -> c_int;
    pub fn posix_fadvise(__fd: c_int, __offset: __off64_t, __len: __off64_t,
                         __advise: c_int) -> c_int;
    pub fn posix_fallocate(__fd: c_int, __offset: __off64_t, __len: __off64_t)
     -> c_int;
}
<commit_msg>Remove unused file<commit_after><|endoftext|>


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

use std;
use rustc;

import option;
import option::{some, none};
import rustc::syntax::ast;
import rustc::syntax::codemap;
import rustc::syntax::parse::parser;
import rustc::syntax::print::pprust;
import rustc::syntax::visit;
import std::io;
import std::map;

type rustdoc = {
    ps: pprust::ps,
    w: io::writer
};

type fndoc = {
    brief: str,
    desc: option::t<str>,
    return: option::t<str>,
    args: map::hashmap<str, str>
};

#[doc(
  brief = "Documents a single function.",
  args(rd = "Rustdoc context",
       ident = "Identifier for this function",
       doc = "Function docs extracted from attributes",
       _fn = "AST object representing this function")
)]
fn doc_fn(rd: rustdoc, ident: str, doc: fndoc, _fn: ast::_fn) {
    rd.w.write_line("## Function `" + ident + "`");
    rd.w.write_line(doc.brief);
    alt doc.desc {
        some(_d) {
            rd.w.write_line("");
            rd.w.write_line(_d);
            rd.w.write_line("");
        }
        none. { }
    }
    for arg: ast::arg in _fn.decl.inputs {
        rd.w.write_str("### Argument `" + arg.ident + "`: ");
        rd.w.write_line("`" + pprust::ty_to_str(arg.ty) + "`");
        alt doc.args.find(arg.ident) {
            some(_d) {
                rd.w.write_line(_d);
            }
            none. { }
        };
    }
    rd.w.write_line("### Returns `" + pprust::ty_to_str(_fn.decl.output) + "`");
    alt doc.return {
        some(_r) { rd.w.write_line(_r); }
        none. { }
    }
}

#[doc(
  brief = "Parses function docs from a complex #[doc] attribute.",
  desc = "Supported attributes:

* `brief`: Brief description
* `desc`: Long description
* `return`: Description of return value
* `args`: List of argname = argdesc pairs
",
  args(items = "Doc attribute contents"),
  return = "Parsed function docs."
)]
fn parse_compound_fndoc(items: [@ast::meta_item]) -> fndoc {
    let brief = none;
    let desc = none;
    let return = none;
    let argdocs = map::new_str_hash::<str>();
    let argdocsfound = none;
    for item: @ast::meta_item in items {
        alt item.node {
            ast::meta_name_value("brief", {node: ast::lit_str(value),
                                           span: _}) {
                brief = some(value);
            }
            ast::meta_name_value("desc", {node: ast::lit_str(value),
                                              span: _}) {
                desc = some(value);
            }
            ast::meta_name_value("return", {node: ast::lit_str(value),
                                            span: _}) {
                return = some(value);
            }
            ast::meta_list("args", args) {
                argdocsfound = some(args);
            }
            _ { }
        }
    }

    alt argdocsfound {
        none. { }
        some(ds) {
            for d: @ast::meta_item in ds {
                alt d.node {
                    ast::meta_name_value(key, {node: ast::lit_str(value),
                                               span: _}) {
                        argdocs.insert(key, value);
                    }
                }
            }
        }
    }

    let _brief = alt brief {
        some(_b) { _b }
        none. { "_undocumented_" }
    };

    { brief: _brief, desc: desc, return: return, args: argdocs }
}

#[doc(
  brief = "Documents a single crate item.",
  args(rd = "Rustdoc context",
       item = "AST item to document")
)]
fn doc_item(rd: rustdoc, item: @ast::item) {
    let _fndoc = none;
    let noargdocs = map::new_str_hash::<str>();
    for attr: ast::attribute in item.attrs {
        alt attr.node.value.node {
            ast::meta_name_value("doc", {node: ast::lit_str(value), span: _}) {
                _fndoc = some({ brief: value,
                                desc: none,
                                return: none,
                                args: noargdocs });
            }
            ast::meta_list("doc", docs) {
                _fndoc = some(parse_compound_fndoc(docs));
            }
        }
    }

    let _fndoc0 = alt _fndoc {
        some(_d) { _d }
        none. { { brief: "_undocumented_", desc: none, return: none, args: noargdocs } }
    };

    alt item.node {
        ast::item_const(ty, expr) { }
        ast::item_fn(_fn, _) {
            doc_fn(rd, item.ident, _fndoc0, _fn);
        }
        ast::item_mod(_mod) { }
        ast::item_ty(ty, typarams) { }
        ast::item_tag(variant, typarams) { }
        ast::item_obj(_obj, typarams, node_id) { }
        ast::item_res(dtor, dtorid, typarams, ctorid) { }
    };
}

#[doc(
  brief = "Generate a crate document header.",
  args(rd = "Rustdoc context",
       name = "Crate name")
)]
fn doc_header(rd: rustdoc, name: str) {
    rd.w.write_line("# Crate " + name);
}

#[doc(
  brief = "Main function.",
  desc = "Command-line arguments:

*  argv[1]: crate file name",
  args(argv = "Command-line arguments.")
)]
fn main(argv: [str]) {
    let sess = @{cm: codemap::new_codemap(), mutable next_id: 0};
    let w = io::stdout();
    let rd = { ps: pprust::rust_printer(w), w: w };
    doc_header(rd, argv[1]);
    let p = parser::parse_crate_from_source_file(argv[1], [], sess);
    let v = visit::mk_simple_visitor(@{
        visit_item: bind doc_item(rd, _)
        with *visit::default_simple_visitor()});
    visit::visit_crate(*p, (), v);
}
<commit_msg>rustdoc: delete bogus license text<commit_after>/* rustdoc: rust -> markdown translator
 * Copyright 2011 Google Inc. All Rights Reserved.
 */

use std;
use rustc;

import option;
import option::{some, none};
import rustc::syntax::ast;
import rustc::syntax::codemap;
import rustc::syntax::parse::parser;
import rustc::syntax::print::pprust;
import rustc::syntax::visit;
import std::io;
import std::map;

type rustdoc = {
    ps: pprust::ps,
    w: io::writer
};

type fndoc = {
    brief: str,
    desc: option::t<str>,
    return: option::t<str>,
    args: map::hashmap<str, str>
};

#[doc(
  brief = "Documents a single function.",
  args(rd = "Rustdoc context",
       ident = "Identifier for this function",
       doc = "Function docs extracted from attributes",
       _fn = "AST object representing this function")
)]
fn doc_fn(rd: rustdoc, ident: str, doc: fndoc, _fn: ast::_fn) {
    rd.w.write_line("## Function `" + ident + "`");
    rd.w.write_line(doc.brief);
    alt doc.desc {
        some(_d) {
            rd.w.write_line("");
            rd.w.write_line(_d);
            rd.w.write_line("");
        }
        none. { }
    }
    for arg: ast::arg in _fn.decl.inputs {
        rd.w.write_str("### Argument `" + arg.ident + "`: ");
        rd.w.write_line("`" + pprust::ty_to_str(arg.ty) + "`");
        alt doc.args.find(arg.ident) {
            some(_d) {
                rd.w.write_line(_d);
            }
            none. { }
        };
    }
    rd.w.write_line("### Returns `" + pprust::ty_to_str(_fn.decl.output) + "`");
    alt doc.return {
        some(_r) { rd.w.write_line(_r); }
        none. { }
    }
}

#[doc(
  brief = "Parses function docs from a complex #[doc] attribute.",
  desc = "Supported attributes:

* `brief`: Brief description
* `desc`: Long description
* `return`: Description of return value
* `args`: List of argname = argdesc pairs
",
  args(items = "Doc attribute contents"),
  return = "Parsed function docs."
)]
fn parse_compound_fndoc(items: [@ast::meta_item]) -> fndoc {
    let brief = none;
    let desc = none;
    let return = none;
    let argdocs = map::new_str_hash::<str>();
    let argdocsfound = none;
    for item: @ast::meta_item in items {
        alt item.node {
            ast::meta_name_value("brief", {node: ast::lit_str(value),
                                           span: _}) {
                brief = some(value);
            }
            ast::meta_name_value("desc", {node: ast::lit_str(value),
                                              span: _}) {
                desc = some(value);
            }
            ast::meta_name_value("return", {node: ast::lit_str(value),
                                            span: _}) {
                return = some(value);
            }
            ast::meta_list("args", args) {
                argdocsfound = some(args);
            }
            _ { }
        }
    }

    alt argdocsfound {
        none. { }
        some(ds) {
            for d: @ast::meta_item in ds {
                alt d.node {
                    ast::meta_name_value(key, {node: ast::lit_str(value),
                                               span: _}) {
                        argdocs.insert(key, value);
                    }
                }
            }
        }
    }

    let _brief = alt brief {
        some(_b) { _b }
        none. { "_undocumented_" }
    };

    { brief: _brief, desc: desc, return: return, args: argdocs }
}

#[doc(
  brief = "Documents a single crate item.",
  args(rd = "Rustdoc context",
       item = "AST item to document")
)]
fn doc_item(rd: rustdoc, item: @ast::item) {
    let _fndoc = none;
    let noargdocs = map::new_str_hash::<str>();
    for attr: ast::attribute in item.attrs {
        alt attr.node.value.node {
            ast::meta_name_value("doc", {node: ast::lit_str(value), span: _}) {
                _fndoc = some({ brief: value,
                                desc: none,
                                return: none,
                                args: noargdocs });
            }
            ast::meta_list("doc", docs) {
                _fndoc = some(parse_compound_fndoc(docs));
            }
        }
    }

    let _fndoc0 = alt _fndoc {
        some(_d) { _d }
        none. { { brief: "_undocumented_", desc: none, return: none, args: noargdocs } }
    };

    alt item.node {
        ast::item_const(ty, expr) { }
        ast::item_fn(_fn, _) {
            doc_fn(rd, item.ident, _fndoc0, _fn);
        }
        ast::item_mod(_mod) { }
        ast::item_ty(ty, typarams) { }
        ast::item_tag(variant, typarams) { }
        ast::item_obj(_obj, typarams, node_id) { }
        ast::item_res(dtor, dtorid, typarams, ctorid) { }
    };
}

#[doc(
  brief = "Generate a crate document header.",
  args(rd = "Rustdoc context",
       name = "Crate name")
)]
fn doc_header(rd: rustdoc, name: str) {
    rd.w.write_line("# Crate " + name);
}

#[doc(
  brief = "Main function.",
  desc = "Command-line arguments:

*  argv[1]: crate file name",
  args(argv = "Command-line arguments.")
)]
fn main(argv: [str]) {
    let sess = @{cm: codemap::new_codemap(), mutable next_id: 0};
    let w = io::stdout();
    let rd = { ps: pprust::rust_printer(w), w: w };
    doc_header(rd, argv[1]);
    let p = parser::parse_crate_from_source_file(argv[1], [], sess);
    let v = visit::mk_simple_visitor(@{
        visit_item: bind doc_item(rd, _)
        with *visit::default_simple_visitor()});
    visit::visit_crate(*p, (), v);
}
<|endoftext|>


<commit_before>use std::sync::{Arc, Mutex};
use std::thread;
use std::process::{Command, Stdio, ChildStdout};
use std::io::Read;
use std::cmp;

const INTERVAL: u64 = 5;

pub struct NetStat {
    rx: u64,
    tx: u64,
    rx_max: u64,
    tx_max: u64,
}

impl NetStat {
    pub fn open() -> Arc<Mutex<NetStat>> {
        let netstat = Arc::new(Mutex::new(
                NetStat { rx: 0, tx: 0, rx_max: 1, tx_max: 1 }
                ));
        let netstat_thread = netstat.clone();
        let netstat_main = netstat.clone();
        thread::spawn(move || {
            match Command::new("netstat")
                .arg("-ib")
                .arg(INTERVAL.to_string())
                .stdout(Stdio::piped())
                .spawn() {
                    Err(_)  => (),
                    Ok(p)   => NetStat::read_loop(netstat_thread, &mut p.stdout.unwrap()),
                }
        });
        netstat_main
    }

    fn read_loop(netstat: Arc<Mutex<NetStat>>, out: &mut ChildStdout) {
        for _ in 1..3 {
            let mut buf = vec![0;512];
            out.read(&mut buf).unwrap();
        }
        loop {
            let mut buf = vec![0;512];
            let size = out.read(&mut buf).unwrap();
            buf.truncate(size);
            let s = String::from_utf8(buf).unwrap();
            let words: Vec<&str> = s.split_whitespace().collect();
            let wc = words.len();
            if wc >= 2 {
                let mut n = netstat.lock().unwrap();
                if let Ok(newrx) = words[wc - 2].parse::<u64>() {
                    n.rx = newrx / INTERVAL;
                    n.rx_max = cmp::max(n.rx, n.rx_max);
                }
                if let Ok(newtx) = words[wc - 1].parse::<u64>() {
                    n.tx = newtx / INTERVAL;
                    n.tx_max = cmp::max(n.tx, n.tx_max);
                }
            }
        }
    }

    pub fn fetch(netstat: &Arc<Mutex<NetStat>>) -> (u32, u32) {
        let n = netstat.lock().unwrap();
        (
            (n.rx * 100 / n.rx_max) as u32,
            (n.tx * 100 / n.tx_max) as u32
        )
    }
}
<commit_msg>Add netstat support for FreeBSD<commit_after>use std::sync::{Arc, Mutex};
use std::thread;
use std::process::{Command, Stdio, ChildStdout};
use std::io::Read;
use std::cmp;

const INTERVAL: u64 = 5;

macro_rules! constants_for_system {
    ( $s:expr => $(const $l:ident: $t:ty = $e:expr);*; ) =>
    {
        $(
        #[cfg(target_os = $s)]
        const $l : $t = $e
        );*;
    }
}

constants_for_system!("openbsd" =>
                      const NETSTAT_COLUMNS: usize = 2;
                      const NETSTAT_COLUMN_RX: usize = 2;
                      const NETSTAT_COLUMN_TX: usize = 1;
                     );

constants_for_system!("freebsd" =>
                      const NETSTAT_COLUMNS: usize = 8;
                      const NETSTAT_COLUMN_RX: usize = 5;
                      const NETSTAT_COLUMN_TX: usize = 2;
                     );

pub struct NetStat {
    rx: u64,
    tx: u64,
    rx_max: u64,
    tx_max: u64,
}

impl NetStat {
    pub fn open() -> Arc<Mutex<NetStat>> {
        let netstat = Arc::new(Mutex::new(
                NetStat { rx: 0, tx: 0, rx_max: 1, tx_max: 1 }
                ));
        let netstat_thread = netstat.clone();
        let netstat_main = netstat.clone();
        thread::spawn(move || {
            match Command::new("netstat")
                .arg("-ib")
                .arg(INTERVAL.to_string())
                .stdout(Stdio::piped())
                .spawn() {
                    Err(_)  => (),
                    Ok(p)   => NetStat::read_loop(netstat_thread, &mut p.stdout.unwrap()),
                }
        });
        netstat_main
    }

    fn read_loop(netstat: Arc<Mutex<NetStat>>, out: &mut ChildStdout) {
        for _ in 1..3 {
            let mut buf = vec![0;512];
            out.read(&mut buf).unwrap();
        }
        loop {
            let mut buf = vec![0;512];
            let size = out.read(&mut buf).unwrap();
            buf.truncate(size);
            let s = String::from_utf8(buf).unwrap();
            let words: Vec<&str> = s.split_whitespace().collect();
            let wc = words.len();
            if wc >= NETSTAT_COLUMNS {
                let mut n = netstat.lock().unwrap();
                if let Ok(newrx) = words[wc - NETSTAT_COLUMN_RX].parse::<u64>() {
                    n.rx = newrx / INTERVAL;
                    n.rx_max = cmp::max(n.rx, n.rx_max);
                }
                if let Ok(newtx) = words[wc - NETSTAT_COLUMN_TX].parse::<u64>() {
                    n.tx = newtx / INTERVAL;
                    n.tx_max = cmp::max(n.tx, n.tx_max);
                }
            }
        }
    }

    pub fn fetch(netstat: &Arc<Mutex<NetStat>>) -> (u32, u32) {
        let n = netstat.lock().unwrap();
        (
            (n.rx * 100 / n.rx_max) as u32,
            (n.tx * 100 / n.tx_max) as u32
        )
    }
}
<|endoftext|>


<commit_before>use core::float::consts::pi;

use angle::*;
use mat::Mat4;
use vec::{Vec3, Vec4};

#[test]
fn test_radians() {
    assert *Radians(0.0).to_degrees()           == *Degrees(0.0);
    assert *Radians(pi / 4.0).to_degrees()      == *Degrees(45.0);
    assert *Radians(pi / 2.0).to_degrees()      == *Degrees(90.0);
    assert *Radians(pi).to_degrees()            == *Degrees(180.0);
    assert *Radians(2.0 * pi).to_degrees()      == *Degrees(360.0);
    assert *Radians(5.0 * pi).to_degrees()      == *Degrees(900.0);
    assert *Radians(-pi).to_degrees()           == *Degrees(-180.0);

    assert *Radians(0.0).to_radians()           == *Radians(0.0);
    assert *Radians(5.0 * pi).to_radians()      == *Radians(5.0 * pi);
    assert *Radians(-pi).to_radians()           == *Radians(-pi);

    assert *Radians(pi).wrap()                  == *Radians(pi);
    assert *Radians(3.0 * pi).wrap()            == *Radians(pi);
    assert *Radians(2.0 * pi).wrap()            == *Radians(0.0);
    assert *Radians(-pi).wrap()                 == *Radians(-pi);
    assert *Radians(-3.0 * pi).wrap()           == *Radians(-pi);
    assert *Radians(-2.0 * pi).wrap()           == *Radians(0.0);

    assert *(Radians(pi) + Radians(pi))         == *Radians(2.0 * pi);
    assert *(Radians(2.0 * pi) - Radians(pi))   == *Radians(pi);
    assert *(Radians(pi) * 2.0)                 == *Radians(2.0 * pi);
    assert *(Radians(pi) / 2.0)                 == *Radians(pi / 2.0);
    assert *(Radians(3.0 * pi) % (2.0 * pi))    == *Radians(pi);
    assert *(-Radians(pi))                      == *Radians(-pi);
}

#[test]
fn test_degrees() {
    assert *Degrees(0.0).to_radians()           == *Radians(0.0)      as float;
    assert *Degrees(45.0).to_radians()          == *Radians(pi / 4.0) as float;
    assert *Degrees(90.0).to_radians()          == *Radians(pi / 2.0) as float;
    assert *Degrees(180.0).to_radians()         == *Radians(pi)       as float;
    assert *Degrees(360.0).to_radians()         == *Radians(2.0 * pi) as float;
    assert *Degrees(900.0).to_radians()         == *Radians(5.0 * pi) as float;
    assert *Degrees(-180.0).to_radians()        == *Radians(-pi)      as float;

    assert *Degrees(0.0).to_degrees()           == *Degrees(0.0);
    assert *Degrees(900.0).to_degrees()         == *Degrees(900.0);
    assert *Degrees(-180.0).to_degrees()        == *Degrees(-180.0);

    assert *Degrees(90.0).wrap()                == *Degrees(90.0);
    assert *Degrees(450.0).wrap()               == *Degrees(90.0);
    assert *Degrees(360.0).wrap()               == *Degrees(0.0);
    assert *Degrees(-90.0).wrap()               == *Degrees(-90.0);
    assert *Degrees(-450.0).wrap()              == *Degrees(-90.0);
    assert *Degrees(-360.0).wrap()              == *Degrees(0.0);

    assert *(Degrees(180.0) + Degrees(180.0))   == *Degrees(360.0);
    assert *(Degrees(360.0) - Degrees(180.0))   == *Degrees(180.0);
    assert *(Degrees(360.0) * 2.0)              == *Degrees(720.0);
    assert *(Degrees(180.0) / 2.0)              == *Degrees(90.0);
    assert *(Degrees(540.0) % (360.0))          == *Degrees(180.0);
    assert *(-Degrees(180.0))                   == *Degrees(-180.0);
}

#[test]
fn test_rotation() {
    {
        let pos = Vec4::new(1.0, 0.0, 0.0, 1.0);   // the position to transform
        let rot = Rotation {
            theta: Degrees(180.0).to_radians(),
            axis:  Vec3::new(0.0, 0.0, 1.0),       // unit_z
        };

        let newpos = rot.to_mat4().mul_v(&pos);
        let expected_pos = Vec4::new(-1.0, 0.0, 0.0, 1.0);

        assert newpos == expected_pos;
    }
    {
        let pos = Vec4::new(4f32, 0f32, 0f32, 1f32);

        let rot_a = Rotation {
            theta: Degrees(90f32).to_radians(),
            axis:  Vec3::new(0f32, 1f32, 0f32),     // unit_y
        };

        let rot_b = Rotation {
            theta: Degrees(90f32).to_radians(),
            axis:  -Vec3::new(0f32, 1f32, 0f32),    // -unit_y
        };

        let newpos_a = rot_a.to_mat4().mul_v(&pos);
        let newpos_b = rot_b.to_mat4().mul_v(&pos);

        let expected_pos_a = Vec4::new(0f32, 0f32, -4f32, 1f32);
        let expected_pos_b = Vec4::new(0f32, 0f32,  4f32, 1f32);

        assert newpos_a == expected_pos_a;
        assert newpos_b == expected_pos_b;
    }

    // TODO: test to_quat
}<commit_msg>Remove enum unwrapping<commit_after>use core::float::consts::pi;

use angle::*;
use mat::Mat4;
use vec::{Vec3, Vec4};

#[test]
fn test_radians() {
    assert Radians(0.0).to_degrees()            == Degrees(0.0);
    assert *Radians(pi / 4.0).to_degrees()      == *Degrees(45.0);   // Removing the unwrap operators causes an ICE.
    assert *Radians(pi / 2.0).to_degrees()      == *Degrees(90.0);   // I think it only happens on operations where
    assert *Radians(pi).to_degrees()            == *Degrees(180.0);  // Rust has to do a bit of type inference.
    assert *Radians(2.0 * pi).to_degrees()      == *Degrees(360.0);
    assert *Radians(5.0 * pi).to_degrees()      == *Degrees(900.0);
    assert *Radians(-pi).to_degrees()           == *Degrees(-180.0);

    assert Radians(0.0).to_radians()            == Radians(0.0);
    assert *Radians(5.0 * pi).to_radians()      == *Radians(5.0 * pi);
    assert *Radians(-pi).to_radians()           == *Radians(-pi);

    assert *Radians(pi).wrap()                  == *Radians(pi);
    assert *Radians(3.0 * pi).wrap()            == *Radians(pi);
    assert *Radians(2.0 * pi).wrap()            == *Radians(0.0);
    assert *Radians(-pi).wrap()                 == *Radians(-pi);
    assert *Radians(-3.0 * pi).wrap()           == *Radians(-pi);
    assert *Radians(-2.0 * pi).wrap()           == *Radians(0.0);

    assert *(Radians(pi) + Radians(pi))         == *Radians(2.0 * pi);
    assert *(Radians(2.0 * pi) - Radians(pi))   == *Radians(pi);
    assert *(Radians(pi) * 2.0)                 == *Radians(2.0 * pi);
    assert *(Radians(pi) / 2.0)                 == *Radians(pi / 2.0);
    assert *(Radians(3.0 * pi) % (2.0 * pi))    == *Radians(pi);
    assert *(-Radians(pi))                      == *Radians(-pi);
}

#[test]
fn test_degrees() {
    assert Degrees(0.0).to_radians()            == Radians(0.0);
    assert Degrees(45.0).to_radians()           == Radians(pi / 4.0 as float);  // Rust can't infer these types
    assert Degrees(90.0).to_radians()           == Radians(pi / 2.0 as float);
    assert Degrees(180.0).to_radians()          == Radians(pi       as float);
    assert Degrees(360.0).to_radians()          == Radians(2.0 * pi as float);
    assert Degrees(900.0).to_radians()          == Radians(5.0 * pi as float);
    assert Degrees(-180.0).to_radians()         == Radians(-pi      as float);

    assert Degrees(0.0).to_degrees()            == Degrees(0.0);
    assert Degrees(900.0).to_degrees()          == Degrees(900.0);
    assert Degrees(-180.0).to_degrees()         == Degrees(-180.0);

    assert Degrees(90.0).wrap()                 == Degrees(90.0);
    assert Degrees(450.0).wrap()                == Degrees(90.0);
    assert Degrees(360.0).wrap()                == Degrees(0.0);
    assert Degrees(-90.0).wrap()                == Degrees(-90.0);
    assert Degrees(-450.0).wrap()               == Degrees(-90.0);
    assert Degrees(-360.0).wrap()               == Degrees(0.0);

    assert (Degrees(180.0) + Degrees(180.0))    == Degrees(360.0);
    assert (Degrees(360.0) - Degrees(180.0))    == Degrees(180.0);
    assert (Degrees(360.0) * 2.0)               == Degrees(720.0);
    assert (Degrees(180.0) / 2.0)               == Degrees(90.0);
    assert (Degrees(540.0) % (360.0))           == Degrees(180.0);
    assert (-Degrees(180.0))                    == Degrees(-180.0);
}

#[test]
fn test_rotation() {
    {
        let pos = Vec4::new(1.0, 0.0, 0.0, 1.0);   // the position to transform
        let rot = Rotation {
            theta: Degrees(180.0).to_radians(),
            axis:  Vec3::new(0.0, 0.0, 1.0),       // unit_z
        };

        let newpos = rot.to_mat4().mul_v(&pos);
        let expected_pos = Vec4::new(-1.0, 0.0, 0.0, 1.0);

        assert newpos == expected_pos;
    }
    {
        let pos = Vec4::new(4f32, 0f32, 0f32, 1f32);

        let rot_a = Rotation {
            theta: Degrees(90f32).to_radians(),
            axis:  Vec3::new(0f32, 1f32, 0f32),     // unit_y
        };

        let rot_b = Rotation {
            theta: Degrees(90f32).to_radians(),
            axis:  -Vec3::new(0f32, 1f32, 0f32),    // -unit_y
        };

        let newpos_a = rot_a.to_mat4().mul_v(&pos);
        let newpos_b = rot_b.to_mat4().mul_v(&pos);

        let expected_pos_a = Vec4::new(0f32, 0f32, -4f32, 1f32);
        let expected_pos_b = Vec4::new(0f32, 0f32,  4f32, 1f32);

        assert newpos_a == expected_pos_a;
        assert newpos_b == expected_pos_b;
    }

    // TODO: test to_quat
}<|endoftext|>


<commit_before>// -*- rust -*-

import driver.session;
import front.ast;
import lib.llvm.llvmext;
import lib.llvm.mk_object_file;
import lib.llvm.mk_section_iter;
import middle.fold;
import middle.ty;
import util.common;
import util.common.span;

import std._str;
import std._vec;
import std.fs;
import std.option;
import std.os;
import std.map.hashmap;

// TODO: map to a real type here.
type env = @rec(
    @hashmap[str, @ast.external_crate_info] crate_cache,
    vec[str] library_search_paths
);

// Type decoding

// Compact string representation for ty.t values. API ty_str & parse_from_str.
// (The second has to be authed pure.) Extra parameters are for converting
// to/from def_ids in the string rep. Whatever format you choose should not
// contain pipe characters.

// Callback to translate defs to strs or back.
type str_def = fn(str) -> ast.def_id;

type pstate = rec(str rep, mutable uint pos, uint len);

fn peek(@pstate st) -> u8 {
    if (st.pos < st.len) {ret st.rep.(st.pos) as u8;}
    else {ret ' ' as u8;}
}
impure fn next(@pstate st) -> u8 { // ?? somehow not recognized as impure
    if (st.pos >= st.len) {fail;}
    auto ch = st.rep.(st.pos);
    st.pos = st.pos + 1u;
    ret ch as u8;
}

impure fn parse_ty_str(str rep, str_def sd) -> @ty.t {
    auto len = _str.byte_len(rep);
    auto st = @rec(rep=rep, mutable pos=0u, len=len);
    auto result = parse_ty(st, sd);
    check(st.pos == len);
    ret result;
}

impure fn parse_ty(@pstate st, str_def sd) -> @ty.t {
    ret @rec(struct=parse_sty(st, sd),
             cname=option.none[str]);
}

impure fn parse_mt(@pstate st, str_def sd) -> ty.mt {
    auto mut;
    alt (peek(st) as char) {
        case ('m') {next(st); mut = ast.mut;}
        case ('?') {next(st); mut = ast.maybe_mut;}
        case (_)   {mut=ast.imm;}
    }
    ret rec(ty=parse_ty(st, sd), mut=mut);
}

impure fn parse_sty(@pstate st, str_def sd) -> ty.sty {
    alt (next(st) as char) {
        case ('n') {ret ty.ty_nil;}
        case ('b') {ret ty.ty_bool;}
        case ('i') {ret ty.ty_int;}
        case ('u') {ret ty.ty_uint;}
        case ('M') {
            alt (next(st) as char) {
                case ('b') {ret ty.ty_machine(common.ty_u8);}
                case ('w') {ret ty.ty_machine(common.ty_u16);}
                case ('l') {ret ty.ty_machine(common.ty_u32);}
                case ('d') {ret ty.ty_machine(common.ty_u64);}
                case ('B') {ret ty.ty_machine(common.ty_i8);}
                case ('W') {ret ty.ty_machine(common.ty_i16);}
                case ('L') {ret ty.ty_machine(common.ty_i32);}
                case ('D') {ret ty.ty_machine(common.ty_i64);}
                case ('f') {ret ty.ty_machine(common.ty_f32);}
                case ('F') {ret ty.ty_machine(common.ty_f64);}
            }
        }
        case ('c') {ret ty.ty_char;}
        case ('s') {ret ty.ty_str;}
        case ('t') {
            check(next(st) as char == '[');
            auto def = "";
            while (peek(st) as char != '|') {
                def += _str.unsafe_from_byte(next(st));
            }
            st.pos = st.pos + 1u;
            let vec[@ty.t] params = vec();
            while (peek(st) as char != ']') {
                params += vec(parse_ty(st, sd));
            }
            st.pos = st.pos + 1u;
            ret ty.ty_tag(sd(def), params);
        }
        case ('@') {ret ty.ty_box(parse_mt(st, sd));}
        case ('V') {ret ty.ty_vec(parse_mt(st, sd));}
        case ('P') {ret ty.ty_port(parse_ty(st, sd));}
        case ('C') {ret ty.ty_chan(parse_ty(st, sd));}
        case ('T') {
            check(next(st) as char == '[');
            let vec[ty.mt] params = vec();
            while (peek(st) as char != ']') {
                params += vec(parse_mt(st, sd));
            }
            st.pos = st.pos + 1u;
            ret ty.ty_tup(params);
        }
        case ('R') {
            check(next(st) as char == '[');
            let vec[ty.field] fields = vec();
            while (peek(st) as char != ']') {
                auto name = "";
                while (peek(st) as char != '=') {
                    name += _str.unsafe_from_byte(next(st));
                }
                st.pos = st.pos + 1u;
                fields += vec(rec(ident=name, mt=parse_mt(st, sd)));
            }
            st.pos = st.pos + 1u;
            ret ty.ty_rec(fields);
        }
        case ('F') {
            auto func = parse_ty_fn(st, sd);
            ret ty.ty_fn(ast.proto_fn, func._0, func._1);
        }
        case ('W') {
            auto func = parse_ty_fn(st, sd);
            ret ty.ty_fn(ast.proto_iter, func._0, func._1);
        }
        case ('N') {
            auto abi;
            alt (next(st) as char) {
                case ('r') {abi = ast.native_abi_rust;}
                case ('c') {abi = ast.native_abi_cdecl;}
            }
            auto func = parse_ty_fn(st, sd);
            ret ty.ty_native_fn(abi,func._0,func._1);
        }
        case ('O') {
            check(next(st) as char == '[');
            let vec[ty.method] methods = vec();
            while (peek(st) as char != ']') {
                auto proto;
                alt (next(st) as char) {
                    case ('W') {proto = ast.proto_iter;}
                    case ('F') {proto = ast.proto_fn;}
                }
                auto name = "";
                while (peek(st) as char != '[') {
                    name += _str.unsafe_from_byte(next(st));
                }
                auto func = parse_ty_fn(st, sd);
                methods += vec(rec(proto=proto,
                                   ident=name,
                                   inputs=func._0,
                                   output=func._1));
            }
            ret ty.ty_obj(methods);
        }
        case ('X') {ret ty.ty_var(parse_int(st));}
        case ('E') {ret ty.ty_native;}
    }
}

impure fn parse_int(@pstate st) -> int {
    auto n = 0;
    while (true) {
        auto cur = peek(st) as char;
        if (cur < '0' || cur > '9') {break;}
        st.pos = st.pos + 1u;
        n *= 10;
        n += (cur as int) - ('0' as int);
    }
    ret n;
}

impure fn parse_ty_fn(@pstate st, str_def sd) -> tup(vec[ty.arg], @ty.t) {
    check(next(st) as char == '[');
    let vec[ty.arg] inputs = vec();
    while (peek(st) as char != ']') {
        auto mode = ast.val;
        if (peek(st) as char == '&') {
            mode = ast.alias;
            st.pos = st.pos + 1u;
        }
        inputs += vec(rec(mode=mode, ty=parse_ty(st, sd)));
    }
    st.pos = st.pos + 1u;
    ret tup(inputs, parse_ty(st, sd));
}

// TODO: return something
fn load_crate(ast.ident ident, vec[str] library_search_paths) -> @() {
    for (str library_search_path in library_search_paths) {
        auto path = fs.connect(library_search_path, ident);
        // TODO
    }

    ret @();
}

fn fold_view_item_use(&env e, &span sp, ast.ident ident,
        vec[@ast.meta_item] meta_items, ast.def_id id, ast.ann orig_ann)
        -> @ast.view_item {
    auto external_crate;
    if (!e.crate_cache.contains_key(ident)) {
        external_crate = load_crate(ident, e.library_search_paths);
        e.crate_cache.insert(ident, external_crate);
    } else {
        external_crate = e.crate_cache.get(ident);
    }

    auto ann = ast.ann_crate(external_crate);
    auto viu = ast.view_item_use(ident, meta_items, id, ann);
    ret @fold.respan[ast.view_item_](sp, viu);
}

// Reads external crates referenced by "use" directives.
fn read_crates(session.session sess,
               @ast.crate crate,
               vec[str] library_search_paths) -> @ast.crate {
    auto e = @rec(
        crate_cache=@common.new_str_hash[@ast.external_crate_info](),
        library_search_paths=library_search_paths
    );

    auto f = fold_view_item_use;
    auto fld = @rec(fold_view_item_use=f with *fold.new_identity_fold[env]());
    ret fold.fold_crate[env](e, fld, crate);
}

<commit_msg>Teach creader about reading ty_float, and trim trailing whitespace.<commit_after>// -*- rust -*-

import driver.session;
import front.ast;
import lib.llvm.llvmext;
import lib.llvm.mk_object_file;
import lib.llvm.mk_section_iter;
import middle.fold;
import middle.ty;
import util.common;
import util.common.span;

import std._str;
import std._vec;
import std.fs;
import std.option;
import std.os;
import std.map.hashmap;

// TODO: map to a real type here.
type env = @rec(
    @hashmap[str, @ast.external_crate_info] crate_cache,
    vec[str] library_search_paths
);

// Type decoding

// Compact string representation for ty.t values. API ty_str & parse_from_str.
// (The second has to be authed pure.) Extra parameters are for converting
// to/from def_ids in the string rep. Whatever format you choose should not
// contain pipe characters.

// Callback to translate defs to strs or back.
type str_def = fn(str) -> ast.def_id;

type pstate = rec(str rep, mutable uint pos, uint len);

fn peek(@pstate st) -> u8 {
    if (st.pos < st.len) {ret st.rep.(st.pos) as u8;}
    else {ret ' ' as u8;}
}
impure fn next(@pstate st) -> u8 { // ?? somehow not recognized as impure
    if (st.pos >= st.len) {fail;}
    auto ch = st.rep.(st.pos);
    st.pos = st.pos + 1u;
    ret ch as u8;
}

impure fn parse_ty_str(str rep, str_def sd) -> @ty.t {
    auto len = _str.byte_len(rep);
    auto st = @rec(rep=rep, mutable pos=0u, len=len);
    auto result = parse_ty(st, sd);
    check(st.pos == len);
    ret result;
}

impure fn parse_ty(@pstate st, str_def sd) -> @ty.t {
    ret @rec(struct=parse_sty(st, sd),
             cname=option.none[str]);
}

impure fn parse_mt(@pstate st, str_def sd) -> ty.mt {
    auto mut;
    alt (peek(st) as char) {
        case ('m') {next(st); mut = ast.mut;}
        case ('?') {next(st); mut = ast.maybe_mut;}
        case (_)   {mut=ast.imm;}
    }
    ret rec(ty=parse_ty(st, sd), mut=mut);
}

impure fn parse_sty(@pstate st, str_def sd) -> ty.sty {
    alt (next(st) as char) {
        case ('n') {ret ty.ty_nil;}
        case ('b') {ret ty.ty_bool;}
        case ('i') {ret ty.ty_int;}
        case ('u') {ret ty.ty_uint;}
        case ('l') {ret ty.ty_float;}
        case ('M') {
            alt (next(st) as char) {
                case ('b') {ret ty.ty_machine(common.ty_u8);}
                case ('w') {ret ty.ty_machine(common.ty_u16);}
                case ('l') {ret ty.ty_machine(common.ty_u32);}
                case ('d') {ret ty.ty_machine(common.ty_u64);}
                case ('B') {ret ty.ty_machine(common.ty_i8);}
                case ('W') {ret ty.ty_machine(common.ty_i16);}
                case ('L') {ret ty.ty_machine(common.ty_i32);}
                case ('D') {ret ty.ty_machine(common.ty_i64);}
                case ('f') {ret ty.ty_machine(common.ty_f32);}
                case ('F') {ret ty.ty_machine(common.ty_f64);}
            }
        }
        case ('c') {ret ty.ty_char;}
        case ('s') {ret ty.ty_str;}
        case ('t') {
            check(next(st) as char == '[');
            auto def = "";
            while (peek(st) as char != '|') {
                def += _str.unsafe_from_byte(next(st));
            }
            st.pos = st.pos + 1u;
            let vec[@ty.t] params = vec();
            while (peek(st) as char != ']') {
                params += vec(parse_ty(st, sd));
            }
            st.pos = st.pos + 1u;
            ret ty.ty_tag(sd(def), params);
        }
        case ('@') {ret ty.ty_box(parse_mt(st, sd));}
        case ('V') {ret ty.ty_vec(parse_mt(st, sd));}
        case ('P') {ret ty.ty_port(parse_ty(st, sd));}
        case ('C') {ret ty.ty_chan(parse_ty(st, sd));}
        case ('T') {
            check(next(st) as char == '[');
            let vec[ty.mt] params = vec();
            while (peek(st) as char != ']') {
                params += vec(parse_mt(st, sd));
            }
            st.pos = st.pos + 1u;
            ret ty.ty_tup(params);
        }
        case ('R') {
            check(next(st) as char == '[');
            let vec[ty.field] fields = vec();
            while (peek(st) as char != ']') {
                auto name = "";
                while (peek(st) as char != '=') {
                    name += _str.unsafe_from_byte(next(st));
                }
                st.pos = st.pos + 1u;
                fields += vec(rec(ident=name, mt=parse_mt(st, sd)));
            }
            st.pos = st.pos + 1u;
            ret ty.ty_rec(fields);
        }
        case ('F') {
            auto func = parse_ty_fn(st, sd);
            ret ty.ty_fn(ast.proto_fn, func._0, func._1);
        }
        case ('W') {
            auto func = parse_ty_fn(st, sd);
            ret ty.ty_fn(ast.proto_iter, func._0, func._1);
        }
        case ('N') {
            auto abi;
            alt (next(st) as char) {
                case ('r') {abi = ast.native_abi_rust;}
                case ('c') {abi = ast.native_abi_cdecl;}
            }
            auto func = parse_ty_fn(st, sd);
            ret ty.ty_native_fn(abi,func._0,func._1);
        }
        case ('O') {
            check(next(st) as char == '[');
            let vec[ty.method] methods = vec();
            while (peek(st) as char != ']') {
                auto proto;
                alt (next(st) as char) {
                    case ('W') {proto = ast.proto_iter;}
                    case ('F') {proto = ast.proto_fn;}
                }
                auto name = "";
                while (peek(st) as char != '[') {
                    name += _str.unsafe_from_byte(next(st));
                }
                auto func = parse_ty_fn(st, sd);
                methods += vec(rec(proto=proto,
                                   ident=name,
                                   inputs=func._0,
                                   output=func._1));
            }
            ret ty.ty_obj(methods);
        }
        case ('X') {ret ty.ty_var(parse_int(st));}
        case ('E') {ret ty.ty_native;}
    }
}

impure fn parse_int(@pstate st) -> int {
    auto n = 0;
    while (true) {
        auto cur = peek(st) as char;
        if (cur < '0' || cur > '9') {break;}
        st.pos = st.pos + 1u;
        n *= 10;
        n += (cur as int) - ('0' as int);
    }
    ret n;
}

impure fn parse_ty_fn(@pstate st, str_def sd) -> tup(vec[ty.arg], @ty.t) {
    check(next(st) as char == '[');
    let vec[ty.arg] inputs = vec();
    while (peek(st) as char != ']') {
        auto mode = ast.val;
        if (peek(st) as char == '&') {
            mode = ast.alias;
            st.pos = st.pos + 1u;
        }
        inputs += vec(rec(mode=mode, ty=parse_ty(st, sd)));
    }
    st.pos = st.pos + 1u;
    ret tup(inputs, parse_ty(st, sd));
}

// TODO: return something
fn load_crate(ast.ident ident, vec[str] library_search_paths) -> @() {
    for (str library_search_path in library_search_paths) {
        auto path = fs.connect(library_search_path, ident);
        // TODO
    }

    ret @();
}

fn fold_view_item_use(&env e, &span sp, ast.ident ident,
        vec[@ast.meta_item] meta_items, ast.def_id id, ast.ann orig_ann)
        -> @ast.view_item {
    auto external_crate;
    if (!e.crate_cache.contains_key(ident)) {
        external_crate = load_crate(ident, e.library_search_paths);
        e.crate_cache.insert(ident, external_crate);
    } else {
        external_crate = e.crate_cache.get(ident);
    }

    auto ann = ast.ann_crate(external_crate);
    auto viu = ast.view_item_use(ident, meta_items, id, ann);
    ret @fold.respan[ast.view_item_](sp, viu);
}

// Reads external crates referenced by "use" directives.
fn read_crates(session.session sess,
               @ast.crate crate,
               vec[str] library_search_paths) -> @ast.crate {
    auto e = @rec(
        crate_cache=@common.new_str_hash[@ast.external_crate_info](),
        library_search_paths=library_search_paths
    );

    auto f = fold_view_item_use;
    auto fld = @rec(fold_view_item_use=f with *fold.new_identity_fold[env]());
    ret fold.fold_crate[env](e, fld, crate);
}

<|endoftext|>


<commit_before>//! Tests for the `select!` macro parser.
//!
//! These tests make sure that all possible invocations of `select!` actually compile.

extern crate crossbeam;
#[macro_use]
extern crate crossbeam_channel as channel;

use std::ops::Deref;

#[test]
fn recv() {
    let (s1, r1) = channel::unbounded::<i32>();
    let (s2, r2) = channel::unbounded::<i32>();
    let rs = [r1, r2];

    s1.send(0);
    s2.send(0);

    select! {
        recv(rs) => {}
    }

    select! {
        recv(rs) => {}
        default => panic!(),
    }

    select! {
        recv(rs) => panic!(),
        default => {}
    }
}

#[test]
fn references() {
    let (s, r) = channel::unbounded::<i32>();
    select! {
        send(s, 0) => {}
        recv(r) => {}
    }
    select! {
        send(&&&&s, 0) => {}
        recv(&&&&r) => {}
    }

    select! {
        send([&s].iter().map(|x| *x), 0) => {}
        recv([&r].iter().map(|x| *x)) => {}
    }

    let ss = &&&&[s];
    let rr = &&&&[r];
    select! {
        send(ss.iter(), 0) => {}
        recv(rr.iter()) => {}
    }
    select! {
        send(&&&&ss.iter(), 0) => {}
        recv(&&&&rr.iter()) => {}
    }
}

#[test]
fn blocks() {
    let (s, r) = channel::unbounded::<i32>();

    select! {
        recv(r) => 3.0
        recv(r) => loop {
            unreachable!()
        }
        recv(r) => match 7 + 3 {
            _ => unreachable!()
        }
        default => 7.
    };

    select! {
        recv(r, msg) => if msg.is_some() {
            unreachable!()
        }
        default => ()
    }

    drop(s);
}

#[test]
fn move_handles() {
    let (s, r) = channel::unbounded::<i32>();
    select! {
        recv((move || r)()) => {}
        send((move || s)(), 0) => {}
    }
}

#[test]
fn infer_types() {
    let (s, r) = channel::unbounded();
    select! {
        recv(r) => {}
        default => {}
    }
    s.send(());

    let (s, r) = channel::unbounded();
    select! {
        send(s, ()) => {}
    }
    r.recv();
}

#[test]
fn default() {
    let (s, r) = channel::bounded::<i32>(0);

    select! {
        recv(r) => panic!(),
        default => {}
    }
    select! {
        send(s, 0) => panic!(),
        default() => {}
    }
    select! {
        default => {}
    }
    select! {
        default() => {}
    }
}

#[test]
fn same_variable_name() {
    let (_, r) = channel::unbounded::<i32>();
    select! {
        recv(r, r) => assert!(r.is_none()),
    }

    let (s, _) = channel::unbounded::<i32>();
    let s2 = s.clone();
    select! {
        send(s, 0, s) => assert_eq!(s, &s2),
    }
}

#[test]
fn handles_on_heap() {
    let (s, r) = channel::unbounded::<i32>();
    let (s, r) = (Box::new(s), Box::new(r));

    select! {
        send(*s, 0) => {}
        recv(*r) => {}
        default => {}
    }

    drop(s);
    drop(r);
}

#[test]
fn option_receiver() {
    let (_, r) = channel::unbounded::<i32>();
    select! {
        recv(Some(&r)) => {}
    }
    select! {
        recv(Some(&r)) => {}
        recv(Some(&r)) => {}
    }

    let r: Option<channel::Receiver<u32>> = None;
    select! {
        recv(r.as_ref()) => {}
        default => {}
    }
    select! {
        recv(r.as_ref()) => {}
        recv(r.as_ref()) => {}
        default => {}
    }

    let r: Option<&&&Box<&&channel::Receiver<u32>>> = None;
    let r: Option<&channel::Receiver<u32>> = match r {
        None => None,
        Some(r) => Some(r),
    };
    select! {
        recv(r) => {}
        default => {}
    }
    select! {
        recv(r) => {}
        recv(r) => {}
        default => {}
    }
}

#[test]
fn option_sender() {
    let (s, _) = channel::unbounded::<i32>();
    select! {
        send(Some(&s), 0) => {}
        default => {}
    }
    select! {
        send(Some(&s), 0) => {}
        send(Some(&s), 0) => {}
        default => {}
    }

    let s: Option<channel::Sender<u32>> = None;
    select! {
        send(s.as_ref(), 0) => {}
        default => {}
    }
    select! {
        send(s.as_ref(), 0) => {}
        send(s.as_ref(), 0) => {}
        default => {}
    }

    let s: Option<&&&Box<&&channel::Sender<u32>>> = None;
    let s: Option<&channel::Sender<u32>> = match s {
        None => None,
        Some(s) => Some(s),
    };
    select! {
        send(s, 0) => {}
        default => {}
    }
    select! {
        send(s, 0) => {}
        send(s, 0) => {}
        default => {}
    }
}

#[test]
fn once_blocks() {
    let (s, r) = channel::unbounded::<i32>();

    let once = Box::new(());
    select! {
        send(s, 0) => drop(once),
    }

    let once = Box::new(());
    select! {
        recv(r) => drop(once),
    }

    let once1 = Box::new(());
    let once2 = Box::new(());
    select! {
        send(s, 0) => drop(once1),
        default => drop(once2),
    }

    let once1 = Box::new(());
    let once2 = Box::new(());
    select! {
        recv(r) => drop(once1),
        default => drop(once2),
    }

    let once1 = Box::new(());
    let once2 = Box::new(());
    select! {
        recv(r) => drop(once1),
        send(s, 0) => drop(once2),
    }
}

#[test]
fn once_receiver() {
    let (_, r) = channel::unbounded::<i32>();

    let once = Box::new(());
    let get = move || {
        drop(once);
        r
    };

    select! {
        recv(get()) => {}
    }
}

#[test]
fn once_sender() {
    let (s, _) = channel::unbounded::<i32>();

    let once = Box::new(());
    let get = move || {
        drop(once);
        s
    };

    select! {
        send(get(), 5) => {}
    }
}

#[test]
fn once_receive() {

}

#[test]
fn nesting() {
    let (_, r) = channel::unbounded::<i32>();

    select! {
        recv(r) => {
            select! {
                recv(r) => {
                    select! {
                        recv(r) => {
                            select! {
                                default => {}
                            }
                        }
                    }
                }
            }
        }
    }
}

#[test]
fn evaluate() {
    let (s, r) = channel::unbounded::<i32>();

    let v = select! {
        recv(r) => "foo".into(),
        send(s, 0) => "bar".to_owned(),
        default => "baz".to_string(),
    };
    assert_eq!(v, "bar");

    let v = select! {
        recv(r) => "foo".into(),
        default => "baz".to_string(),
    };
    assert_eq!(v, "foo");

    let v = select! {
        recv(r) => "foo".into(),
        default => "baz".to_string(),
    };
    assert_eq!(v, "baz");
}

#[test]
fn variety() {
    let (s1, r1) = channel::unbounded::<i32>();
    let (s2, r2) = channel::bounded::<String>(1);
    let (s3, r3) = channel::bounded::<()>(0);

    select! {
        recv(r1) => {}
        send(s1, 7) => {}
        recv(Some(r2)) => {}
        send(Some(s2), "foo".to_string()) => {}
        recv([&r3].iter().map(|x| *x)) => {}
        send([&s3].iter().map(|x| *x), ()) => {}
        default => {}
    }
}

#[test]
fn deref() {
    struct Sender<T>(channel::Sender<T>);
    struct Receiver<T>(channel::Receiver<T>);

    impl<T> Deref for Receiver<T> {
        type Target = channel::Receiver<T>;

        fn deref(&self) -> &Self::Target {
            &self.0
        }
    }

    impl<T> Deref for Sender<T> {
        type Target = channel::Sender<T>;

        fn deref(&self) -> &Self::Target {
            &self.0
        }
    }

    let (s, r) = channel::bounded::<i32>(0);
    let (s, r) = (Sender(s), Receiver(r));

    select! {
        send(s, 0) => panic!(),
        recv(r) => panic!(),
        default => {}
    }
}
<commit_msg>Add deny(unsafe_code) to tests/parse.rs<commit_after>//! Tests for the `select!` macro parser.
//!
//! These tests make sure that all possible invocations of `select!` actually compile.

#![deny(unsafe_code)]

extern crate crossbeam;
#[macro_use]
extern crate crossbeam_channel as channel;

use std::ops::Deref;

#[test]
fn recv() {
    let (s1, r1) = channel::unbounded::<i32>();
    let (s2, r2) = channel::unbounded::<i32>();
    let rs = [r1, r2];

    s1.send(0);
    s2.send(0);

    select! {
        recv(rs) => {}
    }

    select! {
        recv(rs) => {}
        default => panic!(),
    }

    select! {
        recv(rs) => panic!(),
        default => {}
    }
}

#[test]
fn references() {
    let (s, r) = channel::unbounded::<i32>();
    select! {
        send(s, 0) => {}
        recv(r) => {}
    }
    select! {
        send(&&&&s, 0) => {}
        recv(&&&&r) => {}
    }

    select! {
        send([&s].iter().map(|x| *x), 0) => {}
        recv([&r].iter().map(|x| *x)) => {}
    }

    let ss = &&&&[s];
    let rr = &&&&[r];
    select! {
        send(ss.iter(), 0) => {}
        recv(rr.iter()) => {}
    }
    select! {
        send(&&&&ss.iter(), 0) => {}
        recv(&&&&rr.iter()) => {}
    }
}

#[test]
fn blocks() {
    let (s, r) = channel::unbounded::<i32>();

    select! {
        recv(r) => 3.0
        recv(r) => loop {
            unreachable!()
        }
        recv(r) => match 7 + 3 {
            _ => unreachable!()
        }
        default => 7.
    };

    select! {
        recv(r, msg) => if msg.is_some() {
            unreachable!()
        }
        default => ()
    }

    drop(s);
}

#[test]
fn move_handles() {
    let (s, r) = channel::unbounded::<i32>();
    select! {
        recv((move || r)()) => {}
        send((move || s)(), 0) => {}
    }
}

#[test]
fn infer_types() {
    let (s, r) = channel::unbounded();
    select! {
        recv(r) => {}
        default => {}
    }
    s.send(());

    let (s, r) = channel::unbounded();
    select! {
        send(s, ()) => {}
    }
    r.recv();
}

#[test]
fn default() {
    let (s, r) = channel::bounded::<i32>(0);

    select! {
        recv(r) => panic!(),
        default => {}
    }
    select! {
        send(s, 0) => panic!(),
        default() => {}
    }
    select! {
        default => {}
    }
    select! {
        default() => {}
    }
}

#[test]
fn same_variable_name() {
    let (_, r) = channel::unbounded::<i32>();
    select! {
        recv(r, r) => assert!(r.is_none()),
    }

    let (s, _) = channel::unbounded::<i32>();
    let s2 = s.clone();
    select! {
        send(s, 0, s) => assert_eq!(s, &s2),
    }
}

#[test]
fn handles_on_heap() {
    let (s, r) = channel::unbounded::<i32>();
    let (s, r) = (Box::new(s), Box::new(r));

    select! {
        send(*s, 0) => {}
        recv(*r) => {}
        default => {}
    }

    drop(s);
    drop(r);
}

#[test]
fn option_receiver() {
    let (_, r) = channel::unbounded::<i32>();
    select! {
        recv(Some(&r)) => {}
    }
    select! {
        recv(Some(&r)) => {}
        recv(Some(&r)) => {}
    }

    let r: Option<channel::Receiver<u32>> = None;
    select! {
        recv(r.as_ref()) => {}
        default => {}
    }
    select! {
        recv(r.as_ref()) => {}
        recv(r.as_ref()) => {}
        default => {}
    }

    let r: Option<&&&Box<&&channel::Receiver<u32>>> = None;
    let r: Option<&channel::Receiver<u32>> = match r {
        None => None,
        Some(r) => Some(r),
    };
    select! {
        recv(r) => {}
        default => {}
    }
    select! {
        recv(r) => {}
        recv(r) => {}
        default => {}
    }
}

#[test]
fn option_sender() {
    let (s, _) = channel::unbounded::<i32>();
    select! {
        send(Some(&s), 0) => {}
        default => {}
    }
    select! {
        send(Some(&s), 0) => {}
        send(Some(&s), 0) => {}
        default => {}
    }

    let s: Option<channel::Sender<u32>> = None;
    select! {
        send(s.as_ref(), 0) => {}
        default => {}
    }
    select! {
        send(s.as_ref(), 0) => {}
        send(s.as_ref(), 0) => {}
        default => {}
    }

    let s: Option<&&&Box<&&channel::Sender<u32>>> = None;
    let s: Option<&channel::Sender<u32>> = match s {
        None => None,
        Some(s) => Some(s),
    };
    select! {
        send(s, 0) => {}
        default => {}
    }
    select! {
        send(s, 0) => {}
        send(s, 0) => {}
        default => {}
    }
}

#[test]
fn once_blocks() {
    let (s, r) = channel::unbounded::<i32>();

    let once = Box::new(());
    select! {
        send(s, 0) => drop(once),
    }

    let once = Box::new(());
    select! {
        recv(r) => drop(once),
    }

    let once1 = Box::new(());
    let once2 = Box::new(());
    select! {
        send(s, 0) => drop(once1),
        default => drop(once2),
    }

    let once1 = Box::new(());
    let once2 = Box::new(());
    select! {
        recv(r) => drop(once1),
        default => drop(once2),
    }

    let once1 = Box::new(());
    let once2 = Box::new(());
    select! {
        recv(r) => drop(once1),
        send(s, 0) => drop(once2),
    }
}

#[test]
fn once_receiver() {
    let (_, r) = channel::unbounded::<i32>();

    let once = Box::new(());
    let get = move || {
        drop(once);
        r
    };

    select! {
        recv(get()) => {}
    }
}

#[test]
fn once_sender() {
    let (s, _) = channel::unbounded::<i32>();

    let once = Box::new(());
    let get = move || {
        drop(once);
        s
    };

    select! {
        send(get(), 5) => {}
    }
}

#[test]
fn once_receive() {

}

#[test]
fn nesting() {
    let (_, r) = channel::unbounded::<i32>();

    select! {
        recv(r) => {
            select! {
                recv(r) => {
                    select! {
                        recv(r) => {
                            select! {
                                default => {}
                            }
                        }
                    }
                }
            }
        }
    }
}

#[test]
fn evaluate() {
    let (s, r) = channel::unbounded::<i32>();

    let v = select! {
        recv(r) => "foo".into(),
        send(s, 0) => "bar".to_owned(),
        default => "baz".to_string(),
    };
    assert_eq!(v, "bar");

    let v = select! {
        recv(r) => "foo".into(),
        default => "baz".to_string(),
    };
    assert_eq!(v, "foo");

    let v = select! {
        recv(r) => "foo".into(),
        default => "baz".to_string(),
    };
    assert_eq!(v, "baz");
}

#[test]
fn variety() {
    let (s1, r1) = channel::unbounded::<i32>();
    let (s2, r2) = channel::bounded::<String>(1);
    let (s3, r3) = channel::bounded::<()>(0);

    select! {
        recv(r1) => {}
        send(s1, 7) => {}
        recv(Some(r2)) => {}
        send(Some(s2), "foo".to_string()) => {}
        recv([&r3].iter().map(|x| *x)) => {}
        send([&s3].iter().map(|x| *x), ()) => {}
        default => {}
    }
}

#[test]
fn deref() {
    struct Sender<T>(channel::Sender<T>);
    struct Receiver<T>(channel::Receiver<T>);

    impl<T> Deref for Receiver<T> {
        type Target = channel::Receiver<T>;

        fn deref(&self) -> &Self::Target {
            &self.0
        }
    }

    impl<T> Deref for Sender<T> {
        type Target = channel::Sender<T>;

        fn deref(&self) -> &Self::Target {
            &self.0
        }
    }

    let (s, r) = channel::bounded::<i32>(0);
    let (s, r) = (Sender(s), Receiver(r));

    select! {
        send(s, 0) => panic!(),
        recv(r) => panic!(),
        default => {}
    }
}
<|endoftext|>


<commit_before>
// Copyright 2017 The gltf Library Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use v2::json::{image, Extras, Index};

/// Texture sampler properties for filtering and wrapping modes.
#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
#[serde(deny_unknown_fields)]
pub struct Sampler {
    /// Magnification filter.
    #[serde(rename = "magFilter")]
    pub mag_filter: Option<u32>,

    /// Minification filter.
    #[serde(rename = "minFilter")]
    pub min_filter: Option<u32>,

    /// Optional user-defined name for this object.
    pub name: Option<String>,

    /// `s` wrapping mode.
    #[serde(default = "sampler_wrap_s_default", rename = "wrapS")]
    pub wrap_s: u32,

    /// `t` wrapping mode.
    #[serde(default = "sampler_wrap_t_default", rename = "wrapT")]
    pub wrap_t: u32,

    /// Extension specific data.
    #[serde(default)]
    pub extensions: SamplerExtensions,

    /// Optional application specific data.
    #[serde(default)]
    pub extras: Extras,
}

fn sampler_wrap_s_default() -> u32 {
    10497
}

fn sampler_wrap_t_default() -> u32 {
    10497
}

/// Extension specific data for `Sampler`.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
pub struct SamplerExtensions {
    #[serde(default)]
    _allow_unknown_fields: (),
}

#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
#[serde(deny_unknown_fields)]
pub struct Texture {
    /// Optional user-defined name for this object.
    pub name: Option<String>,

    /// The index of the sampler used by this texture.
    pub sampler: Option<Index<Sampler>>,

    /// The index of the image used by this texture.
    pub source: Index<image::Image>,

    /// Extension specific data.
    #[serde(default)]
    pub extensions: TextureExtensions,

    /// Optional application specific data.
    #[serde(default)]
    pub extras: Extras,
}

/// Extension specific data for `Texture`.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
pub struct TextureExtensions {
    #[serde(default)]
    _allow_unknown_fields: (),
}

#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
#[serde(deny_unknown_fields)]
/// Reference to a `Texture`.
pub struct Info {
    /// The index of the texture.
    pub index: Index<Texture>,

    /// The set index of the texture's `TEXCOORD` attribute.
    #[serde(default, rename = "texCoord")]
    pub tex_coord: u32,

    /// Extension specific data.
    #[serde(default)]
    pub extensions: InfoExtensions,

    /// Optional application specific data.
    #[serde(default)]
    pub extras: Extras,
}

/// Extension specific data for `Info`.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
pub struct InfoExtensions {
    #[serde(default)]
    _allow_unknown_fields: (),
}
<commit_msg>Added validation for Sampler<commit_after>
// Copyright 2017 The gltf Library Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use v2::json::{image, Extras, Index, Root};
use v2::validation::{Error, JsonPath, Validate};

/// Corresponds to `GL_NEAREST`.
pub const NEAREST: u32 = 9728;

/// Corresponds to `GL_LINEAR`.
pub const LINEAR: u32 = 9729;

/// Corresponds to `GL_NEAREST_MIPMAP_NEAREST`.
pub const NEAREST_MIPMAP_NEAREST: u32 = 9984;

/// Corresponds to `GL_LINEAR_MIPMAP_NEAREST`.
pub const LINEAR_MIPMAP_NEAREST: u32 = 9985;

/// Corresponds to `GL_NEAREST_MIPMAP_LINEAR`.
pub const NEAREST_MIPMAP_LINEAR: u32 = 9986;

/// Corresponds to `GL_LINEAR_MIPMAP_LINEAR`.
pub const LINEAR_MIPMAP_LINEAR: u32 = 9987;

/// Corresponds to `GL_CLAMP_TO_EDGE`.
pub const CLAMP_TO_EDGE: u32 = 33071;

/// Corresponds to `GL_MIRRORED_REPEAT`.
pub const MIRRORED_REPEAT: u32 = 33648;

/// Corresponds to `GL_REPEAT`.
pub const REPEAT: u32 = 10497;

/// All valid magnification filters.
pub const VALID_MAG_FILTERS: &'static [u32] = &[
    NEAREST,
    LINEAR,
];

/// All valid minification filters.
pub const VALID_MIN_FILTERS: &'static [u32] = &[
    NEAREST,
    LINEAR,
    NEAREST_MIPMAP_NEAREST,
    LINEAR_MIPMAP_NEAREST,
    NEAREST_MIPMAP_LINEAR,
    LINEAR_MIPMAP_LINEAR,
];

/// All valid wrapping modes.
pub const VALID_WRAPPING_MODES: &'static [u32] = &[
    CLAMP_TO_EDGE,
    MIRRORED_REPEAT,
    REPEAT,
];

/// Texture sampler properties for filtering and wrapping modes.
#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
#[serde(deny_unknown_fields)]
pub struct Sampler {
    /// Magnification filter.
    #[serde(rename = "magFilter")]
    pub mag_filter: Option<MagFilter>,

    /// Minification filter.
    #[serde(rename = "minFilter")]
    pub min_filter: Option<MinFilter>,

    /// Optional user-defined name for this object.
    pub name: Option<String>,

    /// `s` wrapping mode.
    #[serde(default, rename = "wrapS")]
    pub wrap_s: WrappingMode,

    /// `t` wrapping mode.
    #[serde(default, rename = "wrapT")]
    pub wrap_t: WrappingMode,

    /// Extension specific data.
    #[serde(default)]
    pub extensions: SamplerExtensions,

    /// Optional application specific data.
    #[serde(default)]
    pub extras: Extras,
}

/// Extension specific data for `Sampler`.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
pub struct SamplerExtensions {
    #[serde(default)]
    _allow_unknown_fields: (),
}

#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
#[serde(deny_unknown_fields)]
pub struct Texture {
    /// Optional user-defined name for this object.
    pub name: Option<String>,

    /// The index of the sampler used by this texture.
    pub sampler: Option<Index<Sampler>>,

    /// The index of the image used by this texture.
    pub source: Index<image::Image>,

    /// Extension specific data.
    #[serde(default)]
    pub extensions: TextureExtensions,

    /// Optional application specific data.
    #[serde(default)]
    pub extras: Extras,
}

/// Extension specific data for `Texture`.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
pub struct TextureExtensions {
    #[serde(default)]
    _allow_unknown_fields: (),
}

#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
#[serde(deny_unknown_fields)]
/// Reference to a `Texture`.
pub struct Info {
    /// The index of the texture.
    pub index: Index<Texture>,

    /// The set index of the texture's `TEXCOORD` attribute.
    #[serde(default, rename = "texCoord")]
    pub tex_coord: u32,

    /// Extension specific data.
    #[serde(default)]
    pub extensions: InfoExtensions,

    /// Optional application specific data.
    #[serde(default)]
    pub extras: Extras,
}

/// Extension specific data for `Info`.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
pub struct InfoExtensions {
    #[serde(default)]
    _allow_unknown_fields: (),
}

/// Magnification filter.
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct MagFilter(pub u32);

/// Minification filter.
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct MinFilter(pub u32);

/// Texture co-ordinate wrapping mode.
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct WrappingMode(pub u32);

impl Validate for MagFilter {
    fn validate<F>(&self, _: &Root, path: JsonPath, report: &mut F)
        where F: FnMut(Error)
    {
        if !VALID_MAG_FILTERS.contains(&self.0) {
            report(Error::invalid_enum(path, self.0));
        }
    }
}

impl Validate for MinFilter {
    fn validate<F>(&self, _: &Root, path: JsonPath, report: &mut F)
        where F: FnMut(Error)
    {
        if !VALID_MIN_FILTERS.contains(&self.0) {
            report(Error::invalid_enum(path, self.0));
        }
    }
}

impl Default for WrappingMode {
    fn default() -> Self {
        WrappingMode(REPEAT)
    }
}

impl Validate for WrappingMode {
    fn validate<F>(&self, _: &Root, path: JsonPath, report: &mut F)
        where F: FnMut(Error)
    {
        if !VALID_WRAPPING_MODES.contains(&self.0) {
            report(Error::invalid_enum(path, self.0));
        }
    }
}
<|endoftext|>