<commit_before>//! Wrapper types that specify positions in a source file

#[cfg(feature = "serialization")]
use serde::{Deserialize, Serialize};
use std::fmt;
use std::ops::{Add, AddAssign, Neg, Sub, SubAssign};

/// The raw, untyped index. We use a 32-bit integer here for space efficiency,
/// assuming we won't be working with sources larger than 4GB.
pub type RawIndex = u32;

/// The raw, untyped offset.
pub type RawOffset = i64;

/// A zero-indexed line offset into a source file
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
pub struct LineIndex(pub RawIndex);

impl LineIndex {
    /// The 1-indexed line number. Useful for pretty printing source locations.
    ///
    /// ```rust
    /// use codespan::{LineIndex, LineNumber};
    ///
    /// assert_eq!(format!("{}", LineIndex(0).number()), "1");
    /// assert_eq!(format!("{}", LineIndex(3).number()), "4");
    /// ```
    pub const fn number(self) -> LineNumber {
        LineNumber(self.0 + 1)
    }

    /// Convert the index into a `usize`, for use in array indexing
    pub const fn to_usize(self) -> usize {
        self.0 as usize
    }
}

impl Default for LineIndex {
    fn default() -> LineIndex {
        LineIndex(0)
    }
}

impl fmt::Debug for LineIndex {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "LineIndex(")?;
        self.0.fmt(f)?;
        write!(f, ")")
    }
}

impl fmt::Display for LineIndex {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

/// A 1-indexed line number. Useful for pretty printing source locations.
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
pub struct LineNumber(RawIndex);

impl fmt::Debug for LineNumber {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "LineNumber(")?;
        self.0.fmt(f)?;
        write!(f, ")")
    }
}

impl fmt::Display for LineNumber {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

/// A line offset in a source file
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
pub struct LineOffset(pub RawOffset);

impl Default for LineOffset {
    fn default() -> LineOffset {
        LineOffset(0)
    }
}

impl fmt::Debug for LineOffset {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "LineOffset(")?;
        self.0.fmt(f)?;
        write!(f, ")")
    }
}

impl fmt::Display for LineOffset {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

/// A zero-indexed column offset into a source file
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
pub struct ColumnIndex(pub RawIndex);

impl ColumnIndex {
    /// The 1-indexed column number. Useful for pretty printing source locations.
    ///
    /// ```rust
    /// use codespan::{ColumnIndex, ColumnNumber};
    ///
    /// assert_eq!(format!("{}", ColumnIndex(0).number()), "1");
    /// assert_eq!(format!("{}", ColumnIndex(3).number()), "4");
    /// ```
    pub const fn number(self) -> ColumnNumber {
        ColumnNumber(self.0 + 1)
    }

    /// Convert the index into a `usize`, for use in array indexing
    pub const fn to_usize(self) -> usize {
        self.0 as usize
    }
}

impl Default for ColumnIndex {
    fn default() -> ColumnIndex {
        ColumnIndex(0)
    }
}

impl fmt::Debug for ColumnIndex {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "ColumnIndex(")?;
        self.0.fmt(f)?;
        write!(f, ")")
    }
}

impl fmt::Display for ColumnIndex {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

/// A 1-indexed column number. Useful for pretty printing source locations.
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
pub struct ColumnNumber(RawIndex);

impl fmt::Debug for ColumnNumber {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "ColumnNumber(")?;
        self.0.fmt(f)?;
        write!(f, ")")
    }
}

impl fmt::Display for ColumnNumber {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

/// A column offset in a source file
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
pub struct ColumnOffset(pub RawOffset);

impl Default for ColumnOffset {
    fn default() -> ColumnOffset {
        ColumnOffset(0)
    }
}

impl fmt::Debug for ColumnOffset {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "ColumnOffset(")?;
        self.0.fmt(f)?;
        write!(f, ")")
    }
}

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

/// A byte position in a source file.
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
pub struct ByteIndex(pub RawIndex);

impl ByteIndex {
    /// Convert the position into a `usize`, for use in array indexing
    pub const fn to_usize(self) -> usize {
        self.0 as usize
    }
}

impl Default for ByteIndex {
    fn default() -> ByteIndex {
        ByteIndex(0)
    }
}

impl fmt::Debug for ByteIndex {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "ByteIndex(")?;
        self.0.fmt(f)?;
        write!(f, ")")
    }
}

impl fmt::Display for ByteIndex {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

/// A byte offset in a source file
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
pub struct ByteOffset(pub RawOffset);

impl ByteOffset {
    /// Create a byte offset from a UTF8-encoded character
    ///
    /// ```rust
    /// use codespan::ByteOffset;
    ///
    /// assert_eq!(ByteOffset::from_char_len('A').to_usize(), 1);
    /// assert_eq!(ByteOffset::from_char_len('ß').to_usize(), 2);
    /// assert_eq!(ByteOffset::from_char_len('ℝ').to_usize(), 3);
    /// assert_eq!(ByteOffset::from_char_len('💣').to_usize(), 4);
    /// ```
    pub fn from_char_len(ch: char) -> ByteOffset {
        ByteOffset(ch.len_utf8() as RawOffset)
    }

    /// Create a byte offset from a UTF- encoded string
    ///
    /// ```rust
    /// use codespan::ByteOffset;
    ///
    /// assert_eq!(ByteOffset::from_str_len("A").to_usize(), 1);
    /// assert_eq!(ByteOffset::from_str_len("ß").to_usize(), 2);
    /// assert_eq!(ByteOffset::from_str_len("ℝ").to_usize(), 3);
    /// assert_eq!(ByteOffset::from_str_len("💣").to_usize(), 4);
    /// ```
    pub fn from_str_len(value: &str) -> ByteOffset {
        ByteOffset(value.len() as RawOffset)
    }

    /// Convert the offset into a `usize`, for use in array indexing
    pub const fn to_usize(self) -> usize {
        self.0 as usize
    }
}

impl Default for ByteOffset {
    #[inline]
    fn default() -> ByteOffset {
        ByteOffset(0)
    }
}

impl fmt::Debug for ByteOffset {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "ByteOffset(")?;
        self.0.fmt(f)?;
        write!(f, ")")
    }
}

impl fmt::Display for ByteOffset {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

/// A relative offset between two indices
///
/// These can be thought of as 1-dimensional vectors
pub trait Offset: Copy + Ord
where
    Self: Neg<Output = Self>,
    Self: Add<Self, Output = Self>,
    Self: AddAssign<Self>,
    Self: Sub<Self, Output = Self>,
    Self: SubAssign<Self>,
{
    const ZERO: Self;
}

/// Index types
///
/// These can be thought of as 1-dimensional points
pub trait Index: Copy + Ord
where
    Self: Add<<Self as Index>::Offset, Output = Self>,
    Self: AddAssign<<Self as Index>::Offset>,
    Self: Sub<<Self as Index>::Offset, Output = Self>,
    Self: SubAssign<<Self as Index>::Offset>,
    Self: Sub<Self, Output = <Self as Index>::Offset>,
{
    type Offset: Offset;
}

macro_rules! impl_index {
    ($Index:ident, $Offset:ident) => {
        impl From<RawOffset> for $Offset {
            #[inline]
            fn from(i: RawOffset) -> Self {
                $Offset(i)
            }
        }

        impl From<RawIndex> for $Index {
            #[inline]
            fn from(i: RawIndex) -> Self {
                $Index(i)
            }
        }

        impl Offset for $Offset {
            const ZERO: $Offset = $Offset(0);
        }

        impl Index for $Index {
            type Offset = $Offset;
        }

        impl Add<$Offset> for $Index {
            type Output = $Index;

            #[inline]
            fn add(self, rhs: $Offset) -> $Index {
                $Index((self.0 as RawOffset + rhs.0) as RawIndex)
            }
        }

        impl AddAssign<$Offset> for $Index {
            #[inline]
            fn add_assign(&mut self, rhs: $Offset) {
                *self = *self + rhs;
            }
        }

        impl Neg for $Offset {
            type Output = $Offset;

            #[inline]
            fn neg(self) -> $Offset {
                $Offset(-self.0)
            }
        }

        impl Add<$Offset> for $Offset {
            type Output = $Offset;

            #[inline]
            fn add(self, rhs: $Offset) -> $Offset {
                $Offset(self.0 + rhs.0)
            }
        }

        impl AddAssign<$Offset> for $Offset {
            #[inline]
            fn add_assign(&mut self, rhs: $Offset) {
                self.0 += rhs.0;
            }
        }

        impl Sub<$Offset> for $Offset {
            type Output = $Offset;

            #[inline]
            fn sub(self, rhs: $Offset) -> $Offset {
                $Offset(self.0 - rhs.0)
            }
        }

        impl SubAssign<$Offset> for $Offset {
            #[inline]
            fn sub_assign(&mut self, rhs: $Offset) {
                self.0 -= rhs.0;
            }
        }

        impl Sub for $Index {
            type Output = $Offset;

            #[inline]
            fn sub(self, rhs: $Index) -> $Offset {
                $Offset(self.0 as RawOffset - rhs.0 as RawOffset)
            }
        }

        impl Sub<$Offset> for $Index {
            type Output = $Index;

            #[inline]
            fn sub(self, rhs: $Offset) -> $Index {
                $Index((self.0 as RawOffset - rhs.0 as RawOffset) as u32)
            }
        }

        impl SubAssign<$Offset> for $Index {
            #[inline]
            fn sub_assign(&mut self, rhs: $Offset) {
                self.0 = (self.0 as RawOffset - rhs.0) as RawIndex;
            }
        }
    };
}

impl_index!(LineIndex, LineOffset);
impl_index!(ColumnIndex, ColumnOffset);
impl_index!(ByteIndex, ByteOffset);
<commit_msg>Fix gutter misalignments<commit_after>//! Wrapper types that specify positions in a source file

#[cfg(feature = "serialization")]
use serde::{Deserialize, Serialize};
use std::fmt;
use std::ops::{Add, AddAssign, Neg, Sub, SubAssign};

/// The raw, untyped index. We use a 32-bit integer here for space efficiency,
/// assuming we won't be working with sources larger than 4GB.
pub type RawIndex = u32;

/// The raw, untyped offset.
pub type RawOffset = i64;

/// A zero-indexed line offset into a source file
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
pub struct LineIndex(pub RawIndex);

impl LineIndex {
    /// The 1-indexed line number. Useful for pretty printing source locations.
    ///
    /// ```rust
    /// use codespan::{LineIndex, LineNumber};
    ///
    /// assert_eq!(format!("{}", LineIndex(0).number()), "1");
    /// assert_eq!(format!("{}", LineIndex(3).number()), "4");
    /// ```
    pub const fn number(self) -> LineNumber {
        LineNumber(self.0 + 1)
    }

    /// Convert the index into a `usize`, for use in array indexing
    pub const fn to_usize(self) -> usize {
        self.0 as usize
    }
}

impl Default for LineIndex {
    fn default() -> LineIndex {
        LineIndex(0)
    }
}

impl fmt::Debug for LineIndex {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "LineIndex(")?;
        self.0.fmt(f)?;
        write!(f, ")")
    }
}

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

/// A 1-indexed line number. Useful for pretty printing source locations.
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
pub struct LineNumber(RawIndex);

impl fmt::Debug for LineNumber {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "LineNumber(")?;
        self.0.fmt(f)?;
        write!(f, ")")
    }
}

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

/// A line offset in a source file
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
pub struct LineOffset(pub RawOffset);

impl Default for LineOffset {
    fn default() -> LineOffset {
        LineOffset(0)
    }
}

impl fmt::Debug for LineOffset {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "LineOffset(")?;
        self.0.fmt(f)?;
        write!(f, ")")
    }
}

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

/// A zero-indexed column offset into a source file
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
pub struct ColumnIndex(pub RawIndex);

impl ColumnIndex {
    /// The 1-indexed column number. Useful for pretty printing source locations.
    ///
    /// ```rust
    /// use codespan::{ColumnIndex, ColumnNumber};
    ///
    /// assert_eq!(format!("{}", ColumnIndex(0).number()), "1");
    /// assert_eq!(format!("{}", ColumnIndex(3).number()), "4");
    /// ```
    pub const fn number(self) -> ColumnNumber {
        ColumnNumber(self.0 + 1)
    }

    /// Convert the index into a `usize`, for use in array indexing
    pub const fn to_usize(self) -> usize {
        self.0 as usize
    }
}

impl Default for ColumnIndex {
    fn default() -> ColumnIndex {
        ColumnIndex(0)
    }
}

impl fmt::Debug for ColumnIndex {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "ColumnIndex(")?;
        self.0.fmt(f)?;
        write!(f, ")")
    }
}

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

/// A 1-indexed column number. Useful for pretty printing source locations.
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
pub struct ColumnNumber(RawIndex);

impl fmt::Debug for ColumnNumber {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "ColumnNumber(")?;
        self.0.fmt(f)?;
        write!(f, ")")
    }
}

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

/// A column offset in a source file
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
pub struct ColumnOffset(pub RawOffset);

impl Default for ColumnOffset {
    fn default() -> ColumnOffset {
        ColumnOffset(0)
    }
}

impl fmt::Debug for ColumnOffset {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "ColumnOffset(")?;
        self.0.fmt(f)?;
        write!(f, ")")
    }
}

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

/// A byte position in a source file.
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
pub struct ByteIndex(pub RawIndex);

impl ByteIndex {
    /// Convert the position into a `usize`, for use in array indexing
    pub const fn to_usize(self) -> usize {
        self.0 as usize
    }
}

impl Default for ByteIndex {
    fn default() -> ByteIndex {
        ByteIndex(0)
    }
}

impl fmt::Debug for ByteIndex {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "ByteIndex(")?;
        self.0.fmt(f)?;
        write!(f, ")")
    }
}

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

/// A byte offset in a source file
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
pub struct ByteOffset(pub RawOffset);

impl ByteOffset {
    /// Create a byte offset from a UTF8-encoded character
    ///
    /// ```rust
    /// use codespan::ByteOffset;
    ///
    /// assert_eq!(ByteOffset::from_char_len('A').to_usize(), 1);
    /// assert_eq!(ByteOffset::from_char_len('ß').to_usize(), 2);
    /// assert_eq!(ByteOffset::from_char_len('ℝ').to_usize(), 3);
    /// assert_eq!(ByteOffset::from_char_len('💣').to_usize(), 4);
    /// ```
    pub fn from_char_len(ch: char) -> ByteOffset {
        ByteOffset(ch.len_utf8() as RawOffset)
    }

    /// Create a byte offset from a UTF- encoded string
    ///
    /// ```rust
    /// use codespan::ByteOffset;
    ///
    /// assert_eq!(ByteOffset::from_str_len("A").to_usize(), 1);
    /// assert_eq!(ByteOffset::from_str_len("ß").to_usize(), 2);
    /// assert_eq!(ByteOffset::from_str_len("ℝ").to_usize(), 3);
    /// assert_eq!(ByteOffset::from_str_len("💣").to_usize(), 4);
    /// ```
    pub fn from_str_len(value: &str) -> ByteOffset {
        ByteOffset(value.len() as RawOffset)
    }

    /// Convert the offset into a `usize`, for use in array indexing
    pub const fn to_usize(self) -> usize {
        self.0 as usize
    }
}

impl Default for ByteOffset {
    #[inline]
    fn default() -> ByteOffset {
        ByteOffset(0)
    }
}

impl fmt::Debug for ByteOffset {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "ByteOffset(")?;
        self.0.fmt(f)?;
        write!(f, ")")
    }
}

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

/// A relative offset between two indices
///
/// These can be thought of as 1-dimensional vectors
pub trait Offset: Copy + Ord
where
    Self: Neg<Output = Self>,
    Self: Add<Self, Output = Self>,
    Self: AddAssign<Self>,
    Self: Sub<Self, Output = Self>,
    Self: SubAssign<Self>,
{
    const ZERO: Self;
}

/// Index types
///
/// These can be thought of as 1-dimensional points
pub trait Index: Copy + Ord
where
    Self: Add<<Self as Index>::Offset, Output = Self>,
    Self: AddAssign<<Self as Index>::Offset>,
    Self: Sub<<Self as Index>::Offset, Output = Self>,
    Self: SubAssign<<Self as Index>::Offset>,
    Self: Sub<Self, Output = <Self as Index>::Offset>,
{
    type Offset: Offset;
}

macro_rules! impl_index {
    ($Index:ident, $Offset:ident) => {
        impl From<RawOffset> for $Offset {
            #[inline]
            fn from(i: RawOffset) -> Self {
                $Offset(i)
            }
        }

        impl From<RawIndex> for $Index {
            #[inline]
            fn from(i: RawIndex) -> Self {
                $Index(i)
            }
        }

        impl Offset for $Offset {
            const ZERO: $Offset = $Offset(0);
        }

        impl Index for $Index {
            type Offset = $Offset;
        }

        impl Add<$Offset> for $Index {
            type Output = $Index;

            #[inline]
            fn add(self, rhs: $Offset) -> $Index {
                $Index((self.0 as RawOffset + rhs.0) as RawIndex)
            }
        }

        impl AddAssign<$Offset> for $Index {
            #[inline]
            fn add_assign(&mut self, rhs: $Offset) {
                *self = *self + rhs;
            }
        }

        impl Neg for $Offset {
            type Output = $Offset;

            #[inline]
            fn neg(self) -> $Offset {
                $Offset(-self.0)
            }
        }

        impl Add<$Offset> for $Offset {
            type Output = $Offset;

            #[inline]
            fn add(self, rhs: $Offset) -> $Offset {
                $Offset(self.0 + rhs.0)
            }
        }

        impl AddAssign<$Offset> for $Offset {
            #[inline]
            fn add_assign(&mut self, rhs: $Offset) {
                self.0 += rhs.0;
            }
        }

        impl Sub<$Offset> for $Offset {
            type Output = $Offset;

            #[inline]
            fn sub(self, rhs: $Offset) -> $Offset {
                $Offset(self.0 - rhs.0)
            }
        }

        impl SubAssign<$Offset> for $Offset {
            #[inline]
            fn sub_assign(&mut self, rhs: $Offset) {
                self.0 -= rhs.0;
            }
        }

        impl Sub for $Index {
            type Output = $Offset;

            #[inline]
            fn sub(self, rhs: $Index) -> $Offset {
                $Offset(self.0 as RawOffset - rhs.0 as RawOffset)
            }
        }

        impl Sub<$Offset> for $Index {
            type Output = $Index;

            #[inline]
            fn sub(self, rhs: $Offset) -> $Index {
                $Index((self.0 as RawOffset - rhs.0 as RawOffset) as u32)
            }
        }

        impl SubAssign<$Offset> for $Index {
            #[inline]
            fn sub_assign(&mut self, rhs: $Offset) {
                self.0 = (self.0 as RawOffset - rhs.0) as RawIndex;
            }
        }
    };
}

impl_index!(LineIndex, LineOffset);
impl_index!(ColumnIndex, ColumnOffset);
impl_index!(ByteIndex, ByteOffset);
<|endoftext|>


<commit_before>infer_schema!("dotenv:DATABASE_URL");
<commit_msg>fix: Don't infer schema as .env is unavailable in release<commit_after>table! {
    teams {
        id -> Integer,
        time -> Double,
    }
}

table! {
    members {
        id -> Integer,
        name -> Text,
        team_id -> Integer,
        active -> Bool,
        driver -> Bool,
        position -> Integer,
    }
}
<|endoftext|>


<commit_before>use rayon::prelude::*;
use encoding::DecoderTrap;
use chardet::{detect,charset2encoding};
use encoding::label::encoding_from_whatwg_label;

use super::consts::space_fix;
use std::process::Command as Cmd;
use std::process::Output;
use std::error::Error;

#[derive(Debug)]
pub struct Pings {
    pub _6: bool,
    pub only_line: bool,
    pub hosts: Vec<String>,
    pub count: u64,
}
impl Pings {
    pub fn call(self) {
        dbstln!("{:?}",self);
        let host_len_max = self.hosts.as_slice().iter().max_by_key(|p|p.len()).unwrap().len();
        // sleep sort
        self.hosts.par_iter()
         .for_each(|host| ping(host, &self,host_len_max))
    }
    pub fn check_fix(&mut self) -> Result<(), String> {
        let mut vs = Vec::new();
        for arg in &self.hosts {
            let addr =  if self._6 {
                RE6.find(arg)
            } else {
                RE.find(arg)
            };
            if addr.is_none() {
                return Err(format!("ARG is't contains reachable domain/ip: {:?} ", arg));
            }
            vs.push(addr.unwrap().to_string())
        }
        debug_assert!(!vs.is_empty());
        self.hosts = vs;
        Ok(())
    }
}

impl Default for Pings {
    fn default() -> Self {
        Pings {
            _6: false,
            only_line: false,
            hosts: Vec::new(),
            count: 3,
        }
    }
}

fn ping(host:&str, config: &Pings,  host_len_max: usize) {
    let count_str = format!("{}", config.count);
    let mut args = Vec::new();
    let mut ping = "ping";
    // -6
    if config._6 {
        if cfg!(unix){
            ping = "ping6";
        } else {
        args.push("-6");}
    }
    // -count
    if cfg!(unix) {
        args.push("-c");
    } else {
        args.push("-n");
    };
    args.push(&count_str);

    // host
    args.push(host);

    let output = Cmd::new(ping)
        .args(&args[..])
        .output()
        .map_err(|e| panic!("exec ping fails: {}", e.description()))
        .unwrap();
    if output.status.success() && !output.stdout.is_empty() {
        printf(&output, config.only_line, host, host_len_max);
    } else if !output.stderr.is_empty() {
        printf_err(&output, host, host_len_max);
    }
}

fn printf(msg: &Output, only_line: bool, host: &str, host_len_max: usize) {
    debug_assert!(!msg.stdout.is_empty());
    let msg = decode(&msg.stdout[..]);
    let msg = msg.trim();
    // -l/--only-line
    if !only_line {
        println!("{}\n", msg);
        return;
    }

    let vs: Vec<String> = msg.lines().map(|s| s.trim().to_string()).collect();
    dbstln!("{:?}", msg);

    #[cfg(unix)]
    assert!(!vs.len()>2);
    #[cfg(unix)]
    println!("{}: {} -> {}",
             space_fix(host, host_len_max),
             vs[vs.len() - 1],
             vs[vs.len() - 2]);

    #[cfg(windows)]
    assert!(!vs.len()>3);
    #[cfg(windows)]
    println!("{}: {} -> {}",
             space_fix(host, host_len_max),
             vs[vs.len() - 1],
             vs[vs.len() - 3]);
}

fn printf_err(msg: &Output, host: &str, host_len_max: usize) {
    let msg = decode(&msg.stderr[..]);
    let vs: Vec<String> = msg.trim()
        .lines()
        .map(|s| s.trim().to_string())
        .collect();
    assert!(!vs.is_empty());

    errln!("{}: {}", space_fix(host, host_len_max), vs[vs.len() - 1]);
}

// #[cfg(unix)]
// fn decode(msg: &[u8]) -> String {
//     String::from_utf8_lossy(msg).into_owned().to_owned()
// }

// #[cfg(windows)]
fn decode(msg: &[u8]) -> String {
    let result = detect(msg);
    if let Some(code) =  encoding_from_whatwg_label(charset2encoding(&result.0)) {
       if let Ok(str)= code.decode(msg, DecoderTrap::Strict){
           return str;
       }
    }
    String::from_utf8_lossy(msg).into_owned().to_owned()
}
<commit_msg>ping: Use polling instead of multithreading to reduce memory usage, and fix a bug of output's format about '100% packet loss'.<commit_after>use encoding::DecoderTrap;
use chardet::{detect,charset2encoding};
use encoding::label::encoding_from_whatwg_label;

use super::consts::space_fix;
use std::process::Command as Cmd;
use std::process::Output;
use std::time::Duration;
use std::process::{Stdio, Child};
use std::thread::sleep;
use std::error::Error;
use std::io;

#[derive(Debug)]
pub struct Pings {
    pub _6: bool,
    pub only_line: bool,
    pub hosts: Vec<String>,
    pub count: u64,
}
impl Pings {
    pub fn check_fix(&mut self) -> Result<(), String> {
        let mut vs = Vec::new();
        for arg in &self.hosts {
            let addr =  if self._6 {
                RE6.find(arg)
            } else {
                RE.find(arg)
            };
            if addr.is_none() {
                return Err(format!("ARG is't contains reachable domain/ip: {:?} ", arg));
            }
            vs.push(addr.unwrap().to_string())
        }
        debug_assert!(!vs.is_empty());
        self.hosts = vs;
        Ok(())
    }
    pub fn call(self) {
        dbstln!("{:?}",self);
        let host_len_max = self.hosts.as_slice().iter().max_by_key(|p|p.len()).unwrap().len();
        // sleep sort
        let mut childs = self.hosts.as_slice().iter()
          .map(|host|ping(host, &self)
          .map_err(|e| eprintln!("exec ping fails: {}", e.description())))
          .filter_map(|r| r.ok())
          .collect::<Vec<_>>();

        while !childs.is_empty() {
            let mut wait = true;
            let mut idx =0;

            while idx+1 <= childs.len() {
                match childs[idx].0.try_wait() {
                        Ok(None) => {
                            idx+=1;
                            continue;
                        }
                        _=> {
                            wait = false;
                            let (r, host) = childs.remove(idx);
                            callback(r, host, self.only_line,  host_len_max);
                        }
                }
            }
            if  wait && !childs.is_empty() {
                // 1ms=1000_000ns
                sleep(Duration::new(0, 100_000));
            }
        }
    }
}

impl Default for Pings {
    fn default() -> Self {
        Pings {
            _6: false,
            only_line: false,
            hosts: Vec::new(),
            count: 3,
        }
    }
}

fn ping<'a>(host:&'a str, config: &Pings)-> io::Result<(Child, &'a str)> {
    let count_str = format!("{}", config.count);
    let mut args = Vec::new();
    let mut ping = "ping";
    // -6
    if config._6 {
        if cfg!(unix){
            ping = "ping6";
        } else {
        args.push("-6");}
    }
    // -count
    if cfg!(unix) {
        args.push("-c");
    } else {
        args.push("-n");
    };
    args.push(&count_str);

    // host
    args.push(host);

    Cmd::new(ping).args(&args[..]).stderr(Stdio::piped()).stdout(Stdio::piped()).spawn().map(|r|(r, host))
}

fn callback(child: Child, host: &str,  only_line: bool,  host_len_max: usize) {
    let output = child.wait_with_output().map_err(|e|eprintln!("wait ping fails: {}", e.description()));

    if let Ok(output) =output {
        if output.status.success() && !output.stdout.is_empty() {
            printf0(&output, only_line, host, host_len_max);
        }else if !output.status.success() && !output.stdout.is_empty() {
            printf1(&output, only_line, host, host_len_max);
        }else if !output.stderr.is_empty() {
            printf_err(&output, host, host_len_max);
        } else {
            eprintln!("ping {:?} -> code: {:?}, stdout.is_empty: {}, stderr.is_empty: {}", host, output.status,output.stdout.is_empty(), output.stderr.is_empty());
        }
    }
}

fn printf0(msg: &Output, only_line: bool, host: &str, host_len_max: usize) {
    let msg = decode(&msg.stdout[..]);
    let msg = msg.trim();
    // -l/--only-line
    if !only_line {
        println!("{}\n", msg);
        return;
    }

    let vs: Vec<String> = msg.lines().map(|s| s.trim().to_string()).collect();
    dbstln!("{:?}", msg);

    #[cfg(unix)]
    assert!(!vs.len()>2);
    #[cfg(unix)]
    println!("{}: {} -> {}",
             space_fix(host, host_len_max),
             vs[vs.len() - 1],
             vs[vs.len() - 2]);

    #[cfg(windows)]
    assert!(!vs.len()>3);
    #[cfg(windows)]
    println!("{}: {} -> {}",
             space_fix(host, host_len_max),
             vs[vs.len() - 1],
             vs[vs.len() - 3]);
}

// ping fuck.co -c 3                                                                                (%1)
// 3 packets transmitted, 0 received, 100% packet loss, time 2016ms
fn printf1(msg: &Output, only_line: bool, host: &str, host_len_max: usize) {
    let msg = decode(&msg.stdout[..]);
    let msg = msg.trim();
    // -l/--only-line
    if !only_line {
        println!("{}\n", msg);
        return;
    }

    let vs: Vec<String> = msg.lines().map(|s| s.trim().to_string()).collect();
    dbstln!("{:?}", msg);

    #[cfg(unix)]
    assert!(!vs.len()>2);
    #[cfg(unix)]
    println!("{}: -> {}",
             space_fix(host, host_len_max),
             vs[vs.len() - 1]);

    #[cfg(windows)]
    assert!(!vs.len()>3);
    #[cfg(windows)]
    println!("{}: -> {}",
             space_fix(host, host_len_max),
             vs[vs.len() - 1]);
}
fn printf_err(msg: &Output, host: &str, host_len_max: usize) {
    let msg = decode(&msg.stderr[..]);
    let vs: Vec<String> = msg.trim()
        .lines()
        .map(|s| s.trim().to_string())
        .collect();
    assert!(!vs.is_empty());

    errln!("{}: {}", space_fix(host, host_len_max), vs[vs.len() - 1]);
}

// #[cfg(unix)]
// fn decode(msg: &[u8]) -> String {
//     String::from_utf8_lossy(msg).into_owned().to_owned()
// }

// #[cfg(windows)]
fn decode(msg: &[u8]) -> String {
    let result = detect(msg);
    if let Some(code) =  encoding_from_whatwg_label(charset2encoding(&result.0)) {
       if let Ok(str)= code.decode(msg, DecoderTrap::Strict){
           return str;
       }
    }
    String::from_utf8_lossy(msg).into_owned().to_owned()
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

use std::collections::{HashMap};
use ast::*;
use visit::{Visitor};
use std::cell::RefCell;
use ptr::*;

pub type OptionalBinding = Option<B<Binding>>;

pub struct TypeChecker{
    //block_stack : Vec<RefCell<&'a  Block>>,
    pub sym_tab : Vec<(String, OptionalBinding)>,
    //decl_cnt : u32,
    //decl_cnt_stack : Vec<u32>,
    pub ty : TType
}

impl TypeChecker{
    pub fn new()->Self{
        TypeChecker {sym_tab : Vec::new(), ty : TType::TNil}
    }

    fn get_type_for(&self){//}->&TType{
        //self.block_stack
    }
}

impl<'a> Visitor<'a> for TypeChecker{
    fn visit_expr(&mut self, expr: &'a mut Expr){
        match *expr{
            //FIXME remove NilExpr; this is only for unit testing
            Expr::NilExpr => self.ty = TType::TString,
            Expr::NumExpr(_) => self.ty = TType::TInt32,
            Expr::StringExpr(_) => self.ty = TType::TString,
            Expr::IdExpr(ref mut id) =>{
                //search in the symtab for id's existence and get the type
                let mut found = false;
                for &(ref _id, ref _binding) in &self.sym_tab{ //iterator returns a ref to tuple while iterating; so &(_,_) has to be used
                    if *_id == *id{
                        found = true;
                        self.ty = match **_binding.as_ref().unwrap(){
                            Binding::TypeBinding(ref ty) |
                            Binding::VarBinding(ref ty) |
                            Binding::FuncBinding(ref ty) => ty.clone()
                        };
                        break;
                    }
                }
                if !found{
                    panic!("{} not found", id);
                }
            },
            Expr::AddExpr(ref mut left, ref mut right) => {
                self.visit_expr(left);
                let left_ty = self.ty.clone();
                if left_ty != TType::TInt32{
                    panic!("Expected left operand of int type")
                }
                self.visit_expr(right);
                if self.ty != TType::TInt32{
                    panic!("Expected right operand of int type")
                }
            },
            Expr::DivExpr(ref mut left, ref mut  right) => {
                self.visit_expr(left);
                let left_ty = self.ty.clone();
                if left_ty != TType::TInt32{
                    panic!("Expected left operand of int type")
                }
                self.visit_expr(right);
                if self.ty != TType::TInt32{
                    panic!("Expected right operand of int type")
                }

                match **right{
                    Expr::NumExpr(n) => if n == 0 {panic!("Denominator cannot be 0")},
                    _ => {}
                }
            },
            Expr::SeqExpr(ref mut opt_expr_list) => {
                if opt_expr_list.is_none(){
                    self.ty = TType::TVoid;
                    return
                }
                for b_expr in opt_expr_list.as_mut().unwrap() {
                    self.visit_expr(&mut *b_expr);
                }
            },
            Expr::IfThenElseExpr(ref mut conditional_expr, ref mut then_expr, ref mut else_expr) => {
                self.visit_expr(conditional_expr);
                if self.ty != TType::TInt32{
                    panic!("Expected conditional expression of int type");
                }
                self.visit_expr(then_expr);
                let then_ty = self.ty.clone();
                self.visit_expr(else_expr);
                if then_ty != self.ty{
                    panic!("Expected then expr and else expr types to be same");
                }
            },
            Expr::IfThenExpr(ref mut conditional_expr, ref mut then_expr) => {
                self.visit_expr(conditional_expr);
                if self.ty != TType::TInt32{
                    panic!("Expected conditional expression of int type");
                }
                self.visit_expr(then_expr);
                if self.ty != TType::TVoid{
                    panic!("Expected if-body of void type")
                }
            },
            Expr::WhileExpr(ref mut conditional_expr, ref mut body) => {
                self.visit_expr(conditional_expr);
                if self.ty != TType::TInt32{
                    panic!("Expected conditional expression of int type");
                }

                self.visit_expr(body);
                if self.ty != TType::TVoid{
                    panic!("Expected while-body of void type")
                }
            },
            Expr::ForExpr(ref mut id, ref mut from, ref mut to, ref mut body) => {
                self.visit_expr(from);
                if self.ty != TType::TInt32{
                    panic!("Initializing expression type should be int in a for loop");
                }

                self.visit_expr(to);
                if self.ty != TType::TInt32{
                    panic!("To expression type should be int in a for loop");
                }
            },
            Expr::LetExpr(ref mut decls, ref mut opt_expr) => {
                self.sym_tab.push(("<marker>".to_string(), None));

                for dec in decls{ //decls is a &
                    self.visit_decl(dec);
                }

                match *opt_expr {
                    Some(ref mut b_expr) => {
                        self.visit_expr(&mut *b_expr);
                    },
                    _ => {}
                }
                //pop till marker and then pop marker
                while self.sym_tab.last().unwrap().0 != "<marker>".to_string(){
                    self.sym_tab.pop();
                }
                self.sym_tab.pop();
            },

            _ => {}
        }
    }

    fn visit_decl(&mut self, decl : &'a mut Decl){
        macro_rules! store_into_sym_tab {
            ($self_ : ident, $i : ident, $p : path) => {
                $self_.sym_tab.push(($i.clone(), Some(B($p($self_.ty.clone())))));
            }
        }
        match *decl{
            Decl::VarDec(ref id, ref ty, ref mut expr) => {
                self.visit_expr(expr);
                if *ty != self.ty{
                    panic!("Types mismatch")
                }
                store_into_sym_tab!(self, id, Binding::VarBinding);
            },
            Decl::FunDec(ref id, ref params, ref ret_type, ref body, ref body_type) => {
                let mut map = HashMap::new();
                for p in params.as_ref().unwrap(){
                    if map.contains_key(&p.0){
                        panic!(format!("Duplicate param '{0}' found", p.0));
                    }
                    map.insert(&p.0, true);
                }
                //self.visit_expr(&body);
                //if self.ty != *ret_type{
                if ret_type != body_type {
                    panic!("Return type doesn't match with the type of the last expression.")
                }
                store_into_sym_tab!(self, id, Binding::FuncBinding);
            },
            Decl::TypeDec(ref id, ref ty) => {
                store_into_sym_tab!(self, id, Binding::TypeBinding);
            }
        }
    }
}

#[test]
fn test_ty_set_for_num() {
    let mut v = TypeChecker::new();
    v.visit_expr(&Expr::NumExpr(23));
    assert_eq!(TType::TInt32, v.ty);
}

#[test]
fn test_ty_set_for_int_id() {
    let mut v = TypeChecker::new();
    v.sym_tab.push(("a".to_string(), Some(B(Binding::VarBinding(TType::TInt32)))));
    v.visit_expr(&Expr::IdExpr("a".to_string()));
    assert_eq!(TType::TInt32, v.ty);
}

#[test]
fn test_type_match_int_for_var_dec() {
    let mut v = TypeChecker::new();
    v.visit_decl(&Decl::VarDec("a".to_string(), TType::TInt32, B(Expr::NumExpr(4))));
    assert_eq!(TType::TInt32, v.ty);
    assert_eq!(v.sym_tab.len(), 1);
    assert_eq!(v.sym_tab[0].0, "a".to_string());
    //assert_eq!(v.sym_tab[0].1, TType::TInt32);
}

#[test]
fn test_type_match_string_for_var_dec() {
    let mut v = TypeChecker::new();
    v.visit_decl(&Decl::VarDec("a".to_string(), TType::TString, B(Expr::NilExpr)));
    assert_eq!(TType::TString, v.ty);
    assert_eq!(v.sym_tab.len(), 1);
    assert_eq!(v.sym_tab[0].0, "a".to_string());
    //assert_eq!(v.sym_tab[0].1, TType::TString);
}

#[test]
#[should_panic]
fn test_type_check_for_var_dec_type_mismatch() {
    let mut v = TypeChecker::new();
    v.visit_decl(&Decl::VarDec("a".to_string(), TType::TInt32, B(Expr::NilExpr)));
    assert_eq!(TType::TInt32, v.ty);
}

#[test]
fn test_correct_types_for_add_expr() {
    let mut v = TypeChecker::new();
    v.visit_expr(&mut Expr::AddExpr(B(Expr::NumExpr(4)), B(Expr::NumExpr(4))));
    assert_eq!(v.ty, TType::TInt32);
}

#[test]
#[should_panic(expected="Expected left operand of int type")]
fn test_left_type_invalid_for_add_expr() {
    let mut v = TypeChecker::new();
    v.visit_expr(&mut Expr::AddExpr(B(Expr::NilExpr), B(Expr::NumExpr(4))));
}

#[test]
#[should_panic(expected="Expected right operand of int type")]
fn test_right_type_invalid_for_add_expr() {
    let mut v = TypeChecker::new();
    v.visit_expr(&mut Expr::AddExpr(B(Expr::NumExpr(4)), B(Expr::NilExpr)));
}

#[test]
fn test_var_hiding() {
    //let mut v =
}

#[test]
fn test_func_decl_correct_return_type() {
    let mut v = TypeChecker::new();
    v.visit_decl(&Decl::FunDec(String::from("foo"), None, TType::TInt32, B(Expr::NumExpr(4)), TType::TInt32));
}

#[test]
#[should_panic(expected="Return type doesn't match with the type of the last expression.")]
fn test_func_decl_incorrect_return_type() {
    let mut v = TypeChecker::new();
    v.visit_decl(&Decl::FunDec(String::from("foo"), None, TType::TString, B(Expr::NumExpr(4)), TType::TInt32));
}

#[test]
#[should_panic(expected="Expected conditional expression of int type")]
fn test_if_expr_with_incorrect_conditional_type() {
    let mut v = TypeChecker::new();
    v.visit_expr(&Expr::IfThenExpr(B(Expr::StringExpr(String::from("a"))), B(Expr::StringExpr(String::from("a")))));
}

#[test]
fn test_if_expr_with_int_type() {
    let mut v = TypeChecker::new();
    v.visit_expr(&Expr::IfThenExpr(B(Expr::NumExpr(1)), B(Expr::SeqExpr(None))));
    assert_eq!(v.ty, TType::TVoid);
}

#[test]
#[should_panic(expected="Expected if-body of void type")]
fn test_if_expr_with_int_type_conditional_and_int_type_as_body_type() {
    let mut v = TypeChecker::new();
    v.visit_expr(&Expr::IfThenExpr(B(Expr::NumExpr(1)), B(Expr::NumExpr(1))));
    assert_eq!(v.ty, TType::TInt32);
}

#[test]
fn test_if_else_expr_with_matching_types() {
    let mut v = TypeChecker::new();
    v.visit_expr(&Expr::IfThenElseExpr(B(Expr::NumExpr(1)), B(Expr::NumExpr(1)), B(Expr::NumExpr(1))));
    assert_eq!(v.ty, TType::TInt32);
}

#[test]
#[should_panic(expected="Expected then expr and else expr types to be same")]
fn test_if_else_expr_with_non_matching_types() {
    let mut v = TypeChecker::new();
    v.visit_expr(&Expr::IfThenElseExpr(B(Expr::NumExpr(1)), B(Expr::NumExpr(1)), B(Expr::StringExpr(String::from("a")))));
}

#[test]
#[should_panic(expected="Expected conditional expression of int type")]
fn test_while_expr_with_incorrect_conditional_type() {
    let mut v = TypeChecker::new();
    v.visit_expr(&Expr::WhileExpr(B(Expr::StringExpr(String::from("a"))), B(Expr::StringExpr(String::from("a")))));
}

#[test]
#[should_panic(expected="Expected while-body of void type")]
fn test_while_expr_with_int_type() {
    let mut v = TypeChecker::new();
    v.visit_expr(&Expr::WhileExpr(B(Expr::NumExpr(1)), B(Expr::StringExpr(String::from("a")))));
}

#[test]
#[should_panic(expected="Denominator cannot be 0")]
fn test_div_expr_with_0_as_denominator(){
    let mut v = TypeChecker::new();
    v.visit_expr(&Expr::DivExpr(B(Expr::NumExpr(1)), B(Expr::NumExpr(0))));
}

#[test]
fn test_div_expr_with_1_as_denominator(){
    let mut v = TypeChecker::new();
    v.visit_expr(&Expr::DivExpr(B(Expr::NumExpr(1)), B(Expr::NumExpr(1))));
    assert_eq!(v.ty, TType::TInt32);
}

#[test]
#[should_panic(expected="Initializing expression type should be int in a for loop")]
fn test_for_loop_expr_init_type(){
    let mut v = TypeChecker::new();
    v.visit_expr(&Expr::ForExpr(String::from("i"),
                                B(Expr::StringExpr(String::from("adsd"))),
                                B(Expr::NumExpr(1)),
                                B(Expr::NumExpr(2))));
}

#[test]
#[should_panic(expected="Duplicate param 'a' found")]
fn test_func_dec_with_duplicate_param_with_same_type(){
    let mut v = TypeChecker::new();
    v.visit_decl(&Decl::FunDec(String::from("foo"),
                               Some(vec![(String::from("a"), TType::TInt32),
                                         (String::from("a"), TType::TInt32) ]),
                               TType::TString,
                               B(Expr::NumExpr(4)),
                               TType::TInt32));
}

#[test]
#[should_panic(expected="Duplicate param 'a' found")]
fn test_func_dec_with_duplicate_param_with_different_types(){
    let mut v = TypeChecker::new();
    v.visit_decl(&Decl::FunDec(String::from("foo"),
                               Some(vec![(String::from("a"), TType::TInt32),
                                         (String::from("a"), TType::TString) ]),
                               TType::TString,
                               B(Expr::NumExpr(4)),
                               TType::TInt32));
}
<commit_msg>Fix recent type-checking done in function decl in symbol-resolution branch<commit_after>#![allow(dead_code)]

use std::collections::{HashMap};
use ast::*;
use visit::{Visitor};
use std::cell::RefCell;
use ptr::*;

pub type OptionalBinding = Option<B<Binding>>;

pub struct TypeChecker{
    //block_stack : Vec<RefCell<&'a  Block>>,
    pub sym_tab : Vec<(String, OptionalBinding)>,
    //decl_cnt : u32,
    //decl_cnt_stack : Vec<u32>,
    pub ty : TType
}

impl TypeChecker{
    pub fn new()->Self{
        TypeChecker {sym_tab : Vec::new(), ty : TType::TNil}
    }

    fn get_type_for(&self){//}->&TType{
        //self.block_stack
    }
}

impl<'a> Visitor<'a> for TypeChecker{
    fn visit_expr(&mut self, expr: &'a mut Expr){
        match *expr{
            //FIXME remove NilExpr; this is only for unit testing
            Expr::NilExpr => self.ty = TType::TString,
            Expr::NumExpr(_) => self.ty = TType::TInt32,
            Expr::StringExpr(_) => self.ty = TType::TString,
            Expr::IdExpr(ref mut id) =>{
                //search in the symtab for id's existence and get the type
                let mut found = false;
                for &(ref _id, ref _binding) in &self.sym_tab{ //iterator returns a ref to tuple while iterating; so &(_,_) has to be used
                    if *_id == *id{
                        found = true;
                        self.ty = match **_binding.as_ref().unwrap(){
                            Binding::TypeBinding(ref ty) |
                            Binding::VarBinding(ref ty) |
                            Binding::FuncBinding(ref ty) => ty.clone()
                        };
                        break;
                    }
                }
                if !found{
                    panic!("{} not found", id);
                }
            },
            Expr::AddExpr(ref mut left, ref mut right) => {
                self.visit_expr(left);
                let left_ty = self.ty.clone();
                if left_ty != TType::TInt32{
                    panic!("Expected left operand of int type")
                }
                self.visit_expr(right);
                if self.ty != TType::TInt32{
                    panic!("Expected right operand of int type")
                }
            },
            Expr::DivExpr(ref mut left, ref mut  right) => {
                self.visit_expr(left);
                let left_ty = self.ty.clone();
                if left_ty != TType::TInt32{
                    panic!("Expected left operand of int type")
                }
                self.visit_expr(right);
                if self.ty != TType::TInt32{
                    panic!("Expected right operand of int type")
                }

                match **right{
                    Expr::NumExpr(n) => if n == 0 {panic!("Denominator cannot be 0")},
                    _ => {}
                }
            },
            Expr::SeqExpr(ref mut opt_expr_list) => {
                if opt_expr_list.is_none(){
                    self.ty = TType::TVoid;
                    return
                }
                for b_expr in opt_expr_list.as_mut().unwrap() {
                    self.visit_expr(&mut *b_expr);
                }
            },
            Expr::IfThenElseExpr(ref mut conditional_expr, ref mut then_expr, ref mut else_expr) => {
                self.visit_expr(conditional_expr);
                if self.ty != TType::TInt32{
                    panic!("Expected conditional expression of int type");
                }
                self.visit_expr(then_expr);
                let then_ty = self.ty.clone();
                self.visit_expr(else_expr);
                if then_ty != self.ty{
                    panic!("Expected then expr and else expr types to be same");
                }
            },
            Expr::IfThenExpr(ref mut conditional_expr, ref mut then_expr) => {
                self.visit_expr(conditional_expr);
                if self.ty != TType::TInt32{
                    panic!("Expected conditional expression of int type");
                }
                self.visit_expr(then_expr);
                if self.ty != TType::TVoid{
                    panic!("Expected if-body of void type")
                }
            },
            Expr::WhileExpr(ref mut conditional_expr, ref mut body) => {
                self.visit_expr(conditional_expr);
                if self.ty != TType::TInt32{
                    panic!("Expected conditional expression of int type");
                }

                self.visit_expr(body);
                if self.ty != TType::TVoid{
                    panic!("Expected while-body of void type")
                }
            },
            Expr::ForExpr(ref mut id, ref mut from, ref mut to, ref mut body) => {
                self.visit_expr(from);
                if self.ty != TType::TInt32{
                    panic!("Initializing expression type should be int in a for loop");
                }

                self.visit_expr(to);
                if self.ty != TType::TInt32{
                    panic!("To expression type should be int in a for loop");
                }
            },
            Expr::LetExpr(ref mut decls, ref mut opt_expr) => {
                self.sym_tab.push(("<marker>".to_string(), None));

                for dec in decls{ //decls is a &
                    self.visit_decl(dec);
                }

                match *opt_expr {
                    Some(ref mut b_expr) => {
                        self.visit_expr(&mut *b_expr);
                    },
                    _ => {}
                }
                //pop till marker and then pop marker
                while self.sym_tab.last().unwrap().0 != "<marker>".to_string(){
                    self.sym_tab.pop();
                }
                self.sym_tab.pop();
            },

            _ => {}
        }
    }

    fn visit_decl(&mut self, decl : &'a mut Decl){
        macro_rules! store_into_sym_tab {
            ($self_ : ident, $i : ident, $p : path) => {
                $self_.sym_tab.push(($i.clone(), Some(B($p($self_.ty.clone())))));
            }
        }
        match *decl{
            Decl::VarDec(ref id, ref ty, ref mut expr) => {
                self.visit_expr(expr);
                if *ty != self.ty{
                    panic!("Types mismatch")
                }
                store_into_sym_tab!(self, id, Binding::VarBinding);
            },
            Decl::FunDec(ref id, ref params, ref ret_type, ref body, ref body_type) => {
                if ret_type != body_type {
                    panic!("Return type doesn't match with the type of the last expression.")
                }

                if params.is_some() {
                    let mut map = HashMap::new();
                    for p in params.as_ref().unwrap(){
                        if map.contains_key(&p.0){
                            panic!(format!("Duplicate param '{0}' found", p.0));
                        }
                        map.insert(&p.0, true);
                    }
                }
                //self.visit_expr(&body);
                //if self.ty != *ret_type{
                store_into_sym_tab!(self, id, Binding::FuncBinding);
            },
            Decl::TypeDec(ref id, ref ty) => {
                store_into_sym_tab!(self, id, Binding::TypeBinding);
            }
        }
    }
}

#[test]
fn test_ty_set_for_num() {
    let mut v = TypeChecker::new();
    v.visit_expr(&mut Expr::NumExpr(23));
    assert_eq!(TType::TInt32, v.ty);
}

#[test]
fn test_ty_set_for_int_id() {
    let mut v = TypeChecker::new();
    v.sym_tab.push(("a".to_string(), Some(B(Binding::VarBinding(TType::TInt32)))));
    v.visit_expr(&mut Expr::IdExpr("a".to_string()));
    assert_eq!(TType::TInt32, v.ty);
}

#[test]
fn test_type_match_int_for_var_dec() {
    let mut v = TypeChecker::new();
    v.visit_decl(&mut Decl::VarDec("a".to_string(), TType::TInt32, B(Expr::NumExpr(4))));
    assert_eq!(TType::TInt32, v.ty);
    assert_eq!(v.sym_tab.len(), 1);
    assert_eq!(v.sym_tab[0].0, "a".to_string());
    //assert_eq!(v.sym_tab[0].1, TType::TInt32);
}

#[test]
fn test_type_match_string_for_var_dec() {
    let mut v = TypeChecker::new();
    v.visit_decl(&mut Decl::VarDec("a".to_string(), TType::TString, B(Expr::NilExpr)));
    assert_eq!(TType::TString, v.ty);
    assert_eq!(v.sym_tab.len(), 1);
    assert_eq!(v.sym_tab[0].0, "a".to_string());
    //assert_eq!(v.sym_tab[0].1, TType::TString);
}

#[test]
#[should_panic]
fn test_type_check_for_var_dec_type_mismatch() {
    let mut v = TypeChecker::new();
    v.visit_decl(&mut Decl::VarDec("a".to_string(), TType::TInt32, B(Expr::NilExpr)));
    assert_eq!(TType::TInt32, v.ty);
}

#[test]
fn test_correct_types_for_add_expr() {
    let mut v = TypeChecker::new();
    v.visit_expr(&mut Expr::AddExpr(B(Expr::NumExpr(4)), B(Expr::NumExpr(4))));
    assert_eq!(v.ty, TType::TInt32);
}

#[test]
#[should_panic(expected="Expected left operand of int type")]
fn test_left_type_invalid_for_add_expr() {
    let mut v = TypeChecker::new();
    v.visit_expr(&mut Expr::AddExpr(B(Expr::NilExpr), B(Expr::NumExpr(4))));
}

#[test]
#[should_panic(expected="Expected right operand of int type")]
fn test_right_type_invalid_for_add_expr() {
    let mut v = TypeChecker::new();
    v.visit_expr(&mut Expr::AddExpr(B(Expr::NumExpr(4)), B(Expr::NilExpr)));
}

#[test]
fn test_var_hiding() {
    //let mut v =
}

#[test]
fn test_func_decl_correct_return_type() {
    let mut v = TypeChecker::new();
    v.visit_decl(&mut Decl::FunDec(String::from("foo"), None, TType::TInt32, B(Expr::NumExpr(4)), TType::TInt32));
}

#[test]
#[should_panic(expected="Return type doesn't match with the type of the last expression.")]
fn test_func_decl_incorrect_return_type() {
    let mut v = TypeChecker::new();
    v.visit_decl(&mut Decl::FunDec(String::from("foo"), None, TType::TString, B(Expr::NumExpr(4)), TType::TInt32));
}

#[test]
#[should_panic(expected="Expected conditional expression of int type")]
fn test_if_expr_with_incorrect_conditional_type() {
    let mut v = TypeChecker::new();
    v.visit_expr(&mut Expr::IfThenExpr(B(Expr::StringExpr(String::from("a"))), B(Expr::StringExpr(String::from("a")))));
}

#[test]
fn test_if_expr_with_int_type() {
    let mut v = TypeChecker::new();
    v.visit_expr(&mut Expr::IfThenExpr(B(Expr::NumExpr(1)), B(Expr::SeqExpr(None))));
    assert_eq!(v.ty, TType::TVoid);
}

#[test]
#[should_panic(expected="Expected if-body of void type")]
fn test_if_expr_with_int_type_conditional_and_int_type_as_body_type() {
    let mut v = TypeChecker::new();
    v.visit_expr(&mut Expr::IfThenExpr(B(Expr::NumExpr(1)), B(Expr::NumExpr(1))));
    assert_eq!(v.ty, TType::TInt32);
}

#[test]
fn test_if_else_expr_with_matching_types() {
    let mut v = TypeChecker::new();
    v.visit_expr(&mut Expr::IfThenElseExpr(B(Expr::NumExpr(1)), B(Expr::NumExpr(1)), B(Expr::NumExpr(1))));
    assert_eq!(v.ty, TType::TInt32);
}

#[test]
#[should_panic(expected="Expected then expr and else expr types to be same")]
fn test_if_else_expr_with_non_matching_types() {
    let mut v = TypeChecker::new();
    v.visit_expr(&mut Expr::IfThenElseExpr(B(Expr::NumExpr(1)), B(Expr::NumExpr(1)), B(Expr::StringExpr(String::from("a")))));
}

#[test]
#[should_panic(expected="Expected conditional expression of int type")]
fn test_while_expr_with_incorrect_conditional_type() {
    let mut v = TypeChecker::new();
    v.visit_expr(&mut Expr::WhileExpr(B(Expr::StringExpr(String::from("a"))), B(Expr::StringExpr(String::from("a")))));
}

#[test]
#[should_panic(expected="Expected while-body of void type")]
fn test_while_expr_with_int_type() {
    let mut v = TypeChecker::new();
    v.visit_expr(&mut Expr::WhileExpr(B(Expr::NumExpr(1)), B(Expr::StringExpr(String::from("a")))));
}

#[test]
#[should_panic(expected="Denominator cannot be 0")]
fn test_div_expr_with_0_as_denominator(){
    let mut v = TypeChecker::new();
    v.visit_expr(&mut Expr::DivExpr(B(Expr::NumExpr(1)), B(Expr::NumExpr(0))));
}

#[test]
fn test_div_expr_with_1_as_denominator(){
    let mut v = TypeChecker::new();
    v.visit_expr(&mut Expr::DivExpr(B(Expr::NumExpr(1)), B(Expr::NumExpr(1))));
    assert_eq!(v.ty, TType::TInt32);
}

#[test]
#[should_panic(expected="Initializing expression type should be int in a for loop")]
fn test_for_loop_expr_init_type(){
    let mut v = TypeChecker::new();
    v.visit_expr(&mut Expr::ForExpr(String::from("i"),
                                B(Expr::StringExpr(String::from("adsd"))),
                                B(Expr::NumExpr(1)),
                                B(Expr::NumExpr(2))));
}

#[test]
#[should_panic(expected="Duplicate param 'a' found")]
fn test_func_dec_with_duplicate_param_with_same_type(){
    let mut v = TypeChecker::new();
    v.visit_decl(&mut Decl::FunDec(String::from("foo"),
                               Some(vec![(String::from("a"), TType::TInt32),
                                         (String::from("a"), TType::TInt32) ]),
                               TType::TInt32,
                               B(Expr::NumExpr(4)),
                               TType::TInt32));
}

#[test]
#[should_panic(expected="Duplicate param 'a' found")]
fn test_func_dec_with_duplicate_param_with_different_types(){
    let mut v = TypeChecker::new();
    v.visit_decl(&mut Decl::FunDec(String::from("foo"),
                               Some(vec![(String::from("a"), TType::TInt32),
                                         (String::from("a"), TType::TString) ]),
                               TType::TInt32,
                               B(Expr::NumExpr(4)),
                               TType::TInt32));
}
<|endoftext|>


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

/// Get the next instruction
// TODO: Should this be an iterator instead?
pub fn next_inst(editor: &mut Editor) -> Inst {
    let mut n = 0;
    let mut shifted = false;

    // TODO: Make the switch to normal mode shift more well-coded.
    loop {
        if let EventOption::Key(k) = editor.window.poll().unwrap_or(Event::new()).to_option() {
            let c = k.character;
            match c {
                '\0' => {
                    return Inst(0, match k.scancode {
                        K_ALT => Key::Alt(k.pressed),
                        K_CTRL => Key::Ctrl(k.pressed),
                        K_BKSP => Key::Backspace,
                        K_LEFT => Key::Left,
                        K_RIGHT => Key::Right,
                        K_UP => Key::Up,
                        K_DOWN => Key::Down,
                        K_TAB => Key::Tab,
                        K_ESC => Key::Escape,
                        K_LEFT_SHIFT | K_RIGHT_SHIFT => Key::Shift(k.pressed),
                        s => Key::Unknown(s),
                    })
                }
                _ => if k.pressed {
                    match editor.cursor().mode {
                        Mode::Primitive(_) => {
                            return Inst(0, Key::Char(c));
                        },
                        Mode::Command(_) => {
                            n = match c {
                                '0' if n != 0 => n * 10,
                                '1'           => n * 10 + 1,
                                '2'           => n * 10 + 2,
                                '3'           => n * 10 + 3,
                                '4'           => n * 10 + 4,
                                '5'           => n * 10 + 5,
                                '6'           => n * 10 + 6,
                                '7'           => n * 10 + 7,
                                '8'           => n * 10 + 8,
                                '9'           => n * 10 + 9,
                                _             => {

                                    return Inst(if n == 0 { 1 } else { n }, Key::Char(c));
                                }
                            }
                        }
                    }

                },
            }
        }
    }

    unreachable!()
}
<commit_msg>:tada: fix annoying event bug<commit_after>use super::*;
use redox::*;

/// Get the next instruction
// TODO: Should this be an iterator instead?
pub fn next_inst(editor: &mut Editor) -> Inst {
    let mut n = 0;
    let mut shifted = false;

    // TODO: Make the switch to normal mode shift more well-coded.
    loop {
        if let EventOption::Key(k) = editor.window.poll().unwrap_or(Event::new()).to_option() {
            let c = k.character;
            match c {
                '\0' => {
                    return Inst(0, match k.scancode {
                        K_ALT => Key::Alt(k.pressed),
                        K_CTRL => Key::Ctrl(k.pressed),
                        K_LEFT_SHIFT | K_RIGHT_SHIFT => Key::Shift(k.pressed),
                        s if k.pressed => match s {
                            K_BKSP => Key::Backspace,
                            K_LEFT => Key::Left,
                            K_RIGHT => Key::Right,
                            K_UP => Key::Up,
                            K_DOWN => Key::Down,
                            K_TAB => Key::Tab,
                            K_ESC => Key::Escape,
                            _ => Key::Unknown(s),
                        },
                        s => Key::Unknown(s),
                    })
                }
                _ => if k.pressed {
                    match editor.cursor().mode {
                        Mode::Primitive(_) => {
                            return Inst(0, Key::Char(c));
                        },
                        Mode::Command(_) => {
                            n = match c {
                                '0' if n != 0 => n * 10,
                                '1'           => n * 10 + 1,
                                '2'           => n * 10 + 2,
                                '3'           => n * 10 + 3,
                                '4'           => n * 10 + 4,
                                '5'           => n * 10 + 5,
                                '6'           => n * 10 + 6,
                                '7'           => n * 10 + 7,
                                '8'           => n * 10 + 8,
                                '9'           => n * 10 + 9,
                                _             => {

                                    return Inst(if n == 0 { 1 } else { n }, Key::Char(c));
                                }
                            }
                        }
                    }

                },
            }
        }
    }

    unreachable!()
}
<|endoftext|>


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

use std::mem::size_of;

struct t {a: u8, b: i8}
struct u {a: u8, b: i8, c: u8}
struct v {a: u8, b: i8, c: v2, d: u32}
struct v2 {u: char, v: u8}
struct w {a: int, b: ()}
struct x {a: int, b: (), c: ()}
struct y {x: int}

enum e1 {
    a(u8, u32), b(u32), c
}
enum e2 {
    a(u32), b
}

enum e3 {
    a([u64, ..0], u32), b
}

pub fn main() {
    assert_eq!(size_of::<u8>(), 1 as uint);
    assert_eq!(size_of::<u32>(), 4 as uint);
    assert_eq!(size_of::<char>(), 4 as uint);
    assert_eq!(size_of::<i8>(), 1 as uint);
    assert_eq!(size_of::<i32>(), 4 as uint);
    assert_eq!(size_of::<t>(), 2 as uint);
    assert_eq!(size_of::<u>(), 3 as uint);
    // Alignment causes padding before the char and the u32.

    assert!(size_of::<v>() ==
                16 as uint);
    assert_eq!(size_of::<int>(), size_of::<uint>());
    assert_eq!(size_of::<w>(), size_of::<int>());
    assert_eq!(size_of::<x>(), size_of::<int>());
    assert_eq!(size_of::<int>(), size_of::<y>());

    // Make sure enum types are the appropriate size, mostly
    // around ensuring alignment is handled properly

    assert_eq!(size_of::<e1>(), 8 as uint);
    assert_eq!(size_of::<e2>(), 8 as uint);
    assert_eq!(size_of::<e3>(), 16 as uint);
}
<commit_msg>Make alignment-forcing case work the same on 64 and 32-bit platforms<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::mem::size_of;

struct t {a: u8, b: i8}
struct u {a: u8, b: i8, c: u8}
struct v {a: u8, b: i8, c: v2, d: u32}
struct v2 {u: char, v: u8}
struct w {a: int, b: ()}
struct x {a: int, b: (), c: ()}
struct y {x: int}

enum e1 {
    a(u8, u32), b(u32), c
}
enum e2 {
    a(u32), b
}

enum e3 {
    a([u16, ..0], u8), b
}

pub fn main() {
    assert_eq!(size_of::<u8>(), 1 as uint);
    assert_eq!(size_of::<u32>(), 4 as uint);
    assert_eq!(size_of::<char>(), 4 as uint);
    assert_eq!(size_of::<i8>(), 1 as uint);
    assert_eq!(size_of::<i32>(), 4 as uint);
    assert_eq!(size_of::<t>(), 2 as uint);
    assert_eq!(size_of::<u>(), 3 as uint);
    // Alignment causes padding before the char and the u32.

    assert!(size_of::<v>() ==
                16 as uint);
    assert_eq!(size_of::<int>(), size_of::<uint>());
    assert_eq!(size_of::<w>(), size_of::<int>());
    assert_eq!(size_of::<x>(), size_of::<int>());
    assert_eq!(size_of::<int>(), size_of::<y>());

    // Make sure enum types are the appropriate size, mostly
    // around ensuring alignment is handled properly

    assert_eq!(size_of::<e1>(), 8 as uint);
    assert_eq!(size_of::<e2>(), 8 as uint);
    assert_eq!(size_of::<e3>(), 4 as uint);
}
<|endoftext|>


<commit_before>use crate::{
    frame::AMQPFrame,
    protocol::{
        *,
        basic::gen_properties,
    },
    types::{
        *,
        generation::*,
    },
};

use cookie_factory::slice;

/// Serialize a frame in the given buffer
pub fn gen_frame<'a>(x: &'a mut [u8], frame: &'a AMQPFrame) -> GenResult<'a> {
    frame.check_gen_size(x)?;
    match frame {
        AMQPFrame::ProtocolHeader => {
            gen_protocol_header(x)
        },
        AMQPFrame::Heartbeat(_) => {
            gen_heartbeat_frame(x)
        },
        AMQPFrame::Method(channel_id, method) => {
            gen_method_frame(x, *channel_id, method)
        },
        AMQPFrame::Header(channel_id, class_id, header) => {
            gen_content_header_frame(x, *channel_id, *class_id, header.body_size, &header.properties)
        },
        AMQPFrame::Body(channel_id, data) => {
            gen_content_body_frame(x, *channel_id, data)
        }
    }
}

fn gen_protocol_header(x: &mut [u8]) -> GenResult<'_> {
    slice(&[0, metadata::MAJOR_VERSION, metadata::MINOR_VERSION, metadata::REVISION])(slice(metadata::NAME.as_bytes())(x)?)
}

fn gen_heartbeat_frame(x: &mut [u8]) -> GenResult<'_> {
    slice(&[constants::FRAME_HEARTBEAT, 0, 0, 0, 0, 0, 0, constants::FRAME_END])(x)
}

fn gen_method_frame<'a>(x: &'a mut [u8], channel_id: ShortUInt, class: &'a AMQPClass) -> GenResult<'a> {
    gen_short_short_uint(gen_with_len(gen_id(gen_short_short_uint(x, constants::FRAME_METHOD)?, channel_id)?, move |x| gen_class(x, class))?, constants::FRAME_END)
}

fn gen_content_header_frame<'a>(x: &'a mut [u8], channel_id: ShortUInt, class_id: ShortUInt, length: LongLongUInt, properties: &'a basic::AMQPProperties) -> GenResult<'a> {
    gen_short_short_uint(gen_with_len(gen_id(gen_short_short_uint(x, constants::FRAME_HEADER)?, channel_id)?, move |x| gen_properties(gen_long_long_uint(gen_short_uint(gen_id(x, class_id)?, 0 /* weight */)?, length)?, &properties))?, constants::FRAME_END)
}

fn gen_content_body_frame<'a>(x: &'a mut [u8], channel_id: ShortUInt, content: &'a [u8]) -> GenResult<'a> {
    gen_short_short_uint(slice(content)(gen_long_uint(gen_id(gen_short_short_uint(x, constants::FRAME_BODY)?, channel_id)?, content.len() as LongUInt)?)?, constants::FRAME_END)
}
<commit_msg>protocol: make gen_frame return the written length<commit_after>use crate::{
    frame::AMQPFrame,
    protocol::{
        *,
        basic::gen_properties,
    },
    types::{
        *,
        generation::*,
    },
};

use cookie_factory::{length, slice};

/// Serialize a frame in the given buffer
pub fn gen_frame<'a>(x: &'a mut [u8], frame: &'a AMQPFrame) -> Result<(usize, &'a mut [u8]), GenError> {
    frame.check_gen_size(x)?;
    length(move |x| match frame {
        AMQPFrame::ProtocolHeader => {
            gen_protocol_header(x)
        },
        AMQPFrame::Heartbeat(_) => {
            gen_heartbeat_frame(x)
        },
        AMQPFrame::Method(channel_id, method) => {
            gen_method_frame(x, *channel_id, method)
        },
        AMQPFrame::Header(channel_id, class_id, header) => {
            gen_content_header_frame(x, *channel_id, *class_id, header.body_size, &header.properties)
        },
        AMQPFrame::Body(channel_id, data) => {
            gen_content_body_frame(x, *channel_id, data)
        }
    })(x)
}

fn gen_protocol_header(x: &mut [u8]) -> GenResult<'_> {
    slice(&[0, metadata::MAJOR_VERSION, metadata::MINOR_VERSION, metadata::REVISION])(slice(metadata::NAME.as_bytes())(x)?)
}

fn gen_heartbeat_frame(x: &mut [u8]) -> GenResult<'_> {
    slice(&[constants::FRAME_HEARTBEAT, 0, 0, 0, 0, 0, 0, constants::FRAME_END])(x)
}

fn gen_method_frame<'a>(x: &'a mut [u8], channel_id: ShortUInt, class: &'a AMQPClass) -> GenResult<'a> {
    gen_short_short_uint(gen_with_len(gen_id(gen_short_short_uint(x, constants::FRAME_METHOD)?, channel_id)?, move |x| gen_class(x, class))?, constants::FRAME_END)
}

fn gen_content_header_frame<'a>(x: &'a mut [u8], channel_id: ShortUInt, class_id: ShortUInt, length: LongLongUInt, properties: &'a basic::AMQPProperties) -> GenResult<'a> {
    gen_short_short_uint(gen_with_len(gen_id(gen_short_short_uint(x, constants::FRAME_HEADER)?, channel_id)?, move |x| gen_properties(gen_long_long_uint(gen_short_uint(gen_id(x, class_id)?, 0 /* weight */)?, length)?, &properties))?, constants::FRAME_END)
}

fn gen_content_body_frame<'a>(x: &'a mut [u8], channel_id: ShortUInt, content: &'a [u8]) -> GenResult<'a> {
    gen_short_short_uint(slice(content)(gen_long_uint(gen_id(gen_short_short_uint(x, constants::FRAME_BODY)?, channel_id)?, content.len() as LongUInt)?)?, constants::FRAME_END)
}
<|endoftext|>


<commit_before>#![cfg(feature = "serde")]

extern crate serde;
use self::serde::de::{
    Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error, Unexpected, VariantAccess,
    Visitor,
};
use self::serde::ser::{Serialize, Serializer};

use {Level, LevelFilter, LOG_LEVEL_NAMES};

use std::fmt;
use std::str::{self, FromStr};

// The Deserialize impls are handwritten to be case insensitive using FromStr.

impl Serialize for Level {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        match *self {
            Level::Error => serializer.serialize_unit_variant("Level", 0, "ERROR"),
            Level::Warn => serializer.serialize_unit_variant("Level", 1, "WARN"),
            Level::Info => serializer.serialize_unit_variant("Level", 2, "INFO"),
            Level::Debug => serializer.serialize_unit_variant("Level", 3, "DEBUG"),
            Level::Trace => serializer.serialize_unit_variant("Level", 4, "TRACE"),
        }
    }
}

impl<'de> Deserialize<'de> for Level {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct LevelIdentifier;

        impl<'de> Visitor<'de> for LevelIdentifier {
            type Value = Level;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("log level")
            }

            fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
            where
                E: Error,
            {
                // Case insensitive.
                FromStr::from_str(s).map_err(|_| Error::unknown_variant(s, &LOG_LEVEL_NAMES[1..]))
            }

            fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
            where
                E: Error,
            {
                let variant = str::from_utf8(value)
                    .map_err(|_| Error::invalid_value(Unexpected::Bytes(value), &self))?;

                self.visit_str(variant)
            }
        }

        impl<'de> DeserializeSeed<'de> for LevelIdentifier {
            type Value = Level;

            fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
            where
                D: Deserializer<'de>,
            {
                deserializer.deserialize_identifier(LevelIdentifier)
            }
        }

        struct LevelEnum;

        impl<'de> Visitor<'de> for LevelEnum {
            type Value = Level;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("log level")
            }

            fn visit_enum<A>(self, value: A) -> Result<Self::Value, A::Error>
            where
                A: EnumAccess<'de>,
            {
                let (level, variant) = value.variant_seed(LevelIdentifier)?;
                // Every variant is a unit variant.
                variant.unit_variant()?;
                Ok(level)
            }
        }

        deserializer.deserialize_enum("Level", &LOG_LEVEL_NAMES[1..], LevelEnum)
    }
}

impl Serialize for LevelFilter {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        match *self {
            LevelFilter::Off => serializer.serialize_unit_variant("LevelFilter", 0, "OFF"),
            LevelFilter::Error => serializer.serialize_unit_variant("LevelFilter", 1, "ERROR"),
            LevelFilter::Warn => serializer.serialize_unit_variant("LevelFilter", 2, "WARN"),
            LevelFilter::Info => serializer.serialize_unit_variant("LevelFilter", 3, "INFO"),
            LevelFilter::Debug => serializer.serialize_unit_variant("LevelFilter", 4, "DEBUG"),
            LevelFilter::Trace => serializer.serialize_unit_variant("LevelFilter", 5, "TRACE"),
        }
    }
}

impl<'de> Deserialize<'de> for LevelFilter {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct LevelFilterIdentifier;

        impl<'de> Visitor<'de> for LevelFilterIdentifier {
            type Value = LevelFilter;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("log level filter")
            }

            fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
            where
                E: Error,
            {
                // Case insensitive.
                FromStr::from_str(s).map_err(|_| Error::unknown_variant(s, &LOG_LEVEL_NAMES))
            }

            fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
            where
                E: Error,
            {
                let variant = str::from_utf8(value)
                    .map_err(|_| Error::invalid_value(Unexpected::Bytes(value), &self))?;

                self.visit_str(variant)
            }
        }

        impl<'de> DeserializeSeed<'de> for LevelFilterIdentifier {
            type Value = LevelFilter;

            fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
            where
                D: Deserializer<'de>,
            {
                deserializer.deserialize_identifier(LevelFilterIdentifier)
            }
        }

        struct LevelFilterEnum;

        impl<'de> Visitor<'de> for LevelFilterEnum {
            type Value = LevelFilter;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("log level filter")
            }

            fn visit_enum<A>(self, value: A) -> Result<Self::Value, A::Error>
            where
                A: EnumAccess<'de>,
            {
                let (level_filter, variant) = value.variant_seed(LevelFilterIdentifier)?;
                // Every variant is a unit variant.
                variant.unit_variant()?;
                Ok(level_filter)
            }
        }

        deserializer.deserialize_enum("LevelFilter", &LOG_LEVEL_NAMES, LevelFilterEnum)
    }
}

#[cfg(test)]
mod tests {
    extern crate serde_test;
    use self::serde_test::{assert_de_tokens, assert_de_tokens_error, assert_tokens, Token};

    use {Level, LevelFilter};

    fn level_token(variant: &'static str) -> Token {
        Token::UnitVariant {
            name: "Level",
            variant: variant,
        }
    }

    fn level_bytes_tokens(variant: &'static [u8]) -> [Token; 3] {
        [
            Token::Enum { name: "Level" },
            Token::Bytes(variant),
            Token::Unit,
        ]
    }

    fn level_filter_token(variant: &'static str) -> Token {
        Token::UnitVariant {
            name: "LevelFilter",
            variant: variant,
        }
    }

    fn level_filter_bytes_tokens(variant: &'static [u8]) -> [Token; 3] {
        [
            Token::Enum {
                name: "LevelFilter",
            },
            Token::Bytes(variant),
            Token::Unit,
        ]
    }

    #[test]
    fn test_level_ser_de() {
        let cases = [
            (Level::Error, [level_token("ERROR")]),
            (Level::Warn, [level_token("WARN")]),
            (Level::Info, [level_token("INFO")]),
            (Level::Debug, [level_token("DEBUG")]),
            (Level::Trace, [level_token("TRACE")]),
        ];

        for &(s, expected) in &cases {
            assert_tokens(&s, &expected);
        }
    }

    #[test]
    fn test_level_case_insensitive() {
        let cases = [
            (Level::Error, [level_token("error")]),
            (Level::Warn, [level_token("warn")]),
            (Level::Info, [level_token("info")]),
            (Level::Debug, [level_token("debug")]),
            (Level::Trace, [level_token("trace")]),
        ];

        for &(s, expected) in &cases {
            assert_de_tokens(&s, &expected);
        }
    }

    #[test]
    fn test_level_de_bytes() {
        let cases = [
            (Level::Error, level_bytes_tokens(b"ERROR")),
            (Level::Warn, level_bytes_tokens(b"WARN")),
            (Level::Info, level_bytes_tokens(b"INFO")),
            (Level::Debug, level_bytes_tokens(b"DEBUG")),
            (Level::Trace, level_bytes_tokens(b"TRACE")),
        ];

        for &(value, tokens) in &cases {
            assert_de_tokens(&value, &tokens);
        }
    }

    #[test]
    fn test_level_de_error() {
        let msg = "unknown variant `errorx`, expected one of \
                   `ERROR`, `WARN`, `INFO`, `DEBUG`, `TRACE`";
        assert_de_tokens_error::<Level>(&[level_token("errorx")], msg);
    }

    #[test]
    fn test_level_filter_ser_de() {
        let cases = [
            (LevelFilter::Off, [level_filter_token("OFF")]),
            (LevelFilter::Error, [level_filter_token("ERROR")]),
            (LevelFilter::Warn, [level_filter_token("WARN")]),
            (LevelFilter::Info, [level_filter_token("INFO")]),
            (LevelFilter::Debug, [level_filter_token("DEBUG")]),
            (LevelFilter::Trace, [level_filter_token("TRACE")]),
        ];

        for &(s, expected) in &cases {
            assert_tokens(&s, &expected);
        }
    }

    #[test]
    fn test_level_filter_case_insensitive() {
        let cases = [
            (LevelFilter::Off, [level_filter_token("off")]),
            (LevelFilter::Error, [level_filter_token("error")]),
            (LevelFilter::Warn, [level_filter_token("warn")]),
            (LevelFilter::Info, [level_filter_token("info")]),
            (LevelFilter::Debug, [level_filter_token("debug")]),
            (LevelFilter::Trace, [level_filter_token("trace")]),
        ];

        for &(s, expected) in &cases {
            assert_de_tokens(&s, &expected);
        }
    }

    #[test]
    fn test_level_filter_de_bytes() {
        let cases = [
            (LevelFilter::Off, level_filter_bytes_tokens(b"OFF")),
            (LevelFilter::Error, level_filter_bytes_tokens(b"ERROR")),
            (LevelFilter::Warn, level_filter_bytes_tokens(b"WARN")),
            (LevelFilter::Info, level_filter_bytes_tokens(b"INFO")),
            (LevelFilter::Debug, level_filter_bytes_tokens(b"DEBUG")),
            (LevelFilter::Trace, level_filter_bytes_tokens(b"TRACE")),
        ];

        for &(value, tokens) in &cases {
            assert_de_tokens(&value, &tokens);
        }
    }

    #[test]
    fn test_level_filter_de_error() {
        let msg = "unknown variant `errorx`, expected one of \
                   `OFF`, `ERROR`, `WARN`, `INFO`, `DEBUG`, `TRACE`";
        assert_de_tokens_error::<LevelFilter>(&[level_filter_token("errorx")], msg);
    }
}
<commit_msg>Added deserialization from index.<commit_after>#![cfg(feature = "serde")]

extern crate serde;
use self::serde::de::{
    Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error, Unexpected, VariantAccess,
    Visitor,
};
use self::serde::ser::{Serialize, Serializer};

use {Level, LevelFilter, LOG_LEVEL_NAMES};

use std::fmt;
use std::str::{self, FromStr};

// The Deserialize impls are handwritten to be case insensitive using FromStr.

impl Serialize for Level {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        match *self {
            Level::Error => serializer.serialize_unit_variant("Level", 0, "ERROR"),
            Level::Warn => serializer.serialize_unit_variant("Level", 1, "WARN"),
            Level::Info => serializer.serialize_unit_variant("Level", 2, "INFO"),
            Level::Debug => serializer.serialize_unit_variant("Level", 3, "DEBUG"),
            Level::Trace => serializer.serialize_unit_variant("Level", 4, "TRACE"),
        }
    }
}

impl<'de> Deserialize<'de> for Level {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct LevelIdentifier;

        impl<'de> Visitor<'de> for LevelIdentifier {
            type Value = Level;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("log level")
            }

            fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
            where
                E: Error,
            {
                // Case insensitive.
                FromStr::from_str(s).map_err(|_| Error::unknown_variant(s, &LOG_LEVEL_NAMES[1..]))
            }

            fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
            where
                E: Error,
            {
                let variant = str::from_utf8(value)
                    .map_err(|_| Error::invalid_value(Unexpected::Bytes(value), &self))?;

                self.visit_str(variant)
            }

            fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
            where
                E: Error,
            {
                let variant: &str = LOG_LEVEL_NAMES[1..]
                    .get(v as usize)
                    .ok_or_else(|| Error::invalid_value(Unexpected::Unsigned(v), &self))?;

                self.visit_str(variant)
            }
        }

        impl<'de> DeserializeSeed<'de> for LevelIdentifier {
            type Value = Level;

            fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
            where
                D: Deserializer<'de>,
            {
                deserializer.deserialize_identifier(LevelIdentifier)
            }
        }

        struct LevelEnum;

        impl<'de> Visitor<'de> for LevelEnum {
            type Value = Level;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("log level")
            }

            fn visit_enum<A>(self, value: A) -> Result<Self::Value, A::Error>
            where
                A: EnumAccess<'de>,
            {
                let (level, variant) = value.variant_seed(LevelIdentifier)?;
                // Every variant is a unit variant.
                variant.unit_variant()?;
                Ok(level)
            }
        }

        deserializer.deserialize_enum("Level", &LOG_LEVEL_NAMES[1..], LevelEnum)
    }
}

impl Serialize for LevelFilter {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        match *self {
            LevelFilter::Off => serializer.serialize_unit_variant("LevelFilter", 0, "OFF"),
            LevelFilter::Error => serializer.serialize_unit_variant("LevelFilter", 1, "ERROR"),
            LevelFilter::Warn => serializer.serialize_unit_variant("LevelFilter", 2, "WARN"),
            LevelFilter::Info => serializer.serialize_unit_variant("LevelFilter", 3, "INFO"),
            LevelFilter::Debug => serializer.serialize_unit_variant("LevelFilter", 4, "DEBUG"),
            LevelFilter::Trace => serializer.serialize_unit_variant("LevelFilter", 5, "TRACE"),
        }
    }
}

impl<'de> Deserialize<'de> for LevelFilter {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct LevelFilterIdentifier;

        impl<'de> Visitor<'de> for LevelFilterIdentifier {
            type Value = LevelFilter;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("log level filter")
            }

            fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
            where
                E: Error,
            {
                // Case insensitive.
                FromStr::from_str(s).map_err(|_| Error::unknown_variant(s, &LOG_LEVEL_NAMES))
            }

            fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
            where
                E: Error,
            {
                let variant = str::from_utf8(value)
                    .map_err(|_| Error::invalid_value(Unexpected::Bytes(value), &self))?;

                self.visit_str(variant)
            }

            fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
            where
                E: Error,
            {
                let variant: &str = LOG_LEVEL_NAMES
                    .get(v as usize)
                    .ok_or_else(|| Error::invalid_value(Unexpected::Unsigned(v), &self))?;

                self.visit_str(variant)
            }
        }

        impl<'de> DeserializeSeed<'de> for LevelFilterIdentifier {
            type Value = LevelFilter;

            fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
            where
                D: Deserializer<'de>,
            {
                deserializer.deserialize_identifier(LevelFilterIdentifier)
            }
        }

        struct LevelFilterEnum;

        impl<'de> Visitor<'de> for LevelFilterEnum {
            type Value = LevelFilter;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("log level filter")
            }

            fn visit_enum<A>(self, value: A) -> Result<Self::Value, A::Error>
            where
                A: EnumAccess<'de>,
            {
                let (level_filter, variant) = value.variant_seed(LevelFilterIdentifier)?;
                // Every variant is a unit variant.
                variant.unit_variant()?;
                Ok(level_filter)
            }
        }

        deserializer.deserialize_enum("LevelFilter", &LOG_LEVEL_NAMES, LevelFilterEnum)
    }
}

#[cfg(test)]
mod tests {
    extern crate serde_test;
    use self::serde_test::{assert_de_tokens, assert_de_tokens_error, assert_tokens, Token};

    use {Level, LevelFilter};

    fn level_token(variant: &'static str) -> Token {
        Token::UnitVariant {
            name: "Level",
            variant: variant,
        }
    }

    fn level_bytes_tokens(variant: &'static [u8]) -> [Token; 3] {
        [
            Token::Enum { name: "Level" },
            Token::Bytes(variant),
            Token::Unit,
        ]
    }

    fn level_filter_token(variant: &'static str) -> Token {
        Token::UnitVariant {
            name: "LevelFilter",
            variant: variant,
        }
    }

    fn level_filter_bytes_tokens(variant: &'static [u8]) -> [Token; 3] {
        [
            Token::Enum {
                name: "LevelFilter",
            },
            Token::Bytes(variant),
            Token::Unit,
        ]
    }

    #[test]
    fn test_level_ser_de() {
        let cases = [
            (Level::Error, [level_token("ERROR")]),
            (Level::Warn, [level_token("WARN")]),
            (Level::Info, [level_token("INFO")]),
            (Level::Debug, [level_token("DEBUG")]),
            (Level::Trace, [level_token("TRACE")]),
        ];

        for &(s, expected) in &cases {
            assert_tokens(&s, &expected);
        }
    }

    #[test]
    fn test_level_case_insensitive() {
        let cases = [
            (Level::Error, [level_token("error")]),
            (Level::Warn, [level_token("warn")]),
            (Level::Info, [level_token("info")]),
            (Level::Debug, [level_token("debug")]),
            (Level::Trace, [level_token("trace")]),
        ];

        for &(s, expected) in &cases {
            assert_de_tokens(&s, &expected);
        }
    }

    #[test]
    fn test_level_de_bytes() {
        let cases = [
            (Level::Error, level_bytes_tokens(b"ERROR")),
            (Level::Warn, level_bytes_tokens(b"WARN")),
            (Level::Info, level_bytes_tokens(b"INFO")),
            (Level::Debug, level_bytes_tokens(b"DEBUG")),
            (Level::Trace, level_bytes_tokens(b"TRACE")),
        ];

        for &(value, tokens) in &cases {
            assert_de_tokens(&value, &tokens);
        }
    }

    #[test]
    fn test_level_de_error() {
        let msg = "unknown variant `errorx`, expected one of \
                   `ERROR`, `WARN`, `INFO`, `DEBUG`, `TRACE`";
        assert_de_tokens_error::<Level>(&[level_token("errorx")], msg);
    }

    #[test]
    fn test_level_filter_ser_de() {
        let cases = [
            (LevelFilter::Off, [level_filter_token("OFF")]),
            (LevelFilter::Error, [level_filter_token("ERROR")]),
            (LevelFilter::Warn, [level_filter_token("WARN")]),
            (LevelFilter::Info, [level_filter_token("INFO")]),
            (LevelFilter::Debug, [level_filter_token("DEBUG")]),
            (LevelFilter::Trace, [level_filter_token("TRACE")]),
        ];

        for &(s, expected) in &cases {
            assert_tokens(&s, &expected);
        }
    }

    #[test]
    fn test_level_filter_case_insensitive() {
        let cases = [
            (LevelFilter::Off, [level_filter_token("off")]),
            (LevelFilter::Error, [level_filter_token("error")]),
            (LevelFilter::Warn, [level_filter_token("warn")]),
            (LevelFilter::Info, [level_filter_token("info")]),
            (LevelFilter::Debug, [level_filter_token("debug")]),
            (LevelFilter::Trace, [level_filter_token("trace")]),
        ];

        for &(s, expected) in &cases {
            assert_de_tokens(&s, &expected);
        }
    }

    #[test]
    fn test_level_filter_de_bytes() {
        let cases = [
            (LevelFilter::Off, level_filter_bytes_tokens(b"OFF")),
            (LevelFilter::Error, level_filter_bytes_tokens(b"ERROR")),
            (LevelFilter::Warn, level_filter_bytes_tokens(b"WARN")),
            (LevelFilter::Info, level_filter_bytes_tokens(b"INFO")),
            (LevelFilter::Debug, level_filter_bytes_tokens(b"DEBUG")),
            (LevelFilter::Trace, level_filter_bytes_tokens(b"TRACE")),
        ];

        for &(value, tokens) in &cases {
            assert_de_tokens(&value, &tokens);
        }
    }

    #[test]
    fn test_level_filter_de_error() {
        let msg = "unknown variant `errorx`, expected one of \
                   `OFF`, `ERROR`, `WARN`, `INFO`, `DEBUG`, `TRACE`";
        assert_de_tokens_error::<LevelFilter>(&[level_filter_token("errorx")], msg);
    }
}
<|endoftext|>


<commit_before>use ForthResult;
use error::Error::UnknownWord;
use stack::Stack;
use std::rc::Rc;
use std::result::Result::{Ok, Err};
use word::Word;
use word::WordKind::{Builtin, Words};

#[deriving(Default)]
pub struct State {
    stack: Stack,
    dict: Vec<Rc<Word>>,
}

impl State {
    pub fn new() -> State {
        State {
            stack: Stack::new(),
            dict: Vec::new(),
        }
    }

    pub fn add_word(&mut self, word: Word) {
        self.dict.push(Rc::new(word));
    }

    pub fn run_word(&mut self, command: &str) -> ForthResult {
        let mut next = None;
        for word in self.dict.iter() {
            if command == word.command {
                next = Some(word.clone());
                break;
            }
        }
        match next {
            Some(word) => {
                match word.kind {
                    Builtin(ref f) => try!((*f)(&mut self.stack)),
                    Words(ref ws) => for w in ws.iter() {
                        try!(self.run_word(w.as_slice()))
                    },
                }
            },
            None => {
                match command.parse() {
                    Some(i) => self.stack.push(i),
                    None => return Err(UnknownWord),
                }
            },
        }
        Ok(())
    }

    pub fn parse_line(&mut self, line: &str) -> ForthResult {
        for token in line.split(' ') {
            try!(self.run_word(token.trim_right_chars('\n')));
        }
        debug!("stack={}", self.stack);
        Ok(())
    }
}
<commit_msg>Remove need for Rc pointer in State<commit_after>use ForthResult;
use error::Error::UnknownWord;
use stack::Stack;
use std::result::Result::{Ok, Err};
use word::Word;
use word::WordKind::{Builtin, Words};

#[deriving(Default)]
pub struct State {
    stack: Stack,
    dict: Vec<Word>,
}

impl State {
    pub fn new() -> State {
        State {
            stack: Stack::new(),
            dict: Vec::new(),
        }
    }

    pub fn add_word(&mut self, word: Word) {
        self.dict.push(word);
    }

    fn real_run_word(dict: &Vec<Word>, stack: &mut Stack,
                     command: &str) -> ForthResult {
        for word in dict.iter() {
            if command == word.command {
                match word.kind {
                    Builtin(ref f) => try!((*f)(stack)),
                    Words(ref ws) => for w in ws.iter() {
                        try!(State::real_run_word(dict, stack, w.as_slice()));
                    },
                }
                return Ok(());
            }
        }
        let i = try!(command.parse().ok_or(UnknownWord));
        stack.push(i);
        Ok(())
    }

    pub fn run_word(&mut self, command: &str) -> ForthResult {
        State::real_run_word(&self.dict, &mut self.stack, command)
    }

    pub fn parse_line(&mut self, line: &str) -> ForthResult {
        for token in line.split(' ') {
            try!(self.run_word(token.trim_right_chars('\n')));
        }
        debug!("stack={}", self.stack);
        Ok(())
    }
}
<|endoftext|>