<commit_before>use std::ops::{Neg, Add, AddAssign, Sub, SubAssign, Mul, MulAssign};
use rand::{Rand, Rng};
use serde::{Serialize, Deserialize};

// The field size.
const P: u128 = (1 << 127) - 1;

// A finite field element.
//
// It is consistent iff 0 <= self.0 <= P.
// Note that this implies that the zero element has two internal representations.
#[derive(Clone, Copy, Default, Debug)]
pub struct Fp(u128);

impl Serialize for Fp {
    #[inline]
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ::serde::Serializer
    {
        use serde::ser::SerializeTuple;

        // TODO serde currently does not support u128 natively
        let (h, l) = as_limbs(u128::from(*self));
        let mut tup = serializer.serialize_tuple(2)?;
        tup.serialize_element(&h)?;
        tup.serialize_element(&l)?;
        tup.end()
    }
}

impl<'de> Deserialize<'de> for Fp {
    #[inline]
    fn deserialize<D>(deserializer: D) -> Result<Fp, D::Error>
        where D: ::serde::Deserializer<'de>
    {
        use serde::de;

        // TODO serde currently does not support u128 natively
        struct Visitor;
        impl<'de> ::serde::de::Visitor<'de> for Visitor {
            type Value = Fp;

            fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                formatter.write_str("a pair (h, l) of u64 representing an u128 x = h||l \
                                    such that 0 <= x < p where p = 2**127 - 1")
            }

            fn visit_seq<A>(self, mut a: A) -> Result<Fp, A::Error>
                where A: de::SeqAccess<'de>
            {
                let h: u64 = a.next_element()?.ok_or(de::Error::invalid_length(0, &self))?;
                let l: u64 = a.next_element()?.ok_or(de::Error::invalid_length(1, &self))?;
                let x = ((h as u128) << 64) | (l as u128);
                if x >= P {
                    let unexp_str = format!("the u128 with value {:x}", x);
                    let unexp = de::Unexpected::Other(&unexp_str);
                    return Err(de::Error::invalid_value(unexp, &self));
                }
                Ok(Fp::from_u127(x))
            }
        }

        deserializer.deserialize_tuple(2, Visitor { })
    }
}

#[inline]
fn as_limbs(x: u128) -> (u64, u64) {
    ((x >> 64) as u64, x as u64)
}

trait Reduce: Sized {
    fn reduce_once(self) -> u128;

    #[inline]
    fn reduce_once_assert(self) -> u128 {
        let red: u128 = self.reduce_once();
        debug_assert!(red <= P);
        red
    }
}

impl Reduce for u128 {
    #[inline]
    fn reduce_once(self) -> u128 {
        (self & P) + (self >> 127)
    }
}

impl Reduce for (u128, u128) {
    #[inline]
    fn reduce_once(self) -> u128 {
        let (h, l) = self;
        // shift = (h, l) >> 127
        let shift = (h << 1) | (l >> 127);
        (l & P) + shift
    }
}

impl Fp {
    #[inline]
    pub fn from_u127(x: u128) -> Self {
        // x == P is explicitly allowed.
        // This introduces a negligible bias towards the zero element
        // if x is uniformly random from {0,1}^127.
        debug_assert!(x <= P);
        Fp(x)
    }

    #[inline]
    pub fn from_u128_discard_msb(x: u128) -> Self {
        Self::from_u127(x & P)
    }

    #[inline]
    pub fn prime() -> u128 {
        P
    }
}

impl From<Fp> for u128 {
    #[inline]
    fn from(x: Fp) -> u128 {
        let red = x.0.reduce_once_assert();
        if red == P { 0 } else { red }
    }
}

impl Rand for Fp {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> Self {
        Self::from_u128_discard_msb(rng.gen::<u128>())
    }

}

impl Neg for Fp {
    type Output = Self;
    #[inline]
    fn neg(self) -> Self {
        Fp(P - self.0)
    }
}

impl Add for Fp {
    type Output = Self;
    #[inline]
    fn add(self, other: Self) -> Self {
        Fp((self.0 + other.0).reduce_once_assert())
    }
}

impl AddAssign for Fp {
    #[inline]
    fn add_assign(&mut self, other: Self) {
        *self = *self + other
    }
}

impl Sub for Fp {
    type Output = Self;
    #[inline]
    fn sub(self, other: Self) -> Self {
        self + (-other)
    }
}

impl SubAssign for Fp {
    #[inline]
    fn sub_assign(&mut self, other: Self) {
        *self = *self - other
    }
}

impl Mul for Fp {
    type Output = Self;
    #[inline]
    fn mul(self, other: Self) -> Self {
        let (sh, sl) = as_limbs(self.0);
        let (oh, ol) = as_limbs(other.0);

        // (64 bits * 63 bits) + (64 bits * 63 bits) = 128 bits
        let m: u128 = (sh as u128 * ol as u128) + (oh as u128 * sl as u128);
        let (mh, ml) = as_limbs(m);

        // (64 bits * 64 bits) + 128 bits = 129 bits
        let (rl, carry) = (sl as u128 * ol as u128).overflowing_add((ml as u128) << 64);

        // (63 bits * 63 bits) + 64 bits + 1 bit = 127 bits
        let rh: u128 = (sh as u128 * oh as u128) + (mh as u128) + (carry as u128);

        Fp((rh, rl).reduce_once().reduce_once_assert())
    }
}

impl MulAssign for Fp {
    #[inline]
    fn mul_assign(&mut self, other: Self) {
        *self = *self * other
    }
}

impl PartialEq for Fp {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        u128::from(*self) == u128::from(*other)
    }
}

impl Eq for Fp {}

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

    #[test]
    fn neg() {
        assert_eq!(-Fp(0), Fp(0));
        assert_eq!(-Fp(5), Fp(P - 5));
    }

    #[test]
    fn add() {
        assert_eq!(Fp(7) + Fp(5), Fp(12));
        assert_eq!(Fp(P - 2) + Fp(5), Fp(3));
        assert_eq!(
            Fp(75661398932549814984099328258351945610) + Fp(154440289138086217180118920884960981429),
            Fp(59960504610166800432530945427428821312)
        );
    }

    #[test]
    fn sub() {
        assert_eq!(Fp(7) - Fp(5), Fp(2));
        assert_eq!(Fp(4) - Fp(8), Fp(P - 4));
    }

    #[test]
    fn mul() {
        assert_eq!(Fp(4) * Fp(3), Fp(12));
        assert_eq!(Fp(P) * Fp(291298091), Fp(0));
        assert_eq!(
            Fp(14766549069271113692204649107775507741) * Fp(153613967287097206589234951623852979690),
            Fp(113548737858505840193892055835373785352)
        );
        // Two reductions are necessary for the following example.
        assert_eq!(
            Fp(75661398932549814984099328258351945610) * Fp(154440289138086217180118920884960981429),
            Fp(109146875586984049909139102289297416971)
        );
    }

    #[test]
    fn eq() {
        assert_eq!(Fp(0), Fp(P));
        assert!(Fp(17) != Fp(4));
        assert!(Fp(0) != Fp(4));
        assert!(Fp(P) != Fp(17));
    }

    #[test]
    fn assign() {
        let mut a = Fp(17);

        a += Fp(3);
        assert_eq!(a, Fp(20));

        a -= Fp(5);
        assert_eq!(a, Fp(15));

        a *= Fp(2);
        assert_eq!(a, Fp(30));
    }
}
<commit_msg>Implement Ord for Fp<commit_after>use std::ops::{Neg, Add, AddAssign, Sub, SubAssign, Mul, MulAssign};
use std::cmp::Ordering;
use rand::{Rand, Rng};
use serde::{Serialize, Deserialize};

// The field size.
const P: u128 = (1 << 127) - 1;

// A finite field element.
//
// It is consistent iff 0 <= self.0 <= P.
// Note that this implies that the zero element has two internal representations.
#[derive(Clone, Copy, Default, Debug)]
pub struct Fp(u128);

impl Serialize for Fp {
    #[inline]
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ::serde::Serializer
    {
        use serde::ser::SerializeTuple;

        // TODO serde currently does not support u128 natively
        let (h, l) = as_limbs(u128::from(*self));
        let mut tup = serializer.serialize_tuple(2)?;
        tup.serialize_element(&h)?;
        tup.serialize_element(&l)?;
        tup.end()
    }
}

impl<'de> Deserialize<'de> for Fp {
    #[inline]
    fn deserialize<D>(deserializer: D) -> Result<Fp, D::Error>
        where D: ::serde::Deserializer<'de>
    {
        use serde::de;

        // TODO serde currently does not support u128 natively
        struct Visitor;
        impl<'de> ::serde::de::Visitor<'de> for Visitor {
            type Value = Fp;

            fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                formatter.write_str("a pair (h, l) of u64 representing an u128 x = h||l \
                                    such that 0 <= x < p where p = 2**127 - 1")
            }

            fn visit_seq<A>(self, mut a: A) -> Result<Fp, A::Error>
                where A: de::SeqAccess<'de>
            {
                let h: u64 = a.next_element()?.ok_or(de::Error::invalid_length(0, &self))?;
                let l: u64 = a.next_element()?.ok_or(de::Error::invalid_length(1, &self))?;
                let x = ((h as u128) << 64) | (l as u128);
                if x >= P {
                    let unexp_str = format!("the u128 with value {:x}", x);
                    let unexp = de::Unexpected::Other(&unexp_str);
                    return Err(de::Error::invalid_value(unexp, &self));
                }
                Ok(Fp::from_u127(x))
            }
        }

        deserializer.deserialize_tuple(2, Visitor { })
    }
}

#[inline]
fn as_limbs(x: u128) -> (u64, u64) {
    ((x >> 64) as u64, x as u64)
}

trait Reduce: Sized {
    fn reduce_once(self) -> u128;

    #[inline]
    fn reduce_once_assert(self) -> u128 {
        let red: u128 = self.reduce_once();
        debug_assert!(red <= P);
        red
    }
}

impl Reduce for u128 {
    #[inline]
    fn reduce_once(self) -> u128 {
        (self & P) + (self >> 127)
    }
}

impl Reduce for (u128, u128) {
    #[inline]
    fn reduce_once(self) -> u128 {
        let (h, l) = self;
        // shift = (h, l) >> 127
        let shift = (h << 1) | (l >> 127);
        (l & P) + shift
    }
}

impl Fp {
    #[inline]
    pub fn from_u127(x: u128) -> Self {
        // x == P is explicitly allowed.
        // This introduces a negligible bias towards the zero element
        // if x is uniformly random from {0,1}^127.
        debug_assert!(x <= P);
        Fp(x)
    }

    #[inline]
    pub fn from_u128_discard_msb(x: u128) -> Self {
        Self::from_u127(x & P)
    }

    #[inline]
    pub fn prime() -> u128 {
        P
    }
}

impl From<Fp> for u128 {
    #[inline]
    fn from(x: Fp) -> u128 {
        let red = x.0.reduce_once_assert();
        if red == P { 0 } else { red }
    }
}

impl Rand for Fp {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> Self {
        Self::from_u128_discard_msb(rng.gen::<u128>())
    }

}

impl Neg for Fp {
    type Output = Self;
    #[inline]
    fn neg(self) -> Self {
        Fp(P - self.0)
    }
}

impl Add for Fp {
    type Output = Self;
    #[inline]
    fn add(self, other: Self) -> Self {
        Fp((self.0 + other.0).reduce_once_assert())
    }
}

impl AddAssign for Fp {
    #[inline]
    fn add_assign(&mut self, other: Self) {
        *self = *self + other
    }
}

impl Sub for Fp {
    type Output = Self;
    #[inline]
    fn sub(self, other: Self) -> Self {
        self + (-other)
    }
}

impl SubAssign for Fp {
    #[inline]
    fn sub_assign(&mut self, other: Self) {
        *self = *self - other
    }
}

impl Mul for Fp {
    type Output = Self;
    #[inline]
    fn mul(self, other: Self) -> Self {
        let (sh, sl) = as_limbs(self.0);
        let (oh, ol) = as_limbs(other.0);

        // (64 bits * 63 bits) + (64 bits * 63 bits) = 128 bits
        let m: u128 = (sh as u128 * ol as u128) + (oh as u128 * sl as u128);
        let (mh, ml) = as_limbs(m);

        // (64 bits * 64 bits) + 128 bits = 129 bits
        let (rl, carry) = (sl as u128 * ol as u128).overflowing_add((ml as u128) << 64);

        // (63 bits * 63 bits) + 64 bits + 1 bit = 127 bits
        let rh: u128 = (sh as u128 * oh as u128) + (mh as u128) + (carry as u128);

        Fp((rh, rl).reduce_once().reduce_once_assert())
    }
}

impl MulAssign for Fp {
    #[inline]
    fn mul_assign(&mut self, other: Self) {
        *self = *self * other
    }
}

impl PartialEq for Fp {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        u128::from(*self) == u128::from(*other)
    }
}

impl Eq for Fp {}

impl PartialOrd for Fp {
    #[inline]
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        u128::from(*self).partial_cmp(&u128::from(*other))
    }
}

impl Ord for Fp {
    #[inline]
    fn cmp(&self, other: &Self) -> Ordering {
        self.partial_cmp(&other).unwrap()
    }
}

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

    #[test]
    fn neg() {
        assert_eq!(-Fp(0), Fp(0));
        assert_eq!(-Fp(5), Fp(P - 5));
    }

    #[test]
    fn add() {
        assert_eq!(Fp(7) + Fp(5), Fp(12));
        assert_eq!(Fp(P - 2) + Fp(5), Fp(3));
        assert_eq!(
            Fp(75661398932549814984099328258351945610) + Fp(154440289138086217180118920884960981429),
            Fp(59960504610166800432530945427428821312)
        );
    }

    #[test]
    fn sub() {
        assert_eq!(Fp(7) - Fp(5), Fp(2));
        assert_eq!(Fp(4) - Fp(8), Fp(P - 4));
    }

    #[test]
    fn mul() {
        assert_eq!(Fp(4) * Fp(3), Fp(12));
        assert_eq!(Fp(P) * Fp(291298091), Fp(0));
        assert_eq!(
            Fp(14766549069271113692204649107775507741) * Fp(153613967287097206589234951623852979690),
            Fp(113548737858505840193892055835373785352)
        );
        // Two reductions are necessary for the following example.
        assert_eq!(
            Fp(75661398932549814984099328258351945610) * Fp(154440289138086217180118920884960981429),
            Fp(109146875586984049909139102289297416971)
        );
    }

    #[test]
    fn eq() {
        assert_eq!(Fp(0), Fp(P));
        assert!(Fp(17) != Fp(4));
        assert!(Fp(0) != Fp(4));
        assert!(Fp(P) != Fp(17));
    }

    #[test]
    fn assign() {
        let mut a = Fp(17);

        a += Fp(3);
        assert_eq!(a, Fp(20));

        a -= Fp(5);
        assert_eq!(a, Fp(15));

        a *= Fp(2);
        assert_eq!(a, Fp(30));
    }
}
<|endoftext|>


<commit_before>use crate::backtrace::Backtrace;
use crate::context::ContextError;
use std::any::TypeId;
use std::error::Error as StdError;
use std::fmt::{self, Debug, Display};
use std::mem;
use std::ops::{Deref, DerefMut};
use std::ptr;

/// The `Error` type, a wrapper around a dynamic error type.
///
/// `Error` works a lot like `Box<dyn std::error::Error>`, but with these
/// differences:
///
/// - `Error` requires that the error is `Send`, `Sync`, and `'static`.
/// - `Error` guarantees that a backtrace is available, even if the underlying
///   error type does not provide one.
/// - `Error` is represented as a narrow pointer — exactly one word in
///   size instead of two.
pub struct Error {
    inner: Box<ErrorImpl<()>>,
}

impl Error {
    /// Create a new error object from any error type.
    ///
    /// The error type must be threadsafe and `'static`, so that the `Error`
    /// will be as well.
    ///
    /// If the error type does not provide a backtrace, a backtrace will be
    /// created here to ensure that a backtrace exists.
    pub fn new<E>(error: E) -> Self
    where
        E: StdError + Send + Sync + 'static,
    {
        let backtrace = backtrace_if_absent!(error);
        Error::construct(error, TypeId::of::<E>(), backtrace)
    }

    pub(crate) fn new_adhoc<M>(message: M, backtrace: Option<Backtrace>) -> Self
    where
        M: Display + Debug + Send + Sync + 'static,
    {
        Error::construct(MessageError(message), TypeId::of::<M>(), backtrace)
    }

    // Takes backtrace as argument rather than capturing it here so that the
    // user sees one fewer layer of wrapping noise in the backtrace.
    fn construct<E>(error: E, type_id: TypeId, backtrace: Option<Backtrace>) -> Self
    where
        E: StdError + Send + Sync + 'static,
    {
        unsafe {
            let vtable = &ErrorVTable {
                object: object_raw::<E>,
                object_mut: object_mut_raw::<E>,
            };
            let inner = Box::new(ErrorImpl {
                vtable,
                type_id,
                backtrace,
                error,
            });
            Error {
                inner: mem::transmute::<Box<ErrorImpl<E>>, Box<ErrorImpl<()>>>(inner),
            }
        }
    }

    /// Wrap the error value with additional context.
    ///
    /// For attaching context to a `Result` as it is propagated, the
    /// [`Context`][crate::Context] extension trait may be more convenient than
    /// this function.
    ///
    /// The primary reason to use `error.context(...)` instead of
    /// `result.context(...)` via the `Context` trait would be if the context
    /// needs to depend on some data held by the underlying error:
    ///
    /// ```
    /// # use std::fmt::{self, Debug, Display};
    /// #
    /// # type T = ();
    /// #
    /// # impl std::error::Error for ParseError {}
    /// # impl Debug for ParseError {
    /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
    /// #         unimplemented!()
    /// #     }
    /// # }
    /// # impl Display for ParseError {
    /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
    /// #         unimplemented!()
    /// #     }
    /// # }
    /// #
    /// use std::fs::File;
    /// use std::path::Path;
    ///
    /// struct ParseError {
    ///     line: usize,
    ///     column: usize,
    /// }
    ///
    /// fn parse_impl(file: File) -> Result<T, ParseError> {
    ///     # const IGNORE: &str = stringify! {
    ///     ...
    ///     # };
    ///     # unimplemented!()
    /// }
    ///
    /// pub fn parse(path: impl AsRef<Path>) -> anyhow::Result<T> {
    ///     let file = File::open(&path)?;
    ///     parse_impl(file).map_err(|error| {
    ///         let context = format!(
    ///             "only the first {} lines of {} are valid",
    ///             error.line, path.as_ref().display(),
    ///         );
    ///         anyhow::Error::new(error).context(context)
    ///     })
    /// }
    /// ```
    pub fn context<C>(self, context: C) -> Self
    where
        C: Display + Send + Sync + 'static,
    {
        Error::new(ContextError {
            error: self,
            context,
        })
    }

    /// Get the backtrace for this Error.
    ///
    /// Backtraces are only available on the nightly channel. Tracking issue:
    /// [rust-lang/rust#53487][tracking].
    ///
    /// In order for the backtrace to be meaningful, the environment variable
    /// `RUST_LIB_BACKTRACE=1` must be defined. Backtraces are somewhat
    /// expensive to capture in Rust, so we don't necessarily want to be
    /// capturing them all over the place all the time.
    ///
    /// [tracking]: https://github.com/rust-lang/rust/issues/53487
    #[cfg(backtrace)]
    pub fn backtrace(&self) -> &Backtrace {
        // NB: this unwrap can only fail if the underlying error's backtrace
        // method is nondeterministic, which would only happen in maliciously
        // constructed code
        self.inner
            .backtrace
            .as_ref()
            .or_else(|| self.inner.error().backtrace())
            .expect("backtrace capture failed")
    }

    /// An iterator of the chain of source errors contained by this Error.
    ///
    /// This iterator will visit every error in the cause chain of this error
    /// object, beginning with the error that this error object was created
    /// from.
    ///
    /// # Example
    ///
    /// ```
    /// use anyhow::Error;
    /// use std::io;
    ///
    /// pub fn underlying_io_error_kind(error: &Error) -> Option<io::ErrorKind> {
    ///     for cause in error.chain() {
    ///         if let Some(io_error) = cause.downcast_ref::<io::Error>() {
    ///             return Some(io_error.kind());
    ///         }
    ///     }
    ///     None
    /// }
    /// ```
    pub fn chain(&self) -> Chain {
        Chain {
            next: Some(self.inner.error()),
        }
    }

    /// The lowest level cause of this error — this error's cause's
    /// cause's cause etc.
    ///
    /// The root cause is the last error in the iterator produced by
    /// [`chain()`][Error::chain].
    pub fn root_cause(&self) -> &(dyn StdError + 'static) {
        let mut chain = self.chain();
        let mut root_cause = chain.next().unwrap();
        for cause in chain {
            root_cause = cause;
        }
        root_cause
    }

    /// Returns `true` if `E` is the type wrapped by this error object.
    pub fn is<E>(&self) -> bool
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        TypeId::of::<E>() == self.inner.type_id
    }

    /// Attempt to downcast the error object to a concrete type.
    pub fn downcast<E>(self) -> Result<E, Self>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if let Some(error) = self.downcast_ref::<E>() {
            unsafe {
                let error = ptr::read(error);
                drop(ptr::read(&self.inner));
                mem::forget(self);
                Ok(error)
            }
        } else {
            Err(self)
        }
    }

    /// Downcast this error object by reference.
    ///
    /// # Example
    ///
    /// ```
    /// # use anyhow::anyhow;
    /// # use std::fmt::{self, Display};
    /// # use std::task::Poll;
    /// #
    /// # #[derive(Debug)]
    /// # enum DataStoreError {
    /// #     Censored(()),
    /// # }
    /// #
    /// # impl Display for DataStoreError {
    /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
    /// #         unimplemented!()
    /// #     }
    /// # }
    /// #
    /// # impl std::error::Error for DataStoreError {}
    /// #
    /// # const REDACTED_CONTENT: () = ();
    /// #
    /// # let error = anyhow!("...");
    /// # let root_cause = &error;
    /// #
    /// # let ret =
    /// // If the error was caused by redaction, then return a tombstone instead
    /// // of the content.
    /// match root_cause.downcast_ref::<DataStoreError>() {
    ///     Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
    ///     None => Err(error),
    /// }
    /// # ;
    /// ```
    pub fn downcast_ref<E>(&self) -> Option<&E>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if self.is::<E>() {
            unsafe { Some(&*(self.inner.error() as *const dyn StdError as *const E)) }
        } else {
            None
        }
    }

    /// Downcast this error object by mutable reference.
    pub fn downcast_mut<E>(&mut self) -> Option<&mut E>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if self.is::<E>() {
            unsafe { Some(&mut *(self.inner.error_mut() as *mut dyn StdError as *mut E)) }
        } else {
            None
        }
    }
}

impl<E> From<E> for Error
where
    E: StdError + Send + Sync + 'static,
{
    fn from(error: E) -> Self {
        Error::new(error)
    }
}

impl Deref for Error {
    type Target = dyn StdError + Send + Sync + 'static;

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

impl DerefMut for Error {
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.inner.error_mut()
    }
}

impl Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        writeln!(f, "{}", self.inner.error())?;

        let mut chain = self.chain().skip(1).enumerate().peekable();
        if let Some((n, error)) = chain.next() {
            write!(f, "\nCaused by:\n    ")?;
            if chain.peek().is_some() {
                write!(f, "{}: ", n)?;
            }
            writeln!(f, "{}", error)?;
            for (n, error) in chain {
                writeln!(f, "    {}: {}", n, error)?;
            }
        }

        #[cfg(backtrace)]
        {
            use std::backtrace::BacktraceStatus;

            let backtrace = self.backtrace();
            match backtrace.status() {
                BacktraceStatus::Captured => {
                    writeln!(f, "\n{}", backtrace)?;
                }
                BacktraceStatus::Disabled => {
                    writeln!(
                        f,
                        "\nBacktrace disabled; run with RUST_LIB_BACKTRACE=1 environment variable to display a backtrace"
                    )?;
                }
                _ => {}
            }
        }

        Ok(())
    }
}

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.inner.error())
    }
}

unsafe impl Send for Error {}
unsafe impl Sync for Error {}

impl Drop for Error {
    fn drop(&mut self) {
        unsafe { ptr::drop_in_place(self.inner.error_mut()) }
    }
}

struct ErrorVTable {
    object: unsafe fn(*const ()) -> *const (dyn StdError + Send + Sync + 'static),
    object_mut: unsafe fn(*mut ()) -> *mut (dyn StdError + Send + Sync + 'static),
}

unsafe fn object_raw<E>(e: *const ()) -> *const (dyn StdError + Send + Sync + 'static)
where
    E: StdError + Send + Sync + 'static,
{
    e as *const E
}

unsafe fn object_mut_raw<E>(e: *mut ()) -> *mut (dyn StdError + Send + Sync + 'static)
where
    E: StdError + Send + Sync + 'static,
{
    e as *mut E
}

// repr C to ensure that `E` remains in the final position
#[repr(C)]
struct ErrorImpl<E> {
    vtable: &'static ErrorVTable,
    type_id: TypeId,
    backtrace: Option<Backtrace>,
    error: E,
}

#[repr(transparent)]
struct MessageError<M>(M);

impl<M> Debug for MessageError<M>
where
    M: Display + Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(&self.0, f)
    }
}

impl<M> Display for MessageError<M>
where
    M: Display + Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Display::fmt(&self.0, f)
    }
}

impl<M> StdError for MessageError<M> where M: Display + Debug + 'static {}

impl ErrorImpl<()> {
    fn error(&self) -> &(dyn StdError + Send + Sync + 'static) {
        unsafe { &*(self.vtable.object)(&self.error) }
    }

    fn error_mut(&mut self) -> &mut (dyn StdError + Send + Sync + 'static) {
        unsafe { &mut *(self.vtable.object_mut)(&mut self.error) }
    }
}

/// Iterator of a chain of source errors.
///
/// This type is the iterator returned by [`Error::chain`].
///
/// # Example
///
/// ```
/// use anyhow::Error;
/// use std::io;
///
/// pub fn underlying_io_error_kind(error: &Error) -> Option<io::ErrorKind> {
///     for cause in error.chain() {
///         if let Some(io_error) = cause.downcast_ref::<io::Error>() {
///             return Some(io_error.kind());
///         }
///     }
///     None
/// }
/// ```
pub struct Chain<'a> {
    next: Option<&'a (dyn StdError + 'static)>,
}

impl<'a> Iterator for Chain<'a> {
    type Item = &'a (dyn StdError + 'static);

    fn next(&mut self) -> Option<Self::Item> {
        let next = self.next.take()?;
        self.next = next.source();
        Some(next)
    }
}

#[cfg(test)]
mod repr_correctness {
    use super::*;
    use std::marker::Unpin;
    use std::mem;
    use std::sync::atomic::AtomicBool;
    use std::sync::atomic::Ordering::SeqCst;
    use std::sync::Arc;

    #[test]
    fn size_of_error() {
        assert_eq!(mem::size_of::<Error>(), mem::size_of::<usize>());
    }

    #[test]
    fn error_autotraits() {
        fn assert<E: Unpin + Send + Sync + 'static>() {}
        assert::<Error>();
    }

    #[test]
    fn drop_works() {
        #[derive(Debug)]
        struct DetectDrop {
            has_dropped: Arc<AtomicBool>,
        }

        impl StdError for DetectDrop {}

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

        impl Drop for DetectDrop {
            fn drop(&mut self) {
                let already_dropped = self.has_dropped.swap(true, SeqCst);
                assert!(!already_dropped);
            }
        }

        let has_dropped = Arc::new(AtomicBool::new(false));

        drop(Error::new(DetectDrop {
            has_dropped: has_dropped.clone(),
        }));

        assert!(has_dropped.load(SeqCst));
    }
}
<commit_msg>Change Error::construct to unsafe fn because TypeId must be correct<commit_after>use crate::backtrace::Backtrace;
use crate::context::ContextError;
use std::any::TypeId;
use std::error::Error as StdError;
use std::fmt::{self, Debug, Display};
use std::mem;
use std::ops::{Deref, DerefMut};
use std::ptr;

/// The `Error` type, a wrapper around a dynamic error type.
///
/// `Error` works a lot like `Box<dyn std::error::Error>`, but with these
/// differences:
///
/// - `Error` requires that the error is `Send`, `Sync`, and `'static`.
/// - `Error` guarantees that a backtrace is available, even if the underlying
///   error type does not provide one.
/// - `Error` is represented as a narrow pointer — exactly one word in
///   size instead of two.
pub struct Error {
    inner: Box<ErrorImpl<()>>,
}

impl Error {
    /// Create a new error object from any error type.
    ///
    /// The error type must be threadsafe and `'static`, so that the `Error`
    /// will be as well.
    ///
    /// If the error type does not provide a backtrace, a backtrace will be
    /// created here to ensure that a backtrace exists.
    pub fn new<E>(error: E) -> Self
    where
        E: StdError + Send + Sync + 'static,
    {
        let type_id = TypeId::of::<E>();
        let backtrace = backtrace_if_absent!(error);

        // Safety: passing typeid of the right type E.
        unsafe {
            Error::construct(error, type_id, backtrace)
        }
    }

    pub(crate) fn new_adhoc<M>(message: M, backtrace: Option<Backtrace>) -> Self
    where
        M: Display + Debug + Send + Sync + 'static,
    {
        let error = MessageError(message);
        let type_id = TypeId::of::<M>();

        // Safety: MessageError is repr(transparent) so MessageError<M> has the
        // same layout as the typeid specifies.
        unsafe {
            Error::construct(error, type_id, backtrace)
        }
    }

    // Takes backtrace as argument rather than capturing it here so that the
    // user sees one fewer layer of wrapping noise in the backtrace.
    //
    // Unsafe because the type represented by type_id must have the same layout
    // as E or else we allow invalid downcasts.
    unsafe fn construct<E>(error: E, type_id: TypeId, backtrace: Option<Backtrace>) -> Self
    where
        E: StdError + Send + Sync + 'static,
    {
        let vtable = &ErrorVTable {
            object: object_raw::<E>,
            object_mut: object_mut_raw::<E>,
        };
        let inner = Box::new(ErrorImpl {
            vtable,
            type_id,
            backtrace,
            error,
        });
        Error {
            inner: mem::transmute::<Box<ErrorImpl<E>>, Box<ErrorImpl<()>>>(inner),
        }
    }

    /// Wrap the error value with additional context.
    ///
    /// For attaching context to a `Result` as it is propagated, the
    /// [`Context`][crate::Context] extension trait may be more convenient than
    /// this function.
    ///
    /// The primary reason to use `error.context(...)` instead of
    /// `result.context(...)` via the `Context` trait would be if the context
    /// needs to depend on some data held by the underlying error:
    ///
    /// ```
    /// # use std::fmt::{self, Debug, Display};
    /// #
    /// # type T = ();
    /// #
    /// # impl std::error::Error for ParseError {}
    /// # impl Debug for ParseError {
    /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
    /// #         unimplemented!()
    /// #     }
    /// # }
    /// # impl Display for ParseError {
    /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
    /// #         unimplemented!()
    /// #     }
    /// # }
    /// #
    /// use std::fs::File;
    /// use std::path::Path;
    ///
    /// struct ParseError {
    ///     line: usize,
    ///     column: usize,
    /// }
    ///
    /// fn parse_impl(file: File) -> Result<T, ParseError> {
    ///     # const IGNORE: &str = stringify! {
    ///     ...
    ///     # };
    ///     # unimplemented!()
    /// }
    ///
    /// pub fn parse(path: impl AsRef<Path>) -> anyhow::Result<T> {
    ///     let file = File::open(&path)?;
    ///     parse_impl(file).map_err(|error| {
    ///         let context = format!(
    ///             "only the first {} lines of {} are valid",
    ///             error.line, path.as_ref().display(),
    ///         );
    ///         anyhow::Error::new(error).context(context)
    ///     })
    /// }
    /// ```
    pub fn context<C>(self, context: C) -> Self
    where
        C: Display + Send + Sync + 'static,
    {
        Error::new(ContextError {
            error: self,
            context,
        })
    }

    /// Get the backtrace for this Error.
    ///
    /// Backtraces are only available on the nightly channel. Tracking issue:
    /// [rust-lang/rust#53487][tracking].
    ///
    /// In order for the backtrace to be meaningful, the environment variable
    /// `RUST_LIB_BACKTRACE=1` must be defined. Backtraces are somewhat
    /// expensive to capture in Rust, so we don't necessarily want to be
    /// capturing them all over the place all the time.
    ///
    /// [tracking]: https://github.com/rust-lang/rust/issues/53487
    #[cfg(backtrace)]
    pub fn backtrace(&self) -> &Backtrace {
        // NB: this unwrap can only fail if the underlying error's backtrace
        // method is nondeterministic, which would only happen in maliciously
        // constructed code
        self.inner
            .backtrace
            .as_ref()
            .or_else(|| self.inner.error().backtrace())
            .expect("backtrace capture failed")
    }

    /// An iterator of the chain of source errors contained by this Error.
    ///
    /// This iterator will visit every error in the cause chain of this error
    /// object, beginning with the error that this error object was created
    /// from.
    ///
    /// # Example
    ///
    /// ```
    /// use anyhow::Error;
    /// use std::io;
    ///
    /// pub fn underlying_io_error_kind(error: &Error) -> Option<io::ErrorKind> {
    ///     for cause in error.chain() {
    ///         if let Some(io_error) = cause.downcast_ref::<io::Error>() {
    ///             return Some(io_error.kind());
    ///         }
    ///     }
    ///     None
    /// }
    /// ```
    pub fn chain(&self) -> Chain {
        Chain {
            next: Some(self.inner.error()),
        }
    }

    /// The lowest level cause of this error — this error's cause's
    /// cause's cause etc.
    ///
    /// The root cause is the last error in the iterator produced by
    /// [`chain()`][Error::chain].
    pub fn root_cause(&self) -> &(dyn StdError + 'static) {
        let mut chain = self.chain();
        let mut root_cause = chain.next().unwrap();
        for cause in chain {
            root_cause = cause;
        }
        root_cause
    }

    /// Returns `true` if `E` is the type wrapped by this error object.
    pub fn is<E>(&self) -> bool
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        TypeId::of::<E>() == self.inner.type_id
    }

    /// Attempt to downcast the error object to a concrete type.
    pub fn downcast<E>(self) -> Result<E, Self>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if let Some(error) = self.downcast_ref::<E>() {
            unsafe {
                let error = ptr::read(error);
                drop(ptr::read(&self.inner));
                mem::forget(self);
                Ok(error)
            }
        } else {
            Err(self)
        }
    }

    /// Downcast this error object by reference.
    ///
    /// # Example
    ///
    /// ```
    /// # use anyhow::anyhow;
    /// # use std::fmt::{self, Display};
    /// # use std::task::Poll;
    /// #
    /// # #[derive(Debug)]
    /// # enum DataStoreError {
    /// #     Censored(()),
    /// # }
    /// #
    /// # impl Display for DataStoreError {
    /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
    /// #         unimplemented!()
    /// #     }
    /// # }
    /// #
    /// # impl std::error::Error for DataStoreError {}
    /// #
    /// # const REDACTED_CONTENT: () = ();
    /// #
    /// # let error = anyhow!("...");
    /// # let root_cause = &error;
    /// #
    /// # let ret =
    /// // If the error was caused by redaction, then return a tombstone instead
    /// // of the content.
    /// match root_cause.downcast_ref::<DataStoreError>() {
    ///     Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
    ///     None => Err(error),
    /// }
    /// # ;
    /// ```
    pub fn downcast_ref<E>(&self) -> Option<&E>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if self.is::<E>() {
            unsafe { Some(&*(self.inner.error() as *const dyn StdError as *const E)) }
        } else {
            None
        }
    }

    /// Downcast this error object by mutable reference.
    pub fn downcast_mut<E>(&mut self) -> Option<&mut E>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if self.is::<E>() {
            unsafe { Some(&mut *(self.inner.error_mut() as *mut dyn StdError as *mut E)) }
        } else {
            None
        }
    }
}

impl<E> From<E> for Error
where
    E: StdError + Send + Sync + 'static,
{
    fn from(error: E) -> Self {
        Error::new(error)
    }
}

impl Deref for Error {
    type Target = dyn StdError + Send + Sync + 'static;

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

impl DerefMut for Error {
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.inner.error_mut()
    }
}

impl Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        writeln!(f, "{}", self.inner.error())?;

        let mut chain = self.chain().skip(1).enumerate().peekable();
        if let Some((n, error)) = chain.next() {
            write!(f, "\nCaused by:\n    ")?;
            if chain.peek().is_some() {
                write!(f, "{}: ", n)?;
            }
            writeln!(f, "{}", error)?;
            for (n, error) in chain {
                writeln!(f, "    {}: {}", n, error)?;
            }
        }

        #[cfg(backtrace)]
        {
            use std::backtrace::BacktraceStatus;

            let backtrace = self.backtrace();
            match backtrace.status() {
                BacktraceStatus::Captured => {
                    writeln!(f, "\n{}", backtrace)?;
                }
                BacktraceStatus::Disabled => {
                    writeln!(
                        f,
                        "\nBacktrace disabled; run with RUST_LIB_BACKTRACE=1 environment variable to display a backtrace"
                    )?;
                }
                _ => {}
            }
        }

        Ok(())
    }
}

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.inner.error())
    }
}

unsafe impl Send for Error {}
unsafe impl Sync for Error {}

impl Drop for Error {
    fn drop(&mut self) {
        unsafe { ptr::drop_in_place(self.inner.error_mut()) }
    }
}

struct ErrorVTable {
    object: unsafe fn(*const ()) -> *const (dyn StdError + Send + Sync + 'static),
    object_mut: unsafe fn(*mut ()) -> *mut (dyn StdError + Send + Sync + 'static),
}

unsafe fn object_raw<E>(e: *const ()) -> *const (dyn StdError + Send + Sync + 'static)
where
    E: StdError + Send + Sync + 'static,
{
    e as *const E
}

unsafe fn object_mut_raw<E>(e: *mut ()) -> *mut (dyn StdError + Send + Sync + 'static)
where
    E: StdError + Send + Sync + 'static,
{
    e as *mut E
}

// repr C to ensure that `E` remains in the final position
#[repr(C)]
struct ErrorImpl<E> {
    vtable: &'static ErrorVTable,
    type_id: TypeId,
    backtrace: Option<Backtrace>,
    error: E,
}

#[repr(transparent)]
struct MessageError<M>(M);

impl<M> Debug for MessageError<M>
where
    M: Display + Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(&self.0, f)
    }
}

impl<M> Display for MessageError<M>
where
    M: Display + Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Display::fmt(&self.0, f)
    }
}

impl<M> StdError for MessageError<M> where M: Display + Debug + 'static {}

impl ErrorImpl<()> {
    fn error(&self) -> &(dyn StdError + Send + Sync + 'static) {
        unsafe { &*(self.vtable.object)(&self.error) }
    }

    fn error_mut(&mut self) -> &mut (dyn StdError + Send + Sync + 'static) {
        unsafe { &mut *(self.vtable.object_mut)(&mut self.error) }
    }
}

/// Iterator of a chain of source errors.
///
/// This type is the iterator returned by [`Error::chain`].
///
/// # Example
///
/// ```
/// use anyhow::Error;
/// use std::io;
///
/// pub fn underlying_io_error_kind(error: &Error) -> Option<io::ErrorKind> {
///     for cause in error.chain() {
///         if let Some(io_error) = cause.downcast_ref::<io::Error>() {
///             return Some(io_error.kind());
///         }
///     }
///     None
/// }
/// ```
pub struct Chain<'a> {
    next: Option<&'a (dyn StdError + 'static)>,
}

impl<'a> Iterator for Chain<'a> {
    type Item = &'a (dyn StdError + 'static);

    fn next(&mut self) -> Option<Self::Item> {
        let next = self.next.take()?;
        self.next = next.source();
        Some(next)
    }
}

#[cfg(test)]
mod repr_correctness {
    use super::*;
    use std::marker::Unpin;
    use std::mem;
    use std::sync::atomic::AtomicBool;
    use std::sync::atomic::Ordering::SeqCst;
    use std::sync::Arc;

    #[test]
    fn size_of_error() {
        assert_eq!(mem::size_of::<Error>(), mem::size_of::<usize>());
    }

    #[test]
    fn error_autotraits() {
        fn assert<E: Unpin + Send + Sync + 'static>() {}
        assert::<Error>();
    }

    #[test]
    fn drop_works() {
        #[derive(Debug)]
        struct DetectDrop {
            has_dropped: Arc<AtomicBool>,
        }

        impl StdError for DetectDrop {}

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

        impl Drop for DetectDrop {
            fn drop(&mut self) {
                let already_dropped = self.has_dropped.swap(true, SeqCst);
                assert!(!already_dropped);
            }
        }

        let has_dropped = Arc::new(AtomicBool::new(false));

        drop(Error::new(DetectDrop {
            has_dropped: has_dropped.clone(),
        }));

        assert!(has_dropped.load(SeqCst));
    }
}
<|endoftext|>


<commit_before>// This file is part of Grust, GObject introspection bindings for Rust
//
// Copyright (C) 2014, 2015  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

use boxed::BoxedType;
use gstr::GStr;
use gtype::GType;
use quark::Quark;
use types::{gint, gpointer};
use util::escape_bytestring;

use glib as ffi;
use gobject;

use std::error::Error as ErrorTrait;
use std::error::FromError;
use std::fmt;
use std::mem;
use std::num;

pub struct Error {
    ptr: *mut ffi::GError
}

pub struct DomainError<T> {
    inner: Error
}

#[derive(Copy, Debug)]
pub enum Code<T> {
    Known(T),
    Unknown(gint)
}

pub trait Domain : num::FromPrimitive {
    fn domain() -> Quark;
    fn name(&self) -> &'static str;
}

pub fn domain<T>() -> Quark where T: Domain {
    <T as Domain>::domain()
}

unsafe impl Send for Error { }

unsafe impl<T> Send for DomainError<T> { }

impl Drop for Error {
    fn drop(&mut self) {
        unsafe { ffi::g_error_free(self.ptr); }
    }
}

impl Clone for Error {
    fn clone(&self) -> Error {
        Error {
            ptr: unsafe { ffi::g_error_copy(self.ptr) }
        }
    }
}

impl<T> Clone for DomainError<T> {
    fn clone(&self) -> DomainError<T> {
        DomainError { inner: self.inner.clone() }
    }
}

impl BoxedType for Error {

    fn get_type() -> GType {
        unsafe { GType::from_raw(gobject::g_error_get_type()) }
    }

    unsafe fn from_ptr(ptr: gpointer) -> Error {
        Error { ptr: ptr as *mut ffi::GError }
    }

    unsafe fn into_ptr(self) -> gpointer {
        let ptr = self.ptr;
        mem::forget(self);
        ptr as gpointer
    }
}

impl Error {

    pub unsafe fn from_raw(ptr: *mut ffi::GError) -> Error {
        assert!(!ptr.is_null(), "GError pointer is not set");
        Error { ptr: ptr }
    }

    pub fn domain(&self) -> Quark {
        unsafe { Quark::from_raw((*self.ptr).domain) }
    }

    pub fn matches<T>(&self, code: T) -> bool where T: Domain + PartialEq {
        if self.domain() == domain::<T>() {
            let own_code_raw = unsafe { (*self.ptr).code };
            if let Some(own_code) = num::from_i32::<T>(own_code_raw as i32) {
                return own_code == code;
            }
        }
        false
    }

    pub fn key(&self) -> (Quark, gint) {
        unsafe {
            let raw = &*self.ptr;
            (Quark::from_raw(raw.domain), raw.code)
        }
    }

    pub fn in_domain<T>(&self) -> bool where T: Domain {
        self.domain() == domain::<T>()
    }

    pub fn into_domain<T>(self) -> Result<DomainError<T>, Error>
        where T: Domain
    {
        if self.in_domain::<T>() {
            Ok(DomainError { inner: self })
        } else {
            Err(self)
        }
    }

    fn message(&self) -> Option<&str> {
        let message = unsafe { GStr::from_ptr((*self.ptr).message) };
        message.to_utf8().ok()
    }

    fn message_bytes(&self) -> &[u8] {
        let message = unsafe { GStr::from_ptr((*self.ptr).message) };
        message.to_bytes()
    }
}

impl<T> DomainError<T> where T: num::FromPrimitive {
    pub fn code(&self) -> Code<T> {
        let code = unsafe { (*self.inner.ptr).code };
        match num::from_i32(code as i32) {
            Some(domain_code) => Code::Known(domain_code),
            None              => Code::Unknown(code)
        }
    }
}

impl ErrorTrait for Error {
    fn description(&self) -> &str {
        if let Some(s) = self.message() {
            return s;
        }
        match self.domain().to_g_str().to_utf8() {
            Ok(s)  => s,
            Err(_) => "GError (message and domain are not represented)"
        }
    }
}

impl<T> ErrorTrait for DomainError<T> where T: Domain {
    fn description(&self) -> &str {
        if let Some(s) = self.inner.message() {
            return s;
        }
        if let Code::Known(code) = self.code() {
            return code.name();
        }
        match self.inner.domain().to_g_str().to_utf8() {
            Ok(s)  => s,
            Err(_) => "GError (message and domain are not represented; unknown code)"
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let bytes = self.message_bytes();
        write!(f, "{}", String::from_utf8_lossy(bytes))
    }
}

impl<T> fmt::Display for DomainError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let bytes = self.inner.message_bytes();
        write!(f, "{}", String::from_utf8_lossy(bytes))
    }
}

impl fmt::Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let (domain, code) = self.key();
        let message = escape_bytestring(self.message_bytes());
        write!(f,
               r#"GError{{domain={:?}, code={}, message="{}"}}"#,
               domain, code, message)
    }
}

impl<T> fmt::Debug for DomainError<T> where T: Domain {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let domain = self.inner.domain();
        let message = escape_bytestring(self.inner.message_bytes());
        match self.code() {
            Code::Known(code) => {
                write!(f,
                       r#"GError{{domain={:?}, code={}, message="{}"}}"#,
                       domain, code.name(), message)
            }
            Code::Unknown(int_code) => {
                write!(f,
                       r#"GError{{domain={:?}, code={}, message="{}"}}"#,
                       domain, int_code, message)
            }
        }
    }
}

impl<T> FromError<DomainError<T>> for Error {
    fn from_error(err: DomainError<T>) -> Error {
        err.inner
    }
}

impl<T> Code<T> {

    pub fn known(self) -> Option<T> {
        match self {
            Code::Known(code) => Some(code),
            Code::Unknown(_) => None
        }
    }
}

impl<T> PartialEq for Code<T> where T: PartialEq {
    fn eq(&self, other: &Code<T>) -> bool {
        match (self, other) {
            (&Code::Known(ref a), &Code::Known(ref b)) => *a == *b,
            (&Code::Unknown(a), &Code::Unknown(b)) => a == b,
            _ => false
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use glib as ffi;
    use gstr::GStrBuf;
    use quark::Quark;
    use types::gint;

    fn new_error(domain: Quark, code: gint, message: &[u8]) -> Error {
        let msg_buf = GStrBuf::from_bytes(message).unwrap();
        unsafe {
            let raw = ffi::g_error_new_literal(
                domain.to_raw(), code, msg_buf.as_ptr());
            Error::from_raw(raw)
        }
    }

    #[test]
    fn message() {
        let domain = Quark::from_static_str("foo\0");
        let message = "test message";
        let err = new_error(domain, 1, message.as_bytes());
        assert_eq!(err.message().unwrap(), message);
        let err = new_error(domain, 1, b"U can't parse this.\x9C Hammer time!");
        assert!(err.message().is_none());
    }
}
<commit_msg>error: Conventionalized Debug implementation<commit_after>// This file is part of Grust, GObject introspection bindings for Rust
//
// Copyright (C) 2014, 2015  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

use boxed::BoxedType;
use gstr::GStr;
use gtype::GType;
use quark::Quark;
use types::{gint, gpointer};
use util::escape_bytestring;

use glib as ffi;
use gobject;

use std::error::Error as ErrorTrait;
use std::error::FromError;
use std::fmt;
use std::mem;
use std::num;

pub struct Error {
    ptr: *mut ffi::GError
}

pub struct DomainError<T> {
    inner: Error
}

#[derive(Copy, Debug)]
pub enum Code<T> {
    Known(T),
    Unknown(gint)
}

pub trait Domain : num::FromPrimitive {
    fn domain() -> Quark;
    fn name(&self) -> &'static str;
}

pub fn domain<T>() -> Quark where T: Domain {
    <T as Domain>::domain()
}

unsafe impl Send for Error { }

unsafe impl<T> Send for DomainError<T> { }

impl Drop for Error {
    fn drop(&mut self) {
        unsafe { ffi::g_error_free(self.ptr); }
    }
}

impl Clone for Error {
    fn clone(&self) -> Error {
        Error {
            ptr: unsafe { ffi::g_error_copy(self.ptr) }
        }
    }
}

impl<T> Clone for DomainError<T> {
    fn clone(&self) -> DomainError<T> {
        DomainError { inner: self.inner.clone() }
    }
}

impl BoxedType for Error {

    fn get_type() -> GType {
        unsafe { GType::from_raw(gobject::g_error_get_type()) }
    }

    unsafe fn from_ptr(ptr: gpointer) -> Error {
        Error { ptr: ptr as *mut ffi::GError }
    }

    unsafe fn into_ptr(self) -> gpointer {
        let ptr = self.ptr;
        mem::forget(self);
        ptr as gpointer
    }
}

impl Error {

    pub unsafe fn from_raw(ptr: *mut ffi::GError) -> Error {
        assert!(!ptr.is_null(), "GError pointer is not set");
        Error { ptr: ptr }
    }

    pub fn domain(&self) -> Quark {
        unsafe { Quark::from_raw((*self.ptr).domain) }
    }

    pub fn matches<T>(&self, code: T) -> bool where T: Domain + PartialEq {
        if self.domain() == domain::<T>() {
            let own_code_raw = unsafe { (*self.ptr).code };
            if let Some(own_code) = num::from_i32::<T>(own_code_raw as i32) {
                return own_code == code;
            }
        }
        false
    }

    pub fn key(&self) -> (Quark, gint) {
        unsafe {
            let raw = &*self.ptr;
            (Quark::from_raw(raw.domain), raw.code)
        }
    }

    pub fn in_domain<T>(&self) -> bool where T: Domain {
        self.domain() == domain::<T>()
    }

    pub fn into_domain<T>(self) -> Result<DomainError<T>, Error>
        where T: Domain
    {
        if self.in_domain::<T>() {
            Ok(DomainError { inner: self })
        } else {
            Err(self)
        }
    }

    fn message(&self) -> Option<&str> {
        let message = unsafe { GStr::from_ptr((*self.ptr).message) };
        message.to_utf8().ok()
    }

    fn message_bytes(&self) -> &[u8] {
        let message = unsafe { GStr::from_ptr((*self.ptr).message) };
        message.to_bytes()
    }
}

impl<T> DomainError<T> where T: num::FromPrimitive {
    pub fn code(&self) -> Code<T> {
        let code = unsafe { (*self.inner.ptr).code };
        match num::from_i32(code as i32) {
            Some(domain_code) => Code::Known(domain_code),
            None              => Code::Unknown(code)
        }
    }
}

impl ErrorTrait for Error {
    fn description(&self) -> &str {
        if let Some(s) = self.message() {
            return s;
        }
        match self.domain().to_g_str().to_utf8() {
            Ok(s)  => s,
            Err(_) => "GError (message and domain are not represented)"
        }
    }
}

impl<T> ErrorTrait for DomainError<T> where T: Domain {
    fn description(&self) -> &str {
        if let Some(s) = self.inner.message() {
            return s;
        }
        if let Code::Known(code) = self.code() {
            return code.name();
        }
        match self.inner.domain().to_g_str().to_utf8() {
            Ok(s)  => s,
            Err(_) => "GError (message and domain are not represented; unknown code)"
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let bytes = self.message_bytes();
        write!(f, "{}", String::from_utf8_lossy(bytes))
    }
}

impl<T> fmt::Display for DomainError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let bytes = self.inner.message_bytes();
        write!(f, "{}", String::from_utf8_lossy(bytes))
    }
}

impl fmt::Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let (domain, code) = self.key();
        let message = escape_bytestring(self.message_bytes());
        write!(f,
               r#"GError {{ domain: {:?}, code: {}, message: "{}" }}"#,
               domain, code, message)
    }
}

impl<T> fmt::Debug for DomainError<T> where T: Domain {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let domain = self.inner.domain();
        let message = escape_bytestring(self.inner.message_bytes());
        match self.code() {
            Code::Known(code) => {
                write!(f,
                       r#"GError {{ domain: {:?}, code: {:?}, message: "{}" }}"#,
                       domain, code.name(), message)
            }
            Code::Unknown(int_code) => {
                write!(f,
                       r#"GError {{ domain: {:?}, code: {}, message: "{}" }}"#,
                       domain, int_code, message)
            }
        }
    }
}

impl<T> FromError<DomainError<T>> for Error {
    fn from_error(err: DomainError<T>) -> Error {
        err.inner
    }
}

impl<T> Code<T> {

    pub fn known(self) -> Option<T> {
        match self {
            Code::Known(code) => Some(code),
            Code::Unknown(_) => None
        }
    }
}

impl<T> PartialEq for Code<T> where T: PartialEq {
    fn eq(&self, other: &Code<T>) -> bool {
        match (self, other) {
            (&Code::Known(ref a), &Code::Known(ref b)) => *a == *b,
            (&Code::Unknown(a), &Code::Unknown(b)) => a == b,
            _ => false
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use glib as ffi;
    use gstr::GStrBuf;
    use quark::Quark;
    use types::gint;

    fn new_error(domain: Quark, code: gint, message: &[u8]) -> Error {
        let msg_buf = GStrBuf::from_bytes(message).unwrap();
        unsafe {
            let raw = ffi::g_error_new_literal(
                domain.to_raw(), code, msg_buf.as_ptr());
            Error::from_raw(raw)
        }
    }

    #[test]
    fn message() {
        let domain = Quark::from_static_str("foo\0");
        let message = "test message";
        let err = new_error(domain, 1, message.as_bytes());
        assert_eq!(err.message().unwrap(), message);
        let err = new_error(domain, 1, b"U can't parse this.\x9C Hammer time!");
        assert!(err.message().is_none());
    }
}
<|endoftext|>


<commit_before>use index_type::{IndexType, NodeIndex, EdgeIndex, DefIndex};
use std::str::FromStr;
use std::default::Default;
use std::fmt;

pub trait WeightType: Sized + fmt::Debug + Default + Copy {}

#[derive(Debug, Default, Clone, Copy)]
pub struct Unweighted;

impl FromStr for Unweighted {
    type Err = &'static str;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.is_empty() {
            Ok(Unweighted)
        } else {
            Err("Invalid Unweighted string")
        }
    }
}
impl WeightType for Unweighted {}

impl WeightType for f32 {}
impl WeightType for f64 {}

/// A weighted, multi-edged, directed graph. Edges are represented by a unique index EdgeIx. Nodes by their NodeIx.
#[derive(Debug)]
pub struct MDGraph<NodeWt: WeightType = Unweighted,
                   EdgeWt: WeightType = Unweighted,
                   NodeIx: IndexType = DefIndex,
                   EdgeIx: IndexType = DefIndex>
{
    node_weights: Vec<NodeWt>,
    edge_weights: Vec<EdgeWt>,

    // in_edges[v] contains all nodes u with (u, v) in E.
    in_edges: Vec<Vec<(NodeIndex<NodeIx>, EdgeIndex<EdgeIx>)>>,

    // out_edges[u] contains all nodes v with (u, v) in E.
    out_edges: Vec<Vec<(NodeIndex<NodeIx>, EdgeIndex<EdgeIx>)>>,
}

impl<NodeWt: WeightType, EdgeWt: WeightType, NodeIx: IndexType, EdgeIx: IndexType> MDGraph<NodeWt, EdgeWt, NodeIx, EdgeIx> {
    pub fn new() -> MDGraph<NodeWt, EdgeWt, NodeIx, EdgeIx> {
        MDGraph {
            node_weights: Vec::new(),
            edge_weights: Vec::new(),
            in_edges: Vec::new(),
            out_edges: Vec::new(),
        }
    }

    pub fn reserve_nodes(&mut self, additional: usize) {
        self.node_weights.reserve(additional);
        self.in_edges.reserve(additional);
        self.out_edges.reserve(additional);
    }

    pub fn reserve_edges(&mut self, additional: usize) {
        self.edge_weights.reserve(additional);
    }

    pub fn add_node_with_weight(&mut self, weight: NodeWt) -> NodeIndex<NodeIx> {
        let idx = NodeIndex::new(self.node_weights.len());
        self.node_weights.push(weight);
        self.in_edges.push(Vec::new());
        self.out_edges.push(Vec::new());
        idx
    }

    pub fn add_node(&mut self) -> NodeIndex<NodeIx> {
        self.add_node_with_weight(NodeWt::default())
    }

    /// Returns first and last index.
    pub fn add_nodes(&mut self, n: usize) -> (NodeIndex<NodeIx>, NodeIndex<NodeIx>) {
        assert!(n > 0);
        let first_idx = self.add_node();
        let mut last_idx = first_idx;
        for _ in 1..n {
            last_idx = self.add_node();
        }
        return (first_idx, last_idx); // NOTE: Inclusive index!
    }

    pub fn add_edge_with_weight(&mut self,
                                source: NodeIndex<NodeIx>,
                                target: NodeIndex<NodeIx>,
                                weight: EdgeWt)
                                -> EdgeIndex<EdgeIx> {
        assert!(source.index() < self.node_weights.len());
        assert!(target.index() < self.node_weights.len());

        let idx = EdgeIndex::new(self.edge_weights.len());
        self.edge_weights.push(weight);

        self.out_edges[source.index()].push((target, idx));
        self.in_edges[target.index()].push((source, idx));

        idx
    }

    pub fn add_edge(&mut self,
                    source: NodeIndex<NodeIx>,
                    target: NodeIndex<NodeIx>)
                    -> EdgeIndex<EdgeIx> {
        self.add_edge_with_weight(source, target, EdgeWt::default())
    }

    pub fn in_degree(&self, node: NodeIndex<NodeIx>) -> usize {
        self.in_edges[node.index()].len()
    }

    pub fn out_degree(&self, node: NodeIndex<NodeIx>) -> usize {
        self.out_edges[node.index()].len()
    }

    pub fn get_node_weight(&self, node: NodeIndex<NodeIx>) -> &NodeWt {
        &self.node_weights[node.index()]
    }

    pub fn get_node_weight_mut(&mut self, node: NodeIndex<NodeIx>) -> &mut NodeWt {
        &mut self.node_weights[node.index()]
    }

    pub fn get_edge_weight(&self, edge: EdgeIndex<EdgeIx>) -> &EdgeWt {
        &self.edge_weights[edge.index()]
    }

    pub fn get_edge_weight_mut(&mut self, edge: EdgeIndex<EdgeIx>) -> &mut EdgeWt {
        &mut self.edge_weights[edge.index()]
    }

    pub fn in_edges_of(&self,
                       node: NodeIndex<NodeIx>)
                       -> &[(NodeIndex<NodeIx>, EdgeIndex<EdgeIx>)] {
        &self.in_edges[node.index()]
    }

    pub fn out_edges_of(&self,
                        node: NodeIndex<NodeIx>)
                        -> &[(NodeIndex<NodeIx>, EdgeIndex<EdgeIx>)] {
        &self.out_edges[node.index()]
    }

    pub fn edge_count(&self) -> usize {
        self.edge_weights.len()
    }
    pub fn node_count(&self) -> usize {
        self.node_weights.len()
    }

}
<commit_msg>Add MDGraph::degree()<commit_after>use index_type::{IndexType, NodeIndex, EdgeIndex, DefIndex};
use std::str::FromStr;
use std::default::Default;
use std::fmt;

pub trait WeightType: Sized + fmt::Debug + Default + Copy {}

#[derive(Debug, Default, Clone, Copy)]
pub struct Unweighted;

impl FromStr for Unweighted {
    type Err = &'static str;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.is_empty() {
            Ok(Unweighted)
        } else {
            Err("Invalid Unweighted string")
        }
    }
}
impl WeightType for Unweighted {}

impl WeightType for f32 {}
impl WeightType for f64 {}

/// A weighted, multi-edged, directed graph. Edges are represented by a unique index EdgeIx. Nodes by their NodeIx.
#[derive(Debug)]
pub struct MDGraph<NodeWt: WeightType = Unweighted,
                   EdgeWt: WeightType = Unweighted,
                   NodeIx: IndexType = DefIndex,
                   EdgeIx: IndexType = DefIndex>
{
    node_weights: Vec<NodeWt>,
    edge_weights: Vec<EdgeWt>,

    // in_edges[v] contains all nodes u with (u, v) in E.
    in_edges: Vec<Vec<(NodeIndex<NodeIx>, EdgeIndex<EdgeIx>)>>,

    // out_edges[u] contains all nodes v with (u, v) in E.
    out_edges: Vec<Vec<(NodeIndex<NodeIx>, EdgeIndex<EdgeIx>)>>,
}

impl<NodeWt: WeightType, EdgeWt: WeightType, NodeIx: IndexType, EdgeIx: IndexType> MDGraph<NodeWt, EdgeWt, NodeIx, EdgeIx> {
    pub fn new() -> MDGraph<NodeWt, EdgeWt, NodeIx, EdgeIx> {
        MDGraph {
            node_weights: Vec::new(),
            edge_weights: Vec::new(),
            in_edges: Vec::new(),
            out_edges: Vec::new(),
        }
    }

    pub fn reserve_nodes(&mut self, additional: usize) {
        self.node_weights.reserve(additional);
        self.in_edges.reserve(additional);
        self.out_edges.reserve(additional);
    }

    pub fn reserve_edges(&mut self, additional: usize) {
        self.edge_weights.reserve(additional);
    }

    pub fn add_node_with_weight(&mut self, weight: NodeWt) -> NodeIndex<NodeIx> {
        let idx = NodeIndex::new(self.node_weights.len());
        self.node_weights.push(weight);
        self.in_edges.push(Vec::new());
        self.out_edges.push(Vec::new());
        idx
    }

    pub fn add_node(&mut self) -> NodeIndex<NodeIx> {
        self.add_node_with_weight(NodeWt::default())
    }

    /// Returns first and last index.
    pub fn add_nodes(&mut self, n: usize) -> (NodeIndex<NodeIx>, NodeIndex<NodeIx>) {
        assert!(n > 0);
        let first_idx = self.add_node();
        let mut last_idx = first_idx;
        for _ in 1..n {
            last_idx = self.add_node();
        }
        return (first_idx, last_idx); // NOTE: Inclusive index!
    }

    pub fn add_edge_with_weight(&mut self,
                                source: NodeIndex<NodeIx>,
                                target: NodeIndex<NodeIx>,
                                weight: EdgeWt)
                                -> EdgeIndex<EdgeIx> {
        assert!(source.index() < self.node_weights.len());
        assert!(target.index() < self.node_weights.len());

        let idx = EdgeIndex::new(self.edge_weights.len());
        self.edge_weights.push(weight);

        self.out_edges[source.index()].push((target, idx));
        self.in_edges[target.index()].push((source, idx));

        idx
    }

    pub fn add_edge(&mut self,
                    source: NodeIndex<NodeIx>,
                    target: NodeIndex<NodeIx>)
                    -> EdgeIndex<EdgeIx> {
        self.add_edge_with_weight(source, target, EdgeWt::default())
    }

    pub fn in_degree(&self, node: NodeIndex<NodeIx>) -> usize {
        self.in_edges[node.index()].len()
    }

    pub fn out_degree(&self, node: NodeIndex<NodeIx>) -> usize {
        self.out_edges[node.index()].len()
    }

    pub fn degree(&self, node: NodeIndex<NodeIx>) -> usize {
        self.in_degree(node) + self.out_degree(node)
    }

    pub fn get_node_weight(&self, node: NodeIndex<NodeIx>) -> &NodeWt {
        &self.node_weights[node.index()]
    }

    pub fn get_node_weight_mut(&mut self, node: NodeIndex<NodeIx>) -> &mut NodeWt {
        &mut self.node_weights[node.index()]
    }

    pub fn get_edge_weight(&self, edge: EdgeIndex<EdgeIx>) -> &EdgeWt {
        &self.edge_weights[edge.index()]
    }

    pub fn get_edge_weight_mut(&mut self, edge: EdgeIndex<EdgeIx>) -> &mut EdgeWt {
        &mut self.edge_weights[edge.index()]
    }

    pub fn in_edges_of(&self,
                       node: NodeIndex<NodeIx>)
                       -> &[(NodeIndex<NodeIx>, EdgeIndex<EdgeIx>)] {
        &self.in_edges[node.index()]
    }

    pub fn out_edges_of(&self,
                        node: NodeIndex<NodeIx>)
                        -> &[(NodeIndex<NodeIx>, EdgeIndex<EdgeIx>)] {
        &self.out_edges[node.index()]
    }

    pub fn edge_count(&self) -> usize {
        self.edge_weights.len()
    }
    pub fn node_count(&self) -> usize {
        self.node_weights.len()
    }

}
<|endoftext|>


<commit_before>use time::get_time;
use time::Timespec;

use std::sync::Mutex;

use ewma::EWMA;

pub struct MeterSnapshot{
    count: i64,
    rate1: f64,
    rate5: f64,
    rate15: f64,
    rate_mean: f64
}

pub struct Meter {
    data: Mutex<MeterSnapshot>,
    a1: EWMA,
    a5: EWMA,
    a15: EWMA,
    start: Timespec
}

impl Meter {
    pub fn mark(&self, n: i64) {
        let mut s = self.data.lock();
        s.count += n;
        self.a1.update(n as uint);
        self.a5.update(n as uint);
        self.a15.update(n as uint);
    }

    pub fn snapshot(&self) -> MeterSnapshot{
        let s = self.data.lock();
        MeterSnapshot {
            count: s.count,
            rate1: s.rate1,
            rate5: s.rate5,
            rate15: s.rate15,
            rate_mean: s.rate_mean
        }
    }

    fn update_snapshot(&self) {
        let mut s = self.data.lock();
        s.rate1 = self.a1.rate();
        s.rate5 = self.a5.rate();
        s.rate15 = self.a15.rate();

        let diff = get_time() - self.start;
        s.rate_mean = s.count as f64 / diff.num_seconds() as f64;
    }

    pub fn tick(&mut self) {
        self.data.lock();
        self.a1.tick();
        self.a5.tick();
        self.a15.tick();
        self.update_snapshot()
    }

    pub fn new() -> Meter {
        let i = -5.0f64/60.0f64/1f64;

        let data = MeterSnapshot{
            count: 0i64,
            rate1: 0f64,
            rate5: 0f64,
            rate15: 0f64,
            rate_mean: 0f64
        };

        Meter {
            data: Mutex::new(data),
            a1: EWMA::new(1f64 - i),
            a5: EWMA::new(5f64 - i),
            a15: EWMA::new(15f64 - i),
            start: get_time()
        }
    }
}

#[cfg(test)]
mod test {
    use meter::{Meter,MeterSnapshot};

    #[test]
    fn zero() {
        let m: Meter = Meter::new();
        let s: MeterSnapshot = m.snapshot();
        assert_eq!(s.count, 0);
    }

    #[test]
    fn non_zero() {
        let m: Meter = Meter::new();
        m.mark(3);
        let s: MeterSnapshot = m.snapshot();
        assert_eq!(s.count, 3);
    }

    #[test]
    fn snapshot() {
        let m: Meter = Meter::new();
        m.mark(1);
        m.mark(1);

        let s = m.snapshot();

        m.mark(1);

        assert_eq!(s.count, 2);
        assert_eq!(m.snapshot().count, 3);
    }
}<commit_msg>Cleanup meter according to kmc @ irc<commit_after>use time::get_time;
use time::Timespec;

use std::sync::Mutex;

use ewma::EWMA;

const WINDOW: [f64, ..3] = [1f64, 5f64, 15f64];

pub struct MeterSnapshot{
    count: i64,
    rates: [f64, ..3],
    rate_mean: f64
}

pub struct Meter {
    data: Mutex<MeterSnapshot>,
    ewma: [EWMA, ..3],
    start: Timespec
}

impl Meter {
    pub fn mark(&self, n: i64) {
        let mut s = self.data.lock();
        s.count += n;

        for i in range(0, WINDOW.len()) {
            self.ewma[i].update(n as uint);
        }
    }

    pub fn snapshot(&self) -> MeterSnapshot{
        let s = self.data.lock();

        MeterSnapshot {
            count: s.count,
            rates: s.rates,
            rate_mean: s.rate_mean
        }
    }

    fn update_snapshot(&self) {
        let mut s = self.data.lock();

        for i in range(0, WINDOW.len()) {
            s.rates[i] = self.ewma[i].rate();
        }

        let diff = get_time() - self.start;
        s.rate_mean = s.count as f64 / diff.num_seconds() as f64;
    }

    pub fn tick(&mut self) {
        self.data.lock();

        for i in range(0, WINDOW.len()) {
            self.ewma[i].tick();
        }

        self.update_snapshot()
    }

    pub fn new() -> Meter {
        let data = MeterSnapshot{
            count: 0i64,
            rates: [0f64, 0f64, 0f64],
            rate_mean: 0f64
        };

        let ewma: [EWMA, ..3] = [EWMA::new(1f64), EWMA::new(5f64), EWMA::new(15f64)];

        Meter {
            data: Mutex::new(data),
            ewma: ewma,
            start: get_time(),
        }
    }
}

#[cfg(test)]
mod test {
    use meter::{Meter,MeterSnapshot};

    #[test]
    fn zero() {
        let m: Meter = Meter::new();
        let s: MeterSnapshot = m.snapshot();
        assert_eq!(s.count, 0);
    }

    #[test]
    fn non_zero() {
        let m: Meter = Meter::new();
        m.mark(3);
        let s: MeterSnapshot = m.snapshot();
        assert_eq!(s.count, 3);
    }

    #[test]
    fn snapshot() {
        let m: Meter = Meter::new();
        m.mark(1);
        m.mark(1);

        let s = m.snapshot();

        m.mark(1);

        assert_eq!(s.count, 2);
        assert_eq!(m.snapshot().count, 3);
    }
}<|endoftext|>


<commit_before>use sdl2::keyboard::KeyboardState;
use std::collections::HashMap;
use std::collections::HashSet;

pub use sdl2::keyboard::Keycode;
#[derive(Debug,PartialEq,Hash,Clone)]
pub enum BindingState {
    Pressed,
    Held
}

#[derive(Debug,PartialEq,Hash,Clone)]
pub enum Binding {
    Key(BindingState, Keycode),
}

impl Eq for Binding {}

pub struct Input<T> {
    binding: HashMap<Binding, T>,
    command_buffer: Vec<T>,
    keys: HashSet<Keycode>,
    old_keys: HashSet<Keycode>,
}

impl<T> Input<T> where T: Sized + Clone {
    pub fn new(keymap: Option<HashMap<Binding, T>>) -> Input<T> {
        if keymap.is_some() {
            Input {
                binding: keymap.unwrap(),
                command_buffer: Vec::<T>::new(),
                keys: HashSet::<Keycode>::new(),
                old_keys: HashSet::<Keycode>::new(),
            }
        }
        else {
            Input{
                binding: HashMap::<Binding, T>::new(),
                command_buffer: Vec::<T>::new(),
                keys: HashSet::<Keycode>::new(),
                old_keys: HashSet::<Keycode>::new(),
            }
        }
    }

    pub fn add_binding(mut self, b: Option<Binding>, c: T) -> Self {
        if b.is_none() { return self }
        self.binding.insert(b.unwrap(), c);
        self
    }

    pub fn clear_commands(&mut self) {
        self.command_buffer.clear();
    }

    pub fn key_state<'a>(&mut self, keys: KeyboardState<'a>) {
        self.clear_commands();
        self.old_keys = self.keys.clone();
        self.keys = keys.pressed_scancodes().filter_map(Keycode::from_scancode).collect();
        // held keys (exist in old and new)
        for key in self.keys.intersection(&self.old_keys) {
            let command = self.binding.get(&Binding::Key(BindingState::Held, key.clone()));
            if command.is_none() { continue }

            self.command_buffer.push(command.unwrap().clone());
        }

        for key in (&self.keys - &self.old_keys) {
            let command = self.binding.get(&Binding::Key(BindingState::Pressed, key.clone()));
            if command.is_none() { continue }

            self.command_buffer.push(command.unwrap().clone());
        }
    }

    pub fn key_pressed(&self, keycode: Keycode) -> bool {
        (&self.keys - &self.old_keys).contains(&keycode)
    }

    pub fn key_held(&self, keycode: Keycode) -> bool {
        self.keys.contains(&keycode) && self.old_keys.contains(&keycode)
    }

    pub fn command_iter(&mut self) -> ::std::slice::Iter<T> {
        self.command_buffer.iter()
    }
}
<commit_msg>Removed parens that rust was bitching about<commit_after>use sdl2::keyboard::KeyboardState;
use std::collections::HashMap;
use std::collections::HashSet;

pub use sdl2::keyboard::Keycode;
#[derive(Debug,PartialEq,Hash,Clone)]
pub enum BindingState {
    Pressed,
    Held
}

#[derive(Debug,PartialEq,Hash,Clone)]
pub enum Binding {
    Key(BindingState, Keycode),
}

impl Eq for Binding {}

pub struct Input<T> {
    binding: HashMap<Binding, T>,
    command_buffer: Vec<T>,
    keys: HashSet<Keycode>,
    old_keys: HashSet<Keycode>,
}

impl<T> Input<T> where T: Sized + Clone {
    pub fn new(keymap: Option<HashMap<Binding, T>>) -> Input<T> {
        if keymap.is_some() {
            Input {
                binding: keymap.unwrap(),
                command_buffer: Vec::<T>::new(),
                keys: HashSet::<Keycode>::new(),
                old_keys: HashSet::<Keycode>::new(),
            }
        }
        else {
            Input{
                binding: HashMap::<Binding, T>::new(),
                command_buffer: Vec::<T>::new(),
                keys: HashSet::<Keycode>::new(),
                old_keys: HashSet::<Keycode>::new(),
            }
        }
    }

    pub fn add_binding(mut self, b: Option<Binding>, c: T) -> Self {
        if b.is_none() { return self }
        self.binding.insert(b.unwrap(), c);
        self
    }

    pub fn clear_commands(&mut self) {
        self.command_buffer.clear();
    }

    pub fn key_state<'a>(&mut self, keys: KeyboardState<'a>) {
        self.clear_commands();
        self.old_keys = self.keys.clone();
        self.keys = keys.pressed_scancodes().filter_map(Keycode::from_scancode).collect();
        // held keys (exist in old and new)
        for key in self.keys.intersection(&self.old_keys) {
            let command = self.binding.get(&Binding::Key(BindingState::Held, key.clone()));
            if command.is_none() { continue }

            self.command_buffer.push(command.unwrap().clone());
        }

        for key in &self.keys - &self.old_keys {
            let command = self.binding.get(&Binding::Key(BindingState::Pressed, key.clone()));
            if command.is_none() { continue }

            self.command_buffer.push(command.unwrap().clone());
        }
    }

    pub fn key_pressed(&self, keycode: Keycode) -> bool {
        (&self.keys - &self.old_keys).contains(&keycode)
    }

    pub fn key_held(&self, keycode: Keycode) -> bool {
        self.keys.contains(&keycode) && self.old_keys.contains(&keycode)
    }

    pub fn command_iter(&mut self) -> ::std::slice::Iter<T> {
        self.command_buffer.iter()
    }
}
<|endoftext|>


<commit_before>use ParseResult;
use internal::State;
use internal::InputModify;

/// Default (empty) input state.
pub const DEFAULT: u32      = 0;
/// If set the current slice of input is the last one.
pub const END_OF_INPUT: u32 = 1;

/// Linear type containing the parser state, this type is threaded though `bind`.
#[must_use]
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Input<'a, I: 'a>(u32, &'a [I]);

/// Creates a new input from the given state and buffer.
///
/// # Internal
///
/// Only used by fundamental parsers and combinators.
pub fn new<I>(state: u32, buffer: &[I]) -> Input<I> {
    Input(state, buffer)
}

impl<'a, I> Input<'a, I> {
    // TODO: Remove, use parse_slice instead
    pub fn new(b: &'a [I]) -> Self {
        Input(END_OF_INPUT, b)
    }

    /// Returns the value `t` with the input context.
    #[inline]
    pub fn ret<T, E>(self, t: T) -> ParseResult<'a, I, T, E> {
        ParseResult(State::Data(self, t))
    }

    /// Returns the error value `e` with the input context.
    #[inline]
    pub fn err<T, E>(self, e: E) -> ParseResult<'a, I, T, E> {
        ParseResult(State::Error(self.1, e))
    }
}

/// Implementation of internal trait used to build parsers and combinators.
///
/// # Internal
///
/// Only used by fundamental parsers and combinators.
impl<'a, I> InputModify<'a> for Input<'a, I> {
    type Type = I;

    /// Creates a clone of the instance.
    #[inline(always)]
    fn clone_input(&self) -> Self {
        Input(self.0, self.1)
    }

    #[inline(always)]
    fn buffer(&self) -> &'a [Self::Type]
      where <Self as InputModify<'a>>::Type: 'a {
        self.1
    }

    /// Modifies the inner data without leaving the `Input` context.
    #[inline(always)]
    fn replace(self, b: &'a [Self::Type]) -> Self
      where <Self as InputModify<'a>>::Type: 'a {
        Input(self.0, b)
    }

    /// Modifies the inner data without leaving the `Input` context.
    #[inline(always)]
    fn modify<F>(self, f: F) -> Self
      where F: Fn(&'a [Self::Type]) -> &'a [Self::Type],
          <Self as InputModify<'a>>::Type: 'a {
        Input(self.0, f(self.1))
    }

    /// Notifies the combinator that a parser has reached the end of the currently supplied slice but
    /// requires more data.
    ///
    /// # Internal
    ///
    /// Only used by fundamental parsers and combinators.
    #[inline(always)]
    fn incomplete<T, E>(self, n: usize) -> ParseResult<'a, Self::Type, T, E> {
        ParseResult(State::Incomplete(n))
    }

    /// Returns true if this is the last input slice available.
    ///
    /// # Internal
    ///
    /// Only used by fundamental parsers and combinators.
    #[inline(always)]
    fn is_last_slice(&self) -> bool {
        self.0 & END_OF_INPUT == END_OF_INPUT
    }
}
<commit_msg>Input: Added method converting Result to ParseResult<commit_after>use ParseResult;
use internal::State;
use internal::InputModify;

/// Default (empty) input state.
pub const DEFAULT: u32      = 0;
/// If set the current slice of input is the last one.
pub const END_OF_INPUT: u32 = 1;

/// Linear type containing the parser state, this type is threaded though `bind`.
#[must_use]
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Input<'a, I: 'a>(u32, &'a [I]);

/// Creates a new input from the given state and buffer.
///
/// # Internal
///
/// Only used by fundamental parsers and combinators.
pub fn new<I>(state: u32, buffer: &[I]) -> Input<I> {
    Input(state, buffer)
}

impl<'a, I> Input<'a, I> {
    // TODO: Remove, use parse_slice instead
    pub fn new(b: &'a [I]) -> Self {
        Input(END_OF_INPUT, b)
    }

    /// Returns the value `t` with the input context.
    #[inline]
    pub fn ret<T, E>(self, t: T) -> ParseResult<'a, I, T, E> {
        ParseResult(State::Data(self, t))
    }

    /// Returns the error value `e` with the input context.
    #[inline]
    pub fn err<T, E>(self, e: E) -> ParseResult<'a, I, T, E> {
        ParseResult(State::Error(self.1, e))
    }

    /// Converts a `Result` into a `ParseResult`.
    ///
    /// # Examples
    ///
    /// ```
    /// use chomp::Input;
    ///
    /// let r = Input::new(b"test").from_result::<_, ()>(Ok("foo"));
    ///
    /// assert_eq!(r.unwrap(), "foo");
    /// ```
    ///
    /// ```
    /// use chomp::Input;
    ///
    /// let r = Input::new(b"test").from_result::<(), _>(Err("error message"));
    ///
    /// assert_eq!(r.unwrap_err(), "error message");
    /// ```
    #[inline]
    pub fn from_result<T, E>(self, r: Result<T, E>) -> ParseResult<'a, I, T, E> {
        match r {
            Ok(t)  => ParseResult(State::Data(self, t)),
            Err(e) => ParseResult(State::Error(self.1, e)),
        }
    }
}

/// Implementation of internal trait used to build parsers and combinators.
///
/// # Internal
///
/// Only used by fundamental parsers and combinators.
impl<'a, I> InputModify<'a> for Input<'a, I> {
    type Type = I;

    /// Creates a clone of the instance.
    #[inline(always)]
    fn clone_input(&self) -> Self {
        Input(self.0, self.1)
    }

    #[inline(always)]
    fn buffer(&self) -> &'a [Self::Type]
      where <Self as InputModify<'a>>::Type: 'a {
        self.1
    }

    /// Modifies the inner data without leaving the `Input` context.
    #[inline(always)]
    fn replace(self, b: &'a [Self::Type]) -> Self
      where <Self as InputModify<'a>>::Type: 'a {
        Input(self.0, b)
    }

    /// Modifies the inner data without leaving the `Input` context.
    #[inline(always)]
    fn modify<F>(self, f: F) -> Self
      where F: Fn(&'a [Self::Type]) -> &'a [Self::Type],
          <Self as InputModify<'a>>::Type: 'a {
        Input(self.0, f(self.1))
    }

    /// Notifies the combinator that a parser has reached the end of the currently supplied slice but
    /// requires more data.
    ///
    /// # Internal
    ///
    /// Only used by fundamental parsers and combinators.
    #[inline(always)]
    fn incomplete<T, E>(self, n: usize) -> ParseResult<'a, Self::Type, T, E> {
        ParseResult(State::Incomplete(n))
    }

    /// Returns true if this is the last input slice available.
    ///
    /// # Internal
    ///
    /// Only used by fundamental parsers and combinators.
    #[inline(always)]
    fn is_last_slice(&self) -> bool {
        self.0 & END_OF_INPUT == END_OF_INPUT
    }
}
<|endoftext|>


<commit_before>#![feature(compiler_builtins_lib, lang_items, asm, pointer_methods)]
#![feature(core_intrinsics)]
#![feature(const_fn)]
#![feature(alloc, allocator_api)]
#![feature(global_allocator)]
#![feature(decl_macro)]

#[macro_use]
extern crate bitflags;

#[macro_use]
extern crate alloc;
extern crate slab_allocator;
extern crate spin;
extern crate stack_vec;
extern crate volatile;

#[macro_use]
extern crate log;

extern crate fat32;

#[macro_use]
#[cfg(not(test))]
pub mod print;

//#[cfg(not(test))]
//pub mod console;
pub mod externs;
#[cfg(not(test))]
pub mod panic;

#[cfg(not(test))]
pub mod util;

#[cfg(not(test))]
pub mod exception;
#[cfg(not(test))]
pub mod mmu;

#[cfg(not(test))]
pub mod pi;
#[cfg(not(test))]
pub mod fb;
#[cfg(not(test))]
pub mod shell;
//pub mod sd;
pub mod sdn;
pub mod gles;

pub mod fs;

pub mod allocator;

use slab_allocator::LockedHeap;
use alloc::*;

#[cfg(not(test))]
#[global_allocator]
static mut ALLOCATOR: LockedHeap = LockedHeap::empty();

const BINARY_START_ADDR: usize = 0x8_0000; // 512kb

const ADDR_1MB: usize   = 0x0010_0000;
const ADDR_2MB: usize   = 0x0020_0000;
const ADDR_4MB: usize   = 0x0040_0000;
const ADDR_8MB: usize   = 0x0080_0000;
const ADDR_16MB: usize  = 0x0100_0000;
const ADDR_32MB: usize  = 0x0200_0000;
const ADDR_64MB: usize  = 0x0400_0000;
const ADDR_128MB: usize = 0x0800_0000;
const ADDR_256MB: usize = 0x1000_0000;
const ADDR_512MB: usize = 0x2000_0000;
const ADDR_1GB: usize   = 0x4000_0000;
const ADDR_2GB: usize   = 0x8000_0000;

#[cfg(not(test))]
pub fn init_heap() {
    // TODO why?
    let heap_start = 0x0F00_0000;
    let heap_end =   0x1000_0000;
    let heap_size = heap_end - heap_start;
    unsafe {
        ALLOCATOR.init(heap_start, heap_size);
    }
}

#[no_mangle]
#[inline(never)]
#[cfg(not(test))]
pub extern "C" fn kernel_main() -> ! {
    init_heap();

    pi::uart0::Uart0::new().initialize();

    kprintln!("      .  ");
    kprintln!("    < 0 >");
    kprintln!("    ./ \\.");
    kprintln!("");

    unsafe {
        let f: u32 = (1 << 0) | (1 << 1) | (1 << 2);
        asm!("msr cntv_ctl_el0, $0" : : "r"(f) : : "volatile");
    }

    let s = String::from("fucking string!");

    kprintln!("Hello Rust Kernel world! 0x{:X} {}", 0xDEAD, s);

    kprintln!("init fs");
    let fs = fs::FileSystem::uninitialized();
    fs.initialize();

    {
        use fat32::traits::{FileSystem, Entry};
        use std::io::Read;
        let f = fs.open("/README.md").unwrap();
        let mut f = f.into_file().unwrap();

        let mut s = String::new();
        f.read_to_string(&mut s).unwrap();
        kprintln!("--------");
        kprintln!("{}", s);
        kprintln!("--------");
    }

    if true {
        unsafe {
            mmu::init();
        }

        kprintln!("enabled mmu");

        if false {
            use volatile::*;
            // generate a Data Abort with a bad address access
            let r = 0xFFFF_FFFF_FF00_0000 as *mut Volatile<u32>;
            unsafe { (*r).write(1) }
        }

        if false {
            const KERNEL_UART0: usize = 0xFFFFFF80_3F201000;

            let s = format!("fuck {:016X}\n", KERNEL_UART0);
            let mut uart = unsafe { pi::uart0::Uart0::from_addr(KERNEL_UART0) };
            for c in s.chars() {
                uart.send(c as u8);
            }
        }
    }

    unsafe {
        let level: u32;
        // read the current level from system register
        asm!("mrs $0, CurrentEL" : "=r" (level) : : : "volatile");
        kprintln!("Current EL is: 0x{:X} [0x{:X}]", (level >> 2) & 3, level);
    }

    {
        kprint!("Waiting 1000000 CPU cycles (ARM CPU): ");
        util::wait_cycles(1000000);
        kprintln!("OK");

        kprint!("Waiting 1000000 microsec (ARM CPU): ");
        util::wait_msec(1000000);
        kprintln!("OK");

        kprint!("Waiting 1000000 microsec (BCM System Timer): ");
        if pi::timer::current_time() == 0 {
            kprintln!("Not available");
        } else {
            pi::timer::spin_sleep_us(1000000);
            kprintln!("OK");
        }
    }

    kprintln!("init fb");

    match fb::FrameBuffer::new(480, 320, 32) {
        Some(mut fb) =>  {
            fb.fill_rgba(0x000000);
            fb::font().uprint(&mut fb, 13, 5, "Prepare uranus!", 0x00FF00, 0x0000FF);
            fb::font().uprint(&mut fb, 13, 6, "Prepare uranus!", 0xFF0000, 0x0000FF);
            fb::font().uprint(&mut fb, 11, 8, "< Prepare uranus! >", 0xFF0000, 0x000000);

            fb::font().uprint(&mut fb, 1, 0, "  .  ",  0xFFFFFF, 0x000000);
            fb::font().uprint(&mut fb, 1, 1, "< 0 >",  0xFFFFFF, 0x000000);
            fb::font().uprint(&mut fb, 1, 2, "./ \\.", 0xFFFFFF, 0x000000);

        }
        None => kprintln!("Unable to set screen resolution to 1024x768x32"),
    }

    kprintln!("init gles: {:?}", gles::InitV3D());

    shell::shell("> ")
}
<commit_msg>fix src/kmain.rs<commit_after>#![feature(compiler_builtins_lib, lang_items, asm, pointer_methods)]
#![feature(core_intrinsics)]
#![feature(const_fn)]
#![feature(alloc, allocator_api)]
#![feature(global_allocator)]
#![feature(decl_macro)]

#[macro_use]
extern crate bitflags;

#[macro_use]
extern crate alloc;
extern crate slab_allocator;
extern crate spin;
extern crate stack_vec;
extern crate volatile;

#[macro_use]
extern crate log;

extern crate fat32;

#[macro_use]
#[cfg(not(test))]
pub mod print;

//#[cfg(not(test))]
//pub mod console;
pub mod externs;
#[cfg(not(test))]
pub mod panic;

#[cfg(not(test))]
pub mod util;

#[cfg(not(test))]
pub mod exception;
#[cfg(not(test))]
pub mod mmu;

#[cfg(not(test))]
pub mod pi;
#[cfg(not(test))]
pub mod fb;
#[cfg(not(test))]
pub mod shell;
//pub mod sd;
pub mod sdn;
pub mod gles;

pub mod fs;

pub mod allocator;

use slab_allocator::LockedHeap;
use alloc::*;

#[cfg(not(test))]
#[global_allocator]
static mut ALLOCATOR: LockedHeap = LockedHeap::empty();

const BINARY_START_ADDR: usize = 0x8_0000; // 512kb

const ADDR_1MB: usize   = 0x0010_0000;
const ADDR_2MB: usize   = 0x0020_0000;
const ADDR_4MB: usize   = 0x0040_0000;
const ADDR_8MB: usize   = 0x0080_0000;
const ADDR_16MB: usize  = 0x0100_0000;
const ADDR_32MB: usize  = 0x0200_0000;
const ADDR_64MB: usize  = 0x0400_0000;
const ADDR_128MB: usize = 0x0800_0000;
const ADDR_256MB: usize = 0x1000_0000;
const ADDR_512MB: usize = 0x2000_0000;
const ADDR_1GB: usize   = 0x4000_0000;
const ADDR_2GB: usize   = 0x8000_0000;

static FILE_SYSTEM: fs::FileSystem = fs::FileSystem::uninitialized();

#[cfg(not(test))]
pub fn init_heap() {
    // TODO why?
    let heap_start = 0x0F00_0000;
    let heap_end =   0x1000_0000;
    let heap_size = heap_end - heap_start;
    unsafe {
        ALLOCATOR.init(heap_start, heap_size);
    }
}

#[no_mangle]
#[inline(never)]
#[cfg(not(test))]
pub extern "C" fn kernel_main() -> ! {
    init_heap();

    pi::uart0::Uart0::new().initialize();

    kprintln!("      .  ");
    kprintln!("    < 0 >");
    kprintln!("    ./ \\.");
    kprintln!("");

    unsafe {
        let f: u32 = (1 << 0) | (1 << 1) | (1 << 2);
        asm!("msr cntv_ctl_el0, $0" : : "r"(f) : : "volatile");
    }

    let s = String::from("fucking string!");

    kprintln!("Hello Rust Kernel world! 0x{:X} {}", 0xDEAD, s);

    kprintln!("init fs");
    FILE_SYSTEM.initialize();

    {
        use fat32::traits::{FileSystem, Entry};
        use std::io::Read;
        let f = fs.open("/README.md").unwrap();
        let mut f = f.into_file().unwrap();

        let mut s = String::new();
        f.read_to_string(&mut s).unwrap();
        kprintln!("--------");
        kprintln!("{}", s);
        kprintln!("--------");
    }

    if true {
        unsafe {
            mmu::init();
        }

        kprintln!("enabled mmu");

        if false {
            use volatile::*;
            // generate a Data Abort with a bad address access
            let r = 0xFFFF_FFFF_FF00_0000 as *mut Volatile<u32>;
            unsafe { (*r).write(1) }
        }

        if false {
            const KERNEL_UART0: usize = 0xFFFFFF80_3F201000;

            let s = format!("fuck {:016X}\n", KERNEL_UART0);
            let mut uart = unsafe { pi::uart0::Uart0::from_addr(KERNEL_UART0) };
            for c in s.chars() {
                uart.send(c as u8);
            }
        }
    }

    unsafe {
        let level: u32;
        // read the current level from system register
        asm!("mrs $0, CurrentEL" : "=r" (level) : : : "volatile");
        kprintln!("Current EL is: 0x{:X} [0x{:X}]", (level >> 2) & 3, level);
    }

    {
        kprint!("Waiting 1000000 CPU cycles (ARM CPU): ");
        util::wait_cycles(1000000);
        kprintln!("OK");

        kprint!("Waiting 1000000 microsec (ARM CPU): ");
        util::wait_msec(1000000);
        kprintln!("OK");

        kprint!("Waiting 1000000 microsec (BCM System Timer): ");
        if pi::timer::current_time() == 0 {
            kprintln!("Not available");
        } else {
            pi::timer::spin_sleep_us(1000000);
            kprintln!("OK");
        }
    }

    kprintln!("init fb");

    match fb::FrameBuffer::new(480, 320, 32) {
        Some(mut fb) =>  {
            fb.fill_rgba(0x000000);
            fb::font().uprint(&mut fb, 13, 5, "Prepare uranus!", 0x00FF00, 0x0000FF);
            fb::font().uprint(&mut fb, 13, 6, "Prepare uranus!", 0xFF0000, 0x0000FF);
            fb::font().uprint(&mut fb, 11, 8, "< Prepare uranus! >", 0xFF0000, 0x000000);

            fb::font().uprint(&mut fb, 1, 0, "  .  ",  0xFFFFFF, 0x000000);
            fb::font().uprint(&mut fb, 1, 1, "< 0 >",  0xFFFFFF, 0x000000);
            fb::font().uprint(&mut fb, 1, 2, "./ \\.", 0xFFFFFF, 0x000000);

        }
        None => kprintln!("Unable to set screen resolution to 1024x768x32"),
    }

    kprintln!("init gles: {:?}", gles::InitV3D());

    shell::shell("> ")
}
<|endoftext|>