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

//! Traits for working with Errors.
//!
//! # The `Error` trait
//!
//! `Error` is a trait representing the basic expectations for error values,
//! i.e. values of type `E` in `Result<T, E>`. At a minimum, errors must provide
//! a description, but they may optionally provide additional detail (via
//! `Display`) and cause chain information:
//!
//! ```
//! use std::fmt::Display;
//!
//! trait Error: Display {
//!     fn description(&self) -> &str;
//!
//!     fn cause(&self) -> Option<&Error> { None }
//! }
//! ```
//!
//! The `cause` method is generally used when errors cross "abstraction
//! boundaries", i.e.  when a one module must report an error that is "caused"
//! by an error from a lower-level module. This setup makes it possible for the
//! high-level module to provide its own errors that do not commit to any
//! particular implementation, but also reveal some of its implementation for
//! debugging via `cause` chains.

#![stable(feature = "rust1", since = "1.0.0")]

// A note about crates and the facade:
//
// Originally, the `Error` trait was defined in libcore, and the impls
// were scattered about. However, coherence objected to this
// arrangement, because to create the blanket impls for `Box` required
// knowing that `&str: !Error`, and we have no means to deal with that
// sort of conflict just now. Therefore, for the time being, we have
// moved the `Error` trait into libstd. As we evolve a sol'n to the
// coherence challenge (e.g., specialization, neg impls, etc) we can
// reconsider what crate these items belong in.

use any::TypeId;
use boxed::Box;
use char;
use fmt::{self, Debug, Display};
use marker::{Send, Sync, Reflect};
use mem::transmute;
use num;
use raw::TraitObject;
use str;
use string::{self, String};

/// Base functionality for all errors in Rust.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Error: Debug + Display + Reflect {
    /// A short description of the error.
    ///
    /// The description should not contain newlines or sentence-ending
    /// punctuation, to facilitate embedding in larger user-facing
    /// strings.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn description(&self) -> &str;

    /// The lower-level cause of this error, if any.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn cause(&self) -> Option<&Error> { None }

    /// Get the `TypeId` of `self`
    #[doc(hidden)]
    #[unstable(feature = "error_type_id",
               reason = "unclear whether to commit to this public implementation detail",
               issue = "27745")]
    fn type_id(&self) -> TypeId where Self: 'static {
        TypeId::of::<Self>()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, E: Error + 'a> From<E> for Box<Error + 'a> {
    fn from(err: E) -> Box<Error + 'a> {
        Box::new(err)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<Error + Send + Sync + 'a> {
    fn from(err: E) -> Box<Error + Send + Sync + 'a> {
        Box::new(err)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl From<String> for Box<Error + Send + Sync> {
    fn from(err: String) -> Box<Error + Send + Sync> {
        #[derive(Debug)]
        struct StringError(String);

        impl Error for StringError {
            fn description(&self) -> &str { &self.0 }
        }

        impl Display for StringError {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                Display::fmt(&self.0, f)
            }
        }

        Box::new(StringError(err))
    }
}

#[stable(feature = "string_box_error", since = "1.7.0")]
impl From<String> for Box<Error> {
    fn from(str_err: String) -> Box<Error> {
        let err1: Box<Error + Send + Sync> = From::from(str_err);
        let err2: Box<Error> = err1;
        err2
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b> From<&'b str> for Box<Error + Send + Sync + 'a> {
    fn from(err: &'b str) -> Box<Error + Send + Sync + 'a> {
        From::from(String::from(err))
    }
}

#[stable(feature = "string_box_error", since = "1.7.0")]
impl<'a> From<&'a str> for Box<Error> {
    fn from(err: &'a str) -> Box<Error> {
        From::from(String::from(err))
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for str::ParseBoolError {
    fn description(&self) -> &str { "failed to parse bool" }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for str::Utf8Error {
    fn description(&self) -> &str {
        "invalid utf-8: corrupt contents"
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for num::ParseIntError {
    fn description(&self) -> &str {
        self.__description()
    }
}

#[unstable(feature = "try_from", issue = "33417")]
impl Error for num::TryFromIntError {
    fn description(&self) -> &str {
        self.__description()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for num::ParseFloatError {
    fn description(&self) -> &str {
        self.__description()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for string::FromUtf8Error {
    fn description(&self) -> &str {
        "invalid utf-8"
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for string::FromUtf16Error {
    fn description(&self) -> &str {
        "invalid utf-16"
    }
}

#[stable(feature = "str_parse_error2", since = "1.8.0")]
impl Error for string::ParseError {
    fn description(&self) -> &str {
        match *self {}
    }
}

#[stable(feature = "decode_utf16", since = "1.9.0")]
impl Error for char::DecodeUtf16Error {
    fn description(&self) -> &str {
        "unpaired surrogate found"
    }
}

#[stable(feature = "box_error", since = "1.7.0")]
impl<T: Error> Error for Box<T> {
    fn description(&self) -> &str {
        Error::description(&**self)
    }

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

// copied from any.rs
impl Error + 'static {
    /// Returns true if the boxed type is the same as `T`
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn is<T: Error + 'static>(&self) -> bool {
        // Get TypeId of the type this function is instantiated with
        let t = TypeId::of::<T>();

        // Get TypeId of the type in the trait object
        let boxed = self.type_id();

        // Compare both TypeIds on equality
        t == boxed
    }

    /// Returns some reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute(self);

                // Extract the data pointer
                Some(&*(to.data as *const T))
            }
        } else {
            None
        }
    }

    /// Returns some mutable reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute(self);

                // Extract the data pointer
                Some(&mut *(to.data as *const T as *mut T))
            }
        } else {
            None
        }
    }
}

impl Error + 'static + Send {
    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn is<T: Error + 'static>(&self) -> bool {
        <Error + 'static>::is::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
        <Error + 'static>::downcast_ref::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
        <Error + 'static>::downcast_mut::<T>(self)
    }
}

impl Error + 'static + Send + Sync {
    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn is<T: Error + 'static>(&self) -> bool {
        <Error + 'static>::is::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
        <Error + 'static>::downcast_ref::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
        <Error + 'static>::downcast_mut::<T>(self)
    }
}

impl Error {
    #[inline]
    #[stable(feature = "error_downcast", since = "1.3.0")]
    /// Attempt to downcast the box to a concrete type.
    pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Error>> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let raw = Box::into_raw(self);
                let to: TraitObject =
                    transmute::<*mut Error, TraitObject>(raw);

                // Extract the data pointer
                Ok(Box::from_raw(to.data as *mut T))
            }
        } else {
            Err(self)
        }
    }
}

impl Error + Send {
    #[inline]
    #[stable(feature = "error_downcast", since = "1.3.0")]
    /// Attempt to downcast the box to a concrete type.
    pub fn downcast<T: Error + 'static>(self: Box<Self>)
                                        -> Result<Box<T>, Box<Error + Send>> {
        let err: Box<Error> = self;
        <Error>::downcast(err).map_err(|s| unsafe {
            // reapply the Send marker
            transmute::<Box<Error>, Box<Error + Send>>(s)
        })
    }
}

impl Error + Send + Sync {
    #[inline]
    #[stable(feature = "error_downcast", since = "1.3.0")]
    /// Attempt to downcast the box to a concrete type.
    pub fn downcast<T: Error + 'static>(self: Box<Self>)
                                        -> Result<Box<T>, Box<Self>> {
        let err: Box<Error> = self;
        <Error>::downcast(err).map_err(|s| unsafe {
            // reapply the Send+Sync marker
            transmute::<Box<Error>, Box<Error + Send + Sync>>(s)
        })
    }
}

#[cfg(test)]
mod tests {
    use prelude::v1::*;
    use super::Error;
    use fmt;

    #[derive(Debug, PartialEq)]
    struct A;
    #[derive(Debug, PartialEq)]
    struct B;

    impl fmt::Display for A {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "A")
        }
    }
    impl fmt::Display for B {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "B")
        }
    }

    impl Error for A {
        fn description(&self) -> &str { "A-desc" }
    }
    impl Error for B {
        fn description(&self) -> &str { "A-desc" }
    }

    #[test]
    fn downcasting() {
        let mut a = A;
        let mut a = &mut a as &mut (Error + 'static);
        assert_eq!(a.downcast_ref::<A>(), Some(&A));
        assert_eq!(a.downcast_ref::<B>(), None);
        assert_eq!(a.downcast_mut::<A>(), Some(&mut A));
        assert_eq!(a.downcast_mut::<B>(), None);

        let a: Box<Error> = Box::new(A);
        match a.downcast::<B>() {
            Ok(..) => panic!("expected error"),
            Err(e) => assert_eq!(*e.downcast::<A>().unwrap(), A),
        }
    }
}
<commit_msg>Rollup merge of #33856 - GuillaumeGomez:fmt_error, r=alexcrichton<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Traits for working with Errors.
//!
//! # The `Error` trait
//!
//! `Error` is a trait representing the basic expectations for error values,
//! i.e. values of type `E` in `Result<T, E>`. At a minimum, errors must provide
//! a description, but they may optionally provide additional detail (via
//! `Display`) and cause chain information:
//!
//! ```
//! use std::fmt::Display;
//!
//! trait Error: Display {
//!     fn description(&self) -> &str;
//!
//!     fn cause(&self) -> Option<&Error> { None }
//! }
//! ```
//!
//! The `cause` method is generally used when errors cross "abstraction
//! boundaries", i.e.  when a one module must report an error that is "caused"
//! by an error from a lower-level module. This setup makes it possible for the
//! high-level module to provide its own errors that do not commit to any
//! particular implementation, but also reveal some of its implementation for
//! debugging via `cause` chains.

#![stable(feature = "rust1", since = "1.0.0")]

// A note about crates and the facade:
//
// Originally, the `Error` trait was defined in libcore, and the impls
// were scattered about. However, coherence objected to this
// arrangement, because to create the blanket impls for `Box` required
// knowing that `&str: !Error`, and we have no means to deal with that
// sort of conflict just now. Therefore, for the time being, we have
// moved the `Error` trait into libstd. As we evolve a sol'n to the
// coherence challenge (e.g., specialization, neg impls, etc) we can
// reconsider what crate these items belong in.

use any::TypeId;
use boxed::Box;
use char;
use fmt::{self, Debug, Display};
use marker::{Send, Sync, Reflect};
use mem::transmute;
use num;
use raw::TraitObject;
use str;
use string::{self, String};

/// Base functionality for all errors in Rust.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Error: Debug + Display + Reflect {
    /// A short description of the error.
    ///
    /// The description should not contain newlines or sentence-ending
    /// punctuation, to facilitate embedding in larger user-facing
    /// strings.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn description(&self) -> &str;

    /// The lower-level cause of this error, if any.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn cause(&self) -> Option<&Error> { None }

    /// Get the `TypeId` of `self`
    #[doc(hidden)]
    #[unstable(feature = "error_type_id",
               reason = "unclear whether to commit to this public implementation detail",
               issue = "27745")]
    fn type_id(&self) -> TypeId where Self: 'static {
        TypeId::of::<Self>()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, E: Error + 'a> From<E> for Box<Error + 'a> {
    fn from(err: E) -> Box<Error + 'a> {
        Box::new(err)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<Error + Send + Sync + 'a> {
    fn from(err: E) -> Box<Error + Send + Sync + 'a> {
        Box::new(err)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl From<String> for Box<Error + Send + Sync> {
    fn from(err: String) -> Box<Error + Send + Sync> {
        #[derive(Debug)]
        struct StringError(String);

        impl Error for StringError {
            fn description(&self) -> &str { &self.0 }
        }

        impl Display for StringError {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                Display::fmt(&self.0, f)
            }
        }

        Box::new(StringError(err))
    }
}

#[stable(feature = "string_box_error", since = "1.7.0")]
impl From<String> for Box<Error> {
    fn from(str_err: String) -> Box<Error> {
        let err1: Box<Error + Send + Sync> = From::from(str_err);
        let err2: Box<Error> = err1;
        err2
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b> From<&'b str> for Box<Error + Send + Sync + 'a> {
    fn from(err: &'b str) -> Box<Error + Send + Sync + 'a> {
        From::from(String::from(err))
    }
}

#[stable(feature = "string_box_error", since = "1.7.0")]
impl<'a> From<&'a str> for Box<Error> {
    fn from(err: &'a str) -> Box<Error> {
        From::from(String::from(err))
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for str::ParseBoolError {
    fn description(&self) -> &str { "failed to parse bool" }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for str::Utf8Error {
    fn description(&self) -> &str {
        "invalid utf-8: corrupt contents"
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for num::ParseIntError {
    fn description(&self) -> &str {
        self.__description()
    }
}

#[unstable(feature = "try_from", issue = "33417")]
impl Error for num::TryFromIntError {
    fn description(&self) -> &str {
        self.__description()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for num::ParseFloatError {
    fn description(&self) -> &str {
        self.__description()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for string::FromUtf8Error {
    fn description(&self) -> &str {
        "invalid utf-8"
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for string::FromUtf16Error {
    fn description(&self) -> &str {
        "invalid utf-16"
    }
}

#[stable(feature = "str_parse_error2", since = "1.8.0")]
impl Error for string::ParseError {
    fn description(&self) -> &str {
        match *self {}
    }
}

#[stable(feature = "decode_utf16", since = "1.9.0")]
impl Error for char::DecodeUtf16Error {
    fn description(&self) -> &str {
        "unpaired surrogate found"
    }
}

#[stable(feature = "box_error", since = "1.7.0")]
impl<T: Error> Error for Box<T> {
    fn description(&self) -> &str {
        Error::description(&**self)
    }

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

#[stable(feature = "fmt_error", since = "1.11.0")]
impl Error for fmt::Error {
    fn description(&self) -> &str {
        "an error occurred when formatting an argument"
    }
}

// copied from any.rs
impl Error + 'static {
    /// Returns true if the boxed type is the same as `T`
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn is<T: Error + 'static>(&self) -> bool {
        // Get TypeId of the type this function is instantiated with
        let t = TypeId::of::<T>();

        // Get TypeId of the type in the trait object
        let boxed = self.type_id();

        // Compare both TypeIds on equality
        t == boxed
    }

    /// Returns some reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute(self);

                // Extract the data pointer
                Some(&*(to.data as *const T))
            }
        } else {
            None
        }
    }

    /// Returns some mutable reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute(self);

                // Extract the data pointer
                Some(&mut *(to.data as *const T as *mut T))
            }
        } else {
            None
        }
    }
}

impl Error + 'static + Send {
    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn is<T: Error + 'static>(&self) -> bool {
        <Error + 'static>::is::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
        <Error + 'static>::downcast_ref::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
        <Error + 'static>::downcast_mut::<T>(self)
    }
}

impl Error + 'static + Send + Sync {
    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn is<T: Error + 'static>(&self) -> bool {
        <Error + 'static>::is::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
        <Error + 'static>::downcast_ref::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "error_downcast", since = "1.3.0")]
    #[inline]
    pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
        <Error + 'static>::downcast_mut::<T>(self)
    }
}

impl Error {
    #[inline]
    #[stable(feature = "error_downcast", since = "1.3.0")]
    /// Attempt to downcast the box to a concrete type.
    pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Error>> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let raw = Box::into_raw(self);
                let to: TraitObject =
                    transmute::<*mut Error, TraitObject>(raw);

                // Extract the data pointer
                Ok(Box::from_raw(to.data as *mut T))
            }
        } else {
            Err(self)
        }
    }
}

impl Error + Send {
    #[inline]
    #[stable(feature = "error_downcast", since = "1.3.0")]
    /// Attempt to downcast the box to a concrete type.
    pub fn downcast<T: Error + 'static>(self: Box<Self>)
                                        -> Result<Box<T>, Box<Error + Send>> {
        let err: Box<Error> = self;
        <Error>::downcast(err).map_err(|s| unsafe {
            // reapply the Send marker
            transmute::<Box<Error>, Box<Error + Send>>(s)
        })
    }
}

impl Error + Send + Sync {
    #[inline]
    #[stable(feature = "error_downcast", since = "1.3.0")]
    /// Attempt to downcast the box to a concrete type.
    pub fn downcast<T: Error + 'static>(self: Box<Self>)
                                        -> Result<Box<T>, Box<Self>> {
        let err: Box<Error> = self;
        <Error>::downcast(err).map_err(|s| unsafe {
            // reapply the Send+Sync marker
            transmute::<Box<Error>, Box<Error + Send + Sync>>(s)
        })
    }
}

#[cfg(test)]
mod tests {
    use prelude::v1::*;
    use super::Error;
    use fmt;

    #[derive(Debug, PartialEq)]
    struct A;
    #[derive(Debug, PartialEq)]
    struct B;

    impl fmt::Display for A {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "A")
        }
    }
    impl fmt::Display for B {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "B")
        }
    }

    impl Error for A {
        fn description(&self) -> &str { "A-desc" }
    }
    impl Error for B {
        fn description(&self) -> &str { "A-desc" }
    }

    #[test]
    fn downcasting() {
        let mut a = A;
        let mut a = &mut a as &mut (Error + 'static);
        assert_eq!(a.downcast_ref::<A>(), Some(&A));
        assert_eq!(a.downcast_ref::<B>(), None);
        assert_eq!(a.downcast_mut::<A>(), Some(&mut A));
        assert_eq!(a.downcast_mut::<B>(), None);

        let a: Box<Error> = Box::new(A);
        match a.downcast::<B>() {
            Ok(..) => panic!("expected error"),
            Err(e) => assert_eq!(*e.downcast::<A>().unwrap(), A),
        }
    }
}
<|endoftext|>


<commit_before>use prolog::allocator::*;
use prolog::ast::*;
use prolog::targets::*;

use std::cell::Cell;
use std::collections::{BTreeSet, HashMap};
use std::rc::Rc;

pub struct DebrayAllocator {
    bindings: HashMap<Rc<Var>, VarData>,
    arg_c:    usize,
    temp_lb:  usize,
    arity:    usize, // 0 if not at head.
    contents: HashMap<usize, Rc<Var>>,
    in_use:   BTreeSet<usize>,
}

impl DebrayAllocator {
    fn is_curr_arg_distinct_from(&self, var: &Var) -> bool {
        match self.contents.get(&self.arg_c) {
            Some(t_var) if **t_var != *var => true,
            _ => false
        }
    }

    fn occurs_shallowly_in_head(&self, var: &Var, r: usize) -> bool
    {
        match self.bindings.get(var).unwrap() {
            &VarData::Temp(_, _, ref tvd) =>
                tvd.use_set.contains(&(GenContext::Head, r)),
            _ => false
        }
    }

    fn is_in_use(&self, r: usize) -> bool {
        let in_use_range = r < self.arity && r >= self.arg_c;
        self.in_use.contains(&r) || in_use_range
    }

    fn alloc_with_cr(&self, var: &Var) -> usize
    {
        match self.bindings.get(var) {
            Some(&VarData::Temp(_, _, ref tvd)) => {
                for &(_, reg) in tvd.use_set.iter() {
                    if !self.is_in_use(reg) {
                        return reg;
                    }
                }

                let mut result = 0;

                for reg in self.temp_lb .. {
                    if !self.is_in_use(reg) {
                        if !tvd.no_use_set.contains(&reg) {
                            result = reg;
                            break;
                        }
                    }
                }

                result
            },
            _ => 0
        }
    }

    fn alloc_with_ca(&self, var: &Var) -> usize
    {
        match self.bindings.get(var) {
            Some(&VarData::Temp(_, _, ref tvd)) => {
                for &(_, reg) in tvd.use_set.iter() {
                    if !self.is_in_use(reg) {
                        return reg;
                    }
                }

                let mut result = 0;

                for reg in self.temp_lb .. {
                    if !self.is_in_use(reg) {
                        if !tvd.no_use_set.contains(&reg) {
                            if !tvd.conflict_set.contains(&reg) {
                                result = reg;
                                break;
                            }
                        }
                    }
                }

                result
            },
            _ => 0
        }
    }

    fn alloc_in_last_goal_hint(&self, chunk_num: usize) -> Option<(Rc<Var>, usize)>
    {
        // we want to allocate a register to the k^{th} parameter, par_k.
        // par_k may not be a temporary variable.
        let k = self.arg_c;

        match self.contents.get(&k) {
            Some(t_var) => {
                // suppose this branch fires. then t_var is a
                // temp. var. belonging to the current chunk.
                // consider its use set. T == par_k iff
                // (GenContext::Last(_), k) is in t_var.use_set.

                let tvd = self.bindings.get(t_var).unwrap();
                if let &VarData::Temp(_, _, ref tvd) = tvd {
                    if !tvd.use_set.contains(&(GenContext::Last(chunk_num), k)) {
                        return Some((t_var.clone(), self.alloc_with_ca(t_var)));
                    }
                }

                None
            },
            _ => None
        }
    }

    fn evacuate_arg<'a, Target>(&mut self, chunk_num: usize, target: &mut Vec<Target>)
        where Target: CompilationTarget<'a>
    {
        match self.alloc_in_last_goal_hint(chunk_num) {
            Some((var, r)) => {
                let k = self.arg_c;

                if r != k {
                    let r = RegType::Temp(r);

                    target.push(Target::move_to_register(r, k));

                    self.contents.remove(&k);
                    self.contents.insert(r.reg_num(), var.clone());

                    self.record_register(var, r);
                    self.in_use.insert(r.reg_num());
                }
            },
            _ => {}
        };
    }

    fn alloc_reg_to_var<'a, Target>(&mut self, var: &Var, lvl: Level, term_loc: GenContext,
                                    target: &mut Vec<Target>)
                                -> usize
        where Target: CompilationTarget<'a>
    {
        match term_loc {
            GenContext::Head =>
                if let Level::Shallow = lvl {
                    self.evacuate_arg(0, target);
                    self.alloc_with_cr(var)
                } else {
                    self.alloc_with_ca(var)
                },
            GenContext::Mid(_) =>
                self.alloc_with_ca(var),
            GenContext::Last(chunk_num) =>
                if let Level::Shallow = lvl {
                    self.evacuate_arg(chunk_num, target);
                    self.alloc_with_cr(var)
                } else {
                    self.alloc_with_ca(var)
                }
        }
    }

    fn alloc_reg_to_non_var(&mut self) -> usize
    {
        let mut final_index = 0;

        for index in self.temp_lb .. {
            if !self.in_use.contains(&index) {
                final_index = index;
                break;
            }
        }

        self.temp_lb = final_index + 1;

        final_index
    }

    fn in_place(&self, var: &Var, term_loc: GenContext, r: RegType, k: usize) -> bool
    {
        match term_loc {
            GenContext::Head if !r.is_perm() => r.reg_num() == k,
            _ => match self.bindings().get(var).unwrap() {
                     &VarData::Temp(_, o, _) if r.reg_num() == k => o == k,
                     _ => false
                 }
        }
    }
}

impl<'a> Allocator<'a> for DebrayAllocator
{
    fn new() -> DebrayAllocator {
        DebrayAllocator {
            arity:   0,
            arg_c:   1,
            temp_lb: 1,
            bindings: HashMap::new(),
            contents: HashMap::new(),
            in_use: BTreeSet::new()
        }
    }

    fn mark_anon_var<Target>(&mut self, lvl: Level, target: &mut Vec<Target>)
        where Target: CompilationTarget<'a>
    {
        let r = RegType::Temp(self.alloc_reg_to_non_var());

        match lvl {
            Level::Deep => target.push(Target::subterm_to_variable(r)),
            Level::Root | Level::Shallow => {
                let k = self.arg_c;
                self.arg_c += 1;

                target.push(Target::argument_to_variable(r, k));
            }
        };
    }

    fn mark_non_var<Target>(&mut self, lvl: Level, term_loc: GenContext,
                            cell: &Cell<RegType>, target: &mut Vec<Target>)
        where Target: CompilationTarget<'a>
    {
        let r = cell.get();

        if r.reg_num() == 0 {
            let r = match lvl {
                Level::Shallow => {
                    let k = self.arg_c;

                    if let GenContext::Last(chunk_num) = term_loc {
                        self.evacuate_arg(chunk_num, target);
                    }

                    self.arg_c += 1;
                    RegType::Temp(k)
                },
                _ => RegType::Temp(self.alloc_reg_to_non_var())
            };

            cell.set(r);
        }
    }

    fn mark_var<Target>(&mut self, var: Rc<Var>, lvl: Level, cell: &Cell<VarReg>,
                        term_loc: GenContext, target: &mut Vec<Target>)
        where Target: CompilationTarget<'a>
    {
        let (r, is_new_var) = match self.get(var.clone()) {
            RegType::Temp(0) => {
                // here, r is temporary *and* unassigned.
                let o = self.alloc_reg_to_var(&var, lvl, term_loc, target);

                cell.set(VarReg::Norm(RegType::Temp(o)));

                (RegType::Temp(o), true)
            },
            RegType::Perm(0) => {
                let pr = cell.get().norm();
                self.record_register(var.clone(), pr);

                (pr, true)
            },
            r => (r, false)
        };

        match lvl {
            Level::Root | Level::Shallow => {
                let k = self.arg_c;

                if self.is_curr_arg_distinct_from(&var) {
                    self.evacuate_arg(term_loc.chunk_num(), target);
                }

                self.arg_c += 1;

                cell.set(VarReg::ArgAndNorm(r, k));

                if !self.in_place(&var, term_loc, r, k) {
                    if is_new_var {
                        target.push(Target::argument_to_variable(r, k));
                    } else {
                        target.push(Target::argument_to_value(r, k));
                    }
                }
            },
            Level::Deep if is_new_var =>
                if let GenContext::Head = term_loc {
                    if self.occurs_shallowly_in_head(&var, r.reg_num()) {
                        target.push(Target::subterm_to_value(r));
                    } else {
                        target.push(Target::subterm_to_variable(r));
                    }
                } else {
                    target.push(Target::subterm_to_variable(r));
                },
            Level::Deep =>
                target.push(Target::subterm_to_value(r))
        };

        if !r.is_perm() {
            let o = r.reg_num();

            self.contents.insert(o, var.clone());
            self.record_register(var.clone(), r);
            self.in_use.insert(o);
        }
    }

    fn reset(&mut self) {
        self.bindings.clear();
        self.contents.clear();
        self.in_use.clear();
    }

    fn reset_contents(&mut self) {
        self.contents.clear();
        self.in_use.clear();
    }

    fn advance_arg(&mut self) {
        self.arg_c += 1;
    }

    fn bindings(&self) -> &AllocVarDict {
        &self.bindings
    }

    fn bindings_mut(&mut self) -> &mut AllocVarDict {
        &mut self.bindings
    }

    fn take_bindings(self) -> AllocVarDict {
        self.bindings
    }

    fn reset_at_head(&mut self, args: &Vec<Box<Term>>) {
        self.reset_arg(args.len());
        self.arity = args.len();

        for (idx, arg) in args.iter().enumerate() {
            if let &Term::Var(_, ref var) = arg.as_ref() {
                let r = self.get(var.clone());

                if !r.is_perm() && r.reg_num() == 0 {
                    self.in_use.insert(idx + 1);
                    self.contents.insert(idx + 1, var.clone());
                    self.record_register(var.clone(), temp_v!(idx + 1));
                }
            }
        }
    }

    fn reset_arg(&mut self, arity: usize) {
        self.arity   = 0;
        self.arg_c   = 1;
        self.temp_lb = arity + 1;
    }
}
<commit_msg>further debray fix.<commit_after>use prolog::allocator::*;
use prolog::ast::*;
use prolog::targets::*;

use std::cell::Cell;
use std::collections::{BTreeSet, HashMap};
use std::rc::Rc;

pub struct DebrayAllocator {
    bindings: HashMap<Rc<Var>, VarData>,
    arg_c:    usize,
    temp_lb:  usize,
    arity:    usize, // 0 if not at head.
    contents: HashMap<usize, Rc<Var>>,
    in_use:   BTreeSet<usize>,
}

impl DebrayAllocator {
    fn is_curr_arg_distinct_from(&self, var: &Var) -> bool {
        match self.contents.get(&self.arg_c) {
            Some(t_var) if **t_var != *var => true,
            _ => false
        }
    }

    fn occurs_shallowly_in_head(&self, var: &Var, r: usize) -> bool
    {
        match self.bindings.get(var).unwrap() {
            &VarData::Temp(_, _, ref tvd) =>
                tvd.use_set.contains(&(GenContext::Head, r)),
            _ => false
        }
    }

    fn is_in_use(&self, r: usize) -> bool {
        let in_use_range = r <= self.arity && r >= self.arg_c;
        self.in_use.contains(&r) || in_use_range
    }

    fn alloc_with_cr(&self, var: &Var) -> usize
    {
        match self.bindings.get(var) {
            Some(&VarData::Temp(_, _, ref tvd)) => {
                for &(_, reg) in tvd.use_set.iter() {
                    if !self.is_in_use(reg) {
                        return reg;
                    }
                }

                let mut result = 0;

                for reg in self.temp_lb .. {
                    if !self.is_in_use(reg) {
                        if !tvd.no_use_set.contains(&reg) {
                            result = reg;
                            break;
                        }
                    }
                }

                result
            },
            _ => 0
        }
    }

    fn alloc_with_ca(&self, var: &Var) -> usize
    {
        match self.bindings.get(var) {
            Some(&VarData::Temp(_, _, ref tvd)) => {
                for &(_, reg) in tvd.use_set.iter() {
                    if !self.is_in_use(reg) {
                        return reg;
                    }
                }

                let mut result = 0;

                for reg in self.temp_lb .. {
                    if !self.is_in_use(reg) {
                        if !tvd.no_use_set.contains(&reg) {
                            if !tvd.conflict_set.contains(&reg) {
                                result = reg;
                                break;
                            }
                        }
                    }
                }

                result
            },
            _ => 0
        }
    }

    fn alloc_in_last_goal_hint(&self, chunk_num: usize) -> Option<(Rc<Var>, usize)>
    {
        // we want to allocate a register to the k^{th} parameter, par_k.
        // par_k may not be a temporary variable.
        let k = self.arg_c;

        match self.contents.get(&k) {
            Some(t_var) => {
                // suppose this branch fires. then t_var is a
                // temp. var. belonging to the current chunk.
                // consider its use set. T == par_k iff
                // (GenContext::Last(_), k) is in t_var.use_set.

                let tvd = self.bindings.get(t_var).unwrap();
                if let &VarData::Temp(_, _, ref tvd) = tvd {
                    if !tvd.use_set.contains(&(GenContext::Last(chunk_num), k)) {
                        return Some((t_var.clone(), self.alloc_with_ca(t_var)));
                    }
                }

                None
            },
            _ => None
        }
    }

    fn evacuate_arg<'a, Target>(&mut self, chunk_num: usize, target: &mut Vec<Target>)
        where Target: CompilationTarget<'a>
    {
        match self.alloc_in_last_goal_hint(chunk_num) {
            Some((var, r)) => {
                let k = self.arg_c;

                if r != k {
                    let r = RegType::Temp(r);

                    target.push(Target::move_to_register(r, k));

                    self.contents.remove(&k);
                    self.contents.insert(r.reg_num(), var.clone());

                    self.record_register(var, r);
                    self.in_use.insert(r.reg_num());
                }
            },
            _ => {}
        };
    }

    fn alloc_reg_to_var<'a, Target>(&mut self, var: &Var, lvl: Level, term_loc: GenContext,
                                    target: &mut Vec<Target>)
                                -> usize
        where Target: CompilationTarget<'a>
    {
        match term_loc {
            GenContext::Head =>
                if let Level::Shallow = lvl {
                    self.evacuate_arg(0, target);
                    self.alloc_with_cr(var)
                } else {
                    self.alloc_with_ca(var)
                },
            GenContext::Mid(_) =>
                self.alloc_with_ca(var),
            GenContext::Last(chunk_num) =>
                if let Level::Shallow = lvl {
                    self.evacuate_arg(chunk_num, target);
                    self.alloc_with_cr(var)
                } else {
                    self.alloc_with_ca(var)
                }
        }
    }

    fn alloc_reg_to_non_var(&mut self) -> usize
    {
        let mut final_index = 0;

        for index in self.temp_lb .. {
            if !self.in_use.contains(&index) {
                final_index = index;
                break;
            }
        }

        self.temp_lb = final_index + 1;

        final_index
    }

    fn in_place(&self, var: &Var, term_loc: GenContext, r: RegType, k: usize) -> bool
    {
        match term_loc {
            GenContext::Head if !r.is_perm() => r.reg_num() == k,
            _ => match self.bindings().get(var).unwrap() {
                     &VarData::Temp(_, o, _) if r.reg_num() == k => o == k,
                     _ => false
                 }
        }
    }
}

impl<'a> Allocator<'a> for DebrayAllocator
{
    fn new() -> DebrayAllocator {
        DebrayAllocator {
            arity:   0,
            arg_c:   1,
            temp_lb: 1,
            bindings: HashMap::new(),
            contents: HashMap::new(),
            in_use: BTreeSet::new()
        }
    }

    fn mark_anon_var<Target>(&mut self, lvl: Level, target: &mut Vec<Target>)
        where Target: CompilationTarget<'a>
    {
        let r = RegType::Temp(self.alloc_reg_to_non_var());

        match lvl {
            Level::Deep => target.push(Target::subterm_to_variable(r)),
            Level::Root | Level::Shallow => {
                let k = self.arg_c;
                self.arg_c += 1;

                target.push(Target::argument_to_variable(r, k));
            }
        };
    }

    fn mark_non_var<Target>(&mut self, lvl: Level, term_loc: GenContext,
                            cell: &Cell<RegType>, target: &mut Vec<Target>)
        where Target: CompilationTarget<'a>
    {
        let r = cell.get();

        if r.reg_num() == 0 {
            let r = match lvl {
                Level::Shallow => {
                    let k = self.arg_c;

                    if let GenContext::Last(chunk_num) = term_loc {
                        self.evacuate_arg(chunk_num, target);
                    }

                    self.arg_c += 1;
                    RegType::Temp(k)
                },
                _ => RegType::Temp(self.alloc_reg_to_non_var())
            };

            cell.set(r);
        }
    }

    fn mark_var<Target>(&mut self, var: Rc<Var>, lvl: Level, cell: &Cell<VarReg>,
                        term_loc: GenContext, target: &mut Vec<Target>)
        where Target: CompilationTarget<'a>
    {
        let (r, is_new_var) = match self.get(var.clone()) {
            RegType::Temp(0) => {
                // here, r is temporary *and* unassigned.
                let o = self.alloc_reg_to_var(&var, lvl, term_loc, target);

                cell.set(VarReg::Norm(RegType::Temp(o)));

                (RegType::Temp(o), true)
            },
            RegType::Perm(0) => {
                let pr = cell.get().norm();
                self.record_register(var.clone(), pr);

                (pr, true)
            },
            r => (r, false)
        };

        match lvl {
            Level::Root | Level::Shallow => {
                let k = self.arg_c;

                if self.is_curr_arg_distinct_from(&var) {
                    self.evacuate_arg(term_loc.chunk_num(), target);
                }

                self.arg_c += 1;

                cell.set(VarReg::ArgAndNorm(r, k));

                if !self.in_place(&var, term_loc, r, k) {
                    if is_new_var {
                        target.push(Target::argument_to_variable(r, k));
                    } else {
                        target.push(Target::argument_to_value(r, k));
                    }
                }
            },
            Level::Deep if is_new_var =>
                if let GenContext::Head = term_loc {
                    if self.occurs_shallowly_in_head(&var, r.reg_num()) {
                        target.push(Target::subterm_to_value(r));
                    } else {
                        target.push(Target::subterm_to_variable(r));
                    }
                } else {
                    target.push(Target::subterm_to_variable(r));
                },
            Level::Deep =>
                target.push(Target::subterm_to_value(r))
        };

        if !r.is_perm() {
            let o = r.reg_num();

            self.contents.insert(o, var.clone());
            self.record_register(var.clone(), r);
            self.in_use.insert(o);
        }
    }

    fn reset(&mut self) {
        self.bindings.clear();
        self.contents.clear();
        self.in_use.clear();
    }

    fn reset_contents(&mut self) {
        self.contents.clear();
        self.in_use.clear();
    }

    fn advance_arg(&mut self) {
        self.arg_c += 1;
    }

    fn bindings(&self) -> &AllocVarDict {
        &self.bindings
    }

    fn bindings_mut(&mut self) -> &mut AllocVarDict {
        &mut self.bindings
    }

    fn take_bindings(self) -> AllocVarDict {
        self.bindings
    }

    fn reset_at_head(&mut self, args: &Vec<Box<Term>>) {
        self.reset_arg(args.len());
        self.arity = args.len();

        for (idx, arg) in args.iter().enumerate() {
            if let &Term::Var(_, ref var) = arg.as_ref() {
                let r = self.get(var.clone());

                if !r.is_perm() && r.reg_num() == 0 {
                    self.in_use.insert(idx + 1);
                    self.contents.insert(idx + 1, var.clone());
                    self.record_register(var.clone(), temp_v!(idx + 1));
                }
            }
        }
    }

    fn reset_arg(&mut self, arity: usize) {
        self.arity   = 0;
        self.arg_c   = 1;
        self.temp_lb = arity + 1;
    }
}
<|endoftext|>


<commit_before><commit_msg>genet-kernel: allow integer literal separators<commit_after><|endoftext|>


<commit_before><commit_msg>start new<commit_after>enum MathExp {
    Value(i32),
    Add(Box<MathExp>, Box<MathExp>),
    Minus(Box<MathExp>, Box<MathExp>),
    Multiply(Box<MathExp>, Box<MathExp>),
    Divide(Box<MathExp>, Box<MathExp>),
}

impl MathExp {
    fn evaluate(&mut self) -> i32 {
        match *self {
            MathExp::Value(a) => return a,
            MathExp::Add(a, b) => Box::into_raw(a).evaluate() + Box::into_raw(b).evaluate(),
            MathExp::Minus(a, b) => Box::into_raw(a).evaluate() - Box::into_raw(b).evaluate(),
            MathExp::Multiply(a, b) => Box::into_raw(a).evaluate() * Box::into_raw(b).evaluate(),
            MathExp::Divide(a, b) => Box::into_raw(a).evaluate() / Box::into_raw(b).evaluate(),
        }
    }
}

fn main() {}
<|endoftext|>


<commit_before><commit_msg>Start Porting Decompressor<commit_after>
use std::io;
use std::io::{BufWriter, ErrorKind, Write, Seek, SeekFrom, Result, Error};
use std::result;
use self::byteorder::{ByteOrder, WriteBytesExt, LittleEndian};

// decompressed_len returns the length of the decoded block.
pub fn decompressed_len(src: &[u8]) -> Result<usize> {
	src.read_u64::<LittleEndian>()
}

// Decompress reads the decoded form of src into dst and returns the length
// read.
// Returns an error if dst was not large enough to hold the entire decoded
// block.
fn decompress(dst: &[u8], src: &[u8]) -> io::Result<usize> {
	// TODO: Handle Error
	let dLen = decompressed_len(src).unwrap();
	// TODO FIX!!
	// For now, always assume 8 bytes used for src header length
	let s: usize = 8;

	if dst.len() < dLen {
        return Err(Error::new(ErrorKind::InvalidInput, "snappy: destination buffer is too short"));
    }

    let (d, offset, length): (isize, isize, isize);

    while s < src.len() {
    	match src[s] & 0x03 {
    		TAG_LITERAL => {
    			let mut x = src[s] >> 2;

    			match x {
	    			0..59 => s += 1,
    				60 => {
    					s += 2;
    					if s > src.len() {
    						return Err(ErrorKind::InvalidData)
    					};
    					x = src[s-1] as usize;
    				},
    				61 => {
    					s += 3;
    					if s > src.len() {
    						return Err(ErrorKind::InvalidData)
    					};
    					x = (src[s-2] as usize) | ((src[s-1]<<8) as usize);
    				},
    				62 => {
    					s += 4;
    					if s > src.len() {
    						return Err(ErrorKind::InvalidData)
    					};
    					x = (src[s-3] as usize) | ((src[s-2]<<8) as usize) | ((src[s-1]<<16) as usize);
    				},
    				63 => {
    					s += 5;
    					if s > src.len() {
    						return Err(ErrorKind::InvalidData)
    					};
    					x = (src[s-4] as usize) | ((src[s-3]<<8) as usize) | ((src[s-2]<<16) as usize) | ((src[s-1]<<24) as usize);
    				},
    				_
    			}
    			length = (x+1) as isize;

    			if length <= 0 {
			        return Err(Error::new(ErrorKind::InvalidInput, "snappy: unsupported literal length"));
    			}
    			if length > dst.len() - d || length > src.len() - s {
    				return Err(ErrorKind::InvalidData)
    			}

    			// Copy src[s: s+length] to dst[d:0]
    			for (id, is) in dst.split_at_mut(d).1.iter_mut().zip(src.split_at(s).1.split_at(s+length).0.iter()) {
			        *id = *is;
			    }
			    d += length;
			    s += length;
			    continue;
    		}
    	}
    }
}

<|endoftext|>


<commit_before><commit_msg>Add check-pass test for `#[unwind(aborts)]` on a `const fn`<commit_after>// check-pass

#![feature(unwind_attributes, const_panic)]

// `#[unwind(aborts)]` is okay for a `const fn`. We don't unwind in const-eval anyways.
#[unwind(aborts)]
const fn foo() {
    panic!()
}

const fn bar() {
    foo();
}

fn main() {
    bar();
}
<|endoftext|>


<commit_before><commit_msg>Add basic setter test<commit_after>#[macro_use] extern crate custom_derive;
#[macro_use] extern crate derive_builder;

custom_derive!{
    #[derive(Debug, PartialEq, Default, Builder)]
    struct Lorem {
        ipsum: String,
        dolor: String,
        sit: i32,
        amet: bool,
    }
}

impl Lorem {
    pub fn new<T: Into<String>>(value: T) -> Self {
        Lorem {
            ipsum: value.into(),
            ..Default::default()
        }
    }
}

#[test]
fn contructor_sanity_check() {
    let x = Lorem::new("lorem");

    assert_eq!(x, Lorem { ipsum: "lorem".into(), dolor: "".into(), sit: 0, amet: false, });
}

#[test]
fn setters() {
    let x = Lorem::new("lorem")
        .dolor("dolor")
        .sit(42)
        .amet(true);

    assert_eq!(x, Lorem { ipsum: "lorem".into(), dolor: "dolor".into(), sit: 42, amet: true, });
}
<|endoftext|>


<commit_before><commit_msg>start new<commit_after>fn main() {
    let test = vec![
        30, 63, 83, 40, 15, 45, 46, 15, 56, 39, 82, 97, 59, 88, 3, 1, 40, 95, 83, 32, 38, 70, 4,
        87, 54, 48, 19, 8, 52, 49, 64, 72, 46, 72, 59, 36, 21, 68, 81, 34, 23, 6, 70, 80, 80, 12,
        32, 84, 17, 19, 28, 58, 68, 19, 65, 46, 43, 22, 12, 95, 89, 15, 39, 88, 64, 95, 99, 25, 2,
        7, 86, 36, 73, 90, 30, 31, 0, 62, 73, 35, 4, 26, 0, 93, 91, 77, 34, 92, 31, 56, 34, 61, 23,
        47, 78, 5, 5, 26, 36, 71, 50, 5, 59, 22, 21, 0, 72, 72, 72, 69, 5, 11, 95, 5, 0, 14, 34,
        91, 4, 27, 46, 21, 94, 96, 48, 58, 79, 21, 65, 35, 17, 16, 57, 91, 36, 50, 16, 82, 92, 1,
        29, 52, 74, 90, 48, 79, 81, 53, 46, 82, 36, 43, 64, 24, 55, 48, 27, 21, 69, 93, 49, 70, 58,
        8, 50, 97, 30, 68, 1, 34, 15, 38, 52, 27, 50, 10, 22, 67, 25, 37, 84, 91, 13, 15, 0, 5, 31,
        18, 5, 31, 49, 93, 95, 3, 86, 11, 37, 68, 43, 74,
    ];
}
<|endoftext|>


<commit_before>//! Generic WebSocket protocol implementation

mod frame;
mod message;

pub use self::message::Message;

use std::collections::VecDeque;
use std::io::{Read, Write};
use std::mem::replace;

use error::{Error, Result};
use self::message::{IncompleteMessage, IncompleteMessageType};
use self::frame::{Frame, FrameSocket};
use self::frame::coding::{OpCode, Data as OpData, Control as OpCtl, CloseCode};
use util::NonBlockingResult;

/// Indicates a Client or Server role of the websocket
#[derive(Debug, Clone, Copy)]
pub enum Role {
    /// This socket is a server
    Server,
    /// This socket is a client
    Client,
}

/// WebSocket input-output stream
pub struct WebSocket<Stream> {
    /// Server or client?
    role: Role,
    /// The underlying socket.
    socket: FrameSocket<Stream>,
    /// The state of processing, either "active" or "closing".
    state: WebSocketState,
    /// Receive: an incomplete message being processed.
    incomplete: Option<IncompleteMessage>,
    /// Send: a data send queue.
    send_queue: VecDeque<Frame>,
    /// Send: an OOB pong message.
    pong: Option<Frame>,
}

impl<Stream> WebSocket<Stream> {
    /// Convert a raw socket into a WebSocket without performing a handshake.
    pub fn from_raw_socket(stream: Stream, role: Role) -> Self {
        WebSocket::from_frame_socket(FrameSocket::new(stream), role)
    }

    /// Convert a raw socket into a WebSocket without performing a handshake.
    pub fn from_partially_read(stream: Stream, part: Vec<u8>, role: Role) -> Self {
        WebSocket::from_frame_socket(FrameSocket::from_partially_read(stream, part), role)
    }

    /// Returns a shared reference to the inner stream.
    pub fn get_ref(&self) -> &Stream {
        self.socket.get_ref()
    }
    /// Returns a mutable reference to the inner stream.
    pub fn get_mut(&mut self) -> &mut Stream {
        self.socket.get_mut()
    }

    /// Convert a frame socket into a WebSocket.
    fn from_frame_socket(socket: FrameSocket<Stream>, role: Role) -> Self {
        WebSocket {
            role: role,
            socket: socket,
            state: WebSocketState::Active,
            incomplete: None,
            send_queue: VecDeque::new(),
            pong: None,
        }
    }
}

impl<Stream: Read + Write> WebSocket<Stream> {
    /// Read a message from stream, if possible.
    ///
    /// This function sends pong and close responses automatically.
    /// However, it never blocks on write.
    pub fn read_message(&mut self) -> Result<Message> {
        loop {
            // Since we may get ping or close, we need to reply to the messages even during read.
            // Thus we call write_pending() but ignore its blocking.
            self.write_pending().no_block()?;
            // If we get here, either write blocks or we have nothing to write.
            // Thus if read blocks, just let it return WouldBlock.
            if let Some(message) = self.read_message_frame()? {
                trace!("Received message {}", message);
                return Ok(message)
            }
        }
    }

    /// Send a message to stream, if possible.
    ///
    /// This function guarantees that the frame is queued regardless of any errors.
    /// There is no need to resend the frame. In order to handle WouldBlock or Incomplete,
    /// call write_pending() afterwards.
    pub fn write_message(&mut self, message: Message) -> Result<()> {
        let frame = {
            let opcode = match message {
                Message::Text(_) => OpData::Text,
                Message::Binary(_) => OpData::Binary,
            };
            Frame::message(message.into_data(), OpCode::Data(opcode), true)
        };
        self.send_queue.push_back(frame);
        self.write_pending()
    }

    /// Close the connection.
    ///
    /// This function guarantees that the close frame will be queued.
    /// There is no need to call it again, just like write_message().
    pub fn close(&mut self) -> Result<()> {
        match self.state {
            WebSocketState::Active => {
                self.state = WebSocketState::ClosedByUs;
                let frame = Frame::close(None);
                self.send_queue.push_back(frame);
            }
            _ => {
                // already closed, nothing to do
            }
        }
        self.write_pending()
    }

    /// Flush the pending send queue.
    pub fn write_pending(&mut self) -> Result<()> {
        // First, make sure we have no pending frame sending.
        self.socket.write_pending()?;

        // Upon receipt of a Ping frame, an endpoint MUST send a Pong frame in
        // response, unless it already received a Close frame. It SHOULD
        // respond with Pong frame as soon as is practical. (RFC 6455)
        if let Some(pong) = replace(&mut self.pong, None) {
            self.send_one_frame(pong)?;
        }
        // If we have any unsent frames, send them.
        while let Some(data) = self.send_queue.pop_front() {
            self.send_one_frame(data)?;
        }

        // If we're closing and there is nothing to send anymore, we should close the connection.
        match self.state {
            WebSocketState::ClosedByPeer if self.send_queue.is_empty() => {
                // The underlying TCP connection, in most normal cases, SHOULD be closed
                // first by the server, so that it holds the TIME_WAIT state and not the
                // client (as this would prevent it from re-opening the connection for 2
                // maximum segment lifetimes (2MSL), while there is no corresponding
                // server impact as a TIME_WAIT connection is immediately reopened upon
                // a new SYN with a higher seq number). (RFC 6455)
                match self.role {
                    Role::Client => Ok(()),
                    Role::Server => Err(Error::ConnectionClosed),
                }
            }
            _ => Ok(()),
        }
    }

    /// Try to decode one message frame. May return None.
    fn read_message_frame(&mut self) -> Result<Option<Message>> {
        if let Some(mut frame) = self.socket.read_frame()? {

            // MUST be 0 unless an extension is negotiated that defines meanings
            // for non-zero values.  If a nonzero value is received and none of
            // the negotiated extensions defines the meaning of such a nonzero
            // value, the receiving endpoint MUST _Fail the WebSocket
            // Connection_.
            if frame.has_rsv1() || frame.has_rsv2() || frame.has_rsv3() {
                return Err(Error::Protocol("Reserved bits are non-zero".into()))
            }

            match self.role {
                Role::Server => {
                    if frame.is_masked() {
                        // A server MUST remove masking for data frames received from a client
                        // as described in Section 5.3. (RFC 6455)
                        frame.remove_mask()
                    } else {
                        // The server MUST close the connection upon receiving a
                        // frame that is not masked. (RFC 6455)
                        return Err(Error::Protocol("Received an unmasked frame from client".into()))
                    }
                }
                Role::Client => {
                    if frame.is_masked() {
                        // A client MUST close a connection if it detects a masked frame. (RFC 6455)
                        return Err(Error::Protocol("Received a masked frame from server".into()))
                    }
                }
            }

            match frame.opcode() {

                OpCode::Control(ctl) => {
                    (match ctl {
                        // All control frames MUST have a payload length of 125 bytes or less
                        // and MUST NOT be fragmented. (RFC 6455)
                        _ if !frame.is_final() => {
                            Err(Error::Protocol("Fragmented control frame".into()))
                        }
                        _ if frame.payload().len() > 125 => {
                            Err(Error::Protocol("Control frame too big".into()))
                        }
                        OpCtl::Close => {
                            self.do_close(frame.into_close()?)
                        }
                        OpCtl::Reserved(i) => {
                            Err(Error::Protocol(format!("Unknown control frame type {}", i).into()))
                        }
                        OpCtl::Ping | OpCtl::Pong if !self.state.is_active() => {
                            // No ping processing while closing.
                            Ok(())
                        }
                        OpCtl::Ping => {
                            self.do_ping(frame.into_data())
                        }
                        OpCtl::Pong => {
                            self.do_pong(frame.into_data())
                        }
                    }).map(|_| None)
                }

                OpCode::Data(_) if !self.state.is_active() => {
                    // No data processing while closing.
                    Ok(None)
                }

                OpCode::Data(data) => {
                    let fin = frame.is_final();
                    match data {
                        OpData::Continue => {
                            if let Some(ref mut msg) = self.incomplete {
                                // TODO if msg too big
                                msg.extend(frame.into_data())?;
                            } else {
                                return Err(Error::Protocol("Continue frame but nothing to continue".into()))
                            }
                            if fin {
                                Ok(Some(replace(&mut self.incomplete, None).unwrap().complete()?))
                            } else {
                                Ok(None)
                            }
                        }
                        c if self.incomplete.is_some() => {
                            Err(Error::Protocol(
                                format!("Received {} while waiting for more fragments", c).into()
                            ))
                        }
                        OpData::Text | OpData::Binary => {
                            let msg = {
                                let message_type = match data {
                                    OpData::Text => IncompleteMessageType::Text,
                                    OpData::Binary => IncompleteMessageType::Binary,
                                    _ => panic!("Bug: message is not text nor binary"),
                                };
                                let mut m = IncompleteMessage::new(message_type);
                                m.extend(frame.into_data())?;
                                m
                            };
                            if fin {
                                Ok(Some(msg.complete()?))
                            } else {
                                self.incomplete = Some(msg);
                                Ok(None)
                            }
                        }
                        OpData::Reserved(i) => {
                            Err(Error::Protocol(format!("Unknown data frame type {}", i).into()))
                        }
                    }
                }

            } // match opcode

        } else {
            Err(Error::Protocol("Connection reset without closing handshake".into()))
        }
    }

    /// Received a close frame.
    fn do_close(&mut self, close: Option<(CloseCode, String)>) -> Result<()> {
        match self.state {
            WebSocketState::Active => {
                self.state = WebSocketState::ClosedByPeer;
                let reply = if let Some((code, _)) = close {
                    if code.is_allowed() {
                        Frame::close(Some((CloseCode::Normal, "")))
                    } else {
                        Frame::close(Some((CloseCode::Protocol, "Protocol violation")))
                    }
                } else {
                    Frame::close(None)
                };
                self.send_queue.push_back(reply);
                Ok(())
            }
            WebSocketState::ClosedByPeer => {
                // It is already closed, just ignore.
                Ok(())
            }
            WebSocketState::ClosedByUs => {
                // We received a reply.
                match self.role {
                    Role::Client => {
                        // Client waits for the server to close the connection.
                        Ok(())
                    }
                    Role::Server => {
                        // Server closes the connection.
                        Err(Error::ConnectionClosed)
                    }
                }
            }
        }
    }

    /// Received a ping frame.
    fn do_ping(&mut self, ping: Vec<u8>) -> Result<()> {
        // If an endpoint receives a Ping frame and has not yet sent Pong
        // frame(s) in response to previous Ping frame(s), the endpoint MAY
        // elect to send a Pong frame for only the most recently processed Ping
        // frame. (RFC 6455)
        // We do exactly that, keeping a "queue" from one and only Pong frame.
        self.pong = Some(Frame::pong(ping));
        Ok(())
    }

    /// Received a pong frame.
    fn do_pong(&mut self, _: Vec<u8>) -> Result<()> {
        // A Pong frame MAY be sent unsolicited.  This serves as a
        // unidirectional heartbeat.  A response to an unsolicited Pong frame is
        // not expected. (RFC 6455)
        // Due to this, we just don't check pongs right now.
        // TODO: check if there was a reply to our ping at all...
        Ok(())
    }

    /// Send a single pending frame.
    fn send_one_frame(&mut self, mut frame: Frame) -> Result<()> {
        match self.role {
            Role::Server => {
            }
            Role::Client => {
                // 5.  If the data is being sent by the client, the frame(s) MUST be
                // masked as defined in Section 5.3. (RFC 6455)
                frame.set_mask();
            }
        }
        self.socket.write_frame(frame)
    }

}

/// The current connection state.
enum WebSocketState {
    Active,
    ClosedByUs,
    ClosedByPeer,
}

impl WebSocketState {
    /// Tell if we're allowed to process normal messages.
    fn is_active(&self) -> bool {
        match *self {
            WebSocketState::Active => true,
            _ => false,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::{WebSocket, Role, Message};

    use std::io;
    use std::io::Cursor;

    struct WriteMoc<Stream>(Stream);

    impl<Stream> io::Write for WriteMoc<Stream> {
        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
            Ok(buf.len())
        }
        fn flush(&mut self) -> io::Result<()> {
            Ok(())
        }
    }

    impl<Stream: io::Read> io::Read for WriteMoc<Stream> {
        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
            self.0.read(buf)
        }
    }

    #[test]
    fn receive_messages() {
        let incoming = Cursor::new(vec![
            0x01, 0x07,
            0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20,
            0x80, 0x06,
            0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21,
            0x82, 0x03,
            0x01, 0x02, 0x03,
        ]);
        let mut socket = WebSocket::from_raw_socket(WriteMoc(incoming), Role::Client);
        assert_eq!(socket.read_message().unwrap(), Message::Text("Hello, World!".into()));
        assert_eq!(socket.read_message().unwrap(), Message::Binary(vec![0x01, 0x02, 0x03]));
    }

}
<commit_msg>Add possibility to send pings<commit_after>//! Generic WebSocket protocol implementation

mod frame;
mod message;

pub use self::message::Message;

use std::collections::VecDeque;
use std::io::{Read, Write};
use std::mem::replace;

use error::{Error, Result};
use self::message::{IncompleteMessage, IncompleteMessageType};
use self::frame::{Frame, FrameSocket};
use self::frame::coding::{OpCode, Data as OpData, Control as OpCtl, CloseCode};
use util::NonBlockingResult;

/// Indicates a Client or Server role of the websocket
#[derive(Debug, Clone, Copy)]
pub enum Role {
    /// This socket is a server
    Server,
    /// This socket is a client
    Client,
}

/// WebSocket input-output stream
pub struct WebSocket<Stream> {
    /// Server or client?
    role: Role,
    /// The underlying socket.
    socket: FrameSocket<Stream>,
    /// The state of processing, either "active" or "closing".
    state: WebSocketState,
    /// Receive: an incomplete message being processed.
    incomplete: Option<IncompleteMessage>,
    /// Send: a data send queue.
    send_queue: VecDeque<Frame>,
    /// Send: an OOB pong message.
    pong: Option<Frame>,
}

impl<Stream> WebSocket<Stream> {
    /// Convert a raw socket into a WebSocket without performing a handshake.
    pub fn from_raw_socket(stream: Stream, role: Role) -> Self {
        WebSocket::from_frame_socket(FrameSocket::new(stream), role)
    }

    /// Convert a raw socket into a WebSocket without performing a handshake.
    pub fn from_partially_read(stream: Stream, part: Vec<u8>, role: Role) -> Self {
        WebSocket::from_frame_socket(FrameSocket::from_partially_read(stream, part), role)
    }

    /// Returns a shared reference to the inner stream.
    pub fn get_ref(&self) -> &Stream {
        self.socket.get_ref()
    }
    /// Returns a mutable reference to the inner stream.
    pub fn get_mut(&mut self) -> &mut Stream {
        self.socket.get_mut()
    }

    /// Convert a frame socket into a WebSocket.
    fn from_frame_socket(socket: FrameSocket<Stream>, role: Role) -> Self {
        WebSocket {
            role: role,
            socket: socket,
            state: WebSocketState::Active,
            incomplete: None,
            send_queue: VecDeque::new(),
            pong: None,
        }
    }
}

impl<Stream: Read + Write> WebSocket<Stream> {
    /// Read a message from stream, if possible.
    ///
    /// This function sends pong and close responses automatically.
    /// However, it never blocks on write.
    pub fn read_message(&mut self) -> Result<Message> {
        loop {
            // Since we may get ping or close, we need to reply to the messages even during read.
            // Thus we call write_pending() but ignore its blocking.
            self.write_pending().no_block()?;
            // If we get here, either write blocks or we have nothing to write.
            // Thus if read blocks, just let it return WouldBlock.
            if let Some(message) = self.read_message_frame()? {
                trace!("Received message {}", message);
                return Ok(message)
            }
        }
    }

    /// Send a message to stream, if possible.
    ///
    /// This function guarantees that the frame is queued regardless of any errors.
    /// There is no need to resend the frame. In order to handle WouldBlock or Incomplete,
    /// call write_pending() afterwards.
    pub fn write_message(&mut self, message: Message) -> Result<()> {
        let frame = {
            let opcode = match message {
                Message::Text(_) => OpData::Text,
                Message::Binary(_) => OpData::Binary,
            };
            Frame::message(message.into_data(), OpCode::Data(opcode), true)
        };
        self.send_queue.push_back(frame);
        self.write_pending()
    }

    /// Send ping.
    pub fn send_ping(&mut self, payload: Vec<u8>) -> Result<()> {
        self.send_queue.push_back(Frame::ping(payload));
        self.write_pending()
    }

    /// Close the connection.
    ///
    /// This function guarantees that the close frame will be queued.
    /// There is no need to call it again, just like write_message().
    pub fn close(&mut self) -> Result<()> {
        match self.state {
            WebSocketState::Active => {
                self.state = WebSocketState::ClosedByUs;
                let frame = Frame::close(None);
                self.send_queue.push_back(frame);
            }
            _ => {
                // already closed, nothing to do
            }
        }
        self.write_pending()
    }

    /// Flush the pending send queue.
    pub fn write_pending(&mut self) -> Result<()> {
        // First, make sure we have no pending frame sending.
        self.socket.write_pending()?;

        // Upon receipt of a Ping frame, an endpoint MUST send a Pong frame in
        // response, unless it already received a Close frame. It SHOULD
        // respond with Pong frame as soon as is practical. (RFC 6455)
        if let Some(pong) = replace(&mut self.pong, None) {
            self.send_one_frame(pong)?;
        }
        // If we have any unsent frames, send them.
        while let Some(data) = self.send_queue.pop_front() {
            self.send_one_frame(data)?;
        }

        // If we're closing and there is nothing to send anymore, we should close the connection.
        match self.state {
            WebSocketState::ClosedByPeer if self.send_queue.is_empty() => {
                // The underlying TCP connection, in most normal cases, SHOULD be closed
                // first by the server, so that it holds the TIME_WAIT state and not the
                // client (as this would prevent it from re-opening the connection for 2
                // maximum segment lifetimes (2MSL), while there is no corresponding
                // server impact as a TIME_WAIT connection is immediately reopened upon
                // a new SYN with a higher seq number). (RFC 6455)
                match self.role {
                    Role::Client => Ok(()),
                    Role::Server => Err(Error::ConnectionClosed),
                }
            }
            _ => Ok(()),
        }
    }

    /// Try to decode one message frame. May return None.
    fn read_message_frame(&mut self) -> Result<Option<Message>> {
        if let Some(mut frame) = self.socket.read_frame()? {

            // MUST be 0 unless an extension is negotiated that defines meanings
            // for non-zero values.  If a nonzero value is received and none of
            // the negotiated extensions defines the meaning of such a nonzero
            // value, the receiving endpoint MUST _Fail the WebSocket
            // Connection_.
            if frame.has_rsv1() || frame.has_rsv2() || frame.has_rsv3() {
                return Err(Error::Protocol("Reserved bits are non-zero".into()))
            }

            match self.role {
                Role::Server => {
                    if frame.is_masked() {
                        // A server MUST remove masking for data frames received from a client
                        // as described in Section 5.3. (RFC 6455)
                        frame.remove_mask()
                    } else {
                        // The server MUST close the connection upon receiving a
                        // frame that is not masked. (RFC 6455)
                        return Err(Error::Protocol("Received an unmasked frame from client".into()))
                    }
                }
                Role::Client => {
                    if frame.is_masked() {
                        // A client MUST close a connection if it detects a masked frame. (RFC 6455)
                        return Err(Error::Protocol("Received a masked frame from server".into()))
                    }
                }
            }

            match frame.opcode() {

                OpCode::Control(ctl) => {
                    (match ctl {
                        // All control frames MUST have a payload length of 125 bytes or less
                        // and MUST NOT be fragmented. (RFC 6455)
                        _ if !frame.is_final() => {
                            Err(Error::Protocol("Fragmented control frame".into()))
                        }
                        _ if frame.payload().len() > 125 => {
                            Err(Error::Protocol("Control frame too big".into()))
                        }
                        OpCtl::Close => {
                            self.do_close(frame.into_close()?)
                        }
                        OpCtl::Reserved(i) => {
                            Err(Error::Protocol(format!("Unknown control frame type {}", i).into()))
                        }
                        OpCtl::Ping | OpCtl::Pong if !self.state.is_active() => {
                            // No ping processing while closing.
                            Ok(())
                        }
                        OpCtl::Ping => {
                            self.do_ping(frame.into_data())
                        }
                        OpCtl::Pong => {
                            self.do_pong(frame.into_data())
                        }
                    }).map(|_| None)
                }

                OpCode::Data(_) if !self.state.is_active() => {
                    // No data processing while closing.
                    Ok(None)
                }

                OpCode::Data(data) => {
                    let fin = frame.is_final();
                    match data {
                        OpData::Continue => {
                            if let Some(ref mut msg) = self.incomplete {
                                // TODO if msg too big
                                msg.extend(frame.into_data())?;
                            } else {
                                return Err(Error::Protocol("Continue frame but nothing to continue".into()))
                            }
                            if fin {
                                Ok(Some(replace(&mut self.incomplete, None).unwrap().complete()?))
                            } else {
                                Ok(None)
                            }
                        }
                        c if self.incomplete.is_some() => {
                            Err(Error::Protocol(
                                format!("Received {} while waiting for more fragments", c).into()
                            ))
                        }
                        OpData::Text | OpData::Binary => {
                            let msg = {
                                let message_type = match data {
                                    OpData::Text => IncompleteMessageType::Text,
                                    OpData::Binary => IncompleteMessageType::Binary,
                                    _ => panic!("Bug: message is not text nor binary"),
                                };
                                let mut m = IncompleteMessage::new(message_type);
                                m.extend(frame.into_data())?;
                                m
                            };
                            if fin {
                                Ok(Some(msg.complete()?))
                            } else {
                                self.incomplete = Some(msg);
                                Ok(None)
                            }
                        }
                        OpData::Reserved(i) => {
                            Err(Error::Protocol(format!("Unknown data frame type {}", i).into()))
                        }
                    }
                }

            } // match opcode

        } else {
            Err(Error::Protocol("Connection reset without closing handshake".into()))
        }
    }

    /// Received a close frame.
    fn do_close(&mut self, close: Option<(CloseCode, String)>) -> Result<()> {
        match self.state {
            WebSocketState::Active => {
                self.state = WebSocketState::ClosedByPeer;
                let reply = if let Some((code, _)) = close {
                    if code.is_allowed() {
                        Frame::close(Some((CloseCode::Normal, "")))
                    } else {
                        Frame::close(Some((CloseCode::Protocol, "Protocol violation")))
                    }
                } else {
                    Frame::close(None)
                };
                self.send_queue.push_back(reply);
                Ok(())
            }
            WebSocketState::ClosedByPeer => {
                // It is already closed, just ignore.
                Ok(())
            }
            WebSocketState::ClosedByUs => {
                // We received a reply.
                match self.role {
                    Role::Client => {
                        // Client waits for the server to close the connection.
                        Ok(())
                    }
                    Role::Server => {
                        // Server closes the connection.
                        Err(Error::ConnectionClosed)
                    }
                }
            }
        }
    }

    /// Received a ping frame.
    fn do_ping(&mut self, ping: Vec<u8>) -> Result<()> {
        // If an endpoint receives a Ping frame and has not yet sent Pong
        // frame(s) in response to previous Ping frame(s), the endpoint MAY
        // elect to send a Pong frame for only the most recently processed Ping
        // frame. (RFC 6455)
        // We do exactly that, keeping a "queue" from one and only Pong frame.
        self.pong = Some(Frame::pong(ping));
        Ok(())
    }

    /// Received a pong frame.
    fn do_pong(&mut self, _: Vec<u8>) -> Result<()> {
        // A Pong frame MAY be sent unsolicited.  This serves as a
        // unidirectional heartbeat.  A response to an unsolicited Pong frame is
        // not expected. (RFC 6455)
        // Due to this, we just don't check pongs right now.
        // TODO: check if there was a reply to our ping at all...
        Ok(())
    }

    /// Send a single pending frame.
    fn send_one_frame(&mut self, mut frame: Frame) -> Result<()> {
        match self.role {
            Role::Server => {
            }
            Role::Client => {
                // 5.  If the data is being sent by the client, the frame(s) MUST be
                // masked as defined in Section 5.3. (RFC 6455)
                frame.set_mask();
            }
        }
        self.socket.write_frame(frame)
    }

}

/// The current connection state.
enum WebSocketState {
    Active,
    ClosedByUs,
    ClosedByPeer,
}

impl WebSocketState {
    /// Tell if we're allowed to process normal messages.
    fn is_active(&self) -> bool {
        match *self {
            WebSocketState::Active => true,
            _ => false,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::{WebSocket, Role, Message};

    use std::io;
    use std::io::Cursor;

    struct WriteMoc<Stream>(Stream);

    impl<Stream> io::Write for WriteMoc<Stream> {
        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
            Ok(buf.len())
        }
        fn flush(&mut self) -> io::Result<()> {
            Ok(())
        }
    }

    impl<Stream: io::Read> io::Read for WriteMoc<Stream> {
        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
            self.0.read(buf)
        }
    }

    #[test]
    fn receive_messages() {
        let incoming = Cursor::new(vec![
            0x01, 0x07,
            0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20,
            0x80, 0x06,
            0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21,
            0x82, 0x03,
            0x01, 0x02, 0x03,
        ]);
        let mut socket = WebSocket::from_raw_socket(WriteMoc(incoming), Role::Client);
        assert_eq!(socket.read_message().unwrap(), Message::Text("Hello, World!".into()));
        assert_eq!(socket.read_message().unwrap(), Message::Binary(vec![0x01, 0x02, 0x03]));
    }

}
<|endoftext|>


<commit_before><commit_msg>Have find use iter_elements.<commit_after><|endoftext|>


<commit_before><commit_msg>Added src/lib.rs<commit_after><|endoftext|>


<commit_before><commit_msg>lib.rs for extra file and path handling features<commit_after>use std::path::Path;
use std::process::Command;

pub fn mkdir(path: &String) {
  if Path::new(path).exists(){
     println!("{:?} already exists", path);
  } else {
    Command::new("mkdir")
            .arg(path)
            .spawn()
            .expect("failed to mkdir");
  }
}

pub fn zopen(path: &String, mode: String) {

}
<|endoftext|>


<commit_before><commit_msg>Implement flush_to_disk for macos<commit_after><|endoftext|>


<commit_before><commit_msg>updated to check/remove dirty file<commit_after><|endoftext|>


<commit_before><commit_msg>added CXXFLAGS=-std=c++11 to make<commit_after><|endoftext|>


<commit_before><commit_msg>start integrating websocket for rewarder<commit_after><|endoftext|>


<commit_before><commit_msg>Allow more fine-granular control over IO behaviour in runtime<commit_after><|endoftext|>


<commit_before><commit_msg>More test<commit_after><|endoftext|>


<commit_before><commit_msg>Remove residual extern crates.<commit_after><|endoftext|>


<commit_before><commit_msg>Implement basic ecr for ldsr/stsr<commit_after><|endoftext|>


<commit_before><commit_msg>Add code ror semi-structured-logs<commit_after>/// various log levels
#[derive(Clone, PartialEq, Debug)]
pub enum LogLevel {
    Debug,
    Info,
    Warning,
    Error,
}
/// primary function for emitting logs
pub fn log(level: LogLevel, message: &str) -> String {
    match level {
        LogLevel::Debug => debug(message),
        LogLevel::Info => info(message),
        LogLevel::Warning => warn(message),
        LogLevel::Error => error(message),
    }
}

pub fn debug(message: &str) -> String {
    format!("[DEBUG]: {}", message)
}

pub fn info(message: &str) -> String {
    format!("[INFO]: {}", message)
}
pub fn warn(message: &str) -> String {
    format!("[WARNING]: {}", message)
}
pub fn error(message: &str) -> String {
    format!("[ERROR]: {}", message)
}
<|endoftext|>


<commit_before>use super::errors::*;

static C_PRE: &'static str = "const char data[] = {";
static C_SEPERATOR: &'static str = ",";
static C_POST: &'static str = "};";

static CPP_PRE: &'static str = "const char data[] = {";
static CPP_SEPERATOR: &'static str = ",";
static CPP_POST: &'static str = "};";

static PYTHON_PRE: &'static str = "data = [";
static PYTHON_SEPERATOR: &'static str = ",";
static PYTHON_POST: &'static str = "]";

static RUST_PRE: &'static str = "let data = [";
static RUST_SEPERATOR: &'static str = ",";
static RUST_POST: &'static str = "];";

trait Render {
    fn render(&self, data: &[u8]) -> String;
}

pub enum Language {
    C,
    Cpp,
    Rust,
    Python,
}

struct Template {
    prefix: String,
    separator: String,
    suffix: String,
}

impl Template {
    fn new(lang: Language) -> Template {
        match lang {
            Language::C => {
                Template {
                    prefix: C_PRE.to_string(),
                    separator: C_SEPERATOR.to_string(),
                    suffix: C_POST.to_string(),
                }
            }
            Language::Cpp => {
                Template {
                    prefix: CPP_PRE.to_string(),
                    separator: CPP_SEPERATOR.to_string(),
                    suffix: CPP_POST.to_string(),
                }
            }
            Language::Python => {
                Template {
                    prefix: PYTHON_PRE.to_string(),
                    separator: PYTHON_SEPERATOR.to_string(),
                    suffix: PYTHON_POST.to_string(),
                }
            }
            Language::Rust => {
                Template {
                    prefix: RUST_PRE.to_string(),
                    separator: RUST_SEPERATOR.to_string(),
                    suffix: RUST_POST.to_string(),
                }
            }
        }
    }
}

impl Render for Template {
    fn render(&self, data: &[u8]) -> String {
        let mut output = String::new();
        output = output + &self.prefix;
        for element in data.iter().enumerate() {
            let (index, byte) = element;
            if data.len() - 1 == index {
                output = output + &format!("{}", byte);
            } else {
                output = output + &format!("{}{} ", byte, self.separator);
            }
        }
        output = output + &self.suffix;
        output
    }
}

mod test {
    use super::*;

    #[test]
    fn render_basic_c_template() {
        let data = [0, 1, 2, 3, 4, 5];
        let template = Template::new(Language::C);
        let expected_result = "const char data[] = {0, 1, 2, 3, 4, 5};";
        assert_eq!(template.render(&data), expected_result);
    }

    #[test]
    fn render_basic_cplusplus_template() {
        let data = [0, 1, 2, 3, 4, 5];
        let template = Template::new(Language::Cpp);
        let expected_result = "const char data[] = {0, 1, 2, 3, 4, 5};";
        assert_eq!(template.render(&data), expected_result);
    }

    #[test]
    fn render_basic_python_template() {
        let data = [0, 1, 2, 3, 4, 5];
        let template = Template::new(Language::Python);
        let expected_result = "data = [0, 1, 2, 3, 4, 5]";
        assert_eq!(template.render(&data), expected_result);
    }

    #[test]
    fn render_basic_rust_template() {
        let data = [0, 1, 2, 3, 4, 5];
        let template = Template::new(Language::Rust);
        let expected_result = "let data = [0, 1, 2, 3, 4, 5];";
        assert_eq!(template.render(&data), expected_result);
    }
}
<commit_msg>Add bytes_per_line setting<commit_after>use super::errors::*;

static C_PRE: &'static str = "const char data[] = {";
static C_SEPERATOR: &'static str = ",";
static C_POST: &'static str = "};";

static CPP_PRE: &'static str = "const char data[] = {";
static CPP_SEPERATOR: &'static str = ",";
static CPP_POST: &'static str = "};";

static PYTHON_PRE: &'static str = "data = [";
static PYTHON_SEPERATOR: &'static str = ",";
static PYTHON_POST: &'static str = "]";

static RUST_PRE: &'static str = "let data = [";
static RUST_SEPERATOR: &'static str = ",";
static RUST_POST: &'static str = "];";

trait Render {
    fn render(&self, data: &[u8]) -> String;
}

pub enum Language {
    C,
    Cpp,
    Rust,
    Python,
}

struct Template {
    prefix: String,
    separator: String,
    suffix: String,
    bytes_per_line: usize,
}

impl Template {
    fn new(lang: Language) -> Template {
        match lang {
            Language::C => {
                Template {
                    prefix: C_PRE.to_string(),
                    separator: C_SEPERATOR.to_string(),
                    suffix: C_POST.to_string(),
                    bytes_per_line: 16,
                }
            }
            Language::Cpp => {
                Template {
                    prefix: CPP_PRE.to_string(),
                    separator: CPP_SEPERATOR.to_string(),
                    suffix: CPP_POST.to_string(),
                    bytes_per_line: 16,
                }
            }
            Language::Python => {
                Template {
                    prefix: PYTHON_PRE.to_string(),
                    separator: PYTHON_SEPERATOR.to_string(),
                    suffix: PYTHON_POST.to_string(),
                    bytes_per_line: 16,
                }
            }
            Language::Rust => {
                Template {
                    prefix: RUST_PRE.to_string(),
                    separator: RUST_SEPERATOR.to_string(),
                    suffix: RUST_POST.to_string(),
                    bytes_per_line: 16,
                }
            }
        }
    }
}

impl Render for Template {
    fn render(&self, data: &[u8]) -> String {
        let mut output = String::new();
        output = output + &self.prefix;
        for element in data.iter().enumerate() {
            let (index, byte) = element;
            if data.len() - 1 == index {
                output = output + &format!("{}", byte);
            } else {
                output = output + &format!("{}{} ", byte, self.separator);
                if (index + 1) % self.bytes_per_line == 0 {
                    output = output + &"\n";
                }
            }
        }
        output = output + &self.suffix;
        output
    }
}

mod test {
    use super::*;

    #[test]
    fn render_basic_c_template() {
        let data = [0, 1, 2, 3, 4, 5];
        let template = Template::new(Language::C);
        let expected_result = "const char data[] = {0, 1, 2, 3, 4, 5};";
        assert_eq!(template.render(&data), expected_result);
    }

    #[test]
    fn render_c_template_with_large_data() {
        let data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
                    22, 23, 24, 25, 26];
        let template = Template::new(Language::C);
        let expected_result = "const char data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, \n16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26};";
        assert_eq!(template.render(&data), expected_result);
    }

    #[test]
    fn render_basic_cplusplus_template() {
        let data = [0, 1, 2, 3, 4, 5];
        let template = Template::new(Language::Cpp);
        let expected_result = "const char data[] = {0, 1, 2, 3, 4, 5};";
        assert_eq!(template.render(&data), expected_result);
    }

    #[test]
    fn render_cplusplus_template_with_large_data() {
        let data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
                    22, 23, 24, 25, 26];
        let template = Template::new(Language::Cpp);
        let expected_result = "const char data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, \n16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26};";
        assert_eq!(template.render(&data), expected_result);
    }

    #[test]
    fn render_basic_python_template() {
        let data = [0, 1, 2, 3, 4, 5];
        let template = Template::new(Language::Python);
        let expected_result = "data = [0, 1, 2, 3, 4, 5]";
        assert_eq!(template.render(&data), expected_result);
    }

    #[test]
    fn render_python_template_with_large_data() {
        let data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
                    22, 23, 24, 25, 26];
        let template = Template::new(Language::Python);
        let expected_result = "data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, \n16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]";
        assert_eq!(template.render(&data), expected_result);
    }

    #[test]
    fn render_basic_rust_template() {
        let data = [0, 1, 2, 3, 4, 5];
        let template = Template::new(Language::Rust);
        let expected_result = "let data = [0, 1, 2, 3, 4, 5];";
        assert_eq!(template.render(&data), expected_result);
    }

    #[test]
    fn render_rust_template_with_large_data() {
        let data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
                    22, 23, 24, 25, 26];
        let template = Template::new(Language::Rust);
        let expected_result = "let data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, \n16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26];";
        assert_eq!(template.render(&data), expected_result);
    }
}
<|endoftext|>