<commit_before>//! ByteSize is an utility that easily makes bytes size representation
//! and helps its arithmetic operations.
//!
//! ## Example
//!
//! ```ignore
//! extern crate bytesize;
//!
//! use bytesize::ByteSize;
//!
//! fn byte_arithmetic_operator() {
//!   let x = ByteSize::mb(1);
//!   let y = ByteSize::kb(100);
//!
//!   let plus = x + y;
//!   print!("{} bytes", plus.as_u64());
//!
//!   let minus = ByteSize::tb(100) - ByteSize::gb(4);
//!   print!("{} bytes", minus.as_u64());
//! }
//! ```
//!
//! It also provides its human readable string as follows:
//!
//! ```ignore=
//!  assert_eq!("482 GiB".to_string(), ByteSize::gb(518).to_string(true));
//!  assert_eq!("518 GB".to_string(), ByteSize::gb(518).to_string(false));
//! ```

#[cfg(feature = "serde")]
#[macro_use]
extern crate serde;

use std::fmt::{Debug, Display, Formatter, Result};
use std::ops::{Add, AddAssign, Mul, MulAssign};

/// byte size for 1 byte
pub const B: u64 = 1;
/// bytes size for 1 kilobyte
pub const KB: u64 = 1_000;
/// bytes size for 1 megabyte
pub const MB: u64 = 1_000_000;
/// bytes size for 1 gigabyte
pub const GB: u64 = 1_000_000_000;
/// bytes size for 1 terabyte
pub const TB: u64 = 1_000_000_000_000;
/// bytes size for 1 petabyte
pub const PB: u64 = 1_000_000_000_000_000;

/// bytes size for 1 kibibyte
pub const KIB: u64 = 1_024;
/// bytes size for 1 mebibyte
pub const MIB: u64 = 1_048_576;
/// bytes size for 1 gibibyte
pub const GIB: u64 = 1_073_741_824;
/// bytes size for 1 tebibyte
pub const TIB: u64 = 1_099_511_627_776;
/// bytes size for 1 pebibyte
pub const PIB: u64 = 1_125_899_906_842_624;

static UNITS: &'static str = "KMGTPE";
static UNITS_SI: &'static str = "kMGTPE";
static LN_KB: f64 = 6.931471806; // ln 1024
static LN_KIB: f64 = 6.907755279; // ln 1000

pub fn kb<V: Into<u64>>(size: V) -> u64 {
    size.into() * KB
}

pub fn kib<V: Into<u64>>(size: V) -> u64 {
    size.into() * KIB
}

pub fn mb<V: Into<u64>>(size: V) -> u64 {
    size.into() * MB
}

pub fn mib<V: Into<u64>>(size: V) -> u64 {
    size.into() * MIB
}

pub fn gb<V: Into<u64>>(size: V) -> u64 {
    size.into() * GB
}

pub fn gib<V: Into<u64>>(size: V) -> u64 {
    size.into() * GIB
}

pub fn tb<V: Into<u64>>(size: V) -> u64 {
    size.into() * TB
}

pub fn tib<V: Into<u64>>(size: V) -> u64 {
    size.into() * TIB
}

pub fn pb<V: Into<u64>>(size: V) -> u64 {
    size.into() * PB
}

pub fn pib<V: Into<u64>>(size: V) -> u64 {
    size.into() * PIB
}

/// Byte size representation
#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ByteSize(pub u64);

impl ByteSize {
    #[inline(always)]
    pub const fn b(size: u64) -> ByteSize {
        ByteSize(size)
    }

    #[inline(always)]
    pub const fn kb(size: u64) -> ByteSize {
        ByteSize(size * KB)
    }

    #[inline(always)]
    pub const fn kib(size: u64) -> ByteSize {
        ByteSize(size * KIB)
    }

    #[inline(always)]
    pub const fn mb(size: u64) -> ByteSize {
        ByteSize(size * MB)
    }

    #[inline(always)]
    pub const fn mib(size: u64) -> ByteSize {
        ByteSize(size * MIB)
    }

    #[inline(always)]
    pub const fn gb(size: u64) -> ByteSize {
        ByteSize(size * GB)
    }

    #[inline(always)]
    pub const fn gib(size: u64) -> ByteSize {
        ByteSize(size * GIB)
    }

    #[inline(always)]
    pub const fn tb(size: u64) -> ByteSize {
        ByteSize(size * TB)
    }

    #[inline(always)]
    pub const fn tib(size: u64) -> ByteSize {
        ByteSize(size * TIB)
    }

    #[inline(always)]
    pub const fn pb(size: u64) -> ByteSize {
        ByteSize(size * PB)
    }

    #[inline(always)]
    pub const fn pib(size: u64) -> ByteSize {
        ByteSize(size * PIB)
    }

    #[inline(always)]
    pub fn as_u64(&self) -> u64 {
        self.0
    }

    #[inline(always)]
    pub fn to_string_as(&self, si_unit: bool) -> String {
        to_string(self.0, si_unit)
    }
}

pub fn to_string(bytes: u64, si_prefix: bool) -> String {
    let unit = if si_prefix { KIB } else { KB };
    let unit_base = if si_prefix { LN_KIB } else { LN_KB };
    let unit_prefix = if si_prefix {
        UNITS_SI.as_bytes()
    } else {
        UNITS.as_bytes()
    };
    let unit_suffix = if si_prefix { "iB" } else { "B" };

    if bytes < unit {
        format!("{} B", bytes)
    } else {
        let size = bytes as f64;
        let exp = match (size.ln() / unit_base) as usize {
            e if e == 0 => 1,
            e => e,
        };

        format!(
            "{:.1} {}{}",
            (size / unit.pow(exp as u32) as f64),
            unit_prefix[exp - 1] as char,
            unit_suffix
        )
    }
}

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

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

macro_rules! commutative_op {
    ($t:ty) => {
        impl Add<ByteSize> for $t {
            type Output = ByteSize;
            #[inline(always)]
            fn add(self, rhs: ByteSize) -> ByteSize {
                ByteSize(rhs.0 + (self as u64))
            }
        }

        impl Mul<ByteSize> for $t {
            type Output = ByteSize;
            #[inline(always)]
            fn mul(self, rhs: ByteSize) -> ByteSize {
                ByteSize(rhs.0 * (self as u64))
            }
        }
    };
}

commutative_op!(u64);
commutative_op!(u32);
commutative_op!(u16);
commutative_op!(u8);

impl Add<ByteSize> for ByteSize {
    type Output = ByteSize;

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

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

impl<T> Mul<T> for ByteSize
    where T: Into<u64> {
    type Output = ByteSize;
    #[inline(always)]
    fn mul(self, rhs: T) -> ByteSize {
        ByteSize(self.0 * (rhs.into() as u64))
    }
}

impl<T> MulAssign<T> for ByteSize
    where T: Into<u64> {
    #[inline(always)]
    fn mul_assign(&mut self, rhs: T) {
        self.0 *= rhs.into() as u64;
    }
}

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

    #[test]
    fn test_arithmetic_op() {
        let mut x = ByteSize::mb(1);
        let y = ByteSize::kb(100);

        assert_eq!((x + y).as_u64(), 1_100_000u64);

        assert_eq!((x + (100 * 1000) as u64).as_u64(), 1_100_000);

        assert_eq!((x * 2u64).as_u64(), 2_000_000);

        x += y;
        assert_eq!(x.as_u64(), 1_100_000);
        x *= 2u64;
        assert_eq!(x.as_u64(), 2_200_000);
    }

    #[test]
    fn test_arithmetic_primitives() {
        let mut x = ByteSize::mb(1);

        assert_eq!((x + MB as u64).as_u64(), 2_000_000);

        assert_eq!((x + MB as u32).as_u64(), 2_000_000);

        assert_eq!((x + KB as u16).as_u64(), 1_001_000);

        assert_eq!((x + B as u8).as_u64(), 1_000_001);

        x += MB as u64;
        x += MB as u32;
        x += 10 as u16;
        x += 1 as u8;
        assert_eq!(x.as_u64(), 3_000_011);
    }

    #[test]
    fn test_comparison() {
        assert!(ByteSize::mb(1) == ByteSize::kb(1000));
        assert!(ByteSize::mib(1) == ByteSize::kib(1024));
        assert!(ByteSize::mb(1) != ByteSize::kib(1024));
        assert!(ByteSize::mb(1) < ByteSize::kib(1024));
        assert!(ByteSize::b(0) < ByteSize::tib(1));
    }

    fn assert_display(expected: &str, b: ByteSize) {
        assert_eq!(expected, format!("{}", b));
    }

    #[test]
    fn test_display() {
        assert_display("215 B", ByteSize::b(215));
        assert_display("1.0 KB", ByteSize::kb(1));
        assert_display("301.0 KB", ByteSize::kb(301));
        assert_display("419.0 MB", ByteSize::mb(419));
        assert_display("518.0 GB", ByteSize::gb(518));
        assert_display("815.0 TB", ByteSize::tb(815));
        assert_display("609.0 PB", ByteSize::pb(609));
    }

    #[test]
    fn test_display_alignment() {
        assert_eq!("|357 B     |", format!("|{:10}|", ByteSize(357)));
        assert_eq!("|     357 B|", format!("|{:>10}|", ByteSize(357)));
        assert_eq!("|357 B     |", format!("|{:<10}|", ByteSize(357)));
        assert_eq!("|  357 B   |", format!("|{:^10}|", ByteSize(357)));

        assert_eq!("|-----357 B|", format!("|{:->10}|", ByteSize(357)));
        assert_eq!("|357 B-----|", format!("|{:-<10}|", ByteSize(357)));
        assert_eq!("|--357 B---|", format!("|{:-^10}|", ByteSize(357)));
    }

    fn assert_to_string(expected: &str, b: ByteSize, si: bool) {
        assert_eq!(expected.to_string(), b.to_string_as(si));
    }

    #[test]
    fn test_to_string_as() {
        assert_to_string("215 B", ByteSize::b(215), true);
        assert_to_string("215 B", ByteSize::b(215), false);

        assert_to_string("1.0 kiB", ByteSize::kib(1), true);
        assert_to_string("1.0 KB", ByteSize::kib(1), false);

        assert_to_string("293.9 kiB", ByteSize::kb(301), true);
        assert_to_string("301.0 KB", ByteSize::kb(301), false);

        assert_to_string("1.0 MiB", ByteSize::mib(1), true);
        assert_to_string("1048.6 KB", ByteSize::mib(1), false);

        // a bug case: https://github.com/flang-project/bytesize/issues/8
        assert_to_string("1.9 GiB", ByteSize::mib(1907), true);
        assert_to_string("2.0 GB", ByteSize::mib(1908), false);

        assert_to_string("399.6 MiB", ByteSize::mb(419), true);
        assert_to_string("419.0 MB", ByteSize::mb(419), false);

        assert_to_string("482.4 GiB", ByteSize::gb(518), true);
        assert_to_string("518.0 GB", ByteSize::gb(518), false);

        assert_to_string("741.2 TiB", ByteSize::tb(815), true);
        assert_to_string("815.0 TB", ByteSize::tb(815), false);

        assert_to_string("540.9 PiB", ByteSize::pb(609), true);
        assert_to_string("609.0 PB", ByteSize::pb(609), false);
    }

    #[test]
    fn test_default() {
        assert_eq!(ByteSize::b(0), ByteSize::default());
    }

    #[test]
    fn test_to_string() {
        assert_to_string("609.0 PB", ByteSize::pb(609), false);
    }
}
<commit_msg>Update lib.rs<commit_after>//! ByteSize is an utility that easily makes bytes size representation
//! and helps its arithmetic operations.
//!
//! ## Example
//!
//! ```ignore
//! extern crate bytesize;
//!
//! use bytesize::ByteSize;
//!
//! fn byte_arithmetic_operator() {
//!   let x = ByteSize::mb(1);
//!   let y = ByteSize::kb(100);
//!
//!   let plus = x + y;
//!   print!("{} bytes", plus.as_u64());
//!
//!   let minus = ByteSize::tb(100) - ByteSize::gb(4);
//!   print!("{} bytes", minus.as_u64());
//! }
//! ```
//!
//! It also provides its human readable string as follows:
//!
//! ```ignore=
//!  assert_eq!("482 GiB".to_string(), ByteSize::gb(518).to_string(true));
//!  assert_eq!("518 GB".to_string(), ByteSize::gb(518).to_string(false));
//! ```

#[cfg(feature = "serde")]
#[macro_use]
extern crate serde;

use std::fmt::{Debug, Display, Formatter, Result};
use std::ops::{Add, AddAssign, Mul, MulAssign};

/// byte size for 1 byte
pub const B: u64 = 1;
/// bytes size for 1 kilobyte
pub const KB: u64 = 1_000;
/// bytes size for 1 megabyte
pub const MB: u64 = 1_000_000;
/// bytes size for 1 gigabyte
pub const GB: u64 = 1_000_000_000;
/// bytes size for 1 terabyte
pub const TB: u64 = 1_000_000_000_000;
/// bytes size for 1 petabyte
pub const PB: u64 = 1_000_000_000_000_000;

/// bytes size for 1 kibibyte
pub const KIB: u64 = 1_024;
/// bytes size for 1 mebibyte
pub const MIB: u64 = 1_048_576;
/// bytes size for 1 gibibyte
pub const GIB: u64 = 1_073_741_824;
/// bytes size for 1 tebibyte
pub const TIB: u64 = 1_099_511_627_776;
/// bytes size for 1 pebibyte
pub const PIB: u64 = 1_125_899_906_842_624;

static UNITS: &'static str = "KMGTPE";
static UNITS_SI: &'static str = "kMGTPE";
static LN_KB: f64 = 6.931471806; // ln 1024
static LN_KIB: f64 = 6.907755279; // ln 1000

pub fn kb<V: Into<u64>>(size: V) -> u64 {
    size.into() * KB
}

pub fn kib<V: Into<u64>>(size: V) -> u64 {
    size.into() * KIB
}

pub fn mb<V: Into<u64>>(size: V) -> u64 {
    size.into() * MB
}

pub fn mib<V: Into<u64>>(size: V) -> u64 {
    size.into() * MIB
}

pub fn gb<V: Into<u64>>(size: V) -> u64 {
    size.into() * GB
}

pub fn gib<V: Into<u64>>(size: V) -> u64 {
    size.into() * GIB
}

pub fn tb<V: Into<u64>>(size: V) -> u64 {
    size.into() * TB
}

pub fn tib<V: Into<u64>>(size: V) -> u64 {
    size.into() * TIB
}

pub fn pb<V: Into<u64>>(size: V) -> u64 {
    size.into() * PB
}

pub fn pib<V: Into<u64>>(size: V) -> u64 {
    size.into() * PIB
}

/// Byte size representation
#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ByteSize(pub u64);

impl ByteSize {
    #[inline(always)]
    pub const fn b(size: u64) -> ByteSize {
        ByteSize(size)
    }

    #[inline(always)]
    pub const fn kb(size: u64) -> ByteSize {
        ByteSize(size * KB)
    }

    #[inline(always)]
    pub const fn kib(size: u64) -> ByteSize {
        ByteSize(size * KIB)
    }

    #[inline(always)]
    pub const fn mb(size: u64) -> ByteSize {
        ByteSize(size * MB)
    }

    #[inline(always)]
    pub const fn mib(size: u64) -> ByteSize {
        ByteSize(size * MIB)
    }

    #[inline(always)]
    pub const fn gb(size: u64) -> ByteSize {
        ByteSize(size * GB)
    }

    #[inline(always)]
    pub const fn gib(size: u64) -> ByteSize {
        ByteSize(size * GIB)
    }

    #[inline(always)]
    pub const fn tb(size: u64) -> ByteSize {
        ByteSize(size * TB)
    }

    #[inline(always)]
    pub const fn tib(size: u64) -> ByteSize {
        ByteSize(size * TIB)
    }

    #[inline(always)]
    pub const fn pb(size: u64) -> ByteSize {
        ByteSize(size * PB)
    }

    #[inline(always)]
    pub const fn pib(size: u64) -> ByteSize {
        ByteSize(size * PIB)
    }

    #[inline(always)]
    pub fn as_u64(&self) -> u64 {
        self.0
    }

    #[inline(always)]
    pub fn to_string_as(&self, si_unit: bool) -> String {
        to_string(self.0, si_unit)
    }
}

pub fn to_string(bytes: u64, si_prefix: bool) -> String {
    let unit = if si_prefix { KIB } else { KB };
    let unit_base = if si_prefix { LN_KIB } else { LN_KB };
    let unit_prefix = if si_prefix {
        UNITS_SI.as_bytes()
    } else {
        UNITS.as_bytes()
    };
    let unit_suffix = if si_prefix { "iB" } else { "B" };

    if bytes < unit {
        format!("{} B", bytes)
    } else {
        let size = bytes as f64;
        let exp = match (size.ln() / unit_base) as usize {
            e if e == 0 => 1,
            e => e,
        };

        format!(
            "{:.1} {}{}",
            (size / unit.pow(exp as u32) as f64),
            unit_prefix[exp - 1] as char,
            unit_suffix
        )
    }
}

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

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

macro_rules! commutative_op {
    ($t:ty) => {
        impl Add<ByteSize> for $t {
            type Output = ByteSize;
            #[inline(always)]
            fn add(self, rhs: ByteSize) -> ByteSize {
                ByteSize(rhs.0 + (self as u64))
            }
        }

        impl Mul<ByteSize> for $t {
            type Output = ByteSize;
            #[inline(always)]
            fn mul(self, rhs: ByteSize) -> ByteSize {
                ByteSize(rhs.0 * (self as u64))
            }
        }
    };
}

commutative_op!(u64);
commutative_op!(u32);
commutative_op!(u16);
commutative_op!(u8);

impl Add<ByteSize> for ByteSize {
    type Output = ByteSize;

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

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

impl<T> Add<T> for ByteSize
    where T: Into<u64> {
    type Output = ByteSize;
    #[inline(always)]
    fn add(self, rhs: T) -> ByteSize {
        ByteSize(self.0 + (rhs.into() as u64))
    }
}

impl<T> AddAssign<T> for ByteSize
    where T: Into<u64> {
    #[inline(always)]
    fn add_assign(&mut self, rhs: T) {
        self.0 += rhs.into() as u64;
    }
}

impl<T> Mul<T> for ByteSize
    where T: Into<u64> {
    type Output = ByteSize;
    #[inline(always)]
    fn mul(self, rhs: T) -> ByteSize {
        ByteSize(self.0 * (rhs.into() as u64))
    }
}

impl<T> MulAssign<T> for ByteSize
    where T: Into<u64> {
    #[inline(always)]
    fn mul_assign(&mut self, rhs: T) {
        self.0 *= rhs.into() as u64;
    }
}

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

    #[test]
    fn test_arithmetic_op() {
        let mut x = ByteSize::mb(1);
        let y = ByteSize::kb(100);

        assert_eq!((x + y).as_u64(), 1_100_000u64);

        assert_eq!((x + (100 * 1000) as u64).as_u64(), 1_100_000);

        assert_eq!((x * 2u64).as_u64(), 2_000_000);

        x += y;
        assert_eq!(x.as_u64(), 1_100_000);
        x *= 2u64;
        assert_eq!(x.as_u64(), 2_200_000);
    }

    #[test]
    fn test_arithmetic_primitives() {
        let mut x = ByteSize::mb(1);

        assert_eq!((x + MB as u64).as_u64(), 2_000_000);

        assert_eq!((x + MB as u32).as_u64(), 2_000_000);

        assert_eq!((x + KB as u16).as_u64(), 1_001_000);

        assert_eq!((x + B as u8).as_u64(), 1_000_001);

        x += MB as u64;
        x += MB as u32;
        x += 10 as u16;
        x += 1 as u8;
        assert_eq!(x.as_u64(), 3_000_011);
    }

    #[test]
    fn test_comparison() {
        assert!(ByteSize::mb(1) == ByteSize::kb(1000));
        assert!(ByteSize::mib(1) == ByteSize::kib(1024));
        assert!(ByteSize::mb(1) != ByteSize::kib(1024));
        assert!(ByteSize::mb(1) < ByteSize::kib(1024));
        assert!(ByteSize::b(0) < ByteSize::tib(1));
    }

    fn assert_display(expected: &str, b: ByteSize) {
        assert_eq!(expected, format!("{}", b));
    }

    #[test]
    fn test_display() {
        assert_display("215 B", ByteSize::b(215));
        assert_display("1.0 KB", ByteSize::kb(1));
        assert_display("301.0 KB", ByteSize::kb(301));
        assert_display("419.0 MB", ByteSize::mb(419));
        assert_display("518.0 GB", ByteSize::gb(518));
        assert_display("815.0 TB", ByteSize::tb(815));
        assert_display("609.0 PB", ByteSize::pb(609));
    }

    #[test]
    fn test_display_alignment() {
        assert_eq!("|357 B     |", format!("|{:10}|", ByteSize(357)));
        assert_eq!("|     357 B|", format!("|{:>10}|", ByteSize(357)));
        assert_eq!("|357 B     |", format!("|{:<10}|", ByteSize(357)));
        assert_eq!("|  357 B   |", format!("|{:^10}|", ByteSize(357)));

        assert_eq!("|-----357 B|", format!("|{:->10}|", ByteSize(357)));
        assert_eq!("|357 B-----|", format!("|{:-<10}|", ByteSize(357)));
        assert_eq!("|--357 B---|", format!("|{:-^10}|", ByteSize(357)));
    }

    fn assert_to_string(expected: &str, b: ByteSize, si: bool) {
        assert_eq!(expected.to_string(), b.to_string_as(si));
    }

    #[test]
    fn test_to_string_as() {
        assert_to_string("215 B", ByteSize::b(215), true);
        assert_to_string("215 B", ByteSize::b(215), false);

        assert_to_string("1.0 kiB", ByteSize::kib(1), true);
        assert_to_string("1.0 KB", ByteSize::kib(1), false);

        assert_to_string("293.9 kiB", ByteSize::kb(301), true);
        assert_to_string("301.0 KB", ByteSize::kb(301), false);

        assert_to_string("1.0 MiB", ByteSize::mib(1), true);
        assert_to_string("1048.6 KB", ByteSize::mib(1), false);

        // a bug case: https://github.com/flang-project/bytesize/issues/8
        assert_to_string("1.9 GiB", ByteSize::mib(1907), true);
        assert_to_string("2.0 GB", ByteSize::mib(1908), false);

        assert_to_string("399.6 MiB", ByteSize::mb(419), true);
        assert_to_string("419.0 MB", ByteSize::mb(419), false);

        assert_to_string("482.4 GiB", ByteSize::gb(518), true);
        assert_to_string("518.0 GB", ByteSize::gb(518), false);

        assert_to_string("741.2 TiB", ByteSize::tb(815), true);
        assert_to_string("815.0 TB", ByteSize::tb(815), false);

        assert_to_string("540.9 PiB", ByteSize::pb(609), true);
        assert_to_string("609.0 PB", ByteSize::pb(609), false);
    }

    #[test]
    fn test_default() {
        assert_eq!(ByteSize::b(0), ByteSize::default());
    }

    #[test]
    fn test_to_string() {
        assert_to_string("609.0 PB", ByteSize::pb(609), false);
    }
}
<|endoftext|>


<commit_before>extern crate libc;

use std::os::raw;
use std::ffi::CString;
use std::mem::transmute;

#[link(name = "rust")]
extern {
  fn klee_make_symbolic(data: *const raw::c_void, length: libc::size_t, name: *const raw::c_char);
}

pub fn any(data: *const raw::c_void, length: usize, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(data, length as libc::size_t, name_cstr.as_ptr());
  }
}

pub fn i32(data: *const i32, name: &str) {
  unsafe { any(transmute(data), 4, name); }
}

pub fn u32(data: *const u32, name: &str) {
  unsafe { any(transmute(data), 4, name); }
}

pub fn bytes(data: &[u8], name: &str) {
  unsafe { any(transmute(data.as_ptr()), data.len(), name); }
}
<commit_msg>Update lib.rs<commit_after>extern crate libc;

use std::os::raw;
use std::ffi::CString;
use std::mem::transmute;

#[link(name = "rust")]
extern {
  fn klee_make_symbolic(data: *const raw::c_void, length: libc::size_t, name: *const raw::c_char);
}

pub fn any(data: *const raw::c_void, length: usize, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(data, length as libc::size_t, name_cstr.as_ptr());
  }
}

pub fn i32(data: *const i32, name: &str) {
  unsafe { any(transmute(data), 4, name); }
}

pub fn u32(data: *const u32, name: &str) {
  unsafe { any(transmute(data), 4, name); }
}

pub fn str(data: &str, name: &str) {
  unsafe { any(transmute(data.as_ptr()), data.len(), name); }
}

pub fn bytes(data: &[u8], name: &str) {
  unsafe { any(transmute(data.as_ptr()), data.len(), name); }
}
<|endoftext|>


<commit_before>extern crate curl;

use std::str;
use curl::http;

pub struct Firebase {
    base_uri: String,
}

impl Firebase {
    pub fn new(base_uri: &str) -> Firebase {
        Firebase {
            base_uri: base_uri.to_string(),
        }
    }

    pub fn at(&self, path: &str) -> Firebase {
        Firebase {
            base_uri: self.base_uri.clone() + path,
        }
    }

    pub fn get(&self) -> Response {
        self.request(Method::GET, None)
    }

    pub fn set(&self, data: &str) -> Response {
        self.request(Method::PUT, Some(data))
    }

    pub fn push(&self, data: &str) -> Response {
        self.request(Method::POST, Some(data))
    }

    pub fn update(&self, data: &str) -> Response {
        self.request(Method::PATCH, Some(data))
    }

    pub fn delete(&self) -> Response {
        self.request(Method::DELETE, None)
    }

    fn request(&self, method: Method, data: Option<&str>) -> Response {
        let url = &self.base_uri as &str;
        let mut handler = http::handle();

        let req = match method {
            Method::GET => handler.get(url),
            Method::POST => handler.post(url, data.unwrap()),
            Method::PUT => handler.put(url, data.unwrap()),
            Method::PATCH => handler.patch(url, data.unwrap()),
            Method::DELETE => handler.delete(url)
        };
        let res = req.exec().unwrap();

        let body = match str::from_utf8(res.get_body()) {
            Ok(b) => b,
            Err(..) => "Unable to parse"
        };

        return Response {
            body: body.to_string(),
            code: res.get_code(),
        };
    }
}

enum Method {
    GET,
    POST,
    PUT,
    PATCH,
    DELETE,
}

pub struct Response {
    pub body: String,
    pub code: u32,
}

impl Response {
    pub fn is_success(&self) -> bool {
        if self.code < 400 {
            return true;
        }
        return false;
    }
}
<commit_msg>Better style<commit_after>extern crate curl;

use std::str;
use curl::http;

pub struct Firebase {
    base_uri: String,
}

impl Firebase {
    pub fn new(base_uri: &str) -> Firebase {
        Firebase {
            base_uri: base_uri.to_string(),
        }
    }

    pub fn at(&self, path: &str) -> Firebase {
        Firebase {
            base_uri: self.base_uri.clone() + path,
        }
    }

    pub fn get(&self) -> Response {
        self.request(Method::GET, None)
    }

    pub fn set(&self, data: &str) -> Response {
        self.request(Method::PUT, Some(data))
    }

    pub fn push(&self, data: &str) -> Response {
        self.request(Method::POST, Some(data))
    }

    pub fn update(&self, data: &str) -> Response {
        self.request(Method::PATCH, Some(data))
    }

    pub fn delete(&self) -> Response {
        self.request(Method::DELETE, None)
    }

    fn request(&self, method: Method, data: Option<&str>) -> Response {
        let url: &str = &self.base_uri;
        let mut handler = http::handle();

        let req = match method {
            Method::GET     => handler.get(url),
            Method::POST    => handler.post(url, data.unwrap()),
            Method::PUT     => handler.put(url, data.unwrap()),
            Method::PATCH   => handler.patch(url, data.unwrap()),
            Method::DELETE  => handler.delete(url)
        };
        let res = req.exec().unwrap();

        let body = match str::from_utf8(res.get_body()) {
            Ok(b) => b,
            Err(..) => "Unable to parse"
        };

        return Response {
            body: body.to_string(),
            code: res.get_code(),
        };
    }
}

enum Method {
    GET,
    POST,
    PUT,
    PATCH,
    DELETE,
}

pub struct Response {
    pub body: String,
    pub code: u32,
}

impl Response {
    pub fn is_success(&self) -> bool {
        if self.code < 400 {
            return true;
        }
        return false;
    }
}
<|endoftext|>


<commit_before>use std::io::{self, Write};
use std::iter::Peekable;
use std::collections::BTreeMap;

#[derive(PartialEq, Eq, Debug)]
pub enum Bencode {
    Integer(Vec<u8>),
    Bytes(Vec<u8>),
    Array(Vec<Bencode>),
    Object(BTreeMap<Vec<u8>, Bencode>),
}

type BencodeResult<T> = Result<T, ParseError>;

pub enum ParseError {
	Truncated,
	InvalidCharacter,
	InvalidLength,
	OutOfOrderKey,
}

fn is_digit(val: u8) -> bool {
	b'0' <= val && val <= b'9'
}

fn bdecode_extract_integer<I>(stream: &mut Peekable<I>)
	-> BencodeResult<Vec<u8>>
	where
		I: Iterator<Item=u8> {

	let mut buf = Vec::new();
	loop {
		match stream.peek() {
			Some(&val) if is_digit(val) => buf.push(stream.next().unwrap()),
			Some(_) => return Ok(buf),
			None => return Err(ParseError::Truncated)
		}
	}
}

fn bdecode_integer<I>(stream: &mut Peekable<I>) -> BencodeResult<Vec<u8>>
	where
		I: Iterator<Item=u8> {

	let output = match stream.next() {
		Some(b'i') => try!(bdecode_extract_integer(stream)),
		Some(_) => return Err(ParseError::InvalidCharacter),
		None => return Err(ParseError::Truncated)
	};
	match stream.next() {
		Some(b'e') => Ok(output),
		Some(_) => Err(ParseError::Truncated),
		None => Err(ParseError::Truncated)
	}
}

fn bdecode_bytea<I>(stream: &mut Peekable<I>) -> BencodeResult<Vec<u8>>
	where
		I: Iterator<Item=u8> {

	let intbuf = try!(bdecode_extract_integer(stream));
	let length = std::str::from_utf8(&intbuf[..]).ok()
		.expect("bdecode_extract_integer failed to hold invariant")
		.parse::<usize>();

	let length = match length {
		Ok(value) => value,
		Err(_) => return Err(ParseError::InvalidLength),
	};

	match stream.next() {
		Some(b':') => Ok(stream.take(length).collect()),
		Some(_) => return Err(ParseError::InvalidCharacter),
		None => return Err(ParseError::Truncated)
	}
}

fn bdecode_list<I>(stream: &mut Peekable<I>) -> BencodeResult<Vec<Bencode>>
	where
		I: Iterator<Item=u8> {

	let mut output = Vec::new();
	assert_eq!(Some(b'l'), stream.next());

	loop {
		match stream.peek() {
			Some(&b'e') => {
				stream.next().expect("expected b'e'");
				return Ok(output);
			},
			Some(_) => output.push(try!(bdecode(stream))),
			None => return Err(ParseError::Truncated)
		}
	}
}

fn bdecode_dict<I>(stream: &mut Peekable<I>)
	-> BencodeResult<BTreeMap<Vec<u8>, Bencode>>
	where
		I: Iterator<Item=u8> {

	// Key order checking. Elide these checks in the future?
	let mut prev_key = Vec::new();

	let mut output = BTreeMap::new();
	assert_eq!(Some(b'd'), stream.next());

	loop {
		match stream.peek() {
			Some(&b'e') => return Ok(output),
			Some(_) => (),
			None => return Err(ParseError::Truncated),
		}
		let key = try!(bdecode_bytea(stream));
		if key < prev_key {
			return Err(ParseError::OutOfOrderKey);
		}
		prev_key.clear();
		prev_key.extend(key.iter().cloned());

		let value = try!(bdecode(stream));
		output.insert(key, value);
	}
}

fn iter_bdecode<I>(stream: &mut Peekable<I>) -> Result<Bencode, ParseError>
	where
		I: Iterator<Item=u8> {

	use Bencode::{Integer, Array, Object, Bytes};
	match stream.peek() {
		Some(&b'i') => Ok(Integer(try!(bdecode_integer(stream)))),
		Some(&b'l') => Ok(Array(try!(bdecode_list(stream)))),
		Some(&b'd') => Ok(Object(try!(bdecode_dict(stream)))),
		Some(&val) if is_digit(val) => Ok(Bytes(try!(bdecode_bytea(stream)))),
		_ => Err(ParseError::InvalidCharacter),
	}
}

fn bencode_bytea<W>(bytea: &[u8], writer: &mut W) -> Result<(), io::Error>
	where
		W: Write {

	try!(write!(writer, "{}:", bytea.len()));
	try!(writer.write_all(bytea));
	Ok(())
}

pub fn bencode<W>(document: &Bencode, writer: &mut W) -> Result<(), io::Error>
	where
		W: Write {

	match document {
		&Bencode::Integer(ref buf) => {
			try!(writer.write_all(b"i"));
			try!(writer.write_all(buf));
			try!(writer.write_all(b"e"));
		},
		&Bencode::Bytes(ref buf) => try!(bencode_bytea(buf, writer)),
		&Bencode::Array(ref items) => {
			try!(writer.write_all(b"l"));
			for item in items.iter() {
				try!(bencode(item, writer));
			}
			try!(writer.write_all(b"e"));
		},
		&Bencode::Object(ref map) => {
			try!(writer.write_all(b"d"));
			for (key, value) in map.iter() {
				try!(bencode_bytea(key, writer));
				try!(bencode(value, writer));
			}
			try!(writer.write_all(b"e"));
		},
	};
	Ok(())
}

#[test]
fn it_works() {
	let document = b"d1:a3:eh?1:bl3:beeee";

	let mut peekable = document.iter().cloned().peekable();
	let result = bdecode(&mut peekable).ok().expect("failed to parse");

	let obj = match result {
		Bencode::Object(ref obj) => obj,
		_ => panic!("Must be an Bencode::Object"),
	};

	assert_eq!(
		obj.get(b"a" as &[u8]),
		Some(&Bencode::Bytes(b"eh?".to_vec())));

	assert_eq!(
		obj.get(b"b" as &[u8]),
		Some(&Bencode::Array(vec![
			Bencode::Bytes(b"bee".to_vec())
		])));

	let mut reserialized = Vec::new();
	bencode(&result, &mut reserialized).ok().expect("failed to serialize");
	assert_eq!(document, &reserialized[..]);
}
<commit_msg>Fix indentation<commit_after>use std::io::{self, Write};
use std::iter::Peekable;
use std::collections::BTreeMap;

#[derive(PartialEq, Eq, Debug)]
pub enum Bencode {
    Integer(Vec<u8>),
    Bytes(Vec<u8>),
    Array(Vec<Bencode>),
    Object(BTreeMap<Vec<u8>, Bencode>),
}

type BencodeResult<T> = Result<T, ParseError>;

pub enum ParseError {
    Truncated,
    InvalidCharacter,
    InvalidLength,
    OutOfOrderKey,
}

fn is_digit(val: u8) -> bool {
    b'0' <= val && val <= b'9'
}

fn bdecode_extract_integer<I>(stream: &mut Peekable<I>)
    -> BencodeResult<Vec<u8>>
    where
        I: Iterator<Item=u8> {

    let mut buf = Vec::new();
    loop {
        match stream.peek() {
            Some(&val) if is_digit(val) => buf.push(stream.next().unwrap()),
            Some(_) => return Ok(buf),
            None => return Err(ParseError::Truncated)
        }
    }
}

fn bdecode_integer<I>(stream: &mut Peekable<I>) -> BencodeResult<Vec<u8>>
    where
        I: Iterator<Item=u8> {

    let output = match stream.next() {
        Some(b'i') => try!(bdecode_extract_integer(stream)),
        Some(_) => return Err(ParseError::InvalidCharacter),
        None => return Err(ParseError::Truncated)
    };
    match stream.next() {
        Some(b'e') => Ok(output),
        Some(_) => Err(ParseError::Truncated),
        None => Err(ParseError::Truncated)
    }
}

fn bdecode_bytea<I>(stream: &mut Peekable<I>) -> BencodeResult<Vec<u8>>
    where
        I: Iterator<Item=u8> {

    let intbuf = try!(bdecode_extract_integer(stream));
    let length = std::str::from_utf8(&intbuf[..]).ok()
        .expect("bdecode_extract_integer failed to hold invariant")
        .parse::<usize>();

    let length = match length {
        Ok(value) => value,
        Err(_) => return Err(ParseError::InvalidLength),
    };

    match stream.next() {
        Some(b':') => Ok(stream.take(length).collect()),
        Some(_) => return Err(ParseError::InvalidCharacter),
        None => return Err(ParseError::Truncated)
    }
}

fn bdecode_list<I>(stream: &mut Peekable<I>) -> BencodeResult<Vec<Bencode>>
    where
        I: Iterator<Item=u8> {

    let mut output = Vec::new();
    assert_eq!(Some(b'l'), stream.next());

    loop {
        match stream.peek() {
            Some(&b'e') => {
                stream.next().expect("expected b'e'");
                return Ok(output);
            },
            Some(_) => output.push(try!(bdecode(stream))),
            None => return Err(ParseError::Truncated)
        }
    }
}

fn bdecode_dict<I>(stream: &mut Peekable<I>)
    -> BencodeResult<BTreeMap<Vec<u8>, Bencode>>
    where
        I: Iterator<Item=u8> {

    // Key order checking. Elide these checks in the future?
    let mut prev_key = Vec::new();

    let mut output = BTreeMap::new();
    assert_eq!(Some(b'd'), stream.next());

    loop {
        match stream.peek() {
            Some(&b'e') => return Ok(output),
            Some(_) => (),
            None => return Err(ParseError::Truncated),
        }
        let key = try!(bdecode_bytea(stream));
        if key < prev_key {
            return Err(ParseError::OutOfOrderKey);
        }
        prev_key.clear();
        prev_key.extend(key.iter().cloned());

        let value = try!(bdecode(stream));
        output.insert(key, value);
    }
}

fn iter_bdecode<I>(stream: &mut Peekable<I>) -> Result<Bencode, ParseError>
    where
        I: Iterator<Item=u8> {

    use Bencode::{Integer, Array, Object, Bytes};
    match stream.peek() {
        Some(&b'i') => Ok(Integer(try!(bdecode_integer(stream)))),
        Some(&b'l') => Ok(Array(try!(bdecode_list(stream)))),
        Some(&b'd') => Ok(Object(try!(bdecode_dict(stream)))),
        Some(&val) if is_digit(val) => Ok(Bytes(try!(bdecode_bytea(stream)))),
        _ => Err(ParseError::InvalidCharacter),
    }
}

fn bencode_bytea<W>(bytea: &[u8], writer: &mut W) -> Result<(), io::Error>
    where
        W: Write {

    try!(write!(writer, "{}:", bytea.len()));
    try!(writer.write_all(bytea));
    Ok(())
}

pub fn bencode<W>(document: &Bencode, writer: &mut W) -> Result<(), io::Error>
    where
        W: Write {

    match document {
        &Bencode::Integer(ref buf) => {
            try!(writer.write_all(b"i"));
            try!(writer.write_all(buf));
            try!(writer.write_all(b"e"));
        },
        &Bencode::Bytes(ref buf) => try!(bencode_bytea(buf, writer)),
        &Bencode::Array(ref items) => {
            try!(writer.write_all(b"l"));
            for item in items.iter() {
                try!(bencode(item, writer));
            }
            try!(writer.write_all(b"e"));
        },
        &Bencode::Object(ref map) => {
            try!(writer.write_all(b"d"));
            for (key, value) in map.iter() {
                try!(bencode_bytea(key, writer));
                try!(bencode(value, writer));
            }
            try!(writer.write_all(b"e"));
        },
    };
    Ok(())
}

#[test]
fn it_works() {
    let document = b"d1:a3:eh?1:bl3:beeee";

    let mut peekable = document.iter().cloned().peekable();
    let result = bdecode(&mut peekable).ok().expect("failed to parse");

    let obj = match result {
        Bencode::Object(ref obj) => obj,
        _ => panic!("Must be an Bencode::Object"),
    };

    assert_eq!(
        obj.get(b"a" as &[u8]),
        Some(&Bencode::Bytes(b"eh?".to_vec())));

    assert_eq!(
        obj.get(b"b" as &[u8]),
        Some(&Bencode::Array(vec![
            Bencode::Bytes(b"bee".to_vec())
        ])));

    let mut reserialized = Vec::new();
    bencode(&result, &mut reserialized).ok().expect("failed to serialize");
    assert_eq!(document, &reserialized[..]);
}
<|endoftext|>


<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2014 J.C. Moyer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#![feature(unsafe_destructor)]

extern crate libc;

pub use state::{
  State,

  Number,
  Integer,
  Function,
  Continuation,
  Reader,
  Writer,
  Context,
  Allocator,
  Hook,
  Index,

  Arithmetic,
  LuaAdd, LuaSub, LuaMul, LuaMod, LuaPow, LuaDiv, LuaIDiv,
  LuaBAnd, LuaBOr, LuaBXor, LuaShl, LuaShr, LuaUnm, LuaBNot,

  Comparison,
  LuaEq, LuaLt, LuaLe,

  ThreadStatus,
  LuaOk, LuaYield, LuaRuntimeError, LuaSyntaxError, LuaMemoryError,
  LuaGcError, LuaMessageHandlerError, LuaFileError,

  GcOption,
  GcStop, GcRestart, GcCollect, GcCount, GcCountBytes, GcStep, GcSetPause,
  GcSetStepMul, GcIsRunning,

  Type,
  LuaNone, LuaNil, LuaBoolean, LuaLightUserdata, LuaNumber, LuaString,
  LuaTable, LuaFunction, LuaUserdata, LuaThread,

  Reference,
  REFNIL, NOREF,

  HookMask,
  MASKCALL, MASKRET, MASKLINE, MASKCOUNT,

  MULTRET, REGISTRYINDEX,
  RIDX_MAINTHREAD, RIDX_GLOBALS
};

#[link(name="lua53")]
extern {}

pub mod ffi;
mod state;

<commit_msg>Add crate metadata attributes<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2014 J.C. Moyer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#![crate_name = "lua"]
#![crate_type = "lib"]
#![comment = "Lua 5.3 bindings for Rust"]
#![license = "MIT"]

#![feature(unsafe_destructor)]

extern crate libc;

pub use state::{
  State,

  Number,
  Integer,
  Function,
  Continuation,
  Reader,
  Writer,
  Context,
  Allocator,
  Hook,
  Index,

  Arithmetic,
  LuaAdd, LuaSub, LuaMul, LuaMod, LuaPow, LuaDiv, LuaIDiv,
  LuaBAnd, LuaBOr, LuaBXor, LuaShl, LuaShr, LuaUnm, LuaBNot,

  Comparison,
  LuaEq, LuaLt, LuaLe,

  ThreadStatus,
  LuaOk, LuaYield, LuaRuntimeError, LuaSyntaxError, LuaMemoryError,
  LuaGcError, LuaMessageHandlerError, LuaFileError,

  GcOption,
  GcStop, GcRestart, GcCollect, GcCount, GcCountBytes, GcStep, GcSetPause,
  GcSetStepMul, GcIsRunning,

  Type,
  LuaNone, LuaNil, LuaBoolean, LuaLightUserdata, LuaNumber, LuaString,
  LuaTable, LuaFunction, LuaUserdata, LuaThread,

  Reference,
  REFNIL, NOREF,

  HookMask,
  MASKCALL, MASKRET, MASKLINE, MASKCOUNT,

  MULTRET, REGISTRYINDEX,
  RIDX_MAINTHREAD, RIDX_GLOBALS
};

#[link(name="lua53")]
extern {}

pub mod ffi;
mod state;

<|endoftext|>


<commit_before>#![deny(missing_docs)]

//! A simple and type agnostic quaternion math designed for reexporting

extern crate vecmath;

/// Quaternion type alias.
pub type Quaternion<T> = [T; 4];

pub use vecmath::vec4_add as add;

<commit_msg>Added `mul`<commit_after>#![deny(missing_docs)]

//! A simple and type agnostic quaternion math designed for reexporting

extern crate vecmath;

use std::num::Float;

/// Quaternion type alias.
pub type Quaternion<T> = [T; 4];

pub use vecmath::vec4_add as add;

/// Multiplies two quaternions.
#[inline(always)]
pub fn mul<T: Float + Copy>(
    a: Quaternion<T>,
    b: Quaternion<T>
) -> Quaternion<T> {
    use vecmath::vec3_cross as cross;
    use vecmath::vec3_add as add;
    use vecmath::vec3_dot as dot;
    use vecmath::vec3_scale as scale;

    let r1 = a[0];
    let r2 = b[0];
    let v1 = [a[1], a[2], a[3]];
    let v2 = [b[1], b[2], b[3]];
    let scalar = r1 * r2 - dot(v1, v2);
    let vector = add(
        add(scale(v2, r1), scale(v1, r2)),
        cross(v1, v2)
    );
    [scalar, vector[0], vector[1], vector[2]]
}

<|endoftext|>


<commit_before>//! Nom, eating data byte by byte
//!
//! The goal is to make a parser combinator library that is safe,
//! supports streaming (push and pull), and as much as possible zero copy.
//!
//! The code is available on [Github](https://github.com/Geal/nom)
//!
//! # Example
//!
//! ```
//! #[macro_use]
//! extern crate nom;
//!
//! use nom::{IResult,digit,multispace};
//! use nom::IResult::*;
//!
//! // Parser definition
//!
//! use std::str;
//! use std::str::FromStr;
//!
//! named!(parens<i64>, delimited!(
//!     delimited!(opt!(multispace), tag!("("), opt!(multispace)),
//!     expr,
//!     delimited!(opt!(multispace), tag!(")"), opt!(multispace))
//!   )
//! );
//!
//! // We transform an integer string into a i64
//! // we look for a digit suite, and try to convert it.
//! // if either str::from_utf8 or FromStr::from_str fail,
//! // the parser will fail
//! named!(factor<i64>,
//!   alt!(
//!     map_res!(
//!       map_res!(
//!         delimited!(opt!(multispace), digit, opt!(multispace)),
//!         str::from_utf8
//!       ),
//!       FromStr::from_str
//!     )
//!   | parens
//!   )
//! );
//!
//! // we define acc as mutable to update its value whenever a new term is found
//! named!(term <i64>,
//!   chain!(
//!     mut acc: factor  ~
//!              many0!(
//!                alt!(
//!                  tap!(mul: preceded!(tag!("*"), factor) => acc = acc * mul) |
//!                  tap!(div: preceded!(tag!("/"), factor) => acc = acc / div)
//!                )
//!              ),
//!     || { return acc }
//!   )
//! );
//!
//! named!(expr <i64>,
//!   chain!(
//!     mut acc: term  ~
//!              many0!(
//!                alt!(
//!                  tap!(add: preceded!(tag!("+"), term) => acc = acc + add) |
//!                  tap!(sub: preceded!(tag!("-"), term) => acc = acc - sub)
//!                )
//!              ),
//!     || { return acc }
//!   )
//! );
//!
//! fn main() {
//!   assert_eq!(expr(&b" 1 +  2 "[..]),             IResult::Done(&b""[..], 3));
//!   assert_eq!(expr(&b" 12 + 6 - 4+  3"[..]),      IResult::Done(&b""[..], 17));
//!   assert_eq!(expr(&b" 1 + 2*3 + 4"[..]),         IResult::Done(&b""[..], 11));
//!
//!   assert_eq!(expr(&b" (  2 )"[..]),              IResult::Done(&b""[..], 2));
//!   assert_eq!(expr(&b" 2* (  3 + 4 ) "[..]),      IResult::Done(&b""[..], 14));
//!   assert_eq!(expr(&b"  2*2 / ( 5 - 1) + 3"[..]), IResult::Done(&b""[..], 4));
//! }
//! ```
#![cfg_attr(feature = "core", feature(no_std))]
#![cfg_attr(feature = "core", feature(collections))]
#![cfg_attr(feature = "core", no_std)]
#![cfg_attr(feature = "regexp_macros", feature(plugin))]
#![cfg_attr(feature = "regexp_macros", plugin(regex_macros))]
#![cfg_attr(feature = "nightly", feature(test))]

#[cfg(feature = "core")]
extern crate collections;
#[cfg(feature = "regexp")]
extern crate regex;
#[cfg(feature = "nightly")]
extern crate test;

#[cfg(feature = "core")]
mod std {
#[macro_use]
  pub use core::{fmt, iter, option, ops, slice, mem};
  pub use collections::{boxed, vec, string};
  pub mod prelude {
    pub use core::prelude as v1;
  }
}

pub use self::util::*;
pub use self::internal::*;
pub use self::macros::*;
pub use self::bytes::*;
pub use self::bits::*;

pub use self::nom::*;
pub use self::character::*;

#[cfg(feature = "regexp")]
pub use self::regexp::*;

#[cfg(not(feature = "core"))]
#[cfg(feature = "stream")]
pub use self::stream::*;

#[cfg(not(feature = "core"))]
pub use self::str::*;

#[macro_use] mod util;
mod internal;
#[macro_use] mod macros;
#[macro_use] mod bytes;
#[macro_use] mod bits;

#[macro_use] mod nom;
#[macro_use] mod character;

#[cfg(feature = "regexp")]
#[macro_use] mod regexp;

#[macro_use]
#[cfg(not(feature = "core"))]
#[cfg(feature = "stream")]
mod stream;

#[cfg(not(feature = "core"))]
mod str;
<commit_msg>Simplify the arithmetic example parser<commit_after>//! Nom, eating data byte by byte
//!
//! The goal is to make a parser combinator library that is safe,
//! supports streaming (push and pull), and as much as possible zero copy.
//!
//! The code is available on [Github](https://github.com/Geal/nom)
//!
//! # Example
//!
//! ```
//! #[macro_use]
//! extern crate nom;
//!
//! use nom::{IResult,digit};
//! use nom::IResult::*;
//!
//! // Parser definition
//!
//! use std::str;
//! use std::str::FromStr;
//!
//! named!(parens<i64>, delimited!(
//!     char!('('),
//!     expr,
//!     char!(')')
//!   )
//! );
//!
//! named!(i64_digit<i64>,
//!   map_res!(
//!     map_res!(
//!       digit,
//!       str::from_utf8
//!     ),
//!     FromStr::from_str
//!   )
//! );
//!
//! // We transform an integer string into a i64
//! // we look for a digit suite, and try to convert it.
//! // if either str::from_utf8 or FromStr::from_str fail,
//! // the parser will fail
//! named!(factor<i64>,
//!   alt!(
//!     i64_digit
//!   | parens
//!   )
//! );
//!
//! // we define acc as mutable to update its value whenever a new term is found
//! named!(term <i64>,
//!   chain!(
//!     mut acc: factor  ~
//!              many0!(
//!                alt!(
//!                  tap!(mul: preceded!(tag!("*"), factor) => acc = acc * mul) |
//!                  tap!(div: preceded!(tag!("/"), factor) => acc = acc / div)
//!                )
//!              ),
//!     || { return acc }
//!   )
//! );
//!
//! named!(expr <i64>,
//!   chain!(
//!     mut acc: term  ~
//!              many0!(
//!                alt!(
//!                  tap!(add: preceded!(tag!("+"), term) => acc = acc + add) |
//!                  tap!(sub: preceded!(tag!("-"), term) => acc = acc - sub)
//!                )
//!              ),
//!     || { return acc }
//!   )
//! );
//!
//! fn main() {
//!   assert_eq!(expr(b"1+2"),         IResult::Done(&b""[..], 3));
//!   assert_eq!(expr(b"12+6-4+3"),    IResult::Done(&b""[..], 17));
//!   assert_eq!(expr(b"1+2*3+4"),     IResult::Done(&b""[..], 11));
//!
//!   assert_eq!(expr(b"(2)"),         IResult::Done(&b""[..], 2));
//!   assert_eq!(expr(b"2*(3+4)"),     IResult::Done(&b""[..], 14));
//!   assert_eq!(expr(b"2*2/(5-1)+3"), IResult::Done(&b""[..], 4));
//! }
//! ```
#![cfg_attr(feature = "core", feature(no_std))]
#![cfg_attr(feature = "core", feature(collections))]
#![cfg_attr(feature = "core", no_std)]
#![cfg_attr(feature = "regexp_macros", feature(plugin))]
#![cfg_attr(feature = "regexp_macros", plugin(regex_macros))]
#![cfg_attr(feature = "nightly", feature(test))]

#[cfg(feature = "core")]
extern crate collections;
#[cfg(feature = "regexp")]
extern crate regex;
#[cfg(feature = "nightly")]
extern crate test;

#[cfg(feature = "core")]
mod std {
#[macro_use]
  pub use core::{fmt, iter, option, ops, slice, mem};
  pub use collections::{boxed, vec, string};
  pub mod prelude {
    pub use core::prelude as v1;
  }
}

pub use self::util::*;
pub use self::internal::*;
pub use self::macros::*;
pub use self::bytes::*;
pub use self::bits::*;

pub use self::nom::*;
pub use self::character::*;

#[cfg(feature = "regexp")]
pub use self::regexp::*;

#[cfg(not(feature = "core"))]
#[cfg(feature = "stream")]
pub use self::stream::*;

#[cfg(not(feature = "core"))]
pub use self::str::*;

#[macro_use] mod util;
mod internal;
#[macro_use] mod macros;
#[macro_use] mod bytes;
#[macro_use] mod bits;

#[macro_use] mod nom;
#[macro_use] mod character;

#[cfg(feature = "regexp")]
#[macro_use] mod regexp;

#[macro_use]
#[cfg(not(feature = "core"))]
#[cfg(feature = "stream")]
mod stream;

#[cfg(not(feature = "core"))]
mod str;
<|endoftext|>


<commit_before>#![allow(unused_variables)]
#![allow(warnings)]

#[macro_use]
extern crate log;
#[macro_use]
extern crate lazy_static;
extern crate hyper;
extern crate typemap;
extern crate conduit_mime_types as mime_types;

mod request;
mod response;
mod handler;
mod recognizer;
mod router_m;
mod router;
mod app;

pub use app::SapperApp;
pub use app::SapperAppShell;
pub use app::SapperRequest as Request;
pub use app::SapperResponse as Response;
pub use app::SapperModule;
pub use app::SapperHandler;
pub use app::SapperRouter;
pub use app::{Result, Error, Key};
pub use app::{header, status, mime};
pub use app::PathParams;

<commit_msg>export hypper primitive client<commit_after>#![allow(unused_variables)]
#![allow(warnings)]

#[macro_use]
extern crate log;
#[macro_use]
extern crate lazy_static;
extern crate hyper;
extern crate typemap;
extern crate conduit_mime_types as mime_types;

mod request;
mod response;
mod handler;
mod recognizer;
mod router_m;
mod router;
mod app;

pub use app::SapperApp;
pub use app::SapperAppShell;
pub use app::SapperRequest as Request;
pub use app::SapperResponse as Response;
pub use app::SapperModule;
pub use app::SapperHandler;
pub use app::SapperRouter;
pub use app::{Result, Error, Key};
pub use app::{header, status, mime};
pub use app::PathParams;
pub use app::Client;

<|endoftext|>


<commit_before>//! The `sentinel_list` crate provides a simple sentinel based list implementation.
//! Once you insert element to the list you are given back a handle into this list.
//! This handle allows you to remove element from the list in O(1) time.
//!
//! # Examples
//!
//! ```rust
//! extern crate sentinel_list;
//! use sentinel_list::*;
//!
//! fn main() {
//!	 let l = &mut List::new();
//!	 let h1 = l.push_head(1);
//!	 let h2 = l.push_tail(2);
//!	 let h3 = l.push_tail(3);
//!	 {
//!		assert_eq!(&1, (&h1).as_ref());
//!		assert_eq!(&1, l.peek_head().unwrap());
//!		assert_eq!(&3, l.peek_tail().unwrap());
//!	 }
//!	 let e1 = h1.unlink();
//!	 assert_eq!(&2, l.peek_head().unwrap());
//!	 let e3 = h3.unlink();
//!	 assert_eq!(&2, l.peek_tail().unwrap());
//!	 let e2 = h2.unlink();
//!	 assert_eq!(None, l.peek_tail());
//!	 assert_eq!(None, l.peek_head());
//!	 assert_eq!(1, e1);
//!	 assert_eq!(2, e2);
//!	 assert_eq!(3, e3);
//! }
//! ```

#![feature(conservative_impl_trait)]

use std::ptr;
use std::fmt;
use std::ops::Deref;

pub trait ListHandle<T>
{
	fn unlink(self) -> T;
	fn as_ref(&self) -> &T;
}

pub struct Iter<'a, T: 'a>
{
	next: &'a Link<T>,
}

pub struct IterMut<'a, T: 'a>
{
	next: Option<&'a mut Link<T>>,
}

pub struct List<T>
{
	sentinel: Handle<T>,
}

impl<T> List<T>
{
	pub fn new() -> Self
	{
		List {
			sentinel: new_sentinel(),
		}
	}

	pub fn push_head(&mut self, e: T) -> impl ListHandle<T>
	{
		let mut h = new_handle(e);
		insert_after(&mut self.sentinel, &mut h);
		h
	}

	pub fn push_tail(&mut self, e: T) -> impl ListHandle<T>
	{
		let mut h = new_handle(e);
		insert_after(unsafe {&mut *self.sentinel.prev}, &mut h);
		h
	}

	pub fn peek_head(&self) -> Option<&T>
	{
		let link = unsafe { &*self.sentinel.next };
		link.value.as_ref()
	}

	pub fn peek_head_mut(&mut self) -> Option<&mut T>
	{
		let link = unsafe { &mut *self.sentinel.next };
		link.value.as_mut()
	}

	pub fn peek_tail(&self) -> Option<&T>
	{
		let link = unsafe { &*self.sentinel.prev };
		link.value.as_ref()
	}

	pub fn peek_tail_mut(&mut self) -> Option<&mut T>
	{
		let link = unsafe { &mut *self.sentinel.prev };
		link.value.as_mut()
	}

	pub fn iter(&self) -> Iter<T>
	{
		Iter { next: unsafe {&*self.sentinel.next} }
	}

	pub fn iter_mut(&mut self) -> IterMut<T>
	{
		let next = Some(unsafe {&mut *self.sentinel.next});
		let inext = next.map(|v| {
			v
		});
		IterMut { next: inext }
	}
}

impl<'a, T> Iterator for Iter<'a, T>
{
	type Item = &'a T;

	fn next(&mut self) -> Option<Self::Item>
	{
		self.next.value.as_ref().and_then(|v| {
			self.next = unsafe {&*self.next.next};
			Some(v)
		})
	}
}

impl<'a, T> Iterator for IterMut<'a, T>
{
	type Item = &'a mut T;

	fn next(&mut self) -> Option<Self::Item>
	{
		self.next.take().and_then(|link| {
			self.next = Some(unsafe {&mut *link.next});
			link.value.as_mut().map(|v| {
				v
			})
		})
	}
}

#[derive(PartialEq)]
struct Link<T>
{
	pub next: *mut Link<T>,
	pub prev: *mut Link<T>,
	pub value: Option<T>,
}

type Handle<T> = Box<Link<T>>;

impl<T> Link<T>
{
	fn new(v: T) -> Link<T>
	{
		Link {
			prev: ptr::null_mut(),
			next: ptr::null_mut(),
			value: Some(v),
		}
	}
}

impl<T: fmt::Debug> fmt::Debug for Link<T>
{
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		write!(f, "Link {{ prev: {:p}, next: {:p}, value: {:?} }}", self.prev, self.next, self.value)
	}
}

impl<T> ListHandle<T> for Handle<T>
{
	fn unlink(self) -> T
	{
		// if you call it on the sentinel
		// you deserve to get what's coming
		unlink(self).unwrap()
	}

	fn as_ref(&self) -> &T
	{
		&self
	}
}

impl<T> Deref for Link<T>
{
	type Target = T;
	fn deref(&self) -> &Self::Target
	{
		// if you call it on the sentinel
		// you deserve to get what's coming
		self.value.as_ref().unwrap()
	}
}

fn new_sentinel<T>() -> Handle<T>
{
	let mut h = Box::new(
		Link {
			prev: ptr::null_mut(),
			next: ptr::null_mut(),
			value: None,
		}
	);
	h.prev = &mut *h;
	h.next = &mut *h;
	h
}

fn new_handle<T>(v: T) -> Handle<T>
{
	Box::new(Link::new(v))
}

fn insert_after<T>(after: &mut Link<T>, h: &mut Link<T>)
{
	let n: *mut _ = after.next;

	h.prev = &mut *after;
	h.next = n;

	after.next = &mut *h;

	let n = unsafe { &mut *h.next };
	n.prev = &mut *h;
}

fn unlink<T>(h: Handle<T>) -> Option<T>
{
	let prev = unsafe { &mut *h.prev };
	let next = unsafe { &mut *h.next };
	next.prev = prev;
	prev.next = next;
	h.value
}

#[allow(dead_code)]
#[cfg(test)]
fn debug_print<T: fmt::Debug>(s: &mut Handle<T>)
{
	let mut h = s.next;
	while h != &mut **s {
		let n = unsafe { &*h };
		println!("{:?}", n);
		h = n.next;
	}
}

#[cfg(test)]
#[test]
fn link_unlink()
{
	let mut s = new_sentinel();
	let mut h1 = new_handle(1);
	let mut h2 = new_handle(2);
	let mut h3 = new_handle(3);

	insert_after(&mut s,  &mut h1);
	insert_after(&mut h1, &mut h2);
	insert_after(&mut h2, &mut h3);

	assert_eq!(unsafe {&*s.next}, &*h1);
	assert_eq!(unsafe {&*h1.prev}, &*s);

	assert_eq!(unsafe {&*h1.next}, &*h2);
	assert_eq!(unsafe {&*h2.prev}, &*h1);

	assert_eq!(unsafe {&*h2.next}, &*h3);
	assert_eq!(unsafe {&*h3.prev}, &*h2);

	assert_eq!(unsafe {&*h3.next}, &*s);
	assert_eq!(unsafe {&*s.prev}, &*h3);

	unlink(h2);

	assert_eq!(unsafe {&*s.next}, &*h1);
	assert_eq!(unsafe {&*h1.prev}, &*s);

	assert_eq!(unsafe {&*h1.next}, &*h3);
	assert_eq!(unsafe {&*h3.prev}, &*h1);

	assert_eq!(unsafe {&*h3.next}, &*s);
	assert_eq!(unsafe {&*s.prev}, &*h3);

	let mut h2 = new_handle(2);
	insert_after(&mut h1, &mut h2);

	unlink(h1);
	assert_eq!(unsafe {&*s.next}, &*h2);
	unlink(h2);
	assert_eq!(unsafe {&*s.next}, &*h3);
	assert_eq!(unsafe {&*s.prev}, &*h3);
	assert_eq!(unsafe {&*h3.prev}, &*s);
	assert_eq!(unsafe {&*h3.next}, &*s);
	unlink(h3);
	assert_eq!(unsafe {&*s.prev}, &*s);
	assert_eq!(unsafe {&*s.next}, &*s);

	unlink(s);
}

#[cfg(test)]
#[test]
fn iter_test()
{
	let l = &mut List::new();
	let h1 = l.push_head(1);
	let h2 = l.push_tail(2);
	let h3 = l.push_tail(3);

	let mut i = l.iter();
	assert_eq!(Some(&1), i.next());
	assert_eq!(Some(&2), i.next());
	assert_eq!(Some(&3), i.next());
	assert_eq!(None, i.next());

    h1.unlink();
    h2.unlink();
    h3.unlink();
}

#[cfg(test)]
#[test]
fn iter_mut_test()
{
	let l = &mut List::new();
	let h1 = l.push_head(1);
	let h2 = l.push_tail(2);
	let h3 = l.push_tail(3);

	{
	let mut i = l.iter_mut();
	assert_eq!(Some(&mut 1), i.next());
	assert_eq!(Some(&mut 2), i.next());
	assert_eq!(Some(&mut 3), i.next());
	assert_eq!(None, i.next());
	}

	l.iter_mut().fold(3, |i, v| {
		*v = i;
		i - 1
	});

	{
	let mut i = l.iter_mut();
	assert_eq!(Some(&mut 3), i.next());
	assert_eq!(Some(&mut 2), i.next());
	assert_eq!(Some(&mut 1), i.next());
	assert_eq!(None, i.next());
	}

	assert_eq!(&3, h1.as_ref());
	assert_eq!(&2, h2.as_ref());
	assert_eq!(&1, h3.as_ref());
}
<commit_msg>Handle now is not Box but rather pure raw pointer, this allows to not destroy handle when binding is dropped, though I am not sure this is a good thing, need to think<commit_after>//! The `sentinel_list` crate provides a simple sentinel based list implementation.
//! Once you insert element to the list you are given back a handle into this list.
//! This handle allows you to remove element from the list in O(1) time.
//!
//! # Examples
//!
//! ```rust
//! extern crate sentinel_list;
//! use sentinel_list::*;
//!
//! fn main() {
//!	 let l = &mut List::new();
//!	 let h1 = l.push_head(1);
//!	 let h2 = l.push_tail(2);
//!	 let h3 = l.push_tail(3);
//!	 {
//!		assert_eq!(&1, (&h1).as_ref());
//!		assert_eq!(&1, l.peek_head().unwrap());
//!		assert_eq!(&3, l.peek_tail().unwrap());
//!	 }
//!	 let e1 = h1.unlink();
//!	 assert_eq!(&2, l.peek_head().unwrap());
//!	 let e3 = h3.unlink();
//!	 assert_eq!(&2, l.peek_tail().unwrap());
//!	 let e2 = h2.unlink();
//!	 assert_eq!(None, l.peek_tail());
//!	 assert_eq!(None, l.peek_head());
//!	 assert_eq!(1, e1);
//!	 assert_eq!(2, e2);
//!	 assert_eq!(3, e3);
//! }
//! ```

#![feature(conservative_impl_trait)]

use std::ptr;
use std::fmt;
use std::ops::{Deref, DerefMut};

pub trait ListHandle<T>
{
	fn unlink(self) -> T;
	fn as_ref(&self) -> &T;
}

pub struct Iter<'a, T: 'a>
{
	next: &'a Link<T>,
}

pub struct IterMut<'a, T: 'a>
{
	next: Option<&'a mut Link<T>>,
}

pub struct List<T>
{
	sentinel: Handle<T>,
}

#[derive(PartialEq)]
struct Link<T>
{
	pub next: *mut Link<T>,
	pub prev: *mut Link<T>,
	pub value: Option<T>,
}

struct Handle<T>(*mut Link<T>);

impl<T> List<T>
{
	pub fn new() -> Self
	{
		List {
			sentinel: Handle::new_sentinel(),
		}
	}

	pub fn push_head(&mut self, e: T) -> impl ListHandle<T>
	{
		let mut h = Handle::new(e);
		insert_after(&mut self.sentinel, &mut h);
		h
	}

	pub fn push_tail(&mut self, e: T) -> impl ListHandle<T>
	{
		let mut h = Handle::new(e);
		insert_after(unsafe {&mut *self.sentinel.prev}, &mut h);
		h
	}

	pub fn peek_head(&self) -> Option<&T>
	{
		let link = unsafe { &*self.sentinel.next };
		link.value.as_ref()
	}

	pub fn peek_head_mut(&mut self) -> Option<&mut T>
	{
		let link = unsafe { &mut *self.sentinel.next };
		link.value.as_mut()
	}

	pub fn peek_tail(&self) -> Option<&T>
	{
		let link = unsafe { &*self.sentinel.prev };
		link.value.as_ref()
	}

	pub fn peek_tail_mut(&mut self) -> Option<&mut T>
	{
		let link = unsafe { &mut *self.sentinel.prev };
		link.value.as_mut()
	}

	pub fn iter(&self) -> Iter<T>
	{
		Iter { next: unsafe {&*self.sentinel.next} }
	}

	pub fn iter_mut(&mut self) -> IterMut<T>
	{
		let next = Some(unsafe {&mut *self.sentinel.next});
		let inext = next.map(|v| {
			v
		});
		IterMut { next: inext }
	}
}

impl<'a, T> Iterator for Iter<'a, T>
{
	type Item = &'a T;

	fn next(&mut self) -> Option<Self::Item>
	{
		self.next.value.as_ref().and_then(|v| {
			self.next = unsafe {&*self.next.next};
			Some(v)
		})
	}
}

impl<'a, T> Iterator for IterMut<'a, T>
{
	type Item = &'a mut T;

	fn next(&mut self) -> Option<Self::Item>
	{
		self.next.take().and_then(|link| {
			self.next = Some(unsafe {&mut *link.next});
			link.value.as_mut().map(|v| {
				v
			})
		})
	}
}

impl<T> Link<T>
{
	fn new(v: T) -> Link<T>
	{
		Link {
			prev: ptr::null_mut(),
			next: ptr::null_mut(),
			value: Some(v),
		}
	}

    // just unlinks
    // after calling this it's unsafe to use
    // this Handle without adjusting prev, next
    fn unlink(&mut self)
    {
        let prev = unsafe { &mut *self.prev };
        let next = unsafe { &mut *self.next };
        next.prev = prev;
        prev.next = next;
    }

}
impl<T> Handle<T>
{
    fn new(v: T) -> Self
    {
	    Handle(Box::into_raw(Box::new(Link::new(v))))
    }

	fn new_sentinel() -> Self
	{
		let mut h = Box::new(
			Link {
				prev: ptr::null_mut(),
				next: ptr::null_mut(),
				value: None,
			}
		);
		h.prev = &mut *h;
		h.next = &mut *h;
		Handle(Box::into_raw(h))
	}

    fn into_inner(self) -> Option<T>
    {
        let mut h = self;
        let link = unsafe { &mut *h.0 };
        link.unlink();
        link.value.take()
    }
}

impl<T: fmt::Debug> fmt::Debug for Link<T>
{
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		write!(f, "Link {{ prev: {:p}, next: {:p}, value: {:?} }}", self.prev, self.next, self.value)
	}
}

impl<T> Drop for Handle<T>
{
    fn drop(&mut self)
    {
        let link = unsafe { &mut *self.0 };
        link.unlink();
        if !self.0.is_null() {
            let h = unsafe { Box::from_raw(self.0) };
            drop(h);
        }
        // not sure if this matters
        //println!("Drop");
    }
}

impl<T> ListHandle<T> for Handle<T>
{
	fn unlink(self) -> T
	{
		// if you call it on the sentinel
		// you deserve to get what's coming
		self.into_inner().unwrap()
	}

	fn as_ref(&self) -> &T
	{
		&self
	}
}

impl<T> Deref for Link<T>
{
	type Target = T;
	fn deref(&self) -> &Self::Target
	{
		// if you call it on the sentinel
		// you deserve to get what's coming
		self.value.as_ref().unwrap()
	}
}

impl<T> Deref for Handle<T>
{
	type Target = Link<T>;
	fn deref(&self) -> &Self::Target
	{
		unsafe {&*self.0}
	}
}

impl<T> DerefMut for Handle<T>
{
	fn deref_mut(&mut self) -> &mut Self::Target
	{
		unsafe {&mut *self.0}
	}
}

fn insert_after<T>(after: &mut Link<T>, h: &mut Link<T>)
{
	let n: *mut _ = after.next;

	h.prev = &mut *after;
	h.next = n;

	after.next = &mut *h;

	let n = unsafe { &mut *h.next };
	n.prev = &mut *h;
}

#[allow(dead_code)]
#[cfg(test)]
fn debug_print<T: fmt::Debug>(s: &mut Handle<T>)
{
	let mut h = s.next;
	while h != &mut **s {
		let n = unsafe { &*h };
		println!("{:?}", n);
		h = n.next;
	}
}

#[cfg(test)]
#[test]
fn link_unlink()
{
	let mut s = Handle::new_sentinel();
	let mut h1 = Handle::new(1);
	let mut h2 = Handle::new(2);
	let mut h3 = Handle::new(3);

	insert_after(&mut s,  &mut h1);
	insert_after(&mut h1, &mut h2);
	insert_after(&mut h2, &mut h3);

	assert_eq!(unsafe {&*s.next}, &*h1);
	assert_eq!(unsafe {&*h1.prev}, &*s);

	assert_eq!(unsafe {&*h1.next}, &*h2);
	assert_eq!(unsafe {&*h2.prev}, &*h1);

	assert_eq!(unsafe {&*h2.next}, &*h3);
	assert_eq!(unsafe {&*h3.prev}, &*h2);

	assert_eq!(unsafe {&*h3.next}, &*s);
	assert_eq!(unsafe {&*s.prev}, &*h3);

	h2.into_inner();

	assert_eq!(unsafe {&*s.next}, &*h1);
	assert_eq!(unsafe {&*h1.prev}, &*s);

	assert_eq!(unsafe {&*h1.next}, &*h3);
	assert_eq!(unsafe {&*h3.prev}, &*h1);

	assert_eq!(unsafe {&*h3.next}, &*s);
	assert_eq!(unsafe {&*s.prev}, &*h3);

	let mut h2 = Handle::new(2);
	insert_after(&mut h1, &mut h2);

	h1.into_inner();
	assert_eq!(unsafe {&*s.next}, &*h2);
	h2.into_inner();
	assert_eq!(unsafe {&*s.next}, &*h3);
	assert_eq!(unsafe {&*s.prev}, &*h3);
	assert_eq!(unsafe {&*h3.prev}, &*s);
	assert_eq!(unsafe {&*h3.next}, &*s);
	h3.into_inner();
	assert_eq!(unsafe {&*s.prev}, &*s);
	assert_eq!(unsafe {&*s.next}, &*s);

	s.into_inner();
}

#[cfg(test)]
#[test]
fn iter_test()
{
	let l = &mut List::new();
	let h1 = l.push_head(1);
    {
	let h2 = l.push_tail(2);
    }
    let h3 = l.push_tail(3);

	let mut i = l.iter();
	assert_eq!(Some(&1), i.next());
	//assert_eq!(Some(&2), i.next());
	assert_eq!(Some(&3), i.next());
	assert_eq!(None, i.next());

    h1.unlink();
    //h2.unlink();
    h3.unlink();
}

#[cfg(test)]
#[test]
fn iter_mut_test()
{
	let l = &mut List::new();
	let h1 = l.push_head(1);
	let h2 = l.push_tail(2);
	let h3 = l.push_tail(3);

	{
	let mut i = l.iter_mut();
	assert_eq!(Some(&mut 1), i.next());
	assert_eq!(Some(&mut 2), i.next());
	assert_eq!(Some(&mut 3), i.next());
	assert_eq!(None, i.next());
	}

	l.iter_mut().fold(3, |i, v| {
		*v = i;
		i - 1
	});

	{
	let mut i = l.iter_mut();
	assert_eq!(Some(&mut 3), i.next());
	assert_eq!(Some(&mut 2), i.next());
	assert_eq!(Some(&mut 1), i.next());
	assert_eq!(None, i.next());
	}

	assert_eq!(&3, h1.as_ref());
	assert_eq!(&2, h2.as_ref());
	assert_eq!(&1, h3.as_ref());
}

#[cfg(test)]
//#[test]
fn test_drop()
{
    let line = &mut String::new();

    std::io::stdin().read_line(line);

    let mut s = Handle::new_sentinel();
    let mut vec = vec![];

    for i in 1..100000 {
        let mut h = Handle::new(vec![0u32;1000]);
        insert_after(&mut s,  &mut h);
        vec.push(h);
    }

    std::io::stdin().read_line(line);

    while !vec.is_empty() {
        vec.pop().unwrap().into_inner();
    }

    std::io::stdin().read_line(line);
}
<|endoftext|>


<commit_before>//! A library to parse and load configuration files.
//!
//! This library parses and loads configuration files in much the same way as C/C++'s
//! [libconfig](http://www.hyperrealm.com/libconfig/). At this time, It can only read and load
//! configurations, but future plans include a much richer user API to allow other forms of
//! interaction, such as manipulating values, writing the current configuration to a file, etc.
//!
//!# Getting started
//!
//! A configuration file consists of a group of settings. A setting is a key/value pair, where the
//! key is a string of the form `[a-zA-Z][-a-zA-Z0-9_]*`, and the value is anything represented by
//! `types::Value`. In a configuration file, setting/value pairs are written as
//! `setting_name = value;`. Possible values include primitive integer and floating point types,
//! strings, arrays, lists, etc.
//!
//! The library provides a bunch of methods to read the configuration data in the `reader` module.
//! The possibilities include reading from a string, from a file, or from anything that implements
//! the `Read` trait.
//!
//! As of now, every reader will first attempt to read the whole configuration into memory,
//! and only begins parsing once everything was read.
//!
//! In case of error, the parser returns a `config::error`.
//! On success, the parser returns a `Config`, which can then be used to browse the loaded data.
//!
//! Browsing is typically done with the `lookup_*` methods implemented by `Config`. The `lookup`
//! methods work with *paths*. Essentially, a path unambiguously describes the location of
//! a setting.
//!
//! For example, consider this input configuration file:
//!
//!```ignore
//! title = "My HTTP server";
//! listen_ports = [ 80, 443 ];
//! misc = {
//!     owner = "Chuck Norris";
//!     location = "CA";
//!     contact = {
//!         phone = "415-256-9999";
//!         // This is an array. Arrays start with `[` and end with `]`
//!         // Arrays are homogeneous and can only hold scalar data types.
//!         // See types::ScalarValue for further information
//!         emails = ["chuck@norris.com", "chuck.norris@gmail.com"];
//!     };
//! };
//!```
//!
//! At the top level, we have 3 settings: `title`, `listen_ports` and `misc`. `misc` is itself a
//! group of settings. Each value in this configuration is reachable by a unique path of settings
//! to follow. Each setting in a path is separated by `.`
//!
//! **Example**: The path `misc.contact.phone` identifies the setting with value `415-256-9999`.
//!
//! Array and list types are indexed using `[i]` in a path.
//!
//! **Example**: The path `listen_ports.[1]` identifies the setting with value `443`.
//!
//! **Example**: The path `misc.contact.emails.[0]` identifies the setting with value
//! `chuck@norris.com`
//!
//! Lists, as opposed to arrays, are heterogeneous and can store any data type, including other
//! lists. Here's a setting consisting of a heterogeneous list:
//!
//!```ignore
//! // This is a list. Lists start with `(` and end with `)`
//! // Lists are heterogeneous and can store any data type, including other lists
//! a_setting = ("a string", // The first element is a string
//!              ((1, 2, 3)), // The 2nd element is a list storing a list of 3 integers
//!              misc = { x = 4; y = 3; } // 3rd element: a group
//!             );
//!```
//!
//! Here are some valid paths for this example:
//!
//! `a_setting.[0]` - returns the string `a string`
//!
//! `a_setting.[1].[0].[2]` - returns the integer `3`
//!
//! `a_setting.[2].misc.x` - returns the integer `4`
//!
//! Adjacent string literals separated by whitespace, newlines and / or comments are automatically
//! concatenated.
//!
//! **Example**:
//!
//! ```ignore
//! "a"/* a comment */" string"    " liter"
//!
//! // This is a commment
//!
//!    "al"
//! ```
//!
//! is equivalent to:
//!
//! ```ignore
//! "a string literal"
//! ```
//!
//! See the integration tests (in the `tests/` directory) for sample use cases and more complex
//! examples.
//!
//!# Grammar
//!
//! This section describes the configuration input format. The starting rule is `conf`.
//!
//! ```text
//! conf -> __ settings_list __
//!
//! settings_list -> // empty
//!                | setting settings_list
//! setting -> __ name __ (":"|"=") __ value __ ";" __
//!
//! name -> [a-zA-Z][-a-zA-Z0-9_]*
//!
//! value -> scalar_value
//!        | array_value
//!        | list_value
//!        | group_value
//!
//! scalar_value -> boolean_scalar_value
//!               | floating64_scalar_value
//!               | floating32_scalar_value
//!               | integer64_scalar_value
//!               | integer32_scalar_value
//!               | str_scalar_value
//!
//! boolean_scalar_value -> [Tt][Rr][Uu][Ee]
//!                       | [Yy][Ee][Ss]
//!                       | [Ff][Aa][Ll][Ss][Ee]
//!                       | [Nn][Oo]
//!
//! floating64_scalar_value -> [+-]?([0-9]+\.[0-9]*|\.[0-9]+)([eE][+-]?[0-9]+)?"L"
//!
//! floating32_scalar_value -> [+-]?([0-9]+\.[0-9]*|\.[0-9]+)([eE][+-]?[0-9]+)?
//!
//! integer32_scalar_value -> [+-]?[0-9]+
//!
//! integer64_scalar_value -> [+-]?[0-9]+"L"
//!
//! str_scalar_value -> __ str_literal __
//!                   | __ str_literal __ str_scalar_value
//!
//! str_literal -> "\"" ([^\"\\]|(("\\r"|"\\n"|"\\t"|"\\\""|"\\\\")))* "\""
//!
//! array_value -> "["
//!                (bool_array |
//!                 flt64_array | flt32_array |
//!                 int64_array | int32_array |
//!                 str_array)
//!                "]"
//!              | "[" __ "]"
//!
//! bool_array -> __ boolean_scalar_value __
//!             | __ boolean_scalar_value __ "," __ bool_array
//!
//! flt64_array -> __ floating64_scalar_value __
//!              | __ floating64_scalar_value __ "," __ flt64_array
//!
//! flt32_array -> __ floating32_scalar_value __
//!              | __ floating32_scalar_value __ "," __ flt32_array
//
//! int64_array -> __ integer64_scalar_value __
//!              | __ integer64_scalar_value __ "," __ int64_array
//!
//! int32_array -> __ integer32_scalar_value __
//!              | __ integer32_scalar_value __ "," __ int32_array
//!
//! str_array -> __ str_scalar_value __
//!            | __ str_scalar_value __ "," __ str_array
//!
//! list_value -> "(" __ ")"
//!             | "(" list_elements ")"
//!
//! list_elements -> __ value __
//!                | __ value __ "," __ list_elements
//!
//! group_value -> "{" settings_list "}"
//!
//! __ -> // empty
//!     | whitespace __
//!     | eol __
//!     | comment __
//!
//! whitespace -> [\s\t]
//!
//! eol -> "\r\n"
//!      | "\n"
//!
//! comment -> single_line_comment
//!          | multi_line_comment
//!
//! single_line_comment -> ("//"|"#")[^\n]*"\n"
//!
//! multi_line_comment -> "/*"([^*]|"*"[^/])*"*/"
//!
//! ```
//!

#![crate_name = "config"]
#![crate_type = "lib"]
#![warn(missing_docs)]

#[macro_use]
extern crate nom;

mod parser;

pub mod types;
pub mod error;
pub mod reader;
<commit_msg>Updated docs<commit_after>//! A library to parse and load configuration files.
//!
//! This library parses and loads configuration files in much the same way as C/C++'s
//! [libconfig](http://www.hyperrealm.com/libconfig/). At this time, it can only read and load
//! configurations, but future plans include a much richer user API to allow other forms of
//! interaction, such as manipulating values, writing the current configuration to a file, etc.
//!
//!# Getting started
//!
//! A configuration file consists of a group of settings. A setting is a key/value pair, where the
//! key is a string of the form `[a-zA-Z][-a-zA-Z0-9_]*`, and the value is anything represented by
//! `types::Value`. In a configuration file, setting/value pairs are written as
//! `setting_name = value;`. Possible values include primitive integer and floating point types,
//! strings, arrays, lists, etc.
//!
//! The library provides a bunch of methods to read the configuration data in the `reader` module.
//! The possibilities include reading from a string, from a file, or from anything that implements
//! the `Read` trait.
//!
//! As of now, every reader will first attempt to read the whole configuration into memory,
//! and only begins parsing once everything was read.
//!
//! In case of error, the parser returns a `config::error`.
//! On success, the parser returns a `Config`, which can then be used to browse the loaded data.
//!
//! Browsing is typically done with the `lookup_*` methods implemented by `Config`. The `lookup`
//! methods work with *paths*. Essentially, a path unambiguously describes the location of
//! a setting.
//!
//! For example, consider this input configuration file:
//!
//!```ignore
//! title = "My HTTP server";
//! listen_ports = [ 80, 443 ];
//! misc = {
//!     owner = "Chuck Norris";
//!     location = "CA";
//!     contact = {
//!         phone = "415-256-9999";
//!         // This is an array. Arrays start with `[` and end with `]`
//!         // Arrays are homogeneous and can only hold scalar data types.
//!         // See types::ScalarValue for further information
//!         emails = ["chuck@norris.com", "chuck.norris@gmail.com"];
//!     };
//! };
//!```
//!
//! At the top level, we have 3 settings: `title`, `listen_ports` and `misc`. `misc` is itself a
//! group of settings. Each value in this configuration is reachable by a unique path of settings
//! to follow. Each setting in a path is separated by `.`
//!
//! **Example**: The path `misc.contact.phone` identifies the setting with value `415-256-9999`.
//!
//! Array and list types are indexed using `[i]` in a path.
//!
//! **Example**: The path `listen_ports.[1]` identifies the setting with value `443`.
//!
//! **Example**: The path `misc.contact.emails.[0]` identifies the setting with value
//! `chuck@norris.com`
//!
//! Lists, as opposed to arrays, are heterogeneous and can store any data type, including other
//! lists. Here's a setting consisting of a heterogeneous list:
//!
//!```ignore
//! // This is a list. Lists start with `(` and end with `)`
//! // Lists are heterogeneous and can store any data type, including other lists
//! a_setting = ("a string", // The first element is a string
//!              ((1, 2, 3)), // The 2nd element is a list storing a list of 3 integers
//!              misc = { x = 4; y = 3; } // 3rd element: a group
//!             );
//!```
//!
//! Here are some valid paths for this example:
//!
//! `a_setting.[0]` - returns the string `a string`
//!
//! `a_setting.[1].[0].[2]` - returns the integer `3`
//!
//! `a_setting.[2].misc.x` - returns the integer `4`
//!
//! Adjacent string literals separated by whitespace, newlines and / or comments are automatically
//! concatenated.
//!
//! **Example**:
//!
//! ```ignore
//! "a"/* a comment */" string"    " liter"
//!
//! // This is a commment
//!
//!    "al"
//! ```
//!
//! is equivalent to:
//!
//! ```ignore
//! "a string literal"
//! ```
//!
//! See the integration tests (in the `tests/` directory) for sample use cases and more complex
//! examples.
//!
//!# Grammar
//!
//! This section describes the configuration input format. The starting rule is `conf`.
//!
//! ```text
//! conf -> __ settings_list __
//!
//! settings_list -> // empty
//!                | setting settings_list
//! setting -> __ name __ (":"|"=") __ value __ ";" __
//!
//! name -> [a-zA-Z][-a-zA-Z0-9_]*
//!
//! value -> scalar_value
//!        | array_value
//!        | list_value
//!        | group_value
//!
//! scalar_value -> boolean_scalar_value
//!               | floating64_scalar_value
//!               | floating32_scalar_value
//!               | integer64_scalar_value
//!               | integer32_scalar_value
//!               | str_scalar_value
//!
//! boolean_scalar_value -> [Tt][Rr][Uu][Ee]
//!                       | [Yy][Ee][Ss]
//!                       | [Ff][Aa][Ll][Ss][Ee]
//!                       | [Nn][Oo]
//!
//! floating64_scalar_value -> [+-]?([0-9]+\.[0-9]*|\.[0-9]+)([eE][+-]?[0-9]+)?"L"
//!
//! floating32_scalar_value -> [+-]?([0-9]+\.[0-9]*|\.[0-9]+)([eE][+-]?[0-9]+)?
//!
//! integer32_scalar_value -> [+-]?[0-9]+
//!
//! integer64_scalar_value -> [+-]?[0-9]+"L"
//!
//! str_scalar_value -> __ str_literal __
//!                   | __ str_literal __ str_scalar_value
//!
//! str_literal -> "\"" ([^\"\\]|(("\\r"|"\\n"|"\\t"|"\\\""|"\\\\")))* "\""
//!
//! array_value -> "["
//!                (bool_array |
//!                 flt64_array | flt32_array |
//!                 int64_array | int32_array |
//!                 str_array)
//!                "]"
//!              | "[" __ "]"
//!
//! bool_array -> __ boolean_scalar_value __
//!             | __ boolean_scalar_value __ "," __ bool_array
//!
//! flt64_array -> __ floating64_scalar_value __
//!              | __ floating64_scalar_value __ "," __ flt64_array
//!
//! flt32_array -> __ floating32_scalar_value __
//!              | __ floating32_scalar_value __ "," __ flt32_array
//
//! int64_array -> __ integer64_scalar_value __
//!              | __ integer64_scalar_value __ "," __ int64_array
//!
//! int32_array -> __ integer32_scalar_value __
//!              | __ integer32_scalar_value __ "," __ int32_array
//!
//! str_array -> __ str_scalar_value __
//!            | __ str_scalar_value __ "," __ str_array
//!
//! list_value -> "(" __ ")"
//!             | "(" list_elements ")"
//!
//! list_elements -> __ value __
//!                | __ value __ "," __ list_elements
//!
//! group_value -> "{" settings_list "}"
//!
//! __ -> // empty
//!     | whitespace __
//!     | eol __
//!     | comment __
//!
//! whitespace -> [\s\t]
//!
//! eol -> "\r\n"
//!      | "\n"
//!
//! comment -> single_line_comment
//!          | multi_line_comment
//!
//! single_line_comment -> ("//"|"#")[^\n]*"\n"?
//!
//! multi_line_comment -> "/*"([^*]|"*"[^/])*"*/"
//!
//! ```
//!

#![crate_name = "config"]
#![crate_type = "lib"]
#![warn(missing_docs)]

#[macro_use]
extern crate nom;

mod parser;

pub mod types;
pub mod error;
pub mod reader;
<|endoftext|>


<commit_before>//! A formatted and aligned table printer written in rust
extern crate unicode_width;
extern crate term;

use std::io::{Write, Error};
use std::fmt;
use std::iter::{FromIterator, IntoIterator};
use std::ops::{Index, IndexMut};

use term::{Terminal, stdout};

pub mod cell;
pub mod row;
pub mod format;
mod utils;

use row::Row;
use cell::Cell;
use format::{TableFormat, FORMAT_DEFAULT};
use utils::StringWriter;

/// A Struct representing a printable table
#[derive(Clone, Debug)]
pub struct Table {
	format: TableFormat,
	titles: Option<Row>,
	rows: Vec<Row>
}

impl Table {
	/// Create an empty table
	pub fn new() -> Table {
		return Self::init(Vec::new());
	}

	/// Create a table initialized with `rows`
	pub fn init(rows: Vec<Row>) -> Table {
		return Table {
			rows: rows,
			titles: None,
			format: FORMAT_DEFAULT
		};
	}

	/// Change separators the table format
	pub fn set_format(&mut self, format: TableFormat) {
		self.format = format;
	}

	/// Compute and return the number of column
	pub fn get_column_num(&self) -> usize {
		let mut cnum = 0;
		for r in &self.rows {
			let l = r.len();
			if l > cnum {
				cnum = l;
			}
		}
		return cnum;
	}

	/// Get the number of rows
	pub fn len(&self) -> usize {
		return self.rows.len();
	}

	/// Set the optional title lines
	pub fn set_titles(&mut self, titles: Row) {
		self.titles = Some(titles);
	}

	/// Unset the title line
	pub fn unset_titles(&mut self) {
		self.titles = None;
	}

	/// Get a mutable reference to a row
	pub fn get_mut_row(&mut self, row: usize) -> Option<&mut Row> {
		return self.rows.get_mut(row);
	}

	/// Get an immutable reference to a row
	pub fn get_row(&self, row: usize) -> Option<&Row> {
		return self.rows.get(row);
	}

	/// Append a row in the table, transferring ownership of this row to the table
	/// and returning a mutable reference to the row
	pub fn add_row(&mut self, row: Row) -> &mut Row {
		self.rows.push(row);
		let l = self.rows.len()-1;
		return &mut self.rows[l];
	}

	/// Append an empty row in the table. Return a mutable reference to this new row.
	pub fn add_empty_row(&mut self) -> &mut Row {
		return self.add_row(Row::default());
	}

	/// Insert `row` at the position `index`, and return a mutable reference to this row.
	/// If index is higher than current numbers of rows, `row` is appended at the end of the table
	pub fn insert_row(&mut self, index: usize, row: Row) -> &mut Row {
		if index < self.rows.len() {
			self.rows.insert(index, row);
			return &mut self.rows[index];
		} else {
			return self.add_row(row);
		}
	}

	/// Modify a single element in the table
	pub fn set_element(&mut self, element: &str, column: usize, row: usize) -> Result<(), &str> {
		let rowline = try!(self.get_mut_row(row).ok_or("Cannot find row"));
		// TODO : If a cell already exist, copy it's alignment parameter
		return rowline.set_cell(Cell::new(element), column);
	}

	/// Remove the row at position `index`. Silently skip if the row does not exist
	pub fn remove_row(&mut self, index: usize) {
		if index < self.rows.len() {
			self.rows.remove(index);
		}
	}

	/// Get the width of the column at position `col_idx`.
	/// Return 0 if the column does not exists;
	pub fn get_column_width(&self, col_idx: usize) -> usize {
		let mut width = match self.titles {
			Some(ref t) => t.get_cell_width(col_idx),
			None => 0
		};
		for r in &self.rows {
			let l = r.get_cell_width(col_idx);
			if l > width {
				width = l;
			}
		}
		return width;
	}

	/// Get the width of all columns, and return a slice
	/// with the result for each column
	pub fn get_all_column_width(&self) -> Vec<usize> {
		let colnum = self.get_column_num();
		let mut col_width = vec![0usize; colnum];
		for i in 0..colnum {
			col_width[i] = self.get_column_width(i);
		}
		return col_width;
	}

	/// Return an iterator over the immutable cells of the column specified by `column`
	pub fn column_iter(&self, column: usize) -> ColumnIter {
		return ColumnIter(self.rows.iter(), column);
	}

	/// Return an iterator over the mutable cells of the column specified by `column`
	pub fn column_iter_mut(&mut self, column: usize) -> ColumnIterMut {
		return ColumnIterMut(self.rows.iter_mut(), column);
	}

	/// Internal only
	fn __print<T: Write+?Sized, F>(&self, out: &mut T, f: F) -> Result<(), Error> where F: Fn(&Row, &mut T, &TableFormat, &[usize]) -> Result<(), Error> {
		// Compute columns width
		let col_width = self.get_all_column_width();
		try!(self.format.print_line_separator(out, &col_width));
		if let Some(ref t) = self.titles {
			try!(f(t, out, &self.format, &col_width));
			try!(self.format.print_title_separator(out, &col_width));
		}
		// Print rows
		for r in &self.rows {
			try!(f(r, out, &self.format, &col_width));
			try!(self.format.print_line_separator(out, &col_width));
		}
		return out.flush();
	}

	/// Print the table to `out`
	pub fn print<T: Write+?Sized>(&self, out: &mut T) -> Result<(), Error> {
		return self.__print(out, Row::print);
	}

	/// Print the table to terminal `out`, applying styles when needed
	pub fn print_term<T: Terminal+?Sized>(&self, out: &mut T) -> Result<(), Error> {
		return self.__print(out, Row::print_term);
	}

	/// Print the table to standard output
	/// # Panic
	/// Panic if writing to standard output fails
	pub fn printstd(&self) {
		self.print_term(&mut *stdout().unwrap())
			.ok()
			.expect("Cannot print table to standard output");
	}
}

impl Index<usize> for Table {
	type Output = Row;
	fn index(&self, idx: usize) -> &Self::Output {
		return &self.rows[idx];
	}
}

impl IndexMut<usize> for Table {
	fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
		return &mut self.rows[idx];
	}
}

impl fmt::Display for Table {
	fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
		let mut writer = StringWriter::new();
		if let Err(_) = self.print(&mut writer) {
			return Err(fmt::Error)
		}
		return fmt.write_str(writer.as_string());
	}
}

impl <B: ToString, A: IntoIterator<Item=B>> FromIterator<A> for Table {
	fn from_iter<T>(iterator: T) -> Table where T: IntoIterator<Item=A> {
		return Self::init(iterator.into_iter().map(|r| Row::from(r)).collect());
	}
}

impl <T, A, B> From<T> for Table where B: ToString, A: IntoIterator<Item=B>, T : IntoIterator<Item=A> {
	fn from(it: T) -> Table {
		return Self::from_iter(it);
	}
}

/// Iterator over immutable cells in a column
pub struct ColumnIter<'a>(std::slice::Iter<'a, Row>, usize);

impl <'a> std::iter::Iterator for ColumnIter<'a> {
	type Item = &'a Cell;

	fn next(&mut self) -> Option<&'a Cell> {
		return match self.0.next() {
			None => None,
			Some(row) => row.get_cell(self.1)
		}
	}
}

/// Iterator over mutable cells in a column
pub struct ColumnIterMut<'a>(std::slice::IterMut<'a, Row>, usize);

impl <'a> std::iter::Iterator for ColumnIterMut<'a> {
	type Item = &'a mut Cell;

	fn next(&mut self) -> Option<&'a mut Cell> {
		return match self.0.next() {
			None => None,
			Some(row) => row.get_mut_cell(self.1)
		}
	}
}

/// Create a table filled with some values
///
/// All the arguments used for elements must implement the `std::string::ToString` trait
/// # Syntax
/// ```text
/// table!([Element1_ row1, Element2_ row1, ...], [Element1_row2, ...], ...);
/// ```
///
/// # Example
/// ```
/// # #[macro_use] extern crate prettytable;
/// # fn main() {
/// // Create a table initialized with some rows :
/// let tab = table!(["Element1", "Element2", "Element3"],
/// 				 [1, 2, 3],
/// 				 ["A", "B", "C"]
/// 				 );
/// # drop(tab);
/// # }
/// ```
///
/// Some style can also be given in table creation
///
/// ```
/// # #[macro_use] extern crate prettytable;
/// # fn main() {
/// let tab = table!([FrByl:"Element1", Fgc:"Element2", "Element3"],
/// 				 [FrBy -> 1, 2, 3],
/// 				 ["A", "B", "C"]
/// 				 );
/// # drop(tab);
/// # }
/// ```
///
/// For details about style specifier syntax, check doc for [Cell::style_spec](cell/struct.Cell.html#method.style_spec) method
#[macro_export]
macro_rules! table {
	($([$($content:tt)*]), *) => (
		$crate::Table::init(vec![$(row![$($content)*]), *])
	);
}

/// Create a table with `table!` macro, print it to standard output, then return this table for future usage.
///
/// The syntax is the same that the one for the `table!` macro
#[macro_export]
macro_rules! ptable {
	($($content:tt)*) => (
		{
			let tab = table!($($content)*);
			tab.printstd();
			tab
		}
	);
}
<commit_msg>Added unittest on tables<commit_after>//! A formatted and aligned table printer written in rust
extern crate unicode_width;
extern crate term;

use std::io::{Write, Error};
use std::fmt;
use std::iter::{FromIterator, IntoIterator};
use std::ops::{Index, IndexMut};

use term::{Terminal, stdout};

pub mod cell;
pub mod row;
pub mod format;
mod utils;

use row::Row;
use cell::Cell;
use format::{TableFormat, FORMAT_DEFAULT};
use utils::StringWriter;

/// A Struct representing a printable table
#[derive(Clone, Debug)]
pub struct Table {
	format: TableFormat,
	titles: Option<Row>,
	rows: Vec<Row>
}

impl Table {
	/// Create an empty table
	pub fn new() -> Table {
		return Self::init(Vec::new());
	}

	/// Create a table initialized with `rows`
	pub fn init(rows: Vec<Row>) -> Table {
		return Table {
			rows: rows,
			titles: None,
			format: FORMAT_DEFAULT
		};
	}

	/// Change separators the table format
	pub fn set_format(&mut self, format: TableFormat) {
		self.format = format;
	}

	/// Compute and return the number of column
	pub fn get_column_num(&self) -> usize {
		let mut cnum = 0;
		for r in &self.rows {
			let l = r.len();
			if l > cnum {
				cnum = l;
			}
		}
		return cnum;
	}

	/// Get the number of rows
	pub fn len(&self) -> usize {
		return self.rows.len();
	}

	/// Set the optional title lines
	pub fn set_titles(&mut self, titles: Row) {
		self.titles = Some(titles);
	}

	/// Unset the title line
	pub fn unset_titles(&mut self) {
		self.titles = None;
	}

	/// Get a mutable reference to a row
	pub fn get_mut_row(&mut self, row: usize) -> Option<&mut Row> {
		return self.rows.get_mut(row);
	}

	/// Get an immutable reference to a row
	pub fn get_row(&self, row: usize) -> Option<&Row> {
		return self.rows.get(row);
	}

	/// Append a row in the table, transferring ownership of this row to the table
	/// and returning a mutable reference to the row
	pub fn add_row(&mut self, row: Row) -> &mut Row {
		self.rows.push(row);
		let l = self.rows.len()-1;
		return &mut self.rows[l];
	}

	/// Append an empty row in the table. Return a mutable reference to this new row.
	pub fn add_empty_row(&mut self) -> &mut Row {
		return self.add_row(Row::default());
	}

	/// Insert `row` at the position `index`, and return a mutable reference to this row.
	/// If index is higher than current numbers of rows, `row` is appended at the end of the table
	pub fn insert_row(&mut self, index: usize, row: Row) -> &mut Row {
		if index < self.rows.len() {
			self.rows.insert(index, row);
			return &mut self.rows[index];
		} else {
			return self.add_row(row);
		}
	}

	/// Modify a single element in the table
	pub fn set_element(&mut self, element: &str, column: usize, row: usize) -> Result<(), &str> {
		let rowline = try!(self.get_mut_row(row).ok_or("Cannot find row"));
		// TODO : If a cell already exist, copy it's alignment parameter
		return rowline.set_cell(Cell::new(element), column);
	}

	/// Remove the row at position `index`. Silently skip if the row does not exist
	pub fn remove_row(&mut self, index: usize) {
		if index < self.rows.len() {
			self.rows.remove(index);
		}
	}

	/// Get the width of the column at position `col_idx`.
	/// Return 0 if the column does not exists;
	pub fn get_column_width(&self, col_idx: usize) -> usize {
		let mut width = match self.titles {
			Some(ref t) => t.get_cell_width(col_idx),
			None => 0
		};
		for r in &self.rows {
			let l = r.get_cell_width(col_idx);
			if l > width {
				width = l;
			}
		}
		return width;
	}

	/// Get the width of all columns, and return a slice
	/// with the result for each column
	pub fn get_all_column_width(&self) -> Vec<usize> {
		let colnum = self.get_column_num();
		let mut col_width = vec![0usize; colnum];
		for i in 0..colnum {
			col_width[i] = self.get_column_width(i);
		}
		return col_width;
	}

	/// Return an iterator over the immutable cells of the column specified by `column`
	pub fn column_iter(&self, column: usize) -> ColumnIter {
		return ColumnIter(self.rows.iter(), column);
	}

	/// Return an iterator over the mutable cells of the column specified by `column`
	pub fn column_iter_mut(&mut self, column: usize) -> ColumnIterMut {
		return ColumnIterMut(self.rows.iter_mut(), column);
	}

	/// Internal only
	fn __print<T: Write+?Sized, F>(&self, out: &mut T, f: F) -> Result<(), Error> where F: Fn(&Row, &mut T, &TableFormat, &[usize]) -> Result<(), Error> {
		// Compute columns width
		let col_width = self.get_all_column_width();
		try!(self.format.print_line_separator(out, &col_width));
		if let Some(ref t) = self.titles {
			try!(f(t, out, &self.format, &col_width));
			try!(self.format.print_title_separator(out, &col_width));
		}
		// Print rows
		for r in &self.rows {
			try!(f(r, out, &self.format, &col_width));
			try!(self.format.print_line_separator(out, &col_width));
		}
		return out.flush();
	}

	/// Print the table to `out`
	pub fn print<T: Write+?Sized>(&self, out: &mut T) -> Result<(), Error> {
		return self.__print(out, Row::print);
	}

	/// Print the table to terminal `out`, applying styles when needed
	pub fn print_term<T: Terminal+?Sized>(&self, out: &mut T) -> Result<(), Error> {
		return self.__print(out, Row::print_term);
	}

	/// Print the table to standard output
	/// # Panic
	/// Panic if writing to standard output fails
	pub fn printstd(&self) {
		self.print_term(&mut *stdout().unwrap())
			.ok()
			.expect("Cannot print table to standard output");
	}
}

impl Index<usize> for Table {
	type Output = Row;
	fn index(&self, idx: usize) -> &Self::Output {
		return &self.rows[idx];
	}
}

impl IndexMut<usize> for Table {
	fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
		return &mut self.rows[idx];
	}
}

impl fmt::Display for Table {
	fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
		let mut writer = StringWriter::new();
		if let Err(_) = self.print(&mut writer) {
			return Err(fmt::Error)
		}
		return fmt.write_str(writer.as_string());
	}
}

impl <B: ToString, A: IntoIterator<Item=B>> FromIterator<A> for Table {
	fn from_iter<T>(iterator: T) -> Table where T: IntoIterator<Item=A> {
		return Self::init(iterator.into_iter().map(|r| Row::from(r)).collect());
	}
}

impl <T, A, B> From<T> for Table where B: ToString, A: IntoIterator<Item=B>, T : IntoIterator<Item=A> {
	fn from(it: T) -> Table {
		return Self::from_iter(it);
	}
}

/// Iterator over immutable cells in a column
pub struct ColumnIter<'a>(std::slice::Iter<'a, Row>, usize);

impl <'a> std::iter::Iterator for ColumnIter<'a> {
	type Item = &'a Cell;

	fn next(&mut self) -> Option<&'a Cell> {
		return match self.0.next() {
			None => None,
			Some(row) => row.get_cell(self.1)
		}
	}
}

/// Iterator over mutable cells in a column
pub struct ColumnIterMut<'a>(std::slice::IterMut<'a, Row>, usize);

impl <'a> std::iter::Iterator for ColumnIterMut<'a> {
	type Item = &'a mut Cell;

	fn next(&mut self) -> Option<&'a mut Cell> {
		return match self.0.next() {
			None => None,
			Some(row) => row.get_mut_cell(self.1)
		}
	}
}

/// Create a table filled with some values
///
/// All the arguments used for elements must implement the `std::string::ToString` trait
/// # Syntax
/// ```text
/// table!([Element1_ row1, Element2_ row1, ...], [Element1_row2, ...], ...);
/// ```
///
/// # Example
/// ```
/// # #[macro_use] extern crate prettytable;
/// # fn main() {
/// // Create a table initialized with some rows :
/// let tab = table!(["Element1", "Element2", "Element3"],
/// 				 [1, 2, 3],
/// 				 ["A", "B", "C"]
/// 				 );
/// # drop(tab);
/// # }
/// ```
///
/// Some style can also be given in table creation
///
/// ```
/// # #[macro_use] extern crate prettytable;
/// # fn main() {
/// let tab = table!([FrByl:"Element1", Fgc:"Element2", "Element3"],
/// 				 [FrBy -> 1, 2, 3],
/// 				 ["A", "B", "C"]
/// 				 );
/// # drop(tab);
/// # }
/// ```
///
/// For details about style specifier syntax, check doc for [Cell::style_spec](cell/struct.Cell.html#method.style_spec) method
#[macro_export]
macro_rules! table {
	($([$($content:tt)*]), *) => (
		$crate::Table::init(vec![$(row![$($content)*]), *])
	);
}

/// Create a table with `table!` macro, print it to standard output, then return this table for future usage.
///
/// The syntax is the same that the one for the `table!` macro
#[macro_export]
macro_rules! ptable {
	($($content:tt)*) => (
		{
			let tab = table!($($content)*);
			tab.printstd();
			tab
		}
	);
}

#[cfg(test)]
mod tests {

	use Table;
	use row::Row;
	use cell::Cell;

	#[test]
	fn table() {
		let mut table = Table::new();
		table.add_row(Row::new(vec![Cell::new("a"), Cell::new("bc"), Cell::new("def")]));
		table.add_row(Row::new(vec![Cell::new("def"), Cell::new("bc"), Cell::new("a")]));
		table.set_titles(Row::new(vec![Cell::new("t1"), Cell::new("t2"), Cell::new("t3")]));
		let out = "\
+-----+----+-----+
| t1  | t2 | t3  |
+=====+====+=====+
| a   | bc | def |
+-----+----+-----+
| def | bc | a   |
+-----+----+-----+
";
		assert_eq!(table.to_string().replace("\r\n", "\n"), out);
	}
}
<|endoftext|>