<commit_before>#![no_std]

/// This macros defines a single field of a bitfiled.
///
/// It must be called from an impl and will generates methods. You should not
/// call this macro directly. Use `simple_bitfiled_fields` instead.
#[macro_export]
macro_rules! simple_bitfield_field {
    ($(#[$attribute:meta])* ($($vis:tt)*) $t:ty, _, $setter:ident: $msb:expr, $lsb:expr,
     $count:expr) => {
        $(#[$attribute])*
        #[allow(unknown_lints)]
        #[allow(eq_op)]
        $($vis)* fn $setter(&mut self, index: usize, value: $t) {
            use $crate::BitRange;
            debug_assert!(index < $count);
            let width = $msb - $lsb + 1;
            let lsb = $lsb + index*width;
            let msb = lsb + width - 1;
            self.set_bit_range(msb, lsb, value);
        }
    };
    ($(#[$attribute:meta])* ($($vis:tt)*) $t:ty, _, $setter:ident: $msb:expr, $lsb:expr) => {
        $(#[$attribute])*
        $($vis)* fn $setter(&mut self, value: $t) {
            use $crate::BitRange;
            self.set_bit_range($msb, $lsb, value);
        }
    };
    ($(#[$attribute:meta])* ($($vis:tt)*) $t:ty, _, $setter:ident: $bit:expr) => {
        $(#[$attribute])*
        $($vis)* fn $setter(&mut self, value: bool) {
            use $crate::Bit;
            self.set_bit($bit, value);
        }
    };
    ($(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $getter:ident, _: $msb:expr, $lsb:expr,
     $count:expr) => {
        $(#[$attribute])*
        #[allow(unknown_lints)]
        #[allow(eq_op)]
        $($vis)* fn $getter(&self, index: usize) -> $t {
            use $crate::BitRange;
            debug_assert!(index < $count);
            let width = $msb - $lsb + 1;
            let lsb = $lsb + index*width;
            let msb = lsb + width - 1;
            self.bit_range(msb, lsb)
        }
    };
    ($(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $getter:ident, _: $msb:expr, $lsb:expr) => {
        $(#[$attribute])*
        $($vis)* fn $getter(&self) -> $t {
            use $crate::BitRange;
            self.bit_range($msb, $lsb)
        }
    };
    ($(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $getter:ident, _: $bit:expr) => {
        $(#[$attribute])*
        $($vis)* fn $getter(&self) -> bool {
            use $crate::Bit;
            self.bit($bit)
        }
    };
    ($(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $getter:ident, $setter:ident:
     $($exprs:expr),*) => {
        simple_bitfield_field!($(#[$attribute])* ($($vis)*) $t, $getter, _: $($exprs),*);
        simple_bitfield_field!($(#[$attribute])* ($($vis)*) $t, _, $setter: $($exprs),*);
    };
}

#[macro_export]
macro_rules! simple_bitfield_fields {
    ($t:ty;) => {};
    ($default_ty:ty; pub $($rest:tt)*) => {
        simple_bitfield_fields!{$default_ty; () pub $($rest)*}
    };
    ($default_ty:ty; #[$attribute:meta] $($rest:tt)*) => {
        simple_bitfield_fields!{$default_ty; (#[$attribute]) $($rest)*}
    };
    ($default_ty:ty; ($(#[$attributes:meta])*) #[$attribute:meta] $($rest:tt)*) => {
        simple_bitfield_fields!{$default_ty; ($(#[$attributes])* #[$attribute]) $($rest)*}
    };
    ($default_ty:ty; ($(#[$attribute:meta])*) pub $t:ty, $getter:tt, $setter:tt:  $($exprs:expr),*;
     $($rest:tt)*) => {
        simple_bitfield_field!{$(#[$attribute])* (pub) $t, $getter, $setter: $($exprs),*}
        simple_bitfield_fields!{$default_ty; $($rest)*}
    };
    ($default_ty:ty; ($(#[$attribute:meta])*) pub $getter:tt, $setter:tt:  $($exprs:expr),*;
     $($rest:tt)*) => {
        simple_bitfield_field!{$(#[$attribute])* (pub) $default_ty, $getter, $setter: $($exprs),*}
        simple_bitfield_fields!{$default_ty; $($rest)*}
    };
    ($default_ty:ty; ($(#[$attribute:meta])*) $t:ty, $getter:tt, $setter:tt:  $($exprs:expr),*;
     $($rest:tt)*) => {
        simple_bitfield_field!{$(#[$attribute])* () $t, $getter, $setter: $($exprs),*}
        simple_bitfield_fields!{$default_ty; $($rest)*}
    };
    ($default_ty:ty; ($(#[$attribute:meta])*) $getter:tt, $setter:tt:  $($exprs:expr),*;
     $($rest:tt)*) => {
        simple_bitfield_field!{$(#[$attribute])* () $default_ty, $getter, $setter: $($exprs),*}
        simple_bitfield_fields!{$default_ty; $($rest)*}
    };
    ($previous_default_ty:ty; $default_ty:ty; $($rest:tt)*) => {
        simple_bitfield_fields!{$default_ty; $($rest)*}
    };
    ($default_ty:ty; $($rest:tt)*) => {
        simple_bitfield_fields!{$default_ty; () $($rest)*}
    };
}

#[macro_export]
macro_rules! simple_bitfield_struct {
    ($(#[$attribute:meta])* struct $name:ident($($args:tt)*)) => {
        simple_bitfield_struct!($(#[$attribute])* () struct $name($($args)*));
    };
    ($(#[$attribute:meta])* pub struct $name:ident($($args:tt)*))=> {
        simple_bitfield_struct!($(#[$attribute])* (pub) struct $name($($args)*));
    };
    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident([$t:ty])) => {
        $(#[$attribute])*
        $($vis)* struct $name<T>(pub T);

        impl_bitrange_slice!($name, $t, u8);
        impl_bitrange_slice!($name, $t, u16);
        impl_bitrange_slice!($name, $t, u32);
        impl_bitrange_slice!($name, $t, u64);
    };
    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident(MSB0 [$t:ty])) => {
        $(#[$attribute])*
        $($vis)* struct $name<T>(pub T);

        impl_bitrange_slice_msb0!($name, $t, u8);
        impl_bitrange_slice_msb0!($name, $t, u16);
        impl_bitrange_slice_msb0!($name, $t, u32);
        impl_bitrange_slice_msb0!($name, $t, u64);
    };
    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($t:ty)) => {
        $(#[$attribute])*
        $($vis)* struct $name(pub $t);

        impl<T> $crate::BitRange<T> for $name where $t: $crate::BitRange<T> {
            fn bit_range(&self, msb: usize, lsb: usize) -> T {
                self.0.bit_range(msb, lsb)
            }
            fn set_bit_range(&mut self, msb: usize, lsb: usize, value: T) {
                self.0.set_bit_range(msb, lsb, value);
            }
        }
    };
}

#[macro_export]
macro_rules! simple_bitfield {
    ($(#[$attribute:meta])* pub struct $($rest:tt)*) => {
        simple_bitfield!($(#[$attribute])* (pub) struct $($rest)*);
    };
    ($(#[$attribute:meta])* struct $($rest:tt)*) => {
        simple_bitfield!($(#[$attribute])* () struct $($rest)*);
    };
    ($(#[$attribute:meta])* ($($vis:tt)* )struct $name:ident([$t:ty]); $($rest:tt)*) => {
        simple_bitfield_struct!($(#[$attribute])* $($vis)* struct $name([$t]));

        impl<T: AsMut<[$t]> + AsRef<[$t]>> $name<T> {
            simple_bitfield_fields!{u64; $($rest)*}
        }
    };
    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident(MSB0 [$t:ty]); $($rest:tt)*) => {
        simple_bitfield_struct!($(#[$attribute])* $($vis)* struct $name(MSB0 [$t]));

        impl<T: AsMut<[$t]> + AsRef<[$t]>> $name<T> {
            simple_bitfield_fields!{u64; $($rest)*}
        }
    };
    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($t:ty); $($rest:tt)*) => {
        simple_bitfield_struct!($(#[$attribute])* $($vis)* struct $name($t));

        impl $name {
            simple_bitfield_fields!{$t; $($rest)*}
         }
    };
}

#[doc(hidden)]
pub use core::mem::size_of;

/// A trait to get or set ranges of bits.
pub trait BitRange<T> {
    /// Get a range of bits.
    fn bit_range(&self, msb: usize, lsb: usize) -> T;
    /// Set a range of bits.
    fn set_bit_range(&mut self, msb: usize, lsb: usize, value: T);
}

/// A trait to get or set a single bit.
pub trait Bit {
    /// Get a single bit.
    fn bit(&self, bit: usize) -> bool;

    /// Set a single bit.
    fn set_bit(&mut self, bit: usize, value: bool);
}

impl<T: BitRange<u8>> Bit for T {
    fn bit(&self, bit: usize) -> bool {
        self.bit_range(bit, bit) != 0
    }
    fn set_bit(&mut self, bit: usize, value: bool) {
        self.set_bit_range(bit, bit, value as u8);
    }
}

macro_rules! impl_bitrange_for_u {
    ($t:ty, $bitrange_ty:ty) => {
        impl BitRange<$bitrange_ty> for $t {
            #[inline]
            fn bit_range(&self, msb: usize, lsb: usize) -> $bitrange_ty {
                let bit_len = size_of::<$t>()*8;
                ((*self << (bit_len - msb - 1)) >> (bit_len - msb - 1 + lsb)) as $bitrange_ty
            }

            #[inline]
            fn set_bit_range(&mut self, msb: usize, lsb: usize, value: $bitrange_ty) {
                let bit_len = size_of::<$t>()*8;
                let mask: $t = !(0 as $t)
                    << (bit_len - msb - 1)
                    >> (bit_len - msb - 1 + lsb)
                        << (lsb);
                *self &= !mask;
                *self |= (value as $t << lsb) & mask;
            }
        }
    }
}

impl_bitrange_for_u!{u8, u8}
impl_bitrange_for_u!{u16, u8}
impl_bitrange_for_u!{u16, u16}
impl_bitrange_for_u!{u32, u8}
impl_bitrange_for_u!{u32, u16}
impl_bitrange_for_u!{u32, u32}
impl_bitrange_for_u!{u64, u8}
impl_bitrange_for_u!{u64, u16}
impl_bitrange_for_u!{u64, u32}
impl_bitrange_for_u!{u64, u64}

#[doc(hidden)]
#[macro_export]
macro_rules! impl_bitrange_slice {
    ($name:ident, $slice_ty:ty, $bitrange_ty:ty) => {
        impl<T: AsMut<[$slice_ty]> + AsRef<[$slice_ty]>> $crate::BitRange<$bitrange_ty>
            for $name<T> {
            fn bit_range(&self, msb: usize, lsb: usize) -> $bitrange_ty {
                let bit_len = $crate::size_of::<$slice_ty>()*8;
                let mut value = 0;
                for i in (lsb..msb+1).rev() {
                    value <<= 1;
                    value |= ((self.0.as_ref()[i/bit_len] >> (i%bit_len)) & 1) as $bitrange_ty;
                }
                value
            }

            fn set_bit_range(&mut self, msb: usize, lsb: usize, value: $bitrange_ty) {
                let bit_len = $crate::size_of::<$slice_ty>()*8;
                let mut value = value;
                for i in lsb..msb+1 {
                    self.0.as_mut()[i/bit_len] &= !(1 << (i%bit_len));
                    self.0.as_mut()[i/bit_len] |= (value & 1) as $slice_ty << (i%bit_len);
                    value >>= 1;
                }
            }
        }
    }
}

#[doc(hidden)]
#[macro_export]
macro_rules! impl_bitrange_slice_msb0 {
    ($name:ident, $slice_ty:ty, $bitrange_ty:ty) => {
        impl<T: AsMut<[$slice_ty]> + AsRef<[$slice_ty]>> $crate::BitRange<$bitrange_ty>
            for $name<T> {
            fn bit_range(&self, msb: usize, lsb: usize) -> $bitrange_ty {
                let bit_len = $crate::size_of::<$slice_ty>()*8;
                let mut value = 0;
                for i in lsb..msb+1 {
                    value <<= 1;
                    value |= ((self.0.as_ref()[i/bit_len] >> (bit_len - i%bit_len - 1)) & 1)
                        as $bitrange_ty;
                }
                value
            }

            fn set_bit_range(&mut self, msb: usize, lsb: usize, value: $bitrange_ty) {
                let bit_len = $crate::size_of::<$slice_ty>()*8;
                let mut value = value;
                for i in (lsb..msb+1).rev() {
                    self.0.as_mut()[i/bit_len] &= !(1 << (bit_len - i%bit_len - 1));
                    self.0.as_mut()[i/bit_len] |= (value & 1) as $slice_ty
                        << (bit_len - i%bit_len - 1);
                    value >>= 1;
                }
            }
        }
    }
}
<commit_msg>Use an internal rules instead of another macros<commit_after>#![no_std]
#[macro_export]
macro_rules! simple_bitfield_fields {
    (@field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, _, $setter:ident: $msb:expr, $lsb:expr,
     $count:expr) => {
        $(#[$attribute])*
        #[allow(unknown_lints)]
        #[allow(eq_op)]
        $($vis)* fn $setter(&mut self, index: usize, value: $t) {
            use $crate::BitRange;
            debug_assert!(index < $count);
            let width = $msb - $lsb + 1;
            let lsb = $lsb + index*width;
            let msb = lsb + width - 1;
            self.set_bit_range(msb, lsb, value);
        }
    };
    (@field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, _, $setter:ident: $msb:expr, $lsb:expr) => {
        $(#[$attribute])*
        $($vis)* fn $setter(&mut self, value: $t) {
            use $crate::BitRange;
            self.set_bit_range($msb, $lsb, value);
        }
    };
    (@field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, _, $setter:ident: $bit:expr) => {
        $(#[$attribute])*
        $($vis)* fn $setter(&mut self, value: bool) {
            use $crate::Bit;
            self.set_bit($bit, value);
        }
    };
    (@field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $getter:ident, _: $msb:expr, $lsb:expr,
     $count:expr) => {
        $(#[$attribute])*
        #[allow(unknown_lints)]
        #[allow(eq_op)]
        $($vis)* fn $getter(&self, index: usize) -> $t {
            use $crate::BitRange;
            debug_assert!(index < $count);
            let width = $msb - $lsb + 1;
            let lsb = $lsb + index*width;
            let msb = lsb + width - 1;
            self.bit_range(msb, lsb)
        }
    };
    (@field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $getter:ident, _: $msb:expr, $lsb:expr) => {
        $(#[$attribute])*
        $($vis)* fn $getter(&self) -> $t {
            use $crate::BitRange;
            self.bit_range($msb, $lsb)
        }
    };
    (@field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $getter:ident, _: $bit:expr) => {
        $(#[$attribute])*
        $($vis)* fn $getter(&self) -> bool {
            use $crate::Bit;
            self.bit($bit)
        }
    };
    (@field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $getter:ident, $setter:ident:
     $($exprs:expr),*) => {
        simple_bitfield_fields!(@field $(#[$attribute])* ($($vis)*) $t, $getter, _: $($exprs),*);
        simple_bitfield_fields!(@field $(#[$attribute])* ($($vis)*) $t, _, $setter: $($exprs),*);
    };
    ($t:ty;) => {};
    ($default_ty:ty; pub $($rest:tt)*) => {
        simple_bitfield_fields!{$default_ty; () pub $($rest)*}
    };
    ($default_ty:ty; #[$attribute:meta] $($rest:tt)*) => {
        simple_bitfield_fields!{$default_ty; (#[$attribute]) $($rest)*}
    };
    ($default_ty:ty; ($(#[$attributes:meta])*) #[$attribute:meta] $($rest:tt)*) => {
        simple_bitfield_fields!{$default_ty; ($(#[$attributes])* #[$attribute]) $($rest)*}
    };
    ($default_ty:ty; ($(#[$attribute:meta])*) pub $t:ty, $getter:tt, $setter:tt:  $($exprs:expr),*;
     $($rest:tt)*) => {
        simple_bitfield_fields!{@field $(#[$attribute])* (pub) $t, $getter, $setter: $($exprs),*}
        simple_bitfield_fields!{$default_ty; $($rest)*}
    };
    ($default_ty:ty; ($(#[$attribute:meta])*) pub $getter:tt, $setter:tt:  $($exprs:expr),*;
     $($rest:tt)*) => {
        simple_bitfield_fields!{@field $(#[$attribute])* (pub) $default_ty, $getter, $setter:
                                $($exprs),*}
        simple_bitfield_fields!{$default_ty; $($rest)*}
    };
    ($default_ty:ty; ($(#[$attribute:meta])*) $t:ty, $getter:tt, $setter:tt:  $($exprs:expr),*;
     $($rest:tt)*) => {
        simple_bitfield_fields!{@field $(#[$attribute])* () $t, $getter, $setter: $($exprs),*}
        simple_bitfield_fields!{$default_ty; $($rest)*}
    };
    ($default_ty:ty; ($(#[$attribute:meta])*) $getter:tt, $setter:tt:  $($exprs:expr),*;
     $($rest:tt)*) => {
        simple_bitfield_fields!{@field $(#[$attribute])* () $default_ty, $getter, $setter:
                                $($exprs),*}
        simple_bitfield_fields!{$default_ty; $($rest)*}
    };
    ($previous_default_ty:ty; $default_ty:ty; $($rest:tt)*) => {
        simple_bitfield_fields!{$default_ty; $($rest)*}
    };
    ($default_ty:ty; $($rest:tt)*) => {
        simple_bitfield_fields!{$default_ty; () $($rest)*}
    };
}

#[macro_export]
macro_rules! simple_bitfield_struct {
    ($(#[$attribute:meta])* struct $name:ident($($args:tt)*)) => {
        simple_bitfield_struct!($(#[$attribute])* () struct $name($($args)*));
    };
    ($(#[$attribute:meta])* pub struct $name:ident($($args:tt)*))=> {
        simple_bitfield_struct!($(#[$attribute])* (pub) struct $name($($args)*));
    };
    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident([$t:ty])) => {
        $(#[$attribute])*
        $($vis)* struct $name<T>(pub T);

        impl_bitrange_slice!($name, $t, u8);
        impl_bitrange_slice!($name, $t, u16);
        impl_bitrange_slice!($name, $t, u32);
        impl_bitrange_slice!($name, $t, u64);
    };
    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident(MSB0 [$t:ty])) => {
        $(#[$attribute])*
        $($vis)* struct $name<T>(pub T);

        impl_bitrange_slice_msb0!($name, $t, u8);
        impl_bitrange_slice_msb0!($name, $t, u16);
        impl_bitrange_slice_msb0!($name, $t, u32);
        impl_bitrange_slice_msb0!($name, $t, u64);
    };
    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($t:ty)) => {
        $(#[$attribute])*
        $($vis)* struct $name(pub $t);

        impl<T> $crate::BitRange<T> for $name where $t: $crate::BitRange<T> {
            fn bit_range(&self, msb: usize, lsb: usize) -> T {
                self.0.bit_range(msb, lsb)
            }
            fn set_bit_range(&mut self, msb: usize, lsb: usize, value: T) {
                self.0.set_bit_range(msb, lsb, value);
            }
        }
    };
}

#[macro_export]
macro_rules! simple_bitfield {
    ($(#[$attribute:meta])* pub struct $($rest:tt)*) => {
        simple_bitfield!($(#[$attribute])* (pub) struct $($rest)*);
    };
    ($(#[$attribute:meta])* struct $($rest:tt)*) => {
        simple_bitfield!($(#[$attribute])* () struct $($rest)*);
    };
    ($(#[$attribute:meta])* ($($vis:tt)* )struct $name:ident([$t:ty]); $($rest:tt)*) => {
        simple_bitfield_struct!($(#[$attribute])* $($vis)* struct $name([$t]));

        impl<T: AsMut<[$t]> + AsRef<[$t]>> $name<T> {
            simple_bitfield_fields!{u64; $($rest)*}
        }
    };
    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident(MSB0 [$t:ty]); $($rest:tt)*) => {
        simple_bitfield_struct!($(#[$attribute])* $($vis)* struct $name(MSB0 [$t]));

        impl<T: AsMut<[$t]> + AsRef<[$t]>> $name<T> {
            simple_bitfield_fields!{u64; $($rest)*}
        }
    };
    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($t:ty); $($rest:tt)*) => {
        simple_bitfield_struct!($(#[$attribute])* $($vis)* struct $name($t));

        impl $name {
            simple_bitfield_fields!{$t; $($rest)*}
         }
    };
}

#[doc(hidden)]
pub use core::mem::size_of;

/// A trait to get or set ranges of bits.
pub trait BitRange<T> {
    /// Get a range of bits.
    fn bit_range(&self, msb: usize, lsb: usize) -> T;
    /// Set a range of bits.
    fn set_bit_range(&mut self, msb: usize, lsb: usize, value: T);
}

/// A trait to get or set a single bit.
pub trait Bit {
    /// Get a single bit.
    fn bit(&self, bit: usize) -> bool;

    /// Set a single bit.
    fn set_bit(&mut self, bit: usize, value: bool);
}

impl<T: BitRange<u8>> Bit for T {
    fn bit(&self, bit: usize) -> bool {
        self.bit_range(bit, bit) != 0
    }
    fn set_bit(&mut self, bit: usize, value: bool) {
        self.set_bit_range(bit, bit, value as u8);
    }
}

macro_rules! impl_bitrange_for_u {
    ($t:ty, $bitrange_ty:ty) => {
        impl BitRange<$bitrange_ty> for $t {
            #[inline]
            fn bit_range(&self, msb: usize, lsb: usize) -> $bitrange_ty {
                let bit_len = size_of::<$t>()*8;
                ((*self << (bit_len - msb - 1)) >> (bit_len - msb - 1 + lsb)) as $bitrange_ty
            }

            #[inline]
            fn set_bit_range(&mut self, msb: usize, lsb: usize, value: $bitrange_ty) {
                let bit_len = size_of::<$t>()*8;
                let mask: $t = !(0 as $t)
                    << (bit_len - msb - 1)
                    >> (bit_len - msb - 1 + lsb)
                        << (lsb);
                *self &= !mask;
                *self |= (value as $t << lsb) & mask;
            }
        }
    }
}

impl_bitrange_for_u!{u8, u8}
impl_bitrange_for_u!{u16, u8}
impl_bitrange_for_u!{u16, u16}
impl_bitrange_for_u!{u32, u8}
impl_bitrange_for_u!{u32, u16}
impl_bitrange_for_u!{u32, u32}
impl_bitrange_for_u!{u64, u8}
impl_bitrange_for_u!{u64, u16}
impl_bitrange_for_u!{u64, u32}
impl_bitrange_for_u!{u64, u64}

#[doc(hidden)]
#[macro_export]
macro_rules! impl_bitrange_slice {
    ($name:ident, $slice_ty:ty, $bitrange_ty:ty) => {
        impl<T: AsMut<[$slice_ty]> + AsRef<[$slice_ty]>> $crate::BitRange<$bitrange_ty>
            for $name<T> {
            fn bit_range(&self, msb: usize, lsb: usize) -> $bitrange_ty {
                let bit_len = $crate::size_of::<$slice_ty>()*8;
                let mut value = 0;
                for i in (lsb..msb+1).rev() {
                    value <<= 1;
                    value |= ((self.0.as_ref()[i/bit_len] >> (i%bit_len)) & 1) as $bitrange_ty;
                }
                value
            }

            fn set_bit_range(&mut self, msb: usize, lsb: usize, value: $bitrange_ty) {
                let bit_len = $crate::size_of::<$slice_ty>()*8;
                let mut value = value;
                for i in lsb..msb+1 {
                    self.0.as_mut()[i/bit_len] &= !(1 << (i%bit_len));
                    self.0.as_mut()[i/bit_len] |= (value & 1) as $slice_ty << (i%bit_len);
                    value >>= 1;
                }
            }
        }
    }
}

#[doc(hidden)]
#[macro_export]
macro_rules! impl_bitrange_slice_msb0 {
    ($name:ident, $slice_ty:ty, $bitrange_ty:ty) => {
        impl<T: AsMut<[$slice_ty]> + AsRef<[$slice_ty]>> $crate::BitRange<$bitrange_ty>
            for $name<T> {
            fn bit_range(&self, msb: usize, lsb: usize) -> $bitrange_ty {
                let bit_len = $crate::size_of::<$slice_ty>()*8;
                let mut value = 0;
                for i in lsb..msb+1 {
                    value <<= 1;
                    value |= ((self.0.as_ref()[i/bit_len] >> (bit_len - i%bit_len - 1)) & 1)
                        as $bitrange_ty;
                }
                value
            }

            fn set_bit_range(&mut self, msb: usize, lsb: usize, value: $bitrange_ty) {
                let bit_len = $crate::size_of::<$slice_ty>()*8;
                let mut value = value;
                for i in (lsb..msb+1).rev() {
                    self.0.as_mut()[i/bit_len] &= !(1 << (bit_len - i%bit_len - 1));
                    self.0.as_mut()[i/bit_len] |= (value & 1) as $slice_ty
                        << (bit_len - i%bit_len - 1);
                    value >>= 1;
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>#![deny(missing_docs)]

//! Interpolation algorithms.
//!
//! Interpolation is used in animation,
//! to describe smooth shapes and to make transitions.
//! Any object that fullfill certain mathematical
//! properties can be interpolated.
//! A common technique is using one or more 'numbers'
//! controlling the mixture of states.
//! The choice of interpolation algorithm depends often
//! on the circumstances where it used.

pub use ease::{ Ease, EaseFunction };
pub use spatial::Spatial;

mod ease;
mod spatial;

/// Performs linear interpolation.
/// A linear interpolation consists of two states 'a' and 'b'.
/// The 't' variable is a factor between 0 and 1 that
/// gives weight to 'a' or 'b'.
/// When 't' is zero then 'a' has full weight.
/// When 't' is one then 'b' has full weight.
#[inline(always)]
pub fn lerp<T: Spatial>(a: &T, b: &T, t: &T::Scalar) -> T {
    a.add(&b.sub(a).scale(t))
}

/// Performs quadratic beziér interpolation.
/// This is done by nesting linear interpolations.
/// For more information, see:
///
/// Beziér Curve at Wikipedia
#[inline(always)]
pub fn quad_bez<T: Spatial>(
    x0: &T,
    x1: &T,
    x2: &T,
    t: &T::Scalar
) -> T {
    let x_0_1 = lerp(x0, x1, t);
    let x_1_2 = lerp(x1, x2, t);
    lerp(&x_0_1, &x_1_2, t)
}

/// Performs cubic beziér interpolation.
/// This is done by interpolation between two quadratic beziér.
/// For more information, see:
///
/// Beziér Curve at Wikipedia
#[inline(always)]
pub fn cub_bez<T: Spatial>(
    x0: &T,
    x1: &T,
    x2: &T,
    x3: &T,
    t: &T::Scalar
) -> T {
    let x_0_2 = quad_bez(x0, x1, x2, t);
    let x_1_3 = quad_bez(x1, x2, x3, t);
    lerp(&x_0_2, &x_1_3, t)
}
<commit_msg>Use markdown instead of html for url link.<commit_after>#![deny(missing_docs)]

//! Interpolation algorithms.
//!
//! Interpolation is used in animation,
//! to describe smooth shapes and to make transitions.
//! Any object that fullfill certain mathematical
//! properties can be interpolated.
//! A common technique is using one or more 'numbers'
//! controlling the mixture of states.
//! The choice of interpolation algorithm depends often
//! on the circumstances where it used.

pub use ease::{ Ease, EaseFunction };
pub use spatial::Spatial;

mod ease;
mod spatial;

/// Performs linear interpolation.
/// A linear interpolation consists of two states 'a' and 'b'.
/// The 't' variable is a factor between 0 and 1 that
/// gives weight to 'a' or 'b'.
/// When 't' is zero then 'a' has full weight.
/// When 't' is one then 'b' has full weight.
#[inline(always)]
pub fn lerp<T: Spatial>(a: &T, b: &T, t: &T::Scalar) -> T {
    a.add(&b.sub(a).scale(t))
}

/// Performs quadratic beziér interpolation.
/// This is done by nesting linear interpolations.
/// For more information, see:
///
/// [Beziér Curve at Wikipedia](http://en.wikipedia.org/wiki/B%C3%A9zier_curve)
#[inline(always)]
pub fn quad_bez<T: Spatial>(
    x0: &T,
    x1: &T,
    x2: &T,
    t: &T::Scalar
) -> T {
    let x_0_1 = lerp(x0, x1, t);
    let x_1_2 = lerp(x1, x2, t);
    lerp(&x_0_1, &x_1_2, t)
}

/// Performs cubic beziér interpolation.
/// This is done by interpolation between two quadratic beziér.
/// For more information, see:
///
/// [Beziér Curve at Wikipedia](http://en.wikipedia.org/wiki/B%C3%A9zier_curve)
#[inline(always)]
pub fn cub_bez<T: Spatial>(
    x0: &T,
    x1: &T,
    x2: &T,
    x3: &T,
    t: &T::Scalar
) -> T {
    let x_0_2 = quad_bez(x0, x1, x2, t);
    let x_1_3 = quad_bez(x1, x2, x3, t);
    lerp(&x_0_2, &x_1_3, t)
}
<|endoftext|>


<commit_before>//! This is a library for controlling a cursor and a screen,
//! on ANSI terminals.
//!
//!
//! ## Example
//!
//!     use ansi_control::*;
//!

use std::cmp::{self, Ordering};

/// A Pos is position of clearing (display|line) from cursor.
pub enum Pos {
    Back,
    Front,
    Both,
}

impl Pos {
    fn num(&self) -> u32 {
        match *self {
            Pos::Back   => 0,
            Pos::Front  => 1,
            Pos::Both   => 2,
        }
    }
}

/// Moves the cursor _i_ (row), _j_ (column) cells. If the cursor
/// is already at the edge of the screen, this has no effect.
pub fn move_cursor(i: i32, j: i32) -> String {
    let code0 = match i.cmp(&0) {
        Ordering::Less      => format!("\x1B[{}B", -i),
        Ordering::Equal     => format!(""),
        Ordering::Greater   => format!("\x1B[{}A", i),
    };
    let code1 = match j.cmp(&0) {
        Ordering::Less      => format!("\x1B[{}D", -j),
        Ordering::Equal     => format!(""),
        Ordering::Greater   => format!("\x1B[{}C", j),
    };
    format!("{}{}", code0, code1)
}

/// Moves the cursor to beginning of the line _n_ lines down.
/// If _n_ is a negative number, this function moves the cursor
/// _|n|_ lines up.
pub fn move_line(n: i32) -> String {
    match n.cmp(&0) {
        Ordering::Less      => format!("\x1B[{}F", -n),
        Ordering::Equal     => format!(""),
        Ordering::Greater   => format!("\x1B[{}E", n),
    }
}

/// Sets the column of the cursor. (n: column)
pub fn set_column(n: u32) -> String {
    format!("\x1B[{}G", cmp::max(1, n))
}

/// Sets the position of the cursor. (i: row, j: column)
pub fn set_position(i: u32, j: u32) -> String {
    format!("\x1B[{};{}H", cmp::max(1, i), cmp::max(1, j))
}

/// Clears part of screen. If pos is Pos::Back, clear from cursor
/// to the end of the screen. If pos is Pos::Front, clear from
/// cursor to beginning of the screen. If pos is Pos::Both, clear
/// entire screen.
pub fn clear_display(pos: Pos) -> String {
    let num = match pos {
        Pos::Back   => 0,
        Pos::Front  => 1,
        Pos::Both   => 2,
    };
    format!("\x1B[{}J", num)
}

/// Clears part of line. If pos is Pos::Back, clear from cursor
/// to the end of the line. If pos is Pos::Front, clear from
/// cursor to beginning of the line. If pos is Pos::Both, clear
/// entire line.
pub fn clear_line(pos: Pos) -> String {
    format!("")
}

/// Scroll whole page up by _n_ lines. If _n_ is a negative
/// number, this function scroll whole page down by _|n|_ lines.
pub fn scroll(n: i32) -> String {
    format!("")
}

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

    macro_rules! test {
        ($name: ident; $ctrl: expr => $result: expr) => {
            #[test]
            fn $name() {
                assert_eq!($result, $ctrl)
            }
        };
    }

    test!(move_cursor0; move_cursor(2, -4) => "\x1B[2A\x1B[4D");
    test!(move_cursor1; move_cursor(-2, 0) => "\x1B[2B");
    test!(move_cursor2; move_cursor(0, 6) => "\x1B[6C");
    test!(move_cursor3; move_cursor(0, 0) => "");

    test!(move_line0; move_line(4) => "\x1B[4E");
    test!(move_line1; move_line(-4) => "\x1B[4F");

    test!(set_column0; set_column(3) => "\x1B[3G");
    test!(set_column1; set_column(0) => "\x1B[1G");

    test!(set_position0; set_position(3, 5) => "\x1B[3;5H");
    test!(set_position1; set_position(0, 0) => "\x1B[1;1H");

    test!(clear_display0; clear_display(Pos::Back) => "\x1B[0J");
    test!(clear_display1; clear_display(Pos::Front) => "\x1B[1J");
    test!(clear_display2; clear_display(Pos::Both) => "\x1B[2J");

    test!(clear_line0; clear_line(Pos::Back) => "\x1B[0K");
    test!(clear_line1; clear_line(Pos::Front) => "\x1B[1K");
    test!(clear_line2; clear_line(Pos::Both) => "\x1B[2K");

    test!(scroll0; scroll(7) => "\x1B[7S");
    test!(scroll1; scroll(-5) => "\x1B[5T");
}
<commit_msg>Use Pos::num in clear_display<commit_after>//! This is a library for controlling a cursor and a screen,
//! on ANSI terminals.
//!
//!
//! ## Example
//!
//!     use ansi_control::*;
//!

use std::cmp::{self, Ordering};

/// A Pos is position of clearing (display|line) from cursor.
pub enum Pos {
    Back,
    Front,
    Both,
}

impl Pos {
    fn num(&self) -> u32 {
        match *self {
            Pos::Back   => 0,
            Pos::Front  => 1,
            Pos::Both   => 2,
        }
    }
}

/// Moves the cursor _i_ (row), _j_ (column) cells. If the cursor
/// is already at the edge of the screen, this has no effect.
pub fn move_cursor(i: i32, j: i32) -> String {
    let code0 = match i.cmp(&0) {
        Ordering::Less      => format!("\x1B[{}B", -i),
        Ordering::Equal     => format!(""),
        Ordering::Greater   => format!("\x1B[{}A", i),
    };
    let code1 = match j.cmp(&0) {
        Ordering::Less      => format!("\x1B[{}D", -j),
        Ordering::Equal     => format!(""),
        Ordering::Greater   => format!("\x1B[{}C", j),
    };
    format!("{}{}", code0, code1)
}

/// Moves the cursor to beginning of the line _n_ lines down.
/// If _n_ is a negative number, this function moves the cursor
/// _|n|_ lines up.
pub fn move_line(n: i32) -> String {
    match n.cmp(&0) {
        Ordering::Less      => format!("\x1B[{}F", -n),
        Ordering::Equal     => format!(""),
        Ordering::Greater   => format!("\x1B[{}E", n),
    }
}

/// Sets the column of the cursor. (n: column)
pub fn set_column(n: u32) -> String {
    format!("\x1B[{}G", cmp::max(1, n))
}

/// Sets the position of the cursor. (i: row, j: column)
pub fn set_position(i: u32, j: u32) -> String {
    format!("\x1B[{};{}H", cmp::max(1, i), cmp::max(1, j))
}

/// Clears part of screen. If pos is Pos::Back, clear from cursor
/// to the end of the screen. If pos is Pos::Front, clear from
/// cursor to beginning of the screen. If pos is Pos::Both, clear
/// entire screen.
pub fn clear_display(pos: Pos) -> String {
    format!("\x1B[{}J", pos.num())
}

/// Clears part of line. If pos is Pos::Back, clear from cursor
/// to the end of the line. If pos is Pos::Front, clear from
/// cursor to beginning of the line. If pos is Pos::Both, clear
/// entire line.
pub fn clear_line(pos: Pos) -> String {
    format!("")
}

/// Scroll whole page up by _n_ lines. If _n_ is a negative
/// number, this function scroll whole page down by _|n|_ lines.
pub fn scroll(n: i32) -> String {
    format!("")
}

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

    macro_rules! test {
        ($name: ident; $ctrl: expr => $result: expr) => {
            #[test]
            fn $name() {
                assert_eq!($result, $ctrl)
            }
        };
    }

    test!(move_cursor0; move_cursor(2, -4) => "\x1B[2A\x1B[4D");
    test!(move_cursor1; move_cursor(-2, 0) => "\x1B[2B");
    test!(move_cursor2; move_cursor(0, 6) => "\x1B[6C");
    test!(move_cursor3; move_cursor(0, 0) => "");

    test!(move_line0; move_line(4) => "\x1B[4E");
    test!(move_line1; move_line(-4) => "\x1B[4F");

    test!(set_column0; set_column(3) => "\x1B[3G");
    test!(set_column1; set_column(0) => "\x1B[1G");

    test!(set_position0; set_position(3, 5) => "\x1B[3;5H");
    test!(set_position1; set_position(0, 0) => "\x1B[1;1H");

    test!(clear_display0; clear_display(Pos::Back) => "\x1B[0J");
    test!(clear_display1; clear_display(Pos::Front) => "\x1B[1J");
    test!(clear_display2; clear_display(Pos::Both) => "\x1B[2J");

    test!(clear_line0; clear_line(Pos::Back) => "\x1B[0K");
    test!(clear_line1; clear_line(Pos::Front) => "\x1B[1K");
    test!(clear_line2; clear_line(Pos::Both) => "\x1B[2K");

    test!(scroll0; scroll(7) => "\x1B[7S");
    test!(scroll1; scroll(-5) => "\x1B[5T");
}
<|endoftext|>


<commit_before>//! A Rust representation of Abstract Syntax Trees of Erlang modules
//!
//! See: [The Abstract Format](http://erlang.org/doc/apps/erts/absform.html)
extern crate beam_file;
extern crate eetf;
extern crate num;

pub mod ast;
pub mod result;
pub mod error;
pub mod format;

use std::path::Path;

/// Abstract Syntax Tree
#[derive(Debug)]
pub struct AST {
    pub module: ast::ModuleDecl,
}
impl AST {
    /// Builds AST from the BEAM file
    pub fn from_beam_file<P: AsRef<Path>>(beam_file: P) -> result::FromBeamResult<Self> {
        let code = try!(format::raw_abstract_v1::AbstractCode::from_beam_file(beam_file));
        let forms = try!(code.to_forms());
        Ok(AST { module: ast::ModuleDecl { forms: forms } })
    }
}

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

    #[test]
    fn it_works() {
        AST::from_beam_file("src/testdata/test.beam")
            .map_err(|err| {
                println!("[ERROR] {}", err);
                "Failed"
            })
            .unwrap();
    }
}
<commit_msg>Add top-level documents<commit_after>//! A Rust representation of Abstract Syntax Trees of Erlang modules.
//!
//! Currently the library provide only a functionality that
//! loading ASTs from beam files which have debug infos.
//!
//! See also: [The Abstract Format](http://erlang.org/doc/apps/erts/absform.html)
//!
//! # Examples
//!
//! ```
//! use erl_ast::AST;
//!
//! let ast = AST::from_beam_file("src/testdata/test.beam").unwrap();
//! println!("{:?}", ast);
//! ```
extern crate beam_file;
extern crate eetf;
extern crate num;

pub mod ast;
pub mod result;
pub mod error;
pub mod format;

use std::path::Path;

/// Abstract Syntax Tree
#[derive(Debug)]
pub struct AST {
    pub module: ast::ModuleDecl,
}
impl AST {
    /// Builds AST from the BEAM file
    pub fn from_beam_file<P: AsRef<Path>>(beam_file: P) -> result::FromBeamResult<Self> {
        let code = try!(format::raw_abstract_v1::AbstractCode::from_beam_file(beam_file));
        let forms = try!(code.to_forms());
        Ok(AST { module: ast::ModuleDecl { forms: forms } })
    }
}

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

    #[test]
    fn it_works() {
        AST::from_beam_file("src/testdata/test.beam")
            .map_err(|err| {
                println!("[ERROR] {}", err);
                "Failed"
            })
            .unwrap();
    }
}
<|endoftext|>


<commit_before>//! # `derive_more`
//! Rust has lots of builtin traits that are implemented for its basic types, such as [`Add`],
//! [`Not`] or [`From`].
//! However, when wrapping these types inside your own structs or enums you lose the
//! implementations of these traits and are required to recreate them.
//! This is especially annoying when your own structures are very simple, such as when using the
//! commonly advised newtype pattern (e.g. `MyInt(i32)`).
//!
//! This library tries to remove these annoyances and the corresponding boilerplate code.
//! It does this by allowing you to derive lots of commonly used traits for both structs and enums.
//!
//! ## Example code
//!
//! By using this library the following code just works:
//!
//!
//! ```rust
//! # #[macro_use] extern crate derive_more;
//!
//! #[derive(Debug, Eq, PartialEq, From, Add)]
//! struct MyInt(i32);
//!
//! #[derive(Debug, Eq, PartialEq, From, Into, Constructor, Mul)]
//! struct Point2D {
//!     x: i32,
//!     y: i32,
//! }
//!
//! #[derive(Debug, Eq, PartialEq, From, Add)]
//! enum MyEnum {
//!     Int(i32),
//!     UnsignedInt(u32),
//!     Nothing,
//! }
//!
//! fn main() {
//!     let my_11 = MyInt(5) + 6.into();
//!     assert_eq!(MyInt(11), MyInt(5) + 6.into());
//!     assert_eq!(Point2D { x: 5, y: 6 } * 10, (50, 60).into());
//!     assert_eq!((5, 6), Point2D { x: 5, y: 6 }.into());
//!     assert_eq!(Point2D { x: 5, y: 6 }, Point2D::new(5, 6));
//!     assert_eq!(MyEnum::Int(15), (MyEnum::Int(8) + 7.into()).unwrap())
//! }
//! ```
//!
//! ## The derivable traits
//!
//! Below are all the traits that you can derive using this library.
//! Some trait derivations are so similar that the furter documentation will only show a single one
//! of them.
//! You can recognize these by the "-like" suffix in their name.
//! The trait name before that will be the only one that is used throughout the further
//! documentation.
//!
//! **NOTE**: You still have to derive each trait separately. So `#[derive(Mul)]` doesn't
//! automatically derive `Div` as well. To derive both you should do `#[derive(Mul, Div)]`
//!
//! ### Conversion traits
//! These are traits that are used to convert automatically between types.
//!
//! 1. [`From`]
//! 2. [`Into`]
//!
//! ### Single field forwarding traits
//! These traits can only be derived for structs that have a single field, usually these are
//! newtypes such as `MyInt(32)`.
//!
//! 1. [`FromStr`]
//! 2. `Display`-like, contains [`Display`], [`Binary`], [`Octal`], [`LowerHex`], [`UpperHex`],
//!    [`LowerExp`], [`UpperExp`], [`Pointer`]
//!
//! ### Operators
//! These are traits that can be used for operator overloading.
//!
//! 1. `Not`-like, contains [`Not`] and [`Neg`]
//! 2. `Add`-like, contains [`Add`], [`Sub`], [`BitAnd`], [`BitOr`] and [`BitXor`]
//! 3. `AddAssign`-like, contains [`AddAssign`], [`SubAssign`], [`BitAndAssign`], [`BitOrAssign`]
//!    and [`BitXorAssign`]
//! 4. `Mul`-like, contains [`Mul`], [`Div`], [`Rem`], [`Shr`] and [`Shl`]
//! 5. `MulAssign`-like, contains [`MulAssign`], [`DivAssign`], [`RemAssign`], [`ShrAssign`] and
//!    [`ShlAssign`]
//!
//! ### Static methods
//! These don't derive traits, but derive static methods instead.
//!
//! 1. `Constructor`, this derives a `new` method that can be used as a constructor. This is very
//!    basic if you need more customization for your constructor, check out the [`derive-new`] crate.
//!
//!
//! ## Generated code
//!
//! It is important to understand what code gets generated when using one of the derives from this
//! crate.
//! That is why the links below explain what code gets generated for a trait for each group from
//! before.
//!
//! 1. [`#[derive(From)]`](from.html)
//! 2. [`#[derive(Into)]`](into.html)
//! 3. [`#[derive(FromStr)]`](from_str.html)
//! 4. [`#[derive(Display)]`](display.html)
//! 5. [`#[derive(Not)]`](not.html)
//! 6. [`#[derive(Add)]`](add.html)
//! 7. [`#[derive(AddAssign)]`](add_assign.html)
//! 8. [`#[derive(Mul)]`](mul.html)
//! 9. [`#[derive(MulAssign)]`](mul_assign.html)
//! 10. [`#[derive(Constructor)]`](constructor.html)
//!
//! If you want to be sure what code is generated for your specific type I recommend using the
//! [`cargo-expand`] utility.
//! This will show you your code with all macros and derives expanded.
//!
//! ## Installation
//!
//! This library requires Rust 1.15 or higher, so this needs to be installed.
//! Then add the following to `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! derive_more = "0.6.0"
//! ```
//!
//! And this to the top of your Rust file:
//!
//! ```rust
//! #[macro_use]
//! extern crate derive_more;
//! # fn main () {}
//! ```
//!
//! [`cargo-expand`]: https://github.com/dtolnay/cargo-expand
//! [`derive-new`]: https://github.com/nrc/derive-new
//! [`From`]: https://doc.rust-lang.org/core/convert/trait.From.html
//! [`Into`]: https://doc.rust-lang.org/core/convert/trait.Into.html
//! [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html
//! [`Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html
//! [`Binary`]: https://doc.rust-lang.org/std/fmt/trait.Binary.html
//! [`Octal`]: https://doc.rust-lang.org/std/fmt/trait.Octal.html
//! [`LowerHex`]: https://doc.rust-lang.org/std/fmt/trait.LowerHex.html
//! [`UpperHex`]: https://doc.rust-lang.org/std/fmt/trait.UpperHex.html
//! [`LowerExp`]: https://doc.rust-lang.org/std/fmt/trait.LowerExp.html
//! [`UpperExp`]: https://doc.rust-lang.org/std/fmt/trait.UpperExp.html
//! [`Pointer`]: https://doc.rust-lang.org/std/fmt/trait.Pointer.html
//! [`Not`]: https://doc.rust-lang.org/std/ops/trait.Not.html
//! [`Neg`]: https://doc.rust-lang.org/std/ops/trait.Neg.html
//! [`Add`]: https://doc.rust-lang.org/std/ops/trait.Add.html
//! [`Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
//! [`BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
//! [`BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
//! [`BitXor`]: https://doc.rust-lang.org/std/ops/trait.BitXor.html
//! [`AddAssign`]: https://doc.rust-lang.org/std/ops/trait.AddAssign.html
//! [`SubAssign`]: https://doc.rust-lang.org/std/ops/trait.SubAssign.html
//! [`BitAndAssign`]: https://doc.rust-lang.org/std/ops/trait.BitAndAssign.html
//! [`BitOrAssign`]: https://doc.rust-lang.org/std/ops/trait.BitOrAssign.html
//! [`BitXorAssign`]: https://doc.rust-lang.org/std/ops/trait.BitXorAssign.html
//! [`Mul`]: https://doc.rust-lang.org/std/ops/trait.Mul.html
//! [`Div`]: https://doc.rust-lang.org/std/ops/trait.Div.html
//! [`Rem`]: https://doc.rust-lang.org/std/ops/trait.Rem.html
//! [`Shr`]: https://doc.rust-lang.org/std/ops/trait.Shr.html
//! [`Shl`]: https://doc.rust-lang.org/std/ops/trait.Shl.html
//! [`MulAssign`]: https://doc.rust-lang.org/std/ops/trait.MulAssign.html
//! [`DivAssign`]: https://doc.rust-lang.org/std/ops/trait.DivAssign.html
//! [`RemAssign`]: https://doc.rust-lang.org/std/ops/trait.RemAssign.html
//! [`ShrAssign`]: https://doc.rust-lang.org/std/ops/trait.ShrAssign.html
//! [`ShlAssign`]: https://doc.rust-lang.org/std/ops/trait.ShlAssign.html

extern crate proc_macro;
#[macro_use]
extern crate quote;
extern crate syn;

use proc_macro::TokenStream;

mod utils;

mod from;
mod into;
mod constructor;
mod not_like;
mod add_like;
mod add_assign_like;
mod mul_like;
mod mul_assign_like;
mod from_str;
mod display;
mod index;

macro_rules! create_derive(
    ($mod_:ident, $trait_:ident, $fn_name: ident) => {
        #[proc_macro_derive($trait_)]
        #[doc(hidden)]
        pub fn $fn_name(input: TokenStream) -> TokenStream {
            let ast = syn::parse(input).unwrap();
            $mod_::expand(&ast, stringify!($trait_)).into()
        }
    }
);

create_derive!(from, From, from_derive);

create_derive!(into, Into, into_derive);

create_derive!(constructor, Constructor, constructor_derive);

create_derive!(not_like, Not, not_derive);
create_derive!(not_like, Neg, neg_derive);

create_derive!(add_like, Add, add_derive);
create_derive!(add_like, Sub, sub_derive);
create_derive!(add_like, BitAnd, bit_and_derive);
create_derive!(add_like, BitOr, bit_or_derive);
create_derive!(add_like, BitXor, bit_xor_derive);

create_derive!(mul_like, Mul, mul_derive);
create_derive!(mul_like, Div, div_derive);
create_derive!(mul_like, Rem, rem_derive);
create_derive!(mul_like, Shr, shr_derive);
create_derive!(mul_like, Shl, shl_derive);

create_derive!(add_assign_like, AddAssign, add_assign_derive);
create_derive!(add_assign_like, SubAssign, sub_assign_derive);
create_derive!(add_assign_like, BitAndAssign, bit_and_assign_derive);
create_derive!(add_assign_like, BitOrAssign, bit_or_assign_derive);
create_derive!(add_assign_like, BitXorAssign, bit_xor_assign_derive);

create_derive!(mul_assign_like, MulAssign, mul_assign_derive);
create_derive!(mul_assign_like, DivAssign, div_assign_derive);
create_derive!(mul_assign_like, RemAssign, rem_assign_derive);
create_derive!(mul_assign_like, ShrAssign, shr_assign_derive);
create_derive!(mul_assign_like, ShlAssign, shl_assign_derive);

create_derive!(from_str, FromStr, from_str_derive);

create_derive!(display, Display, display_derive);
create_derive!(display, Binary, binary_derive);
create_derive!(display, Octal, octal_derive);
create_derive!(display, LowerHex, lower_hex_derive);
create_derive!(display, UpperHex, upper_hex_derive);
create_derive!(display, LowerExp, lower_exp_derive);
create_derive!(display, UpperExp, upper_exp_derive);
create_derive!(display, Pointer, pointer_derive);

create_derive!(index, Index, index_derive);
<commit_msg>Docs: Add Index to the doc homepage<commit_after>//! # `derive_more`
//! Rust has lots of builtin traits that are implemented for its basic types, such as [`Add`],
//! [`Not`] or [`From`].
//! However, when wrapping these types inside your own structs or enums you lose the
//! implementations of these traits and are required to recreate them.
//! This is especially annoying when your own structures are very simple, such as when using the
//! commonly advised newtype pattern (e.g. `MyInt(i32)`).
//!
//! This library tries to remove these annoyances and the corresponding boilerplate code.
//! It does this by allowing you to derive lots of commonly used traits for both structs and enums.
//!
//! ## Example code
//!
//! By using this library the following code just works:
//!
//!
//! ```rust
//! # #[macro_use] extern crate derive_more;
//!
//! #[derive(Debug, Eq, PartialEq, From, Add)]
//! struct MyInt(i32);
//!
//! #[derive(Debug, Eq, PartialEq, From, Into, Constructor, Mul)]
//! struct Point2D {
//!     x: i32,
//!     y: i32,
//! }
//!
//! #[derive(Debug, Eq, PartialEq, From, Add)]
//! enum MyEnum {
//!     Int(i32),
//!     UnsignedInt(u32),
//!     Nothing,
//! }
//!
//! fn main() {
//!     let my_11 = MyInt(5) + 6.into();
//!     assert_eq!(MyInt(11), MyInt(5) + 6.into());
//!     assert_eq!(Point2D { x: 5, y: 6 } * 10, (50, 60).into());
//!     assert_eq!((5, 6), Point2D { x: 5, y: 6 }.into());
//!     assert_eq!(Point2D { x: 5, y: 6 }, Point2D::new(5, 6));
//!     assert_eq!(MyEnum::Int(15), (MyEnum::Int(8) + 7.into()).unwrap())
//! }
//! ```
//!
//! ## The derivable traits
//!
//! Below are all the traits that you can derive using this library.
//! Some trait derivations are so similar that the furter documentation will only show a single one
//! of them.
//! You can recognize these by the "-like" suffix in their name.
//! The trait name before that will be the only one that is used throughout the further
//! documentation.
//!
//! **NOTE**: You still have to derive each trait separately. So `#[derive(Mul)]` doesn't
//! automatically derive `Div` as well. To derive both you should do `#[derive(Mul, Div)]`
//!
//! ### Conversion traits
//! These are traits that are used to convert automatically between types.
//!
//! 1. [`From`]
//! 2. [`Into`]
//! 3. [`FromStr`]
//!
//! ### Formatting traits
//! These traits are used for converting a struct to a string in different ways.
//!
//! 1. `Display`-like, contains [`Display`], [`Binary`], [`Octal`], [`LowerHex`], [`UpperHex`],
//!    [`LowerExp`], [`UpperExp`], [`Pointer`]
//!
//! ### Operators
//! These are traits that can be used for operator overloading.
//!
//! 1. [`Index`]
//! 2. `Not`-like, contains [`Not`] and [`Neg`]
//! 3. `Add`-like, contains [`Add`], [`Sub`], [`BitAnd`], [`BitOr`] and [`BitXor`]
//!    and [`BitXorAssign`]
//! 4. `Mul`-like, contains [`Mul`], [`Div`], [`Rem`], [`Shr`] and [`Shl`]
//! 5. `AddAssign`-like, contains [`AddAssign`], [`SubAssign`], [`BitAndAssign`], [`BitOrAssign`]
//! 6. `MulAssign`-like, contains [`MulAssign`], [`DivAssign`], [`RemAssign`], [`ShrAssign`] and
//!    [`ShlAssign`]
//!
//! ### Static methods
//! These don't derive traits, but derive static methods instead.
//!
//! 1. `Constructor`, this derives a `new` method that can be used as a constructor. This is very
//!    basic if you need more customization for your constructor, check out the [`derive-new`] crate.
//!
//!
//! ## Generated code
//!
//! It is important to understand what code gets generated when using one of the derives from this
//! crate.
//! That is why the links below explain what code gets generated for a trait for each group from
//! before.
//!
//! 1. [`#[derive(From)]`](from.html)
//! 2. [`#[derive(Into)]`](into.html)
//! 3. [`#[derive(FromStr)]`](from_str.html)
//! 4. [`#[derive(Display)]`](display.html)
//! 7. [`#[derive(Index)]`](index.html)
//! 5. [`#[derive(Not)]`](not.html)
//! 6. [`#[derive(Add)]`](add.html)
//! 7. [`#[derive(Mul)]`](mul.html)
//! 8. [`#[derive(AddAssign)]`](add_assign.html)
//! 9. [`#[derive(MulAssign)]`](mul_assign.html)
//! 10. [`#[derive(Constructor)]`](constructor.html)
//!
//! If you want to be sure what code is generated for your specific type I recommend using the
//! [`cargo-expand`] utility.
//! This will show you your code with all macros and derives expanded.
//!
//! ## Installation
//!
//! This library requires Rust 1.15 or higher, so this needs to be installed.
//! Then add the following to `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! derive_more = "0.6.0"
//! ```
//!
//! And this to the top of your Rust file:
//!
//! ```rust
//! #[macro_use]
//! extern crate derive_more;
//! # fn main () {}
//! ```
//!
//! [`cargo-expand`]: https://github.com/dtolnay/cargo-expand
//! [`derive-new`]: https://github.com/nrc/derive-new
//! [`From`]: https://doc.rust-lang.org/core/convert/trait.From.html
//! [`Into`]: https://doc.rust-lang.org/core/convert/trait.Into.html
//! [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html
//! [`Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html
//! [`Binary`]: https://doc.rust-lang.org/std/fmt/trait.Binary.html
//! [`Octal`]: https://doc.rust-lang.org/std/fmt/trait.Octal.html
//! [`LowerHex`]: https://doc.rust-lang.org/std/fmt/trait.LowerHex.html
//! [`UpperHex`]: https://doc.rust-lang.org/std/fmt/trait.UpperHex.html
//! [`LowerExp`]: https://doc.rust-lang.org/std/fmt/trait.LowerExp.html
//! [`UpperExp`]: https://doc.rust-lang.org/std/fmt/trait.UpperExp.html
//! [`Pointer`]: https://doc.rust-lang.org/std/fmt/trait.Pointer.html
//! [`Index`]: https://doc.rust-lang.org/std/ops/trait.Index.html
//! [`Not`]: https://doc.rust-lang.org/std/ops/trait.Not.html
//! [`Neg`]: https://doc.rust-lang.org/std/ops/trait.Neg.html
//! [`Add`]: https://doc.rust-lang.org/std/ops/trait.Add.html
//! [`Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
//! [`BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
//! [`BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
//! [`BitXor`]: https://doc.rust-lang.org/std/ops/trait.BitXor.html
//! [`Mul`]: https://doc.rust-lang.org/std/ops/trait.Mul.html
//! [`Div`]: https://doc.rust-lang.org/std/ops/trait.Div.html
//! [`Rem`]: https://doc.rust-lang.org/std/ops/trait.Rem.html
//! [`Shr`]: https://doc.rust-lang.org/std/ops/trait.Shr.html
//! [`Shl`]: https://doc.rust-lang.org/std/ops/trait.Shl.html
//! [`AddAssign`]: https://doc.rust-lang.org/std/ops/trait.AddAssign.html
//! [`SubAssign`]: https://doc.rust-lang.org/std/ops/trait.SubAssign.html
//! [`BitAndAssign`]: https://doc.rust-lang.org/std/ops/trait.BitAndAssign.html
//! [`BitOrAssign`]: https://doc.rust-lang.org/std/ops/trait.BitOrAssign.html
//! [`BitXorAssign`]: https://doc.rust-lang.org/std/ops/trait.BitXorAssign.html
//! [`MulAssign`]: https://doc.rust-lang.org/std/ops/trait.MulAssign.html
//! [`DivAssign`]: https://doc.rust-lang.org/std/ops/trait.DivAssign.html
//! [`RemAssign`]: https://doc.rust-lang.org/std/ops/trait.RemAssign.html
//! [`ShrAssign`]: https://doc.rust-lang.org/std/ops/trait.ShrAssign.html
//! [`ShlAssign`]: https://doc.rust-lang.org/std/ops/trait.ShlAssign.html

extern crate proc_macro;
#[macro_use]
extern crate quote;
extern crate syn;

use proc_macro::TokenStream;

mod utils;

mod from;
mod into;
mod constructor;
mod not_like;
mod add_like;
mod add_assign_like;
mod mul_like;
mod mul_assign_like;
mod from_str;
mod display;
mod index;

macro_rules! create_derive(
    ($mod_:ident, $trait_:ident, $fn_name: ident) => {
        #[proc_macro_derive($trait_)]
        #[doc(hidden)]
        pub fn $fn_name(input: TokenStream) -> TokenStream {
            let ast = syn::parse(input).unwrap();
            $mod_::expand(&ast, stringify!($trait_)).into()
        }
    }
);

create_derive!(from, From, from_derive);

create_derive!(into, Into, into_derive);

create_derive!(constructor, Constructor, constructor_derive);

create_derive!(not_like, Not, not_derive);
create_derive!(not_like, Neg, neg_derive);

create_derive!(add_like, Add, add_derive);
create_derive!(add_like, Sub, sub_derive);
create_derive!(add_like, BitAnd, bit_and_derive);
create_derive!(add_like, BitOr, bit_or_derive);
create_derive!(add_like, BitXor, bit_xor_derive);

create_derive!(mul_like, Mul, mul_derive);
create_derive!(mul_like, Div, div_derive);
create_derive!(mul_like, Rem, rem_derive);
create_derive!(mul_like, Shr, shr_derive);
create_derive!(mul_like, Shl, shl_derive);

create_derive!(add_assign_like, AddAssign, add_assign_derive);
create_derive!(add_assign_like, SubAssign, sub_assign_derive);
create_derive!(add_assign_like, BitAndAssign, bit_and_assign_derive);
create_derive!(add_assign_like, BitOrAssign, bit_or_assign_derive);
create_derive!(add_assign_like, BitXorAssign, bit_xor_assign_derive);

create_derive!(mul_assign_like, MulAssign, mul_assign_derive);
create_derive!(mul_assign_like, DivAssign, div_assign_derive);
create_derive!(mul_assign_like, RemAssign, rem_assign_derive);
create_derive!(mul_assign_like, ShrAssign, shr_assign_derive);
create_derive!(mul_assign_like, ShlAssign, shl_assign_derive);

create_derive!(from_str, FromStr, from_str_derive);

create_derive!(display, Display, display_derive);
create_derive!(display, Binary, binary_derive);
create_derive!(display, Octal, octal_derive);
create_derive!(display, LowerHex, lower_hex_derive);
create_derive!(display, UpperHex, upper_hex_derive);
create_derive!(display, LowerExp, lower_exp_derive);
create_derive!(display, UpperExp, upper_exp_derive);
create_derive!(display, Pointer, pointer_derive);

create_derive!(index, Index, index_derive);
<|endoftext|>


<commit_before>//! The `neon` crate provides the entire [Neon](http://neon.rustbridge.io) API.

extern crate neon_sys;

mod internal;
pub mod mem;
pub mod vm;
pub mod scope;
pub mod js;

/// Register the current crate as a Node module, providing startup
/// logic for initializing the module object at runtime.
///
/// Example:
///
/// ```rust
/// register_module!(m, {
///     try!(m.export("foo", foo));
///     try!(m.export("bar", bar));
///     try!(m.export("baz", baz));
///     Ok(())
/// });
/// ```
#[macro_export]
macro_rules! register_module {
    ($module:ident, $init:block) => {
        // Mark this function as a global constructor (like C++).
        #[cfg_attr(target_os = "linux", link_section = ".ctors")]
        #[cfg_attr(target_os = "macos", link_section = "__DATA,__mod_init_func")]
        #[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")]
        pub static __LOAD_NEON_MODULE: extern "C" fn() = {
            fn __init_neon_module(mut $module: $crate::vm::Module) -> $crate::vm::VmResult<()> $init

            extern "C" fn __load_neon_module() {
                // Put everything else in the ctor fn so the user fn can't see it.
                #[repr(C)]
                struct __NodeModule {
                    version: i32,
                    flags: u32,
                    dso_handle: *mut u8,
                    filename: *const u8,
                    register_func: Option<extern "C" fn(
                        $crate::mem::Handle<$crate::js::JsObject>, *mut u8, *mut u8)>,
                    context_register_func: Option<extern "C" fn(
                        $crate::mem::Handle<$crate::js::JsObject>, *mut u8, *mut u8, *mut u8)>,
                    modname: *const u8,
                    priv_data: *mut u8,
                    link: *mut __NodeModule
                }

                static mut __NODE_MODULE: __NodeModule = __NodeModule {
                    version: 0,
                    flags: 0,
                    dso_handle: 0 as *mut _,
                    filename: b"neon_source.rs\0" as *const u8,
                    register_func: Some(__register_neon_module),
                    context_register_func: None,
                    modname: b"neon_module\0" as *const u8,
                    priv_data: 0 as *mut _,
                    link: 0 as *mut _
                };

                extern "C" fn __register_neon_module(
                        m: $crate::mem::Handle<$crate::js::JsObject>, _: *mut u8, _: *mut u8) {
                    $crate::vm::Module::initialize(m, __init_neon_module);
                }

                extern "C" {
                    fn node_module_register(module: *mut __NodeModule);
                }

                unsafe {
                    // Set the ABI version, which is passed in by `neon build` as an env var.
                    __NODE_MODULE.version = env!("NEON_NODE_ABI").parse().unwrap();

                    node_module_register(&mut __NODE_MODULE);
                }
            }

            __load_neon_module
        };
    }
}
<commit_msg>ignore rustdoc code<commit_after>//! The `neon` crate provides the entire [Neon](http://neon.rustbridge.io) API.

extern crate neon_sys;

mod internal;
pub mod mem;
pub mod vm;
pub mod scope;
pub mod js;

/// Register the current crate as a Node module, providing startup
/// logic for initializing the module object at runtime.
///
/// Example:
///
/// ```rust,ignore
/// register_module!(m, {
///     try!(m.export("foo", foo));
///     try!(m.export("bar", bar));
///     try!(m.export("baz", baz));
///     Ok(())
/// });
/// ```
#[macro_export]
macro_rules! register_module {
    ($module:ident, $init:block) => {
        // Mark this function as a global constructor (like C++).
        #[cfg_attr(target_os = "linux", link_section = ".ctors")]
        #[cfg_attr(target_os = "macos", link_section = "__DATA,__mod_init_func")]
        #[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")]
        pub static __LOAD_NEON_MODULE: extern "C" fn() = {
            fn __init_neon_module(mut $module: $crate::vm::Module) -> $crate::vm::VmResult<()> $init

            extern "C" fn __load_neon_module() {
                // Put everything else in the ctor fn so the user fn can't see it.
                #[repr(C)]
                struct __NodeModule {
                    version: i32,
                    flags: u32,
                    dso_handle: *mut u8,
                    filename: *const u8,
                    register_func: Option<extern "C" fn(
                        $crate::mem::Handle<$crate::js::JsObject>, *mut u8, *mut u8)>,
                    context_register_func: Option<extern "C" fn(
                        $crate::mem::Handle<$crate::js::JsObject>, *mut u8, *mut u8, *mut u8)>,
                    modname: *const u8,
                    priv_data: *mut u8,
                    link: *mut __NodeModule
                }

                static mut __NODE_MODULE: __NodeModule = __NodeModule {
                    version: 0,
                    flags: 0,
                    dso_handle: 0 as *mut _,
                    filename: b"neon_source.rs\0" as *const u8,
                    register_func: Some(__register_neon_module),
                    context_register_func: None,
                    modname: b"neon_module\0" as *const u8,
                    priv_data: 0 as *mut _,
                    link: 0 as *mut _
                };

                extern "C" fn __register_neon_module(
                        m: $crate::mem::Handle<$crate::js::JsObject>, _: *mut u8, _: *mut u8) {
                    $crate::vm::Module::initialize(m, __init_neon_module);
                }

                extern "C" {
                    fn node_module_register(module: *mut __NodeModule);
                }

                unsafe {
                    // Set the ABI version, which is passed in by `neon build` as an env var.
                    __NODE_MODULE.version = env!("NEON_NODE_ABI").parse().unwrap();

                    node_module_register(&mut __NODE_MODULE);
                }
            }

            __load_neon_module
        };
    }
}
<|endoftext|>


<commit_before>#![crate_id = "graphics"]
#![deny(missing_doc)]

//! Attempt of creating a cheap drawing context.

use std::num::Float;

pub type Matrix2d = [f64, ..6];
pub type Color = [f64, ..4];
pub type Rectangle = [f64, ..4];

/// Implemented by all graphics back-ends.
/// This trait uses default methods to simplify implementation.
pub trait BackEnd {
    /// Returns true if feature is supported.
    #[inline(always)]
    fn supports_tri_list_xy_rgba_f64(&self) -> bool { false }

    /// Renders list of 2d triangles with color assigned per vertex.
    fn tri_list_xy_rgba_f64(&mut self, _vertices: &[f64], _colors: &[f64]) {}

    /// Returns true if feature is supported.
    #[inline(always)]
    fn supports_tri_list_xy_rgba_f32(&self) -> bool { false }

    /// Renders list of 2d triangles with color assigned per vertex.
    fn tri_list_xy_rgba_f32(&mut self, _vertices: &[f32], _colors: &[f32]) {}
}

/// Implemented by contexts that can transform.
pub trait Transform2d<'a> {
    /// Translate x and y.
    fn trans(&'a self, x: f64, y: f64) -> Self;
    /// Rotate degrees.
    fn rot_deg(&'a self, angle: f64) -> Self;
    /// Rotate radians.
    fn rot_rad(&'a self, angle: f64) -> Self;
    /// Scale.
    fn scale(&'a self, sx: f64, sy: f64) -> Self;
    /// Shear.
    fn shear(&'a self, sx: f64, sy: f64) -> Self;
}

/// A structure that might contain a value or a borrowed value.
/// This is to used as building block to create data structure
/// that is partially based on an existing structure.
pub enum Field<'a, T> {
    /// Contains a value.
    Value(T),
    /// Contains a borrowed pointer.
    Borrowed(&'a T),
}

impl<'a, T> Field<'a, T> {
    /// Gets a read only value.
    #[inline(always)]
    pub fn get(&'a self) -> &'a T {
        match *self {
            Value(ref val) => val,
            Borrowed(rval) => rval,
        }
    }
}

/// Multiplies two matrices.
#[inline(always)]
pub fn multiply(m: &[f64, ..6], b: &[f64, ..6]) -> Matrix2d {
    [m[0]*b[0]+m[1]*b[3]+m[2]*0.0,  m[0]*b[1]+m[1]*b[4]+m[2]*0.0,  m[0]*b[2]+m[1]*b[5]+m[2]*1.0,
     m[3]*b[0]+m[4]*b[3]+m[5]*0.0,  m[3]*b[1]+m[4]*b[4]+m[5]*0.0,  m[3]*b[2]+m[4]*b[5]+m[5]*1.0]
}

/// Creates a translation matrix.
#[inline(always)]
pub fn translate(x: f64, y: f64) -> Matrix2d {
    [1.0, 0.0, x,
     0.0, 1.0, y]
}

/// Drawing 2d context.
pub struct Context<'a> {
    base: Field<'a, Matrix2d>,
    transform: Field<'a, Matrix2d>,
}

impl<'a> Transform2d<'a> for Context<'a> {
    #[inline(always)]
    fn trans(&'a self, x: f64, y: f64) -> Context<'a> {
        Context {
            base: Borrowed(self.base.get()),
            transform: Value({
                let trans = translate(x, y);
                 multiply(&trans, self.transform.get())
            }),
        }
    }

    #[inline(always)]
    fn rot_deg(&'a self, angle: f64) -> Context<'a> {
        let pi: f64 = Float::pi();
        self.rot_rad(angle * pi / 180.0)
    }

    #[inline(always)]
    fn rot_rad(&'a self, angle: f64) -> Context<'a> {
        Context {
            base: Borrowed(self.base.get()),
            transform: Value({
                let c = angle.cos();
                let s = angle.sin();
                let rot: [f64, ..6] = [c, s, 0.0,
                                      -s, c, 0.0];
                multiply(&rot, self.transform.get())
            }),
        }
    }

    #[inline(always)]
    fn scale(&'a self, sx: f64, sy: f64) -> Context<'a> {
        Context {
            base: Borrowed(self.base.get()),
            transform: Value({
                let scale: [f64, ..6] = [sx, 0.0, 0.0,
                                         0.0, sy, 0.0];
                multiply(&scale, self.transform.get())
            }),
        }
    }

    #[inline(always)]
    fn shear(&'a self, sx: f64, sy: f64) -> Context<'a> {
        Context {
            base: Borrowed(self.base.get()),
            transform: Value({
                let shear: [f64, ..6] = [1.0, sx, 0.0,
                                         sy, 1.0, 0.0];
            multiply(&shear, self.transform.get())
            }),
        }
    }
}

impl<'a> Context<'a> {
    /// Creates a new drawing context.
    pub fn new() -> Context {
        Context {
            base:  Value([1.0, 0.0, 0.0,
                          0.0, 1.0, 0.0]),
            transform: Value([1.0, 0.0, 0.0,
                          0.0, 1.0, 0.0]),
        }
    }

}

#[test]
fn test_context() {
    let c = Context::new();
    {
        let d = c.trans(20.0, 40.0);
        let d = d.trans(10.0, 10.0);
        assert_eq!(d.transform.get()[2], 30.0);
        assert_eq!(d.transform.get()[5], 50.0);
    }
    assert_eq!(c.transform.get()[2], 0.0);
    assert_eq!(c.transform.get()[5], 0.0);

    let c = c.rot_deg(90.0);
    assert!((c.transform.get()[0] - 0.0).abs() < 0.00001);
    assert!((c.transform.get()[1] - 1.0).abs() < 0.00001);
}

#[test]
fn test_scale() {
    let c = Context::new();
    let c = c.scale(2.0, 3.0);
    assert!((c.transform.get()[0] - 2.0).abs() < 0.00001);
    assert!((c.transform.get()[4] - 3.0).abs() < 0.00001);
}

/// A context with color information.
pub struct ColorContext<'a> {
    base: Field<'a, Matrix2d>,
    transform: Field<'a, Matrix2d>,
    color: Field<'a, Color>,
}

/// A rectangle context.
pub struct RectangleContext<'a> {
    base: Field<'a, Matrix2d>,
    transform: Field<'a, Matrix2d>,
    rect: Field<'a, Rectangle>,
}

/// A rectangle color context.
pub struct RectangleColorContext<'a> {
    base: Field<'a, Matrix2d>,
    transform: Field<'a, Matrix2d>,
    rect: Field<'a, Rectangle>,
    color: Field<'a, Color>,
}

<commit_msg>Moved creation of matrices to own functions<commit_after>#![crate_id = "graphics"]
#![deny(missing_doc)]

//! Attempt of creating a cheap drawing context.

use std::num::Float;

pub type Matrix2d = [f64, ..6];
pub type Color = [f64, ..4];
pub type Rectangle = [f64, ..4];

/// Implemented by all graphics back-ends.
/// This trait uses default methods to simplify implementation.
pub trait BackEnd {
    /// Returns true if feature is supported.
    #[inline(always)]
    fn supports_tri_list_xy_rgba_f64(&self) -> bool { false }

    /// Renders list of 2d triangles with color assigned per vertex.
    fn tri_list_xy_rgba_f64(&mut self, _vertices: &[f64], _colors: &[f64]) {}

    /// Returns true if feature is supported.
    #[inline(always)]
    fn supports_tri_list_xy_rgba_f32(&self) -> bool { false }

    /// Renders list of 2d triangles with color assigned per vertex.
    fn tri_list_xy_rgba_f32(&mut self, _vertices: &[f32], _colors: &[f32]) {}
}

/// Implemented by contexts that can transform.
pub trait Transform2d<'a> {
    /// Translate x and y.
    fn trans(&'a self, x: f64, y: f64) -> Self;
    /// Rotate degrees.
    fn rot_deg(&'a self, angle: f64) -> Self;
    /// Rotate radians.
    fn rot_rad(&'a self, angle: f64) -> Self;
    /// Scale.
    fn scale(&'a self, sx: f64, sy: f64) -> Self;
    /// Shear.
    fn shear(&'a self, sx: f64, sy: f64) -> Self;
}

/// A structure that might contain a value or a borrowed value.
/// This is to used as building block to create data structure
/// that is partially based on an existing structure.
pub enum Field<'a, T> {
    /// Contains a value.
    Value(T),
    /// Contains a borrowed pointer.
    Borrowed(&'a T),
}

impl<'a, T> Field<'a, T> {
    /// Gets a read only value.
    #[inline(always)]
    pub fn get(&'a self) -> &'a T {
        match *self {
            Value(ref val) => val,
            Borrowed(rval) => rval,
        }
    }
}

/// Multiplies two matrices.
#[inline(always)]
pub fn multiply(m: &[f64, ..6], b: &[f64, ..6]) -> Matrix2d {
    [m[0]*b[0]+m[1]*b[3]+m[2]*0.0,  m[0]*b[1]+m[1]*b[4]+m[2]*0.0,  m[0]*b[2]+m[1]*b[5]+m[2]*1.0,
     m[3]*b[0]+m[4]*b[3]+m[5]*0.0,  m[3]*b[1]+m[4]*b[4]+m[5]*0.0,  m[3]*b[2]+m[4]*b[5]+m[5]*1.0]
}

/// Creates a translation matrix.
#[inline(always)]
pub fn translate(x: f64, y: f64) -> Matrix2d {
    [1.0, 0.0, x,
     0.0, 1.0, y]
}

/// Creates a rotation matrix.
#[inline(always)]
pub fn rotate_radians(angle: f64) -> Matrix2d {
    let c = angle.cos();
    let s = angle.sin();
    [c, s, 0.0,
    -s, c, 0.0]
}

/// Create a scale matrix.
#[inline(always)]
pub fn scale(sx: f64, sy: f64) -> Matrix2d {
    [sx, 0.0, 0.0,
     0.0, sy, 0.0]
}

/// Create a shear matrix.
#[inline(always)]
pub fn shear(sx: f64, sy: f64) -> Matrix2d {
    [1.0, sx, 0.0,
     sy, 1.0, 0.0]
}

/// Drawing 2d context.
pub struct Context<'a> {
    base: Field<'a, Matrix2d>,
    transform: Field<'a, Matrix2d>,
}

impl<'a> Transform2d<'a> for Context<'a> {
    #[inline(always)]
    fn trans(&'a self, x: f64, y: f64) -> Context<'a> {
        Context {
            base: Borrowed(self.base.get()),
            transform: Value({
                let trans = translate(x, y);
                 multiply(&trans, self.transform.get())
            }),
        }
    }

    #[inline(always)]
    fn rot_deg(&'a self, angle: f64) -> Context<'a> {
        let pi: f64 = Float::pi();
        self.rot_rad(angle * pi / 180.0)
    }

    #[inline(always)]
    fn rot_rad(&'a self, angle: f64) -> Context<'a> {
        Context {
            base: Borrowed(self.base.get()),
            transform: Value({
                let rot = rotate_radians(angle);
                multiply(&rot, self.transform.get())
            }),
        }
    }

    #[inline(always)]
    fn scale(&'a self, sx: f64, sy: f64) -> Context<'a> {
        Context {
            base: Borrowed(self.base.get()),
            transform: Value({
                let scale = scale(sx, sy);
                multiply(&scale, self.transform.get())
            }),
        }
    }

    #[inline(always)]
    fn shear(&'a self, sx: f64, sy: f64) -> Context<'a> {
        Context {
            base: Borrowed(self.base.get()),
            transform: Value({
                let shear = shear(sx, sy);
                multiply(&shear, self.transform.get())
            }),
        }
    }
}

impl<'a> Context<'a> {
    /// Creates a new drawing context.
    pub fn new() -> Context {
        Context {
            base:  Value([1.0, 0.0, 0.0,
                          0.0, 1.0, 0.0]),
            transform: Value([1.0, 0.0, 0.0,
                          0.0, 1.0, 0.0]),
        }
    }

}

#[test]
fn test_context() {
    let c = Context::new();
    {
        let d = c.trans(20.0, 40.0);
        let d = d.trans(10.0, 10.0);
        assert_eq!(d.transform.get()[2], 30.0);
        assert_eq!(d.transform.get()[5], 50.0);
    }
    assert_eq!(c.transform.get()[2], 0.0);
    assert_eq!(c.transform.get()[5], 0.0);

    let c = c.rot_deg(90.0);
    assert!((c.transform.get()[0] - 0.0).abs() < 0.00001);
    assert!((c.transform.get()[1] - 1.0).abs() < 0.00001);
}

#[test]
fn test_scale() {
    let c = Context::new();
    let c = c.scale(2.0, 3.0);
    assert!((c.transform.get()[0] - 2.0).abs() < 0.00001);
    assert!((c.transform.get()[4] - 3.0).abs() < 0.00001);
}

/// A context with color information.
pub struct ColorContext<'a> {
    base: Field<'a, Matrix2d>,
    transform: Field<'a, Matrix2d>,
    color: Field<'a, Color>,
}

/// A rectangle context.
pub struct RectangleContext<'a> {
    base: Field<'a, Matrix2d>,
    transform: Field<'a, Matrix2d>,
    rect: Field<'a, Rectangle>,
}

/// A rectangle color context.
pub struct RectangleColorContext<'a> {
    base: Field<'a, Matrix2d>,
    transform: Field<'a, Matrix2d>,
    rect: Field<'a, Rectangle>,
    color: Field<'a, Color>,
}

<|endoftext|>


<commit_before>//! A lazy, zero-copy parser for the DWARF debugging information format.
//!
//! * **Zero-copy:** everything is just a reference to the original input
//!   buffer. No copies of the input data ever get made.
//!
//! * **Lazy:** only the compilation units' entries that you iterate over get
//!   parsed, and only as deep as you ask. Skip over a compilation unit and its
//!   entries don't get parsed.
//!
//! * **Cross-platform:** `gimli` isn't coupled to any platform or object file
//!   format. Use your own ELF parser on Linux or a Mach-O parser on OSX.
//!
//!   * Unsure which object file parser to use? Try the cross-platform
//!   [`object`](https://github.com/gimli-rs/object) crate.
//!
//! This library primarily targets the fourth edition of the standard (the most
//! recent, at time of writing).
//!
//! ## Example Usage
//!
//! Print out all of the functions in the debuggee program:
//!
//! ```rust,no_run
//! extern crate gimli;
//!
//! # fn example() -> Result<(), gimli::Error> {
//! # let debug_info_buf = [];
//! # let debug_abbrev_buf = [];
//! # let read_debug_info = || &debug_info_buf;
//! # let read_debug_abbrev = || &debug_abbrev_buf;
//! // Read the .debug_info and .debug_abbrev sections with whatever object
//! // loader you're using.
//! let debug_info = gimli::DebugInfo::<gimli::LittleEndian>::new(read_debug_info());
//! let debug_abbrev = gimli::DebugAbbrev::<gimli::LittleEndian>::new(read_debug_abbrev());
//!
//! // Iterate over all compilation units.
//! let mut iter = debug_info.units();
//! while let Some(unit) = try!(iter.next()) {
//!     // Parse the abbreviations for this compilation unit.
//!     let abbrevs = try!(unit.abbreviations(debug_abbrev));
//!
//!     // Iterate over all of this compilation unit's entries.
//!     let mut entries = unit.entries(&abbrevs);
//!     while let Some((_, entry)) = try!(entries.next_dfs()) {
//!         // If we find an entry for a function, print it.
//!         if entry.tag() == gimli::DW_TAG_subprogram {
//!             println!("Found a function: {:?}", entry);
//!         }
//!     }
//! }
//! # Ok(())
//! # }
//! ```
//!
//! See the [example
//! programs](https://github.com/gimli-rs/gimli/blob/master/examples/) for
//! complete examples.
//!
//! ## API Structure
//!
//! * Basic familiarity with DWARF is assumed.
//!
//! * Each section gets its own type. Consider these types the entry points to
//! the library:
//!
//!   * [`DebugAbbrev`](./struct.DebugAbbrev.html): The `.debug_abbrev` section.
//!
//!   * [`DebugAranges`](./struct.DebugAranges.html): The `.debug_aranges`
//!   section.
//!
//!   * [`DebugFrame`](./struct.DebugFrame.html): The `.debug_frame` section.
//!
//!   * [`DebugInfo`](./struct.DebugInfo.html): The `.debug_info` section.
//!
//!   * [`DebugLine`](./struct.DebugLine.html): The `.debug_line` section.
//!
//!   * [`DebugLoc`](./struct.DebugLoc.html): The `.debug_loc` section.
//!
//!   * [`DebugPubNames`](./type.DebugPubNames.html): The `.debug_pubnames`
//!   section.
//!
//!   * [`DebugPubTypes`](./type.DebugPubTypes.html): The `.debug_pubtypes`
//!   section.
//!
//!   * [`DebugRanges`](./struct.DebugRanges.html): The `.debug_ranges` section.
//!
//!   * [`DebugStr`](./struct.DebugStr.html): The `.debug_str` section.
//!
//!   * [`DebugTypes`](./struct.DebugTypes.html): The `.debug_types` section.
//!
//! * Each section type exposes methods for accessing the debugging data encoded
//! in that section. For example, the [`DebugInfo`](./struct.DebugInfo.html)
//! struct has the [`units`](./struct.DebugInfo.html#method.units) method for
//! iterating over the compilation units defined within it.
//!
//! * Offsets into a section are strongly typed: an offset into `.debug_info` is
//! the [`DebugInfoOffset`](./struct.DebugInfoOffset.html) type. It cannot be
//! used to index into the [`DebugLine`](./struct.DebugLine.html) type because
//! `DebugLine` represents the `.debug_line` section. There are similar types
//! for offsets relative to a compilation unit rather than a section.
//!
//! ## Using with `FallibleIterator`
//!
//! The standard library's `Iterator` trait and related APIs do not play well
//! with iterators where the `next` operation is fallible. One can make the
//! `Iterator`'s associated `Item` type be a `Result<T, E>`, however the
//! provided methods cannot gracefully handle the case when an `Err` is
//! returned.
//!
//! This situation led to the
//! [`fallible-iterator`](https://crates.io/crates/fallible-iterator) crate's
//! existence. You can read more of the rationale for its existence in its
//! docs. The crate provides the helpers you have come to expect (eg `map`,
//! `filter`, etc) for iterators that can fail.
//!
//! `gimli`'s many lazy parsing iterators are a perfect match for the
//! `fallible-iterator` crate's `FallibleIterator` trait because parsing is not
//! done eagerly. Parse errors later in the input might only be discovered after
//! having iterated through many items.
//!
//! To use `gimli` iterators with `FallibleIterator`, import the crate and trait
//! into your code:
//!
//! ```
//! // Add the `fallible-iterator` crate. Don't forget to add it to your
//! // `Cargo.toml`, too!
//! extern crate fallible_iterator;
//! extern crate gimli;
//!
//! // Use the `FallibleIterator` trait so its methods are in scope!
//! use fallible_iterator::FallibleIterator;
//! use gimli::{DebugAranges, LittleEndian};
//!
//! fn find_sum_of_address_range_lengths(aranges: DebugAranges<LittleEndian>)
//!     -> gimli::Result<u64>
//! {
//!     // `DebugAranges::items` returns a `FallibleIterator`!
//!     aranges.items()
//!         // `map` is provided by `FallibleIterator`!
//!         .map(|arange| arange.length())
//!         // `fold` is provided by `FallibleIterator`!
//!         .fold(0, |sum, len| sum + len)
//! }
//!
//! # fn main() {}
//! ```

#![deny(missing_docs)]
#![deny(missing_debug_implementations)]

extern crate byteorder;
extern crate fallible_iterator;
extern crate leb128;

mod cfi;
pub use cfi::*;

mod constants;
pub use constants::*;

mod endianity;
pub use endianity::{Endianity, EndianBuf, LittleEndian, BigEndian, NativeEndian};

mod parser;
pub use parser::{Error, Result, Format};
pub use parser::DebugMacinfoOffset;

mod abbrev;
pub use abbrev::{DebugAbbrev, DebugAbbrevOffset, Abbreviations, Abbreviation,
                 AttributeSpecification};

mod aranges;
pub use aranges::{DebugAranges, ArangeEntryIter, ArangeEntry};

mod line;
pub use line::*;

mod loc;
pub use loc::{DebugLoc, DebugLocOffset, LocationListIter, RawLocationListIter, LocationListEntry};

mod lookup;

mod op;
pub use op::*;

mod pubnames;
pub use pubnames::{DebugPubNames, PubNamesEntryIter, PubNamesEntry};

mod pubtypes;
pub use pubtypes::{DebugPubTypes, PubTypesEntryIter, PubTypesEntry};

mod ranges;
pub use ranges::{DebugRanges, DebugRangesOffset, RangesIter, RawRangesIter, Range};

mod str;
pub use str::*;

#[cfg(test)]
mod test_util;

mod unit;
pub use unit::{DebugInfo, DebugInfoOffset, CompilationUnitHeadersIter, CompilationUnitHeader,
               UnitOffset};
pub use unit::{DebugTypes, DebugTypesOffset, DebugTypeSignature, TypeUnitHeadersIter,
               TypeUnitHeader};
pub use unit::{EntriesCursor, EntriesTree, EntriesTreeIter, DebuggingInformationEntry};
pub use unit::{AttrsIter, Attribute, AttributeValue};
<commit_msg>Make warnings cause compilation failures<commit_after>//! A lazy, zero-copy parser for the DWARF debugging information format.
//!
//! * **Zero-copy:** everything is just a reference to the original input
//!   buffer. No copies of the input data ever get made.
//!
//! * **Lazy:** only the compilation units' entries that you iterate over get
//!   parsed, and only as deep as you ask. Skip over a compilation unit and its
//!   entries don't get parsed.
//!
//! * **Cross-platform:** `gimli` isn't coupled to any platform or object file
//!   format. Use your own ELF parser on Linux or a Mach-O parser on OSX.
//!
//!   * Unsure which object file parser to use? Try the cross-platform
//!   [`object`](https://github.com/gimli-rs/object) crate.
//!
//! This library primarily targets the fourth edition of the standard (the most
//! recent, at time of writing).
//!
//! ## Example Usage
//!
//! Print out all of the functions in the debuggee program:
//!
//! ```rust,no_run
//! extern crate gimli;
//!
//! # fn example() -> Result<(), gimli::Error> {
//! # let debug_info_buf = [];
//! # let debug_abbrev_buf = [];
//! # let read_debug_info = || &debug_info_buf;
//! # let read_debug_abbrev = || &debug_abbrev_buf;
//! // Read the .debug_info and .debug_abbrev sections with whatever object
//! // loader you're using.
//! let debug_info = gimli::DebugInfo::<gimli::LittleEndian>::new(read_debug_info());
//! let debug_abbrev = gimli::DebugAbbrev::<gimli::LittleEndian>::new(read_debug_abbrev());
//!
//! // Iterate over all compilation units.
//! let mut iter = debug_info.units();
//! while let Some(unit) = try!(iter.next()) {
//!     // Parse the abbreviations for this compilation unit.
//!     let abbrevs = try!(unit.abbreviations(debug_abbrev));
//!
//!     // Iterate over all of this compilation unit's entries.
//!     let mut entries = unit.entries(&abbrevs);
//!     while let Some((_, entry)) = try!(entries.next_dfs()) {
//!         // If we find an entry for a function, print it.
//!         if entry.tag() == gimli::DW_TAG_subprogram {
//!             println!("Found a function: {:?}", entry);
//!         }
//!     }
//! }
//! # Ok(())
//! # }
//! ```
//!
//! See the [example
//! programs](https://github.com/gimli-rs/gimli/blob/master/examples/) for
//! complete examples.
//!
//! ## API Structure
//!
//! * Basic familiarity with DWARF is assumed.
//!
//! * Each section gets its own type. Consider these types the entry points to
//! the library:
//!
//!   * [`DebugAbbrev`](./struct.DebugAbbrev.html): The `.debug_abbrev` section.
//!
//!   * [`DebugAranges`](./struct.DebugAranges.html): The `.debug_aranges`
//!   section.
//!
//!   * [`DebugFrame`](./struct.DebugFrame.html): The `.debug_frame` section.
//!
//!   * [`DebugInfo`](./struct.DebugInfo.html): The `.debug_info` section.
//!
//!   * [`DebugLine`](./struct.DebugLine.html): The `.debug_line` section.
//!
//!   * [`DebugLoc`](./struct.DebugLoc.html): The `.debug_loc` section.
//!
//!   * [`DebugPubNames`](./type.DebugPubNames.html): The `.debug_pubnames`
//!   section.
//!
//!   * [`DebugPubTypes`](./type.DebugPubTypes.html): The `.debug_pubtypes`
//!   section.
//!
//!   * [`DebugRanges`](./struct.DebugRanges.html): The `.debug_ranges` section.
//!
//!   * [`DebugStr`](./struct.DebugStr.html): The `.debug_str` section.
//!
//!   * [`DebugTypes`](./struct.DebugTypes.html): The `.debug_types` section.
//!
//! * Each section type exposes methods for accessing the debugging data encoded
//! in that section. For example, the [`DebugInfo`](./struct.DebugInfo.html)
//! struct has the [`units`](./struct.DebugInfo.html#method.units) method for
//! iterating over the compilation units defined within it.
//!
//! * Offsets into a section are strongly typed: an offset into `.debug_info` is
//! the [`DebugInfoOffset`](./struct.DebugInfoOffset.html) type. It cannot be
//! used to index into the [`DebugLine`](./struct.DebugLine.html) type because
//! `DebugLine` represents the `.debug_line` section. There are similar types
//! for offsets relative to a compilation unit rather than a section.
//!
//! ## Using with `FallibleIterator`
//!
//! The standard library's `Iterator` trait and related APIs do not play well
//! with iterators where the `next` operation is fallible. One can make the
//! `Iterator`'s associated `Item` type be a `Result<T, E>`, however the
//! provided methods cannot gracefully handle the case when an `Err` is
//! returned.
//!
//! This situation led to the
//! [`fallible-iterator`](https://crates.io/crates/fallible-iterator) crate's
//! existence. You can read more of the rationale for its existence in its
//! docs. The crate provides the helpers you have come to expect (eg `map`,
//! `filter`, etc) for iterators that can fail.
//!
//! `gimli`'s many lazy parsing iterators are a perfect match for the
//! `fallible-iterator` crate's `FallibleIterator` trait because parsing is not
//! done eagerly. Parse errors later in the input might only be discovered after
//! having iterated through many items.
//!
//! To use `gimli` iterators with `FallibleIterator`, import the crate and trait
//! into your code:
//!
//! ```
//! // Add the `fallible-iterator` crate. Don't forget to add it to your
//! // `Cargo.toml`, too!
//! extern crate fallible_iterator;
//! extern crate gimli;
//!
//! // Use the `FallibleIterator` trait so its methods are in scope!
//! use fallible_iterator::FallibleIterator;
//! use gimli::{DebugAranges, LittleEndian};
//!
//! fn find_sum_of_address_range_lengths(aranges: DebugAranges<LittleEndian>)
//!     -> gimli::Result<u64>
//! {
//!     // `DebugAranges::items` returns a `FallibleIterator`!
//!     aranges.items()
//!         // `map` is provided by `FallibleIterator`!
//!         .map(|arange| arange.length())
//!         // `fold` is provided by `FallibleIterator`!
//!         .fold(0, |sum, len| sum + len)
//! }
//!
//! # fn main() {}
//! ```

#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![deny(warnings)]

extern crate byteorder;
extern crate fallible_iterator;
extern crate leb128;

mod cfi;
pub use cfi::*;

mod constants;
pub use constants::*;

mod endianity;
pub use endianity::{Endianity, EndianBuf, LittleEndian, BigEndian, NativeEndian};

mod parser;
pub use parser::{Error, Result, Format};
pub use parser::DebugMacinfoOffset;

mod abbrev;
pub use abbrev::{DebugAbbrev, DebugAbbrevOffset, Abbreviations, Abbreviation,
                 AttributeSpecification};

mod aranges;
pub use aranges::{DebugAranges, ArangeEntryIter, ArangeEntry};

mod line;
pub use line::*;

mod loc;
pub use loc::{DebugLoc, DebugLocOffset, LocationListIter, RawLocationListIter, LocationListEntry};

mod lookup;

mod op;
pub use op::*;

mod pubnames;
pub use pubnames::{DebugPubNames, PubNamesEntryIter, PubNamesEntry};

mod pubtypes;
pub use pubtypes::{DebugPubTypes, PubTypesEntryIter, PubTypesEntry};

mod ranges;
pub use ranges::{DebugRanges, DebugRangesOffset, RangesIter, RawRangesIter, Range};

mod str;
pub use str::*;

#[cfg(test)]
mod test_util;

mod unit;
pub use unit::{DebugInfo, DebugInfoOffset, CompilationUnitHeadersIter, CompilationUnitHeader,
               UnitOffset};
pub use unit::{DebugTypes, DebugTypesOffset, DebugTypeSignature, TypeUnitHeadersIter,
               TypeUnitHeader};
pub use unit::{EntriesCursor, EntriesTree, EntriesTreeIter, DebuggingInformationEntry};
pub use unit::{AttrsIter, Attribute, AttributeValue};
<|endoftext|>


<commit_before>use std::convert::Into;
use std::str::FromStr;

const BYTE: i64     = 1;
const KILOBYTE: i64 = BYTE     << 10;
const MEGABYTE: i64 = KILOBYTE << 10;
const GIGABYTE: i64 = MEGABYTE << 10;
const TERABYTE: i64 = GIGABYTE << 10;
const PETABYTE: i64 = TERABYTE << 10;
const EXABYTE: i64  = PETABYTE << 10;

macro_rules! map(
  { $($key:expr => $value:expr),+ } => {
    {
      let mut m = ::std::collections::HashMap::new();
      $(
        m.insert($key, $value);
        )+
        m
    }
  };
);

pub trait Capacity {

  fn bytes(&self) -> i64;

  fn kilobytes(&self) -> i64 {
    self.bytes().rotate_left(10)
  }

  fn megabytes(&self) -> i64 {
    self.kilobytes().rotate_left(10)
  }

  fn gigabytes(&self) -> i64 {
    self.megabytes().rotate_left(10)
  }

  fn terabytes(&self) -> i64 {
    self.gigabytes().rotate_left(10)
  }

  fn petabytes(&self) -> i64 {
    self.terabytes().rotate_left(10)
  }

  fn exabytes(&self) -> i64 {
    self.petabytes().rotate_left(10)
  }

  fn capacity(&self) -> String {
    match self.bytes() {
      small if small < KILOBYTE =>
        stringify!(small).to_owned(),
      large => {
        let units = vec![
          ('E', EXABYTE),
          ('P', PETABYTE),
          ('T', TERABYTE),
          ('G', GIGABYTE),
          ('M', MEGABYTE),
          ('K', KILOBYTE)
        ];
        for (suffix, size) in units {
          if large == size {
            return format!("1{}", suffix)
          } else if large > size {
            let sized = (large as f64) / (size as f64);
            let round = (sized * 100.0).round() / 100.0;
            return format!("{:.1}{}", round, suffix)
          }
        }
        unreachable!()
      }
    }
  }
}

impl Capacity for i64 {
  fn bytes(&self) -> i64 {
    *self
  }
}

impl Capacity for Bytes {
  fn bytes(&self) -> i64 {
    (*self).size
  }
}

#[derive(Debug)]
pub struct Bytes {
  size: i64
}

impl Into<Bytes> for i64 {
  fn into(self) -> Bytes {
    Bytes { size: self }
  }
}

impl FromStr for Bytes {
  type Err = String;
  fn from_str(s: &str) -> Result<Bytes, String> {
    let units = map!(
      'E' => EXABYTE,
      'P' => PETABYTE,
      'T' => TERABYTE,
      'G' => GIGABYTE,
      'M' => MEGABYTE,
      'K' => KILOBYTE
    );
    let len = s.len();
    if len > 1 {
      let last = s.chars().last().unwrap();
      match units.get(&last) {
        Some(unit) => {
          let init: String = s.chars().take(s.chars().count() - 1).collect();
          init.parse::<i64>().map(|lit| {
            Bytes { size: lit * unit }
          }).or_else(|_| Err(s.to_owned()))
        },
        _ => {
          Err(s.to_owned())
        }
      }
    } else {
      Err(s.to_owned())
    }
  }
}

#[test]
fn test_bytes() {
  assert_eq!(1.bytes(), 1);
}

#[test]
fn test_kilobytes() {
  assert_eq!(1.kilobytes(), 1024)
}

#[test]
fn test_megabytes() {
  assert_eq!(1.megabytes(), 1048576)
}

#[test]
fn test_gigabytes() {
  assert_eq!(1.gigabytes(), 1073741824)
}

#[test]
fn test_terabytes() {
  assert_eq!(1.terabytes(), 1099511627776)
}

#[test]
fn test_petabytes() {
  assert_eq!(1.petabytes(), 1125899906842624)
}

#[test]
fn test_exabytes() {
  assert_eq!(1.exabytes(), 1152921504606846976)
}

#[test]
fn test_kilobytes_capactity() {
  let half = 1.kilobytes() / 2;
  assert_eq!((1.kilobytes() + half).capacity(), "1.5K".to_owned())
}

#[test]
fn test_megabytes_capactity() {
  let half = 1.megabytes() / 2;
  assert_eq!((1.megabytes() + half).capacity(), "1.5M".to_owned())
}

#[test]
fn test_gigabytes_capactity() {
  let half = 1.gigabytes() / 2;
  assert_eq!((1.gigabytes() + half).capacity(), "1.5G".to_owned())
}

#[test]
fn test_terabytes_capactity() {
  let half = 1.terabytes() / 2;
  assert_eq!((1.terabytes() + half).capacity(), "1.5T".to_owned())
}

#[test]
fn test_petabytes_capactity() {
  let half = 1.petabytes() / 2;
  assert_eq!((1.petabytes() + half).capacity(), "1.5P".to_owned())
}

#[test]
fn test_exabytes_capactity() {
  let half = 1.exabytes() / 2;
  assert_eq!((1.exabytes() + half).capacity(), "1.5E".to_owned())
}

#[test]
fn test_kilobytes_parse() {
  let cap: String = 1.kilobytes().capacity();
  let bytes = cap.parse::<Bytes>().ok().unwrap();
  assert_eq!(bytes.size.capacity(), cap)
}
<commit_msg>treat bytes as bytes<commit_after>use std::convert::Into;
use std::str::FromStr;

const BYTE: i64     = 1;
const KILOBYTE: i64 = BYTE     << 10;
const MEGABYTE: i64 = KILOBYTE << 10;
const GIGABYTE: i64 = MEGABYTE << 10;
const TERABYTE: i64 = GIGABYTE << 10;
const PETABYTE: i64 = TERABYTE << 10;
const EXABYTE: i64  = PETABYTE << 10;

macro_rules! map(
  { $($key:expr => $value:expr),+ } => {
    {
      let mut m = ::std::collections::HashMap::new();
      $(
        m.insert($key, $value);
        )+
        m
    }
  };
);

pub trait Capacity {

  fn bytes(&self) -> i64;

  fn kilobytes(&self) -> i64 {
    self.bytes().rotate_left(10)
  }

  fn megabytes(&self) -> i64 {
    self.kilobytes().rotate_left(10)
  }

  fn gigabytes(&self) -> i64 {
    self.megabytes().rotate_left(10)
  }

  fn terabytes(&self) -> i64 {
    self.gigabytes().rotate_left(10)
  }

  fn petabytes(&self) -> i64 {
    self.terabytes().rotate_left(10)
  }

  fn exabytes(&self) -> i64 {
    self.petabytes().rotate_left(10)
  }

  fn capacity(&self) -> String {
    match self.bytes() {
      small if small < KILOBYTE =>
        stringify!(small).to_owned(),
      large => {
        let units = vec![
          ('E', EXABYTE),
          ('P', PETABYTE),
          ('T', TERABYTE),
          ('G', GIGABYTE),
          ('M', MEGABYTE),
          ('K', KILOBYTE)
        ];
        for (suffix, size) in units {
          if large == size {
            return format!("1{}", suffix)
          } else if large > size {
            let sized = (large as f64) / (size as f64);
            let round = (sized * 100.0).round() / 100.0;
            return format!("{:.1}{}", round, suffix)
          }
        }
        unreachable!()
      }
    }
  }
}

impl Capacity for i64 {
  fn bytes(&self) -> i64 {
    *self
  }
}

impl Capacity for Bytes {
  fn bytes(&self) -> i64 {
    (*self).size
  }
}

#[derive(Debug)]
pub struct Bytes {
  size: i64
}

impl Into<Bytes> for i64 {
  fn into(self) -> Bytes {
    Bytes { size: self }
  }
}

impl FromStr for Bytes {
  type Err = String;
  fn from_str(s: &str) -> Result<Bytes, String> {
    let units = map!(
      'E' => EXABYTE,
      'P' => PETABYTE,
      'T' => TERABYTE,
      'G' => GIGABYTE,
      'M' => MEGABYTE,
      'K' => KILOBYTE
    );
    let len = s.len();
    if len > 1 {
      let last = s.chars().last().unwrap();
      match units.get(&last) {
        Some(unit) => {
          let init: String = s.chars().take(s.chars().count() - 1).collect();
          init.parse::<i64>().map(|lit| {
            Bytes { size: lit * unit }
          }).or_else(|_| Err(s.to_owned()))
        },
        _ => {
          Err(s.to_owned())
        }
      }
    } else {
      s.parse::<i64>().map(|lit| {
        Bytes { size: lit }
      }).or_else(|_| Err(s.to_owned()))
    }
  }
}

#[test]
fn test_bytes() {
  assert_eq!(1.bytes(), 1);
}

#[test]
fn test_kilobytes() {
  assert_eq!(1.kilobytes(), 1024)
}

#[test]
fn test_megabytes() {
  assert_eq!(1.megabytes(), 1048576)
}

#[test]
fn test_gigabytes() {
  assert_eq!(1.gigabytes(), 1073741824)
}

#[test]
fn test_terabytes() {
  assert_eq!(1.terabytes(), 1099511627776)
}

#[test]
fn test_petabytes() {
  assert_eq!(1.petabytes(), 1125899906842624)
}

#[test]
fn test_exabytes() {
  assert_eq!(1.exabytes(), 1152921504606846976)
}

#[test]
fn test_kilobytes_capactity() {
  let half = 1.kilobytes() / 2;
  assert_eq!((1.kilobytes() + half).capacity(), "1.5K".to_owned())
}

#[test]
fn test_megabytes_capactity() {
  let half = 1.megabytes() / 2;
  assert_eq!((1.megabytes() + half).capacity(), "1.5M".to_owned())
}

#[test]
fn test_gigabytes_capactity() {
  let half = 1.gigabytes() / 2;
  assert_eq!((1.gigabytes() + half).capacity(), "1.5G".to_owned())
}

#[test]
fn test_terabytes_capactity() {
  let half = 1.terabytes() / 2;
  assert_eq!((1.terabytes() + half).capacity(), "1.5T".to_owned())
}

#[test]
fn test_petabytes_capactity() {
  let half = 1.petabytes() / 2;
  assert_eq!((1.petabytes() + half).capacity(), "1.5P".to_owned())
}

#[test]
fn test_exabytes_capactity() {
  let half = 1.exabytes() / 2;
  assert_eq!((1.exabytes() + half).capacity(), "1.5E".to_owned())
}

#[test]
fn test_kilobytes_parse() {
  let cap: String = 1.kilobytes().capacity();
  let bytes = cap.parse::<Bytes>().ok().unwrap();
  assert_eq!(bytes.size.capacity(), cap)
}
<|endoftext|>