<commit_before>// Claxon -- A FLAC decoding library in Rust
// Copyright (C) 2014-2015 Ruud van Asseldonk
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License, version 3,
// as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

//! The `error` module defines the error and result types.

use std::io;

/// An error that prevents succesful decoding of the FLAC stream.
#[derive(Debug)]
pub enum Error {
    /// Not a decoding error, but a problem with the underlying IO.
    IoError(io::Error),

    /// An ill-formed FLAC stream was encountered.
    FormatError(&'static str),

    /// The audio stream has more bits per sample than the provided sample
    /// buffer to decode into.
    TooWide,

    /// A currently unsupported format was encountered.
    Unsupported,

    /// The stream header does not equal 'fLaC'.
    InvalidStreamHeader,

    /// Metadata block type 127 is invalid, to avoid confusion with a frame sync code.
    InvalidMetadataBlockType,
    /// The streaminfo block must have length 34.
    InvalidMetadataBlockLength,

    /// A lower bound was encountered that was bigger than an upper bound.
    InconsistentBounds,
    /// The minimum block size must be larger than 15, and the block size must
    /// not exceed 65535.
    InvalidBlockSize,
    /// The sample rate must be positive and no larger than 6553550 Hz.
    InvalidSampleRate,

    /// The streaminfo block must be the very first metadata block.
    MissingStreamInfoBlock,

    /// A frame must start with the frame sync code.
    MissingFrameSyncCode,
    /// The frame header contains an invalid value in one of the reserved bits,
    /// or it contains one of the bit patterns that is invalid to prevent
    /// confusion with a frame sync code, or a bit pattern that is reserved.
    InvalidFrameHeader,
    /// The expected UTF-8-ish encoded integer contains invalid bit sequences.
    InvalidVarLengthInt,
    /// The observed frame header CRC does not match the stored CRC.
    FrameHeaderCrcMismatch,

    /// The subframe header contains an invalid or reserved bit pattern.
    InvalidSubframeHeader,
    /// The subframe contains an invalid or reserved bit pattern.
    InvalidSubframe,

    /// The residual contains an invalid or reserved bit pattern.
    InvalidResidual,
    /// The number of bits per sample in an unencoded binary Rice partition
    /// is larger than the bits per sample of the stream.
    InvalidBitsPerSample,
    /// A bit pattern is not a valid Rice code in the context.
    InvalidRiceCode,
    /// An overflow occurred when decoding the side channel.
    InvalidSideSample,
    /// An overflow occurred when doing fixed prediction.
    InvalidFixedSample,
    /// An overflow occurred when doing LPC prediction.
    InvalidLpcSample,

    /// The audio stream has more bits per sample than the provided sample
    /// buffer to decode into.
    SampleTooWide
}

// TODO: implement the Error trait for claxon::error::Error.

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::IoError(err)
    }
}

impl PartialEq for Error {
    fn eq(&self, other: &Error) -> bool {
        use error::Error::{FormatError, TooWide, Unsupported};
        match (self, other) {
            (&FormatError(r1), &FormatError(r2)) => r1 == r2,
            (&TooWide, &TooWide) => true,
            (&Unsupported, &Unsupported) => true,
            // TODO: this is error-prone. The _ case is required for all
            // non-equal combinations, but it will prevent the compiler from
            // emitting a warning once a new enum variant is added. There must
            // be a better way, right?
            _ => false
        }
    }
}

/// Either `T` on success, or an `Error` on failure.
pub type FlacResult<T> = Result<T, Error>;
<commit_msg>implement fmt::Display and error::Error for Error<commit_after>// Claxon -- A FLAC decoding library in Rust
// Copyright (C) 2014-2015 Ruud van Asseldonk
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License, version 3,
// as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

//! The `error` module defines the error and result types.

use std::error;
use std::fmt;
use std::io;
use std::result;

/// An error that prevents succesful decoding of the FLAC stream.
#[derive(Debug)]
pub enum Error {
    /// Not a decoding error, but a problem with the underlying IO.
    IoError(io::Error),

    /// An ill-formed FLAC stream was encountered.
    FormatError(&'static str),

    /// The audio stream has more bits per sample than the provided sample
    /// buffer to decode into.
    TooWide,

    /// A currently unsupported feature of the FLAC format was encountered.
    Unsupported(&'static str),

    /// The stream header does not equal 'fLaC'.
    InvalidStreamHeader,

    /// Metadata block type 127 is invalid, to avoid confusion with a frame sync code.
    InvalidMetadataBlockType,
    /// The streaminfo block must have length 34.
    InvalidMetadataBlockLength,

    /// A lower bound was encountered that was bigger than an upper bound.
    InconsistentBounds,
    /// The minimum block size must be larger than 15, and the block size must
    /// not exceed 65535.
    InvalidBlockSize,
    /// The sample rate must be positive and no larger than 6553550 Hz.
    InvalidSampleRate,

    /// The streaminfo block must be the very first metadata block.
    MissingStreamInfoBlock,

    /// A frame must start with the frame sync code.
    MissingFrameSyncCode,
    /// The frame header contains an invalid value in one of the reserved bits,
    /// or it contains one of the bit patterns that is invalid to prevent
    /// confusion with a frame sync code, or a bit pattern that is reserved.
    InvalidFrameHeader,
    /// The expected UTF-8-ish encoded integer contains invalid bit sequences.
    InvalidVarLengthInt,
    /// The observed frame header CRC does not match the stored CRC.
    FrameHeaderCrcMismatch,

    /// The subframe header contains an invalid or reserved bit pattern.
    InvalidSubframeHeader,
    /// The subframe contains an invalid or reserved bit pattern.
    InvalidSubframe,

    /// The residual contains an invalid or reserved bit pattern.
    InvalidResidual,
    /// The number of bits per sample in an unencoded binary Rice partition
    /// is larger than the bits per sample of the stream.
    InvalidBitsPerSample,
    /// A bit pattern is not a valid Rice code in the context.
    InvalidRiceCode,
    /// An overflow occurred when decoding the side channel.
    InvalidSideSample,
    /// An overflow occurred when doing fixed prediction.
    InvalidFixedSample,
    /// An overflow occurred when doing LPC prediction.
    InvalidLpcSample,

    /// The audio stream has more bits per sample than the provided sample
    /// buffer to decode into.
    SampleTooWide
}

impl PartialEq for Error {
    fn eq(&self, other: &Error) -> bool {
        use error::Error::{FormatError, TooWide, Unsupported};
        match (self, other) {
            (&FormatError(r1), &FormatError(r2)) => r1 == r2,
            (&TooWide, &TooWide) => true,
            (&Unsupported(f1), &Unsupported(f2)) => f1 == f2,
            // TODO: this is error-prone. The _ case is required for all
            // non-equal combinations, but it will prevent the compiler from
            // emitting a warning once a new enum variant is added. There must
            // be a better way, right?
            _ => false
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, formatter: &mut fmt::Formatter)
           -> result::Result<(), fmt::Error> {
        match *self {
            Error::IoError(ref err) => err.fmt(formatter),
            Error::FormatError(reason) => {
                try!(formatter.write_str("Ill-formed FLAC stream: "));
                formatter.write_str(reason)
            },
            Error::TooWide => {
                formatter.write_str("The audio stream has more bits per sample than the provided sample buffer to decode into.")
            },
            Error::Unsupported(feature) => {
                try!(formatter.write_str("A currently unsupported feature of the FLAC format was encountered: "));
                formatter.write_str(feature)
            },
            // TODO: Remove this when possible.
            _ => formatter.write_str("deprecated error variant")
        }
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::IoError(ref err) => err.description(),
            Error::FormatError(reason) => reason,
            Error::TooWide => "the sample has more bits than the destination type",
            Error::Unsupported(_) => "unsupported feature",
            // TODO: Remove this when possible.
            _ => "deprecated error variant"
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            Error::IoError(ref err) => Some(err),
            Error::FormatError(_) => None,
            Error::TooWide => None,
            Error::Unsupported(_) => None,
            // TODO: Remove this when possible.
            _ => None
        }
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::IoError(err)
    }
}

// TODO: Remove the `Flac` prefix.
/// Either `T` on success, or an `Error` on failure.
pub type FlacResult<T> = Result<T, Error>;
<|endoftext|>


<commit_before>//!
//! Values manipulated by services
//!
use std::cmp::{PartialOrd, Ordering};
use std::time::Duration;
use std::str::FromStr;
use std::sync::Arc;

use serde_json;
use chrono;
use serde::ser::{Serialize, Serializer};
use serde::de::{Deserialize, Deserializer, Error};

///
/// The type of values manipulated by endpoints.
///
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize)]
pub enum Type {
    ///
    /// # Trivial values
    ///

    /// An empty value. Used for instance to inform that a countdown
    /// has reached 0 or that a device is ready.
    Unit,

    /// A boolean. Used for instance for on-off switches, presence
    /// detectors, etc.
    Bool,

    ///
    /// # Time
    ///

    /// A duration. Used for instance in countdowns.
    Duration,

    /// A precise timestamp. Used for instance to determine when an
    /// event has taken place.
    TimeStamp,

    Temperature,
    String,
    ///
    /// ...
    ///
    Color,
    Json,
    Binary,
    ExtNumeric,
}

/// A temperature. Internal representation may be either Fahrenheit or
/// Celcius. The FoxBox adapters are expected to perform conversions
/// to the format requested by their devices.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Temperature {
    /// Fahrenheit
    F(f64),
    /// Celcius
    C(f64),
}

impl Temperature {
    /// Get a temperature in Fahrenheit.
    pub fn as_f(&self) -> f64 {
        unimplemented!();
    }

    /// Get a temperature in Celcius.
    pub fn as_c(&self) -> f64 {
        unimplemented!();
    }
}

impl PartialOrd for Temperature {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.as_c().partial_cmp(&other.as_c())
    }
}

/// A color. Internal representation may vary. The FoxBox adapters are
/// expected to perform conversions to the format requested by their
/// device.
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
pub enum Color {
    RGBA(f64, f64, f64, f64, f64)
}

/// Representation of an object in JSON. It is often (albeit not
/// always) possible to choose a more precise data structure for
/// representing values send/accepted by a service. If possible,
/// adapters should rather pick such more precise data structure.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Json(pub serde_json::value::Value);

impl PartialOrd for Json {
    /// Two Json objects are never comparable to each other.
    fn partial_cmp(&self, _: &Self) -> Option<Ordering> {
        None
    }
}

/// A data structure holding a numeric value of a type that has not
/// been standardized yet.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ExtNumeric {
    pub value: f64,

    /// The vendor. Used for namespacing purposes, to avoid
    /// confusing two incompatible extensions with similar
    /// names. For instance, "foxlink@mozilla.com".
    pub vendor: String,

    /// Identification of the adapter introducing this value.
    /// Designed to aid with tracing and debugging.
    pub adapter: String,

    /// A string describing the nature of the value, designed to
    /// aid with type-checking.
    ///
    /// Examples: `"GroundHumidity"`.
    pub kind: String,
}

impl PartialOrd for ExtNumeric {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        if self.vendor != other.vendor {
            return None;
        } else if self.kind != other.kind {
            return None;
        } else {
            self.value.partial_cmp(&other.value)
        }
    }
}

/// Representation of an actual value that can be sent to/received
/// from a service.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Value {
    Unit,
    Bool(bool),
    Duration(ValDuration),
    TimeStamp(TimeStamp),
    Temperature(Temperature),
    Color(Color),
    String(Arc<String>),

    // FIXME: Add more as we identify needs

    /// A numeric value representing a unit that has not been
    /// standardized yet into the API.
    ExtNumeric(ExtNumeric),

    /// A Json value. We put it behind an `Arc` to make sure that
    /// cloning remains unexpensive.
    Json(Arc<Json>),

    /// Binary data.
    Binary {
        /// The actual data. We put it behind an `Arc` to make sure
        /// that cloning remains unexpensive.
        data: Arc<Vec<u8>>,
        mimetype: String
    }
}

impl Value {
    pub fn get_type(&self) -> Type {
        match *self {
            Value::Unit => Type::Unit,
            Value::Bool(_) => Type::Bool,
            Value::String(_) => Type::String,
            Value::Duration(_) => Type::Duration,
            Value::TimeStamp(_) => Type::TimeStamp,
            Value::Temperature(_) => Type::Temperature,
            Value::Color(_) => Type::Color,
            Value::Json(_) => Type::Json,
            Value::Binary{..} => Type::Binary,
            Value::ExtNumeric(_) => Type::ExtNumeric,
        }
    }
}

impl PartialOrd for Value {
    /// Two values of the same type can be compared using the usual
    /// comparison for values of this type. Two values of distinct
    /// types cannot be compared.
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        use self::Value::*;
        use std::cmp::Ordering::*;
        match (self, other) {
            (&Unit, &Unit) => Some(Equal),
            (&Unit, _) => None,

            (&Bool(a), &Bool(b)) => a.partial_cmp(&b),
            (&Bool(_), _) => None,

            (&Duration(ref a), &Duration(ref b)) => a.partial_cmp(b),
            (&Duration(_), _) => None,

            (&TimeStamp(ref a), &TimeStamp(ref b)) => a.partial_cmp(b),
            (&TimeStamp(_), _) => None,

            (&Temperature(ref a), &Temperature(ref b)) => a.partial_cmp(b),
            (&Temperature(_), _) => None,

            (&Color(ref a), &Color(ref b)) => a.partial_cmp(b),
            (&Color(_), _) => None,

            (&ExtNumeric(ref a), &ExtNumeric(ref b)) => a.partial_cmp(b),
            (&ExtNumeric(_), _) => None,

            (&String(ref a), &String(ref b)) => a.partial_cmp(b),
            (&String(_), _) => None,

            (&Json(ref a), &Json(ref b)) => a.partial_cmp(b),
            (&Json(_), _) => None,

            (&Binary{mimetype: ref a_mimetype, data: ref a_data},
             &Binary{mimetype: ref b_mimetype, data: ref b_data}) if a_mimetype == b_mimetype => a_data.partial_cmp(b_data),
            (&Binary{..}, _) => None,
        }
    }
}

#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)]
pub struct ValDuration(Duration);
impl ValDuration {
    pub fn new(duration: Duration) -> Self {
        ValDuration(duration)
    }
}
impl Serialize for ValDuration {
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: Serializer {
        let as_ms : u64 = self.0.as_secs() * 1000
            + (self.0.subsec_nanos() as u64) / 1_000_000;
        as_ms.serialize(serializer)
    }
}
impl Deserialize for ValDuration {
    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
        where D: Deserializer {
        let as_sec : f64 = try!(f64::deserialize(deserializer));
        Ok(ValDuration(Duration::new(as_sec as u64, as_sec.fract() as u32)))
    }
}

#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)]
pub struct TimeStamp(chrono::DateTime<chrono::Local>);
impl TimeStamp {
    pub fn from_s(s: i64) -> Self {
        use chrono::*;
        let naive = chrono::naive::datetime::NaiveDateTime::from_timestamp(s, 0);
        let offset = chrono::offset::fixed::FixedOffset::east(0);
        let date = DateTime::<Local>::from_utc(naive, offset);
        TimeStamp(date)
    }
}
impl Serialize for TimeStamp {
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: Serializer {
        let str = self.0.to_rfc3339();
        str.serialize(serializer)
    }
}
impl Deserialize for TimeStamp {
    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
        where D: Deserializer {
        let str = try!(String::deserialize(deserializer));
        match chrono::DateTime::<chrono::Local>::from_str(&str) {
            Ok(dt) => Ok(TimeStamp(dt)),
            Err(_) => Err(D::Error::syntax("Invalid date"))
        }
    }
}

#[derive(Clone, Deserialize, Serialize)]
/// A comparison between two values.
pub enum Range {
    /// Leq(x) accepts any value v such that v <= x.
    Leq(Value),

    /// Geq(x) accepts any value v such that v >= x.
    Geq(Value),

    /// BetweenEq {min, max} accepts any value v such that `min <= v`
    /// and `v <= max`. If `max < min`, it never accepts anything.
    BetweenEq {min:Value, max:Value},

    /// OutOfStrict {min, max} accepts any value v such that `v < min`
    /// or `max < v`
    OutOfStrict {min:Value, max:Value},

    /// Eq(x) accespts any value v such that v == x
    Eq(Value),
}

impl Range {
    /// Determine if a value is accepted by this range.
    pub fn contains(&self, value: &Value) -> bool {
        use self::Range::*;
        match *self {
            Leq(ref max) => value <= max,
            Geq(ref min) => value >= min,
            BetweenEq {ref min, ref max} => min <= value && value <= max,
            OutOfStrict {ref min, ref max} => value < min || max < value,
            Eq(ref val) => value == val,
        }
    }

    /// Get the type associated to this range.
    ///
    /// If this range has a `min` and a `max` with conflicting types,
    /// produce an error.
    pub fn get_type(&self) -> Result<Type, ()> {
        use self::Range::*;
        match *self {
            Leq(ref v) | Geq(ref v) | Eq(ref v) => Ok(v.get_type()),
            BetweenEq{ref min, ref max} | OutOfStrict{ref min, ref max} => {
                let min_typ = min.get_type();
                let max_typ = max.get_type();
                if min_typ == max_typ {
                    Ok(min_typ)
                } else {
                    Err(())
                }
            }
        }
    }
}
<commit_msg>[fxbox/taxonomy] TimeStamp now uses UTC<commit_after>//!
//! Values manipulated by services
//!
use std::cmp::{PartialOrd, Ordering};
use std::time::Duration;
use std::str::FromStr;
use std::sync::Arc;

use serde_json;
use chrono;
use serde::ser::{Serialize, Serializer};
use serde::de::{Deserialize, Deserializer, Error};

///
/// The type of values manipulated by endpoints.
///
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize)]
pub enum Type {
    ///
    /// # Trivial values
    ///

    /// An empty value. Used for instance to inform that a countdown
    /// has reached 0 or that a device is ready.
    Unit,

    /// A boolean. Used for instance for on-off switches, presence
    /// detectors, etc.
    Bool,

    ///
    /// # Time
    ///

    /// A duration. Used for instance in countdowns.
    Duration,

    /// A precise timestamp. Used for instance to determine when an
    /// event has taken place.
    TimeStamp,

    Temperature,
    String,
    ///
    /// ...
    ///
    Color,
    Json,
    Binary,
    ExtNumeric,
}

/// A temperature. Internal representation may be either Fahrenheit or
/// Celcius. The FoxBox adapters are expected to perform conversions
/// to the format requested by their devices.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Temperature {
    /// Fahrenheit
    F(f64),
    /// Celcius
    C(f64),
}

impl Temperature {
    /// Get a temperature in Fahrenheit.
    pub fn as_f(&self) -> f64 {
        unimplemented!();
    }

    /// Get a temperature in Celcius.
    pub fn as_c(&self) -> f64 {
        unimplemented!();
    }
}

impl PartialOrd for Temperature {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.as_c().partial_cmp(&other.as_c())
    }
}

/// A color. Internal representation may vary. The FoxBox adapters are
/// expected to perform conversions to the format requested by their
/// device.
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
pub enum Color {
    RGBA(f64, f64, f64, f64, f64)
}

/// Representation of an object in JSON. It is often (albeit not
/// always) possible to choose a more precise data structure for
/// representing values send/accepted by a service. If possible,
/// adapters should rather pick such more precise data structure.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Json(pub serde_json::value::Value);

impl PartialOrd for Json {
    /// Two Json objects are never comparable to each other.
    fn partial_cmp(&self, _: &Self) -> Option<Ordering> {
        None
    }
}

/// A data structure holding a numeric value of a type that has not
/// been standardized yet.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ExtNumeric {
    pub value: f64,

    /// The vendor. Used for namespacing purposes, to avoid
    /// confusing two incompatible extensions with similar
    /// names. For instance, "foxlink@mozilla.com".
    pub vendor: String,

    /// Identification of the adapter introducing this value.
    /// Designed to aid with tracing and debugging.
    pub adapter: String,

    /// A string describing the nature of the value, designed to
    /// aid with type-checking.
    ///
    /// Examples: `"GroundHumidity"`.
    pub kind: String,
}

impl PartialOrd for ExtNumeric {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        if self.vendor != other.vendor {
            return None;
        } else if self.kind != other.kind {
            return None;
        } else {
            self.value.partial_cmp(&other.value)
        }
    }
}

/// Representation of an actual value that can be sent to/received
/// from a service.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Value {
    Unit,
    Bool(bool),
    Duration(ValDuration),
    TimeStamp(TimeStamp),
    Temperature(Temperature),
    Color(Color),
    String(Arc<String>),

    // FIXME: Add more as we identify needs

    /// A numeric value representing a unit that has not been
    /// standardized yet into the API.
    ExtNumeric(ExtNumeric),

    /// A Json value. We put it behind an `Arc` to make sure that
    /// cloning remains unexpensive.
    Json(Arc<Json>),

    /// Binary data.
    Binary {
        /// The actual data. We put it behind an `Arc` to make sure
        /// that cloning remains unexpensive.
        data: Arc<Vec<u8>>,
        mimetype: String
    }
}

impl Value {
    pub fn get_type(&self) -> Type {
        match *self {
            Value::Unit => Type::Unit,
            Value::Bool(_) => Type::Bool,
            Value::String(_) => Type::String,
            Value::Duration(_) => Type::Duration,
            Value::TimeStamp(_) => Type::TimeStamp,
            Value::Temperature(_) => Type::Temperature,
            Value::Color(_) => Type::Color,
            Value::Json(_) => Type::Json,
            Value::Binary{..} => Type::Binary,
            Value::ExtNumeric(_) => Type::ExtNumeric,
        }
    }
}

impl PartialOrd for Value {
    /// Two values of the same type can be compared using the usual
    /// comparison for values of this type. Two values of distinct
    /// types cannot be compared.
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        use self::Value::*;
        use std::cmp::Ordering::*;
        match (self, other) {
            (&Unit, &Unit) => Some(Equal),
            (&Unit, _) => None,

            (&Bool(a), &Bool(b)) => a.partial_cmp(&b),
            (&Bool(_), _) => None,

            (&Duration(ref a), &Duration(ref b)) => a.partial_cmp(b),
            (&Duration(_), _) => None,

            (&TimeStamp(ref a), &TimeStamp(ref b)) => a.partial_cmp(b),
            (&TimeStamp(_), _) => None,

            (&Temperature(ref a), &Temperature(ref b)) => a.partial_cmp(b),
            (&Temperature(_), _) => None,

            (&Color(ref a), &Color(ref b)) => a.partial_cmp(b),
            (&Color(_), _) => None,

            (&ExtNumeric(ref a), &ExtNumeric(ref b)) => a.partial_cmp(b),
            (&ExtNumeric(_), _) => None,

            (&String(ref a), &String(ref b)) => a.partial_cmp(b),
            (&String(_), _) => None,

            (&Json(ref a), &Json(ref b)) => a.partial_cmp(b),
            (&Json(_), _) => None,

            (&Binary{mimetype: ref a_mimetype, data: ref a_data},
             &Binary{mimetype: ref b_mimetype, data: ref b_data}) if a_mimetype == b_mimetype => a_data.partial_cmp(b_data),
            (&Binary{..}, _) => None,
        }
    }
}

#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)]
pub struct ValDuration(Duration);
impl ValDuration {
    pub fn new(duration: Duration) -> Self {
        ValDuration(duration)
    }
}
impl Serialize for ValDuration {
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: Serializer {
        let as_ms : u64 = self.0.as_secs() * 1000
            + (self.0.subsec_nanos() as u64) / 1_000_000;
        as_ms.serialize(serializer)
    }
}
impl Deserialize for ValDuration {
    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
        where D: Deserializer {
        let as_sec : f64 = try!(f64::deserialize(deserializer));
        Ok(ValDuration(Duration::new(as_sec as u64, as_sec.fract() as u32)))
    }
}

#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)]
pub struct TimeStamp(chrono::DateTime<chrono::UTC>);
impl TimeStamp {
    pub fn from_datetime(datetime: chrono::DateTime<chrono::UTC>) -> Self {
        TimeStamp(datetime)
    }
    pub fn from_s(s: i64) -> Self {
        use chrono::*;
        let naive = chrono::naive::datetime::NaiveDateTime::from_timestamp(s, 0);
        let date = DateTime::<UTC>::from_utc(naive, chrono::UTC);
        TimeStamp(date)
    }
}
impl Serialize for TimeStamp {
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: Serializer {
        let str = self.0.to_rfc3339();
        str.serialize(serializer)
    }
}
impl Deserialize for TimeStamp {
    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
        where D: Deserializer {
        let str = try!(String::deserialize(deserializer));
        match chrono::DateTime::<chrono::UTC>::from_str(&str) {
            Ok(dt) => Ok(TimeStamp(dt)),
            Err(_) => Err(D::Error::syntax("Invalid date"))
        }
    }
}

#[derive(Clone, Deserialize, Serialize)]
/// A comparison between two values.
pub enum Range {
    /// Leq(x) accepts any value v such that v <= x.
    Leq(Value),

    /// Geq(x) accepts any value v such that v >= x.
    Geq(Value),

    /// BetweenEq {min, max} accepts any value v such that `min <= v`
    /// and `v <= max`. If `max < min`, it never accepts anything.
    BetweenEq {min:Value, max:Value},

    /// OutOfStrict {min, max} accepts any value v such that `v < min`
    /// or `max < v`
    OutOfStrict {min:Value, max:Value},

    /// Eq(x) accespts any value v such that v == x
    Eq(Value),
}

impl Range {
    /// Determine if a value is accepted by this range.
    pub fn contains(&self, value: &Value) -> bool {
        use self::Range::*;
        match *self {
            Leq(ref max) => value <= max,
            Geq(ref min) => value >= min,
            BetweenEq {ref min, ref max} => min <= value && value <= max,
            OutOfStrict {ref min, ref max} => value < min || max < value,
            Eq(ref val) => value == val,
        }
    }

    /// Get the type associated to this range.
    ///
    /// If this range has a `min` and a `max` with conflicting types,
    /// produce an error.
    pub fn get_type(&self) -> Result<Type, ()> {
        use self::Range::*;
        match *self {
            Leq(ref v) | Geq(ref v) | Eq(ref v) => Ok(v.get_type()),
            BetweenEq{ref min, ref max} | OutOfStrict{ref min, ref max} => {
                let min_typ = min.get_type();
                let max_typ = max.get_type();
                if min_typ == max_typ {
                    Ok(min_typ)
                } else {
                    Err(())
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>//! Definition of Thinkerbell scripts.
//!
//! Typical applications will not interact with script
//! objects. Rather, they will use module `parse` to parse a script
//! and module `run` to execute it.

use foxbox_taxonomy::selector::*;
use foxbox_taxonomy::services::*;
use foxbox_taxonomy::values::*;

use std::marker::PhantomData;

/// A thinkerbell script.
#[derive(Debug)]
pub struct Script<Ctx> where Ctx: Context {
    pub name: String,

    /// A set of rules, stating what must be done in which circumstance.
    pub rules: Vec<Rule<Ctx>>,

    pub phantom: PhantomData<Ctx>,
}

impl Parser<Script<UncheckedCtx>> for Script<UncheckedCtx> {
    fn description() -> String {
        "Script".to_owned()
    }
    fn parse(path: Path, source: &mut JSON) -> Result<Self, ParseError> {
        let name =  try!(path.push("", |path| String::take(path, source, "name")));
        let rules = try!(path.push("", |path| Rule::take_vec(path, source, "rules")));
        Ok(Script {
            name: name,
            rules: rules,
            phantom: PhantomData
        })
    }
}

/// A single rule, i.e. "when some condition becomes true, do
/// something".
///
/// # JSON
///
/// A single rule is represented as an object with the following fields:
///
/// - conditions (array of Match): the conditions in which to execute
///   the code – *all* conditions must be met;
/// - execute (array of Statement): the code to execute once all conditions
///   are met.
///
/// ```
/// extern crate foxbox_thinkerbell;
/// extern crate foxbox_taxonomy;
///
/// use foxbox_thinkerbell::ast::*;
/// use foxbox_taxonomy::parse::*;
///
/// # fn main() {
/// let source = r#"{
///   "conditions": [{
///     "source": [{"id": "my getter"}],
///     "kind": "OvenTemperature",
///     "range": {"Geq": {"Temperature": {"C": 300}}},
///     "duration": 3600
///   }],
///   "execute": [{
///     "destination": [{"id": "my setter"}],
///     "value": {"OnOff": "Off"},
///     "kind": "OnOff"
///   }]
/// }"#;
///
/// Rule::<UncheckedCtx>::from_str(&source).unwrap();
/// # }
/// ```
#[derive(Debug)]
pub struct Rule<Ctx> where Ctx: Context {
    /// The condition in which to execute the trigger. The condition
    /// is matched once *all* the `Match` branches are true. Whenever
    /// `conditions` was false and becomes true, we execute `execute`.
    pub conditions: Vec<Match<Ctx>>,

    /// Stuff to do once `condition` is met.
    pub execute: Vec<Statement<Ctx>>,

    pub phantom: PhantomData<Ctx>,
}
impl Parser<Rule<UncheckedCtx>> for Rule<UncheckedCtx> {
    fn description() -> String {
        "Rule".to_owned()
    }

    fn parse(path: Path, source: &mut JSON) -> Result<Self, ParseError> {
        let conditions = try!(path.push("conditions",
            |path| Match::take_vec(path, source, "conditions"))
        );
        let execute = try!(path.push("execute",
            |path| Statement::take_vec(path, source, "execute"))
        );
        Ok(Rule {
            conditions: conditions,
            execute: execute,
            phantom: PhantomData,
        })
    }
}

/// An individual match.
///
/// Matchs always take the form: "data received from getter channel
/// enters given range".
///
/// A condition is true if *any* of the corresponding getter channels
/// yielded a value that enters the given range.
///
/// # JSON
///
/// A match is represented as an object with the following fields:
///
/// - source (array of GetterSelector) - the selector for getters that will
///   provide the data;
/// - kind (ChannelKind) - the kind of getters;
/// - range (Range) - the condition in whih the match is considered met –
///   a match becomes met when any of the sources *enters* the range;
/// - duration (Duration, optional) - if provided, the match is only considered
///   met if any of the sources *enters* and *remains* in the range
///   for `duration`
///
/// ```
/// extern crate foxbox_thinkerbell;
/// extern crate foxbox_taxonomy;
///
/// use foxbox_thinkerbell::ast::*;
/// use foxbox_taxonomy::services::*;
/// use foxbox_taxonomy::parse::*;
///
/// # fn main() {
/// let source = r#"{
///   "source": [{"id": "my getter"}],
///   "kind": "OvenTemperature",
///   "range": {"Geq": {"Temperature": {"C": 300}}},
///   "duration": 3600
/// }"#;
///
/// let match_ = Match::<UncheckedCtx>::from_str(&source).unwrap();
/// assert_eq!(match_.kind, ChannelKind::OvenTemperature);
/// # }
/// ```
#[derive(Debug)]
pub struct Match<Ctx> where Ctx: Context {
    /// The set of getters to watch. Note that the set of getters may
    /// change (e.g. when devices are added/removed) without rebooting
    /// the script.
    pub source: Vec<GetterSelector>,

    /// The kind of channel expected from `source`, e.g. "the current
    /// time of day", "is the door opened?", etc. During compilation,
    /// we make sure that we restrict to the elements of `source` that
    /// offer `kind`.
    pub kind: ChannelKind,

    /// The range of values for which the condition is considered met.
    /// During compilation, we check that the type of `range` is
    /// compatible with that of `getter`.
    pub range: Range,

    /// If specified, the values must remain in the `range` for at least
    /// `duration` before the match is considered valid. This is useful
    /// for sensors that may oscillate around a threshold or for detecting
    /// e.g. that a door has been forgotten open.
    pub duration: Option<Duration>,

    pub phantom: PhantomData<Ctx>,
}
impl Parser<Match<UncheckedCtx>> for Match<UncheckedCtx> {
    fn description() -> String {
        "Match".to_owned()
    }

    fn parse(path: Path, source: &mut JSON) -> Result<Self, ParseError> {
        let sources = try!(path.push("source",
            |path| GetterSelector::take_vec(path, source, "source"))
        );
        let kind = try!(path.push("kind",
            |path| ChannelKind::take(path, source, "kind"))
        );
        let range = try!(path.push("range",
            |path| Range::take(path, source, "range"))
        );
        let duration = match path.push("range",
            |path| Duration::take(path, source, "duration"))
        {
            Err(ParseError::MissingField {..}) => None,
            Err(err) => return Err(err),
            Ok(ok) => Some(ok)
        };
        Ok(Match {
            source: sources,
            kind: kind,
            range: range,
            duration: duration,
            phantom: PhantomData,
        })
    }
}

/// Stuff to actually do. In practice, this means placing calls to devices.
///
/// # JSON
///
/// A statement is represented as an object with the following fields:
/// - destination (array of SetterSelector);
/// - value (Value);
/// - kind (ChannelKind);
///
/// ```
/// extern crate foxbox_thinkerbell;
/// extern crate foxbox_taxonomy;
///
/// use foxbox_thinkerbell::ast::*;
/// use foxbox_taxonomy::values::*;
/// use foxbox_taxonomy::services::*;
/// use foxbox_taxonomy::parse::*;
///
/// # fn main() {
/// let source = r#"{
///   "destination": [{"id": "my setter"}],
///   "value": {"OnOff": "Off"},
///   "kind": "OnOff"
/// }"#;
///
/// let statement = Statement::<UncheckedCtx>::from_str(&source).unwrap();
/// assert_eq!(statement.value, Value::OnOff(OnOff::Off));
/// assert_eq!(statement.kind, ChannelKind::OnOff);
/// # }
/// ```
#[derive(Debug)]
pub struct Statement<Ctx> where Ctx: Context {
    /// The set of setters to which to send a command. Note that the
    /// set of setters may change (e.g. when devices are
    /// added/removed) without rebooting the script.
    pub destination: Vec<SetterSelector>,

    /// Data to send to the resource. During compilation, we check
    /// that the type of `value` is compatible with that of
    /// `destination`.
    pub value: Value,

    /// The kind of channel expected from `destination`, e.g. "close
    /// the door", "set the temperature", etc. During compilation, we
    /// make sure that we restrict to the elements of `destination` that
    /// offer `kind`.
    pub kind: ChannelKind,

    pub phantom: PhantomData<Ctx>,
}
impl Parser<Statement<UncheckedCtx>> for Statement<UncheckedCtx> {
    fn description() -> String {
        "Parser".to_owned()
    }

    fn parse(path: Path, source: &mut JSON) -> Result<Self, ParseError> {
        let destination = try!(path.push("destination",
            |path| SetterSelector::take_vec(path, source, "destination"))
        );
        let kind = try!(path.push("kind",
            |path| ChannelKind::take(path, source, "kind"))
        );
        let value = try!(path.push("value",
            |path| Value::take(path, source, "value"))
        );
        Ok(Statement {
            destination: destination,
            value: value,
            kind: kind,
            phantom: PhantomData,
        })
    }
}

/// A manner of representing internal nodes.
///
/// Two data structures implement `Context`:
///
/// - `UncheckedCtx`, designed to mark the fact that a script has not
/// been compiled/checked yet and must not be executed;
/// - `compile::CompiledCtx`, designed to mark the fact that a script
/// has been compiled and can be executed.
pub trait Context {
}

/// A Context used to represent a script that hasn't been compiled
/// yet.
#[derive(Debug)]
pub struct UncheckedCtx;
impl Context for UncheckedCtx {
}

<commit_msg>[fxbox/thinkerbell] Merge pull request #72 from ferjm/fix.tests<commit_after>//! Definition of Thinkerbell scripts.
//!
//! Typical applications will not interact with script
//! objects. Rather, they will use module `parse` to parse a script
//! and module `run` to execute it.

use foxbox_taxonomy::selector::*;
use foxbox_taxonomy::services::*;
use foxbox_taxonomy::values::*;

use std::marker::PhantomData;

/// A thinkerbell script.
#[derive(Debug)]
pub struct Script<Ctx> where Ctx: Context {
    pub name: String,

    /// A set of rules, stating what must be done in which circumstance.
    pub rules: Vec<Rule<Ctx>>,

    pub phantom: PhantomData<Ctx>,
}

impl Parser<Script<UncheckedCtx>> for Script<UncheckedCtx> {
    fn description() -> String {
        "Script".to_owned()
    }
    fn parse(path: Path, source: &mut JSON) -> Result<Self, ParseError> {
        let name =  try!(path.push("", |path| String::take(path, source, "name")));
        let rules = try!(path.push("", |path| Rule::take_vec(path, source, "rules")));
        Ok(Script {
            name: name,
            rules: rules,
            phantom: PhantomData
        })
    }
}

/// A single rule, i.e. "when some condition becomes true, do
/// something".
///
/// # JSON
///
/// A single rule is represented as an object with the following fields:
///
/// - conditions (array of Match): the conditions in which to execute
///   the code – *all* conditions must be met;
/// - execute (array of Statement): the code to execute once all conditions
///   are met.
///
/// ```
/// extern crate foxbox_thinkerbell;
/// extern crate foxbox_taxonomy;
///
/// use foxbox_thinkerbell::ast::*;
/// use foxbox_taxonomy::parse::*;
///
/// # fn main() {
/// let source = r#"{
///   "conditions": [{
///     "source": [{"id": "my getter"}],
///     "kind": "OvenTemperature",
///     "range": {"Geq": {"Temperature": {"C": 300}}},
///     "duration": 3600
///   }],
///   "execute": [{
///     "destination": [{"id": "my setter"}],
///     "value": {"OnOff": "Off"},
///     "kind": "LightOn"
///   }]
/// }"#;
///
/// Rule::<UncheckedCtx>::from_str(&source).unwrap();
/// # }
/// ```
#[derive(Debug)]
pub struct Rule<Ctx> where Ctx: Context {
    /// The condition in which to execute the trigger. The condition
    /// is matched once *all* the `Match` branches are true. Whenever
    /// `conditions` was false and becomes true, we execute `execute`.
    pub conditions: Vec<Match<Ctx>>,

    /// Stuff to do once `condition` is met.
    pub execute: Vec<Statement<Ctx>>,

    pub phantom: PhantomData<Ctx>,
}
impl Parser<Rule<UncheckedCtx>> for Rule<UncheckedCtx> {
    fn description() -> String {
        "Rule".to_owned()
    }

    fn parse(path: Path, source: &mut JSON) -> Result<Self, ParseError> {
        let conditions = try!(path.push("conditions",
            |path| Match::take_vec(path, source, "conditions"))
        );
        let execute = try!(path.push("execute",
            |path| Statement::take_vec(path, source, "execute"))
        );
        Ok(Rule {
            conditions: conditions,
            execute: execute,
            phantom: PhantomData,
        })
    }
}

/// An individual match.
///
/// Matchs always take the form: "data received from getter channel
/// enters given range".
///
/// A condition is true if *any* of the corresponding getter channels
/// yielded a value that enters the given range.
///
/// # JSON
///
/// A match is represented as an object with the following fields:
///
/// - source (array of GetterSelector) - the selector for getters that will
///   provide the data;
/// - kind (ChannelKind) - the kind of getters;
/// - range (Range) - the condition in whih the match is considered met –
///   a match becomes met when any of the sources *enters* the range;
/// - duration (Duration, optional) - if provided, the match is only considered
///   met if any of the sources *enters* and *remains* in the range
///   for `duration`
///
/// ```
/// extern crate foxbox_thinkerbell;
/// extern crate foxbox_taxonomy;
///
/// use foxbox_thinkerbell::ast::*;
/// use foxbox_taxonomy::services::*;
/// use foxbox_taxonomy::parse::*;
///
/// # fn main() {
/// let source = r#"{
///   "source": [{"id": "my getter"}],
///   "kind": "OvenTemperature",
///   "range": {"Geq": {"Temperature": {"C": 300}}},
///   "duration": 3600
/// }"#;
///
/// let match_ = Match::<UncheckedCtx>::from_str(&source).unwrap();
/// assert_eq!(match_.kind, ChannelKind::OvenTemperature);
/// # }
/// ```
#[derive(Debug)]
pub struct Match<Ctx> where Ctx: Context {
    /// The set of getters to watch. Note that the set of getters may
    /// change (e.g. when devices are added/removed) without rebooting
    /// the script.
    pub source: Vec<GetterSelector>,

    /// The kind of channel expected from `source`, e.g. "the current
    /// time of day", "is the door opened?", etc. During compilation,
    /// we make sure that we restrict to the elements of `source` that
    /// offer `kind`.
    pub kind: ChannelKind,

    /// The range of values for which the condition is considered met.
    /// During compilation, we check that the type of `range` is
    /// compatible with that of `getter`.
    pub range: Range,

    /// If specified, the values must remain in the `range` for at least
    /// `duration` before the match is considered valid. This is useful
    /// for sensors that may oscillate around a threshold or for detecting
    /// e.g. that a door has been forgotten open.
    pub duration: Option<Duration>,

    pub phantom: PhantomData<Ctx>,
}
impl Parser<Match<UncheckedCtx>> for Match<UncheckedCtx> {
    fn description() -> String {
        "Match".to_owned()
    }

    fn parse(path: Path, source: &mut JSON) -> Result<Self, ParseError> {
        let sources = try!(path.push("source",
            |path| GetterSelector::take_vec(path, source, "source"))
        );
        let kind = try!(path.push("kind",
            |path| ChannelKind::take(path, source, "kind"))
        );
        let range = try!(path.push("range",
            |path| Range::take(path, source, "range"))
        );
        let duration = match path.push("range",
            |path| Duration::take(path, source, "duration"))
        {
            Err(ParseError::MissingField {..}) => None,
            Err(err) => return Err(err),
            Ok(ok) => Some(ok)
        };
        Ok(Match {
            source: sources,
            kind: kind,
            range: range,
            duration: duration,
            phantom: PhantomData,
        })
    }
}

/// Stuff to actually do. In practice, this means placing calls to devices.
///
/// # JSON
///
/// A statement is represented as an object with the following fields:
/// - destination (array of SetterSelector);
/// - value (Value);
/// - kind (ChannelKind);
///
/// ```
/// extern crate foxbox_thinkerbell;
/// extern crate foxbox_taxonomy;
///
/// use foxbox_thinkerbell::ast::*;
/// use foxbox_taxonomy::values::*;
/// use foxbox_taxonomy::services::*;
/// use foxbox_taxonomy::parse::*;
///
/// # fn main() {
/// let source = r#"{
///   "destination": [{"id": "my setter"}],
///   "value": {"OnOff": "Off"},
///   "kind": "LightOn"
/// }"#;
///
/// let statement = Statement::<UncheckedCtx>::from_str(&source).unwrap();
/// assert_eq!(statement.value, Value::OnOff(OnOff::Off));
/// assert_eq!(statement.kind, ChannelKind::LightOn);
/// # }
/// ```
#[derive(Debug)]
pub struct Statement<Ctx> where Ctx: Context {
    /// The set of setters to which to send a command. Note that the
    /// set of setters may change (e.g. when devices are
    /// added/removed) without rebooting the script.
    pub destination: Vec<SetterSelector>,

    /// Data to send to the resource. During compilation, we check
    /// that the type of `value` is compatible with that of
    /// `destination`.
    pub value: Value,

    /// The kind of channel expected from `destination`, e.g. "close
    /// the door", "set the temperature", etc. During compilation, we
    /// make sure that we restrict to the elements of `destination` that
    /// offer `kind`.
    pub kind: ChannelKind,

    pub phantom: PhantomData<Ctx>,
}
impl Parser<Statement<UncheckedCtx>> for Statement<UncheckedCtx> {
    fn description() -> String {
        "Parser".to_owned()
    }

    fn parse(path: Path, source: &mut JSON) -> Result<Self, ParseError> {
        let destination = try!(path.push("destination",
            |path| SetterSelector::take_vec(path, source, "destination"))
        );
        let kind = try!(path.push("kind",
            |path| ChannelKind::take(path, source, "kind"))
        );
        let value = try!(path.push("value",
            |path| Value::take(path, source, "value"))
        );
        Ok(Statement {
            destination: destination,
            value: value,
            kind: kind,
            phantom: PhantomData,
        })
    }
}

/// A manner of representing internal nodes.
///
/// Two data structures implement `Context`:
///
/// - `UncheckedCtx`, designed to mark the fact that a script has not
/// been compiled/checked yet and must not be executed;
/// - `compile::CompiledCtx`, designed to mark the fact that a script
/// has been compiled and can be executed.
pub trait Context {
}

/// A Context used to represent a script that hasn't been compiled
/// yet.
#[derive(Debug)]
pub struct UncheckedCtx;
impl Context for UncheckedCtx {
}

<|endoftext|>


<commit_before>use std::f64;
use std::i64;
use rand::Rng;
use error::StatsError;
use function::factorial;
use function::gamma;
use result::Result;
use super::{Distribution, Univariate, Discrete};

#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Poisson {
    lambda: f64
}

impl Poisson {
    pub fn new(lambda: f64) -> Result<Poisson> {
        if lambda.is_nan() || lambda < 0.0 {
            Err(StatsError::BadParams)
        } else {
            Ok(Poisson{lambda: lambda})
        }
    }

    pub fn lambda(&self) -> f64 {
        self.lambda
    }
}

impl Distribution for Poisson {
    fn sample<R: Rng>(&self, r: &mut R) -> f64 {
        0.0
    }
}

impl Univariate for Poisson {
    fn mean(&self) -> f64 {
        self.lambda
    }

    fn variance(&self) -> f64 {
        self.lambda
    }

    fn std_dev(&self) -> f64 {
        self.variance().sqrt()
    }

    fn entropy(&self) -> f64 {
        0.5 * (2.0 * f64::consts::PI * f64::consts::E * self.lambda).ln()
        - 1.0 / (12.0 * self.lambda)
        - 1.0 / (24.0 * self.lambda * self.lambda)
        - 19.0 / (360.0 * self.lambda * self.lambda * self.lambda)
    }

    fn skewness(&self) -> f64 {
       1.0 / self.lambda.sqrt()
    }

    fn median(&self) -> f64 {
        (self.lambda + 1.0 / 3.0 - 0.02 / self.lambda).floor()
    }

    fn cdf(&self, x: f64) -> f64 {
        1.0 - gamma::gamma_lr(x + 1.0, self.lambda).unwrap()
    }
}

impl Discrete for Poisson {
    fn mode(&self) -> i64 {
        self.lambda.floor() as i64
    }

    fn min(&self) -> i64 {
        0
    }

    fn max(&self) -> i64 {
        i64::MAX
    }

    fn pmf(&self, x: i64) -> f64 {
        if x < 0 {
            panic!("{}", StatsError::ArgNotNegative("x"));
        }
        (-self.lambda + x as f64 * self.lambda.ln()).exp() - factorial::ln_factorial(x as u64)
    }

    fn ln_pmf(&self, x: i64) -> f64 {
        if x < 0 {
            panic!("{}", StatsError::ArgNotNegative("x"));
        }
        -self.lambda + x as f64 * self.lambda.ln() - factorial::ln_factorial(x as u64)
    }
}<commit_msg>fix poisson pmf<commit_after>use std::f64;
use std::i64;
use rand::Rng;
use error::StatsError;
use function::factorial;
use function::gamma;
use result::Result;
use super::{Distribution, Univariate, Discrete};

#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Poisson {
    lambda: f64
}

impl Poisson {
    pub fn new(lambda: f64) -> Result<Poisson> {
        if lambda.is_nan() || lambda < 0.0 {
            Err(StatsError::BadParams)
        } else {
            Ok(Poisson{lambda: lambda})
        }
    }

    pub fn lambda(&self) -> f64 {
        self.lambda
    }
}

impl Distribution for Poisson {
    fn sample<R: Rng>(&self, r: &mut R) -> f64 {
        0.0
    }
}

impl Univariate for Poisson {
    fn mean(&self) -> f64 {
        self.lambda
    }

    fn variance(&self) -> f64 {
        self.lambda
    }

    fn std_dev(&self) -> f64 {
        self.variance().sqrt()
    }

    fn entropy(&self) -> f64 {
        0.5 * (2.0 * f64::consts::PI * f64::consts::E * self.lambda).ln()
        - 1.0 / (12.0 * self.lambda)
        - 1.0 / (24.0 * self.lambda * self.lambda)
        - 19.0 / (360.0 * self.lambda * self.lambda * self.lambda)
    }

    fn skewness(&self) -> f64 {
       1.0 / self.lambda.sqrt()
    }

    fn median(&self) -> f64 {
        (self.lambda + 1.0 / 3.0 - 0.02 / self.lambda).floor()
    }

    fn cdf(&self, x: f64) -> f64 {
        1.0 - gamma::gamma_lr(x + 1.0, self.lambda).unwrap()
    }
}

impl Discrete for Poisson {
    fn mode(&self) -> i64 {
        self.lambda.floor() as i64
    }

    fn min(&self) -> i64 {
        0
    }

    fn max(&self) -> i64 {
        i64::MAX
    }

    fn pmf(&self, x: i64) -> f64 {
        if x < 0 {
            panic!("{}", StatsError::ArgNotNegative("x"));
        }
        (-self.lambda + x as f64 * self.lambda.ln() - factorial::ln_factorial(x as u64)).exp()
    }

    fn ln_pmf(&self, x: i64) -> f64 {
        if x < 0 {
            panic!("{}", StatsError::ArgNotNegative("x"));
        }
        -self.lambda + x as f64 * self.lambda.ln() - factorial::ln_factorial(x as u64)
    }
}<|endoftext|>


<commit_before>/*
  A reduced test case for Issue #506, provided by Rob Arnold.

  Testing spawning foreign functions
*/

use std;
import task;

#[abi = "cdecl"]
extern mod rustrt {
    fn get_task_id() -> libc::intptr_t;
}

fn main() {
    let f: fn() -> libc::intptr_t = rustrt::get_task_id;
    task::spawn(unsafe { unsafe::reinterpret_cast(f) });
}
<commit_msg>xfail issue-506 - broken on darwin<commit_after>// xfail-test
/*
  A reduced test case for Issue #506, provided by Rob Arnold.

  Testing spawning foreign functions
*/

use std;
import task;

#[abi = "cdecl"]
extern mod rustrt {
    fn get_task_id() -> libc::intptr_t;
}

fn main() {
    let f: fn() -> libc::intptr_t = rustrt::get_task_id;
    task::spawn(unsafe { unsafe::reinterpret_cast(f) });
}
<|endoftext|>


<commit_before>fn main() {
    for i in range(0, 10) {
        println!("{}", i)
    }
}
<commit_msg>fix sample code<commit_after>fn main() {
    for i in range(0, 10u) {
        println!("{}", i)
    }
}
<|endoftext|>


<commit_before><commit_msg>[dx12] implement fill_buffer<commit_after><|endoftext|>


<commit_before>use std::{
    env,
    fs::OpenOptions,
    io::{Seek, SeekFrom},
    process,
    vec::Vec,
};

use serde_json::Value;

use libstratis::engine::BDA;

fn run(devpath: &str) -> Result<(), String> {
    let mut devfile = OpenOptions::new()
        .read(true)
        .open(&devpath)
        .map_err(|the_io_error| format!("Error opening device: {}", the_io_error))?;

    let bda = BDA::load(&mut devfile)
        .map_err(|bda_load_error| format!("BDA detected but error found: {}", bda_load_error))?
        .ok_or_else(|| "No Stratis BDA metadata found".to_string())?;
    println!("{:#?}", bda);

    devfile
        .seek(SeekFrom::Start(0))
        .map_err(|seek_err| format!("Error during seek: {}", seek_err))?;

    let loaded_state = bda
        .load_state(&mut devfile)
        .map_err(|stateload_err| format!("Error during load state: {}", stateload_err))?;
    println!("Pool metadata:");

    if let Some(loaded_state) = loaded_state {
        let state_json: Value = serde_json::from_slice(&loaded_state)
            .map_err(|extract_err| format!("Error during state JSON extract: {}", extract_err))?;
        let state_json_pretty: String = serde_json::to_string_pretty(&state_json)
            .map_err(|parse_err| format!("Error during state JSON parse: {}", parse_err))?;
        println!("{}", state_json_pretty);
    } else {
        println!("None found");
    }

    Ok(())
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() < 2 {
        eprintln!("Usage: stratis_dumpmetadata <device>");
        process::exit(2);
    }
    let devpath = &args[1];

    match run(devpath) {
        Ok(()) => {}
        Err(e) => {
            eprintln!("Error encountered: {}", e);
            process::exit(1);
        }
    }
}
<commit_msg>stratis_dumpmetadata: add MPL 2.0 license header<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::{
    env,
    fs::OpenOptions,
    io::{Seek, SeekFrom},
    process,
    vec::Vec,
};

use serde_json::Value;

use libstratis::engine::BDA;

fn run(devpath: &str) -> Result<(), String> {
    let mut devfile = OpenOptions::new()
        .read(true)
        .open(&devpath)
        .map_err(|the_io_error| format!("Error opening device: {}", the_io_error))?;

    let bda = BDA::load(&mut devfile)
        .map_err(|bda_load_error| format!("BDA detected but error found: {}", bda_load_error))?
        .ok_or_else(|| "No Stratis BDA metadata found".to_string())?;
    println!("{:#?}", bda);

    devfile
        .seek(SeekFrom::Start(0))
        .map_err(|seek_err| format!("Error during seek: {}", seek_err))?;

    let loaded_state = bda
        .load_state(&mut devfile)
        .map_err(|stateload_err| format!("Error during load state: {}", stateload_err))?;
    println!("Pool metadata:");

    if let Some(loaded_state) = loaded_state {
        let state_json: Value = serde_json::from_slice(&loaded_state)
            .map_err(|extract_err| format!("Error during state JSON extract: {}", extract_err))?;
        let state_json_pretty: String = serde_json::to_string_pretty(&state_json)
            .map_err(|parse_err| format!("Error during state JSON parse: {}", parse_err))?;
        println!("{}", state_json_pretty);
    } else {
        println!("None found");
    }

    Ok(())
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() < 2 {
        eprintln!("Usage: stratis_dumpmetadata <device>");
        process::exit(2);
    }
    let devpath = &args[1];

    match run(devpath) {
        Ok(()) => {}
        Err(e) => {
            eprintln!("Error encountered: {}", e);
            process::exit(1);
        }
    }
}
<|endoftext|>


<commit_before>use basenum::BaseFloat;
use builtin::{ cross, dot, normalize };
use traits::GenFloat;
use num;
use mat::mat::{ Matrix3, Matrix4 };
use vec::vec::{ Vector3, Vector4 };

/// Builds a translation 4 * 4 matrix created from a vector of 3 components.
///
/// Uses input matrix `m` and translation vector coordinates `v`.
///
/// # Example
///
/// ```rust
/// # extern crate num;
/// # extern crate glm;
/// # fn main() {
/// use glm::*;
/// use glm::ext::*;
///
/// let matrix = translate(&num::one(), vec3(1., 2., 3.));
/// assert_eq!(matrix[3], vec4(1., 2., 3., 1.));
/// # }
/// ```
#[inline]
pub fn translate<T>(
    m: &Matrix4<T>,
    v: Vector3<T>
) -> Matrix4<T>
where
    T : BaseFloat
{
    Matrix4::new(
        m.c0, m.c1, m.c2,
        m.c0 * v.x + m.c1 * v.y + m.c2 * v.z + m.c3)
}

#[inline]
/// Creates a matrix for a symetric perspective-view frustum based on the default handedness.
///
/// `fov_y` is the field of view angle in the y direction in radians.
/// The `aspect` ratio determines the field of view in the x direction.
/// `near_z` is the distance from the viewer to the near clipping plane (always positive) and
/// `far_z` is the distance from the viewer to the far clipping plane (always positive).
pub fn perspective<T>(
    fov_y: T,
    aspect: T,
    z_near: T,
    z_far: T
) -> Matrix4<T>
where
    T : BaseFloat
{
    // TODO: make this a compile option
    perspective_rh(fov_y, aspect, z_near, z_far)
}

#[inline]
/// Creates a matrix for a right handed, symetric perspective-view frustum.
///
/// `fov_y` is the field of view angle in the y direction in radians.
/// The `aspect` ratio determines the field of view in the x direction.
/// `near_z` is the distance from the viewer to the near clipping plane (always positive) and
/// `far_z` is the distance from the viewer to the far clipping plane (always positive).
pub fn perspective_rh<T>(
    fov_y: T,
    aspect: T,
    z_near: T,
    z_far: T
) -> Matrix4<T>
where
    T : BaseFloat
{
    let zero = num::zero::<T>();
    let one = num::one::<T>();
    let two = one + one;
    let q = one / (fov_y / two).tan();
    let a = q / aspect;
    let b = (z_near + z_far) / (z_near - z_far);
    let c = (two * z_near * z_far) / (z_near - z_far);

    Matrix4::new(
        Vector4::new(   a, zero, zero, zero),
        Vector4::new(zero,    q, zero, zero),
        Vector4::new(zero, zero,    b, zero - one),
        Vector4::new(zero, zero,    c, zero)
    )
}

#[inline]
/// Builds a rotation 4 * 4 matrix created from an axis vector and an angle.
///
/// `m` as the input matrix multiplied by this rotation matrix.
/// `angle` is the rotation angle expressed in radians.
/// Rotation `axis` is recommended to be normalized.
pub fn rotate<T>(
    m: &Matrix4<T>,
    angle: T,
    v: Vector3<T>
) -> Matrix4<T>
where
    T : BaseFloat + GenFloat<T>
{
    let zero = num::zero::<T>();
    let one = num::one::<T>();

    let a = angle;
    let (s, c) = a.sin_cos();
    let axis = normalize(v);
    let temp = axis * (one - c);

    let rotate = Matrix3::new(
        Vector3::new(
            c + temp.x * axis.x,
            temp.x * axis.y + s * axis.z,
            temp.x * axis.z - s * axis.y),
        Vector3::new(
            temp.y * axis.x - s * axis.z,
            c + temp.y * axis.y,
            temp.y * axis.z + s * axis.x),
        Vector3::new(
            temp.z * axis.x + s * axis.y,
            temp.z * axis.y - s * axis.x,
            c + temp.z * axis.z)
        );

    Matrix4::new(
		m.c0 * rotate.c0.x + m.c1 * rotate.c0.y + m.c2 * rotate.c0.z,
		m.c0 * rotate.c1.x + m.c1 * rotate.c1.y + m.c2 * rotate.c1.z,
		m.c0 * rotate.c2.x + m.c1 * rotate.c2.y + m.c2 * rotate.c2.z,
		m.c3
        )
}

#[inline]
/// Builds a scale 4 * 4 matrix created from 3 scalars.
///
/// `m` is the input matrix multiplied by this scale matrix.
/// `v` is the ratio of scaling for each axis.
pub fn scale<T>(
    m: &Matrix4<T>,
    v: Vector3<T>
) -> Matrix4<T>
where
    T : BaseFloat + GenFloat<T>
{
    Matrix4::new(
        m.c0 * v.x,
        m.c1 * v.y,
        m.c2 * v.z,
        m.c3)
}

#[inline]
/// Build a look at view matrix based on the default handedness.
///
/// View matrix is based on the `eye` position of the camera, `center` position where the camera is
/// looking at and a normalized `up` vector, how the camera is oriented. Typically (0, 0, 1)
pub fn look_at<T>(
    eye: Vector3<T>,
    center: Vector3<T>,
    up: Vector3<T>
) -> Matrix4<T>
where
    T : BaseFloat + GenFloat<T>
{
    // TODO: make handedness configurable
    look_at_rh::<T>(eye, center, up)
}

#[inline]
/// Build a right handed look at view matrix.
///
/// View matrix is based on the `eye` position of the camera, `center` position where the camera is
/// looking at and a normalized `up` vector, how the camera is oriented. Typically (0, 0, 1)
pub fn look_at_rh<T>(
    eye: Vector3<T>,
    center: Vector3<T>,
    up: Vector3<T>
) -> Matrix4<T>
where
    T : BaseFloat + GenFloat<T>
{
    let zero = num::zero::<T>();
    let one = num::one::<T>();
    let f = normalize(center - eye);
    let up_n = normalize(up);
    let s = cross(f, up_n);
    let u = cross(s, f);
    Matrix4::new(
        Vector4::new(s.x, u.x,-f.x, zero),
        Vector4::new(s.y, u.y,-f.y, zero),
        Vector4::new(s.z, u.z,-f.z, zero),
        Vector4::new(-dot(s, eye), -dot(u, eye), dot(f, eye), one)
    )
}

#[cfg(test)]
mod test {
    use num;
    use std::f32;
    use vec::vec::{ vec3, vec4 };
    use ext::{ perspective, translate };

    #[test]
    fn test_translate() {
        let v = vec3(1.0, 3.0, 2.0);
        let m = num::one();
        let t = translate(&m, v);
        assert_eq!(t[0], vec4(1., 0., 0., 0.));
        assert_eq!(t[1], vec4(0., 1., 0., 0.));
        assert_eq!(t[2], vec4(0., 0., 1., 0.));
        assert_eq!(t[3], v.extend(1.));
    }

    #[test]
    fn test_perspective() {
        let p = perspective(f32::consts::PI * 2.0 * 45.0 / 360.0, 1920.0 / 1080.0, 0.1, 100.0);
    }
}
<commit_msg>Move #[inline] after function comment<commit_after>use basenum::BaseFloat;
use builtin::{ cross, dot, normalize };
use traits::GenFloat;
use num;
use mat::mat::{ Matrix3, Matrix4 };
use vec::vec::{ Vector3, Vector4 };

/// Builds a translation 4 * 4 matrix created from a vector of 3 components.
///
/// Uses input matrix `m` and translation vector coordinates `v`.
///
/// # Example
///
/// ```rust
/// # extern crate num;
/// # extern crate glm;
/// # fn main() {
/// use glm::*;
/// use glm::ext::*;
///
/// let matrix = translate(&num::one(), vec3(1., 2., 3.));
/// assert_eq!(matrix[3], vec4(1., 2., 3., 1.));
/// # }
/// ```
#[inline]
pub fn translate<T>(
    m: &Matrix4<T>,
    v: Vector3<T>
) -> Matrix4<T>
where
    T : BaseFloat
{
    Matrix4::new(
        m.c0, m.c1, m.c2,
        m.c0 * v.x + m.c1 * v.y + m.c2 * v.z + m.c3)
}

/// Creates a matrix for a symetric perspective-view frustum based on the default handedness.
///
/// `fov_y` is the field of view angle in the y direction in radians.
/// The `aspect` ratio determines the field of view in the x direction.
/// `near_z` is the distance from the viewer to the near clipping plane (always positive) and
/// `far_z` is the distance from the viewer to the far clipping plane (always positive).
#[inline]
pub fn perspective<T>(
    fov_y: T,
    aspect: T,
    z_near: T,
    z_far: T
) -> Matrix4<T>
where
    T : BaseFloat
{
    // TODO: make this a compile option
    perspective_rh(fov_y, aspect, z_near, z_far)
}

/// Creates a matrix for a right handed, symetric perspective-view frustum.
///
/// `fov_y` is the field of view angle in the y direction in radians.
/// The `aspect` ratio determines the field of view in the x direction.
/// `near_z` is the distance from the viewer to the near clipping plane (always positive) and
/// `far_z` is the distance from the viewer to the far clipping plane (always positive).
#[inline]
pub fn perspective_rh<T>(
    fov_y: T,
    aspect: T,
    z_near: T,
    z_far: T
) -> Matrix4<T>
where
    T : BaseFloat
{
    let zero = num::zero::<T>();
    let one = num::one::<T>();
    let two = one + one;
    let q = one / (fov_y / two).tan();
    let a = q / aspect;
    let b = (z_near + z_far) / (z_near - z_far);
    let c = (two * z_near * z_far) / (z_near - z_far);

    Matrix4::new(
        Vector4::new(   a, zero, zero, zero),
        Vector4::new(zero,    q, zero, zero),
        Vector4::new(zero, zero,    b, zero - one),
        Vector4::new(zero, zero,    c, zero)
    )
}

/// Builds a rotation 4 * 4 matrix created from an axis vector and an angle.
///
/// `m` as the input matrix multiplied by this rotation matrix.
/// `angle` is the rotation angle expressed in radians.
/// Rotation `axis` is recommended to be normalized.
#[inline]
pub fn rotate<T>(
    m: &Matrix4<T>,
    angle: T,
    v: Vector3<T>
) -> Matrix4<T>
where
    T : BaseFloat + GenFloat<T>
{
    let zero = num::zero::<T>();
    let one = num::one::<T>();

    let a = angle;
    let (s, c) = a.sin_cos();
    let axis = normalize(v);
    let temp = axis * (one - c);

    let rotate = Matrix3::new(
        Vector3::new(
            c + temp.x * axis.x,
            temp.x * axis.y + s * axis.z,
            temp.x * axis.z - s * axis.y),
        Vector3::new(
            temp.y * axis.x - s * axis.z,
            c + temp.y * axis.y,
            temp.y * axis.z + s * axis.x),
        Vector3::new(
            temp.z * axis.x + s * axis.y,
            temp.z * axis.y - s * axis.x,
            c + temp.z * axis.z)
        );

    Matrix4::new(
		m.c0 * rotate.c0.x + m.c1 * rotate.c0.y + m.c2 * rotate.c0.z,
		m.c0 * rotate.c1.x + m.c1 * rotate.c1.y + m.c2 * rotate.c1.z,
		m.c0 * rotate.c2.x + m.c1 * rotate.c2.y + m.c2 * rotate.c2.z,
		m.c3
        )
}

/// Builds a scale 4 * 4 matrix created from 3 scalars.
///
/// `m` is the input matrix multiplied by this scale matrix.
/// `v` is the ratio of scaling for each axis.
#[inline]
pub fn scale<T>(
    m: &Matrix4<T>,
    v: Vector3<T>
) -> Matrix4<T>
where
    T : BaseFloat + GenFloat<T>
{
    Matrix4::new(
        m.c0 * v.x,
        m.c1 * v.y,
        m.c2 * v.z,
        m.c3)
}

/// Build a look at view matrix based on the default handedness.
///
/// View matrix is based on the `eye` position of the camera, `center` position where the camera is
/// looking at and a normalized `up` vector, how the camera is oriented. Typically (0, 0, 1)
#[inline]
pub fn look_at<T>(
    eye: Vector3<T>,
    center: Vector3<T>,
    up: Vector3<T>
) -> Matrix4<T>
where
    T : BaseFloat + GenFloat<T>
{
    // TODO: make handedness configurable
    look_at_rh::<T>(eye, center, up)
}

/// Build a right handed look at view matrix.
///
/// View matrix is based on the `eye` position of the camera, `center` position where the camera is
/// looking at and a normalized `up` vector, how the camera is oriented. Typically (0, 0, 1)
#[inline]
pub fn look_at_rh<T>(
    eye: Vector3<T>,
    center: Vector3<T>,
    up: Vector3<T>
) -> Matrix4<T>
where
    T : BaseFloat + GenFloat<T>
{
    let zero = num::zero::<T>();
    let one = num::one::<T>();
    let f = normalize(center - eye);
    let up_n = normalize(up);
    let s = cross(f, up_n);
    let u = cross(s, f);
    Matrix4::new(
        Vector4::new(s.x, u.x,-f.x, zero),
        Vector4::new(s.y, u.y,-f.y, zero),
        Vector4::new(s.z, u.z,-f.z, zero),
        Vector4::new(-dot(s, eye), -dot(u, eye), dot(f, eye), one)
    )
}

#[cfg(test)]
mod test {
    use num;
    use std::f32;
    use vec::vec::{ vec3, vec4 };
    use ext::{ perspective, translate };

    #[test]
    fn test_translate() {
        let v = vec3(1.0, 3.0, 2.0);
        let m = num::one();
        let t = translate(&m, v);
        assert_eq!(t[0], vec4(1., 0., 0., 0.));
        assert_eq!(t[1], vec4(0., 1., 0., 0.));
        assert_eq!(t[2], vec4(0., 0., 1., 0.));
        assert_eq!(t[3], v.extend(1.));
    }

    #[test]
    fn test_perspective() {
        let p = perspective(f32::consts::PI * 2.0 * 45.0 / 360.0, 1920.0 / 1080.0, 0.1, 100.0);
    }
}
<|endoftext|>


<commit_before>/// Maximum order of the fixed predictors permitted by the format.
pub const MAX_FIXED_ORDER: usize = 4;

/// Maximum LPC order permitted by the format.
pub const MAX_LPC_ORDER: usize   = 32;

/// A single channel of audio data.
pub struct SubFrame {
  pub data: Data,
  pub wasted_bits: u32,
}

#[derive(Debug, PartialEq, Eq)]
pub enum Data {
  Constant(i32),
  Verbatim(Vec<i32>),
  Fixed(Fixed),
  LPC(LPC),
}

#[derive(Debug, PartialEq, Eq)]
pub struct Fixed {
  pub entropy_coding_method: EntropyCodingMethod,
  pub order: u8,
  pub warmup: [i32; MAX_FIXED_ORDER],
  pub residual: Vec<i32>,
}

#[derive(Debug, PartialEq, Eq)]
pub struct LPC {
  pub entropy_coding_method: EntropyCodingMethod,
  pub order: u8,
  pub qlp_coeff_precision: u8,
  pub quantization_level: i8,
  pub qlp_coefficients: [i32; MAX_LPC_ORDER],
  pub warmup: [i32; MAX_LPC_ORDER],
  pub residual: Vec<i32>,
}

#[derive(Debug, PartialEq, Eq)]
pub struct EntropyCodingMethod {
  pub method_type: CodingMethod,
  pub data: PartitionedRice,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum CodingMethod {
  PartitionedRice,
  PartitionedRice2,
}

#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRice {
  pub order: u32,
  pub contents: PartitionedRiceContents,
}

#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRiceContents {
  pub parameters: Vec<u32>,
  pub raw_bits: Vec<u32>,
  pub capacity_by_order: u32,
}

impl PartitionedRiceContents {
  pub fn new(capacity_by_order: u32) -> PartitionedRiceContents {
    let capacity       = 2_usize.pow(capacity_by_order);
    let mut parameters = Vec::with_capacity(capacity);
    let mut raw_bits   = Vec::with_capacity(capacity);

    unsafe {
      parameters.set_len(capacity);
      raw_bits.set_len(capacity);
    }

    PartitionedRiceContents {
      parameters: parameters,
      raw_bits: raw_bits,
      capacity_by_order: capacity_by_order,
    }
  }
}
<commit_msg>Add documentation for `subframe::Data`<commit_after>/// Maximum order of the fixed predictors permitted by the format.
pub const MAX_FIXED_ORDER: usize = 4;

/// Maximum LPC order permitted by the format.
pub const MAX_LPC_ORDER: usize   = 32;

/// A single channel of audio data.
pub struct SubFrame {
  pub data: Data,
  pub wasted_bits: u32,
}

/// General enum that holds all the different subframe data types.
#[derive(Debug, PartialEq, Eq)]
pub enum Data {
  Constant(i32),
  Verbatim(Vec<i32>),
  Fixed(Fixed),
  LPC(LPC),
}

#[derive(Debug, PartialEq, Eq)]
pub struct Fixed {
  pub entropy_coding_method: EntropyCodingMethod,
  pub order: u8,
  pub warmup: [i32; MAX_FIXED_ORDER],
  pub residual: Vec<i32>,
}

#[derive(Debug, PartialEq, Eq)]
pub struct LPC {
  pub entropy_coding_method: EntropyCodingMethod,
  pub order: u8,
  pub qlp_coeff_precision: u8,
  pub quantization_level: i8,
  pub qlp_coefficients: [i32; MAX_LPC_ORDER],
  pub warmup: [i32; MAX_LPC_ORDER],
  pub residual: Vec<i32>,
}

#[derive(Debug, PartialEq, Eq)]
pub struct EntropyCodingMethod {
  pub method_type: CodingMethod,
  pub data: PartitionedRice,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum CodingMethod {
  PartitionedRice,
  PartitionedRice2,
}

#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRice {
  pub order: u32,
  pub contents: PartitionedRiceContents,
}

#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRiceContents {
  pub parameters: Vec<u32>,
  pub raw_bits: Vec<u32>,
  pub capacity_by_order: u32,
}

impl PartitionedRiceContents {
  pub fn new(capacity_by_order: u32) -> PartitionedRiceContents {
    let capacity       = 2_usize.pow(capacity_by_order);
    let mut parameters = Vec::with_capacity(capacity);
    let mut raw_bits   = Vec::with_capacity(capacity);

    unsafe {
      parameters.set_len(capacity);
      raw_bits.set_len(capacity);
    }

    PartitionedRiceContents {
      parameters: parameters,
      raw_bits: raw_bits,
      capacity_by_order: capacity_by_order,
    }
  }
}
<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::collections::HashMap;
use std::convert::TryInto;
use std::env;
use std::path::{Path, PathBuf};
use std::rc::{Rc, Weak};

use super::super::super::target::bytecode;
use super::super::frame::Closure;
use super::super::gc::GcTrace;
use super::super::value::Value;
use super::LoadedFunction;

pub struct InnerLoadedModule {
    /// The name of the module. This should almost always be the canonicalized
    /// path to the source file.
    name: String,
    /// The source code of the module.
    source: String,
    functions: Vec<LoadedFunction>,
    /// The module's static scope; it holds:
    ///   - Imports
    ///   - Bound or exported variables
    ///   - Bound or exported functions
    static_closure: Closure,
    // A module loaded into memory is uninitialized. Only after it has been
    // evaluated (and imports and exports resolved) is it initialized.
    initialized: bool,
    imports: Imports,
    exports: Exports,
}

impl InnerLoadedModule {
    fn empty(name: String, source: String, builtins_closure: Option<Closure>) -> Self {
        Self {
            name,
            source,
            functions: vec![],
            static_closure: Closure::new_static(builtins_closure),
            initialized: false,
            imports: Imports::new(),
            exports: Exports::new(),
        }
    }
}

// Opaque wrapper around a reference-counted loaded unit.
#[derive(Clone)]
pub struct LoadedModule(Rc<RefCell<InnerLoadedModule>>);

impl LoadedModule {
    pub fn from_bytecode(
        module: bytecode::layout::Module,
        name: String,
        source: String,
        builtins_closure: Option<Closure>,
    ) -> Self {
        let inner = Rc::new(RefCell::new(InnerLoadedModule::empty(
            name,
            source,
            builtins_closure,
        )));
        let functions = module
            .functions
            .into_iter()
            .map(|function| {
                let weak_loaded_module = Rc::downgrade(&inner);
                LoadedFunction::new(weak_loaded_module, function)
            })
            .collect::<Vec<LoadedFunction>>();
        inner.borrow_mut().functions = functions;
        Self(inner)
    }

    pub fn name(&self) -> String {
        self.0.borrow().name.clone()
    }

    pub fn source(&self) -> String {
        self.0.borrow().source.clone()
    }

    /// Returns a path to the directory in which relative imports can be
    /// processed for this module.
    pub fn relative_import_path(&self) -> Option<PathBuf> {
        let name = self.name();
        // FIXME: Make REPL detection and handling smarter.
        if name.starts_with("repl[") {
            return env::current_dir().ok();
        }
        let path = Path::new(&name);
        if path.is_file() {
            return path.parent().map(Path::to_path_buf);
        }
        None
    }

    pub fn main(&self) -> LoadedFunction {
        self.0.borrow().functions[0].clone()
    }

    pub fn static_closure(&self) -> Closure {
        self.0.borrow().static_closure.clone()
    }

    pub fn initialized(&self) -> bool {
        self.0.borrow().initialized
    }

    pub fn set_initialized(&self) {
        let mut inner = self.0.borrow_mut();
        inner.initialized = true;
    }

    /// Should only be called by the REPL!
    pub fn override_static_closure(&self, static_closure: Closure) {
        self.0.borrow_mut().static_closure = static_closure;
    }

    pub fn function(&self, id: u16) -> LoadedFunction {
        self.0
            .borrow()
            .functions
            .iter()
            .find(|&function| function.id() == id)
            .expect("Function not found")
            .clone()
    }

    pub fn get_export<N: AsRef<str>>(&self, name: N) -> Option<Value> {
        self.0
            .borrow_mut()
            .exports
            .exports
            .get(name.as_ref())
            .map(Clone::clone)
    }

    pub fn set_export<N: Into<String>>(&self, name: N, value: Value) {
        self.0
            .borrow_mut()
            .exports
            .exports
            .insert(name.into(), value);
    }
}

pub type WeakLoadedModule = Weak<RefCell<InnerLoadedModule>>;

impl TryInto<LoadedModule> for WeakLoadedModule {
    type Error = ();

    fn try_into(self) -> Result<LoadedModule, Self::Error> {
        match self.upgrade() {
            Some(inner) => Ok(LoadedModule(inner)),
            None => Err(()),
        }
    }
}

impl GcTrace for LoadedModule {
    fn trace(&self) {
        let inner = self.0.borrow();
        inner.static_closure.trace();
        for export in inner.exports.exports.values() {
            export.trace();
        }
    }
}

struct Imports {
    /// Maps canonicalized import paths to the corresponding module.
    imports: HashMap<PathBuf, LoadedModule>,
}

impl Imports {
    fn new() -> Self {
        Self {
            imports: HashMap::new(),
        }
    }
}

struct Exports {
    exports: HashMap<String, Value>,
}

impl Exports {
    fn new() -> Self {
        Self {
            exports: HashMap::new(),
        }
    }
}
<commit_msg>Remove unnecessary indirection of `Exports` and remove unused `Imports`<commit_after>use std::cell::RefCell;
use std::collections::HashMap;
use std::convert::TryInto;
use std::env;
use std::path::{Path, PathBuf};
use std::rc::{Rc, Weak};

use super::super::super::target::bytecode;
use super::super::frame::Closure;
use super::super::gc::GcTrace;
use super::super::value::Value;
use super::LoadedFunction;

pub struct InnerLoadedModule {
    /// The name of the module. This should almost always be the canonicalized
    /// path to the source file.
    name: String,
    /// The source code of the module.
    source: String,
    functions: Vec<LoadedFunction>,
    /// The module's static scope; it holds:
    ///   - Imports
    ///   - Bound or exported variables
    ///   - Bound or exported functions
    static_closure: Closure,
    // A module loaded into memory is uninitialized. Only after it has been
    // evaluated (and imports and exports resolved) is it initialized.
    initialized: bool,
    exports: HashMap<String, Value>,
}

impl InnerLoadedModule {
    fn empty(name: String, source: String, builtins_closure: Option<Closure>) -> Self {
        Self {
            name,
            source,
            functions: vec![],
            static_closure: Closure::new_static(builtins_closure),
            initialized: false,
            exports: HashMap::new(),
        }
    }
}

// Opaque wrapper around a reference-counted loaded unit.
#[derive(Clone)]
pub struct LoadedModule(Rc<RefCell<InnerLoadedModule>>);

impl LoadedModule {
    pub fn from_bytecode(
        module: bytecode::layout::Module,
        name: String,
        source: String,
        builtins_closure: Option<Closure>,
    ) -> Self {
        let inner = Rc::new(RefCell::new(InnerLoadedModule::empty(
            name,
            source,
            builtins_closure,
        )));
        let functions = module
            .functions
            .into_iter()
            .map(|function| {
                let weak_loaded_module = Rc::downgrade(&inner);
                LoadedFunction::new(weak_loaded_module, function)
            })
            .collect::<Vec<LoadedFunction>>();
        inner.borrow_mut().functions = functions;
        Self(inner)
    }

    pub fn name(&self) -> String {
        self.0.borrow().name.clone()
    }

    pub fn source(&self) -> String {
        self.0.borrow().source.clone()
    }

    /// Returns a path to the directory in which relative imports can be
    /// processed for this module.
    pub fn relative_import_path(&self) -> Option<PathBuf> {
        let name = self.name();
        // FIXME: Make REPL detection and handling smarter.
        if name.starts_with("repl[") {
            return env::current_dir().ok();
        }
        let path = Path::new(&name);
        if path.is_file() {
            return path.parent().map(Path::to_path_buf);
        }
        None
    }

    pub fn main(&self) -> LoadedFunction {
        self.0.borrow().functions[0].clone()
    }

    pub fn static_closure(&self) -> Closure {
        self.0.borrow().static_closure.clone()
    }

    pub fn initialized(&self) -> bool {
        self.0.borrow().initialized
    }

    pub fn set_initialized(&self) {
        let mut inner = self.0.borrow_mut();
        inner.initialized = true;
    }

    /// Should only be called by the REPL!
    pub fn override_static_closure(&self, static_closure: Closure) {
        self.0.borrow_mut().static_closure = static_closure;
    }

    pub fn function(&self, id: u16) -> LoadedFunction {
        self.0
            .borrow()
            .functions
            .iter()
            .find(|&function| function.id() == id)
            .expect("Function not found")
            .clone()
    }

    pub fn get_export<N: AsRef<str>>(&self, name: N) -> Option<Value> {
        self.0
            .borrow_mut()
            .exports
            .get(name.as_ref())
            .map(Clone::clone)
    }

    pub fn set_export<N: Into<String>>(&self, name: N, value: Value) {
        self.0.borrow_mut().exports.insert(name.into(), value);
    }
}

pub type WeakLoadedModule = Weak<RefCell<InnerLoadedModule>>;

impl TryInto<LoadedModule> for WeakLoadedModule {
    type Error = ();

    fn try_into(self) -> Result<LoadedModule, Self::Error> {
        match self.upgrade() {
            Some(inner) => Ok(LoadedModule(inner)),
            None => Err(()),
        }
    }
}

impl GcTrace for LoadedModule {
    fn trace(&self) {
        let inner = self.0.borrow();
        inner.static_closure.trace();
        for export in inner.exports.values() {
            export.trace();
        }
    }
}
<|endoftext|>


<commit_before>use libc::{c_char, c_int, c_void, int32_t, size_t, uint32_t};

#[repr(C)]
pub enum wl_argument {
    i(int32_t),
    u(uint32_t),
    f(wl_fixed_t),
    s(*const c_char),
    o(*mut wl_object),
    n(uint32_t),
    a(*mut wl_array),
    h(int32_t),
}

#[repr(C)]
pub struct wl_array {
    pub size: size_t,
    pub alloc: size_t,
    pub data: *mut c_void,
}

#[repr(C)]
pub type wl_dispatcher_func_t = extern fn(
    _: *const c_void,
    _: *mut c_void,
    _: uint32_t,
    _: *const wl_message,
    _: *mut wl_argument);

#[repr(C)]
pub type wl_fixed_t = uint32_t;

#[repr(C)]
pub struct wl_interface {
    pub name: *const c_char,
    pub version: c_int,
    pub method_count: c_int,
    pub methods: *const wl_message,
    pub event_count: c_int,
    pub events: *const wl_message,
}

#[repr(C)]
pub struct wl_list {
    pub prev: *mut wl_list,
    pub next: *mut wl_list,
}

#[repr(C)]
pub type wl_log_func_t = extern fn(_: *const c_char, ...);

#[repr(C)]
pub struct wl_message {
    pub name: *const c_char,
    pub signature: *const c_char,
    pub types: *mut *const wl_interface,
}

#[repr(C)]
pub struct wl_object;
<commit_msg>wl_argument size did not match with a Rust enum<commit_after>use libc::{c_char, c_int, c_void, size_t, uint32_t, uint64_t};

#[repr(C)]
pub type wl_argument = uint64_t;

#[repr(C)]
pub struct wl_array {
    pub size: size_t,
    pub alloc: size_t,
    pub data: *mut c_void,
}

#[repr(C)]
pub type wl_dispatcher_func_t = extern fn(
    _: *const c_void,
    _: *mut c_void,
    _: uint32_t,
    _: *const wl_message,
    _: *mut wl_argument);

#[repr(C)]
pub type wl_fixed_t = uint32_t;

#[repr(C)]
pub struct wl_interface {
    pub name: *const c_char,
    pub version: c_int,
    pub method_count: c_int,
    pub methods: *const wl_message,
    pub event_count: c_int,
    pub events: *const wl_message,
}

#[repr(C)]
pub struct wl_list {
    pub prev: *mut wl_list,
    pub next: *mut wl_list,
}

#[repr(C)]
pub type wl_log_func_t = extern fn(_: *const c_char, ...);

#[repr(C)]
pub struct wl_message {
    pub name: *const c_char,
    pub signature: *const c_char,
    pub types: *mut *const wl_interface,
}

#[repr(C)]
pub struct wl_object;
<|endoftext|>


<commit_before>// # Iterating docs and positioms.
//
// At its core of tantivy, relies on a data structure
// called an inverted index.
//
// This example shows how to manually iterate through
// the list of documents containing a term, getting
// its term frequency, and accessing its positions.

// ---
// Importing tantivy...
use tantivy::schema::*;
use tantivy::{doc, DocSet, Index, Postings, TERMINATED};

fn main() -> tantivy::Result<()> {
    // We first create a schema for the sake of the
    // example. Check the `basic_search` example for more information.
    let mut schema_builder = Schema::builder();

    // For this example, we need to make sure to index positions for our title
    // field. `TEXT` precisely does this.
    let title = schema_builder.add_text_field("title", TEXT | STORED);
    let schema = schema_builder.build();

    let index = Index::create_in_ram(schema.clone());

    let mut index_writer = index.writer_with_num_threads(1, 50_000_000)?;
    index_writer.add_document(doc!(title => "The Old Man and the Sea"));
    index_writer.add_document(doc!(title => "Of Mice and Men"));
    index_writer.add_document(doc!(title => "The modern Promotheus"));
    index_writer.commit()?;

    let reader = index.reader()?;

    let searcher = reader.searcher();

    // A tantivy index is actually a collection of segments.
    // Similarly, a searcher just wraps a list `segment_reader`.
    //
    // (Because we indexed a very small number of documents over one thread
    // there is actually only one segment here, but let's iterate through the list
    // anyway)
    for segment_reader in searcher.segment_readers() {
        // A segment contains different data structure.
        // Inverted index stands for the combination of
        // - the term dictionary
        // - the inverted lists associated to each terms and their positions
        let inverted_index = segment_reader.inverted_index(title)?;

        // A `Term` is a text token associated with a field.
        // Let's go through all docs containing the term `title:the` and access their position
        let term_the = Term::from_field_text(title, "the");

        // This segment posting object is like a cursor over the documents matching the term.
        // The `IndexRecordOption` arguments tells tantivy we will be interested in both term frequencies
        // and positions.
        //
        // If you don't need all this information, you may get better performance by decompressing less
        // information.
        if let Some(mut segment_postings) =
            inverted_index.read_postings(&term_the, IndexRecordOption::WithFreqsAndPositions)?
        {
            // this buffer will be used to request for positions
            let mut positions: Vec<u32> = Vec::with_capacity(100);
            let mut doc_id = segment_postings.doc();
            while doc_id != TERMINATED {
                // This MAY contains deleted documents as well.
                if segment_reader.is_deleted(doc_id) {
                    doc_id = segment_postings.advance();
                    continue;
                }

                // the number of time the term appears in the document.
                let term_freq: u32 = segment_postings.term_freq();
                // accessing positions is slightly expensive and lazy, do not request
                // for them if you don't need them for some documents.
                segment_postings.positions(&mut positions);

                // By definition we should have `term_freq` positions.
                assert_eq!(positions.len(), term_freq as usize);

                // This prints:
                // ```
                // Doc 0: TermFreq 2: [0, 4]
                // Doc 2: TermFreq 1: [0]
                // ```
                println!("Doc {}: TermFreq {}: {:?}", doc_id, term_freq, positions);
                doc_id = segment_postings.advance();
            }
        }
    }

    // A `Term` is a text token associated with a field.
    // Let's go through all docs containing the term `title:the` and access their position
    let term_the = Term::from_field_text(title, "the");

    // Some other powerful operations (especially `.skip_to`) may be useful to consume these
    // posting lists rapidly.
    // You can check for them in the [`DocSet`](https://docs.rs/tantivy/~0/tantivy/trait.DocSet.html) trait
    // and the [`Postings`](https://docs.rs/tantivy/~0/tantivy/trait.Postings.html) trait

    // Also, for some VERY specific high performance use case like an OLAP analysis of logs,
    // you can get better performance by accessing directly the blocks of doc ids.
    for segment_reader in searcher.segment_readers() {
        // A segment contains different data structure.
        // Inverted index stands for the combination of
        // - the term dictionary
        // - the inverted lists associated to each terms and their positions
        let inverted_index = segment_reader.inverted_index(title)?;

        // This segment posting object is like a cursor over the documents matching the term.
        // The `IndexRecordOption` arguments tells tantivy we will be interested in both term frequencies
        // and positions.
        //
        // If you don't need all this information, you may get better performance by decompressing less
        // information.
        if let Some(mut block_segment_postings) =
            inverted_index.read_block_postings(&term_the, IndexRecordOption::Basic)?
        {
            loop {
                let docs = block_segment_postings.docs();
                if docs.is_empty() {
                    break;
                }
                // Once again these docs MAY contains deleted documents as well.
                let docs = block_segment_postings.docs();
                // Prints `Docs [0, 2].`
                println!("Docs {:?}", docs);
                block_segment_postings.advance();
            }
        }
    }

    Ok(())
}
<commit_msg>Fixed spelling<commit_after>// # Iterating docs and positions.
//
// At its core of tantivy, relies on a data structure
// called an inverted index.
//
// This example shows how to manually iterate through
// the list of documents containing a term, getting
// its term frequency, and accessing its positions.

// ---
// Importing tantivy...
use tantivy::schema::*;
use tantivy::{doc, DocSet, Index, Postings, TERMINATED};

fn main() -> tantivy::Result<()> {
    // We first create a schema for the sake of the
    // example. Check the `basic_search` example for more information.
    let mut schema_builder = Schema::builder();

    // For this example, we need to make sure to index positions for our title
    // field. `TEXT` precisely does this.
    let title = schema_builder.add_text_field("title", TEXT | STORED);
    let schema = schema_builder.build();

    let index = Index::create_in_ram(schema.clone());

    let mut index_writer = index.writer_with_num_threads(1, 50_000_000)?;
    index_writer.add_document(doc!(title => "The Old Man and the Sea"));
    index_writer.add_document(doc!(title => "Of Mice and Men"));
    index_writer.add_document(doc!(title => "The modern Promotheus"));
    index_writer.commit()?;

    let reader = index.reader()?;

    let searcher = reader.searcher();

    // A tantivy index is actually a collection of segments.
    // Similarly, a searcher just wraps a list `segment_reader`.
    //
    // (Because we indexed a very small number of documents over one thread
    // there is actually only one segment here, but let's iterate through the list
    // anyway)
    for segment_reader in searcher.segment_readers() {
        // A segment contains different data structure.
        // Inverted index stands for the combination of
        // - the term dictionary
        // - the inverted lists associated to each terms and their positions
        let inverted_index = segment_reader.inverted_index(title)?;

        // A `Term` is a text token associated with a field.
        // Let's go through all docs containing the term `title:the` and access their position
        let term_the = Term::from_field_text(title, "the");

        // This segment posting object is like a cursor over the documents matching the term.
        // The `IndexRecordOption` arguments tells tantivy we will be interested in both term frequencies
        // and positions.
        //
        // If you don't need all this information, you may get better performance by decompressing less
        // information.
        if let Some(mut segment_postings) =
            inverted_index.read_postings(&term_the, IndexRecordOption::WithFreqsAndPositions)?
        {
            // this buffer will be used to request for positions
            let mut positions: Vec<u32> = Vec::with_capacity(100);
            let mut doc_id = segment_postings.doc();
            while doc_id != TERMINATED {
                // This MAY contains deleted documents as well.
                if segment_reader.is_deleted(doc_id) {
                    doc_id = segment_postings.advance();
                    continue;
                }

                // the number of time the term appears in the document.
                let term_freq: u32 = segment_postings.term_freq();
                // accessing positions is slightly expensive and lazy, do not request
                // for them if you don't need them for some documents.
                segment_postings.positions(&mut positions);

                // By definition we should have `term_freq` positions.
                assert_eq!(positions.len(), term_freq as usize);

                // This prints:
                // ```
                // Doc 0: TermFreq 2: [0, 4]
                // Doc 2: TermFreq 1: [0]
                // ```
                println!("Doc {}: TermFreq {}: {:?}", doc_id, term_freq, positions);
                doc_id = segment_postings.advance();
            }
        }
    }

    // A `Term` is a text token associated with a field.
    // Let's go through all docs containing the term `title:the` and access their position
    let term_the = Term::from_field_text(title, "the");

    // Some other powerful operations (especially `.skip_to`) may be useful to consume these
    // posting lists rapidly.
    // You can check for them in the [`DocSet`](https://docs.rs/tantivy/~0/tantivy/trait.DocSet.html) trait
    // and the [`Postings`](https://docs.rs/tantivy/~0/tantivy/trait.Postings.html) trait

    // Also, for some VERY specific high performance use case like an OLAP analysis of logs,
    // you can get better performance by accessing directly the blocks of doc ids.
    for segment_reader in searcher.segment_readers() {
        // A segment contains different data structure.
        // Inverted index stands for the combination of
        // - the term dictionary
        // - the inverted lists associated to each terms and their positions
        let inverted_index = segment_reader.inverted_index(title)?;

        // This segment posting object is like a cursor over the documents matching the term.
        // The `IndexRecordOption` arguments tells tantivy we will be interested in both term frequencies
        // and positions.
        //
        // If you don't need all this information, you may get better performance by decompressing less
        // information.
        if let Some(mut block_segment_postings) =
            inverted_index.read_block_postings(&term_the, IndexRecordOption::Basic)?
        {
            loop {
                let docs = block_segment_postings.docs();
                if docs.is_empty() {
                    break;
                }
                // Once again these docs MAY contains deleted documents as well.
                let docs = block_segment_postings.docs();
                // Prints `Docs [0, 2].`
                println!("Docs {:?}", docs);
                block_segment_postings.advance();
            }
        }
    }

    Ok(())
}
<|endoftext|>