<commit_before>/* Copyright 2016 The encode_unicode Developers
 *
 * Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
 * http://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.
 */

//! Boilerplatey error enums

extern crate core;
use self::core::fmt::{self,Display,Formatter};
#[cfg(feature="std")]
use std::error::Error;

macro_rules! description {($err:ty, $desc:expr) => {
    #[cfg(not(feature="std"))]
    impl $err {
        #[allow(missing_docs)]
        pub fn description(&self) -> &'static str {
            ($desc)(self)
        }
    }
    #[cfg(feature="std")]
    impl Error for $err {
        fn description(&self) -> &'static str {
            ($desc)(self)
        }
    }
    impl Display for $err {
        fn fmt(&self,  fmtr: &mut Formatter) -> fmt::Result {
            write!(fmtr, "{}", self.description())
        }
    }
}}

/// Cannot tell whether an `u16` needs an extra unit,
/// because it's a trailing surrogate itself.
#[derive(Clone,Copy, Debug, PartialEq,Eq)]
pub struct InvalidUtf16FirstUnit;
description!{InvalidUtf16FirstUnit, |_| "Is a trailing surrogate" }

macro_rules! simple {(#[$tydoc:meta] $err:ident  {
                          $($(#[$vardoc:meta])* ::$variant:ident => $string:expr),+,
                      } ) => {
    #[$tydoc]
    #[derive(Clone,Copy, Debug, PartialEq,Eq)]
    pub enum $err {
        $($(#[$vardoc])* $variant),*
    }
    description!{$err, |e: &$err| match *e {$($err::$variant=>$string),*} }
}}

simple!{/// Reasons why an `u32` is not a valid UTF codepoint.
    InvalidCodepoint {
        /// It's reserved for UTF-16 surrogate pairs."
        ::Utf16Reserved => "is reserved for UTF-16 surrogate pairs",
        /// It's higher than the highest codepoint (which is 0x10ffff).
        ::TooHigh => "is higher than the highest codepoint",
    }}
use self::InvalidCodepoint::*;
impl InvalidCodepoint {
    /// Get the range of values for which this error would be given.
    pub fn error_range(self) -> (u32,u32) {match self {
        Utf16Reserved => (0xd8_00, 0xdf_ff),
        TooHigh => (0x00_10_ff_ff, 0xff_ff_ff_ff),
    }}
}

simple!{/// Reasons why one or two `u16`s are not valid UTF-16, in sinking precedence.
    InvalidUtf16Tuple {
        /// The first unit is a trailing/low surrogate, which is never valid.
        ///
        /// Note that the value of a low surrogate is actually higher than a high surrogate.
        ::FirstIsTrailingSurrogate => "the first unit is a trailing / low surrogate, which is never valid",
        /// You provided a second unit, but the first one stands on its own.
        ::SuperfluousSecond => "the second unit is superfluous",
        /// The first and only unit requires a second unit.
        ::MissingSecond => "the first unit requires a second unit",
        /// The first unit requires a second unit, but it's not a trailing/low surrogate.
        ///
        /// Note that the value of a low surrogate is actually higher than a high surrogate.
        ::InvalidSecond => "the required second unit is not a trailing / low surrogate",
    }}

simple!{/// Reasons why a slice of `u16`s doesn't start with valid UTF-16.
    InvalidUtf16Slice {
        /// The slice is empty.
        ::EmptySlice => "the slice is empty",
        /// The first unit is a low surrogate.
        ::FirstLowSurrogate => "the first unit is a trailing surrogate",
        /// The first and only unit requires a second unit.
        ::MissingSecond => "the first and only unit requires a second one",
        /// The first unit requires a second one, but it's not a trailing surrogate.
        ::SecondNotLowSurrogate => "the required second unit is not a trailing surrogate",
    }}

/// Cannot create an `Utf8Char` for the first codepoint of a str,
/// because there are none.
#[derive(Clone,Copy, Debug, PartialEq,Eq)]
pub struct EmptyStrError;
description!{EmptyStrError, |_| "Is empty" }

simple!{/// Reasons why `Utf8Char::from_str()` failed.
    FromStrError {
        /// `Utf8Char` cannot store more than a single codepoint.
        ::MultipleCodepoints => "has more than one codepoint",
        /// `Utf8Char` cannot be empty.
        ::Empty => "is empty",
    }}

simple!{/// Reasons why a byte is not the start of a UTF-8 codepoint.
    InvalidUtf8FirstByte {
        /// Sequences cannot be longer than 4 bytes. Is given for values >= 240.
        ::TooLongSeqence => "is greater than 247 (UTF-8 sequences cannot be longer than four bytes)",
        /// This byte belongs to a previous sequence. Is given for values between 128 and 192 (exclusive).
        ::ContinuationByte => "is a continuation of a previous sequence",
    }}
use self::InvalidUtf8FirstByte::*;

macro_rules! complex {
($err:ty
 {$($sub:ty => $to:expr,)*}
 {$($desc:pat => $string:expr),+,}
 => $use_cause:expr =>
 {$($cause:pat => $result:expr),+,} $(#[$causedoc:meta])*
) => {
    $(impl From<$sub> for $err {
          fn from(error: $sub) -> $err {
              $to(error)
          }
      })*
    #[cfg(not(feature="std"))]
    impl $err {
        #[allow(missing_docs)]
        pub fn description(&self) -> &'static str {
            match *self{ $($desc => $string,)* }
        }
        /// A hack to avoid two Display impls
        fn cause(&self) -> Option<&Display> {None}
    }
    #[cfg(feature="std")]
    impl Error for $err {
        fn description(&self) -> &'static str {
            match *self{ $($desc => $string,)* }
        }
        $(#[$causedoc])*
        fn cause(&self) -> Option<&Error> {
            match *self{ $($cause => $result,)* }
        }
    }
    impl Display for $err {
        fn fmt(&self,  fmtr: &mut Formatter) -> fmt::Result {
            match (self.cause(), $use_cause) {
                (Some(d),true) => write!(fmtr, "{}: {}", self.description(), d),
                        _      => write!(fmtr, "{}", self.description()),
            }
        }
    }
}}

/// Reasons why a byte sequence is not valid UTF-8, excluding invalid codepoint.
/// In sinking precedence.
#[derive(Clone,Copy, Debug, PartialEq,Eq)]
pub enum InvalidUtf8 {
    /// Something is wrong with the first byte.
    FirstByte(InvalidUtf8FirstByte),
    /// The byte at index 1...3 should be a continuation byte,
    /// but dosesn't fit the pattern 0b10xx_xxxx.
    NotAContinuationByte(usize),
    /// There are too many leading zeros: it could be a byte shorter.
    ///
    /// [Decoding this could allow someone to input otherwise prohibited
    /// characters and sequences, such as "../"](https://tools.ietf.org/html/rfc3629#section-10).
    OverLong,
}
use self::InvalidUtf8::*;
complex!{InvalidUtf8 {
        InvalidUtf8FirstByte => FirstByte,
    } {
        FirstByte(TooLongSeqence) => "the first byte is greater than 239 (UTF-8 sequences cannot be longer than four bytes)",
        FirstByte(ContinuationByte) => "the first byte is a continuation of a previous sequence",
        OverLong => "the sequence contains too many zeros and could be shorter",
        NotAContinuationByte(_) => "the sequence is too short",
    } => false => {
        FirstByte(ref cause) => Some(cause),
        _ => None,
    }/// Returns `Some` if the error is a `InvalidUtf8FirstByte`.
}

/// Reasons why a byte array is not valid UTF-8, in sinking precedence.
#[derive(Clone,Copy, Debug, PartialEq,Eq)]
pub enum InvalidUtf8Array {
    /// Not a valid UTF-8 sequence.
    Utf8(InvalidUtf8),
    /// Not a valid unicode codepoint.
    Codepoint(InvalidCodepoint),
}
complex!{InvalidUtf8Array {
        InvalidUtf8 => InvalidUtf8Array::Utf8,
        InvalidCodepoint => InvalidUtf8Array::Codepoint,
    } {
        InvalidUtf8Array::Utf8(_) => "the sequence is invalid UTF-8",
        InvalidUtf8Array::Codepoint(_) => "the encoded codepoint is invalid",
    } => true => {
        InvalidUtf8Array::Utf8(ref u) => Some(u),
        InvalidUtf8Array::Codepoint(ref c) => Some(c),
    }/// Always returns `Some`.
}

/// Reasons why a byte slice is not valid UTF-8, in sinking precedence.
#[derive(Clone,Copy, Debug, PartialEq,Eq)]
pub enum InvalidUtf8Slice {
    /// Something is certainly wrong with the first byte.
    Utf8(InvalidUtf8),
    /// The encoded codepoint is invalid:
    Codepoint(InvalidCodepoint),
    /// The slice is too short; n bytes was required.
    TooShort(usize),
}
complex!{InvalidUtf8Slice {
        InvalidUtf8 => InvalidUtf8Slice::Utf8,
        InvalidCodepoint => InvalidUtf8Slice::Codepoint,
    } {
        InvalidUtf8Slice::Utf8(_) => "the sequence is invalid UTF-8",
        InvalidUtf8Slice::Codepoint(_) => "the encoded codepoint is invalid",
        InvalidUtf8Slice::TooShort(0) => "the slice is empty",
        InvalidUtf8Slice::TooShort(_) => "the slice is shorter than the sequence",
    } => true => {
        InvalidUtf8Slice::Utf8(ref u) => Some(u),
        InvalidUtf8Slice::Codepoint(ref c) => Some(c),
        InvalidUtf8Slice::TooShort(_) => None,
    }
}
<commit_msg>Update documentation for EmptyStrError and FromStrError<commit_after>/* Copyright 2016 The encode_unicode Developers
 *
 * Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
 * http://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.
 */

//! Boilerplatey error enums

extern crate core;
use self::core::fmt::{self,Display,Formatter};
#[cfg(feature="std")]
use std::error::Error;

macro_rules! description {($err:ty, $desc:expr) => {
    #[cfg(not(feature="std"))]
    impl $err {
        #[allow(missing_docs)]
        pub fn description(&self) -> &'static str {
            ($desc)(self)
        }
    }
    #[cfg(feature="std")]
    impl Error for $err {
        fn description(&self) -> &'static str {
            ($desc)(self)
        }
    }
    impl Display for $err {
        fn fmt(&self,  fmtr: &mut Formatter) -> fmt::Result {
            write!(fmtr, "{}", self.description())
        }
    }
}}

/// Cannot tell whether an `u16` needs an extra unit,
/// because it's a trailing surrogate itself.
#[derive(Clone,Copy, Debug, PartialEq,Eq)]
pub struct InvalidUtf16FirstUnit;
description!{InvalidUtf16FirstUnit, |_| "Is a trailing surrogate" }

macro_rules! simple {(#[$tydoc:meta] $err:ident  {
                          $($(#[$vardoc:meta])* ::$variant:ident => $string:expr),+,
                      } ) => {
    #[$tydoc]
    #[derive(Clone,Copy, Debug, PartialEq,Eq)]
    pub enum $err {
        $($(#[$vardoc])* $variant),*
    }
    description!{$err, |e: &$err| match *e {$($err::$variant=>$string),*} }
}}

simple!{/// Reasons why an `u32` is not a valid UTF codepoint.
    InvalidCodepoint {
        /// It's reserved for UTF-16 surrogate pairs."
        ::Utf16Reserved => "is reserved for UTF-16 surrogate pairs",
        /// It's higher than the highest codepoint (which is 0x10ffff).
        ::TooHigh => "is higher than the highest codepoint",
    }}
use self::InvalidCodepoint::*;
impl InvalidCodepoint {
    /// Get the range of values for which this error would be given.
    pub fn error_range(self) -> (u32,u32) {match self {
        Utf16Reserved => (0xd8_00, 0xdf_ff),
        TooHigh => (0x00_10_ff_ff, 0xff_ff_ff_ff),
    }}
}

simple!{/// Reasons why one or two `u16`s are not valid UTF-16, in sinking precedence.
    InvalidUtf16Tuple {
        /// The first unit is a trailing/low surrogate, which is never valid.
        ///
        /// Note that the value of a low surrogate is actually higher than a high surrogate.
        ::FirstIsTrailingSurrogate => "the first unit is a trailing / low surrogate, which is never valid",
        /// You provided a second unit, but the first one stands on its own.
        ::SuperfluousSecond => "the second unit is superfluous",
        /// The first and only unit requires a second unit.
        ::MissingSecond => "the first unit requires a second unit",
        /// The first unit requires a second unit, but it's not a trailing/low surrogate.
        ///
        /// Note that the value of a low surrogate is actually higher than a high surrogate.
        ::InvalidSecond => "the required second unit is not a trailing / low surrogate",
    }}

simple!{/// Reasons why a slice of `u16`s doesn't start with valid UTF-16.
    InvalidUtf16Slice {
        /// The slice is empty.
        ::EmptySlice => "the slice is empty",
        /// The first unit is a low surrogate.
        ::FirstLowSurrogate => "the first unit is a trailing surrogate",
        /// The first and only unit requires a second unit.
        ::MissingSecond => "the first and only unit requires a second one",
        /// The first unit requires a second one, but it's not a trailing surrogate.
        ::SecondNotLowSurrogate => "the required second unit is not a trailing surrogate",
    }}

/// Cannot create an `Utf8Char` or `Utf16Char` from the first codepoint of a str,
/// because there are none.
#[derive(Clone,Copy, Debug, PartialEq,Eq)]
pub struct EmptyStrError;
description!{EmptyStrError, |_| "is empty" }

simple!{/// Reasons why `Utf8Char::from_str()` or `Utf16Char::from_str()` failed.
    FromStrError {
        /// `Utf8Char` or `Utf16Char` cannot store more than a single codepoint.
        ::MultipleCodepoints => "has more than one codepoint",
        /// `Utf8Char` or `Utf16Char` cannot be empty.
        ::Empty => "is empty",
    }}

simple!{/// Reasons why a byte is not the start of a UTF-8 codepoint.
    InvalidUtf8FirstByte {
        /// Sequences cannot be longer than 4 bytes. Is given for values >= 240.
        ::TooLongSeqence => "is greater than 247 (UTF-8 sequences cannot be longer than four bytes)",
        /// This byte belongs to a previous sequence. Is given for values between 128 and 192 (exclusive).
        ::ContinuationByte => "is a continuation of a previous sequence",
    }}
use self::InvalidUtf8FirstByte::*;

macro_rules! complex {
($err:ty
 {$($sub:ty => $to:expr,)*}
 {$($desc:pat => $string:expr),+,}
 => $use_cause:expr =>
 {$($cause:pat => $result:expr),+,} $(#[$causedoc:meta])*
) => {
    $(impl From<$sub> for $err {
          fn from(error: $sub) -> $err {
              $to(error)
          }
      })*
    #[cfg(not(feature="std"))]
    impl $err {
        #[allow(missing_docs)]
        pub fn description(&self) -> &'static str {
            match *self{ $($desc => $string,)* }
        }
        /// A hack to avoid two Display impls
        fn cause(&self) -> Option<&Display> {None}
    }
    #[cfg(feature="std")]
    impl Error for $err {
        fn description(&self) -> &'static str {
            match *self{ $($desc => $string,)* }
        }
        $(#[$causedoc])*
        fn cause(&self) -> Option<&Error> {
            match *self{ $($cause => $result,)* }
        }
    }
    impl Display for $err {
        fn fmt(&self,  fmtr: &mut Formatter) -> fmt::Result {
            match (self.cause(), $use_cause) {
                (Some(d),true) => write!(fmtr, "{}: {}", self.description(), d),
                        _      => write!(fmtr, "{}", self.description()),
            }
        }
    }
}}

/// Reasons why a byte sequence is not valid UTF-8, excluding invalid codepoint.
/// In sinking precedence.
#[derive(Clone,Copy, Debug, PartialEq,Eq)]
pub enum InvalidUtf8 {
    /// Something is wrong with the first byte.
    FirstByte(InvalidUtf8FirstByte),
    /// The byte at index 1...3 should be a continuation byte,
    /// but dosesn't fit the pattern 0b10xx_xxxx.
    NotAContinuationByte(usize),
    /// There are too many leading zeros: it could be a byte shorter.
    ///
    /// [Decoding this could allow someone to input otherwise prohibited
    /// characters and sequences, such as "../"](https://tools.ietf.org/html/rfc3629#section-10).
    OverLong,
}
use self::InvalidUtf8::*;
complex!{InvalidUtf8 {
        InvalidUtf8FirstByte => FirstByte,
    } {
        FirstByte(TooLongSeqence) => "the first byte is greater than 239 (UTF-8 sequences cannot be longer than four bytes)",
        FirstByte(ContinuationByte) => "the first byte is a continuation of a previous sequence",
        OverLong => "the sequence contains too many zeros and could be shorter",
        NotAContinuationByte(_) => "the sequence is too short",
    } => false => {
        FirstByte(ref cause) => Some(cause),
        _ => None,
    }/// Returns `Some` if the error is a `InvalidUtf8FirstByte`.
}

/// Reasons why a byte array is not valid UTF-8, in sinking precedence.
#[derive(Clone,Copy, Debug, PartialEq,Eq)]
pub enum InvalidUtf8Array {
    /// Not a valid UTF-8 sequence.
    Utf8(InvalidUtf8),
    /// Not a valid unicode codepoint.
    Codepoint(InvalidCodepoint),
}
complex!{InvalidUtf8Array {
        InvalidUtf8 => InvalidUtf8Array::Utf8,
        InvalidCodepoint => InvalidUtf8Array::Codepoint,
    } {
        InvalidUtf8Array::Utf8(_) => "the sequence is invalid UTF-8",
        InvalidUtf8Array::Codepoint(_) => "the encoded codepoint is invalid",
    } => true => {
        InvalidUtf8Array::Utf8(ref u) => Some(u),
        InvalidUtf8Array::Codepoint(ref c) => Some(c),
    }/// Always returns `Some`.
}

/// Reasons why a byte slice is not valid UTF-8, in sinking precedence.
#[derive(Clone,Copy, Debug, PartialEq,Eq)]
pub enum InvalidUtf8Slice {
    /// Something is certainly wrong with the first byte.
    Utf8(InvalidUtf8),
    /// The encoded codepoint is invalid:
    Codepoint(InvalidCodepoint),
    /// The slice is too short; n bytes was required.
    TooShort(usize),
}
complex!{InvalidUtf8Slice {
        InvalidUtf8 => InvalidUtf8Slice::Utf8,
        InvalidCodepoint => InvalidUtf8Slice::Codepoint,
    } {
        InvalidUtf8Slice::Utf8(_) => "the sequence is invalid UTF-8",
        InvalidUtf8Slice::Codepoint(_) => "the encoded codepoint is invalid",
        InvalidUtf8Slice::TooShort(0) => "the slice is empty",
        InvalidUtf8Slice::TooShort(_) => "the slice is shorter than the sequence",
    } => true => {
        InvalidUtf8Slice::Utf8(ref u) => Some(u),
        InvalidUtf8Slice::Codepoint(ref c) => Some(c),
        InvalidUtf8Slice::TooShort(_) => None,
    }
}
<|endoftext|>


<commit_before>/* Copyright 2016 The encode_unicode Developers
 *
 * Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
 * http://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.
 */

//! Boilerplatey error types

extern crate core;
use self::core::fmt::{self,Display,Formatter};
#[cfg(feature="std")]
use std::error::Error;

macro_rules! description {($err:ty, $desc:expr) => {
    #[cfg(not(feature="std"))]
    impl $err {
        #[allow(missing_docs)]
        pub fn description(&self) -> &'static str {
            ($desc)(self)
        }
    }
    #[cfg(feature="std")]
    impl Error for $err {
        fn description(&self) -> &'static str {
            ($desc)(self)
        }
    }
    impl Display for $err {
        fn fmt(&self,  fmtr: &mut Formatter) -> fmt::Result {
            write!(fmtr, "{}", self.description())
        }
    }
}}

macro_rules! single_cause {(#[$doc1:meta] #[$doc2:meta] $err:ident => $desc:expr) => {
    // Rust 1.15 doesn't understand $(#[$doc:meta])* $:ident
    #[$doc1]
    #[$doc2]
    #[derive(Clone,Copy, Debug, PartialEq,Eq)]
    pub struct $err;
    description!{$err, |_| $desc }
}}

single_cause!{
    /// Cannot tell whether an `u16` needs an extra unit,
    /// because it's a trailing surrogate itself.
    InvalidUtf16FirstUnit => "is a trailing surrogate"
}

single_cause!{
    /// Cannot create an `Utf8Char` or `Utf16Char` from the first codepoint of a str,
    /// because there are none.
    EmptyStrError => "is empty"
}

single_cause!{
    /// Cannot create an `Utf8Char` from a standalone `u8`
    /// that is not an ASCII character.
    NonAsciiError => "is not an ASCII character"
}

single_cause!{
    /// Cannot create an `Utf16Char` from a standalone `u16` that is not a
    /// codepoint in the basic multilingual plane, but part of a suurrogate pair.
    NonBMPError => "is not a codepoint in the basic multilingual plane"
}

macro_rules! simple {(#[$tydoc:meta] $err:ident  {
                          $($(#[$vardoc:meta])* ::$variant:ident => $string:expr),+,
                      } ) => {
    #[$tydoc]
    #[derive(Clone,Copy, Debug, PartialEq,Eq)]
    pub enum $err {
        $($(#[$vardoc])* $variant),*
    }
    description!{$err, |e: &$err| match *e {$($err::$variant=>$string),*} }
}}

simple!{/// Reasons why an `u32` is not a valid UTF codepoint.
    InvalidCodepoint {
        /// It's reserved for UTF-16 surrogate pairs."
        ::Utf16Reserved => "is reserved for UTF-16 surrogate pairs",
        /// It's higher than the highest codepoint (which is 0x10ffff).
        ::TooHigh => "is higher than the highest codepoint",
    }}
use self::InvalidCodepoint::*;
impl InvalidCodepoint {
    /// Get the range of values for which this error would be given.
    pub fn error_range(self) -> (u32,u32) {match self {
        Utf16Reserved => (0xd8_00, 0xdf_ff),
        TooHigh => (0x00_10_ff_ff, 0xff_ff_ff_ff),
    }}
}

simple!{/// Reasons why one or two `u16`s are not valid UTF-16, in sinking precedence.
    InvalidUtf16Tuple {
        /// The first unit is a trailing/low surrogate, which is never valid.
        ///
        /// Note that the value of a low surrogate is actually higher than a high surrogate.
        ::FirstIsTrailingSurrogate => "the first unit is a trailing / low surrogate, which is never valid",
        /// You provided a second unit, but the first one stands on its own.
        ::SuperfluousSecond => "the second unit is superfluous",
        /// The first and only unit requires a second unit.
        ::MissingSecond => "the first unit requires a second unit",
        /// The first unit requires a second unit, but it's not a trailing/low surrogate.
        ///
        /// Note that the value of a low surrogate is actually higher than a high surrogate.
        ::InvalidSecond => "the required second unit is not a trailing / low surrogate",
    }}

simple!{/// Reasons why a slice of `u16`s doesn't start with valid UTF-16.
    InvalidUtf16Slice {
        /// The slice is empty.
        ::EmptySlice => "the slice is empty",
        /// The first unit is a low surrogate.
        ::FirstLowSurrogate => "the first unit is a trailing surrogate",
        /// The first and only unit requires a second unit.
        ::MissingSecond => "the first and only unit requires a second one",
        /// The first unit requires a second one, but it's not a trailing surrogate.
        ::SecondNotLowSurrogate => "the required second unit is not a trailing surrogate",
    }}

simple!{/// Reasons why `Utf8Char::from_str()` or `Utf16Char::from_str()` failed.
    FromStrError {
        /// `Utf8Char` or `Utf16Char` cannot store more than a single codepoint.
        ::MultipleCodepoints => "has more than one codepoint",
        /// `Utf8Char` or `Utf16Char` cannot be empty.
        ::Empty => "is empty",
    }}

simple!{/// Reasons why a byte is not the start of a UTF-8 codepoint.
    InvalidUtf8FirstByte {
        /// Sequences cannot be longer than 4 bytes. Is given for values >= 240.
        ::TooLongSeqence => "is greater than 247 (UTF-8 sequences cannot be longer than four bytes)",
        /// This byte belongs to a previous sequence. Is given for values between 128 and 192 (exclusive).
        ::ContinuationByte => "is a continuation of a previous sequence",
    }}
use self::InvalidUtf8FirstByte::*;

macro_rules! complex {
($err:ty
 {$($sub:ty => $to:expr,)*}
 {$($desc:pat => $string:expr),+,}
 => $use_cause:expr =>
 {$($cause:pat => $result:expr),+,} $(#[$causedoc:meta])*
) => {
    $(impl From<$sub> for $err {
          fn from(error: $sub) -> $err {
              $to(error)
          }
      })*
    #[cfg(not(feature="std"))]
    impl $err {
        #[allow(missing_docs)]
        pub fn description(&self) -> &'static str {
            match *self{ $($desc => $string,)* }
        }
        /// A hack to avoid two Display impls
        fn cause(&self) -> Option<&Display> {None}
    }
    #[cfg(feature="std")]
    impl Error for $err {
        fn description(&self) -> &'static str {
            match *self{ $($desc => $string,)* }
        }
        $(#[$causedoc])*
        fn cause(&self) -> Option<&Error> {
            match *self{ $($cause => $result,)* }
        }
    }
    impl Display for $err {
        fn fmt(&self,  fmtr: &mut Formatter) -> fmt::Result {
            match (self.cause(), $use_cause) {
                (Some(d),true) => write!(fmtr, "{}: {}", self.description(), d),
                        _      => write!(fmtr, "{}", self.description()),
            }
        }
    }
}}

/// Reasons why a byte sequence is not valid UTF-8, excluding invalid codepoint.
/// In sinking precedence.
#[derive(Clone,Copy, Debug, PartialEq,Eq)]
pub enum InvalidUtf8 {
    /// Something is wrong with the first byte.
    FirstByte(InvalidUtf8FirstByte),
    /// The byte at index 1...3 should be a continuation byte,
    /// but dosesn't fit the pattern 0b10xx_xxxx.
    NotAContinuationByte(usize),
    /// There are too many leading zeros: it could be a byte shorter.
    ///
    /// [Decoding this could allow someone to input otherwise prohibited
    /// characters and sequences, such as "../"](https://tools.ietf.org/html/rfc3629#section-10).
    OverLong,
}
use self::InvalidUtf8::*;
complex!{InvalidUtf8 {
        InvalidUtf8FirstByte => FirstByte,
    } {
        FirstByte(TooLongSeqence) => "the first byte is greater than 239 (UTF-8 sequences cannot be longer than four bytes)",
        FirstByte(ContinuationByte) => "the first byte is a continuation of a previous sequence",
        OverLong => "the sequence contains too many zeros and could be shorter",
        NotAContinuationByte(_) => "the sequence is too short",
    } => false => {
        FirstByte(ref cause) => Some(cause),
        _ => None,
    }/// Returns `Some` if the error is a `InvalidUtf8FirstByte`.
}

/// Reasons why a byte array is not valid UTF-8, in sinking precedence.
#[derive(Clone,Copy, Debug, PartialEq,Eq)]
pub enum InvalidUtf8Array {
    /// Not a valid UTF-8 sequence.
    Utf8(InvalidUtf8),
    /// Not a valid unicode codepoint.
    Codepoint(InvalidCodepoint),
}
complex!{InvalidUtf8Array {
        InvalidUtf8 => InvalidUtf8Array::Utf8,
        InvalidCodepoint => InvalidUtf8Array::Codepoint,
    } {
        InvalidUtf8Array::Utf8(_) => "the sequence is invalid UTF-8",
        InvalidUtf8Array::Codepoint(_) => "the encoded codepoint is invalid",
    } => true => {
        InvalidUtf8Array::Utf8(ref u) => Some(u),
        InvalidUtf8Array::Codepoint(ref c) => Some(c),
    }/// Always returns `Some`.
}

/// Reasons why a byte slice is not valid UTF-8, in sinking precedence.
#[derive(Clone,Copy, Debug, PartialEq,Eq)]
pub enum InvalidUtf8Slice {
    /// Something is certainly wrong with the first byte.
    Utf8(InvalidUtf8),
    /// The encoded codepoint is invalid:
    Codepoint(InvalidCodepoint),
    /// The slice is too short; n bytes was required.
    TooShort(usize),
}
complex!{InvalidUtf8Slice {
        InvalidUtf8 => InvalidUtf8Slice::Utf8,
        InvalidCodepoint => InvalidUtf8Slice::Codepoint,
    } {
        InvalidUtf8Slice::Utf8(_) => "the sequence is invalid UTF-8",
        InvalidUtf8Slice::Codepoint(_) => "the encoded codepoint is invalid",
        InvalidUtf8Slice::TooShort(0) => "the slice is empty",
        InvalidUtf8Slice::TooShort(_) => "the slice is shorter than the sequence",
    } => true => {
        InvalidUtf8Slice::Utf8(ref u) => Some(u),
        InvalidUtf8Slice::Codepoint(ref c) => Some(c),
        InvalidUtf8Slice::TooShort(_) => None,
    }
}
<commit_msg>Improve InvalidUtf8Slice::description()<commit_after>/* Copyright 2016 The encode_unicode Developers
 *
 * Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
 * http://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.
 */

//! Boilerplatey error types

extern crate core;
use self::core::fmt::{self,Display,Formatter};
#[cfg(feature="std")]
use std::error::Error;

macro_rules! description {($err:ty, $desc:expr) => {
    #[cfg(not(feature="std"))]
    impl $err {
        #[allow(missing_docs)]
        pub fn description(&self) -> &'static str {
            ($desc)(self)
        }
    }
    #[cfg(feature="std")]
    impl Error for $err {
        fn description(&self) -> &'static str {
            ($desc)(self)
        }
    }
    impl Display for $err {
        fn fmt(&self,  fmtr: &mut Formatter) -> fmt::Result {
            write!(fmtr, "{}", self.description())
        }
    }
}}

macro_rules! single_cause {(#[$doc1:meta] #[$doc2:meta] $err:ident => $desc:expr) => {
    // Rust 1.15 doesn't understand $(#[$doc:meta])* $:ident
    #[$doc1]
    #[$doc2]
    #[derive(Clone,Copy, Debug, PartialEq,Eq)]
    pub struct $err;
    description!{$err, |_| $desc }
}}

single_cause!{
    /// Cannot tell whether an `u16` needs an extra unit,
    /// because it's a trailing surrogate itself.
    InvalidUtf16FirstUnit => "is a trailing surrogate"
}

single_cause!{
    /// Cannot create an `Utf8Char` or `Utf16Char` from the first codepoint of a str,
    /// because there are none.
    EmptyStrError => "is empty"
}

single_cause!{
    /// Cannot create an `Utf8Char` from a standalone `u8`
    /// that is not an ASCII character.
    NonAsciiError => "is not an ASCII character"
}

single_cause!{
    /// Cannot create an `Utf16Char` from a standalone `u16` that is not a
    /// codepoint in the basic multilingual plane, but part of a suurrogate pair.
    NonBMPError => "is not a codepoint in the basic multilingual plane"
}

macro_rules! simple {(#[$tydoc:meta] $err:ident  {
                          $($(#[$vardoc:meta])* ::$variant:ident => $string:expr),+,
                      } ) => {
    #[$tydoc]
    #[derive(Clone,Copy, Debug, PartialEq,Eq)]
    pub enum $err {
        $($(#[$vardoc])* $variant),*
    }
    description!{$err, |e: &$err| match *e {$($err::$variant=>$string),*} }
}}

simple!{/// Reasons why an `u32` is not a valid UTF codepoint.
    InvalidCodepoint {
        /// It's reserved for UTF-16 surrogate pairs."
        ::Utf16Reserved => "is reserved for UTF-16 surrogate pairs",
        /// It's higher than the highest codepoint (which is 0x10ffff).
        ::TooHigh => "is higher than the highest codepoint",
    }}
use self::InvalidCodepoint::*;
impl InvalidCodepoint {
    /// Get the range of values for which this error would be given.
    pub fn error_range(self) -> (u32,u32) {match self {
        Utf16Reserved => (0xd8_00, 0xdf_ff),
        TooHigh => (0x00_10_ff_ff, 0xff_ff_ff_ff),
    }}
}

simple!{/// Reasons why one or two `u16`s are not valid UTF-16, in sinking precedence.
    InvalidUtf16Tuple {
        /// The first unit is a trailing/low surrogate, which is never valid.
        ///
        /// Note that the value of a low surrogate is actually higher than a high surrogate.
        ::FirstIsTrailingSurrogate => "the first unit is a trailing / low surrogate, which is never valid",
        /// You provided a second unit, but the first one stands on its own.
        ::SuperfluousSecond => "the second unit is superfluous",
        /// The first and only unit requires a second unit.
        ::MissingSecond => "the first unit requires a second unit",
        /// The first unit requires a second unit, but it's not a trailing/low surrogate.
        ///
        /// Note that the value of a low surrogate is actually higher than a high surrogate.
        ::InvalidSecond => "the required second unit is not a trailing / low surrogate",
    }}

simple!{/// Reasons why a slice of `u16`s doesn't start with valid UTF-16.
    InvalidUtf16Slice {
        /// The slice is empty.
        ::EmptySlice => "the slice is empty",
        /// The first unit is a low surrogate.
        ::FirstLowSurrogate => "the first unit is a trailing surrogate",
        /// The first and only unit requires a second unit.
        ::MissingSecond => "the first and only unit requires a second one",
        /// The first unit requires a second one, but it's not a trailing surrogate.
        ::SecondNotLowSurrogate => "the required second unit is not a trailing surrogate",
    }}

simple!{/// Reasons why `Utf8Char::from_str()` or `Utf16Char::from_str()` failed.
    FromStrError {
        /// `Utf8Char` or `Utf16Char` cannot store more than a single codepoint.
        ::MultipleCodepoints => "has more than one codepoint",
        /// `Utf8Char` or `Utf16Char` cannot be empty.
        ::Empty => "is empty",
    }}

simple!{/// Reasons why a byte is not the start of a UTF-8 codepoint.
    InvalidUtf8FirstByte {
        /// Sequences cannot be longer than 4 bytes. Is given for values >= 240.
        ::TooLongSeqence => "is greater than 247 (UTF-8 sequences cannot be longer than four bytes)",
        /// This byte belongs to a previous sequence. Is given for values between 128 and 192 (exclusive).
        ::ContinuationByte => "is a continuation of a previous sequence",
    }}
use self::InvalidUtf8FirstByte::*;

macro_rules! complex {
($err:ty
 {$($sub:ty => $to:expr,)*}
 {$($desc:pat => $string:expr),+,}
 => $use_cause:expr =>
 {$($cause:pat => $result:expr),+,} $(#[$causedoc:meta])*
) => {
    $(impl From<$sub> for $err {
          fn from(error: $sub) -> $err {
              $to(error)
          }
      })*
    #[cfg(not(feature="std"))]
    impl $err {
        #[allow(missing_docs)]
        pub fn description(&self) -> &'static str {
            match *self{ $($desc => $string,)* }
        }
        /// A hack to avoid two Display impls
        fn cause(&self) -> Option<&Display> {None}
    }
    #[cfg(feature="std")]
    impl Error for $err {
        fn description(&self) -> &'static str {
            match *self{ $($desc => $string,)* }
        }
        $(#[$causedoc])*
        fn cause(&self) -> Option<&Error> {
            match *self{ $($cause => $result,)* }
        }
    }
    impl Display for $err {
        fn fmt(&self,  fmtr: &mut Formatter) -> fmt::Result {
            match (self.cause(), $use_cause) {
                (Some(d),true) => write!(fmtr, "{}: {}", self.description(), d),
                        _      => write!(fmtr, "{}", self.description()),
            }
        }
    }
}}

/// Reasons why a byte sequence is not valid UTF-8, excluding invalid codepoint.
/// In sinking precedence.
#[derive(Clone,Copy, Debug, PartialEq,Eq)]
pub enum InvalidUtf8 {
    /// Something is wrong with the first byte.
    FirstByte(InvalidUtf8FirstByte),
    /// The byte at index 1...3 should be a continuation byte,
    /// but dosesn't fit the pattern 0b10xx_xxxx.
    NotAContinuationByte(usize),
    /// There are too many leading zeros: it could be a byte shorter.
    ///
    /// [Decoding this could allow someone to input otherwise prohibited
    /// characters and sequences, such as "../"](https://tools.ietf.org/html/rfc3629#section-10).
    OverLong,
}
use self::InvalidUtf8::*;
complex!{InvalidUtf8 {
        InvalidUtf8FirstByte => FirstByte,
    } {
        FirstByte(TooLongSeqence) => "the first byte is greater than 239 (UTF-8 sequences cannot be longer than four bytes)",
        FirstByte(ContinuationByte) => "the first byte is a continuation of a previous sequence",
        OverLong => "the sequence contains too many zeros and could be shorter",
        NotAContinuationByte(_) => "the sequence is too short",
    } => false => {
        FirstByte(ref cause) => Some(cause),
        _ => None,
    }/// Returns `Some` if the error is a `InvalidUtf8FirstByte`.
}

/// Reasons why a byte array is not valid UTF-8, in sinking precedence.
#[derive(Clone,Copy, Debug, PartialEq,Eq)]
pub enum InvalidUtf8Array {
    /// Not a valid UTF-8 sequence.
    Utf8(InvalidUtf8),
    /// Not a valid unicode codepoint.
    Codepoint(InvalidCodepoint),
}
complex!{InvalidUtf8Array {
        InvalidUtf8 => InvalidUtf8Array::Utf8,
        InvalidCodepoint => InvalidUtf8Array::Codepoint,
    } {
        InvalidUtf8Array::Utf8(_) => "the sequence is invalid UTF-8",
        InvalidUtf8Array::Codepoint(_) => "the encoded codepoint is invalid",
    } => true => {
        InvalidUtf8Array::Utf8(ref u) => Some(u),
        InvalidUtf8Array::Codepoint(ref c) => Some(c),
    }/// Always returns `Some`.
}

/// Reasons why a byte slice is not valid UTF-8, in sinking precedence.
#[derive(Clone,Copy, Debug, PartialEq,Eq)]
pub enum InvalidUtf8Slice {
    /// Something is certainly wrong with the first byte.
    Utf8(InvalidUtf8),
    /// The encoded codepoint is invalid:
    Codepoint(InvalidCodepoint),
    /// The slice is too short; n bytes was required.
    TooShort(usize),
}
complex!{InvalidUtf8Slice {
        InvalidUtf8 => InvalidUtf8Slice::Utf8,
        InvalidCodepoint => InvalidUtf8Slice::Codepoint,
    } {
        InvalidUtf8Slice::Utf8(_) => "the sequence is invalid UTF-8",
        InvalidUtf8Slice::Codepoint(_) => "the encoded codepoint is invalid",
        InvalidUtf8Slice::TooShort(1) => "the slice is empty",
        InvalidUtf8Slice::TooShort(_) => "the slice is shorter than the sequence",
    } => true => {
        InvalidUtf8Slice::Utf8(ref u) => Some(u),
        InvalidUtf8Slice::Codepoint(ref c) => Some(c),
        InvalidUtf8Slice::TooShort(_) => None,
    }
}
<|endoftext|>


<commit_before>use std::fmt;
use std::cell::RefCell;

/// Format all iterator elements lazily, separated by `sep`.
///
/// See [`.format()`](trait.Itertools.html#method.format) for more information.
pub struct Format<'a, I, F> {
    sep: &'a str,
    /// Format uses interior mutability because Display::fmt takes &self.
    inner: RefCell<(I, F)>,
}

pub fn new_format<'a, I, F>(iter: I, separator: &'a str, f: F) -> Format<'a, I, F>
    where I: Iterator,
          F: FnMut(I::Item, &mut FnMut(&fmt::Display) -> fmt::Result) -> fmt::Result,
{
    Format{sep: separator, inner: RefCell::new((iter, f))}
}

impl<'a, I, F> fmt::Display for Format<'a, I, F>
    where I: Iterator,
          F: FnMut(I::Item, &mut FnMut(&fmt::Display) -> fmt::Result) -> fmt::Result,
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let mut cb = &mut |disp: &fmt::Display| write!(fmt, "{}", disp);
        let mut inner = self.inner.borrow_mut();
        let mut trailing = false;
        while let Some(elt) = inner.0.next() {
            if trailing && self.sep.len() > 0 {
                try!(cb(&self.sep));
            }
            try!((&mut inner.1)(elt, cb));
            trailing = true;
        }
        Ok(())
    }
}

impl<'a, I, F> fmt::Debug for Format<'a, I, F>
    where I: Iterator,
          F: FnMut(I::Item, &mut FnMut(&fmt::Display) -> fmt::Result) -> fmt::Result,
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(self, fmt)
    }
}

<commit_msg>format: Code cleanup<commit_after>use std::fmt;
use std::cell::RefCell;

/// Format all iterator elements lazily, separated by `sep`.
///
/// See [`.format()`](trait.Itertools.html#method.format) for more information.
pub struct Format<'a, I, F> {
    sep: &'a str,
    /// Format uses interior mutability because Display::fmt takes &self.
    inner: RefCell<(I, F)>,
}

pub fn new_format<'a, I, F>(iter: I, separator: &'a str, f: F) -> Format<'a, I, F>
    where I: Iterator,
          F: FnMut(I::Item, &mut FnMut(&fmt::Display) -> fmt::Result) -> fmt::Result,
{
    Format{sep: separator, inner: RefCell::new((iter, f))}
}

impl<'a, I, F> fmt::Display for Format<'a, I, F>
    where I: Iterator,
          F: FnMut(I::Item, &mut FnMut(&fmt::Display) -> fmt::Result) -> fmt::Result,
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let mut cb = &mut |disp: &fmt::Display| write!(fmt, "{}", disp);
        let (ref mut iter, ref mut format)  = *self.inner.borrow_mut();

        if let Some(fst) = iter.next() {
            try!(format(fst, cb));
            for elt in iter {
                if self.sep.len() > 0 {
                    try!(cb(&self.sep));
                }
                try!(format(elt, cb));
            }
        }
        Ok(())
    }
}

impl<'a, I, F> fmt::Debug for Format<'a, I, F>
    where I: Iterator,
          F: FnMut(I::Item, &mut FnMut(&fmt::Display) -> fmt::Result) -> fmt::Result,
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(self, fmt)
    }
}

<|endoftext|>


<commit_before>//! The implementation for Version 1 [`Uuid`]s.
//!
//! Note that you need feature `v1` in order to use these features.
//!
//! [`Uuid`]: ../struct.Uuid.html

use crate::prelude::*;
use core::sync::atomic;

/// The number of 100 ns ticks between the UUID epoch
/// `1582-10-15 00:00:00` and the Unix epoch `1970-01-01 00:00:00`.
const UUID_TICKS_BETWEEN_EPOCHS: u64 = 0x01B2_1DD2_1381_4000;

/// A thread-safe, stateful context for the v1 generator to help ensure
/// process-wide uniqueness.
#[derive(Debug)]
pub struct Context {
    count: atomic::AtomicUsize,
}

/// Stores the number of nanoseconds from an epoch and a counter for ensuring
/// V1 ids generated on the same host are unique.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Timestamp {
    ticks: u64,
    counter: u16
}

impl Timestamp {
    /// Construct a `Timestamp` from its raw component values: an RFC4122 timestamp
    /// and counter.
    ///
    /// RFC4122, which defines the V1 UUID, specifies a 60-byte timestamp format as
    /// the number of 100-nanosecond intervals elapsed since 00:00:00.00, 15 Oct 1582,
    /// "the date of the Gregorian reform of the Christian calendar."
    ///
    /// The counter value is used to differentiate between ids generated by
    /// the same host computer in rapid succession (i.e. with the same observed
    /// time). See `ClockSequence` trait for a generic interface to any counter
    /// generators that might be used.
    ///
    /// Internally, the timestamp is stored as a `u64`. For this reason, dates prior
    /// to October 1582 are not supported.
    ///
    pub fn from_rfc4122(hundred_ns_intervals: u64, counter: u16) -> Self {
        Timestamp { ticks: hundred_ns_intervals, counter }
    }

    /// Construct a `Timestamp` from a unix timestamp and sequence-generating `context`.
    ///
    /// A unix timestamp represents the elapsed time since Jan 1 1970. Libc's `clock_gettime`
    /// and other popular implementations traditionally represent this duration as a
    /// `timespec`: a struct with `i64` and `u32` fields representing the seconds, and
    /// "subsecond" or fractional nanoseconds elapsed since the timestamp's second began,
    /// respectively.
    ///
    /// This constructs a `Timestamp` from the seconds and fractional nanoseconds of a unix
    /// timestamp, converting the duration since 1970 into the number of 100-nanosecond
    /// intervals since 00:00:00.00, 15 Oct 1982 specified by RFC4122 and used internally
    /// by `Timestamp`.
    ///
    pub fn from_unix<T: ClockSequence>(secs: i64, subsec_nanos: u32, context: &T) -> Self {
        let counter = context.generate_sequence(secs.abs() as u64, subsec_nanos);
        let ticks =
            (UUID_TICKS_BETWEEN_EPOCHS as i64 + secs * 10_000_000 + ((subsec_nanos / 100) as i64)) as u64;
        Timestamp { ticks, counter }
    }

    /// Returns the raw RFC4122 timestamp and counter values stored by the `Timestamp`.
    /// The timestamp (the first, `u64` element in the tuple) represents the number of
    /// 100-nanosecond intervals since 00:00:00.00, 15 Oct 1582. The counter is used to
    /// differentiate between ids generated on the same host computer with the same
    /// observed time.
    ///
    pub fn to_rfc4122(&self) -> (u64, u16) {
        (self.ticks, self.counter)
    }

    /// Returns the timestamp converted to the seconds and fractional nanoseconds
    /// since Jan 1 1970. Internally, the time is stored in 100-nanosecond intervals,
    /// thus the maximum precision represented by the fractional nanoseconds value
    /// is less than its unit size (100 ns vs. 1 ns).
    ///
    pub fn to_unix(&self) -> (i64, u32) {
        let unix_ticks = (self.ticks - UUID_TICKS_BETWEEN_EPOCHS) as i64;
        (unix_ticks / 10_000_000, (unix_ticks % 10_000_000).abs() as u32 * 100)
    }

    /// Returns the timestamp converted into nanoseconds elapsed since Jan 1 1970.
    /// Internally, the time is stored in 100-nanosecond intervals, thus the maximum
    /// precision represented is less than the units it is measured in (100 ns vs. 1 ns).
    /// The value returned represents the same duration as `to_unix`; this provides
    /// it in nanosecond units for convenience.
    ///
    pub fn to_unix_nanos(&self) -> i64 {
        (self.ticks - UUID_TICKS_BETWEEN_EPOCHS) as i64 * 100
    }
}

/// A trait that abstracts over generation of Uuid v1 "Clock Sequence" values.
pub trait ClockSequence {
    /// Return a 16-bit number that will be used as the "clock sequence" in
    /// the Uuid. The number must be different if the time has changed since
    /// the last time a clock sequence was requested.
    fn generate_sequence(&self, seconds: u64, subsec_nanos: u32) -> u16;
}

impl Uuid {
    /// Create a new [`Uuid`] (version 1) using a time value + sequence +
    /// *NodeId*.
    ///
    /// This expects two values representing a monotonically increasing value
    /// as well as a unique 6 byte NodeId, and an implementation of
    /// [`ClockSequence`]. This function is only guaranteed to produce
    /// unique values if the following conditions hold:
    ///
    /// 1. The *NodeId* is unique for this process,
    /// 2. The *Context* is shared across all threads which are generating v1
    ///    [`Uuid`]s,
    /// 3. The [`ClockSequence`] implementation reliably returns unique
    ///    clock sequences (this crate provides [`Context`] for this
    ///    purpose. However you can create your own [`ClockSequence`]
    ///    implementation, if [`Context`] does not meet your needs).
    ///
    /// The NodeID must be exactly 6 bytes long. If the NodeID is not a valid
    /// length this will return a [`ParseError`]`::InvalidLength`.
    ///
    /// The function is not guaranteed to produce monotonically increasing
    /// values however.  There is a slight possibility that two successive
    /// equal time values could be supplied and the sequence counter wraps back
    /// over to 0.
    ///
    /// If uniqueness and monotonicity is required, the user is responsible for
    /// ensuring that the time value always increases between calls (including
    /// between restarts of the process and device).
    ///
    /// Note that usage of this method requires the `v1` feature of this crate
    /// to be enabled.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```rust
    /// use uuid::v1::Context;
    /// use uuid::Uuid;
    ///
    /// let context = Context::new(42);
    /// if let Ok(uuid) =
    ///     Uuid::new_v1(&context, 1497624119, 1234, &[1, 2, 3, 4, 5, 6])
    /// {
    ///     assert_eq!(
    ///         uuid.to_hyphenated().to_string(),
    ///         "f3b4958c-52a1-11e7-802a-010203040506"
    ///     )
    /// } else {
    ///     panic!()
    /// }
    /// ```
    ///
    /// [`ParseError`]: ../enum.ParseError.html
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`ClockSequence`]: struct.ClockSequence.html
    /// [`Context`]: struct.Context.html
    pub fn new_v1<T>(
        context: &T,
        seconds: u64,
        nano_seconds: u32,
        node_id: &[u8],
    ) -> Result<Self, crate::Error>
    where
        T: ClockSequence,
    {
        const NODE_ID_LEN: usize = 6;

        let len = node_id.len();
        if len != NODE_ID_LEN {
            Err(crate::builder::Error::new(NODE_ID_LEN, len))?;
        }

        let time_low;
        let time_mid;
        let time_high_and_version;

        {
            let timestamp =
                seconds * 10_000_000 + u64::from(nano_seconds / 100);
            let uuid_time = timestamp + UUID_TICKS_BETWEEN_EPOCHS;

            time_low = (uuid_time & 0xFFFF_FFFF) as u32;
            time_mid = ((uuid_time >> 32) & 0xFFFF) as u16;
            time_high_and_version =
                (((uuid_time >> 48) & 0x0FFF) as u16) | (1 << 12);
        }

        let mut d4 = [0; 8];

        {
            let count = context.generate_sequence(seconds, nano_seconds);
            d4[0] = (((count & 0x3F00) >> 8) as u8) | 0x80;
            d4[1] = (count & 0xFF) as u8;
        }

        d4[2..].copy_from_slice(node_id);

        Uuid::from_fields(time_low, time_mid, time_high_and_version, &d4)
    }

    /// Construct V1 UUID from a `Timestamp` and `node_id`.
    pub fn with_timestamp(
        ts: &Timestamp,
        node_id: &[u8],
    ) -> Result<Self, crate::Error> {
        const NODE_ID_LEN: usize = 6;

        let len = node_id.len();
        if len != NODE_ID_LEN {
            Err(crate::builder::Error::new(NODE_ID_LEN, len))?;
        }

        let time_low = (ts.ticks & 0xFFFF_FFFF) as u32;
        let time_mid = ((ts.ticks >> 32) & 0xFFFF) as u16;
        let time_high_and_version =
                (((ts.ticks >> 48) & 0x0FFF) as u16) | (1 << 12);

        let mut d4 = [0; 8];

        {
            d4[0] = (((ts.counter & 0x3F00) >> 8) as u8) | 0x80;
            d4[1] = (ts.counter & 0xFF) as u8;
        }

        d4[2..].copy_from_slice(node_id);

        Uuid::from_fields(time_low, time_mid, time_high_and_version, &d4)
    }

    /// Returns an Optional `Timestamp` storing the timestamp and
    /// counter portion parsed from a V1 UUID.
    ///
    /// Returns `None` if the supplied UUID is not V1.
    ///
    /// The V1 timestamp format defined in RFC4122 specifies a 60-bit
    /// integer representing the number of 100-nanosecond intervals
    /// since 00:00:00.00, 15 Oct 1582.
    ///
    /// `Timestamp` offers several options for converting the raw RFC4122
    /// value into more commonly-used formats, such as a unix timestamp.
    pub fn to_timestamp(&self) -> Option<Timestamp> {
        if self
            .get_version()
            .map(|v| v != Version::Mac)
            .unwrap_or(true)
        {
            return None;
        }

        let ticks: u64 = u64::from(self.as_bytes()[6] & 0x0F) << 56
            | u64::from(self.as_bytes()[7]) << 48
            | u64::from(self.as_bytes()[4]) << 40
            | u64::from(self.as_bytes()[5]) << 32
            | u64::from(self.as_bytes()[0]) << 24
            | u64::from(self.as_bytes()[1]) << 16
            | u64::from(self.as_bytes()[2]) << 8
            | u64::from(self.as_bytes()[3]);

        let counter: u16 = u16::from(self.as_bytes()[8] & 0x3F) << 8
            | u16::from(self.as_bytes()[9]);

        Some(Timestamp::from_rfc4122(ticks, counter))
    }
}

impl Context {
    /// Creates a thread-safe, internally mutable context to help ensure
    /// uniqueness.
    ///
    /// This is a context which can be shared across threads. It maintains an
    /// internal counter that is incremented at every request, the value ends
    /// up in the clock_seq portion of the [`Uuid`] (the fourth group). This
    /// will improve the probability that the [`Uuid`] is unique across the
    /// process.
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    pub const fn new(count: u16) -> Self {
        Self {
            count: atomic::AtomicUsize::new(count as usize),
        }
    }
}

impl ClockSequence for Context {
    fn generate_sequence(&self, _: u64, _: u32) -> u16 {
        (self.count.fetch_add(1, atomic::Ordering::SeqCst) & 0xffff) as u16
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    use crate::{
        std::string::ToString,
    };

    #[test]
    fn test_new_v1() {
        let time: u64 = 1_496_854_535;
        let time_fraction: u32 = 812_946_000;
        let node = [1, 2, 3, 4, 5, 6];
        let context = Context::new(0);

        {
            let uuid =
                Uuid::new_v1(&context, time, time_fraction, &node).unwrap();

            assert_eq!(uuid.get_version(), Some(Version::Mac));
            assert_eq!(uuid.get_variant(), Some(Variant::RFC4122));
            assert_eq!(
                uuid.to_hyphenated().to_string(),
                "20616934-4ba2-11e7-8000-010203040506"
            );

            let ts = uuid.to_timestamp().unwrap().to_rfc4122();

            assert_eq!(ts.0 - 0x01B2_1DD2_1381_4000, 14_968_545_358_129_460);
            assert_eq!(ts.1, 0);
        };

        {
            let uuid2 =
                Uuid::new_v1(&context, time, time_fraction, &node).unwrap();

            assert_eq!(
                uuid2.to_hyphenated().to_string(),
                "20616934-4ba2-11e7-8001-010203040506"
            );
            assert_eq!(uuid2.to_timestamp().unwrap().to_rfc4122().1, 1)
        };
    }
}
<commit_msg>refactor v1 timestamp generation<commit_after>//! The implementation for Version 1 [`Uuid`]s.
//!
//! Note that you need feature `v1` in order to use these features.
//!
//! [`Uuid`]: ../struct.Uuid.html

use crate::prelude::*;
use core::sync::atomic;

/// The number of 100 ns ticks between the UUID epoch
/// `1582-10-15 00:00:00` and the Unix epoch `1970-01-01 00:00:00`.
const UUID_TICKS_BETWEEN_EPOCHS: u64 = 0x01B2_1DD2_1381_4000;

/// A thread-safe, stateful context for the v1 generator to help ensure
/// process-wide uniqueness.
#[derive(Debug)]
pub struct Context {
    count: atomic::AtomicUsize,
}

/// Stores the number of nanoseconds from an epoch and a counter for ensuring
/// V1 ids generated on the same host are unique.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Timestamp {
    ticks: u64,
    counter: u16,
}

impl Timestamp {
    /// Construct a `Timestamp` from its raw component values: an RFC4122 timestamp
    /// and counter.
    ///
    /// RFC4122, which defines the V1 UUID, specifies a 60-byte timestamp format as
    /// the number of 100-nanosecond intervals elapsed since 00:00:00.00, 15 Oct 1582,
    /// "the date of the Gregorian reform of the Christian calendar."
    ///
    /// The counter value is used to differentiate between ids generated by
    /// the same host computer in rapid succession (i.e. with the same observed
    /// time). See `ClockSequence` trait for a generic interface to any counter
    /// generators that might be used.
    ///
    /// Internally, the timestamp is stored as a `u64`. For this reason, dates prior
    /// to October 1582 are not supported.
    pub const fn from_rfc4122(ticks: u64, counter: u16) -> Self {
        Timestamp { ticks, counter }
    }

    /// Construct a `Timestamp` from a unix timestamp and sequence-generating `context`.
    ///
    /// A unix timestamp represents the elapsed time since Jan 1 1970. Libc's `clock_gettime`
    /// and other popular implementations traditionally represent this duration as a
    /// `timespec`: a struct with `u64` and `u32` fields representing the seconds, and
    /// "subsecond" or fractional nanoseconds elapsed since the timestamp's second began,
    /// respectively.
    ///
    /// This constructs a `Timestamp` from the seconds and fractional nanoseconds of a unix
    /// timestamp, converting the duration since 1970 into the number of 100-nanosecond
    /// intervals since 00:00:00.00, 15 Oct 1982 specified by RFC4122 and used internally
    /// by `Timestamp`.
    ///
    /// The function is not guaranteed to produce monotonically increasing
    /// values however. There is a slight possibility that two successive
    /// equal time values could be supplied and the sequence counter wraps back
    /// over to 0.
    ///
    /// If uniqueness and monotonicity is required, the user is responsible for
    /// ensuring that the time value always increases between calls (including
    /// between restarts of the process and device).
    pub fn from_unix(context: impl ClockSequence, seconds: u64, subsec_nanos: u32) -> Self {
        let counter = context.generate_sequence(seconds, subsec_nanos);
        let ticks =
            UUID_TICKS_BETWEEN_EPOCHS + seconds * 10_000_000 + (subsec_nanos as u64 / 100);
        Timestamp { ticks, counter }
    }

    /// Returns the raw RFC4122 timestamp and counter values stored by the `Timestamp`.
    ///
    /// The timestamp (the first, `u64` element in the tuple) represents the number of
    /// 100-nanosecond intervals since 00:00:00.00, 15 Oct 1582. The counter is used to
    /// differentiate between ids generated on the same host computer with the same
    /// observed time.
    pub const fn to_rfc4122(&self) -> (u64, u16) {
        (self.ticks, self.counter)
    }

    /// Returns the timestamp converted to the seconds and fractional nanoseconds
    /// since Jan 1 1970.
    ///
    /// Internally, the time is stored in 100-nanosecond intervals,
    /// thus the maximum precision represented by the fractional nanoseconds value
    /// is less than its unit size (100 ns vs. 1 ns).
    pub const fn to_unix(&self) -> (u64, u32) {
        let unix_ticks = self.ticks - UUID_TICKS_BETWEEN_EPOCHS;
        (unix_ticks / 10_000_000, (unix_ticks % 10_000_000) as u32 * 100)
    }

    /// Returns the timestamp converted into nanoseconds elapsed since Jan 1 1970.
    /// Internally, the time is stored in 100-nanosecond intervals, thus the maximum
    /// precision represented is less than the units it is measured in (100 ns vs. 1 ns).
    /// The value returned represents the same duration as `to_unix`; this provides
    /// it in nanosecond units for convenience.
    pub const fn to_unix_nanos(&self) -> u64 {
        (self.ticks - UUID_TICKS_BETWEEN_EPOCHS) * 100
    }
}

/// A trait that abstracts over generation of Uuid v1 "Clock Sequence" values.
pub trait ClockSequence {
    /// Return a 16-bit number that will be used as the "clock sequence" in
    /// the Uuid. The number must be different if the time has changed since
    /// the last time a clock sequence was requested.
    fn generate_sequence(&self, seconds: u64, subsec_nanos: u32) -> u16;
}

impl<'a, T: ClockSequence + ?Sized> ClockSequence for &'a T {
    fn generate_sequence(&self, seconds: u64, subsec_nanos: u32) -> u16 {
        (**self).generate_sequence(seconds, subsec_nanos)
    }
}

impl Uuid {
    /// Create a new [`Uuid`] (version 1) using a time value + sequence +
    /// *NodeId*.
    ///
    /// When generating [`Timestamp`]s using a [`ClockSequence`], this function
    /// is only guaranteed to produce unique values if the following conditions hold:
    ///
    /// 1. The *NodeId* is unique for this process,
    /// 2. The *Context* is shared across all threads which are generating v1
    ///    [`Uuid`]s,
    /// 3. The [`ClockSequence`] implementation reliably returns unique
    ///    clock sequences (this crate provides [`Context`] for this
    ///    purpose. However you can create your own [`ClockSequence`]
    ///    implementation, if [`Context`] does not meet your needs).
    ///
    /// The NodeID must be exactly 6 bytes long. If the NodeID is not a valid
    /// length this will return a [`ParseError`]`::InvalidLength`.
    ///
    /// Note that usage of this method requires the `v1` feature of this crate
    /// to be enabled.
    ///
    /// # Examples
    ///
    /// A [`Uuid`] can be created from a unix [`Timestamp`] with a [`ClockSequence`]:
    ///
    /// ```rust
    /// use uuid::v1::{Timestamp, Context};
    /// use uuid::Uuid;
    ///
    /// let context = Context::new(42);
    /// let ts = Timestamp::from_unix(&context, 1497624119, 1234);
    /// let uuid = Uuid::new_v1(ts, &[1, 2, 3, 4, 5, 6]).expect("failed to generate UUID");
    ///
    /// assert_eq!(
    ///     uuid.to_hyphenated().to_string(),
    ///     "f3b4958c-52a1-11e7-802a-010203040506"
    /// );
    /// ```
    ///
    /// The timestamp can also be created manually as per RFC4122:
    ///
    /// ```
    /// use uuid::v1::{Timestamp, Context};
    /// use uuid::Uuid;
    ///
    /// let context = Context::new(42);
    /// let ts = Timestamp::from_rfc4122(1497624119, 0);
    /// let uuid = Uuid::new_v1(ts, &[1, 2, 3, 4, 5, 6]).expect("failed to generate UUID");
    ///
    /// assert_eq!(
    ///     uuid.to_hyphenated().to_string(),
    ///     "5943ee37-0000-1000-8000-010203040506"
    /// );
    /// ```
    ///
    /// [`ParseError`]: ../enum.ParseError.html
    /// [`Uuid`]: ../struct.Uuid.html
    /// [`ClockSequence`]: struct.ClockSequence.html
    /// [`Context`]: struct.Context.html
    pub fn new_v1(
        ts: Timestamp,
        node_id: &[u8],
    ) -> Result<Self, crate::Error> {
        const NODE_ID_LEN: usize = 6;

        let len = node_id.len();
        if len != NODE_ID_LEN {
            Err(crate::builder::Error::new(NODE_ID_LEN, len))?;
        }

        let time_low = (ts.ticks & 0xFFFF_FFFF) as u32;
        let time_mid = ((ts.ticks >> 32) & 0xFFFF) as u16;
        let time_high_and_version =
                (((ts.ticks >> 48) & 0x0FFF) as u16) | (1 << 12);

        let mut d4 = [0; 8];

        {
            d4[0] = (((ts.counter & 0x3F00) >> 8) as u8) | 0x80;
            d4[1] = (ts.counter & 0xFF) as u8;
        }

        d4[2..].copy_from_slice(node_id);

        Uuid::from_fields(time_low, time_mid, time_high_and_version, &d4)
    }

    /// Returns an optional `Timestamp` storing the timestamp and
    /// counter portion parsed from a V1 UUID.
    ///
    /// Returns `None` if the supplied UUID is not V1.
    ///
    /// The V1 timestamp format defined in RFC4122 specifies a 60-bit
    /// integer representing the number of 100-nanosecond intervals
    /// since 00:00:00.00, 15 Oct 1582.
    ///
    /// `Timestamp` offers several options for converting the raw RFC4122
    /// value into more commonly-used formats, such as a unix timestamp.
    pub fn to_timestamp(&self) -> Option<Timestamp> {
        if self
            .get_version()
            .map(|v| v != Version::Mac)
            .unwrap_or(true)
        {
            return None;
        }

        let ticks: u64 = u64::from(self.as_bytes()[6] & 0x0F) << 56
            | u64::from(self.as_bytes()[7]) << 48
            | u64::from(self.as_bytes()[4]) << 40
            | u64::from(self.as_bytes()[5]) << 32
            | u64::from(self.as_bytes()[0]) << 24
            | u64::from(self.as_bytes()[1]) << 16
            | u64::from(self.as_bytes()[2]) << 8
            | u64::from(self.as_bytes()[3]);

        let counter: u16 = u16::from(self.as_bytes()[8] & 0x3F) << 8
            | u16::from(self.as_bytes()[9]);

        Some(Timestamp::from_rfc4122(ticks, counter))
    }
}

impl Context {
    /// Creates a thread-safe, internally mutable context to help ensure
    /// uniqueness.
    ///
    /// This is a context which can be shared across threads. It maintains an
    /// internal counter that is incremented at every request, the value ends
    /// up in the clock_seq portion of the [`Uuid`] (the fourth group). This
    /// will improve the probability that the [`Uuid`] is unique across the
    /// process.
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    pub const fn new(count: u16) -> Self {
        Self {
            count: atomic::AtomicUsize::new(count as usize),
        }
    }
}

impl ClockSequence for Context {
    fn generate_sequence(&self, _: u64, _: u32) -> u16 {
        (self.count.fetch_add(1, atomic::Ordering::SeqCst) & 0xffff) as u16
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    use crate::{
        std::string::ToString,
    };

    #[test]
    fn test_new_v1() {
        let time: u64 = 1_496_854_535;
        let time_fraction: u32 = 812_946_000;
        let node = [1, 2, 3, 4, 5, 6];
        let context = Context::new(0);

        {
            let uuid =
                Uuid::new_v1(Timestamp::from_unix(&context, time, time_fraction), &node).unwrap();

            assert_eq!(uuid.get_version(), Some(Version::Mac));
            assert_eq!(uuid.get_variant(), Some(Variant::RFC4122));
            assert_eq!(
                uuid.to_hyphenated().to_string(),
                "20616934-4ba2-11e7-8000-010203040506"
            );

            let ts = uuid.to_timestamp().unwrap().to_rfc4122();

            assert_eq!(ts.0 - 0x01B2_1DD2_1381_4000, 14_968_545_358_129_460);
            assert_eq!(ts.1, 0);
        };

        {
            let uuid2 =
                Uuid::new_v1(Timestamp::from_unix(&context, time, time_fraction), &node).unwrap();

            assert_eq!(
                uuid2.to_hyphenated().to_string(),
                "20616934-4ba2-11e7-8001-010203040506"
            );
            assert_eq!(uuid2.to_timestamp().unwrap().to_rfc4122().1, 1)
        };
    }
}
<|endoftext|>


<commit_before>use prelude::*;
use rand;

impl Uuid {
    /// Creates a random [`Uuid`].
    ///
    /// This uses the [`rand`] crate's default task RNG as the source of random
    /// numbers. If you'd like to use a custom generator, don't use this
    /// method: use the `rand::Rand trait`'s `rand()` method instead.
    ///
    /// Note that usage of this method requires the `v4` feature of this crate
    /// to be enabled.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use uuid::Uuid;
    ///
    /// let uuid = Uuid::new_v4();
    /// ```
    ///
    /// [`rand`]: https://crates.io/crates/rand
    /// [`Uuid`]: ../struct.Uuid.html
    pub fn new_v4() -> Self {
        use rand::RngCore;

        let mut rng = rand::thread_rng();
        let mut bytes = [0; 16];

        rng.fill_bytes(&mut bytes);

        Self::from_random_bytes(bytes)
    }
}

#[cfg(test)]
mod tests {
    use prelude::*;

    #[test]
    fn test_new() {
        let uuid = Uuid::new_v4();

        assert_eq!(uuid.get_version(), Some(Version::Random));
        assert_eq!(uuid.get_variant(), Some(Variant::RFC4122));
    }

    #[test]
    fn test_get_version() {
        let uuid = Uuid::new_v4();

        assert_eq!(uuid.get_version(), Some(Version::Random));
        assert_eq!(uuid.get_version_num(), 4)
    }
}
<commit_msg>remove use of from_random_bytes, instead use the Builder<commit_after>use prelude::*;
use rand;

impl Uuid {
    /// Creates a random [`Uuid`].
    ///
    /// This uses the [`rand`] crate's default task RNG as the source of random
    /// numbers. If you'd like to use a custom generator, don't use this
    /// method: use the `rand::Rand trait`'s `rand()` method instead.
    ///
    /// Note that usage of this method requires the `v4` feature of this crate
    /// to be enabled.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use uuid::Uuid;
    ///
    /// let uuid = Uuid::new_v4();
    /// ```
    ///
    /// [`rand`]: https://crates.io/crates/rand
    /// [`Uuid`]: ../struct.Uuid.html
    pub fn new_v4() -> Self {
        use rand::RngCore;

        let mut rng = rand::thread_rng();
        let mut bytes = [0; 16];

        rng.fill_bytes(&mut bytes);

        Builder::from_bytes_be(bytes)
            .set_variant(Variant::RFC4122)
            .set_version(Version::Random)
            .build()
    }
}

#[cfg(test)]
mod tests {
    use prelude::*;

    #[test]
    fn test_new() {
        let uuid = Uuid::new_v4();

        assert_eq!(uuid.get_version(), Some(Version::Random));
        assert_eq!(uuid.get_variant(), Some(Variant::RFC4122));
    }

    #[test]
    fn test_get_version() {
        let uuid = Uuid::new_v4();

        assert_eq!(uuid.get_version(), Some(Version::Random));
        assert_eq!(uuid.get_version_num(), 4)
    }
}
<|endoftext|>


<commit_before>type Cell = u8;

pub struct VM {
    cells: [Cell; 30_000],
    data_pointer: usize,
}

impl VM {
    pub fn new() -> VM {
        VM { cells: [0; 30_000], data_pointer: 0 }
    }

    pub fn output(&self) {
        print!("{}", self.cells[self.data_pointer]);
    }

    pub fn increment(&mut self) {
        self.cells[self.data_pointer] = self.cells[self.data_pointer] + 1;
    }

    pub fn decrement(&mut self) {
        self.cells[self.data_pointer] = self.cells[self.data_pointer] - 1;
    }

    pub fn right_shift(&mut self) {
        self.data_pointer = self.data_pointer + 1;
    }

    pub fn left_shift(&mut self) {
        self.data_pointer = self.data_pointer - 1;
    }
}
<commit_msg>Add vm.input function<commit_after>use std::io;
use std::io::Read;

type Cell = u8;

pub struct VM {
    cells: [Cell; 30_000],
    data_pointer: usize,
}

impl VM {
    pub fn new() -> VM {
        VM { cells: [0; 30_000], data_pointer: 0 }
    }

    pub fn output(&self) {
        print!("{}", self.cells[self.data_pointer]);
    }

    pub fn input(&self) {
        let mut buffer = [0; 1];
        let mut stdin = io::stdin();
        stdin.read_exact(&mut buffer).unwrap();
    }

    pub fn increment(&mut self) {
        self.cells[self.data_pointer] = self.cells[self.data_pointer] + 1;
    }

    pub fn decrement(&mut self) {
        self.cells[self.data_pointer] = self.cells[self.data_pointer] - 1;
    }

    pub fn right_shift(&mut self) {
        self.data_pointer = self.data_pointer + 1;
    }

    pub fn left_shift(&mut self) {
        self.data_pointer = self.data_pointer - 1;
    }
}
<|endoftext|>


<commit_before>#![feature(phase)]
#![crate_type="staticlib"]
#![no_std]

extern crate core;
extern crate zinc;

#[no_mangle]
#[allow(unused_variables)]
#[allow(dead_code)]
pub unsafe fn main() {
  use zinc::hal::timer::Timer;
  use zinc::hal::stm32f4::{pin, timer};
  zinc::hal::mem_init::init_stack();
  zinc::hal::mem_init::init_data();

  let led1 = pin::PinConf{
    port: pin::PortG,
    pin: 13u8,
    function: pin::GPIOOut
  };
  let led2 = pin::PinConf{
    port: pin::PortG,
    pin: 14u8,
    function: pin::GPIOOut
  };
  led1.setup();
  led2.setup();

  let timer = timer::Timer::new(timer::Timer2, 25u32);

  loop {
    led1.set_high();
    led2.set_low();
    timer.wait_ms(300);
    led1.set_low();
    led2.set_high();
    timer.wait_ms(300);
  }
}
<commit_msg>Changed portg to portd to light leds on the stm32f4<commit_after>#![feature(phase)]
#![crate_type="staticlib"]
#![no_std]

extern crate core;
extern crate zinc;

#[no_mangle]
#[allow(unused_variables)]
#[allow(dead_code)]
pub unsafe fn main() {
  use zinc::hal::timer::Timer;
  use zinc::hal::stm32f4::{pin, timer};
  zinc::hal::mem_init::init_stack();
  zinc::hal::mem_init::init_data();

  let led1 = pin::PinConf{
    port: pin::PortD,
    pin: 13u8,
    function: pin::GPIOOut
  };
  let led2 = pin::PinConf{
    port: pin::PortD,
    pin: 14u8,
    function: pin::GPIOOut
  };
  led1.setup();
  led2.setup();

  let timer = timer::Timer::new(timer::Timer2, 25u32);

  loop {
    led1.set_high();
    led2.set_low();
    timer.wait_ms(300);
    led1.set_low();
    led2.set_high();
    timer.wait_ms(300);
  }
}
<|endoftext|>


<commit_before>// Copyright 2015 Jauhien Piatlicki.
//
// 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.

// LLVM Execution Engine
// LLVM-C header ExecutionEngine.h

use std;
use std::ffi::CString;

use libc::{c_char, c_uint, size_t};

use llvm_sys::prelude::*;
use llvm_sys::core::*;
use llvm_sys::execution_engine::*;
use llvm_sys::target_machine::*;

use ::{LLVMRef, LLVMRefCtor};
use core;
use execution_engine::GenericValue;
use execution_engine::MCJITMemoryManager;

pub struct FrozenModule {
    module: core::Module
}

impl FrozenModule {
    pub fn get(&self) -> &core::Module {
        &self.module
    }
}

pub struct ExecutionEngine {
    ee: LLVMExecutionEngineRef,
    _memory_manager: Option<Box<MCJITMemoryManager>>
}

impl ExecutionEngine {
    pub fn new(mut module: core::Module) -> Result<(ExecutionEngine, FrozenModule), String> {
        let mut ee = 0 as LLVMExecutionEngineRef;
        let mut error = 0 as *mut c_char;
        unsafe {
            module.unown();
            if LLVMCreateExecutionEngineForModule(&mut ee, module.to_ref(), &mut error) > 0 {
                let cstr_buf = std::ffi::CStr::from_ptr(error);
                let result = String::from_utf8_lossy(cstr_buf.to_bytes()).into_owned();
                LLVMDisposeMessage(error);
                Err(result)
            } else {
                Ok((ExecutionEngine {ee:ee, _memory_manager: None}, FrozenModule {module:module}))
            }
        }
    }

    pub fn new_interpreter(mut module: core::Module) -> Result<(ExecutionEngine, FrozenModule), String> {
        let mut ee = 0 as LLVMExecutionEngineRef;
        let mut error = 0 as *mut c_char;
        unsafe {
            module.unown();
            if LLVMCreateInterpreterForModule(&mut ee, module.to_ref(), &mut error) > 0 {
                let cstr_buf = std::ffi::CStr::from_ptr(error);
                let result = String::from_utf8_lossy(cstr_buf.to_bytes()).into_owned();
                LLVMDisposeMessage(error);
                Err(result)
            } else {
                Ok((ExecutionEngine {ee:ee, _memory_manager: None}, FrozenModule {module:module}))
            }
        }
    }

    pub fn new_jit_compiler(mut module: core::Module, opt_level: u32) -> Result<(ExecutionEngine, FrozenModule), String> {
        let mut ee = 0 as LLVMExecutionEngineRef;
        let mut error = 0 as *mut c_char;
        unsafe {
            module.unown();
            if LLVMCreateJITCompilerForModule(&mut ee, module.to_ref(), opt_level, &mut error) > 0 {
                let cstr_buf = std::ffi::CStr::from_ptr(error);
                let result = String::from_utf8_lossy(cstr_buf.to_bytes()).into_owned();
                LLVMDisposeMessage(error);
                Err(result)
            } else {
                Ok((ExecutionEngine {ee:ee, _memory_manager: None}, FrozenModule {module:module}))
            }
        }
    }

    pub fn add_module(&mut self, mut module: core::Module) -> FrozenModule {
        unsafe {
            LLVMAddModule(self.to_ref(), module.to_ref());
            module.unown();
        }
        FrozenModule {module: module}
    }

    pub fn remove_module(&mut self, module: FrozenModule) -> Result<core::Module, String> {
        let mut module_ref = 0 as LLVMModuleRef;
        let mut error = 0 as *mut c_char;
        unsafe {
            if LLVMRemoveModule(self.to_ref(), module.get().to_ref(), &mut module_ref, &mut error) > 0 {
                let cstr_buf = std::ffi::CStr::from_ptr(error);
                let result = String::from_utf8_lossy(cstr_buf.to_bytes()).into_owned();
                LLVMDisposeMessage(error);
                Err(result)
            }
            else {
                Ok(core::Module::from_ref(module_ref))
            }
        }
    }

    pub fn run_static_constructors(&mut self) {
        unsafe {
            LLVMRunStaticConstructors(self.to_ref())
        }
    }

    pub fn run_static_destructors(&mut self) {
        unsafe {
            LLVMRunStaticDestructors(self.to_ref())
        }
    }

    pub fn run_function<T:core::Function>(&mut self, f: &T, args: &mut [LLVMGenericValueRef]) -> GenericValue {
        unsafe {
            GenericValue::from_ref(LLVMRunFunction(self.to_ref(), f.to_ref(), args.len() as c_uint, args.as_mut_ptr()))
        }
    }

    pub fn get_function_address(&self, name: &str) -> u64 {
        let name = CString::new(name).unwrap();
        unsafe {
            LLVMGetFunctionAddress(self.to_ref(), name.as_ptr() as *const c_char)
        }
    }
}

impl LLVMRef<LLVMExecutionEngineRef> for ExecutionEngine {
    fn to_ref(&self) -> LLVMExecutionEngineRef {
        self.ee
    }
}

impl Drop for ExecutionEngine {
    fn drop(&mut self) {
        unsafe {
            LLVMDisposeExecutionEngine(self.to_ref())
        }
    }
}

pub struct MCJITBuilder {
    options: LLVMMCJITCompilerOptions,
    memory_manager: Option<Box<MCJITMemoryManager>>
}

impl MCJITBuilder {
    pub fn new() -> MCJITBuilder {
        let options = LLVMMCJITCompilerOptions {
            OptLevel: 0,
            CodeModel: LLVMCodeModel::LLVMCodeModelJITDefault,
            NoFramePointerElim: 0,
            EnableFastISel: 0,
            MCJMM: 0 as LLVMMCJITMemoryManagerRef
        };
        MCJITBuilder {options: options, memory_manager: None}
    }

    pub fn set_opt_level(mut self, opt_level: u32) -> Self {
        self.options.OptLevel = opt_level;
        self
    }

    pub fn set_code_model(mut self, code_model: LLVMCodeModel) -> Self {
        self.options.CodeModel = code_model;
        self
    }

    pub fn no_frame_pointer_elim(mut self) -> Self {
        self.options.NoFramePointerElim = 1;
        self
    }

    pub fn enable_fast_isel(mut self) -> Self {
        self.options.EnableFastISel = 1;
        self
    }

    pub fn set_mcjit_memory_manager(mut self, memory_manager: Box<MCJITMemoryManager>) -> Self {
        self.options.MCJMM = memory_manager.to_ref();
        self.memory_manager = Some(memory_manager);
        self
    }

    pub fn create(mut self, mut module: core::Module) -> Result<(ExecutionEngine, FrozenModule), String> {
        let mut ee = 0 as LLVMExecutionEngineRef;
        let mut error = 0 as *mut c_char;
        unsafe {
            module.unown();
            self.memory_manager = self.memory_manager.map(|mut mm| {mm.unown(); mm});
            if LLVMCreateMCJITCompilerForModule(&mut ee,
                                                module.to_ref(),
                                                &mut self.options,
                                                std::mem::size_of::<LLVMMCJITCompilerOptions>() as size_t,
                                                &mut error) > 0 {
                let cstr_buf = std::ffi::CStr::from_ptr(error);
                let result = String::from_utf8_lossy(cstr_buf.to_bytes()).into_owned();
                LLVMDisposeMessage(error);
                Err(result)
            } else {
                match self.memory_manager {
                    Some(memory_manager) => {
                        Ok((ExecutionEngine {ee:ee, _memory_manager: Some(memory_manager)}, FrozenModule {module:module}))
                    }
                    None => Ok((ExecutionEngine {ee:ee, _memory_manager: None}, FrozenModule {module:module}))
                }
            }
        }
    }
}

pub fn link_in_mcjit() {
    unsafe {
        LLVMLinkInMCJIT();
    }
}

pub fn link_in_interpreter() {
    unsafe {
        LLVMLinkInInterpreter();
    }
}
<commit_msg>[execution_engine] use proper options initializing function in MCJITBuilder<commit_after>// Copyright 2015 Jauhien Piatlicki.
//
// 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.

// LLVM Execution Engine
// LLVM-C header ExecutionEngine.h

use std;
use std::ffi::CString;

use libc::{c_char, c_uint, size_t};

use llvm_sys::prelude::*;
use llvm_sys::core::*;
use llvm_sys::execution_engine::*;
use llvm_sys::target_machine::*;

use ::{LLVMRef, LLVMRefCtor};
use core;
use execution_engine::GenericValue;
use execution_engine::MCJITMemoryManager;

pub struct FrozenModule {
    module: core::Module
}

impl FrozenModule {
    pub fn get(&self) -> &core::Module {
        &self.module
    }
}

pub struct ExecutionEngine {
    ee: LLVMExecutionEngineRef,
    _memory_manager: Option<Box<MCJITMemoryManager>>
}

impl ExecutionEngine {
    pub fn new(mut module: core::Module) -> Result<(ExecutionEngine, FrozenModule), String> {
        let mut ee = 0 as LLVMExecutionEngineRef;
        let mut error = 0 as *mut c_char;
        unsafe {
            module.unown();
            if LLVMCreateExecutionEngineForModule(&mut ee, module.to_ref(), &mut error) > 0 {
                let cstr_buf = std::ffi::CStr::from_ptr(error);
                let result = String::from_utf8_lossy(cstr_buf.to_bytes()).into_owned();
                LLVMDisposeMessage(error);
                Err(result)
            } else {
                Ok((ExecutionEngine {ee:ee, _memory_manager: None}, FrozenModule {module:module}))
            }
        }
    }

    pub fn new_interpreter(mut module: core::Module) -> Result<(ExecutionEngine, FrozenModule), String> {
        let mut ee = 0 as LLVMExecutionEngineRef;
        let mut error = 0 as *mut c_char;
        unsafe {
            module.unown();
            if LLVMCreateInterpreterForModule(&mut ee, module.to_ref(), &mut error) > 0 {
                let cstr_buf = std::ffi::CStr::from_ptr(error);
                let result = String::from_utf8_lossy(cstr_buf.to_bytes()).into_owned();
                LLVMDisposeMessage(error);
                Err(result)
            } else {
                Ok((ExecutionEngine {ee:ee, _memory_manager: None}, FrozenModule {module:module}))
            }
        }
    }

    pub fn new_jit_compiler(mut module: core::Module, opt_level: u32) -> Result<(ExecutionEngine, FrozenModule), String> {
        let mut ee = 0 as LLVMExecutionEngineRef;
        let mut error = 0 as *mut c_char;
        unsafe {
            module.unown();
            if LLVMCreateJITCompilerForModule(&mut ee, module.to_ref(), opt_level, &mut error) > 0 {
                let cstr_buf = std::ffi::CStr::from_ptr(error);
                let result = String::from_utf8_lossy(cstr_buf.to_bytes()).into_owned();
                LLVMDisposeMessage(error);
                Err(result)
            } else {
                Ok((ExecutionEngine {ee:ee, _memory_manager: None}, FrozenModule {module:module}))
            }
        }
    }

    pub fn add_module(&mut self, mut module: core::Module) -> FrozenModule {
        unsafe {
            LLVMAddModule(self.to_ref(), module.to_ref());
            module.unown();
        }
        FrozenModule {module: module}
    }

    pub fn remove_module(&mut self, module: FrozenModule) -> Result<core::Module, String> {
        let mut module_ref = 0 as LLVMModuleRef;
        let mut error = 0 as *mut c_char;
        unsafe {
            if LLVMRemoveModule(self.to_ref(), module.get().to_ref(), &mut module_ref, &mut error) > 0 {
                let cstr_buf = std::ffi::CStr::from_ptr(error);
                let result = String::from_utf8_lossy(cstr_buf.to_bytes()).into_owned();
                LLVMDisposeMessage(error);
                Err(result)
            }
            else {
                Ok(core::Module::from_ref(module_ref))
            }
        }
    }

    pub fn run_static_constructors(&mut self) {
        unsafe {
            LLVMRunStaticConstructors(self.to_ref())
        }
    }

    pub fn run_static_destructors(&mut self) {
        unsafe {
            LLVMRunStaticDestructors(self.to_ref())
        }
    }

    pub fn run_function<T:core::Function>(&mut self, f: &T, args: &mut [LLVMGenericValueRef]) -> GenericValue {
        unsafe {
            GenericValue::from_ref(LLVMRunFunction(self.to_ref(), f.to_ref(), args.len() as c_uint, args.as_mut_ptr()))
        }
    }

    pub fn get_function_address(&self, name: &str) -> u64 {
        let name = CString::new(name).unwrap();
        unsafe {
            LLVMGetFunctionAddress(self.to_ref(), name.as_ptr() as *const c_char)
        }
    }
}

impl LLVMRef<LLVMExecutionEngineRef> for ExecutionEngine {
    fn to_ref(&self) -> LLVMExecutionEngineRef {
        self.ee
    }
}

impl Drop for ExecutionEngine {
    fn drop(&mut self) {
        unsafe {
            LLVMDisposeExecutionEngine(self.to_ref())
        }
    }
}

pub struct MCJITBuilder {
    options: LLVMMCJITCompilerOptions,
    memory_manager: Option<Box<MCJITMemoryManager>>
}

impl MCJITBuilder {
    pub fn new() -> MCJITBuilder {
        let mut options;
        unsafe {
            options = std::mem::uninitialized();
            LLVMInitializeMCJITCompilerOptions(&mut options, std::mem::size_of::<LLVMMCJITCompilerOptions>() as size_t);
        }

        MCJITBuilder {options: options, memory_manager: None}
    }

    pub fn set_opt_level(mut self, opt_level: u32) -> Self {
        self.options.OptLevel = opt_level;
        self
    }

    pub fn set_code_model(mut self, code_model: LLVMCodeModel) -> Self {
        self.options.CodeModel = code_model;
        self
    }

    pub fn no_frame_pointer_elim(mut self) -> Self {
        self.options.NoFramePointerElim = 1;
        self
    }

    pub fn enable_fast_isel(mut self) -> Self {
        self.options.EnableFastISel = 1;
        self
    }

    pub fn set_mcjit_memory_manager(mut self, memory_manager: Box<MCJITMemoryManager>) -> Self {
        self.options.MCJMM = memory_manager.to_ref();
        self.memory_manager = Some(memory_manager);
        self
    }

    pub fn create(mut self, mut module: core::Module) -> Result<(ExecutionEngine, FrozenModule), String> {
        let mut ee = 0 as LLVMExecutionEngineRef;
        let mut error = 0 as *mut c_char;
        unsafe {
            module.unown();
            self.memory_manager = self.memory_manager.map(|mut mm| {mm.unown(); mm});
            if LLVMCreateMCJITCompilerForModule(&mut ee,
                                                module.to_ref(),
                                                &mut self.options,
                                                std::mem::size_of::<LLVMMCJITCompilerOptions>() as size_t,
                                                &mut error) > 0 {
                let cstr_buf = std::ffi::CStr::from_ptr(error);
                let result = String::from_utf8_lossy(cstr_buf.to_bytes()).into_owned();
                LLVMDisposeMessage(error);
                Err(result)
            } else {
                match self.memory_manager {
                    Some(memory_manager) => {
                        Ok((ExecutionEngine {ee:ee, _memory_manager: Some(memory_manager)}, FrozenModule {module:module}))
                    }
                    None => Ok((ExecutionEngine {ee:ee, _memory_manager: None}, FrozenModule {module:module}))
                }
            }
        }
    }
}

pub fn link_in_mcjit() {
    unsafe {
        LLVMLinkInMCJIT();
    }
}

pub fn link_in_interpreter() {
    unsafe {
        LLVMLinkInInterpreter();
    }
}
<|endoftext|>