<commit_before>// Copyright (c) 2017-2019 Rene van der Meer
//
// 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.

//! Miscellaneous `embedded-hal` trait implementations.
//!
//! The `hal` module consists of a collection of `embedded-hal` trait
//! implementations for traits that aren't tied to a specific peripheral.
//!
//! This module is only included when either the `hal` or `hal-unproven` feature
//! flag is enabled.

use std::thread;
use std::time::{Duration, Instant};

use embedded_hal::blocking::delay::{DelayMs, DelayUs};
use embedded_hal::timer::CountDown;
use void::Void;

/// Implements the `embedded-hal` `DelayMs` and `DelayUs` traits.
#[derive(Debug, Default)]
pub struct Delay {}

impl Delay {
    /// Constructs a new `Delay`.
    pub fn new() -> Delay {
        Delay {}
    }
}

impl DelayMs<u8> for Delay {
    fn delay_ms(&mut self, ms: u8) {
        thread::sleep(Duration::from_millis(u64::from(ms)));
    }
}

impl DelayMs<u16> for Delay {
    fn delay_ms(&mut self, ms: u16) {
        thread::sleep(Duration::from_millis(u64::from(ms)));
    }
}

impl DelayMs<u32> for Delay {
    fn delay_ms(&mut self, ms: u32) {
        thread::sleep(Duration::from_millis(u64::from(ms)));
    }
}

impl DelayMs<u64> for Delay {
    fn delay_ms(&mut self, ms: u64) {
        thread::sleep(Duration::from_millis(ms));
    }
}

impl DelayUs<u8> for Delay {
    fn delay_us(&mut self, us: u8) {
        thread::sleep(Duration::from_micros(u64::from(us)));
    }
}

impl DelayUs<u16> for Delay {
    fn delay_us(&mut self, us: u16) {
        thread::sleep(Duration::from_micros(u64::from(us)));
    }
}

impl DelayUs<u32> for Delay {
    fn delay_us(&mut self, us: u32) {
        thread::sleep(Duration::from_micros(u64::from(us)));
    }
}

impl DelayUs<u64> for Delay {
    fn delay_us(&mut self, us: u64) {
        thread::sleep(Duration::from_micros(us));
    }
}

/// Implements the `embedded-hal` `CountDown` trait.
#[derive(Debug, Default, Copy, Clone)]
pub struct Timer {
    now: Instant,
    duration: Duration,
}

impl Timer {
    /// Constructs a new `Timer`.
    pub fn new() -> Self {
        Self {
            now: Instant::now(),
            duration: Duration::from_micros(0),
        }
    }
}

pub struct Millisecond(pub u64);
pub struct Microsecond(pub u64);
pub struct Second(pub u64);

impl From<Millisecond> for Microsecond {
    fn from(item: Millisecond) -> Self {
        Microsecond(item.0 * 1_000)
    }
}

impl From<Second> for Microsecond {
    fn from(item: Second) -> Self {
        Microsecond(item.0 * 1_000_000)
    }
}

impl Microsecond {
    fn as_u64(&self) -> u64 {
        let &Microsecond(t) = self;
        t
    }
}

impl CountDown for Timer {
    type Time = Microsecond;

    /// Start the timer with a `timeout`
    fn start<T>(&mut self, timeout: T)
    where
        T: Into<Microsecond>,
    {
        self.duration = Duration::from_micros(timeout.into().as_u64());
        self.now = Instant::now();
    }

    /// Return `Ok` if the timer has wrapped
    /// Automatically clears the flag and restarts the time
    fn wait(&mut self) -> nb::Result<(), Void> {
        if self.now.elapsed() >= self.duration {
            let duration = Duration::from_micros(1);
            thread::sleep(duration);
            Ok(())
        } else {
            Err(nb::Error::WouldBlock)
        }
    }
}
<commit_msg>Remove 1 µs sleep<commit_after>// Copyright (c) 2017-2019 Rene van der Meer
//
// 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.

//! Miscellaneous `embedded-hal` trait implementations.
//!
//! The `hal` module consists of a collection of `embedded-hal` trait
//! implementations for traits that aren't tied to a specific peripheral.
//!
//! This module is only included when either the `hal` or `hal-unproven` feature
//! flag is enabled.

use std::thread;
use std::time::{Duration, Instant};

use embedded_hal::blocking::delay::{DelayMs, DelayUs};
use embedded_hal::timer::CountDown;
use void::Void;

/// Implements the `embedded-hal` `DelayMs` and `DelayUs` traits.
#[derive(Debug, Default)]
pub struct Delay {}

impl Delay {
    /// Constructs a new `Delay`.
    pub fn new() -> Delay {
        Delay {}
    }
}

impl DelayMs<u8> for Delay {
    fn delay_ms(&mut self, ms: u8) {
        thread::sleep(Duration::from_millis(u64::from(ms)));
    }
}

impl DelayMs<u16> for Delay {
    fn delay_ms(&mut self, ms: u16) {
        thread::sleep(Duration::from_millis(u64::from(ms)));
    }
}

impl DelayMs<u32> for Delay {
    fn delay_ms(&mut self, ms: u32) {
        thread::sleep(Duration::from_millis(u64::from(ms)));
    }
}

impl DelayMs<u64> for Delay {
    fn delay_ms(&mut self, ms: u64) {
        thread::sleep(Duration::from_millis(ms));
    }
}

impl DelayUs<u8> for Delay {
    fn delay_us(&mut self, us: u8) {
        thread::sleep(Duration::from_micros(u64::from(us)));
    }
}

impl DelayUs<u16> for Delay {
    fn delay_us(&mut self, us: u16) {
        thread::sleep(Duration::from_micros(u64::from(us)));
    }
}

impl DelayUs<u32> for Delay {
    fn delay_us(&mut self, us: u32) {
        thread::sleep(Duration::from_micros(u64::from(us)));
    }
}

impl DelayUs<u64> for Delay {
    fn delay_us(&mut self, us: u64) {
        thread::sleep(Duration::from_micros(us));
    }
}

/// Implements the `embedded-hal` `CountDown` trait.
#[derive(Debug, Default, Copy, Clone)]
pub struct Timer {
    now: Instant,
    duration: Duration,
}

impl Timer {
    /// Constructs a new `Timer`.
    pub fn new() -> Self {
        Self {
            now: Instant::now(),
            duration: Duration::from_micros(0),
        }
    }
}

pub struct Millisecond(pub u64);
pub struct Microsecond(pub u64);
pub struct Second(pub u64);

impl From<Millisecond> for Microsecond {
    fn from(item: Millisecond) -> Self {
        Microsecond(item.0 * 1_000)
    }
}

impl From<Second> for Microsecond {
    fn from(item: Second) -> Self {
        Microsecond(item.0 * 1_000_000)
    }
}

impl Microsecond {
    fn as_u64(&self) -> u64 {
        let &Microsecond(t) = self;
        t
    }
}

impl CountDown for Timer {
    type Time = Microsecond;

    /// Start the timer with a `timeout`
    fn start<T>(&mut self, timeout: T)
    where
        T: Into<Microsecond>,
    {
        self.duration = Duration::from_micros(timeout.into().as_u64());
        self.now = Instant::now();
    }

    /// Return `Ok` if the timer has wrapped
    /// Automatically clears the flag and restarts the time
    fn wait(&mut self) -> nb::Result<(), Void> {
        if self.now.elapsed() >= self.duration {
            Ok(())
        } else {
            Err(nb::Error::WouldBlock)
        }
    }
}
<|endoftext|>


<commit_before>#[cfg(feature = "ssl")] extern crate openssl;
#[cfg(feature = "ssl")] use openssl::ssl::{Ssl,SslContext, SslMethod, SslStream};
#[cfg(feature = "ssl")] use openssl::ssl::error::SslError;
use std::io::{BufReader, Read, BufRead, BufWriter, Write};
use std::net::TcpStream;
use std::fmt;

pub struct UnsecureConnection
{
    stream: TcpStream,
    reader: BufReader<TcpStream>,
    writer: BufWriter<TcpStream>
}

impl UnsecureConnection
{
    pub fn new(host: &str, port: u16) -> UnsecureConnection
    {
        let stream = match TcpStream::connect((host, port))
        {
            Ok(sock) => sock,
            Err(err) => panic!("Failed to create socket in UnsecureConnection constructor. Exiting.")
        };
        let mut reader = BufReader::new(stream.try_clone().ok().expect("Failed to clone socket for BufReader in Connection constructor!"));
        let mut writer = BufWriter::new(stream.try_clone().ok().expect("Failed to clone socket for BufWriter in Connection constructor!"));
        UnsecureConnection{ stream: stream, reader: reader, writer: writer}
    }
    pub fn send(&mut self, to_send: &str)
    {
        self.writer.write_fmt(format_args!("{}\r\n", to_send));
        self.writer.flush();
    }
    pub fn read(&mut self) -> String
    {
        let mut buf = String::new();
        let bytes = self.reader.read_line(&mut buf).unwrap();
        buf
    }

}

#[cfg(feature = "ssl")]
pub struct SSLConnection
{
    ssl_stream: SslStream<TcpStream>,
    reader: BufReader<SslStream<TcpStream>>,
    writer: BufWriter<SslStream<TcpStream>>
}

#[cfg(feature = "ssl")]
impl SSLConnection
{
    pub fn new(host: &str, port: u16) -> SSLConnection
    {
        let stream = match TcpStream::connect((host, port))
        {
            Ok(sock) => sock,
            Err(err) => panic!("Failed to create socket in SSLConnection constructor! Exiting.")
        };
        let ssl_context = SslContext::new(SslMethod::Tlsv1).ok().expect("Failed to create SslContext in SSLConnection constructor!");
        let ssl = Ssl::new(&ssl_context).ok().expect("Failed to create Ssl in SSLConnection constructor!");
        let ssl_stream = SslStream::connect(ssl,stream).ok().expect("Failed to create SslStream in SSLConnection constructor!");
        let mut reader = BufReader::new(ssl_stream.try_clone().ok().expect("Failed to create reader for SSLConnection in SSLConnection constructor!"));
        let mut writer = BufWriter::new(ssl_stream.try_clone().ok().expect("Failed to create writer for SSLConnection in SSLConnection constructor!"));
        SSLConnection{ ssl_stream: ssl_stream, reader: reader, writer: writer}
    }
    pub fn send(&mut self, to_send: &str)
    {
        self.writer.write_fmt(format_args!("{}\r\n", to_send)).ok().expect("Bytes not written!");
        self.writer.flush();
    }
    pub fn read(&mut self) -> String
    {
        let mut buf = String::new();
        let bytes = self.reader.read_line(&mut buf).unwrap();
        buf
    }

}

<commit_msg>Updates<commit_after>#[cfg(feature = "ssl")] extern crate openssl;
#[cfg(feature = "ssl")] pub use openssl::ssl::{Ssl,SslContext, SslMethod, SslStream};
#[cfg(feature = "ssl")] pub use openssl::ssl::error::SslError;
pub use std::io::{BufReader, Read, BufRead, BufWriter, Write};
pub use std::net::TcpStream;
pub use std::fmt;

pub struct UnsecureConnection
{
    stream: TcpStream,
    reader: BufReader<TcpStream>,
    writer: BufWriter<TcpStream>
}

impl UnsecureConnection
{
    pub fn new(host: &str, port: u16) -> UnsecureConnection
    {
        let stream = match TcpStream::connect((host, port))
        {
            Ok(sock) => sock,
            Err(err) => panic!("Failed to create socket in UnsecureConnection constructor. Exiting.")
        };
        let mut reader = BufReader::new(stream.try_clone().ok().expect("Failed to clone socket for BufReader in Connection constructor!"));
        let mut writer = BufWriter::new(stream.try_clone().ok().expect("Failed to clone socket for BufWriter in Connection constructor!"));
        UnsecureConnection{ stream: stream, reader: reader, writer: writer}
    }
    pub fn send(&mut self, to_send: &str)
    {
        self.writer.write_fmt(format_args!("{}\r\n", to_send));
        self.writer.flush();
    }
    pub fn read(&mut self) -> Option<String>
    {
        let mut buf = String::new();
        let bytes = match self.reader.read_line(&mut buf)
        {
            Ok(x) => x,
            Err(_) => 0,
        };
        if bytes == 0
        {
            return None
        } else
        {
            Some(buf)
        }
    }

}

#[cfg(feature = "ssl")]
pub struct SSLConnection
{
    ssl_stream: SslStream<TcpStream>,
    reader: BufReader<SslStream<TcpStream>>,
    writer: BufWriter<SslStream<TcpStream>>
}

#[cfg(feature = "ssl")]
impl SSLConnection
{
    pub fn new(host: &str, port: u16) -> SSLConnection
    {
        let stream = match TcpStream::connect((host, port))
        {
            Ok(sock) => sock,
            Err(err) => panic!("Failed to create socket in SSLConnection constructor! Exiting.")
        };
        let ssl_context = SslContext::new(SslMethod::Tlsv1).ok().expect("Failed to create SslContext in SSLConnection constructor!");
        let ssl = Ssl::new(&ssl_context).ok().expect("Failed to create Ssl in SSLConnection constructor!");
        let ssl_stream = SslStream::connect(ssl,stream).ok().expect("Failed to create SslStream in SSLConnection constructor!");
        let mut reader = BufReader::new(ssl_stream.try_clone().ok().expect("Failed to create reader for SSLConnection in SSLConnection constructor!"));
        let mut writer = BufWriter::new(ssl_stream.try_clone().ok().expect("Failed to create writer for SSLConnection in SSLConnection constructor!"));
        SSLConnection{ ssl_stream: ssl_stream, reader: reader, writer: writer}
    }
    pub fn send(&mut self, to_send: &str)
    {
        self.writer.write_fmt(format_args!("{}\r\n", to_send)).ok().expect("Bytes not written!");
        self.writer.flush();
    }
    pub fn read(&mut self) -> Option<String>
    {
        let mut buf = String::new();
        let bytes = match self.reader.read_line(&mut buf)
        {
            Ok(x) => x,
            Err(_) => 0,
        };
        if bytes == 0
        {
            return None
        } else
        {
            Some(buf)
        }
    }

}

<|endoftext|>


<commit_before>//! Calculate the crc64 checksum of the given data, starting with the given crc.
//!
//! Implements the CRC64 used by Redis, which is the variant with "Jones" coefficients and init value of 0.
//!
//! Specification of this CRC64 variant follows:
//!
//! ```text
//! Name: crc-64-jones
//! Width: 64 bites
//! Poly: 0xad93d23594c935a9
//! Reflected In: True
//! Xor_In: 0xffffffffffffffff
//! Reflected_Out: True
//! Xor_Out: 0x0
//! Check("123456789"): 0xe9c6d914c4b8d9ca
//! ```
//!
//! Example:
//!
//! ```rust
//! let cksum = crc64::crc64(0, "123456789".as_bytes());
//! assert_eq!(16845390139448941002, cksum);
//! ```

use std::io::{self, Write};

use crc_table::CRC64_TAB;

mod crc_table;

fn crc_reflect(data: u64, len: usize) -> u64 {
    let mut data = data;
    let mut ret = data & 0x01;

    let mut i = 1;
    while i < len {
        data >>= 1;
        ret = (ret << 1) | (data & 0x01);
        i += 1;
    }

    ret
}

fn crc64_trivial(crc: u64, in_data: &[u8]) -> u64 {
    let mut crc = crc;
    let len = in_data.len();

    let poly = 0xad93d23594c935a9;

    let mut bit: bool;

    let mut offset = 0;

    while offset < len {
        let c = in_data[offset];
        let mut i = 0x01;
        while i != 0x0 {
            bit = crc & 0x8000000000000000 != 0x0;
            if c & i != 0x0 {
                bit = !bit;
            }
            crc <<= 1;
            if bit {
                crc ^= poly;
            }
            i <<= 1;
        }
        crc &= 0xffffffffffffffff;
        offset += 1;
    }
    crc &= 0xffffffffffffffff;

    crc_reflect(crc, 64)
}

pub fn crc64_init() -> Vec<Vec<u64>> {
    let mut crc;

    let mut table: Vec<Vec<u64>> = Vec::with_capacity(8);

    for _ in 0..8 {
        table.push(Vec::with_capacity(256));
    }

    for n in 0..256 {
        table[0].push(crc64_trivial(0, &[n as u8]));
        table[1].push(0);
        table[2].push(0);
        table[3].push(0);
        table[4].push(0);
        table[5].push(0);
        table[6].push(0);
        table[7].push(0);
    }

    for n in 0..256 {
        crc = table[0][n];
        for k in 1..8 {
            let idx = (crc as usize) & 0xff;
            crc = table[0][idx] ^ (crc >> 8);
            table[k][n] = crc;
        }
    }

    table
}

fn to_u64(data: &[u8]) -> u64 {
    debug_assert!(data.len() == 8);
    let arr: [u8; 8] = data.try_into().expect("incorrect length");
    u64::from_le_bytes(arr)
}

pub fn crc64(crc: u64, data: &[u8]) -> u64 {
    let mut crc = crc;
    let mut len = data.len();
    let mut offset = 0usize;

    while len >= 8 {
        crc ^= to_u64(&data[offset..(offset + 8)]);
        crc = CRC64_TAB[7][(crc & 0xff) as usize]
            ^ CRC64_TAB[6][((crc >> 8) & 0xff) as usize]
            ^ CRC64_TAB[5][((crc >> 16) & 0xff) as usize]
            ^ CRC64_TAB[4][((crc >> 24) & 0xff) as usize]
            ^ CRC64_TAB[3][((crc >> 32) & 0xff) as usize]
            ^ CRC64_TAB[2][((crc >> 40) & 0xff) as usize]
            ^ CRC64_TAB[1][((crc >> 48) & 0xff) as usize]
            ^ CRC64_TAB[0][(crc >> 56) as usize];

        offset += 8;
        len -= 8;
    }

    while len > 0 {
        crc = CRC64_TAB[0][((crc ^ data[offset] as u64) & 0xff) as usize] ^ (crc >> 8);
        offset += 1;
        len -= 1;
    }

    crc
}

pub struct Crc64 {
    crc64: u64,
}

impl Crc64 {
    pub fn new() -> Crc64 {
        Crc64 { crc64: 0 }
    }
    pub fn get(&self) -> u64 {
        self.crc64
    }
}

impl Default for Crc64 {
    fn default() -> Self {
        Self::new()
    }
}

impl Write for Crc64 {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.crc64 = crc64(self.crc64, buf);
        Ok(buf.len())
    }
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

#[test]
fn test_crc64_works() {
    assert_eq!(0xe9c6d914c4b8d9ca, crc64(0, "123456789".as_bytes()))
}

#[test]
fn test_crc64_write() {
    let step1 = "12345".as_bytes();
    let step2 = "6789".as_bytes();
    let value1 = 17326901458626182669;
    let value2 = 16845390139448941002;
    assert_eq!(value1, crc64(0, &step1));
    assert_eq!(value2, crc64(value1, &step2));

    let mut crc = Crc64::new();
    assert_eq!(crc.write(&step1).unwrap(), step1.len());
    assert_eq!(value1, crc.get());
    assert_eq!(crc.write(&step2).unwrap(), step2.len());
    assert_eq!(value2, crc.get());
}
<commit_msg>Apply clippy<commit_after>//! Calculate the crc64 checksum of the given data, starting with the given crc.
//!
//! Implements the CRC64 used by Redis, which is the variant with "Jones" coefficients and init value of 0.
//!
//! Specification of this CRC64 variant follows:
//!
//! ```text
//! Name: crc-64-jones
//! Width: 64 bites
//! Poly: 0xad93d23594c935a9
//! Reflected In: True
//! Xor_In: 0xffffffffffffffff
//! Reflected_Out: True
//! Xor_Out: 0x0
//! Check("123456789"): 0xe9c6d914c4b8d9ca
//! ```
//!
//! Example:
//!
//! ```rust
//! let cksum = crc64::crc64(0, "123456789".as_bytes());
//! assert_eq!(16845390139448941002, cksum);
//! ```

use std::io::{self, Write};

use crc_table::CRC64_TAB;

mod crc_table;

fn crc_reflect(data: u64, len: usize) -> u64 {
    let mut data = data;
    let mut ret = data & 0x01;

    let mut i = 1;
    while i < len {
        data >>= 1;
        ret = (ret << 1) | (data & 0x01);
        i += 1;
    }

    ret
}

fn crc64_trivial(crc: u64, in_data: &[u8]) -> u64 {
    let mut crc = crc;
    let len = in_data.len();

    let poly = 0xad93d23594c935a9;

    let mut bit: bool;

    let mut offset = 0;

    while offset < len {
        let c = in_data[offset];
        let mut i = 0x01;
        while i != 0x0 {
            bit = crc & 0x8000000000000000 != 0x0;
            if c & i != 0x0 {
                bit = !bit;
            }
            crc <<= 1;
            if bit {
                crc ^= poly;
            }
            i <<= 1;
        }
        crc &= 0xffffffffffffffff;
        offset += 1;
    }
    crc &= 0xffffffffffffffff;

    crc_reflect(crc, 64)
}

pub fn crc64_init() -> Vec<Vec<u64>> {
    let mut crc;

    let mut table: Vec<Vec<u64>> = Vec::with_capacity(8);

    for _ in 0..8 {
        table.push(Vec::with_capacity(256));
    }

    for n in 0..256 {
        table[0].push(crc64_trivial(0, &[n as u8]));
        table[1].push(0);
        table[2].push(0);
        table[3].push(0);
        table[4].push(0);
        table[5].push(0);
        table[6].push(0);
        table[7].push(0);
    }

    for n in 0..256 {
        crc = table[0][n];
        for k in 1..8 {
            let idx = (crc as usize) & 0xff;
            crc = table[0][idx] ^ (crc >> 8);
            table[k][n] = crc;
        }
    }

    table
}

fn to_u64(data: &[u8]) -> u64 {
    debug_assert!(data.len() == 8);
    let arr: [u8; 8] = data.try_into().expect("incorrect length");
    u64::from_le_bytes(arr)
}

pub fn crc64(crc: u64, data: &[u8]) -> u64 {
    let mut crc = crc;
    let mut len = data.len();
    let mut offset = 0usize;

    while len >= 8 {
        crc ^= to_u64(&data[offset..(offset + 8)]);
        crc = CRC64_TAB[7][(crc & 0xff) as usize]
            ^ CRC64_TAB[6][((crc >> 8) & 0xff) as usize]
            ^ CRC64_TAB[5][((crc >> 16) & 0xff) as usize]
            ^ CRC64_TAB[4][((crc >> 24) & 0xff) as usize]
            ^ CRC64_TAB[3][((crc >> 32) & 0xff) as usize]
            ^ CRC64_TAB[2][((crc >> 40) & 0xff) as usize]
            ^ CRC64_TAB[1][((crc >> 48) & 0xff) as usize]
            ^ CRC64_TAB[0][(crc >> 56) as usize];

        offset += 8;
        len -= 8;
    }

    while len > 0 {
        crc = CRC64_TAB[0][((crc ^ data[offset] as u64) & 0xff) as usize] ^ (crc >> 8);
        offset += 1;
        len -= 1;
    }

    crc
}

pub struct Crc64 {
    crc64: u64,
}

impl Crc64 {
    pub fn new() -> Crc64 {
        Crc64 { crc64: 0 }
    }
    pub fn get(&self) -> u64 {
        self.crc64
    }
}

impl Default for Crc64 {
    fn default() -> Self {
        Self::new()
    }
}

impl Write for Crc64 {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.crc64 = crc64(self.crc64, buf);
        Ok(buf.len())
    }
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

#[test]
fn test_crc64_works() {
    assert_eq!(0xe9c6d914c4b8d9ca, crc64(0, "123456789".as_bytes()))
}

#[test]
fn test_crc64_write() {
    let step1 = "12345".as_bytes();
    let step2 = "6789".as_bytes();
    let value1 = 17326901458626182669;
    let value2 = 16845390139448941002;
    assert_eq!(value1, crc64(0, step1));
    assert_eq!(value2, crc64(value1, step2));

    let mut crc = Crc64::new();
    assert_eq!(crc.write(step1).unwrap(), step1.len());
    assert_eq!(value1, crc.get());
    assert_eq!(crc.write(step2).unwrap(), step2.len());
    assert_eq!(value2, crc.get());
}
<|endoftext|>


<commit_before>//! # Handlebars for Iron
//!
//! This library combines [Handlebars templating library](https://github.com/sunng87/handlebars-rust) and [Iron web framework](http://ironframework.io) together. It gives you a `HandlebarsEngine` as Iron `AfterMiddleware`, so you can render your data with specified handlebars template.
//!
//! ## Setup
//!
//! Handlebars-iron provides two kinds of template source: `DirectorySource` and `MemorySource` by default. `DirectorySource` helps you to load template files from a directory, which `MemorySource` loads template as string in memory.
//!
//! To load files from file system, you need to specify template root and file suffix. Handlebars-iron will scan the directory and loads all templates that matches the suffix. The file's relative path name will be applied as template name.
//!
//! ```ignore
//! /// HandlebarsEngine will look up all files with "./examples/templates/**/*.hbs"
//! let mut hbse = HandlebarsEngine::new();
//! hbse.add(Box::new(DirectorySource::new("./examples/templates/", ".hbs")));
//!
//! // load templates from all registered sources
//! if let Err(r) = hbse.reload() {
//!   panic!("{}", r.description());
//! }
//!
//! chain.link_after(hbse);
//!
//! ```
//!
//! ## Usage
//!
//! From any of your handler, you can set template name and data into our `Template` struct. Remember you need to make your data `ToJson`-able, which is required by handlebars-rust.
//!
//! We have implemented Modifier for `Template` on `Response`, so you can just use `response.set` to put set template into response and let it processed by our middleware.
//!
//! Also we made `Response` plugin for `Template` via `HandlebarsEngine`. So you can test your handler from a test case, and retrieve the `Template` you set into it by `response.get::<HandlebarsEngine>`.
//!

extern crate iron;

#[cfg(not(feature = "serde_type"))]
extern crate rustc_serialize as serialize;
#[cfg(feature = "serde_type")]
extern crate serde;
#[cfg(feature = "serde_type")]
extern crate serde_json;

extern crate handlebars;
extern crate plugin;
extern crate walkdir;
#[cfg(feature = "watch")]
extern crate notify;

#[macro_use]
extern crate log;

pub use self::middleware::Template;
pub use self::middleware::HandlebarsEngine;
pub use self::source::{Source, SourceError};
pub use self::sources::directory::DirectorySource;
pub use self::sources::memory::MemorySource;
#[cfg(feature = "watch")]
pub use self::watch::Watchable;

mod middleware;
#[cfg(feature = "watch")]
mod watch;
mod source;
mod sources;
<commit_msg>(refactor) re-export handlebars crate<commit_after>//! # Handlebars for Iron
//!
//! This library combines [Handlebars templating library](https://github.com/sunng87/handlebars-rust) and [Iron web framework](http://ironframework.io) together. It gives you a `HandlebarsEngine` as Iron `AfterMiddleware`, so you can render your data with specified handlebars template.
//!
//! ## Setup
//!
//! Handlebars-iron provides two kinds of template source: `DirectorySource` and `MemorySource` by default. `DirectorySource` helps you to load template files from a directory, which `MemorySource` loads template as string in memory.
//!
//! To load files from file system, you need to specify template root and file suffix. Handlebars-iron will scan the directory and loads all templates that matches the suffix. The file's relative path name will be applied as template name.
//!
//! ```ignore
//! /// HandlebarsEngine will look up all files with "./examples/templates/**/*.hbs"
//! let mut hbse = HandlebarsEngine::new();
//! hbse.add(Box::new(DirectorySource::new("./examples/templates/", ".hbs")));
//!
//! // load templates from all registered sources
//! if let Err(r) = hbse.reload() {
//!   panic!("{}", r.description());
//! }
//!
//! chain.link_after(hbse);
//!
//! ```
//!
//! ## Usage
//!
//! From any of your handler, you can set template name and data into our `Template` struct. Remember you need to make your data `ToJson`-able, which is required by handlebars-rust.
//!
//! We have implemented Modifier for `Template` on `Response`, so you can just use `response.set` to put set template into response and let it processed by our middleware.
//!
//! Also we made `Response` plugin for `Template` via `HandlebarsEngine`. So you can test your handler from a test case, and retrieve the `Template` you set into it by `response.get::<HandlebarsEngine>`.
//!

pub extern crate handlebars;

extern crate iron;

#[cfg(not(feature = "serde_type"))]
extern crate rustc_serialize as serialize;
#[cfg(feature = "serde_type")]
extern crate serde;
#[cfg(feature = "serde_type")]
extern crate serde_json;

extern crate plugin;
extern crate walkdir;
#[cfg(feature = "watch")]
extern crate notify;

#[macro_use]
extern crate log;

pub use self::middleware::Template;
pub use self::middleware::HandlebarsEngine;
pub use self::source::{Source, SourceError};
pub use self::sources::directory::DirectorySource;
pub use self::sources::memory::MemorySource;
#[cfg(feature = "watch")]
pub use self::watch::Watchable;

mod middleware;
#[cfg(feature = "watch")]
mod watch;
mod source;
mod sources;
<|endoftext|>


<commit_before>//! [tui](https://github.com/fdehau/tui-rs) is a library used to build rich
//! terminal users interfaces and dashboards.
//!
//! ![](https://raw.githubusercontent.com/fdehau/tui-rs/master/assets/demo.gif)
//!
//! # Get started
//!
//! ## Adding `tui` as a dependency
//!
//! ```toml
//! [dependencies]
//! tui = "0.8"
//! termion = "1.5"
//! ```
//!
//! The crate is using the `termion` backend by default but if for example you want your
//! application to work on Windows, you might want to use the `crossterm` backend instead. This can
//! be done by changing your dependencies specification to the following:
//!
//! ```toml
//! [dependencies]
//! crossterm = "0.14"
//! tui = { version = "0.8", default-features = false, features = ['crossterm'] }
//! ```
//!
//! The same logic applies for all other available backends.
//!
//! ## Creating a `Terminal`
//!
//! Every application using `tui` should start by instantiating a `Terminal`. It is a light
//! abstraction over available backends that provides basic functionalities such as clearing the
//! screen, hiding the cursor, etc.
//!
//! ```rust,no_run
//! use std::io;
//! use tui::Terminal;
//! use tui::backend::TermionBackend;
//! use termion::raw::IntoRawMode;
//!
//! fn main() -> Result<(), io::Error> {
//!     let stdout = io::stdout().into_raw_mode()?;
//!     let backend = TermionBackend::new(stdout);
//!     let mut terminal = Terminal::new(backend)?;
//!     Ok(())
//! }
//! ```
//!
//! If you had previously chosen `rustbox` as a backend, the terminal can be created in a similar
//! way:
//!
//! ```rust,ignore
//! use tui::Terminal;
//! use tui::backend::RustboxBackend;
//!
//! fn main() -> Result<(), io::Error> {
//!     let backend = RustboxBackend::new()?;
//!     let mut terminal = Terminal::new(backend);
//!     Ok(())
//! }
//! ```
//!
//! You may also refer to the examples to find out how to create a `Terminal` for each available
//! backend.
//!
//! ## Building a User Interface (UI)
//!
//! Every component of your interface will be implementing the `Widget` trait.  The library comes
//! with a predefined set of widgets that should met most of your use cases. You are also free to
//! implement your owns.
//!
//! Each widget follows a builder pattern API providing a default configuration along with methods
//! to customize them. The widget is then registered using its `render` method that take a `Frame`
//! instance and an area to draw to.
//!
//! The following example renders a block of the size of the terminal:
//!
//! ```rust,no_run
//! use std::io;
//! use termion::raw::IntoRawMode;
//! use tui::Terminal;
//! use tui::backend::TermionBackend;
//! use tui::widgets::{Widget, Block, Borders};
//! use tui::layout::{Layout, Constraint, Direction};
//!
//! fn main() -> Result<(), io::Error> {
//!     let stdout = io::stdout().into_raw_mode()?;
//!     let backend = TermionBackend::new(stdout);
//!     let mut terminal = Terminal::new(backend)?;
//!     terminal.draw(|mut f| {
//!         let size = f.size();
//!         let block = Block::default()
//!             .title("Block")
//!             .borders(Borders::ALL);
//!         f.render_widget(block, size);
//!     })
//! }
//! ```
//!
//! ## Layout
//!
//! The library comes with a basic yet useful layout management object called `Layout`. As you may
//! see below and in the examples, the library makes heavy use of the builder pattern to provide
//! full customization. And `Layout` is no exception:
//!
//! ```rust,no_run
//! use std::io;
//! use termion::raw::IntoRawMode;
//! use tui::Terminal;
//! use tui::backend::TermionBackend;
//! use tui::widgets::{Widget, Block, Borders};
//! use tui::layout::{Layout, Constraint, Direction};
//!
//! fn main() -> Result<(), io::Error> {
//!     let stdout = io::stdout().into_raw_mode()?;
//!     let backend = TermionBackend::new(stdout);
//!     let mut terminal = Terminal::new(backend)?;
//!     terminal.draw(|mut f| {
//!         let chunks = Layout::default()
//!             .direction(Direction::Vertical)
//!             .margin(1)
//!             .constraints(
//!                 [
//!                     Constraint::Percentage(10),
//!                     Constraint::Percentage(80),
//!                     Constraint::Percentage(10)
//!                 ].as_ref()
//!             )
//!             .split(f.size());
//!         let block = Block::default()
//!              .title("Block")
//!              .borders(Borders::ALL);
//!         f.render_widget(block, chunks[0]);
//!         let block = Block::default()
//!              .title("Block 2")
//!              .borders(Borders::ALL);
//!         f.render_widget(block, chunks[1]);
//!     })
//! }
//! ```
//!
//! This let you describe responsive terminal UI by nesting layouts. You should note that by
//! default the computed layout tries to fill the available space completely. So if for any reason
//! you might need a blank space somewhere, try to pass an additional constraint and don't use the
//! corresponding area.

#![deny(warnings)]

pub mod backend;
pub mod buffer;
pub mod layout;
pub mod style;
pub mod symbols;
pub mod terminal;
pub mod widgets;

pub use self::terminal::{Frame, Terminal};
<commit_msg>fix some typos<commit_after>//! [tui](https://github.com/fdehau/tui-rs) is a library used to build rich
//! terminal users interfaces and dashboards.
//!
//! ![](https://raw.githubusercontent.com/fdehau/tui-rs/master/assets/demo.gif)
//!
//! # Get started
//!
//! ## Adding `tui` as a dependency
//!
//! ```toml
//! [dependencies]
//! tui = "0.8"
//! termion = "1.5"
//! ```
//!
//! The crate is using the `termion` backend by default but if for example you want your
//! application to work on Windows, you might want to use the `crossterm` backend instead. This can
//! be done by changing your dependencies specification to the following:
//!
//! ```toml
//! [dependencies]
//! crossterm = "0.14"
//! tui = { version = "0.8", default-features = false, features = ['crossterm'] }
//! ```
//!
//! The same logic applies for all other available backends.
//!
//! ## Creating a `Terminal`
//!
//! Every application using `tui` should start by instantiating a `Terminal`. It is a light
//! abstraction over available backends that provides basic functionalities such as clearing the
//! screen, hiding the cursor, etc.
//!
//! ```rust,no_run
//! use std::io;
//! use tui::Terminal;
//! use tui::backend::TermionBackend;
//! use termion::raw::IntoRawMode;
//!
//! fn main() -> Result<(), io::Error> {
//!     let stdout = io::stdout().into_raw_mode()?;
//!     let backend = TermionBackend::new(stdout);
//!     let mut terminal = Terminal::new(backend)?;
//!     Ok(())
//! }
//! ```
//!
//! If you had previously chosen `rustbox` as a backend, the terminal can be created in a similar
//! way:
//!
//! ```rust,ignore
//! use tui::Terminal;
//! use tui::backend::RustboxBackend;
//!
//! fn main() -> Result<(), io::Error> {
//!     let backend = RustboxBackend::new()?;
//!     let mut terminal = Terminal::new(backend);
//!     Ok(())
//! }
//! ```
//!
//! You may also refer to the examples to find out how to create a `Terminal` for each available
//! backend.
//!
//! ## Building a User Interface (UI)
//!
//! Every component of your interface will be implementing the `Widget` trait.  The library comes
//! with a predefined set of widgets that should meet most of your use cases. You are also free to
//! implement your own.
//!
//! Each widget follows a builder pattern API providing a default configuration along with methods
//! to customize them. The widget is then registered using its `render` method that take a `Frame`
//! instance and an area to draw to.
//!
//! The following example renders a block of the size of the terminal:
//!
//! ```rust,no_run
//! use std::io;
//! use termion::raw::IntoRawMode;
//! use tui::Terminal;
//! use tui::backend::TermionBackend;
//! use tui::widgets::{Widget, Block, Borders};
//! use tui::layout::{Layout, Constraint, Direction};
//!
//! fn main() -> Result<(), io::Error> {
//!     let stdout = io::stdout().into_raw_mode()?;
//!     let backend = TermionBackend::new(stdout);
//!     let mut terminal = Terminal::new(backend)?;
//!     terminal.draw(|mut f| {
//!         let size = f.size();
//!         let block = Block::default()
//!             .title("Block")
//!             .borders(Borders::ALL);
//!         f.render_widget(block, size);
//!     })
//! }
//! ```
//!
//! ## Layout
//!
//! The library comes with a basic yet useful layout management object called `Layout`. As you may
//! see below and in the examples, the library makes heavy use of the builder pattern to provide
//! full customization. And `Layout` is no exception:
//!
//! ```rust,no_run
//! use std::io;
//! use termion::raw::IntoRawMode;
//! use tui::Terminal;
//! use tui::backend::TermionBackend;
//! use tui::widgets::{Widget, Block, Borders};
//! use tui::layout::{Layout, Constraint, Direction};
//!
//! fn main() -> Result<(), io::Error> {
//!     let stdout = io::stdout().into_raw_mode()?;
//!     let backend = TermionBackend::new(stdout);
//!     let mut terminal = Terminal::new(backend)?;
//!     terminal.draw(|mut f| {
//!         let chunks = Layout::default()
//!             .direction(Direction::Vertical)
//!             .margin(1)
//!             .constraints(
//!                 [
//!                     Constraint::Percentage(10),
//!                     Constraint::Percentage(80),
//!                     Constraint::Percentage(10)
//!                 ].as_ref()
//!             )
//!             .split(f.size());
//!         let block = Block::default()
//!              .title("Block")
//!              .borders(Borders::ALL);
//!         f.render_widget(block, chunks[0]);
//!         let block = Block::default()
//!              .title("Block 2")
//!              .borders(Borders::ALL);
//!         f.render_widget(block, chunks[1]);
//!     })
//! }
//! ```
//!
//! This let you describe responsive terminal UI by nesting layouts. You should note that by
//! default the computed layout tries to fill the available space completely. So if for any reason
//! you might need a blank space somewhere, try to pass an additional constraint and don't use the
//! corresponding area.

#![deny(warnings)]

pub mod backend;
pub mod buffer;
pub mod layout;
pub mod style;
pub mod symbols;
pub mod terminal;
pub mod widgets;

pub use self::terminal::{Frame, Terminal};
<|endoftext|>


<commit_before>//! A lazy, zero-copy parser for the DWARF debugging information format.
//!
//! * Zero-copy: everything is just a reference to the original input buffer. No
//!   copies of the input data ever get made.
//!
//! * Lazy: only the compilation units' entries that you iterate over get
//!   parsed, and only as deep as you ask. Skip over a compilation unit and its
//!   entries don't get parsed.
//!
//! * Bring your own object file parser: `gimli` isn't coupled to any platform
//!   or object file format. Use your own ELF parser on Linux or a Mach-O parser
//!   on OSX.
//!
//! This library primarily targets the fourth edition of the standard (the most
//! recent, at time of writing).
//!
//! ## Example Usage
//!
//! Print out all of the functions in a compilation unit.
//!
//! ```rust,no_run
//! use gimli;
//!
//! # let debug_info_buf = [];
//! # let debug_abbrev_buf = [];
//! # let read_debug_info = || &debug_info_buf;
//! # let read_debug_abbrev = || &debug_abbrev_buf;
//! // Read the .debug_info and .debug_abbrev sections with whatever object
//! // loader you're using.
//! let debug_info = gimli::DebugInfo::<gimli::LittleEndian>::new(read_debug_info());
//! let debug_abbrev = gimli::DebugAbbrev::<gimli::LittleEndian>::new(read_debug_abbrev());
//!
//! // Grab the first compilation unit.
//! let unit = debug_info.units().next()
//!     .expect("Should have at least one unit")
//!     .expect("and it should parse OK");
//!
//! // Parse the abbreviations for this compilation unit.
//! let abbrevs = unit.abbreviations(debug_abbrev)
//!     .expect("Should parse the abbreviations OK");
//!
//! // Get a cursor for iterating over this unit's entries.
//! let mut entries = unit.entries(&abbrevs);
//!
//! // Keep iterating entries while the cursor is not exhausted.
//! while let Some((_, entry)) = entries.next_dfs().expect("Should parse next entry") {
//!     // If we find an entry for a function, print it.
//!     if entry.tag() == gimli::DW_TAG_subprogram {
//!         println!("Found a function: {:?}", entry);
//!     }
//! }
//! ```
//!
//! See the [example
//! programs](https://github.com/gimli-rs/gimli/blob/master/examples/) for
//! complete examples.
//!
//! ## Using with `FallibleIterator`
//!
//! The standard library's `Iterator` trait and related APIs do not play well
//! with iterators where the `next` operation is fallible. One can make the
//! `Iterator`'s associated `Item` type be a `Result<T, E>`, however the
//! provided methods cannot gracefully handle the case when an `Err` is
//! returned.
//!
//! This situation led to the
//! [`fallible-iterator`](https://crates.io/crates/fallible-iterator) crate's
//! existence. You can read more of the rationale for its existence in its
//! docs. The crate provides the helpers you have come to expect (eg `map`,
//! `filter`, etc) for iterators that can fail.
//!
//! `gimli`'s many lazy parsing iterators are a perfect match for the
//! `fallible-iterator` crate's `FallibleIterator` trait because parsing is not
//! done eagerly. Parse errors later in the input might only be discovered after
//! having iterated through many items.
//!
//! To use `gimli` iterators with `FallibleIterator`, import the crate and trait
//! into your code:
//!
//! ```
//! // Add the `fallinle-iterator` crate. Don't forget to add it to your
//! // `Cargo.toml`, too!
//! extern crate fallible_iterator;
//! extern crate gimli;
//!
//! // Use the `FallibleIterator` trait so its methods are in scope!
//! use fallible_iterator::FallibleIterator;
//! use gimli::{DebugAranges, LittleEndian, ParseResult};
//!
//! fn find_sum_of_address_range_lengths(aranges: DebugAranges<LittleEndian>)
//!     -> ParseResult<u64>
//! {
//!     // `DebugAranges::items` returns a `FallibleIterator`!
//!     aranges.items()
//!         // `map` is provided by `FallibleIterator`!
//!         .map(|arange| arange.length())
//!         // `fold` is provided by `FallibleIterator`!
//!         .fold(0, |sum, len| sum + len)
//! }
//!
//! # fn main() {}
//! ```

#![deny(missing_docs)]

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

mod cfi;
pub use cfi::*;

mod constants;
pub use constants::*;

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

mod parser;
pub use parser::{Error, ParseResult, Format};
pub use parser::{DebugLocOffset, DebugMacinfoOffset, DebugRangesOffset, UnitOffset};
pub use parser::{DebugInfo, DebugInfoOffset, UnitHeadersIter, UnitHeader};
pub use parser::{DebugTypes, DebugTypesOffset, DebugTypeSignature, TypeUnitHeadersIter,
                 TypeUnitHeader};
pub use parser::{EntriesCursor, DebuggingInformationEntry, AttrsIter, Attribute, AttributeValue};

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

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

mod line;
pub use line::*;

mod lookup;

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

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

mod str;
pub use str::*;

mod op;
pub use op::*;
<commit_msg>s/fallinle/fallible/ in crate documentation comment<commit_after>//! A lazy, zero-copy parser for the DWARF debugging information format.
//!
//! * Zero-copy: everything is just a reference to the original input buffer. No
//!   copies of the input data ever get made.
//!
//! * Lazy: only the compilation units' entries that you iterate over get
//!   parsed, and only as deep as you ask. Skip over a compilation unit and its
//!   entries don't get parsed.
//!
//! * Bring your own object file parser: `gimli` isn't coupled to any platform
//!   or object file format. Use your own ELF parser on Linux or a Mach-O parser
//!   on OSX.
//!
//! This library primarily targets the fourth edition of the standard (the most
//! recent, at time of writing).
//!
//! ## Example Usage
//!
//! Print out all of the functions in a compilation unit.
//!
//! ```rust,no_run
//! use gimli;
//!
//! # let debug_info_buf = [];
//! # let debug_abbrev_buf = [];
//! # let read_debug_info = || &debug_info_buf;
//! # let read_debug_abbrev = || &debug_abbrev_buf;
//! // Read the .debug_info and .debug_abbrev sections with whatever object
//! // loader you're using.
//! let debug_info = gimli::DebugInfo::<gimli::LittleEndian>::new(read_debug_info());
//! let debug_abbrev = gimli::DebugAbbrev::<gimli::LittleEndian>::new(read_debug_abbrev());
//!
//! // Grab the first compilation unit.
//! let unit = debug_info.units().next()
//!     .expect("Should have at least one unit")
//!     .expect("and it should parse OK");
//!
//! // Parse the abbreviations for this compilation unit.
//! let abbrevs = unit.abbreviations(debug_abbrev)
//!     .expect("Should parse the abbreviations OK");
//!
//! // Get a cursor for iterating over this unit's entries.
//! let mut entries = unit.entries(&abbrevs);
//!
//! // Keep iterating entries while the cursor is not exhausted.
//! while let Some((_, entry)) = entries.next_dfs().expect("Should parse next entry") {
//!     // If we find an entry for a function, print it.
//!     if entry.tag() == gimli::DW_TAG_subprogram {
//!         println!("Found a function: {:?}", entry);
//!     }
//! }
//! ```
//!
//! See the [example
//! programs](https://github.com/gimli-rs/gimli/blob/master/examples/) for
//! complete examples.
//!
//! ## Using with `FallibleIterator`
//!
//! The standard library's `Iterator` trait and related APIs do not play well
//! with iterators where the `next` operation is fallible. One can make the
//! `Iterator`'s associated `Item` type be a `Result<T, E>`, however the
//! provided methods cannot gracefully handle the case when an `Err` is
//! returned.
//!
//! This situation led to the
//! [`fallible-iterator`](https://crates.io/crates/fallible-iterator) crate's
//! existence. You can read more of the rationale for its existence in its
//! docs. The crate provides the helpers you have come to expect (eg `map`,
//! `filter`, etc) for iterators that can fail.
//!
//! `gimli`'s many lazy parsing iterators are a perfect match for the
//! `fallible-iterator` crate's `FallibleIterator` trait because parsing is not
//! done eagerly. Parse errors later in the input might only be discovered after
//! having iterated through many items.
//!
//! To use `gimli` iterators with `FallibleIterator`, import the crate and trait
//! into your code:
//!
//! ```
//! // Add the `fallible-iterator` crate. Don't forget to add it to your
//! // `Cargo.toml`, too!
//! extern crate fallible_iterator;
//! extern crate gimli;
//!
//! // Use the `FallibleIterator` trait so its methods are in scope!
//! use fallible_iterator::FallibleIterator;
//! use gimli::{DebugAranges, LittleEndian, ParseResult};
//!
//! fn find_sum_of_address_range_lengths(aranges: DebugAranges<LittleEndian>)
//!     -> ParseResult<u64>
//! {
//!     // `DebugAranges::items` returns a `FallibleIterator`!
//!     aranges.items()
//!         // `map` is provided by `FallibleIterator`!
//!         .map(|arange| arange.length())
//!         // `fold` is provided by `FallibleIterator`!
//!         .fold(0, |sum, len| sum + len)
//! }
//!
//! # fn main() {}
//! ```

#![deny(missing_docs)]

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

mod cfi;
pub use cfi::*;

mod constants;
pub use constants::*;

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

mod parser;
pub use parser::{Error, ParseResult, Format};
pub use parser::{DebugLocOffset, DebugMacinfoOffset, DebugRangesOffset, UnitOffset};
pub use parser::{DebugInfo, DebugInfoOffset, UnitHeadersIter, UnitHeader};
pub use parser::{DebugTypes, DebugTypesOffset, DebugTypeSignature, TypeUnitHeadersIter,
                 TypeUnitHeader};
pub use parser::{EntriesCursor, DebuggingInformationEntry, AttrsIter, Attribute, AttributeValue};

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

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

mod line;
pub use line::*;

mod lookup;

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

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

mod str;
pub use str::*;

mod op;
pub use op::*;
<|endoftext|>


<commit_before>// Many of my decisions were based off the following document
// https://web.archive.org/web/20140727185616/http://algs4.cs.princeton.edu/33balanced/

// TODO:
// Collection trait
// convert this to Key/Value K/V

use Direction::{Left, Middle, Right, Leaf};
use InsertResult::{Fit, Split};

/// SplitNode
enum SplitNode<V: Ord> {
    Four(V, V, V, Box<Node<V>>, Box<Node<V>>, Box<Node<V>>, Box<Node<V>>),
    LeafFour(V, V, V),
}

impl <V: Ord> SplitNode<V> {
    fn to_two(self) -> Two<V> {
        match self {
            SplitNode::LeafFour(v1, v2, v3) =>
                Two(v2,
                    box Node::LeafTwo(LeafTwo(v1)),
                    box Node::LeafTwo(LeafTwo(v3))),
            SplitNode::Four(v1, v2, v3, n1, n2, n3, n4) =>
                Two(v2,
                    box Node::Two(Two(v1, n1, n2)),
                    box Node::Two(Two(v3, n3, n4))),
        }
    }
}

/// InsertResult
enum InsertResult<V: Ord> {
    Fit(Node<V>),
    Split(SplitNode<V>),
}

/// Direction
enum Direction {
    Left,
    Middle,
    Right,
    Leaf,
}

/// Two
pub struct Two<V: Ord>(pub V, pub Box<Node<V>>, pub Box<Node<V>>);

impl <V: Ord> Two<V> {
    fn as_node(self) -> Node<V> { Node::Two(self) }

    fn to_three(self, other_value: V, other_node: Box<Node<V>>) -> Three<V> {
        let Two(self_value, self_left, self_middle) = self;
        if self_value > other_value {
            Three(other_value, self_value, other_node, self_left, self_middle)
        } else {
            Three(self_value, other_value, self_left, self_middle, other_node)
        }
    }

    fn has_value(&self, value: &V) -> bool {
        let &Two(ref self_value, _, _) = self;
        *self_value == *value
    }
}

/// Three
pub struct Three<V: Ord>(pub V, pub V, pub Box<Node<V>>, pub Box<Node<V>>, pub Box<Node<V>>);

impl <V: Ord> Three<V> {
    fn as_node(self) -> Node<V> { Node::Three(self) }

    fn to_split_node(self, other_value: V, other_node: Box<Node<V>>) -> SplitNode<V> {
        let Three(self_value1, self_value2, self_left, self_middle, self_right) = self;
        if other_value < self_value1 {
            SplitNode::Four(other_value, self_value1, self_value2, other_node, self_left, self_middle, self_right)
        } else {
            SplitNode::Four(self_value1, self_value2, other_value, self_left, self_middle, self_right, other_node)
        }
    }

    fn has_value(&self, value: &V) -> bool {
        let &Three(ref self_value1, ref self_value2, _, _, _) = self;
        *self_value1 == *value || *self_value2 == *value
    }
}

/// LeafTwo
pub struct LeafTwo<V: Ord>(pub V);

impl <V: Ord> LeafTwo<V> {
    fn to_three(self, other_value: V) -> LeafThree<V> {
        let LeafTwo(self_value) = self;
        if self_value > other_value {
            LeafThree(other_value, self_value)
        } else {
            LeafThree(self_value, other_value)
        }
    }

    fn has_value(&self, value: &V) -> bool {
        let &LeafTwo(ref self_value) = self;
        *self_value == *value
    }
}

/// LeafThree
pub struct LeafThree<V: Ord>(pub V, pub V);

impl <V: Ord> LeafThree<V> {
    fn as_node(self) -> Node<V> { Node::LeafThree(self) }

    fn to_split_node(self, value: V) -> SplitNode<V> {
        let LeafThree(value1, value2) = self;
        if value > value2      { SplitNode::LeafFour(value1, value2, value) }
        else if value < value1 { SplitNode::LeafFour(value, value1, value2) }
        else                   { SplitNode::LeafFour(value1, value, value2) }
    }

    fn has_value(&self, value: &V) -> bool {
        let &LeafThree(ref self_value1, ref self_value2) = self;
        *self_value1 == *value || *self_value2 == *value
    }
}

/// Node
pub enum Node<V: Ord> {
    LeafTwo(LeafTwo<V>),
    LeafThree(LeafThree<V>),
    Two(Two<V>),
    Three(Three<V>),
}

impl <V: Ord> Node<V> {
    fn next_direction(&self, to_insert: &V) -> Direction {
        match self {
            &Node::Two(Two(ref value, _, _)) =>
                if to_insert < value { Left }
                else                 { Middle },
            &Node::Three(Three(ref value1, ref value2, _, _, _)) =>
                if      to_insert < value1 { Left }
                else if to_insert > value2 { Right }
                else                       { Middle },
            _ => Leaf,
        }
    }

    fn has_value(&self, value: &V) -> bool {
        match self {
            &Node::LeafTwo(ref n)   => n.has_value(value),
            &Node::LeafThree(ref n) => n.has_value(value),
            &Node::Two(ref n)       => n.has_value(value),
            &Node::Three(ref n)     => n.has_value(value),
        }
    }

    fn insert(self, to_insert: V) -> InsertResult<V> {
        // If value is already in this node, we're done (prevent duplicates)
        if self.has_value(&to_insert) { return Fit(self); }

        let next_direction = self.next_direction(&to_insert);

        match self {
            // Insert if leaf TwoNode
            Node::LeafTwo(leaf_two) => {
                let three_node = leaf_two.to_three(to_insert);
                Fit(three_node.as_node())
            },

            // Split if leaf ThreeNode
            Node::LeafThree(leaf_three) => {
                let split_node = leaf_three.to_split_node(to_insert);
                Split(split_node)
            },

            // Recurse down if internal Node and handle results
            Node::Two(Two(value, box left, box middle)) => {

                // Determine which node we'll recurse next
                let (next_node, other_node) = match next_direction {
                    Left => (left, middle),
                    Middle => (middle, left),
                    _ => panic!(""),
                };

                // Recurse, save the result of the insert
                let insert_result = next_node.insert(to_insert);

                // Handle the result of the insert
                let new_node = match insert_result {
                    Fit(returned_node) =>
                        match next_direction {
                            Left =>   Two(value, box returned_node, box other_node),
                            Middle => Two(value, box other_node, box returned_node),
                            _ => panic!(""),
                        }.as_node(),
                    Split(split_node) => split_node.to_two().to_three(value, box other_node).as_node(),
                };

                Fit(new_node)
            },

            // Recurse down if internal Node and handle results
            Node::Three(Three(value1, value2, left, middle, right)) => {

                // Determine which node we'll recurse next
                let (next_node, other_node1, other_node2) = match next_direction {
                    Left => (left, middle, right),
                    Middle => (middle, left, right),
                    Right => (right, left, middle),
                    _ => panic!(""),
                };

                let insert_result = next_node.insert(to_insert);

                match insert_result {
                    Fit(returned_node) => {
                        let three = match next_direction {
                            Left =>   Three(value1, value2, box returned_node, other_node1, other_node2),
                            Middle => Three(value1, value2, other_node1, box returned_node, other_node2),
                            Right =>  Three(value1, value2, other_node1, other_node2, box returned_node),
                            _ => panic!(""),
                        };
                        Fit(three.as_node())
                    },
                    Split(split_node) => {
                        let two = split_node.to_two();
                        let new_node = match next_direction {
                            Left =>   two.to_three(value1, other_node1).to_split_node(value2, other_node2),
                            Middle => two.to_three(value1, other_node1).to_split_node(value2, other_node2),
                            Right =>  two.to_three(value2, other_node2).to_split_node(value1, other_node1),
                            _ => panic!(""),
                        };
                        Split(new_node)
                    }
                }
            }
        }
    }
}

/// TTTree
pub struct TTTree<V: Ord> {
    pub root: Option<Node<V>>,
}

impl <V: Ord> TTTree<V> {
    pub fn new() -> TTTree<V> {
        TTTree { root: None }
    }

    pub fn insert(&mut self, value: V) -> () {
        let root: Option<Node<V>> = self.root.take();
        let new_root: Node<V> = match root {
            None => Node::LeafTwo(LeafTwo(value)),
            Some(root) => {
                let result = root.insert(value);
                match result {
                    Fit(node) => node,
                    Split(split_node) => split_node.to_two().as_node(),
                }
            }
        };
        self.root = Some(new_root);
    }
}
<commit_msg>Simplify more logic<commit_after>// Many of my decisions were based off the following document
// https://web.archive.org/web/20140727185616/http://algs4.cs.princeton.edu/33balanced/

// TODO:
// Collection trait
// convert this to Key/Value K/V

use Direction::{Left, Middle, Right, Leaf};
use InsertResult::{Fit, Split};

/// SplitNode
enum SplitNode<V: Ord> {
    Four(V, V, V, Box<Node<V>>, Box<Node<V>>, Box<Node<V>>, Box<Node<V>>),
    LeafFour(V, V, V),
}

impl <V: Ord> SplitNode<V> {
    fn to_two(self) -> Two<V> {
        match self {
            SplitNode::LeafFour(v1, v2, v3) =>
                Two(v2,
                    box Node::LeafTwo(LeafTwo(v1)),
                    box Node::LeafTwo(LeafTwo(v3))),
            SplitNode::Four(v1, v2, v3, n1, n2, n3, n4) =>
                Two(v2,
                    box Node::Two(Two(v1, n1, n2)),
                    box Node::Two(Two(v3, n3, n4))),
        }
    }
}

/// InsertResult
enum InsertResult<V: Ord> {
    Fit(Node<V>),
    Split(SplitNode<V>),
}

/// Direction
enum Direction {
    Left,
    Middle,
    Right,
    Leaf,
}

/// Two
pub struct Two<V: Ord>(pub V, pub Box<Node<V>>, pub Box<Node<V>>);

impl <V: Ord> Two<V> {
    fn as_node(self) -> Node<V> { Node::Two(self) }

    fn to_three(self, other_value: V, other_node: Box<Node<V>>) -> Three<V> {
        let Two(self_value, self_left, self_middle) = self;
        if self_value > other_value {
            Three(other_value, self_value, other_node, self_left, self_middle)
        } else {
            Three(self_value, other_value, self_left, self_middle, other_node)
        }
    }

    fn has_value(&self, value: &V) -> bool {
        let &Two(ref self_value, _, _) = self;
        *self_value == *value
    }
}

/// Three
pub struct Three<V: Ord>(pub V, pub V, pub Box<Node<V>>, pub Box<Node<V>>, pub Box<Node<V>>);

impl <V: Ord> Three<V> {
    fn as_node(self) -> Node<V> { Node::Three(self) }

    fn to_split_node(self, other_value: V, other_node: Box<Node<V>>) -> SplitNode<V> {
        let Three(self_value1, self_value2, self_left, self_middle, self_right) = self;
        if other_value < self_value1 {
            SplitNode::Four(other_value, self_value1, self_value2, other_node, self_left, self_middle, self_right)
        } else {
            SplitNode::Four(self_value1, self_value2, other_value, self_left, self_middle, self_right, other_node)
        }
    }

    fn has_value(&self, value: &V) -> bool {
        let Three(ref self_value1, ref self_value2, _, _, _) = *self;
        *self_value1 == *value || *self_value2 == *value
    }
}

/// LeafTwo
pub struct LeafTwo<V: Ord>(pub V);

impl <V: Ord> LeafTwo<V> {
    fn to_three(self, other_value: V) -> LeafThree<V> {
        let LeafTwo(self_value) = self;
        if self_value > other_value {
            LeafThree(other_value, self_value)
        } else {
            LeafThree(self_value, other_value)
        }
    }

    fn has_value(&self, value: &V) -> bool {
        let &LeafTwo(ref self_value) = self;
        *self_value == *value
    }
}

/// LeafThree
pub struct LeafThree<V: Ord>(pub V, pub V);

impl <V: Ord> LeafThree<V> {
    fn as_node(self) -> Node<V> { Node::LeafThree(self) }

    fn to_split_node(self, value: V) -> SplitNode<V> {
        let LeafThree(value1, value2) = self;
        if value > value2      { SplitNode::LeafFour(value1, value2, value) }
        else if value < value1 { SplitNode::LeafFour(value, value1, value2) }
        else                   { SplitNode::LeafFour(value1, value, value2) }
    }

    fn has_value(&self, value: &V) -> bool {
        let &LeafThree(ref self_value1, ref self_value2) = self;
        *self_value1 == *value || *self_value2 == *value
    }
}

/// Node
pub enum Node<V: Ord> {
    LeafTwo(LeafTwo<V>),
    LeafThree(LeafThree<V>),
    Two(Two<V>),
    Three(Three<V>),
}

impl <V: Ord> Node<V> {
    fn next_direction(&self, to_insert: &V) -> Direction {
        match *self {
            Node::Two(Two(ref value, _, _)) =>
                if to_insert < value { Left }
                else                 { Middle },
            Node::Three(Three(ref value1, ref value2, _, _, _)) =>
                if      to_insert < value1 { Left }
                else if to_insert > value2 { Right }
                else                       { Middle },
            _ => Leaf,
        }
    }

    fn has_value(&self, value: &V) -> bool {
        match *self {
            Node::LeafTwo(ref n)   => n.has_value(value),
            Node::LeafThree(ref n) => n.has_value(value),
            Node::Two(ref n)       => n.has_value(value),
            Node::Three(ref n)     => n.has_value(value),
        }
    }

    fn insert(self, to_insert: V) -> InsertResult<V> {
        // If value is already in this node, we're done (prevent duplicates)
        if self.has_value(&to_insert) { return Fit(self); }

        let next_direction = self.next_direction(&to_insert);

        match self {
            // Insert if leaf TwoNode
            Node::LeafTwo(leaf_two) => {
                let three_node = leaf_two.to_three(to_insert);
                Fit(three_node.as_node())
            },

            // Split if leaf ThreeNode
            Node::LeafThree(leaf_three) => {
                let split_node = leaf_three.to_split_node(to_insert);
                Split(split_node)
            },

            // Recurse down if internal Node and handle results
            Node::Two(Two(value, box left, box middle)) => {

                // Determine which node we'll recurse next
                let (next_node, other_node) = match next_direction {
                    Left => (left, middle),
                    Middle => (middle, left),
                    _ => panic!(""),
                };

                // Recurse, save the result of the insert
                let insert_result = next_node.insert(to_insert);

                // Handle the result of the insert
                let new_node = match insert_result {
                    Fit(returned_node) =>
                        match next_direction {
                            Left =>   Two(value, box returned_node, box other_node),
                            Middle => Two(value, box other_node, box returned_node),
                            _ => panic!(""),
                        }.as_node(),
                    Split(split_node) => split_node.to_two().to_three(value, box other_node).as_node(),
                };

                Fit(new_node)
            },

            // Recurse down if internal Node and handle results
            Node::Three(Three(value1, value2, left, middle, right)) => {

                // Determine which node we'll recurse next
                let (next_node, other_node1, other_node2) = match next_direction {
                    Left => (left, middle, right),
                    Middle => (middle, left, right),
                    Right => (right, left, middle),
                    _ => panic!(""),
                };

                let insert_result = next_node.insert(to_insert);

                match insert_result {
                    Fit(returned_node) => {
                        let three = match next_direction {
                            Left =>   Three(value1, value2, box returned_node, other_node1, other_node2),
                            Middle => Three(value1, value2, other_node1, box returned_node, other_node2),
                            Right =>  Three(value1, value2, other_node1, other_node2, box returned_node),
                            _ => panic!(""),
                        };
                        Fit(three.as_node())
                    },
                    Split(split_node) => {
                        let two = split_node.to_two();
                        let new_node = match next_direction {
                            Left =>   two.to_three(value1, other_node1).to_split_node(value2, other_node2),
                            Middle => two.to_three(value1, other_node1).to_split_node(value2, other_node2),
                            Right =>  two.to_three(value2, other_node2).to_split_node(value1, other_node1),
                            _ => panic!(""),
                        };
                        Split(new_node)
                    }
                }
            }
        }
    }
}

/// TTTree
pub struct TTTree<V: Ord> {
    pub root: Option<Node<V>>,
}

impl <V: Ord> TTTree<V> {
    pub fn new() -> TTTree<V> {
        TTTree { root: None }
    }

    pub fn insert(&mut self, value: V) -> () {
        let root: Option<Node<V>> = self.root.take();
        let new_root: Node<V> = match root {
            None => Node::LeafTwo(LeafTwo(value)),
            Some(root) => {
                let result = root.insert(value);
                match result {
                    Fit(node) => node,
                    Split(split_node) => split_node.to_two().as_node(),
                }
            }
        };
        self.root = Some(new_root);
    }
}
<|endoftext|>


<commit_before>/* Copyright 2017 Christopher Bacher
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

use std::ops::Drop;
use std::fmt::Debug;

pub trait TestFixture<'param, P, R> : Drop
        where P: Debug + 'static {
    fn new(curried_params: &'param P) -> Self;

    fn parameters() -> Option<Box<Iterator<Item=P>>>;

    fn setup(&mut self) -> FixtureBinding<Self, R>
            where Self: std::marker::Sized;

    fn tear_down(&self) { }
}

pub struct FixtureBinding<'fixture, F:'fixture, R> {
    pub val: R,
    pub params: &'fixture F
}

impl<'fixture, F:'fixture, R> FixtureBinding<'fixture, F, R> {
    pub fn decompose(self) -> (R, &'fixture F) {
        (self.val, self.params)
    }

    pub fn into_val(self) -> R {
        self.val
    }

    pub fn into_params(self) -> &'fixture F {
        self.params
    }
}

/// Creates a new `TestFixture` implementation.
///
/// A `fixture!` requires a name, parameters and a
#[macro_export]
macro_rules! fixture {
    ( @impl_drop $name:ident ) => {
        impl<'param> ::std::ops::Drop for $name<'param> {
            fn drop(&mut self) {
                use ::galvanic_test::TestFixture;
                self.tear_down();
            }
        }
    };

    ( @impl_struct $name:ident Params[$($param:ident : $param_ty:ty),*] Members[$($member:ident : $member_ty:ty),*] ) => {
        #[allow(non_camel_case_types)]
        #[derive(Debug)]
        pub struct $name<'param> {
            $(pub $param : &'param $param_ty,)*
            $($member : Option<$member_ty>,)*
        }
    };

    ( @new_method Params[$param:ident : $param_ty:ty] Members[$($member:ident),*] ) => {
        fn new($param : &'param $param_ty) -> Self {
            Self {
                $param,
                $($member: None,)*
            }
        }
    };
    ( @new_method Params[$($param:ident : $param_ty:ty),+] Members[$($member:ident),*] ) => {
        fn new(&($(ref $param),*) : &'param ($($param_ty),*)) -> Self {
            Self {
                $($param,)*
                $($member: None,)*
            }
        }
    };

    ( $name:ident ( ) -> $ret_ty:ty {
          $(members { $($member:ident : Option<$member_ty:ty>),* })*
          setup(& mut $self_setup:ident) $setup_body:block
          $(tear_down(&$self_td:ident) $tear_down_body:block)*
      }
    ) => {
        fixture!(@impl_struct $name Params[_phantom : ()] Members[$($($member : $member_ty),*),*]);

        impl<'param> ::galvanic_test::TestFixture<'param, (), $ret_ty> for $name<'param> {
            fn new(_phantom: &'param ()) -> Self {
                Self {
                    _phantom,
                    $($($member: None),*),*
                }
            }
            fn parameters() -> Option<Box<Iterator<Item=()>>> {
                Some(Box::new(Some(()).into_iter()))
            }
            fn setup(&mut $self_setup) -> ::galvanic_test::FixtureBinding<Self, $ret_ty> {
                let value = $setup_body;
                ::galvanic_test::FixtureBinding {
                    val: value,
                    params: $self_setup
                }
            }
            $(fn tear_down(&$self_td) $tear_down_body)*
        }

        fixture!(@impl_drop $name);
    };

    ( $name:ident ($($param:ident : $param_ty:ty),+) -> $ret_ty:ty {
          $(members { $($member:ident : Option<$member_ty:ty>),* })*
          $(params $params_body:block)*
          setup(& mut $self_setup:ident) $setup_body:block
          $(tear_down(&$self_td:ident) $tear_down_body:block)*
      }
    ) => {
        fixture!(@impl_struct $name Params[$($param : $param_ty),*] Members[$($($member : $member_ty),*),*]);

        impl<'param> ::galvanic_test::TestFixture<'param, ($($param_ty),*), $ret_ty> for $name<'param> {
            fixture!(@new_method Params[$($param : $param_ty),*] Members[$($($member),*),*]);
            fn parameters() -> Option<Box<Iterator<Item=($($param_ty),*)>>> {
                (None as Option<Box<Iterator<Item=($($param_ty),*)>>>)
                $(; Some(Box::new($params_body)))*
            }
            fn setup(&mut $self_setup) -> ::galvanic_test::FixtureBinding<Self, $ret_ty> {
                let value = $setup_body;
                ::galvanic_test::FixtureBinding {
                    val: value,
                    params: $self_setup
                }
            }
            $(fn tear_down(&$self_td) $tear_down_body)*
        }

        fixture!(@impl_drop $name);
    };
}

#[macro_export]
macro_rules! test {
    ( @parameters | $body:block $test_case_failed:ident ) => { $body };

    ( @parameters | $body:block $test_case_failed:ident $(($fixture_obj:ident, $params:expr, $fixture:ident))+) => {
        let mut described_parameters = String::from("Test panicked before all fixtures have been assigned.");
        let result = ::std::panic::catch_unwind(::std::panic::AssertUnwindSafe(|| {
            let mut described_params = Vec::new();
            $(
                let params = &$params;
                let mut $fixture_obj = $fixture::new(params);
                described_params.push(format!("{:?}", $fixture_obj));
                let mut $fixture = $fixture_obj.setup();
                noop(&mut $fixture);
            )*
            described_parameters = described_params.join(", ");
            $body
        }));
        if result.is_err() {
            println!("The above error occured with the following parameterisation of the test case:\n    {}\n",
                     described_parameters);
            $test_case_failed.set(true);
        }
    };

    ( @parameters , $($remainder:tt)+ ) => {
        test!(@parameters $($remainder)*);
    };

    ( @parameters $fixture:ident ( $($expr:expr),* ) $($remainder:tt)+ ) => {
        test!(@parameters $($remainder)* (fixture_obj, ($($expr),*), $fixture));
    };

    ( @parameters $fixture:ident $($remainder:tt)+ ) => {
        match $fixture::parameters() {
            Some(iterator) => {
                for params in iterator {
                    test!(@parameters $($remainder)* (fixture_obj, params, $fixture));
                }
            },
            None => panic!(concat!(
                "If a test fixture should be injected without supplying parameters, ",
                "it either needs to have no arguments ",
                "or a `params` block returning an iterator of parameter tuples ",
                "must be given for the fixture."))
        }
    };

    ( $(#[$attr:meta])* $name:ident | $($args_and_body:tt)* ) => {
        #[test]
        $(#[$attr])*
        fn $name() {
            #[allow(dead_code)]
            fn noop<F, R>(_: &::galvanic_test::FixtureBinding<F,R>) { }
            // Cell is a workaround for #![allow(unused_mut)] which would affect the whole fn
            let test_case_failed = ::std::cell::Cell::new(false);
            test!(@parameters $($args_and_body)* test_case_failed);
            if test_case_failed.get() {
                panic!("Some parameterised test cases failed");
            }
        }
    };

    ( $(#[$attr:meta])* $name:ident $body:block ) => {
        #[test]
        $(#[$attr])*
        fn $name() {
            $body
        }
    };
}

#[macro_export]
#[cfg(not(feature = "galvanic_mock_integration"))]
macro_rules! test_suite {
    // named test suite
    ( name $name:ident ; $($remainder:tt)* ) => {
        #[cfg(test)]
        mod $name {
            #[allow(unused_imports)] use ::galvanic_test::TestFixture;
            __test_suite_int!(@int $($remainder)*);
        }
    };

    // anonymous test suite
    ( $($remainder:tt)* ) => {
        #[cfg(test)]
        mod __galvanic_test {
            #[allow(unused_imports)] use ::galvanic_test::TestFixture;
            __test_suite_int!(@int $($remainder)*);
        }
    };
}

#[macro_export]
#[cfg(feature = "galvanic_mock_integration")]
macro_rules! test_suite {
    // named test suite
    ( name $name:ident ; $($remainder:tt)* ) => {
        #[cfg(test)]
        mod $name {
            #[allow(unused_imports)] use ::galvanic_mock::use_mocks;
            #[allow(unused_imports)] use super::*;
            #[use_mocks]
            mod with_mocks {
                #[allow(unused_imports)] use ::galvanic_test::TestFixture;
                __test_suite_int!(@int $($remainder)*);
            }
        }
    };

    // anonymous test suite
    ( $($remainder:tt)* ) => {
        #[cfg(test)]
        mod __galvanic_test {
            #[allow(unused_imports)] use ::galvanic_mock::use_mocks;
            #[allow(unused_imports)] use super::*;
            #[use_mocks]
            mod with_mocks {
                #[allow(unused_imports)] use ::galvanic_test::TestFixture;
                __test_suite_int!(@int $($remainder)*);
            }
        }
    };
}

#[macro_export]
macro_rules! __test_suite_int {
    // internal: fixture in test_suite
    ( @int $(#[$attr:meta])* fixture $name:ident ($($param:ident : $param_ty:ty),*) -> $ret_ty:ty {
          $(members { $($member:ident : Option<$member_ty:ty>),* })*
          $(params $params_body:block)*
          setup(& mut $self_setup:ident) $setup_body:block
          $(tear_down(&$self_td:ident) $tear_down_body:block)*
      } $($remainder:tt)*
    ) => {
        fixture!( $(#[$attr])* $name ($($param : $param_ty),*) -> $ret_ty {
              $(members { $($member : Option<$member_ty>),* })*
              $(params $params_body)*
              setup(& mut $self_setup) $setup_body
              $(tear_down(&$self_td) $tear_down_body)*
        });
        __test_suite_int!(@int $($remainder)*);
    };

    // internal: test in test_suite
    ( @int $(#[$attr:meta])* test $name:ident ( $($fixture:ident $(($($expr:expr),*))*),* )
            $body:block
            $($remainder:tt)*
    ) => {
        test!( $(#[$attr])* $name | $($fixture $(($($expr),*))* ),* | $body);
        __test_suite_int!(@int $($remainder)*);
    };

    // internal: arbitrary item in test suite
    ( @int $item:item
            $($remainder:tt)*
    ) => {
        $item
        __test_suite_int!(@int $($remainder)*);
    };

    // internal: empty test suite
    ( @int ) => { };
}
<commit_msg>Fix "unnecessary_mut_passed" Clippy warnings<commit_after>/* Copyright 2017 Christopher Bacher
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

use std::ops::Drop;
use std::fmt::Debug;

pub trait TestFixture<'param, P, R> : Drop
        where P: Debug + 'static {
    fn new(curried_params: &'param P) -> Self;

    fn parameters() -> Option<Box<Iterator<Item=P>>>;

    fn setup(&mut self) -> FixtureBinding<Self, R>
            where Self: std::marker::Sized;

    fn tear_down(&self) { }
}

pub struct FixtureBinding<'fixture, F:'fixture, R> {
    pub val: R,
    pub params: &'fixture F
}

impl<'fixture, F:'fixture, R> FixtureBinding<'fixture, F, R> {
    pub fn decompose(self) -> (R, &'fixture F) {
        (self.val, self.params)
    }

    pub fn into_val(self) -> R {
        self.val
    }

    pub fn into_params(self) -> &'fixture F {
        self.params
    }
}

/// Creates a new `TestFixture` implementation.
///
/// A `fixture!` requires a name, parameters and a
#[macro_export]
macro_rules! fixture {
    ( @impl_drop $name:ident ) => {
        impl<'param> ::std::ops::Drop for $name<'param> {
            fn drop(&mut self) {
                use ::galvanic_test::TestFixture;
                self.tear_down();
            }
        }
    };

    ( @impl_struct $name:ident Params[$($param:ident : $param_ty:ty),*] Members[$($member:ident : $member_ty:ty),*] ) => {
        #[allow(non_camel_case_types)]
        #[derive(Debug)]
        pub struct $name<'param> {
            $(pub $param : &'param $param_ty,)*
            $($member : Option<$member_ty>,)*
        }
    };

    ( @new_method Params[$param:ident : $param_ty:ty] Members[$($member:ident),*] ) => {
        fn new($param : &'param $param_ty) -> Self {
            Self {
                $param,
                $($member: None,)*
            }
        }
    };
    ( @new_method Params[$($param:ident : $param_ty:ty),+] Members[$($member:ident),*] ) => {
        fn new(&($(ref $param),*) : &'param ($($param_ty),*)) -> Self {
            Self {
                $($param,)*
                $($member: None,)*
            }
        }
    };

    ( $name:ident ( ) -> $ret_ty:ty {
          $(members { $($member:ident : Option<$member_ty:ty>),* })*
          setup(& mut $self_setup:ident) $setup_body:block
          $(tear_down(&$self_td:ident) $tear_down_body:block)*
      }
    ) => {
        fixture!(@impl_struct $name Params[_phantom : ()] Members[$($($member : $member_ty),*),*]);

        impl<'param> ::galvanic_test::TestFixture<'param, (), $ret_ty> for $name<'param> {
            fn new(_phantom: &'param ()) -> Self {
                Self {
                    _phantom,
                    $($($member: None),*),*
                }
            }
            fn parameters() -> Option<Box<Iterator<Item=()>>> {
                Some(Box::new(Some(()).into_iter()))
            }
            fn setup(&mut $self_setup) -> ::galvanic_test::FixtureBinding<Self, $ret_ty> {
                let value = $setup_body;
                ::galvanic_test::FixtureBinding {
                    val: value,
                    params: $self_setup
                }
            }
            $(fn tear_down(&$self_td) $tear_down_body)*
        }

        fixture!(@impl_drop $name);
    };

    ( $name:ident ($($param:ident : $param_ty:ty),+) -> $ret_ty:ty {
          $(members { $($member:ident : Option<$member_ty:ty>),* })*
          $(params $params_body:block)*
          setup(& mut $self_setup:ident) $setup_body:block
          $(tear_down(&$self_td:ident) $tear_down_body:block)*
      }
    ) => {
        fixture!(@impl_struct $name Params[$($param : $param_ty),*] Members[$($($member : $member_ty),*),*]);

        impl<'param> ::galvanic_test::TestFixture<'param, ($($param_ty),*), $ret_ty> for $name<'param> {
            fixture!(@new_method Params[$($param : $param_ty),*] Members[$($($member),*),*]);
            fn parameters() -> Option<Box<Iterator<Item=($($param_ty),*)>>> {
                (None as Option<Box<Iterator<Item=($($param_ty),*)>>>)
                $(; Some(Box::new($params_body)))*
            }
            fn setup(&mut $self_setup) -> ::galvanic_test::FixtureBinding<Self, $ret_ty> {
                let value = $setup_body;
                ::galvanic_test::FixtureBinding {
                    val: value,
                    params: $self_setup
                }
            }
            $(fn tear_down(&$self_td) $tear_down_body)*
        }

        fixture!(@impl_drop $name);
    };
}

#[macro_export]
macro_rules! test {
    ( @parameters | $body:block $test_case_failed:ident ) => { $body };

    ( @parameters | $body:block $test_case_failed:ident $(($fixture_obj:ident, $params:expr, $fixture:ident))+) => {
        let mut described_parameters = String::from("Test panicked before all fixtures have been assigned.");
        let result = ::std::panic::catch_unwind(::std::panic::AssertUnwindSafe(|| {
            let mut described_params = Vec::new();
            $(
                let params = &$params;
                let mut $fixture_obj = $fixture::new(params);
                described_params.push(format!("{:?}", $fixture_obj));
                let mut $fixture = $fixture_obj.setup();
                noop(&$fixture);
            )*
            described_parameters = described_params.join(", ");
            $body
        }));
        if result.is_err() {
            println!("The above error occured with the following parameterisation of the test case:\n    {}\n",
                     described_parameters);
            $test_case_failed.set(true);
        }
    };

    ( @parameters , $($remainder:tt)+ ) => {
        test!(@parameters $($remainder)*);
    };

    ( @parameters $fixture:ident ( $($expr:expr),* ) $($remainder:tt)+ ) => {
        test!(@parameters $($remainder)* (fixture_obj, ($($expr),*), $fixture));
    };

    ( @parameters $fixture:ident $($remainder:tt)+ ) => {
        match $fixture::parameters() {
            Some(iterator) => {
                for params in iterator {
                    test!(@parameters $($remainder)* (fixture_obj, params, $fixture));
                }
            },
            None => panic!(concat!(
                "If a test fixture should be injected without supplying parameters, ",
                "it either needs to have no arguments ",
                "or a `params` block returning an iterator of parameter tuples ",
                "must be given for the fixture."))
        }
    };

    ( $(#[$attr:meta])* $name:ident | $($args_and_body:tt)* ) => {
        #[test]
        $(#[$attr])*
        fn $name() {
            #[allow(dead_code)]
            fn noop<F, R>(_: &::galvanic_test::FixtureBinding<F,R>) { }
            // Cell is a workaround for #![allow(unused_mut)] which would affect the whole fn
            let test_case_failed = ::std::cell::Cell::new(false);
            test!(@parameters $($args_and_body)* test_case_failed);
            if test_case_failed.get() {
                panic!("Some parameterised test cases failed");
            }
        }
    };

    ( $(#[$attr:meta])* $name:ident $body:block ) => {
        #[test]
        $(#[$attr])*
        fn $name() {
            $body
        }
    };
}

#[macro_export]
#[cfg(not(feature = "galvanic_mock_integration"))]
macro_rules! test_suite {
    // named test suite
    ( name $name:ident ; $($remainder:tt)* ) => {
        #[cfg(test)]
        mod $name {
            #[allow(unused_imports)] use ::galvanic_test::TestFixture;
            __test_suite_int!(@int $($remainder)*);
        }
    };

    // anonymous test suite
    ( $($remainder:tt)* ) => {
        #[cfg(test)]
        mod __galvanic_test {
            #[allow(unused_imports)] use ::galvanic_test::TestFixture;
            __test_suite_int!(@int $($remainder)*);
        }
    };
}

#[macro_export]
#[cfg(feature = "galvanic_mock_integration")]
macro_rules! test_suite {
    // named test suite
    ( name $name:ident ; $($remainder:tt)* ) => {
        #[cfg(test)]
        mod $name {
            #[allow(unused_imports)] use ::galvanic_mock::use_mocks;
            #[allow(unused_imports)] use super::*;
            #[use_mocks]
            mod with_mocks {
                #[allow(unused_imports)] use ::galvanic_test::TestFixture;
                __test_suite_int!(@int $($remainder)*);
            }
        }
    };

    // anonymous test suite
    ( $($remainder:tt)* ) => {
        #[cfg(test)]
        mod __galvanic_test {
            #[allow(unused_imports)] use ::galvanic_mock::use_mocks;
            #[allow(unused_imports)] use super::*;
            #[use_mocks]
            mod with_mocks {
                #[allow(unused_imports)] use ::galvanic_test::TestFixture;
                __test_suite_int!(@int $($remainder)*);
            }
        }
    };
}

#[macro_export]
macro_rules! __test_suite_int {
    // internal: fixture in test_suite
    ( @int $(#[$attr:meta])* fixture $name:ident ($($param:ident : $param_ty:ty),*) -> $ret_ty:ty {
          $(members { $($member:ident : Option<$member_ty:ty>),* })*
          $(params $params_body:block)*
          setup(& mut $self_setup:ident) $setup_body:block
          $(tear_down(&$self_td:ident) $tear_down_body:block)*
      } $($remainder:tt)*
    ) => {
        fixture!( $(#[$attr])* $name ($($param : $param_ty),*) -> $ret_ty {
              $(members { $($member : Option<$member_ty>),* })*
              $(params $params_body)*
              setup(& mut $self_setup) $setup_body
              $(tear_down(&$self_td) $tear_down_body)*
        });
        __test_suite_int!(@int $($remainder)*);
    };

    // internal: test in test_suite
    ( @int $(#[$attr:meta])* test $name:ident ( $($fixture:ident $(($($expr:expr),*))*),* )
            $body:block
            $($remainder:tt)*
    ) => {
        test!( $(#[$attr])* $name | $($fixture $(($($expr),*))* ),* | $body);
        __test_suite_int!(@int $($remainder)*);
    };

    // internal: arbitrary item in test suite
    ( @int $item:item
            $($remainder:tt)*
    ) => {
        $item
        __test_suite_int!(@int $($remainder)*);
    };

    // internal: empty test suite
    ( @int ) => { };
}
<|endoftext|>


<commit_before>#![crate_name = "gimei"]
#![crate_type = "lib"]

#[macro_use]
extern crate lazy_static;
extern crate rand;
extern crate yaml_rust;

pub mod address;
pub mod item;
pub mod name;

pub use address::Address;
pub use item::Item;
pub use name::{Gender, Name};
<commit_msg>Implement gimei<commit_after>#![crate_name = "gimei"]
#![crate_type = "lib"]

#[macro_use]
extern crate lazy_static;
extern crate rand;
extern crate yaml_rust;

use rand::Rng;

pub mod address;
pub mod item;
pub mod name;

pub use address::Address;
pub use item::Item;
pub use name::{Gender, Name};

pub fn name() -> Name {
  if rand::thread_rng().gen() {
    Name::from_gender(Gender::Male)
  } else {
    Name::from_gender(Gender::Female)
  }
}

pub fn male() -> Name {
  Name::from_gender(Gender::Male)
}

pub fn female() -> Name {
  Name::from_gender(Gender::Female)
}

pub fn address() -> Address {
  Address::new()
}
<|endoftext|>