<commit_before>//! `log` crate adapter for slog-rs
//!
//! This crate provides two way compatibility with Rust standard `log` crate.
//!
//! ### `log` -> `slog`
//!
//! After calling `init()` `slog-stdlog` will take a role of `log` crate
//! back-end, forwarding all the `log` logging to `slog_scope::logger()`.
//! In other words, any `log` crate logging statement will behave like it was `slog`
//! logging statement executed with logger returned by `slog_scope::logger()`.
//!
//! See documentation of `slog-scope` for more information about logging scopes.
//!
//! See [`init` documentation](fn.init.html) for an example.
//!
//! ### `slog` -> `log`
//!
//! `StdLog` is `slog::Drain` that will pass all `Record`s passing through it to
//! `log` crate just like they were crated with `log` crate logging macros in
//! the first place.
//!
//! ## `slog-scope`
//!
//! Since `log` does not have any form of context, and does not support `Logger`
//! `slog-stdlog` relies on "logging scopes" to establish it.
//!
//! You must set up logging context for `log` -> `slog` via `slog_scope::scope`
//! or `slog_scope::set_global_logger`. Setting a global logger upfront via
//! `slog_scope::set_global_logger` is highly recommended.
//!
//! Note: Since `slog-stdlog` v2, unlike previous releases, `slog-stdlog` uses
//! logging scopes provided by `slog-scope` crate instead of it's own.
//!
//! Refer to `slog-scope` crate documentation for more information.
//!
//! ### Warning
//!
//! Be careful when using both methods at the same time, as a loop can be easily
//! created: `log` -> `slog` -> `log` -> ...
//!
//! ## Compile-time log level filtering
//!
//! For filtering `debug!` and other `log` statements at compile-time, configure
//! the features on the `log` crate in your `Cargo.toml`:
//!
//! ```norust
//! log = { version = "*", features = ["max_level_trace", "release_max_level_warn"] }
//! ```
#![warn(missing_docs)]

extern crate log;

use std::{fmt, io};
use slog::{Level, KV, b};

struct Logger;

fn log_to_slog_level(level: log::Level) -> Level {
    match level {
        log::Level::Trace => Level::Trace,
        log::Level::Debug => Level::Debug,
        log::Level::Info => Level::Info,
        log::Level::Warn => Level::Warning,
        log::Level::Error => Level::Error,
    }
}

fn record_as_location(r: &log::Record) -> slog::RecordLocation {
    let module = r.module_path_static().unwrap_or("<unknown>");
    let file = r.file_static().unwrap_or("<unknown>");
    let line = r.line().unwrap_or_default();

    slog::RecordLocation {
        file,
        line,
        column: 0,
        function: "",
        module,
    }
}

impl log::Log for Logger {
    fn enabled(&self, _: &log::Metadata) -> bool {
        true
    }

    fn log(&self, r: &log::Record) {
        let level = log_to_slog_level(r.metadata().level());

        let args = r.args();
        let target = r.target();
        let location = &record_as_location(r);
        let s = slog::RecordStatic {
            location,
            level,
            tag: target,
        };
        slog_scope::with_logger(|logger| logger.log(&slog::Record::new(&s, args, b!())))
    }

    fn flush(&self) {}
}

/// Register `slog-stdlog` as `log` backend.
///
/// This will pass all logging statements crated with `log`
/// crate to current `slog-scope::logger()`.
///
/// ```
/// #[macro_use]
/// extern crate log;
/// #[macro_use(slog_o, slog_kv)]
/// extern crate slog;
/// extern crate slog_stdlog;
/// extern crate slog_scope;
/// extern crate slog_term;
/// extern crate slog_async;
///
/// use slog::Drain;
///
/// fn main() {
///     let decorator = slog_term::TermDecorator::new().build();
///     let drain = slog_term::FullFormat::new(decorator).build().fuse();
///     let drain = slog_async::Async::new(drain).build().fuse();
///     let logger = slog::Logger::root(drain, slog_o!("version" => env!("CARGO_PKG_VERSION")));
///
///     let _scope_guard = slog_scope::set_global_logger(logger);
///     let _log_guard = slog_stdlog::init().unwrap();
///     // Note: this `info!(...)` macro comes from `log` crate
///     info!("standard logging redirected to slog");
/// }
/// ```
pub fn init() -> Result<(), log::SetLoggerError> {
    init_with_level(log::Level::max())
}

/// Register `slog-stdlog` as `log` backend.
/// Pass a log::Level to do the log filter explicitly.
///
/// This will pass all logging statements crated with `log`
/// crate to current `slog-scope::logger()`.
///
/// ```
/// #[macro_use]
/// extern crate log;
/// #[macro_use(slog_o, slog_kv)]
/// extern crate slog;
/// extern crate slog_stdlog;
/// extern crate slog_scope;
/// extern crate slog_term;
/// extern crate slog_async;
///
/// use slog::Drain;
///
/// fn main() {
///     let decorator = slog_term::TermDecorator::new().build();
///     let drain = slog_term::FullFormat::new(decorator).build().fuse();
///     let drain = slog_async::Async::new(drain).build().fuse();
///     let logger = slog::Logger::root(drain, slog_o!("version" => env!("CARGO_PKG_VERSION")));
///
///     let _scope_guard = slog_scope::set_global_logger(logger);
///     let _log_guard = slog_stdlog::init_with_level(log::Level::Error).unwrap();
///     // Note: this `info!(...)` macro comes from `log` crate
///     info!("standard logging redirected to slog");
///     error!("standard logging redirected to slog");
/// }
/// ```
pub fn init_with_level(level: log::Level) -> Result<(), log::SetLoggerError> {
    log::set_boxed_logger(Box::new(Logger))?;
    log::set_max_level(level.to_level_filter());

    Ok(())
}

/// Drain logging `Record`s into `log` crate
///
/// Any `Record` passing through this `Drain` will be forwarded
/// to `log` crate, just like it was created with `log` crate macros
/// in the first place. The message and key-value pairs will be formated
/// to be one string.
///
/// Caution needs to be taken to prevent circular loop where `Logger`
/// installed via `slog-stdlog::set_logger` would log things to a `StdLog`
/// drain, which would again log things to the global `Logger` and so on
/// leading to an infinite recursion.
pub struct StdLog;

struct LazyLogString<'a> {
    info: &'a slog::Record<'a>,
    logger_values: &'a slog::OwnedKVList,
}

impl<'a> LazyLogString<'a> {
    fn new(info: &'a slog::Record, logger_values: &'a slog::OwnedKVList) -> Self {
        LazyLogString {
            info,
            logger_values,
        }
    }
}

impl<'a> fmt::Display for LazyLogString<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.info.msg())?;

        let io = io::Cursor::new(Vec::new());
        let mut ser = KSV::new(io);

        self.logger_values
            .serialize(self.info, &mut ser)
            .map_err(|_| fmt::Error)?;
        self.info
            .kv()
            .serialize(self.info, &mut ser)
            .map_err(|_| fmt::Error)?;

        let values = ser.into_inner().into_inner();

        write!(f, "{}", String::from_utf8_lossy(&values))
    }
}

impl slog::Drain for StdLog {
    type Ok = ();
    type Err = io::Error;

    fn log(&self, info: &slog::Record, logger_values: &slog::OwnedKVList) -> io::Result<()> {
        let level = match info.level() {
            slog::Level::Critical | slog::Level::Error => log::Level::Error,
            slog::Level::Warning => log::Level::Warn,
            slog::Level::Info => log::Level::Info,
            slog::Level::Debug => log::Level::Debug,
            slog::Level::Trace => log::Level::Trace,
        };

        let mut target = info.tag();
        if target.is_empty() {
            target = info.module();
        }

        let lazy = LazyLogString::new(info, logger_values);
        // Please don't yell at me for this! :D
        // https://github.com/rust-lang-nursery/log/issues/95
        log::__private_api_log(format_args!("{}", lazy), level, &(target, info.module(), info.file(), info.line()));

        Ok(())
    }
}

/// Key-Separator-Value serializer
struct KSV<W: io::Write> {
    io: W,
}

impl<W: io::Write> KSV<W> {
    fn new(io: W) -> Self {
        KSV { io: io }
    }

    fn into_inner(self) -> W {
        self.io
    }
}

impl<W: io::Write> slog::Serializer for KSV<W> {
    fn emit_arguments(&mut self, key: slog::Key, val: &fmt::Arguments) -> slog::Result {
        write!(self.io, ", {}: {}", key, val)?;
        Ok(())
    }
}
<commit_msg>Add support to log == 0.4.10.<commit_after>//! `log` crate adapter for slog-rs
//!
//! This crate provides two way compatibility with Rust standard `log` crate.
//!
//! ### `log` -> `slog`
//!
//! After calling `init()` `slog-stdlog` will take a role of `log` crate
//! back-end, forwarding all the `log` logging to `slog_scope::logger()`.
//! In other words, any `log` crate logging statement will behave like it was `slog`
//! logging statement executed with logger returned by `slog_scope::logger()`.
//!
//! See documentation of `slog-scope` for more information about logging scopes.
//!
//! See [`init` documentation](fn.init.html) for an example.
//!
//! ### `slog` -> `log`
//!
//! `StdLog` is `slog::Drain` that will pass all `Record`s passing through it to
//! `log` crate just like they were crated with `log` crate logging macros in
//! the first place.
//!
//! ## `slog-scope`
//!
//! Since `log` does not have any form of context, and does not support `Logger`
//! `slog-stdlog` relies on "logging scopes" to establish it.
//!
//! You must set up logging context for `log` -> `slog` via `slog_scope::scope`
//! or `slog_scope::set_global_logger`. Setting a global logger upfront via
//! `slog_scope::set_global_logger` is highly recommended.
//!
//! Note: Since `slog-stdlog` v2, unlike previous releases, `slog-stdlog` uses
//! logging scopes provided by `slog-scope` crate instead of it's own.
//!
//! Refer to `slog-scope` crate documentation for more information.
//!
//! ### Warning
//!
//! Be careful when using both methods at the same time, as a loop can be easily
//! created: `log` -> `slog` -> `log` -> ...
//!
//! ## Compile-time log level filtering
//!
//! For filtering `debug!` and other `log` statements at compile-time, configure
//! the features on the `log` crate in your `Cargo.toml`:
//!
//! ```norust
//! log = { version = "*", features = ["max_level_trace", "release_max_level_warn"] }
//! ```
#![warn(missing_docs)]

extern crate log;

use std::{fmt, io};
use slog::{Level, KV, b};

struct Logger;

fn log_to_slog_level(level: log::Level) -> Level {
    match level {
        log::Level::Trace => Level::Trace,
        log::Level::Debug => Level::Debug,
        log::Level::Info => Level::Info,
        log::Level::Warn => Level::Warning,
        log::Level::Error => Level::Error,
    }
}

fn record_as_location(r: &log::Record) -> slog::RecordLocation {
    let module = r.module_path_static().unwrap_or("<unknown>");
    let file = r.file_static().unwrap_or("<unknown>");
    let line = r.line().unwrap_or_default();

    slog::RecordLocation {
        file,
        line,
        column: 0,
        function: "",
        module,
    }
}

impl log::Log for Logger {
    fn enabled(&self, _: &log::Metadata) -> bool {
        true
    }

    fn log(&self, r: &log::Record) {
        let level = log_to_slog_level(r.metadata().level());

        let args = r.args();
        let target = r.target();
        let location = &record_as_location(r);
        let s = slog::RecordStatic {
            location,
            level,
            tag: target,
        };
        slog_scope::with_logger(|logger| logger.log(&slog::Record::new(&s, args, b!())))
    }

    fn flush(&self) {}
}

/// Register `slog-stdlog` as `log` backend.
///
/// This will pass all logging statements crated with `log`
/// crate to current `slog-scope::logger()`.
///
/// ```
/// #[macro_use]
/// extern crate log;
/// #[macro_use(slog_o, slog_kv)]
/// extern crate slog;
/// extern crate slog_stdlog;
/// extern crate slog_scope;
/// extern crate slog_term;
/// extern crate slog_async;
///
/// use slog::Drain;
///
/// fn main() {
///     let decorator = slog_term::TermDecorator::new().build();
///     let drain = slog_term::FullFormat::new(decorator).build().fuse();
///     let drain = slog_async::Async::new(drain).build().fuse();
///     let logger = slog::Logger::root(drain, slog_o!("version" => env!("CARGO_PKG_VERSION")));
///
///     let _scope_guard = slog_scope::set_global_logger(logger);
///     let _log_guard = slog_stdlog::init().unwrap();
///     // Note: this `info!(...)` macro comes from `log` crate
///     info!("standard logging redirected to slog");
/// }
/// ```
pub fn init() -> Result<(), log::SetLoggerError> {
    init_with_level(log::Level::max())
}

/// Register `slog-stdlog` as `log` backend.
/// Pass a log::Level to do the log filter explicitly.
///
/// This will pass all logging statements crated with `log`
/// crate to current `slog-scope::logger()`.
///
/// ```
/// #[macro_use]
/// extern crate log;
/// #[macro_use(slog_o, slog_kv)]
/// extern crate slog;
/// extern crate slog_stdlog;
/// extern crate slog_scope;
/// extern crate slog_term;
/// extern crate slog_async;
///
/// use slog::Drain;
///
/// fn main() {
///     let decorator = slog_term::TermDecorator::new().build();
///     let drain = slog_term::FullFormat::new(decorator).build().fuse();
///     let drain = slog_async::Async::new(drain).build().fuse();
///     let logger = slog::Logger::root(drain, slog_o!("version" => env!("CARGO_PKG_VERSION")));
///
///     let _scope_guard = slog_scope::set_global_logger(logger);
///     let _log_guard = slog_stdlog::init_with_level(log::Level::Error).unwrap();
///     // Note: this `info!(...)` macro comes from `log` crate
///     info!("standard logging redirected to slog");
///     error!("standard logging redirected to slog");
/// }
/// ```
pub fn init_with_level(level: log::Level) -> Result<(), log::SetLoggerError> {
    log::set_boxed_logger(Box::new(Logger))?;
    log::set_max_level(level.to_level_filter());

    Ok(())
}

/// Drain logging `Record`s into `log` crate
///
/// Any `Record` passing through this `Drain` will be forwarded
/// to `log` crate, just like it was created with `log` crate macros
/// in the first place. The message and key-value pairs will be formated
/// to be one string.
///
/// Caution needs to be taken to prevent circular loop where `Logger`
/// installed via `slog-stdlog::set_logger` would log things to a `StdLog`
/// drain, which would again log things to the global `Logger` and so on
/// leading to an infinite recursion.
pub struct StdLog;

struct LazyLogString<'a> {
    info: &'a slog::Record<'a>,
    logger_values: &'a slog::OwnedKVList,
}

impl<'a> LazyLogString<'a> {
    fn new(info: &'a slog::Record, logger_values: &'a slog::OwnedKVList) -> Self {
        LazyLogString {
            info,
            logger_values,
        }
    }
}

impl<'a> fmt::Display for LazyLogString<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.info.msg())?;

        let io = io::Cursor::new(Vec::new());
        let mut ser = KSV::new(io);

        self.logger_values
            .serialize(self.info, &mut ser)
            .map_err(|_| fmt::Error)?;
        self.info
            .kv()
            .serialize(self.info, &mut ser)
            .map_err(|_| fmt::Error)?;

        let values = ser.into_inner().into_inner();

        write!(f, "{}", String::from_utf8_lossy(&values))
    }
}

impl slog::Drain for StdLog {
    type Ok = ();
    type Err = io::Error;

    fn log(&self, info: &slog::Record, logger_values: &slog::OwnedKVList) -> io::Result<()> {
        let level = match info.level() {
            slog::Level::Critical | slog::Level::Error => log::Level::Error,
            slog::Level::Warning => log::Level::Warn,
            slog::Level::Info => log::Level::Info,
            slog::Level::Debug => log::Level::Debug,
            slog::Level::Trace => log::Level::Trace,
        };

        let mut target = info.tag();
        if target.is_empty() {
            target = info.module();
        }

        let lazy = LazyLogString::new(info, logger_values);
        // Please don't yell at me for this! :D
        // https://github.com/rust-lang-nursery/log/issues/95
        log::__private_api_log(format_args!("{}", lazy), level, &(target, info.module(), info.file(), info.line()), None);

        Ok(())
    }
}

/// Key-Separator-Value serializer
struct KSV<W: io::Write> {
    io: W,
}

impl<W: io::Write> KSV<W> {
    fn new(io: W) -> Self {
        KSV { io: io }
    }

    fn into_inner(self) -> W {
        self.io
    }
}

impl<W: io::Write> slog::Serializer for KSV<W> {
    fn emit_arguments(&mut self, key: slog::Key, val: &fmt::Arguments) -> slog::Result {
        write!(self.io, ", {}: {}", key, val)?;
        Ok(())
    }
}
<|endoftext|>


<commit_before>use num_traits::Float;

use approx::{AbsDiffEq, RelativeEq, UlpsEq};

use {cast, Component, Lab, LabHue, Lch, RgbHue, Xyz, Yxy};
use white_point::WhitePoint;

macro_rules! impl_eq {
    (  $self_ty: ident , [$($element: ident),+]) => {
        impl<Wp, T> AbsDiffEq for $self_ty<Wp, T>
        where T: Component + Float + AbsDiffEq,
            T::Epsilon: Copy + Float,
            Wp: WhitePoint + PartialEq
        {
            type Epsilon = T::Epsilon;

            fn default_epsilon() -> Self::Epsilon {
                T::default_epsilon()
            }

            fn abs_diff_eq(&self, other: &Self, epsilon: T::Epsilon) -> bool {
                $( self.$element.abs_diff_eq(&other.$element, epsilon) )&&+
            }
            fn abs_diff_ne(&self, other: &Self, epsilon: T::Epsilon) -> bool {
                $( self.$element.abs_diff_ne(&other.$element, epsilon) )&&+
            }
        }

        impl<Wp, T> RelativeEq for $self_ty<Wp, T>
        where T: Component + Float + RelativeEq,
            T::Epsilon: Copy + Float,
            Wp: WhitePoint + PartialEq
        {
            fn default_max_relative() -> T::Epsilon {
                T::default_max_relative()
            }

            fn relative_eq(&self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon) -> bool {
                $( self.$element.relative_eq(&other.$element, epsilon, max_relative) )&&+
            }
            fn relative_ne(&self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon) -> bool {
                $( self.$element.relative_ne(&other.$element, epsilon, max_relative) )&&+
            }
        }

        impl<Wp, T> UlpsEq for $self_ty<Wp, T>
        where T: Component + Float + UlpsEq,
            T::Epsilon: Copy + Float,
            Wp: WhitePoint + PartialEq
        {
            fn default_max_ulps() -> u32 {
                T::default_max_ulps()
            }

            fn ulps_eq(&self, other: &Self, epsilon: T::Epsilon, max_ulps: u32) -> bool {
                $( self.$element.ulps_eq(&other.$element, epsilon, max_ulps) )&&+
            }
            fn ulps_ne(&self, other: &Self, epsilon: T::Epsilon, max_ulps: u32) -> bool {
                $( self.$element.ulps_ne(&other.$element, epsilon, max_ulps) )&&+
            }
        }
    }
}

impl_eq!(Xyz, [x, y, z]);
impl_eq!(Yxy, [y, x, luma]);
impl_eq!(Lab, [l, a, b]);
impl_eq!(Lch, [l, chroma, hue]);

// For hues, the difference is calculated and compared to zero. However due to
// the way floating point's work this is not so simple.
//
// Reference:
// https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
//
// The recommendation is use 180 * epsilon as the epsilon and do not compare by
// ulps. Because of this we loose some precision for values close to 0.0.
macro_rules! impl_eq_hue {
    (  $self_ty: ident ) => {
        impl<T: Float + AbsDiffEq> AbsDiffEq for $self_ty<T>
        where T::Epsilon: Float
        {
            type Epsilon = T::Epsilon;

            fn default_epsilon() -> Self::Epsilon {
                T::default_epsilon() * cast(180.0)
            }

            fn abs_diff_eq(&self, other: &Self, epsilon: T::Epsilon) -> bool {
                let diff: T = (*self - *other).to_degrees();
                T::abs_diff_eq(&diff, &T::zero(), epsilon)
            }
            fn abs_diff_ne(&self, other: &Self, epsilon: T::Epsilon) -> bool {
                let diff: T = (*self - *other).to_degrees();
                T::abs_diff_ne(&diff, &T::zero(), epsilon)
            }
        }

        impl<T: Float + RelativeEq> RelativeEq for $self_ty<T>
        where T::Epsilon: Float
        {
            fn default_max_relative() -> Self::Epsilon {
                T::default_max_relative() * cast(180.0)
            }

            fn relative_eq(&self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon) -> bool {
                let diff: T = (*self - *other).to_degrees();
                T::relative_eq(&diff, &T::zero(), epsilon, max_relative)
            }
            fn relative_ne(&self, other: &Self, epsilon: Self::Epsilon, max_relative: Self::Epsilon) -> bool {
                let diff: T = (*self - *other).to_degrees();
                T::relative_ne(&diff, &T::zero(), epsilon, max_relative)
            }
        }

        impl<T: Float + UlpsEq> UlpsEq for $self_ty<T>
        where T::Epsilon: Float
        {
            fn default_max_ulps() -> u32 {
                T::default_max_ulps() * 180
            }

            fn ulps_eq(&self, other: &Self, epsilon: T::Epsilon, max_ulps: u32) -> bool {
                let diff: T = (*self - *other).to_degrees();
                T::ulps_eq(&diff, &T::zero(), epsilon, max_ulps)
            }
            fn ulps_ne(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
                let diff: T = (*self - *other).to_degrees();
                T::ulps_ne(&diff, &T::zero(), epsilon, max_ulps)
            }
        }
    }
}

impl_eq_hue!(LabHue);
impl_eq_hue!(RgbHue);
<commit_msg>Fix logic mistake in *_ne functions<commit_after>use num_traits::Float;

use approx::{AbsDiffEq, RelativeEq, UlpsEq};

use {cast, Component, Lab, LabHue, Lch, RgbHue, Xyz, Yxy};
use white_point::WhitePoint;

macro_rules! impl_eq {
    (  $self_ty: ident , [$($element: ident),+]) => {
        impl<Wp, T> AbsDiffEq for $self_ty<Wp, T>
        where T: Component + Float + AbsDiffEq,
            T::Epsilon: Copy + Float,
            Wp: WhitePoint + PartialEq
        {
            type Epsilon = T::Epsilon;

            fn default_epsilon() -> Self::Epsilon {
                T::default_epsilon()
            }

            fn abs_diff_eq(&self, other: &Self, epsilon: T::Epsilon) -> bool {
                $( self.$element.abs_diff_eq(&other.$element, epsilon) )&&+
            }
            fn abs_diff_ne(&self, other: &Self, epsilon: T::Epsilon) -> bool {
                $( self.$element.abs_diff_ne(&other.$element, epsilon) )||+
            }
        }

        impl<Wp, T> RelativeEq for $self_ty<Wp, T>
        where T: Component + Float + RelativeEq,
            T::Epsilon: Copy + Float,
            Wp: WhitePoint + PartialEq
        {
            fn default_max_relative() -> T::Epsilon {
                T::default_max_relative()
            }

            fn relative_eq(&self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon) -> bool {
                $( self.$element.relative_eq(&other.$element, epsilon, max_relative) )&&+
            }
            fn relative_ne(&self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon) -> bool {
                $( self.$element.relative_ne(&other.$element, epsilon, max_relative) )||+
            }
        }

        impl<Wp, T> UlpsEq for $self_ty<Wp, T>
        where T: Component + Float + UlpsEq,
            T::Epsilon: Copy + Float,
            Wp: WhitePoint + PartialEq
        {
            fn default_max_ulps() -> u32 {
                T::default_max_ulps()
            }

            fn ulps_eq(&self, other: &Self, epsilon: T::Epsilon, max_ulps: u32) -> bool {
                $( self.$element.ulps_eq(&other.$element, epsilon, max_ulps) )&&+
            }
            fn ulps_ne(&self, other: &Self, epsilon: T::Epsilon, max_ulps: u32) -> bool {
                $( self.$element.ulps_ne(&other.$element, epsilon, max_ulps) )||+
            }
        }
    }
}

impl_eq!(Xyz, [x, y, z]);
impl_eq!(Yxy, [y, x, luma]);
impl_eq!(Lab, [l, a, b]);
impl_eq!(Lch, [l, chroma, hue]);

// For hues, the difference is calculated and compared to zero. However due to
// the way floating point's work this is not so simple.
//
// Reference:
// https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
//
// The recommendation is use 180 * epsilon as the epsilon and do not compare by
// ulps. Because of this we loose some precision for values close to 0.0.
macro_rules! impl_eq_hue {
    (  $self_ty: ident ) => {
        impl<T: Float + AbsDiffEq> AbsDiffEq for $self_ty<T>
        where T::Epsilon: Float
        {
            type Epsilon = T::Epsilon;

            fn default_epsilon() -> Self::Epsilon {
                T::default_epsilon() * cast(180.0)
            }

            fn abs_diff_eq(&self, other: &Self, epsilon: T::Epsilon) -> bool {
                let diff: T = (*self - *other).to_degrees();
                T::abs_diff_eq(&diff, &T::zero(), epsilon)
            }
            fn abs_diff_ne(&self, other: &Self, epsilon: T::Epsilon) -> bool {
                let diff: T = (*self - *other).to_degrees();
                T::abs_diff_ne(&diff, &T::zero(), epsilon)
            }
        }

        impl<T: Float + RelativeEq> RelativeEq for $self_ty<T>
        where T::Epsilon: Float
        {
            fn default_max_relative() -> Self::Epsilon {
                T::default_max_relative() * cast(180.0)
            }

            fn relative_eq(&self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon) -> bool {
                let diff: T = (*self - *other).to_degrees();
                T::relative_eq(&diff, &T::zero(), epsilon, max_relative)
            }
            fn relative_ne(&self, other: &Self, epsilon: Self::Epsilon, max_relative: Self::Epsilon) -> bool {
                let diff: T = (*self - *other).to_degrees();
                T::relative_ne(&diff, &T::zero(), epsilon, max_relative)
            }
        }

        impl<T: Float + UlpsEq> UlpsEq for $self_ty<T>
        where T::Epsilon: Float
        {
            fn default_max_ulps() -> u32 {
                T::default_max_ulps() * 180
            }

            fn ulps_eq(&self, other: &Self, epsilon: T::Epsilon, max_ulps: u32) -> bool {
                let diff: T = (*self - *other).to_degrees();
                T::ulps_eq(&diff, &T::zero(), epsilon, max_ulps)
            }
            fn ulps_ne(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
                let diff: T = (*self - *other).to_degrees();
                T::ulps_ne(&diff, &T::zero(), epsilon, max_ulps)
            }
        }
    }
}

impl_eq_hue!(LabHue);
impl_eq_hue!(RgbHue);
<|endoftext|>


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

use std::fs;
use std::io::{self, Write};

// Needed to set the script mode to executable.
#[cfg(unix)]
use std::os::unix::fs::OpenOptionsExt;
// FIXME: what about Windows?  Are default ACLs executable?

const TEMPLATE: &'static str = include_str!("../install-template.sh");

actor!{
    #[derive(Debug)]
    pub struct Scripter {
        /// The name of the product, for display
        product_name: String = "Product",

        /// The directory under lib/ where the manifest lives
        rel_manifest_dir: String = "manifestlib",

        /// The string to print after successful installation
        success_message: String = "Installed.",

        /// Places to look for legacy manifests to uninstall
        legacy_manifest_dirs: String = "",

        /// The name of the output script
        output_script: String = "install.sh",
    }
}

impl Scripter {
    /// Generate the actual installer script
    pub fn run(self) -> io::Result<()> {
        // Replace dashes in the success message with spaces (our arg handling botches spaces)
        // (TODO: still needed?  kept for compatibility for now...)
        let product_name = self.product_name.replace('-', " ");

        // Replace dashes in the success message with spaces (our arg handling botches spaces)
        // (TODO: still needed?  kept for compatibility for now...)
        let success_message = self.success_message.replace('-', " ");

        let script = TEMPLATE
            .replace("%%TEMPLATE_PRODUCT_NAME%%", &sh_quote(&product_name))
            .replace("%%TEMPLATE_REL_MANIFEST_DIR%%", &self.rel_manifest_dir)
            .replace("%%TEMPLATE_SUCCESS_MESSAGE%%", &sh_quote(&success_message))
            .replace("%%TEMPLATE_LEGACY_MANIFEST_DIRS%%", &sh_quote(&self.legacy_manifest_dirs))
            .replace("%%TEMPLATE_RUST_INSTALLER_VERSION%%", &sh_quote(&::RUST_INSTALLER_VERSION));

        let mut options = fs::OpenOptions::new();
        options.write(true).create_new(true);
        if cfg!(unix) {
            options.mode(0o755);
        }
        let output = options.open(self.output_script)?;
        writeln!(&output, "{}", script)
    }
}

fn sh_quote<T: ToString>(s: &T) -> String {
    // We'll single-quote the whole thing, so first replace single-quotes with
    // '"'"' (leave quoting, double-quote one `'`, re-enter single-quoting)
    format!("'{}'", s.to_string().replace('\'', r#"'"'"'"#))
}
<commit_msg>Fix cfg for calling OpenOptionsExt::mode<commit_after>// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::fs;
use std::io::{self, Write};

// Needed to set the script mode to executable.
#[cfg(unix)]
use std::os::unix::fs::OpenOptionsExt;
// FIXME: what about Windows?  Are default ACLs executable?

const TEMPLATE: &'static str = include_str!("../install-template.sh");

actor!{
    #[derive(Debug)]
    pub struct Scripter {
        /// The name of the product, for display
        product_name: String = "Product",

        /// The directory under lib/ where the manifest lives
        rel_manifest_dir: String = "manifestlib",

        /// The string to print after successful installation
        success_message: String = "Installed.",

        /// Places to look for legacy manifests to uninstall
        legacy_manifest_dirs: String = "",

        /// The name of the output script
        output_script: String = "install.sh",
    }
}

impl Scripter {
    /// Generate the actual installer script
    pub fn run(self) -> io::Result<()> {
        // Replace dashes in the success message with spaces (our arg handling botches spaces)
        // (TODO: still needed?  kept for compatibility for now...)
        let product_name = self.product_name.replace('-', " ");

        // Replace dashes in the success message with spaces (our arg handling botches spaces)
        // (TODO: still needed?  kept for compatibility for now...)
        let success_message = self.success_message.replace('-', " ");

        let script = TEMPLATE
            .replace("%%TEMPLATE_PRODUCT_NAME%%", &sh_quote(&product_name))
            .replace("%%TEMPLATE_REL_MANIFEST_DIR%%", &self.rel_manifest_dir)
            .replace("%%TEMPLATE_SUCCESS_MESSAGE%%", &sh_quote(&success_message))
            .replace("%%TEMPLATE_LEGACY_MANIFEST_DIRS%%", &sh_quote(&self.legacy_manifest_dirs))
            .replace("%%TEMPLATE_RUST_INSTALLER_VERSION%%", &sh_quote(&::RUST_INSTALLER_VERSION));

        let mut options = fs::OpenOptions::new();
        options.write(true).create_new(true);
        #[cfg(unix)] options.mode(0o755);
        let output = options.open(self.output_script)?;
        writeln!(&output, "{}", script)
    }
}

fn sh_quote<T: ToString>(s: &T) -> String {
    // We'll single-quote the whole thing, so first replace single-quotes with
    // '"'"' (leave quoting, double-quote one `'`, re-enter single-quoting)
    format!("'{}'", s.to_string().replace('\'', r#"'"'"'"#))
}
<|endoftext|>


<commit_before>use snafu::{Backtrace, ErrorCompat, Snafu};
use std::io;
use std::path;
use std::result;
use std::sync::mpsc;

pub type Result<T> = result::Result<T, Error>;

#[derive(Debug, Snafu)]
#[snafu(visibility(pub(crate)))]
pub enum Error {
    #[snafu(display("backend lib error: {}", source))]
    Anime {
        source: anime::Error,
        backtrace: Backtrace,
    },

    #[snafu(display("io error: {}", source))]
    IO {
        source: io::Error,
        backtrace: Backtrace,
    },

    #[snafu(display("file io error [{:?}]: {}", path, source))]
    FileIO {
        path: path::PathBuf,
        source: io::Error,
        backtrace: Backtrace,
    },

    #[snafu(display("dir entry error [{:?}]: {}", dir, source))]
    EntryIO {
        dir: path::PathBuf,
        source: io::Error,
        backtrace: Backtrace,
    },

    #[snafu(display("toml decode error [{:?}]: {}", path, source))]
    TomlDecode {
        path: path::PathBuf,
        source: toml::de::Error,
        backtrace: Backtrace,
    },

    #[snafu(display("toml encode error [{:?}]: {}", path, source))]
    TomlEncode {
        path: path::PathBuf,
        source: toml::ser::Error,
        backtrace: Backtrace,
    },

    #[snafu(display("message pack encode error [{:?}]: {}", path, source))]
    RMPEncode {
        path: path::PathBuf,
        source: rmp_serde::encode::Error,
        backtrace: Backtrace,
    },

    #[snafu(display("message pack decode error [{:?}]: {}", path, source))]
    RMPDecode {
        path: path::PathBuf,
        source: rmp_serde::decode::Error,
        backtrace: Backtrace,
    },

    #[snafu(display("mpsc channel receive error: {}", source))]
    MPSCRecv {
        source: mpsc::RecvError,
        backtrace: Backtrace,
    },

    #[snafu(display("no series found with name similar to {}", name))]
    NoMatchingSeries { name: String },

    #[snafu(display("need existing series info to run in offline mode\nrun the program with --prefetch first when an internet connection is available"))]
    RunWithPrefetch,

    #[snafu(display("series name must be specified as there is no last played series"))]
    NoSavedSeriesName,

    #[snafu(display("command can only be ran in online mode"))]
    MustRunOnline,

    #[snafu(display("failed to parse score"))]
    ScoreParseFailed,

    #[snafu(display("cannot drop and put series on hold at the same time"))]
    CantDropAndHold,

    #[snafu(display("failed to play episode {}: {}", episode, source))]
    FailedToPlayEpisode { episode: u32, source: io::Error },

    #[snafu(display("video player didn't exit normally"))]
    AbnormalPlayerExit,

    #[snafu(display("episode {} not found", episode))]
    EpisodeNotFound { episode: u32 },

    #[snafu(display("please run the program in CLI mode to set your AniList token"))]
    GetAniListTokenFromCLI,
}

impl Error {
    pub fn is_file_nonexistant(&self) -> bool {
        match self {
            Error::FileIO { source, .. } => source.kind() == io::ErrorKind::NotFound,
            _ => false,
        }
    }
}

impl From<anime::Error> for Error {
    fn from(source: anime::Error) -> Error {
        Error::Anime {
            source,
            backtrace: Backtrace::new(),
        }
    }
}

pub fn display_error(err: Error) {
    eprintln!("{}", err);

    if let Error::Anime { source, .. } = &err {
        if let anime::Error::NeedExistingSeriesData = source {
            eprintln!("run the program with the --prefetch flag first when an internet connection is available");
        }
    }

    if let Some(backtrace) = err.backtrace() {
        eprintln!("backtrace:\n{}", backtrace);
    }
}
<commit_msg>[anup] Don't print error backtrace for NeedExistingSeriesData<commit_after>use snafu::{Backtrace, ErrorCompat, Snafu};
use std::io;
use std::path;
use std::result;
use std::sync::mpsc;

pub type Result<T> = result::Result<T, Error>;

#[derive(Debug, Snafu)]
#[snafu(visibility(pub(crate)))]
pub enum Error {
    #[snafu(display("backend lib error: {}", source))]
    Anime {
        source: anime::Error,
        backtrace: Backtrace,
    },

    #[snafu(display("io error: {}", source))]
    IO {
        source: io::Error,
        backtrace: Backtrace,
    },

    #[snafu(display("file io error [{:?}]: {}", path, source))]
    FileIO {
        path: path::PathBuf,
        source: io::Error,
        backtrace: Backtrace,
    },

    #[snafu(display("dir entry error [{:?}]: {}", dir, source))]
    EntryIO {
        dir: path::PathBuf,
        source: io::Error,
        backtrace: Backtrace,
    },

    #[snafu(display("toml decode error [{:?}]: {}", path, source))]
    TomlDecode {
        path: path::PathBuf,
        source: toml::de::Error,
        backtrace: Backtrace,
    },

    #[snafu(display("toml encode error [{:?}]: {}", path, source))]
    TomlEncode {
        path: path::PathBuf,
        source: toml::ser::Error,
        backtrace: Backtrace,
    },

    #[snafu(display("message pack encode error [{:?}]: {}", path, source))]
    RMPEncode {
        path: path::PathBuf,
        source: rmp_serde::encode::Error,
        backtrace: Backtrace,
    },

    #[snafu(display("message pack decode error [{:?}]: {}", path, source))]
    RMPDecode {
        path: path::PathBuf,
        source: rmp_serde::decode::Error,
        backtrace: Backtrace,
    },

    #[snafu(display("mpsc channel receive error: {}", source))]
    MPSCRecv {
        source: mpsc::RecvError,
        backtrace: Backtrace,
    },

    #[snafu(display("no series found with name similar to {}", name))]
    NoMatchingSeries { name: String },

    #[snafu(display("need existing series info to run in offline mode\nrun the program with --prefetch first when an internet connection is available"))]
    RunWithPrefetch,

    #[snafu(display("series name must be specified as there is no last played series"))]
    NoSavedSeriesName,

    #[snafu(display("command can only be ran in online mode"))]
    MustRunOnline,

    #[snafu(display("failed to parse score"))]
    ScoreParseFailed,

    #[snafu(display("cannot drop and put series on hold at the same time"))]
    CantDropAndHold,

    #[snafu(display("failed to play episode {}: {}", episode, source))]
    FailedToPlayEpisode { episode: u32, source: io::Error },

    #[snafu(display("video player didn't exit normally"))]
    AbnormalPlayerExit,

    #[snafu(display("episode {} not found", episode))]
    EpisodeNotFound { episode: u32 },

    #[snafu(display("please run the program in CLI mode to set your AniList token"))]
    GetAniListTokenFromCLI,
}

impl Error {
    pub fn is_file_nonexistant(&self) -> bool {
        match self {
            Error::FileIO { source, .. } => source.kind() == io::ErrorKind::NotFound,
            _ => false,
        }
    }
}

impl From<anime::Error> for Error {
    fn from(source: anime::Error) -> Error {
        Error::Anime {
            source,
            backtrace: Backtrace::new(),
        }
    }
}

pub fn display_error(err: Error) {
    eprintln!("{}", err);

    let mut print_backtrace = true;

    if let Error::Anime { source, .. } = &err {
        if let anime::Error::NeedExistingSeriesData = source {
            eprintln!("run the program with the --prefetch flag first when an internet connection is available");
            print_backtrace = false;
        }
    }

    if !print_backtrace {
        return;
    }

    if let Some(backtrace) = err.backtrace() {
        eprintln!("backtrace:\n{}", backtrace);
    }
}
<|endoftext|>


<commit_before>//! Character inclusion in binary or General_Category value Unicode sets.
//!
//! We rely on dead code elimination to remove the tables that aren't needed.

#![allow(bad_style)]

#[allow(unused)]
mod binary;
pub fn ASCII_Hex_Digit(c: char) -> bool {
    self::binary::ASCII_HEX_DIGIT.contains_char(c)
}
pub fn Alphabetic(c: char) -> bool {
    self::binary::ALPHABETIC.contains_char(c)
}
pub fn Bidi_Control(c: char) -> bool {
    self::binary::BIDI_CONTROL.contains_char(c)
}
pub fn Case_Ignorable(c: char) -> bool {
    self::binary::CASE_IGNORABLE.contains_char(c)
}
pub fn Cased(c: char) -> bool {
    self::binary::CASED.contains_char(c)
}
pub fn Changes_When_Casefolded(c: char) -> bool {
    self::binary::CHANGES_WHEN_CASEFOLDED.contains_char(c)
}
pub fn Changes_When_Casemapped(c: char) -> bool {
    self::binary::CHANGES_WHEN_CASEMAPPED.contains_char(c)
}
pub fn Changes_When_Lowercased(c: char) -> bool {
    self::binary::CHANGES_WHEN_LOWERCASED.contains_char(c)
}
pub fn Changes_When_Titlecased(c: char) -> bool {
    self::binary::CHANGES_WHEN_TITLECASED.contains_char(c)
}
pub fn Changes_When_Uppercased(c: char) -> bool {
    self::binary::CHANGES_WHEN_UPPERCASED.contains_char(c)
}
pub fn Dash(c: char) -> bool {
    self::binary::DASH.contains_char(c)
}
pub fn Default_Ignorable_Code_Point(c: char) -> bool {
    self::binary::DEFAULT_IGNORABLE_CODE_POINT.contains_char(c)
}
pub fn Deprecated(c: char) -> bool {
    self::binary::DEPRECATED.contains_char(c)
}
pub fn Diacritic(c: char) -> bool {
    self::binary::DIACRITIC.contains_char(c)
}
pub fn Extender(c: char) -> bool {
    self::binary::EXTENDER.contains_char(c)
}
pub fn Grapheme_Base(c: char) -> bool {
    self::binary::GRAPHEME_BASE.contains_char(c)
}
pub fn Grapheme_Extend(c: char) -> bool {
    self::binary::GRAPHEME_EXTEND.contains_char(c)
}
pub fn Grapheme_Link(c: char) -> bool {
    self::binary::GRAPHEME_LINK.contains_char(c)
}
pub fn Hex_Digit(c: char) -> bool {
    self::binary::HEX_DIGIT.contains_char(c)
}
pub fn Hyphen(c: char) -> bool {
    self::binary::HYPHEN.contains_char(c)
}
pub fn IDS_Binary_Operator(c: char) -> bool {
    self::binary::IDS_BINARY_OPERATOR.contains_char(c)
}
pub fn IDS_Trinary_Operator(c: char) -> bool {
    self::binary::IDS_TRINARY_OPERATOR.contains_char(c)
}
pub fn ID_Continue(c: char) -> bool {
    self::binary::ID_CONTINUE.contains_char(c)
}
pub fn ID_Start(c: char) -> bool {
    self::binary::ID_START.contains_char(c)
}
pub fn Ideographic(c: char) -> bool {
    self::binary::IDEOGRAPHIC.contains_char(c)
}
pub fn Join_Control(c: char) -> bool {
    self::binary::JOIN_CONTROL.contains_char(c)
}
pub fn Logical_Order_Exception(c: char) -> bool {
    self::binary::LOGICAL_ORDER_EXCEPTION.contains_char(c)
}
pub fn Lowercase(c: char) -> bool {
    self::binary::LOWERCASE.contains_char(c)
}
pub fn Math(c: char) -> bool {
    self::binary::MATH.contains_char(c)
}
pub fn Noncharacter_Code_Point(c: char) -> bool {
    self::binary::NONCHARACTER_CODE_POINT.contains_char(c)
}
pub fn Other_Alphabetic(c: char) -> bool {
    self::binary::OTHER_ALPHABETIC.contains_char(c)
}
pub fn Other_Default_Ignorable_Code_Point(c: char) -> bool {
    self::binary::OTHER_DEFAULT_IGNORABLE_CODE_POINT.contains_char(c)
}
pub fn Other_Grapheme_Extend(c: char) -> bool {
    self::binary::OTHER_GRAPHEME_EXTEND.contains_char(c)
}
pub fn Other_ID_Continue(c: char) -> bool {
    self::binary::OTHER_ID_CONTINUE.contains_char(c)
}
pub fn Other_ID_Start(c: char) -> bool {
    self::binary::OTHER_ID_START.contains_char(c)
}
pub fn Other_Lowercase(c: char) -> bool {
    self::binary::OTHER_LOWERCASE.contains_char(c)
}
pub fn Other_Math(c: char) -> bool {
    self::binary::OTHER_MATH.contains_char(c)
}
pub fn Other_Uppercase(c: char) -> bool {
    self::binary::OTHER_UPPERCASE.contains_char(c)
}
pub fn Pattern_Syntax(c: char) -> bool {
    self::binary::PATTERN_SYNTAX.contains_char(c)
}
pub fn Pattern_White_Space(c: char) -> bool {
    self::binary::PATTERN_WHITE_SPACE.contains_char(c)
}
pub fn Prepended_Concatenation_Mark(c: char) -> bool {
    self::binary::PREPENDED_CONCATENATION_MARK.contains_char(c)
}
pub fn Quotation_Mark(c: char) -> bool {
    self::binary::QUOTATION_MARK.contains_char(c)
}
pub fn Radical(c: char) -> bool {
    self::binary::RADICAL.contains_char(c)
}
pub fn Regional_Indicator(c: char) -> bool {
    self::binary::REGIONAL_INDICATOR.contains_char(c)
}
pub fn Sentence_Terminal(c: char) -> bool {
    self::binary::SENTENCE_TERMINAL.contains_char(c)
}
pub fn Soft_Dotted(c: char) -> bool {
    self::binary::SOFT_DOTTED.contains_char(c)
}
pub fn Terminal_Punctuation(c: char) -> bool {
    self::binary::TERMINAL_PUNCTUATION.contains_char(c)
}
pub fn Unified_Ideograph(c: char) -> bool {
    self::binary::UNIFIED_IDEOGRAPH.contains_char(c)
}
pub fn Uppercase(c: char) -> bool {
    self::binary::UPPERCASE.contains_char(c)
}
pub fn Variation_Selector(c: char) -> bool {
    self::binary::VARIATION_SELECTOR.contains_char(c)
}
pub fn White_Space(c: char) -> bool {
    self::binary::WHITE_SPACE.contains_char(c)
}
pub fn XID_Continue(c: char) -> bool {
    self::binary::XID_CONTINUE.contains_char(c)
}
pub fn XID_Start(c: char) -> bool {
    self::binary::XID_START.contains_char(c)
}

#[allow(unused)]
mod category;
pub fn Cased_Letter(c: char) -> bool {
    self::category::CASED_LETTER.contains_char(c)
}
pub fn Close_Punctuation(c: char) -> bool {
    self::category::CLOSE_PUNCTUATION.contains_char(c)
}
pub fn Connector_Punctuation(c: char) -> bool {
    self::category::CONNECTOR_PUNCTUATION.contains_char(c)
}
pub fn Control(c: char) -> bool {
    self::category::CONTROL.contains_char(c)
}
pub fn Currency_Symbol(c: char) -> bool {
    self::category::CURRENCY_SYMBOL.contains_char(c)
}
pub fn Dash_Punctuation(c: char) -> bool {
    self::category::DASH_PUNCTUATION.contains_char(c)
}
pub fn Decimal_Number(c: char) -> bool {
    self::category::DECIMAL_NUMBER.contains_char(c)
}
pub fn Enclosing_Mark(c: char) -> bool {
    self::category::ENCLOSING_MARK.contains_char(c)
}
pub fn Final_Punctuation(c: char) -> bool {
    self::category::FINAL_PUNCTUATION.contains_char(c)
}
pub fn Format(c: char) -> bool {
    self::category::FORMAT.contains_char(c)
}
pub fn Initial_Punctuation(c: char) -> bool {
    self::category::INITIAL_PUNCTUATION.contains_char(c)
}
pub fn Letter(c: char) -> bool {
    self::category::LETTER.contains_char(c)
}
pub fn Letter_Number(c: char) -> bool {
    self::category::LETTER_NUMBER.contains_char(c)
}
pub fn Line_Separator(c: char) -> bool {
    self::category::LINE_SEPARATOR.contains_char(c)
}
pub fn Lowercase_Letter(c: char) -> bool {
    self::category::LOWERCASE_LETTER.contains_char(c)
}
pub fn Mark(c: char) -> bool {
    self::category::MARK.contains_char(c)
}
pub fn Math_Symbol(c: char) -> bool {
    self::category::MATH_SYMBOL.contains_char(c)
}
pub fn Modifier_Letter(c: char) -> bool {
    self::category::MODIFIER_LETTER.contains_char(c)
}
pub fn Modifier_Symbol(c: char) -> bool {
    self::category::MODIFIER_SYMBOL.contains_char(c)
}
pub fn Nonspacing_Mark(c: char) -> bool {
    self::category::NONSPACING_MARK.contains_char(c)
}
pub fn Number(c: char) -> bool {
    self::category::NUMBER.contains_char(c)
}
pub fn Open_Punctuation(c: char) -> bool {
    self::category::OPEN_PUNCTUATION.contains_char(c)
}
pub fn Other(c: char) -> bool {
    self::category::OTHER.contains_char(c)
}
pub fn Other_Letter(c: char) -> bool {
    self::category::OTHER_LETTER.contains_char(c)
}
pub fn Other_Number(c: char) -> bool {
    self::category::OTHER_NUMBER.contains_char(c)
}
pub fn Other_Punctuation(c: char) -> bool {
    self::category::OTHER_PUNCTUATION.contains_char(c)
}
pub fn Other_Symbol(c: char) -> bool {
    self::category::OTHER_SYMBOL.contains_char(c)
}
pub fn Paragraph_Separator(c: char) -> bool {
    self::category::PARAGRAPH_SEPARATOR.contains_char(c)
}
pub fn Private_Use(c: char) -> bool {
    self::category::PRIVATE_USE.contains_char(c)
}
pub fn Punctuation(c: char) -> bool {
    self::category::PUNCTUATION.contains_char(c)
}
pub fn Separator(c: char) -> bool {
    self::category::SEPARATOR.contains_char(c)
}
pub fn Space_Separator(c: char) -> bool {
    self::category::SPACE_SEPARATOR.contains_char(c)
}
pub fn Spacing_Mark(c: char) -> bool {
    self::category::SPACING_MARK.contains_char(c)
}
pub fn Surrogate(c: char) -> bool {
    self::category::SURROGATE.contains_char(c)
}
pub fn Symbol(c: char) -> bool {
    self::category::SYMBOL.contains_char(c)
}
pub fn Titlecase_Letter(c: char) -> bool {
    self::category::TITLECASE_LETTER.contains_char(c)
}
pub fn Unassigned(c: char) -> bool {
    self::category::UNASSIGNED.contains_char(c)
}
pub fn Uppercase_Letter(c: char) -> bool {
    self::category::UPPERCASE_LETTER.contains_char(c)
}
<commit_msg>unicode/mod.rs using a macro closer to generated code per review<commit_after>//! Character inclusion in binary or General_Category value Unicode sets.
//!
//! We rely on dead code elimination to remove the tables that aren't needed.

#![allow(bad_style)]

macro_rules! char_property_functions {
    {$(
        mod $module:ident;
        [$(
            ($func:ident, $trie:ident),
        )*];
    )*} => {$(
        #[allow(unused)]
        mod $module;
        $(pub fn $func(c: char) -> bool {
            self::$module::$trie.contains_char(c)
        })*
    )*};
}

char_property_functions! {
    mod binary;
    [
      (ASCII_Hex_Digit, ASCII_HEX_DIGIT), (Alphabetic, ALPHABETIC),
      (Bidi_Control, BIDI_CONTROL), (Case_Ignorable, CASE_IGNORABLE),
      (Cased, CASED), (Changes_When_Casefolded, CHANGES_WHEN_CASEFOLDED),
      (Changes_When_Casemapped, CHANGES_WHEN_CASEMAPPED),
      (Changes_When_Lowercased, CHANGES_WHEN_LOWERCASED),
      (Changes_When_Titlecased, CHANGES_WHEN_TITLECASED),
      (Changes_When_Uppercased, CHANGES_WHEN_UPPERCASED), (Dash, DASH),
      (Default_Ignorable_Code_Point, DEFAULT_IGNORABLE_CODE_POINT),
      (Deprecated, DEPRECATED), (Diacritic, DIACRITIC),
      (Extender, EXTENDER), (Grapheme_Base, GRAPHEME_BASE),
      (Grapheme_Extend, GRAPHEME_EXTEND), (Grapheme_Link, GRAPHEME_LINK),
      (Hex_Digit, HEX_DIGIT), (Hyphen, HYPHEN),
      (IDS_Binary_Operator, IDS_BINARY_OPERATOR),
      (IDS_Trinary_Operator, IDS_TRINARY_OPERATOR),
      (ID_Continue, ID_CONTINUE), (ID_Start, ID_START),
      (Ideographic, IDEOGRAPHIC), (Join_Control, JOIN_CONTROL),
      (Logical_Order_Exception, LOGICAL_ORDER_EXCEPTION),
      (Lowercase, LOWERCASE), (Math, MATH),
      (Noncharacter_Code_Point, NONCHARACTER_CODE_POINT),
      (Other_Alphabetic, OTHER_ALPHABETIC),
      (Other_Default_Ignorable_Code_Point, OTHER_DEFAULT_IGNORABLE_CODE_POINT),
      (Other_Grapheme_Extend, OTHER_GRAPHEME_EXTEND),
      (Other_ID_Continue, OTHER_ID_CONTINUE),
      (Other_ID_Start, OTHER_ID_START), (Other_Lowercase, OTHER_LOWERCASE),
      (Other_Math, OTHER_MATH), (Other_Uppercase, OTHER_UPPERCASE),
      (Pattern_Syntax, PATTERN_SYNTAX),
      (Pattern_White_Space, PATTERN_WHITE_SPACE),
      (Prepended_Concatenation_Mark, PREPENDED_CONCATENATION_MARK),
      (Quotation_Mark, QUOTATION_MARK), (Radical, RADICAL),
      (Regional_Indicator, REGIONAL_INDICATOR),
      (Sentence_Terminal, SENTENCE_TERMINAL), (Soft_Dotted, SOFT_DOTTED),
      (Terminal_Punctuation, TERMINAL_PUNCTUATION),
      (Unified_Ideograph, UNIFIED_IDEOGRAPH), (Uppercase, UPPERCASE),
      (Variation_Selector, VARIATION_SELECTOR), (White_Space, WHITE_SPACE),
      (XID_Continue, XID_CONTINUE), (XID_Start, XID_START),
    ];

    mod category;
    [
      (Cased_Letter, CASED_LETTER), (Close_Punctuation, CLOSE_PUNCTUATION),
      (Connector_Punctuation, CONNECTOR_PUNCTUATION), (Control, CONTROL),
      (Currency_Symbol, CURRENCY_SYMBOL),
      (Dash_Punctuation, DASH_PUNCTUATION), (Decimal_Number, DECIMAL_NUMBER),
      (Enclosing_Mark, ENCLOSING_MARK),
      (Final_Punctuation, FINAL_PUNCTUATION), (Format, FORMAT),
      (Initial_Punctuation, INITIAL_PUNCTUATION), (Letter, LETTER),
      (Letter_Number, LETTER_NUMBER), (Line_Separator, LINE_SEPARATOR),
      (Lowercase_Letter, LOWERCASE_LETTER), (Mark, MARK),
      (Math_Symbol, MATH_SYMBOL), (Modifier_Letter, MODIFIER_LETTER),
      (Modifier_Symbol, MODIFIER_SYMBOL), (Nonspacing_Mark, NONSPACING_MARK),
      (Number, NUMBER), (Open_Punctuation, OPEN_PUNCTUATION),
      (Other, OTHER), (Other_Letter, OTHER_LETTER),
      (Other_Number, OTHER_NUMBER), (Other_Punctuation, OTHER_PUNCTUATION),
      (Other_Symbol, OTHER_SYMBOL),
      (Paragraph_Separator, PARAGRAPH_SEPARATOR), (Private_Use, PRIVATE_USE),
      (Punctuation, PUNCTUATION), (Separator, SEPARATOR),
      (Space_Separator, SPACE_SEPARATOR), (Spacing_Mark, SPACING_MARK),
      (Surrogate, SURROGATE), (Symbol, SYMBOL),
      (Titlecase_Letter, TITLECASE_LETTER), (Unassigned, UNASSIGNED),
      (Uppercase_Letter, UPPERCASE_LETTER),
    ];
}
<|endoftext|>


<commit_before>//! Point sinks.

pub mod las;
pub mod sdc;

use std::ffi::OsStr;
use std::fs::File;
use std::io::BufWriter;
use std::path::Path;

use las::Writer as LasWriter;
use rustc_serialize::Decodable;
use toml;

use Result;
use error::Error;
use point::Point;

enum SinkType {
    Las,
}

impl SinkType {
    fn from_osstr_ref<S: AsRef<OsStr>>(s: S) -> Result<SinkType> {
        match Path::new(&s).extension().and_then(|e| e.to_str()) {
            Some("las") => Ok(SinkType::Las),
            Some(_) | None => Err(Error::UnregisteredFileExtension(OsStr::new(&s).to_os_string())),
        }
    }
}

macro_rules! decode_or_default {
    ($klass:path, $decoder:expr) => {{
        match $decoder {
            Some(ref mut decoder) => try!(<$klass as FileSink>::Config::decode(decoder)),
            None => Default::default()
        }
    }}
}

/// Opens a file sink with the given options
///
/// # Examples
///
/// ```
/// # use std::fs::remove_file;
/// use pabst::sink::open_file_sink;
/// let sink = open_file_sink("temp.las", None).unwrap();
/// # remove_file("temp.las").unwrap();
/// ```
pub fn open_file_sink<P>(path: P, config: Option<toml::Value>) -> Result<Box<Sink>>
where P: AsRef<Path> + AsRef<OsStr>
{
    let mut decoder = config.map(|c| toml::Decoder::new(c));
    match try!(SinkType::from_osstr_ref(&path)) {
        SinkType::Las =>  LasWriter::<BufWriter<File>>::open_file_sink(path, decode_or_default!(LasWriter<BufWriter<File>>, decoder)),
    }
}

/// A point sink.
///
/// A sink is a place where points go. Mabye they're written to disk. Maybe not.
pub trait Sink {
    /// Sink a single point into this sink.
    fn sink(&mut self, point: &Point) -> Result<()>;

    /// Close a sink, probably writing its points out or something.
    fn close_sink(self: Box<Self>) -> Result<()>;
}

/// A sink that puts points into a path.
pub trait FileSink {
    /// Decodable configuration.
    type Config: Decodable;

    /// Open a new file sink.
    fn open_file_sink<P: AsRef<Path>>(path: P, options: Self::Config) -> Result<Box<Sink>> where Self: Sized;
}
<commit_msg>Implement sink for Box<Sink><commit_after>//! Point sinks.

pub mod las;
pub mod sdc;

use std::ffi::OsStr;
use std::fs::File;
use std::io::BufWriter;
use std::path::Path;

use las::Writer as LasWriter;
use rustc_serialize::Decodable;
use toml;

use Result;
use error::Error;
use point::Point;

enum SinkType {
    Las,
}

impl SinkType {
    fn from_osstr_ref<S: AsRef<OsStr>>(s: S) -> Result<SinkType> {
        match Path::new(&s).extension().and_then(|e| e.to_str()) {
            Some("las") => Ok(SinkType::Las),
            Some(_) | None => Err(Error::UnregisteredFileExtension(OsStr::new(&s).to_os_string())),
        }
    }
}

macro_rules! decode_or_default {
    ($klass:path, $decoder:expr) => {{
        match $decoder {
            Some(ref mut decoder) => try!(<$klass as FileSink>::Config::decode(decoder)),
            None => Default::default()
        }
    }}
}

/// Opens a file sink with the given options
///
/// # Examples
///
/// ```
/// # use std::fs::remove_file;
/// use pabst::sink::open_file_sink;
/// let sink = open_file_sink("temp.las", None).unwrap();
/// # remove_file("temp.las").unwrap();
/// ```
pub fn open_file_sink<P>(path: P, config: Option<toml::Value>) -> Result<Box<Sink>>
where P: AsRef<Path> + AsRef<OsStr>
{
    let mut decoder = config.map(|c| toml::Decoder::new(c));
    match try!(SinkType::from_osstr_ref(&path)) {
        SinkType::Las =>  LasWriter::<BufWriter<File>>::open_file_sink(path, decode_or_default!(LasWriter<BufWriter<File>>, decoder)),
    }
}

/// A point sink.
///
/// A sink is a place where points go. Mabye they're written to disk. Maybe not.
pub trait Sink {
    /// Sink a single point into this sink.
    fn sink(&mut self, point: &Point) -> Result<()>;

    /// Close a sink, probably writing its points out or something.
    fn close_sink(self: Box<Self>) -> Result<()>;
}

impl Sink for Box<Sink> {
    fn sink(&mut self, point: &Point) -> Result<()> {
        (**self).sink(point)
    }
    fn close_sink(self: Box<Self>) -> Result<()> {
        (*self).close_sink()
    }
}

/// A sink that puts points into a path.
pub trait FileSink {
    /// Decodable configuration.
    type Config: Decodable;

    /// Open a new file sink.
    fn open_file_sink<P: AsRef<Path>>(path: P, options: Self::Config) -> Result<Box<Sink>> where Self: Sized;
}
<|endoftext|>


<commit_before>use std::mem::swap;
use std::ops::{Index, IndexMut};

/// The buffer data structure, that Sodium is using.
///
/// This structure consists of two "subbuffers", which are just vectors over lines (defined by
/// Strings). The split is where the cursor currently is.
///
/// The second buffer is in reverse order to get the particular efficiency we want.
pub struct SplitBuffer {
    before: Vec<String>,
    after: Vec<String>,
}

impl SplitBuffer {
    /// Create a new empty buffer
    pub fn new() -> Self {
        SplitBuffer {
            before: vec![String::new()],
            after: Vec::new(),
        }
    }

    pub fn cur_line(&self) -> &String {
        self.before.last().expect("Unexpected condition (the first part of the split buffer is empty)")
    }

    pub fn cur_line_mut(&mut self) -> &mut String {
        self.before.last_mut().expect("Unexpected condition (the first part of the split buffer is empty)")
    }

    pub fn up(&mut self) -> bool {
        if self.before.len() == 1 {
            false
        } else {
            self.after.push(self.before.pop());
            true
        }
    }

    pub fn down(&mut self) -> bool {
        if self.after.len() == 1 {
            false
        } else {
            self.before.push(self.after.pop());
            true
        }
    }

    pub fn y(&self) -> usize {
        self.before.len()
    }

    pub fn get_line(&self, n: usize) -> Option<&String> {
        if n < self.before.len() {
            Some(&self.before[n])
        } else if n < self.before.len() + self.after.len() {
            Some(&self.after[n - self.before.len()])
        } else {
            None
        }
    }

    pub fn get_line_mut(&mut self, n: usize) -> Option<&mut String> {
        if n < self.before.len() {
            Some(&mut self.before[n])
        } else if n < self.before.len() + self.after.len() {
            Some(&mut self.after[n - self.before.len()])
        } else {
            None
        }
    }

    pub fn remove_line(&mut self, n: usize) {
        if n < self.before.len() {
            self.before.remove(n);
        } else if n < self.before.len() + self.after.len() {
            self.after.remove(n - self.before.len());
        }
    }

    pub fn insert_line(&mut self, n: usize, line: String) {
        if n < self.before.len() {
            self.before.insert(n, line);
        } else if n < self.before.len() + self.after.len() {
            self.after.insert(n - self.before.len(), line);
        }
    }

    pub fn from_lines(vec: Vec<String>) -> SplitBuffer {
        SplitBuffer {
            before: vec,
            after: Vec::new(),
        }
    }

    pub fn goto(&mut self, y: usize) {
        if y < self.line() {
            for _ in 1..self.line() - y {
                if !self.up() {
                    break;
                }
            }
        } else if y > self.line() {
            for _ in 1..y - self.line() {
                if !self.down() {
                    break;
                }
            }
        }
    }

    pub fn pop_line(&mut self) -> String {
        self.before.expect("Unexpected condition (Popped the last line)")
    }

    pub fn len(&self) -> usize {
        self.before.len() + self.after.len()
    }

    pub fn lines(&self) -> ::std::iter::Once<Vec<char>> {
        self.after.iter().chain(self.before.iter().reverse())
    }
}

impl Index<usize> for SplitBuffer {
    type Output = String;

    fn index<'a>(&'a self, index: usize) -> &'a Foo {
        self.get_line(index).expect("Out of bound")
    }
}
impl IndexMut<usize> for SplitBuffer {
    type Output = String;

    fn index<'a>(&'a self, index: usize) -> &'a mut Foo {
        self.get_line(index).expect("Out of bound")
    }
}
<commit_msg>Better buffer api<commit_after>use std::mem::swap;
use std::ops::{Index, IndexMut};

// Wow, I would really love having unboxed trait return types...
type BufIter<'a> = ::std::iter::Chain<::std::slice::Iter<'a, String>, ::std::iter::Rev<::std::slice::Iter<'a, String>>>;

/// The buffer data structure, that Sodium is using.
///
/// This structure consists of two "subbuffers", which are just vectors over lines (defined by
/// Strings). The split is where the cursor currently is.
///
/// The second buffer is in reverse order to get the particular efficiency we want.
pub struct SplitBuffer {
    before: Vec<String>,
    after: Vec<String>,
}

impl SplitBuffer {
    /// Create a new empty buffer
    pub fn new() -> Self {
        SplitBuffer {
            before: vec![String::new()],
            after: Vec::new(),
        }
    }

    pub fn cur_line(&self) -> &String {
        self.before.last().expect("Unexpected condition (the first part of the split buffer is empty)")
    }

    pub fn cur_line_mut(&mut self) -> &mut String {
        self.before.last_mut().expect("Unexpected condition (the first part of the split buffer is empty)")
    }

    pub fn up(&mut self) -> bool {
        if self.before.len() == 1 {
            false
        } else {
            self.after.push(self.before.pop().unwrap());
            true
        }
    }

    pub fn down(&mut self) -> bool {
        if self.after.len() == 0 {
            false
        } else {
            self.before.push(self.after.pop().unwrap());
            true
        }
    }

    pub fn y(&self) -> usize {
        self.before.len()
    }

    pub fn get_line(&self, n: usize) -> Option<&String> {
        if n < self.before.len() {
            Some(&self.before[n])
        } else if n < self.before.len() + self.after.len() {
            Some(&self.after[n - self.before.len()])
        } else {
            None
        }
    }

    pub fn get_line_mut(&mut self, n: usize) -> Option<&mut String> {
        if n < self.before.len() {
            Some(&mut self.before[n])
        } else if n < self.before.len() + self.after.len() {
            Some(&mut self.after[n - self.before.len()])
        } else {
            None
        }
    }

    pub fn remove_line(&mut self, n: usize) {
        if n < self.before.len() {
            self.before.remove(n);
        } else if n < self.before.len() + self.after.len() {
            self.after.remove(n - self.before.len());
        }
    }

    pub fn insert_line(&mut self, n: usize, line: String) {
        if n < self.before.len() {
            self.before.insert(n, line);
        } else if n < self.before.len() + self.after.len() {
            self.after.insert(n - self.before.len(), line);
        }
    }

    pub fn from_lines(vec: Vec<String>) -> SplitBuffer {
        SplitBuffer {
            before: vec,
            after: Vec::new(),
        }
    }

    pub fn goto(&mut self, y: usize) {
        if y < self.y() {
            for _ in 1..self.y() - y {
                if !self.up() {
                    break;
                }
            }
        } else if y > self.y() {
            for _ in 1..y - self.y() {
                if !self.down() {
                    break;
                }
            }
        }
    }

    pub fn pop_line(&mut self) -> String {
        self.before.pop().expect("Unexpected condition (Popped the last line)")
    }

    pub fn len(&self) -> usize {
        self.before.len() + self.after.len()
    }

    pub fn lines<'a>(&'a self) -> BufIter<'a> {
        self.after.iter().chain(self.before.iter().rev())
    }

    /// Get the leading whitespaces of the current line. Used for autoindenting.
    pub fn get_indent(&self, n: usize) -> &str {
        let ln = if let Some(s) = self.get_line(n) {
            s
        } else {
            return "";
        };
        let mut len = 0;
        for c in ln.chars() {
            match c {
                '\t' | ' ' => len += 1,
                _ => break,
            }
        }
        &ln[..len]
    }
}

impl Index<usize> for SplitBuffer {
    type Output = String;

    fn index<'a>(&'a self, index: usize) -> &'a String {
        self.get_line(index).expect("Out of bound")
    }
}
impl IndexMut<usize> for SplitBuffer {

    fn index_mut<'a>(&'a mut self, index: usize) -> &'a mut String {
        self.get_line_mut(index).expect("Out of bound")
    }
}
<|endoftext|>


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

// The outlines relation `T: 'a` or `'a: 'b`.

use middle::infer::InferCtxt;
use middle::ty::{self, RegionEscape, Ty};

#[derive(Debug)]
pub enum Component<'tcx> {
    Region(ty::Region),
    Param(ty::ParamTy),
    UnresolvedInferenceVariable(ty::InferTy),

    // Projections like `T::Foo` are tricky because a constraint like
    // `T::Foo: 'a` can be satisfied in so many ways. There may be a
    // where-clause that says `T::Foo: 'a`, or the defining trait may
    // include a bound like `type Foo: 'static`, or -- in the most
    // conservative way -- we can prove that `T: 'a` (more generally,
    // that all components in the projection outlive `'a`). This code
    // is not in a position to judge which is the best technique, so
    // we just product the projection as a component and leave it to
    // the consumer to decide (but see `EscapingProjection` below).
    Projection(ty::ProjectionTy<'tcx>),

    // In the case where a projection has escaping regions -- meaning
    // regions bound within the type itself -- we always use
    // the most conservative rule, which requires that all components
    // outlive the bound. So for example if we had a type like this:
    //
    //     for<'a> Trait1<  <T as Trait2<'a,'b>>::Foo  >
    //                      ~~~~~~~~~~~~~~~~~~~~~~~~~
    //
    // then the inner projection (underlined) has an escaping region
    // `'a`. We consider that outer trait `'c` to meet a bound if `'b`
    // outlives `'b: 'c`, and we don't consider whether the trait
    // declares that `Foo: 'static` etc. Therefore, we just return the
    // free components of such a projection (in this case, `'b`).
    //
    // However, in the future, we may want to get smarter, and
    // actually return a "higher-ranked projection" here. Therefore,
    // we mark that these components are part of an escaping
    // projection, so that implied bounds code can avoid relying on
    // them. This gives us room to improve the regionck reasoning in
    // the future without breaking backwards compat.
    EscapingProjection(Vec<Component<'tcx>>),

    RFC1214(Vec<Component<'tcx>>),
}

/// Returns all the things that must outlive `'a` for the condition
/// `ty0: 'a` to hold.
pub fn components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
                           ty0: Ty<'tcx>)
                           -> Vec<Component<'tcx>> {
    let mut components = vec![];
    compute_components(infcx, ty0, &mut components);
    debug!("outlives({:?}) = {:?}", ty0, components);
    components
}

fn compute_components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
                               ty0: Ty<'tcx>,
                               out: &mut Vec<Component<'tcx>>) {
    // Descend through the types, looking for the various "base"
    // components and collecting them into `out`. This is not written
    // with `collect()` because of the need to sometimes skip subtrees
    // in the `subtys` iterator (e.g., when encountering a
    // projection).
    let mut subtys = ty0.walk();
    while let Some(ty) = subtys.next() {
        match ty.sty {
            ty::TyClosure(_, ref substs) => {
                // FIXME(#27086). We do not accumulate from substs, since they
                // don't represent reachable data. This means that, in
                // practice, some of the lifetime parameters might not
                // be in scope when the body runs, so long as there is
                // no reachable data with that lifetime. For better or
                // worse, this is consistent with fn types, however,
                // which can also encapsulate data in this fashion
                // (though it's somewhat harder, and typically
                // requires virtual dispatch).
                //
                // Note that changing this (in a naive way, at least)
                // causes regressions for what appears to be perfectly
                // reasonable code like this:
                //
                // ```
                // fn foo<'a>(p: &Data<'a>) {
                //    bar(|q: &mut Parser| q.read_addr())
                // }
                // fn bar(p: Box<FnMut(&mut Parser)+'static>) {
                // }
                // ```
                //
                // Note that `p` (and `'a`) are not used in the
                // closure at all, but to meet the requirement that
                // the closure type `C: 'static` (so it can be coerced
                // to the object type), we get the requirement that
                // `'a: 'static` since `'a` appears in the closure
                // type `C`.
                //
                // A smarter fix might "prune" unused `func_substs` --
                // this would avoid breaking simple examples like
                // this, but would still break others (which might
                // indeed be invalid, depending on your POV). Pruning
                // would be a subtle process, since we have to see
                // what func/type parameters are used and unused,
                // taking into consideration UFCS and so forth.

                for &upvar_ty in &substs.upvar_tys {
                    compute_components(infcx, upvar_ty, out);
                }
                subtys.skip_current_subtree();
            }
            ty::TyBareFn(..) | ty::TyTrait(..) => {
                subtys.skip_current_subtree();
                let subcomponents = capture_components(infcx, ty);
                out.push(Component::RFC1214(subcomponents));
            }
            ty::TyParam(p) => {
                out.push(Component::Param(p));
                subtys.skip_current_subtree();
            }
            ty::TyProjection(ref data) => {
                // For projections, we prefer to generate an
                // obligation like `<P0 as Trait<P1...Pn>>::Foo: 'a`,
                // because this gives the regionck more ways to prove
                // that it holds. However, regionck is not (at least
                // currently) prepared to deal with higher-ranked
                // regions that may appear in the
                // trait-ref. Therefore, if we see any higher-ranke
                // regions, we simply fallback to the most restrictive
                // rule, which requires that `Pi: 'a` for all `i`.

                if !data.has_escaping_regions() {
                    // best case: no escaping regions, so push the
                    // projection and skip the subtree (thus
                    // generating no constraints for Pi).
                    out.push(Component::Projection(*data));
                } else {
                    // fallback case: continue walking through and
                    // constrain Pi.
                    let subcomponents = capture_components(infcx, ty);
                    out.push(Component::EscapingProjection(subcomponents));
                }
                subtys.skip_current_subtree();
            }
            ty::TyInfer(_) => {
                let ty = infcx.resolve_type_vars_if_possible(&ty);
                if let ty::TyInfer(infer_ty) = ty.sty {
                    out.push(Component::UnresolvedInferenceVariable(infer_ty));
                } else {
                    compute_components(infcx, ty, out);
                }
            }
            _ => {
                // for all other types, just constrain the regions and
                // keep walking to find any other types.
                push_region_constraints(out, ty.regions());
            }
        }
    }
}

fn capture_components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
                               ty: Ty<'tcx>)
                               -> Vec<Component<'tcx>> {
    let mut temp = vec![];
    push_region_constraints(&mut temp, ty.regions());
    for subty in ty.walk_shallow() {
        compute_components(infcx, subty, &mut temp);
    }
    temp
}

fn push_region_constraints<'tcx>(out: &mut Vec<Component<'tcx>>, regions: Vec<ty::Region>) {
    for r in regions {
        if !r.is_bound() {
            out.push(Component::Region(r));
        }
    }
}

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

// The outlines relation `T: 'a` or `'a: 'b`.

use middle::infer::InferCtxt;
use middle::ty::{self, RegionEscape, Ty};

#[derive(Debug)]
pub enum Component<'tcx> {
    Region(ty::Region),
    Param(ty::ParamTy),
    UnresolvedInferenceVariable(ty::InferTy),

    // Projections like `T::Foo` are tricky because a constraint like
    // `T::Foo: 'a` can be satisfied in so many ways. There may be a
    // where-clause that says `T::Foo: 'a`, or the defining trait may
    // include a bound like `type Foo: 'static`, or -- in the most
    // conservative way -- we can prove that `T: 'a` (more generally,
    // that all components in the projection outlive `'a`). This code
    // is not in a position to judge which is the best technique, so
    // we just product the projection as a component and leave it to
    // the consumer to decide (but see `EscapingProjection` below).
    Projection(ty::ProjectionTy<'tcx>),

    // In the case where a projection has escaping regions -- meaning
    // regions bound within the type itself -- we always use
    // the most conservative rule, which requires that all components
    // outlive the bound. So for example if we had a type like this:
    //
    //     for<'a> Trait1<  <T as Trait2<'a,'b>>::Foo  >
    //                      ~~~~~~~~~~~~~~~~~~~~~~~~~
    //
    // then the inner projection (underlined) has an escaping region
    // `'a`. We consider that outer trait `'c` to meet a bound if `'b`
    // outlives `'b: 'c`, and we don't consider whether the trait
    // declares that `Foo: 'static` etc. Therefore, we just return the
    // free components of such a projection (in this case, `'b`).
    //
    // However, in the future, we may want to get smarter, and
    // actually return a "higher-ranked projection" here. Therefore,
    // we mark that these components are part of an escaping
    // projection, so that implied bounds code can avoid relying on
    // them. This gives us room to improve the regionck reasoning in
    // the future without breaking backwards compat.
    EscapingProjection(Vec<Component<'tcx>>),

    RFC1214(Vec<Component<'tcx>>),
}

/// Returns all the things that must outlive `'a` for the condition
/// `ty0: 'a` to hold.
pub fn components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
                           ty0: Ty<'tcx>)
                           -> Vec<Component<'tcx>> {
    let mut components = vec![];
    compute_components(infcx, ty0, &mut components);
    debug!("outlives({:?}) = {:?}", ty0, components);
    components
}

fn compute_components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
                               ty0: Ty<'tcx>,
                               out: &mut Vec<Component<'tcx>>) {
    // Descend through the types, looking for the various "base"
    // components and collecting them into `out`. This is not written
    // with `collect()` because of the need to sometimes skip subtrees
    // in the `subtys` iterator (e.g., when encountering a
    // projection).
    let mut subtys = ty0.walk();
    while let Some(ty) = subtys.next() {
        match ty.sty {
            ty::TyClosure(_, ref substs) => {
                // FIXME(#27086). We do not accumulate from substs, since they
                // don't represent reachable data. This means that, in
                // practice, some of the lifetime parameters might not
                // be in scope when the body runs, so long as there is
                // no reachable data with that lifetime. For better or
                // worse, this is consistent with fn types, however,
                // which can also encapsulate data in this fashion
                // (though it's somewhat harder, and typically
                // requires virtual dispatch).
                //
                // Note that changing this (in a naive way, at least)
                // causes regressions for what appears to be perfectly
                // reasonable code like this:
                //
                // ```
                // fn foo<'a>(p: &Data<'a>) {
                //    bar(|q: &mut Parser| q.read_addr())
                // }
                // fn bar(p: Box<FnMut(&mut Parser)+'static>) {
                // }
                // ```
                //
                // Note that `p` (and `'a`) are not used in the
                // closure at all, but to meet the requirement that
                // the closure type `C: 'static` (so it can be coerced
                // to the object type), we get the requirement that
                // `'a: 'static` since `'a` appears in the closure
                // type `C`.
                //
                // A smarter fix might "prune" unused `func_substs` --
                // this would avoid breaking simple examples like
                // this, but would still break others (which might
                // indeed be invalid, depending on your POV). Pruning
                // would be a subtle process, since we have to see
                // what func/type parameters are used and unused,
                // taking into consideration UFCS and so forth.

                for &upvar_ty in &substs.upvar_tys {
                    compute_components(infcx, upvar_ty, out);
                }
                subtys.skip_current_subtree();
            }
            ty::TyBareFn(..) | ty::TyTrait(..) => {
                subtys.skip_current_subtree();
                let subcomponents = capture_components(infcx, ty);
                out.push(Component::RFC1214(subcomponents));
            }
            ty::TyParam(p) => {
                out.push(Component::Param(p));
                subtys.skip_current_subtree();
            }
            ty::TyProjection(ref data) => {
                // For projections, we prefer to generate an
                // obligation like `<P0 as Trait<P1...Pn>>::Foo: 'a`,
                // because this gives the regionck more ways to prove
                // that it holds. However, regionck is not (at least
                // currently) prepared to deal with higher-ranked
                // regions that may appear in the
                // trait-ref. Therefore, if we see any higher-ranke
                // regions, we simply fallback to the most restrictive
                // rule, which requires that `Pi: 'a` for all `i`.

                if !data.has_escaping_regions() {
                    // best case: no escaping regions, so push the
                    // projection and skip the subtree (thus
                    // generating no constraints for Pi).
                    out.push(Component::Projection(*data));
                } else {
                    // fallback case: continue walking through and
                    // constrain Pi.
                    let subcomponents = capture_components(infcx, ty);
                    out.push(Component::EscapingProjection(subcomponents));
                }
                subtys.skip_current_subtree();
            }
            ty::TyInfer(_) => {
                let ty = infcx.resolve_type_vars_if_possible(&ty);
                if let ty::TyInfer(infer_ty) = ty.sty {
                    out.push(Component::UnresolvedInferenceVariable(infer_ty));
                } else {
                    compute_components(infcx, ty, out);
                }
            }

            // Most types do not introduce any region binders, nor
            // involve any other subtle cases, and so the WF relation
            // simply constraints any regions referenced directly by
            // the type and then visits the types that are lexically
            // contained within. (The comments refer to relevant rules
            // from RFC1214.)
            ty::TyBool(..) |        // OutlivesScalar
            ty::TyChar(..) |        // OutlivesScalar
            ty::TyInt(..) |         // OutlivesScalar
            ty::TyUint(..) |        // OutlivesScalar
            ty::TyFloat(..) |       // OutlivesScalar
            ty::TyEnum(..) |        // OutlivesNominalType
            ty::TyStruct(..) |      // OutlivesNominalType
            ty::TyBox(..) |         // OutlivesNominalType (ish)
            ty::TyStr(..) |         // OutlivesScalar (ish)
            ty::TyArray(..) |       // ...
            ty::TySlice(..) |       // ...
            ty::TyRawPtr(..) |      // ...
            ty::TyRef(..) |         // OutlivesReference
            ty::TyTuple(..) |       // ...
            ty::TyError(..) => {
                push_region_constraints(out, ty.regions());
            }
        }
    }
}

fn capture_components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
                               ty: Ty<'tcx>)
                               -> Vec<Component<'tcx>> {
    let mut temp = vec![];
    push_region_constraints(&mut temp, ty.regions());
    for subty in ty.walk_shallow() {
        compute_components(infcx, subty, &mut temp);
    }
    temp
}

fn push_region_constraints<'tcx>(out: &mut Vec<Component<'tcx>>, regions: Vec<ty::Region>) {
    for r in regions {
        if !r.is_bound() {
            out.push(Component::Region(r));
        }
    }
}
<|endoftext|>


<commit_before>extern crate uuid;

mod kernel;

use kernel::types::{CellType,
                    CellFormat,
                    RecFormat,
                    Rec,
                    Table,
                    construct_recformat,
                    construct_rec};

use std::sync::{Arc, RwLock};

fn main() {

    {
        let cell_format = CellFormat{name: "id".to_string(),
                                     type_: CellType::Int32(None)};
        let rec_format = construct_rec(vec![cell_format]);
        let rec = construct_rec(rec_format);
    }

    println!("Chpokey!");
}
<commit_msg>Fix build<commit_after>extern crate uuid;

mod kernel;

use kernel::types::{CellType,
                    CellFormat,
                    RecFormat,
                    Rec,
                    Table,
                    construct_recformat,
                    construct_rec};

use std::sync::{Arc, RwLock};

fn main() {

    {
        let cell_format = CellFormat{name: "id".to_string(),
                                     type_: CellType::Int32(None)};
        let rec_format = construct_recformat(vec![cell_format]);
        let rec = construct_rec(rec_format);
    }

    println!("Chpokey!");
}
<|endoftext|>


<commit_before>#[nolink]
#[link_args="-framework AppKit"]
native mod appkit {
    fn NSBeep();
}

<commit_msg>NSApp testcase<commit_after>import base::objc;

#[nolink]
#[link_args="-framework AppKit"]
native mod appkit {
    fn NSBeep();
}

fn NSApp() -> base::id {
    let klass = str::as_c_str("NSApplication") { |s| objc::objc_getClass(s) };
    let sel = str::as_c_str("sharedApplication") { |s| objc::sel_registerName(s) };
    ret objc::objc_msgSend(klass, sel);
}

<|endoftext|>


<commit_before>use std;
use std::f32::consts::PI;

use arrayvec::ArrayVec;
use num::complex::Complex32;
use collect_slice::CollectSlice;

use consts::SAMPLES;
use descramble::VoiceDecisions;
use enhance::EnhancedSpectrals;
use noise::Noise;
use params::BaseParams;
use window;

// Result of equation 121
const SCALING_COEF: f32 = 146.6432708443356;

pub struct UnvoicedDFT {
    dfts: ArrayVec<[Complex32; 256]>,
    scale: f32,
}

impl UnvoicedDFT {
    pub fn new(lower: isize, upper: isize, noise: &Noise, window: &window::Window)
        -> UnvoicedDFT
    {
        let dfts = (lower..upper).map(|m| {
            let mut nclone = noise.clone();

            (-104..105).map(|n| {
                nclone.next() * window.get(n) *
                    Complex32::new(0.0, -2.0 / 256.0 * PI * m as f32 * n as f32).exp()
            }).fold(Complex32::new(0.0, 0.0), |s, x| s + x)
        }).collect::<ArrayVec<[Complex32; 256]>>();

        let sum = dfts.iter().map(|dft| dft.norm_sqr()).fold(0.0, |s, x| s + x);

        UnvoicedDFT {
            dfts: dfts,
            scale: SCALING_COEF / (sum / (upper - lower) as f32).sqrt(),
        }
    }

    pub fn scale(&self, spectral: f32) -> f32 { self.scale * spectral }
}

impl std::ops::Deref for UnvoicedDFT {
    type Target = ArrayVec<[Complex32; 256]>;
    fn deref(&self) -> &Self::Target { &self.dfts }
}

fn edges(l: usize, params: &BaseParams) -> (isize, isize) {
    let edge = |inner: f32| {
        256.0 / (2.0 * PI) * inner * params.fundamental
    };

    (
        edge(l as f32 - 0.5).ceil() as isize,
        edge(l as f32 + 0.5).ceil() as isize,
    )
}

pub struct UnvoicedParts([Complex32; 256]);

impl UnvoicedParts {
    pub fn new(params: &BaseParams, voice: &VoiceDecisions, enhanced: &EnhancedSpectrals)
        -> UnvoicedParts
    {
        let mut parts = [Complex32::new(0.0, 0.0); 256];

        let noise = Noise::new();
        let window = window::synthesis_trunc();

        for (l, &m) in enhanced.iter().enumerate() {
            let l = l + 1;

            if voice.is_voiced(l) {
                continue;
            }

            let (lower, upper) = edges(l, params);

            let pos = UnvoicedDFT::new(lower, upper, &noise, &window);
            let pscale = pos.scale(m);

            let neg = UnvoicedDFT::new(-upper+1, -lower+1, &noise, &window);
            let nscale = neg.scale(m);

            pos.iter()
               .map(|&dft| pscale * dft)
               .collect_slice(&mut parts[128 + lower as usize..]);

            neg.iter()
               .map(|&dft| nscale * dft)
               .collect_slice(&mut parts[129 - upper as usize..]);
        }

        UnvoicedParts(parts)
    }

    // -128 <= m < 128
    fn get(&self, m: isize) -> Complex32 { self.0[(m + 128) as usize] }

    pub fn idft(&self, n: isize) -> f32 {
        if n < -128 || n > 127 {
            return 0.0;
        }

        (-128..128).map(|m| {
            self.get(m) *
                Complex32::new(0.0, 2.0 / 256.0 * PI * m as f32 * n as f32).exp()
        }).fold(Complex32::new(0.0, 0.0), |s, x| s + x).re / 256.0
    }
}

impl Default for UnvoicedParts {
    fn default() -> UnvoicedParts {
        UnvoicedParts([Complex32::new(0.0, 0.0); 256])
    }
}

pub struct Unvoiced<'a, 'b> {
    cur: &'a UnvoicedParts,
    prev: &'b UnvoicedParts,
    window: window::Window,
}

impl<'a, 'b> Unvoiced<'a, 'b> {
    pub fn new(cur: &'a UnvoicedParts, prev: &'b UnvoicedParts) -> Unvoiced<'a, 'b> {
        Unvoiced {
            cur: cur,
            prev: prev,
            window: window::synthesis_full(),
        }
    }

    pub fn get(&self, n: usize) -> f32 {
        let n = n as isize;

        let numer = self.window.get(n) * self.prev.idft(n) +
            self.window.get(n - SAMPLES as isize) * self.cur.idft(n - SAMPLES as isize);
        let denom = self.window.get(n).powi(2) +
            self.window.get(n - SAMPLES as isize).powi(2);

        numer / denom
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use super::edges;
    use descramble::Bootstrap;
    use params::BaseParams;

    #[test]
    fn test_edges() {
        let chunks = [
            0b001000010010,
            0b110011001100,
            0b111000111000,
            0b111111111111,
            0b10100110101,
            0b00101111010,
            0b01110111011,
            0b00001000,
        ];

        let b = Bootstrap::new(&chunks);
        let p = BaseParams::new(b.unwrap_period());

        assert!((p.fundamental - 0.17575344).abs() < 0.000001);

        let (lower, upper) = edges(1, &p);
        assert_eq!(lower, 4);
        assert_eq!(upper, 11);

        let (lower, upper) = edges(2, &p);
        assert_eq!(lower, 11);
        assert_eq!(upper, 18);

        let (lower, upper) = edges(5, &p);
        assert_eq!(lower, 33);
        assert_eq!(upper, 40);

        let (lower, upper) = edges(8, &p);
        assert_eq!(lower, 54);
        assert_eq!(upper, 61);

        let (lower, upper) = edges(16, &p);
        assert_eq!(lower, 111);
        assert_eq!(upper, 119);
    }
}
<commit_msg>Benchmarks show sin/cos is faster than exp<commit_after>use std;
use std::f32::consts::PI;

use arrayvec::ArrayVec;
use num::complex::Complex32;
use collect_slice::CollectSlice;

use consts::SAMPLES;
use descramble::VoiceDecisions;
use enhance::EnhancedSpectrals;
use noise::Noise;
use params::BaseParams;
use window;

// Result of equation 121
const SCALING_COEF: f32 = 146.6432708443356;

pub struct UnvoicedDFT {
    dfts: ArrayVec<[Complex32; 256]>,
    scale: f32,
}

impl UnvoicedDFT {
    pub fn new(lower: isize, upper: isize, noise: &Noise, window: &window::Window)
        -> UnvoicedDFT
    {
        let dfts = (lower..upper).map(|m| {
            let mut nclone = noise.clone();

            (-104..105).map(|n| {
                let (sin, cos) = (2.0 / 256.0 * PI * m as f32 * n as f32).sin_cos();
                nclone.next() * window.get(n) * Complex32::new(cos, -sin)
            }).fold(Complex32::new(0.0, 0.0), |s, x| s + x)
        }).collect::<ArrayVec<[Complex32; 256]>>();

        let sum = dfts.iter().map(|dft| dft.norm_sqr()).fold(0.0, |s, x| s + x);

        UnvoicedDFT {
            dfts: dfts,
            scale: SCALING_COEF / (sum / (upper - lower) as f32).sqrt(),
        }
    }

    pub fn scale(&self, spectral: f32) -> f32 { self.scale * spectral }
}

impl std::ops::Deref for UnvoicedDFT {
    type Target = ArrayVec<[Complex32; 256]>;
    fn deref(&self) -> &Self::Target { &self.dfts }
}

fn edges(l: usize, params: &BaseParams) -> (isize, isize) {
    let edge = |inner: f32| {
        256.0 / (2.0 * PI) * inner * params.fundamental
    };

    (
        edge(l as f32 - 0.5).ceil() as isize,
        edge(l as f32 + 0.5).ceil() as isize,
    )
}

pub struct UnvoicedParts([Complex32; 256]);

impl UnvoicedParts {
    pub fn new(params: &BaseParams, voice: &VoiceDecisions, enhanced: &EnhancedSpectrals)
        -> UnvoicedParts
    {
        let mut parts = [Complex32::new(0.0, 0.0); 256];

        let noise = Noise::new();
        let window = window::synthesis_trunc();

        for (l, &m) in enhanced.iter().enumerate() {
            let l = l + 1;

            if voice.is_voiced(l) {
                continue;
            }

            let (lower, upper) = edges(l, params);

            let pos = UnvoicedDFT::new(lower, upper, &noise, &window);
            let pscale = pos.scale(m);

            let neg = UnvoicedDFT::new(-upper+1, -lower+1, &noise, &window);
            let nscale = neg.scale(m);

            pos.iter()
               .map(|&dft| pscale * dft)
               .collect_slice(&mut parts[128 + lower as usize..]);

            neg.iter()
               .map(|&dft| nscale * dft)
               .collect_slice(&mut parts[129 - upper as usize..]);
        }

        UnvoicedParts(parts)
    }

    // -128 <= m < 128
    fn get(&self, m: isize) -> Complex32 { self.0[(m + 128) as usize] }

    pub fn idft(&self, n: isize) -> f32 {
        if n < -128 || n > 127 {
            return 0.0;
        }

        (-128..128).map(|m| {
            let (sin, cos) = (2.0 / 256.0 * PI * m as f32 * n as f32).sin_cos();
            self.get(m) * Complex32::new(cos, sin)
        }).fold(Complex32::new(0.0, 0.0), |s, x| s + x).re / 256.0
    }
}

impl Default for UnvoicedParts {
    fn default() -> UnvoicedParts {
        UnvoicedParts([Complex32::new(0.0, 0.0); 256])
    }
}

pub struct Unvoiced<'a, 'b> {
    cur: &'a UnvoicedParts,
    prev: &'b UnvoicedParts,
    window: window::Window,
}

impl<'a, 'b> Unvoiced<'a, 'b> {
    pub fn new(cur: &'a UnvoicedParts, prev: &'b UnvoicedParts) -> Unvoiced<'a, 'b> {
        Unvoiced {
            cur: cur,
            prev: prev,
            window: window::synthesis_full(),
        }
    }

    pub fn get(&self, n: usize) -> f32 {
        let n = n as isize;

        let numer = self.window.get(n) * self.prev.idft(n) +
            self.window.get(n - SAMPLES as isize) * self.cur.idft(n - SAMPLES as isize);
        let denom = self.window.get(n).powi(2) +
            self.window.get(n - SAMPLES as isize).powi(2);

        numer / denom
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use super::edges;
    use descramble::Bootstrap;
    use params::BaseParams;

    #[test]
    fn test_edges() {
        let chunks = [
            0b001000010010,
            0b110011001100,
            0b111000111000,
            0b111111111111,
            0b10100110101,
            0b00101111010,
            0b01110111011,
            0b00001000,
        ];

        let b = Bootstrap::new(&chunks);
        let p = BaseParams::new(b.unwrap_period());

        assert!((p.fundamental - 0.17575344).abs() < 0.000001);

        let (lower, upper) = edges(1, &p);
        assert_eq!(lower, 4);
        assert_eq!(upper, 11);

        let (lower, upper) = edges(2, &p);
        assert_eq!(lower, 11);
        assert_eq!(upper, 18);

        let (lower, upper) = edges(5, &p);
        assert_eq!(lower, 33);
        assert_eq!(upper, 40);

        let (lower, upper) = edges(8, &p);
        assert_eq!(lower, 54);
        assert_eq!(upper, 61);

        let (lower, upper) = edges(16, &p);
        assert_eq!(lower, 111);
        assert_eq!(upper, 119);
    }
}
<|endoftext|>