<commit_before>// Copyright 2021 Google LLC
//
// 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
//
//     https://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.

mod abort;
mod common;
mod ldc;
mod mcr;
mod wf;

use abort::{decode_iss_data_abort, decode_iss_instruction_abort};
use bit_field::BitField;
use ldc::decode_iss_ldc;
use mcr::{decode_iss_mcr, decode_iss_mcrr};
use std::fmt::{self, Debug, Display, Formatter};
use std::num::ParseIntError;
use thiserror::Error;
use wf::decode_iss_wf;

/// Information about a particular field.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct FieldInfo {
    /// The short name of the field, e.g. "ISS".
    pub name: &'static str,
    /// The index of the lowest bit of the field.
    pub start: usize,
    /// The number of bits in the field.
    pub width: usize,
    /// The value of the field.
    pub value: u64,
    /// More information about the field and subfields, if available.
    pub decoded: Option<Decoded>,
}

impl FieldInfo {
    fn get(register: u64, name: &'static str, start: usize, end: usize) -> Self {
        let value = register.get_bits(start..end);
        Self {
            name,
            start,
            width: end - start,
            value,
            decoded: None,
        }
    }

    fn get_bit(register: u64, name: &'static str, bit: usize) -> Self {
        Self::get(register, name, bit, bit + 1)
    }

    fn with_decoded(self, decoded: Decoded) -> Self {
        Self {
            decoded: Some(decoded),
            ..self
        }
    }

    fn with_description(self, description: String) -> Self {
        self.with_decoded(Decoded {
            description: Some(description),
            fields: vec![],
        })
    }

    fn as_bit(&self) -> bool {
        assert!(self.width == 1);
        self.value == 1
    }

    /// Assuming this field has a width of exactly 1, describe it with the given function.
    ///
    /// Panics if `self.width != 1`.
    fn describe_bit<F>(self, describer: F) -> Self
    where
        F: FnOnce(bool) -> &'static str,
    {
        let bit = self.as_bit();
        let description = describer(bit).to_string();
        self.with_description(description)
    }

    fn describe<F>(self, describer: F) -> Result<Self, DecodeError>
    where
        F: FnOnce(u64) -> Result<&'static str, DecodeError>,
    {
        let description = describer(self.value)?.to_string();
        Ok(self.with_description(description))
    }

    fn check_res0(self) -> Result<Self, DecodeError> {
        if self.value != 0 {
            Err(DecodeError::InvalidRes0 { res0: self.value })
        } else {
            Ok(self)
        }
    }

    /// Returns the value as a hexadecimal string, or "true" or "false" if it is a single bit.
    pub fn value_string(&self) -> String {
        if self.width == 1 {
            if self.value == 1 { "true" } else { "false" }.to_string()
        } else {
            format!("{:#01$x}", self.value, (self.width + 3) / 4 + 2,)
        }
    }

    /// Returns the value as a binary strings.
    pub fn value_binary_string(&self) -> String {
        format!("{:#01$b}", self.value, self.width + 2)
    }
}

impl Display for FieldInfo {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        if self.width == 1 {
            write!(
                f,
                "{}: {}",
                self.name,
                if self.value == 1 { "true" } else { "false" }
            )
        } else {
            write!(
                f,
                "{}: {} {}",
                self.name,
                self.value_string(),
                self.value_binary_string(),
            )
        }
    }
}

/// An error decoding an ESR value.
#[derive(Debug, Error)]
pub enum DecodeError {
    /// A RES0 field was not 0.
    #[error("Invalid ESR, res0 is {res0:#x}")]
    InvalidRes0 { res0: u64 },
    /// The EC field had an invalid value.
    #[error("Invalid EC {ec:#x}")]
    InvalidEc { ec: u64 },
    /// The DFSC or IFSC field had an invalid value.
    #[error("Invalid DFSC or IFSC {fsc:#x}")]
    InvalidFsc { fsc: u64 },
    /// The SET field had an invalid value.
    #[error("Invalid SET {set:#x}")]
    InvalidSet { set: u64 },
    /// The AM field had an invalid value.
    #[error("Invalid AM {am:#x}")]
    InvalidAm { am: u64 },
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Decoded {
    pub description: Option<String>,
    pub fields: Vec<FieldInfo>,
}

fn decode_iss_res0(iss: u64) -> Result<Decoded, DecodeError> {
    if iss == 0 {
        Ok(Decoded {
            description: Some("ISS is RES0".to_string()),
            fields: vec![],
        })
    } else {
        Err(DecodeError::InvalidRes0 { res0: iss })
    }
}

pub fn decode(esr: u64) -> Result<Decoded, DecodeError> {
    let res0 = FieldInfo::get(esr, "RES0", 37, 64).check_res0()?;
    let iss2 = FieldInfo::get(esr, "ISS2", 32, 37);
    let ec = FieldInfo::get(esr, "EC", 26, 32);
    let il = FieldInfo::get_bit(esr, "IL", 25).describe_bit(describe_il);
    let iss = FieldInfo::get(esr, "ISS", 0, 25);
    let (class, iss_decoded) = match ec.value {
        0b000000 => ("Unknown reason", Some(decode_iss_res0(iss.value)?)),
        0b000001 => ("Wrapped WF* instruction execution", Some(decode_iss_wf(iss.value)?)),
        0b000011 => ("Trapped MCR or MRC access with coproc=0b1111", Some(decode_iss_mcr(iss.value)?)),
        0b000100 => ("Trapped MCRR or MRRC access with coproc=0b1111", Some(decode_iss_mcrr(iss.value)?)),
        0b000101 => ("Trapped MCR or MRC access with coproc=0b1110", Some(decode_iss_mcr(iss.value)?)),
        0b000110 => ("Trapped LDC or STC access", Some(decode_iss_ldc(iss.value)?)),
        0b000111 => ("Trapped access to SVE, Advanced SIMD or floating point", None),
        0b001010 => ("Trapped execution of an LD64B, ST64B, ST64BV, or ST64BV0 instruction", None),
        0b001100 => ("Trapped MRRC access with (coproc==0b1110)", None),
        0b001101 => ("Branch Target Exception", None),
        0b001110 => ("Illegal Execution state", Some(decode_iss_res0(iss.value)?)),
        0b010001 => ("SVC instruction execution in AArch32 state", None),
        0b010101 => ("SVC instruction execution in AArch64 state", None),
        0b011000 => ("Trapped MSR, MRS or System instruction execution in AArch64 state", None),
        0b011001 => ("Access to SVE functionality trapped as a result of CPACR_EL1.ZEN, CPTR_EL2.ZEN, CPTR_EL2.TZ, or CPTR_EL3.EZ", Some(decode_iss_res0(iss.value)?)),
        0b011100 => ("Exception from a Pointer Authentication instruction authentication failure", None),
        0b100000 => ("Instruction Abort from a lower Exception level", Some(decode_iss_instruction_abort(iss.value)?)),
        0b100001 => ("Instruction Abort taken without a change in Exception level", Some(decode_iss_instruction_abort(iss.value)?)),
        0b100010 => ("PC alignment fault exception", Some(decode_iss_res0(iss.value)?)),
        0b100100 => ("Data Abort from a lower Exception level", Some(decode_iss_data_abort(iss.value)?)),
        0b100101 => ("Data Abort taken without a change in Exception level", Some(decode_iss_data_abort(iss.value)?)),
        0b100110 => ("SP alignment fault exception", Some(decode_iss_res0(iss.value)?)),
        0b101000 => ("Trapped floating-point exception taken from AArch32 state", None),
        0b101100 => ("Trapped floating-point exception taken from AArch64 state", None),
        0b101111 => ("SError interrupt", None),
        0b110000 => ("Breakpoint exception from a lower Exception level", None),
        0b110001 => ("Breakpoint exception taken without a change in Exception level", None),
        0b110010 => ("Software Step exception from a lower Exception level", None),
        0b110011 => ("Software Step exception taken without a change in Exception level", None),
        0b110100 => ("Watchpoint exception from a lower Exception level", None),
        0b110101 => ("Watchpoint exception taken without a change in Exception level", None),
        0b111000 => ("BKPT instruction execution in AArch32 state", None),
        0b111100 => ("BRK instruction execution in AArch64 state", None),
        _ => return Err(DecodeError::InvalidEc { ec: ec.value }),
    };
    let iss = FieldInfo {
        decoded: iss_decoded,
        ..iss
    };
    let ec = ec.with_decoded(Decoded {
        description: Some(class.to_string()),
        fields: vec![],
    });
    Ok(Decoded {
        description: Some(class.to_string()),
        fields: vec![res0, iss2, ec, il, iss],
    })
}

fn describe_il(il: bool) -> &'static str {
    if il {
        "32-bit instruction trapped"
    } else {
        "16-bit instruction trapped"
    }
}

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

    #[test]
    fn unknown() {
        let decoded = decode(0).unwrap();
        assert_eq!(
            decoded,
            Decoded {
                description: Some("Unknown reason".to_string()),
                fields: vec![
                    FieldInfo {
                        name: "RES0",
                        start: 37,
                        width: 27,
                        value: 0,
                        decoded: None
                    },
                    FieldInfo {
                        name: "ISS2",
                        start: 32,
                        width: 5,
                        value: 0,
                        decoded: None
                    },
                    FieldInfo {
                        name: "EC",
                        start: 26,
                        width: 6,
                        value: 0,
                        decoded: Some(Decoded {
                            description: Some("Unknown reason".to_string()),
                            fields: vec![]
                        })
                    },
                    FieldInfo {
                        name: "IL",
                        start: 25,
                        width: 1,
                        value: 0,
                        decoded: Some(Decoded {
                            description: Some("16-bit instruction trapped".to_string()),
                            fields: vec![]
                        })
                    },
                    FieldInfo {
                        name: "ISS",
                        start: 0,
                        width: 25,
                        value: 0,
                        decoded: Some(Decoded {
                            description: Some("ISS is RES0".to_string()),
                            fields: vec![]
                        })
                    }
                ]
            }
        );
    }
}

/// Parse a decimal or hexadecimal number.
pub fn parse_number(s: &str) -> Result<u64, ParseIntError> {
    if let Some(hex) = s.strip_prefix("0x") {
        u64::from_str_radix(hex, 16)
    } else {
        s.parse()
    }
}
<commit_msg>More Rustdoc.<commit_after>// Copyright 2021 Google LLC
//
// 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
//
//     https://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.

mod abort;
mod common;
mod ldc;
mod mcr;
mod wf;

use abort::{decode_iss_data_abort, decode_iss_instruction_abort};
use bit_field::BitField;
use ldc::decode_iss_ldc;
use mcr::{decode_iss_mcr, decode_iss_mcrr};
use std::fmt::{self, Debug, Display, Formatter};
use std::num::ParseIntError;
use thiserror::Error;
use wf::decode_iss_wf;

/// Information about a particular field.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct FieldInfo {
    /// The short name of the field, e.g. "ISS".
    pub name: &'static str,
    /// The index of the lowest bit of the field.
    pub start: usize,
    /// The number of bits in the field.
    pub width: usize,
    /// The value of the field.
    pub value: u64,
    /// More information about the field and subfields, if available.
    pub decoded: Option<Decoded>,
}

impl FieldInfo {
    fn get(register: u64, name: &'static str, start: usize, end: usize) -> Self {
        let value = register.get_bits(start..end);
        Self {
            name,
            start,
            width: end - start,
            value,
            decoded: None,
        }
    }

    fn get_bit(register: u64, name: &'static str, bit: usize) -> Self {
        Self::get(register, name, bit, bit + 1)
    }

    fn with_decoded(self, decoded: Decoded) -> Self {
        Self {
            decoded: Some(decoded),
            ..self
        }
    }

    fn with_description(self, description: String) -> Self {
        self.with_decoded(Decoded {
            description: Some(description),
            fields: vec![],
        })
    }

    fn as_bit(&self) -> bool {
        assert!(self.width == 1);
        self.value == 1
    }

    /// Assuming this field has a width of exactly 1, describe it with the given function.
    ///
    /// Panics if `self.width != 1`.
    fn describe_bit<F>(self, describer: F) -> Self
    where
        F: FnOnce(bool) -> &'static str,
    {
        let bit = self.as_bit();
        let description = describer(bit).to_string();
        self.with_description(description)
    }

    fn describe<F>(self, describer: F) -> Result<Self, DecodeError>
    where
        F: FnOnce(u64) -> Result<&'static str, DecodeError>,
    {
        let description = describer(self.value)?.to_string();
        Ok(self.with_description(description))
    }

    fn check_res0(self) -> Result<Self, DecodeError> {
        if self.value != 0 {
            Err(DecodeError::InvalidRes0 { res0: self.value })
        } else {
            Ok(self)
        }
    }

    /// Returns the value as a hexadecimal string, or "true" or "false" if it is a single bit.
    pub fn value_string(&self) -> String {
        if self.width == 1 {
            if self.value == 1 { "true" } else { "false" }.to_string()
        } else {
            format!("{:#01$x}", self.value, (self.width + 3) / 4 + 2,)
        }
    }

    /// Returns the value as a binary strings.
    pub fn value_binary_string(&self) -> String {
        format!("{:#01$b}", self.value, self.width + 2)
    }
}

impl Display for FieldInfo {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        if self.width == 1 {
            write!(
                f,
                "{}: {}",
                self.name,
                if self.value == 1 { "true" } else { "false" }
            )
        } else {
            write!(
                f,
                "{}: {} {}",
                self.name,
                self.value_string(),
                self.value_binary_string(),
            )
        }
    }
}

/// An error decoding an ESR value.
#[derive(Debug, Error)]
pub enum DecodeError {
    /// A RES0 field was not 0.
    #[error("Invalid ESR, res0 is {res0:#x}")]
    InvalidRes0 { res0: u64 },
    /// The EC field had an invalid value.
    #[error("Invalid EC {ec:#x}")]
    InvalidEc { ec: u64 },
    /// The DFSC or IFSC field had an invalid value.
    #[error("Invalid DFSC or IFSC {fsc:#x}")]
    InvalidFsc { fsc: u64 },
    /// The SET field had an invalid value.
    #[error("Invalid SET {set:#x}")]
    InvalidSet { set: u64 },
    /// The AM field had an invalid value.
    #[error("Invalid AM {am:#x}")]
    InvalidAm { am: u64 },
}

/// Information about the decoding of a field (or the entire ESR value).
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Decoded {
    /// A description explaining the field value, if available.
    pub description: Option<String>,
    /// Any sub-fields.
    pub fields: Vec<FieldInfo>,
}

fn decode_iss_res0(iss: u64) -> Result<Decoded, DecodeError> {
    if iss == 0 {
        Ok(Decoded {
            description: Some("ISS is RES0".to_string()),
            fields: vec![],
        })
    } else {
        Err(DecodeError::InvalidRes0 { res0: iss })
    }
}

/// Decodes the given Exception Syndrome Register value, or returns an error if it is not valid.
pub fn decode(esr: u64) -> Result<Decoded, DecodeError> {
    let res0 = FieldInfo::get(esr, "RES0", 37, 64).check_res0()?;
    let iss2 = FieldInfo::get(esr, "ISS2", 32, 37);
    let ec = FieldInfo::get(esr, "EC", 26, 32);
    let il = FieldInfo::get_bit(esr, "IL", 25).describe_bit(describe_il);
    let iss = FieldInfo::get(esr, "ISS", 0, 25);
    let (class, iss_decoded) = match ec.value {
        0b000000 => ("Unknown reason", Some(decode_iss_res0(iss.value)?)),
        0b000001 => ("Wrapped WF* instruction execution", Some(decode_iss_wf(iss.value)?)),
        0b000011 => ("Trapped MCR or MRC access with coproc=0b1111", Some(decode_iss_mcr(iss.value)?)),
        0b000100 => ("Trapped MCRR or MRRC access with coproc=0b1111", Some(decode_iss_mcrr(iss.value)?)),
        0b000101 => ("Trapped MCR or MRC access with coproc=0b1110", Some(decode_iss_mcr(iss.value)?)),
        0b000110 => ("Trapped LDC or STC access", Some(decode_iss_ldc(iss.value)?)),
        0b000111 => ("Trapped access to SVE, Advanced SIMD or floating point", None),
        0b001010 => ("Trapped execution of an LD64B, ST64B, ST64BV, or ST64BV0 instruction", None),
        0b001100 => ("Trapped MRRC access with (coproc==0b1110)", None),
        0b001101 => ("Branch Target Exception", None),
        0b001110 => ("Illegal Execution state", Some(decode_iss_res0(iss.value)?)),
        0b010001 => ("SVC instruction execution in AArch32 state", None),
        0b010101 => ("SVC instruction execution in AArch64 state", None),
        0b011000 => ("Trapped MSR, MRS or System instruction execution in AArch64 state", None),
        0b011001 => ("Access to SVE functionality trapped as a result of CPACR_EL1.ZEN, CPTR_EL2.ZEN, CPTR_EL2.TZ, or CPTR_EL3.EZ", Some(decode_iss_res0(iss.value)?)),
        0b011100 => ("Exception from a Pointer Authentication instruction authentication failure", None),
        0b100000 => ("Instruction Abort from a lower Exception level", Some(decode_iss_instruction_abort(iss.value)?)),
        0b100001 => ("Instruction Abort taken without a change in Exception level", Some(decode_iss_instruction_abort(iss.value)?)),
        0b100010 => ("PC alignment fault exception", Some(decode_iss_res0(iss.value)?)),
        0b100100 => ("Data Abort from a lower Exception level", Some(decode_iss_data_abort(iss.value)?)),
        0b100101 => ("Data Abort taken without a change in Exception level", Some(decode_iss_data_abort(iss.value)?)),
        0b100110 => ("SP alignment fault exception", Some(decode_iss_res0(iss.value)?)),
        0b101000 => ("Trapped floating-point exception taken from AArch32 state", None),
        0b101100 => ("Trapped floating-point exception taken from AArch64 state", None),
        0b101111 => ("SError interrupt", None),
        0b110000 => ("Breakpoint exception from a lower Exception level", None),
        0b110001 => ("Breakpoint exception taken without a change in Exception level", None),
        0b110010 => ("Software Step exception from a lower Exception level", None),
        0b110011 => ("Software Step exception taken without a change in Exception level", None),
        0b110100 => ("Watchpoint exception from a lower Exception level", None),
        0b110101 => ("Watchpoint exception taken without a change in Exception level", None),
        0b111000 => ("BKPT instruction execution in AArch32 state", None),
        0b111100 => ("BRK instruction execution in AArch64 state", None),
        _ => return Err(DecodeError::InvalidEc { ec: ec.value }),
    };
    let iss = FieldInfo {
        decoded: iss_decoded,
        ..iss
    };
    let ec = ec.with_decoded(Decoded {
        description: Some(class.to_string()),
        fields: vec![],
    });
    Ok(Decoded {
        description: Some(class.to_string()),
        fields: vec![res0, iss2, ec, il, iss],
    })
}

fn describe_il(il: bool) -> &'static str {
    if il {
        "32-bit instruction trapped"
    } else {
        "16-bit instruction trapped"
    }
}

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

    #[test]
    fn unknown() {
        let decoded = decode(0).unwrap();
        assert_eq!(
            decoded,
            Decoded {
                description: Some("Unknown reason".to_string()),
                fields: vec![
                    FieldInfo {
                        name: "RES0",
                        start: 37,
                        width: 27,
                        value: 0,
                        decoded: None
                    },
                    FieldInfo {
                        name: "ISS2",
                        start: 32,
                        width: 5,
                        value: 0,
                        decoded: None
                    },
                    FieldInfo {
                        name: "EC",
                        start: 26,
                        width: 6,
                        value: 0,
                        decoded: Some(Decoded {
                            description: Some("Unknown reason".to_string()),
                            fields: vec![]
                        })
                    },
                    FieldInfo {
                        name: "IL",
                        start: 25,
                        width: 1,
                        value: 0,
                        decoded: Some(Decoded {
                            description: Some("16-bit instruction trapped".to_string()),
                            fields: vec![]
                        })
                    },
                    FieldInfo {
                        name: "ISS",
                        start: 0,
                        width: 25,
                        value: 0,
                        decoded: Some(Decoded {
                            description: Some("ISS is RES0".to_string()),
                            fields: vec![]
                        })
                    }
                ]
            }
        );
    }
}

/// Parses a decimal or hexadecimal number from a string.
///
/// If the string starts with `"0x"` then it will be parsed as hexadecimal, otherwise it will be
/// assumed to be decimal.
pub fn parse_number(s: &str) -> Result<u64, ParseIntError> {
    if let Some(hex) = s.strip_prefix("0x") {
        u64::from_str_radix(hex, 16)
    } else {
        s.parse()
    }
}
<|endoftext|>


<commit_before>extern crate antidote;
extern crate chrono;
extern crate config;
extern crate data_encoding;
#[macro_use]
extern crate failure;
extern crate fern;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
#[cfg(test)]
extern crate rand;
extern crate reqwest;
extern crate serde;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate serde_json;
#[cfg(test)]
extern crate spectral;
#[cfg(test)]
extern crate test_server;

mod ctapi;
mod http;
mod logging;
mod settings;

use crate::ctapi::close::close;
use crate::ctapi::data::data;
use crate::ctapi::init::init;
use crate::ctapi::status::Status;
use crate::settings::Settings;
use antidote::RwLock;
use std::panic;

lazy_static! {
    pub(crate) static ref CONFIG: RwLock<Settings> =
        RwLock::new(Settings::init().expect("Failed to init configuration!"));
}

#[no_mangle]
pub extern "system" fn CT_init(ctn: u16, pn: u16) -> i8 {
    logging::init();

    debug!("CT_init(ctn: {}, pn: {})", ctn, pn);
    let status: i8 = match init(ctn, pn) {
        Ok(status) => status.value(),
        Err(why) => {
            error!("Failure during CT_init!");
            debug!("{}", why);
            Status::ERR_HTSI.value()
        }
    };

    debug!("Returning {}", status);
    status
}

#[no_mangle]
pub extern "system" fn CT_data(
    ctn: u16,
    dad: *mut u8,
    sad: *mut u8,
    lenc: u16,
    command: *const u8,
    lenr: *mut u16,
    response: *mut u8,
) -> i8 {
    logging::init();

    if dad.is_null() {
        error!("Null pointer passed into CT_data() as dad");
        return Status::ERR_HTSI.value();
    }

    if sad.is_null() {
        error!("Null pointer passed into CT_data() as sad");
        return Status::ERR_HTSI.value();
    }

    if lenr.is_null() {
        error!("Null pointer passed into CT_data() as lenr");
        return Status::ERR_HTSI.value();
    }

    if response.is_null() {
        error!("Null pointer passed into CT_data() as response");
        return Status::ERR_HTSI.value();
    }

    debug!("CT_data(ctn: {})", ctn);
    let status: i8 =
        match panic::catch_unwind(|| data(ctn, dad, sad, lenc, command, lenr, response)) {
            Ok(result) => match result {
                Ok(status) => status.value(),
                Err(why) => {
                    error!("Failure during CT_data!");
                    debug!("{}", why);
                    Status::ERR_HTSI.value()
                }
            },
            Err(_) => {
                error!("Caught panic!");
                Status::ERR_HTSI.value()
            }
        };

    debug!("Returning {}", status);
    status
}

#[no_mangle]
pub extern "system" fn CT_close(ctn: u16) -> i8 {
    logging::init();

    debug!("CT_close(ctn: {})", ctn);
    let status = match close(ctn) {
        Ok(status) => status.value(),
        Err(why) => {
            error!("Failure during CT_close!");
            debug!("{}", why);
            Status::ERR_HTSI.value()
        }
    };

    debug!("Returning {}", status);
    status
}
<commit_msg>enable more linting<commit_after>extern crate antidote;
extern crate chrono;
extern crate config;
extern crate data_encoding;
#![deny(unused_features)]
#![deny(deprecated)]
#![warn(unused_variables)]
#![warn(unused_imports)]
#![warn(dead_code)]
#![warn(missing_copy_implementations)]

#[macro_use]
extern crate failure;
extern crate fern;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
#[cfg(test)]
extern crate rand;
extern crate reqwest;
extern crate serde;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate serde_json;
#[cfg(test)]
extern crate spectral;
#[cfg(test)]
extern crate test_server;

mod ctapi;
mod http;
mod logging;
mod settings;

use crate::ctapi::close::close;
use crate::ctapi::data::data;
use crate::ctapi::init::init;
use crate::ctapi::status::Status;
use crate::settings::Settings;
use antidote::RwLock;
use std::panic;

lazy_static! {
    pub(crate) static ref CONFIG: RwLock<Settings> =
        RwLock::new(Settings::init().expect("Failed to init configuration!"));
}

#[no_mangle]
pub extern "system" fn CT_init(ctn: u16, pn: u16) -> i8 {
    logging::init();

    debug!("CT_init(ctn: {}, pn: {})", ctn, pn);
    let status: i8 = match init(ctn, pn) {
        Ok(status) => status.value(),
        Err(why) => {
            error!("Failure during CT_init!");
            debug!("{}", why);
            Status::ERR_HTSI.value()
        }
    };

    debug!("Returning {}", status);
    status
}

#[no_mangle]
pub extern "system" fn CT_data(
    ctn: u16,
    dad: *mut u8,
    sad: *mut u8,
    lenc: u16,
    command: *const u8,
    lenr: *mut u16,
    response: *mut u8,
) -> i8 {
    logging::init();

    if dad.is_null() {
        error!("Null pointer passed into CT_data() as dad");
        return Status::ERR_HTSI.value();
    }

    if sad.is_null() {
        error!("Null pointer passed into CT_data() as sad");
        return Status::ERR_HTSI.value();
    }

    if lenr.is_null() {
        error!("Null pointer passed into CT_data() as lenr");
        return Status::ERR_HTSI.value();
    }

    if response.is_null() {
        error!("Null pointer passed into CT_data() as response");
        return Status::ERR_HTSI.value();
    }

    debug!("CT_data(ctn: {})", ctn);
    let status: i8 =
        match panic::catch_unwind(|| data(ctn, dad, sad, lenc, command, lenr, response)) {
            Ok(result) => match result {
                Ok(status) => status.value(),
                Err(why) => {
                    error!("Failure during CT_data!");
                    debug!("{}", why);
                    Status::ERR_HTSI.value()
                }
            },
            Err(_) => {
                error!("Caught panic!");
                Status::ERR_HTSI.value()
            }
        };

    debug!("Returning {}", status);
    status
}

#[no_mangle]
pub extern "system" fn CT_close(ctn: u16) -> i8 {
    logging::init();

    debug!("CT_close(ctn: {})", ctn);
    let status = match close(ctn) {
        Ok(status) => status.value(),
        Err(why) => {
            error!("Failure during CT_close!");
            debug!("{}", why);
            Status::ERR_HTSI.value()
        }
    };

    debug!("Returning {}", status);
    status
}
<|endoftext|>


<commit_before>//! Pure Rust implementation of Ryū, an algorithm to quickly convert floating
//! point numbers to decimal strings.
//!
//! The PLDI'18 paper [*Ryū: fast float-to-string conversion*][paper] by Ulf
//! Adams includes a complete correctness proof of the algorithm. The paper is
//! available under the creative commons CC-BY-SA license.
//!
//! This Rust implementation is a line-by-line port of Ulf Adams' implementation
//! in C, [https://github.com/ulfjack/ryu][upstream]. The [`ryu::raw`][raw]
//! module exposes exactly the API and formatting of the C implementation as
//! unsafe pure Rust functions. There is additionally a safe API as demonstrated
//! in the example code below. The safe API uses the same underlying Ryū
//! algorithm but diverges from the formatting of the C implementation to
//! produce more human-readable output, for example `0.3` rather than `3E-1`.
//!
//! [paper]: https://dl.acm.org/citation.cfm?id=3192369
//! [upstream]: https://github.com/ulfjack/ryu
//! [raw]: raw/index.html
//!
//! # Example
//!
//! ```edition2018
//! fn main() {
//!     let mut buffer = ryu::Buffer::new();
//!     let printed = buffer.format(1.234);
//!     assert_eq!(printed, "1.234");
//! }
//! ```
//!
//! ## Performance
//!
//! You can run upstream's benchmarks with:
//!
//! ```console
//! $ git clone https://github.com/ulfjack/ryu c-ryu
//! $ cd c-ryu
//! $ bazel run -c opt //ryu/benchmark
//! ```
//!
//! And the same benchmark against our implementation with:
//!
//! ```console
//! $ git clone https://github.com/dtolnay/ryu rust-ryu
//! $ cd rust-ryu
//! $ cargo run --example upstream_benchmark --release
//! ```
//!
//! These benchmarks measure the average time to print a 32-bit float and average
//! time to print a 64-bit float, where the inputs are distributed as uniform random
//! bit patterns 32 and 64 bits wide.
//!
//! The upstream C code, the unsafe direct Rust port, and the safe pretty Rust API
//! all perform the same, taking around 21 nanoseconds to format a 32-bit float and
//! 31 nanoseconds to format a 64-bit float.
//!
//! There is also a Rust-specific benchmark comparing this implementation to the
//! standard library which you can run with:
//!
//! ```console
//! $ cargo bench
//! ```
//!
//! The benchmark shows Ryu approximately 4-10x faster than the standard library
//! across a range of f32 and f64 inputs. Measurements are in nanoseconds per
//! iteration; smaller is better.
//!
//! | type=f32 | 0.0  | 0.1234 | 2.718281828459045 | f32::MAX |
//! |:--------:|:----:|:------:|:-----------------:|:--------:|
//! | RYU      | 3ns  | 28ns   | 23ns              | 22ns     |
//! | STD      | 40ns | 106ns  | 128ns             | 110ns    |
//!
//! | type=f64 | 0.0  | 0.1234 | 2.718281828459045 | f64::MAX |
//! |:--------:|:----:|:------:|:-----------------:|:--------:|
//! | RYU      | 3ns  | 50ns   | 35ns              | 32ns     |
//! | STD      | 39ns | 105ns  | 128ns             | 202ns    |
//!
//! ## Formatting
//!
//! This library tends to produce more human-readable output than the standard
//! library's to\_string, which never uses scientific notation. Here are two
//! examples:
//!
//! - *ryu:* 1.23e40, *std:* 12300000000000000000000000000000000000000
//! - *ryu:* 1.23e-40, *std:* 0.000000000000000000000000000000000000000123
//!
//! Both libraries print short decimals such as 0.0000123 without scientific
//! notation.

#![no_std]
#![doc(html_root_url = "https://docs.rs/ryu/0.2.8")]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr(
    feature = "cargo-clippy",
    allow(
        cast_lossless,
        cyclomatic_complexity,
        many_single_char_names,
        needless_pass_by_value,
        unreadable_literal,
    )
)]

#[cfg(feature = "no-panic")]
extern crate no_panic;

mod buffer;
mod common;
mod d2s;
#[cfg(not(feature = "small"))]
mod d2s_full_table;
mod d2s_intrinsics;
#[cfg(feature = "small")]
mod d2s_small_table;
mod digit_table;
mod f2s;
mod pretty;

pub use buffer::{Buffer, Float};

/// Unsafe functions that exactly mirror the API of the C implementation of Ryū.
pub mod raw {
    pub use d2s::d2s_buffered_n;
    pub use f2s::f2s_buffered_n;
    pub use pretty::d2s_buffered_n as pretty_d2s_buffered_n;
    pub use pretty::f2s_buffered_n as pretty_f2s_buffered_n;
}
<commit_msg>Remove clippy exclusions that no longer trigger<commit_after>//! Pure Rust implementation of Ryū, an algorithm to quickly convert floating
//! point numbers to decimal strings.
//!
//! The PLDI'18 paper [*Ryū: fast float-to-string conversion*][paper] by Ulf
//! Adams includes a complete correctness proof of the algorithm. The paper is
//! available under the creative commons CC-BY-SA license.
//!
//! This Rust implementation is a line-by-line port of Ulf Adams' implementation
//! in C, [https://github.com/ulfjack/ryu][upstream]. The [`ryu::raw`][raw]
//! module exposes exactly the API and formatting of the C implementation as
//! unsafe pure Rust functions. There is additionally a safe API as demonstrated
//! in the example code below. The safe API uses the same underlying Ryū
//! algorithm but diverges from the formatting of the C implementation to
//! produce more human-readable output, for example `0.3` rather than `3E-1`.
//!
//! [paper]: https://dl.acm.org/citation.cfm?id=3192369
//! [upstream]: https://github.com/ulfjack/ryu
//! [raw]: raw/index.html
//!
//! # Example
//!
//! ```edition2018
//! fn main() {
//!     let mut buffer = ryu::Buffer::new();
//!     let printed = buffer.format(1.234);
//!     assert_eq!(printed, "1.234");
//! }
//! ```
//!
//! ## Performance
//!
//! You can run upstream's benchmarks with:
//!
//! ```console
//! $ git clone https://github.com/ulfjack/ryu c-ryu
//! $ cd c-ryu
//! $ bazel run -c opt //ryu/benchmark
//! ```
//!
//! And the same benchmark against our implementation with:
//!
//! ```console
//! $ git clone https://github.com/dtolnay/ryu rust-ryu
//! $ cd rust-ryu
//! $ cargo run --example upstream_benchmark --release
//! ```
//!
//! These benchmarks measure the average time to print a 32-bit float and average
//! time to print a 64-bit float, where the inputs are distributed as uniform random
//! bit patterns 32 and 64 bits wide.
//!
//! The upstream C code, the unsafe direct Rust port, and the safe pretty Rust API
//! all perform the same, taking around 21 nanoseconds to format a 32-bit float and
//! 31 nanoseconds to format a 64-bit float.
//!
//! There is also a Rust-specific benchmark comparing this implementation to the
//! standard library which you can run with:
//!
//! ```console
//! $ cargo bench
//! ```
//!
//! The benchmark shows Ryu approximately 4-10x faster than the standard library
//! across a range of f32 and f64 inputs. Measurements are in nanoseconds per
//! iteration; smaller is better.
//!
//! | type=f32 | 0.0  | 0.1234 | 2.718281828459045 | f32::MAX |
//! |:--------:|:----:|:------:|:-----------------:|:--------:|
//! | RYU      | 3ns  | 28ns   | 23ns              | 22ns     |
//! | STD      | 40ns | 106ns  | 128ns             | 110ns    |
//!
//! | type=f64 | 0.0  | 0.1234 | 2.718281828459045 | f64::MAX |
//! |:--------:|:----:|:------:|:-----------------:|:--------:|
//! | RYU      | 3ns  | 50ns   | 35ns              | 32ns     |
//! | STD      | 39ns | 105ns  | 128ns             | 202ns    |
//!
//! ## Formatting
//!
//! This library tends to produce more human-readable output than the standard
//! library's to\_string, which never uses scientific notation. Here are two
//! examples:
//!
//! - *ryu:* 1.23e40, *std:* 12300000000000000000000000000000000000000
//! - *ryu:* 1.23e-40, *std:* 0.000000000000000000000000000000000000000123
//!
//! Both libraries print short decimals such as 0.0000123 without scientific
//! notation.

#![no_std]
#![doc(html_root_url = "https://docs.rs/ryu/0.2.8")]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr(
    feature = "cargo-clippy",
    allow(
        cast_lossless,
        many_single_char_names,
        unreadable_literal,
    )
)]

#[cfg(feature = "no-panic")]
extern crate no_panic;

mod buffer;
mod common;
mod d2s;
#[cfg(not(feature = "small"))]
mod d2s_full_table;
mod d2s_intrinsics;
#[cfg(feature = "small")]
mod d2s_small_table;
mod digit_table;
mod f2s;
mod pretty;

pub use buffer::{Buffer, Float};

/// Unsafe functions that exactly mirror the API of the C implementation of Ryū.
pub mod raw {
    pub use d2s::d2s_buffered_n;
    pub use f2s::f2s_buffered_n;
    pub use pretty::d2s_buffered_n as pretty_d2s_buffered_n;
    pub use pretty::f2s_buffered_n as pretty_f2s_buffered_n;
}
<|endoftext|>


<commit_before>//! This crate provides a simple interface to liblzma.  LZMA is more commonly known as XZ or 7zip,
//! (as in, files with the `.xz` or `.7z` file extension). LZMA compression is fast and aggressive,
//! compressing better than bzip2.  liblzma implements the XZ variant, so it can read and write
//! `.xz` files/streams.
//!
//! Two interfaces are provided.  `LzmaReader`/`LzmaWriter` are generic Readers and Writers that
//! can be composed with other `Read`/`Write` interfaces.  For example, wrap them around a `File`
//! and you can write data to a file while compressing it on the fly, or stream in an `xz` file
//! from disk.
//!
//! `compress`/`decompress` are easy to use functions for simple use cases.
//!
//! See the `LzmaReader` and `LzmaWriter` documentation for further details on that interface.
//! `compress` and `decompress` are documented here.
//!
//! # Examples
//!
//! ```
//! let test_string = "Like tears in rain".to_string();
//! let mut compressed = lzma::compress(&test_string.into_bytes(), 6).unwrap();
//! let decompressed = lzma::decompress(&mut compressed).unwrap();
//! let decompressed_str = String::from_utf8(decompressed).unwrap();
//!
//! assert_eq!("Like tears in rain", decompressed_str);
//! ```

extern crate libc;

pub enum Direction {
	Compress,
	Decompress,
}

pub mod lzma_sys;
pub mod lzma_stream_wrapper;
pub mod reader;
pub mod writer;
pub mod error;

use std::io::{Write, Read, Cursor};
pub use reader::LzmaReader;
pub use writer::LzmaWriter;
pub use error::LzmaError;

pub const EXTREME_PRESET: u32 = (1 << 31);

/// Compress `buf` and return the result.
///
/// preset is [0-9] and corresponds to xz's presets.
/// Binary-or with EXTREME_PRESET for --extreme (e.g. 9 | EXTREME_PRESET).
pub fn compress(buf: &[u8], preset: u32) -> Result<Vec<u8>, LzmaError> {
	let mut output: Vec<u8> = Vec::new();

	{
		let mut pipe = try!(LzmaWriter::new_compressor(&mut output, preset));

		try!(pipe.write_all(buf));
		try!(pipe.finish());
	}

	Ok(output)
}

/// Decompress `buf` and return the result.
pub fn decompress(buf: &[u8]) -> Result<Vec<u8>, LzmaError> {
	let mut output: Vec<u8> = Vec::new();

	{
		let mut cursor = Cursor::new(buf);
		let mut pipe = try!(LzmaReader::new_decompressor(&mut cursor));

		try!(pipe.read_to_end(&mut output));
	}

	Ok(output)
}
<commit_msg>Simplified implementation for compress and decompress helper functions.<commit_after>//! This crate provides a simple interface to liblzma.  LZMA is more commonly known as XZ or 7zip,
//! (as in, files with the `.xz` or `.7z` file extension). LZMA compression is fast and aggressive,
//! compressing better than bzip2.  liblzma implements the XZ variant, so it can read and write
//! `.xz` files/streams.
//!
//! Two interfaces are provided.  `LzmaReader`/`LzmaWriter` are generic Readers and Writers that
//! can be composed with other `Read`/`Write` interfaces.  For example, wrap them around a `File`
//! and you can write data to a file while compressing it on the fly, or stream in an `xz` file
//! from disk.
//!
//! `compress`/`decompress` are easy to use functions for simple use cases.
//!
//! See the `LzmaReader` and `LzmaWriter` documentation for further details on that interface.
//! `compress` and `decompress` are documented here.
//!
//! # Examples
//!
//! ```
//! let test_string = "Like tears in rain".to_string();
//! let mut compressed = lzma::compress(&test_string.into_bytes(), 6).unwrap();
//! let decompressed = lzma::decompress(&mut compressed).unwrap();
//! let decompressed_str = String::from_utf8(decompressed).unwrap();
//!
//! assert_eq!("Like tears in rain", decompressed_str);
//! ```

extern crate libc;

pub enum Direction {
	Compress,
	Decompress,
}

pub mod lzma_sys;
pub mod lzma_stream_wrapper;
pub mod reader;
pub mod writer;
pub mod error;

use std::io::Read;
pub use reader::LzmaReader;
pub use writer::LzmaWriter;
pub use error::LzmaError;

pub const EXTREME_PRESET: u32 = (1 << 31);

/// Compress `buf` and return the result.
///
/// preset is [0-9] and corresponds to xz's presets.
/// Binary-or with EXTREME_PRESET for --extreme (e.g. 9 | EXTREME_PRESET).
pub fn compress(buf: &[u8], preset: u32) -> Result<Vec<u8>, LzmaError> {
	let mut output: Vec<u8> = Vec::new();

	{
		let mut reader = try!(LzmaReader::new_compressor(buf, preset));

		try!(reader.read_to_end(&mut output));
	}

	Ok(output)
}

/// Decompress `buf` and return the result.
pub fn decompress(buf: &[u8]) -> Result<Vec<u8>, LzmaError> {
	let mut output: Vec<u8> = Vec::new();

	{
		let mut reader = try!(LzmaReader::new_decompressor(buf));

		try!(reader.read_to_end(&mut output));
	}

	Ok(output)
}
<|endoftext|>


<commit_before>use std::libc;

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

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

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

pub fn i32(data: *const i32, length: usize, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(transmute(data), length, name_cstr.as_ptr());
  }
}

pub fn u32(data: *const u32, length: usize, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(transmute(data), length, name_cstr.as_ptr());
  }
}
<commit_msg>Update lib.rs<commit_after>extern crate libc;

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

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

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

pub fn i32(data: *const i32, length: usize, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(transmute(data), length, name_cstr.as_ptr());
  }
}

pub fn u32(data: *const u32, length: usize, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(transmute(data), length, name_cstr.as_ptr());
  }
}
<|endoftext|>


<commit_before>#![allow(dead_code)]
use std::rc::Rc;
use std::cell::RefCell;
use std::fmt;
use std::ops::{Drop, Deref, DerefMut};
use std::convert::{AsRef, AsMut};

pub trait Recycleable {
  fn new() -> Self;
  fn reset(&mut self);
}

pub trait InitializeWith<T> {
  fn initialize_with(&mut self, source: T);
}

impl Recycleable for String {
  #[inline]
  fn new() -> String {
    String::new()
  }
  #[inline]
  fn reset(&mut self) {
    self.clear();
  }
}

impl <T> Recycleable for Vec<T> {
  #[inline]
  fn new() -> Vec<T> {
    Vec::new()
  }
  #[inline]
  fn reset(&mut self) {
    self.clear();
  }
}

impl <A> InitializeWith<A> for String where A : AsRef<str> {
  #[inline]
  fn initialize_with(&mut self, source: A) {
    let s : &str = source.as_ref();
    self.push_str(s);
  }
}

pub struct Recycled<T> where T : Recycleable {
  pub value: Option<T>,
  pool: Rc<RefCell<Vec<T>>>
}

impl <T> Drop for Recycled<T> where T : Recycleable {
  #[inline]
  fn drop(&mut self) {
    if let Some(mut value) = self.value.take() {
      value.reset();
      self.pool.borrow_mut().push(value);
    }
  }
}

impl <T> AsRef<T> for Recycled<T> where T : Recycleable {
   fn as_ref(&self) -> &T {
    match self.value.as_ref() {
      Some(v) => v,
      None => panic!("Recycled<T> smartpointer missing its value.")
    }
  }
}

impl <T> AsMut<T> for Recycled<T> where T : Recycleable {
   fn as_mut(&mut self) -> &mut T {
    match self.value.as_mut() {
      Some(v) => v,
      None => panic!("Recycled<T> smartpointer missing its value.")
    }
  }
}

impl <T> fmt::Display for Recycled<T> where T : fmt::Display + Recycleable {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    match self.value {
      Some(ref s) => s.fmt(f),
      None => write!(f, "Empty Recycled<T>")
    }
  }
}

impl <T> Deref for Recycled<T> where T : Recycleable {
  type Target = T;
  #[inline]
  fn deref<'a>(&'a self) -> &'a T {
    self.as_ref()
  }
}

impl <T> DerefMut for Recycled<T> where T : Recycleable {
  #[inline]
  fn deref_mut<'a>(&'a mut self) -> &'a mut T {
    self.as_mut()
  }
}

impl <T> Recycled<T> where T : Recycleable {
  #[inline]
  pub fn new(pool: Rc<RefCell<Vec<T>>>, value: T) -> Recycled<T> {
    Recycled {
      value: Some(value),
      pool: pool
    }
  }

  #[inline]
  pub fn new_from<A>(pool: Rc<RefCell<Vec<T>>>, mut value: T, source: A) -> Recycled<T> where T : InitializeWith<A> {
    value.initialize_with(source);
    Recycled {
      value: Some(value),
      pool: pool
    }
  }

  #[inline]
  pub fn detach(mut self) -> T {
    let value = self.value.take().unwrap();
    drop(self);
    value
  }
}

pub struct Pool <T> where T : Recycleable {
  values: Rc<RefCell<Vec<T>>>,
}

impl <T> Pool <T> where T: Recycleable {
  #[inline]
  pub fn with_size(size: u32) -> Pool <T> {
    let values: Vec<T> =
      (0..size)
      .map(|_| T::new() )
      .collect();
    Pool {
      values: Rc::new(RefCell::new(values)),
    }
  }

  #[inline]
  pub fn attach(&mut self, value: T) -> Recycled<T> {
    let pool_reference = self.values.clone();
    Recycled::new(pool_reference, value)
  }

  #[inline]
  pub fn detached(&mut self) -> T {
    match self.values.borrow_mut().pop() {
      Some(v) => v,
      None => T::new()
    }
  }

  #[inline]
  pub fn new(&mut self) -> Recycled<T> {
    let t = self.detached();
    let pool_reference = self.values.clone();
    Recycled::new(pool_reference, t)
  }

  #[inline(always)]
  pub fn new_from<A>(&mut self, source: A) -> Recycled<T> where T: InitializeWith<A> {
    let t = self.detached();
    let pool_reference = self.values.clone();
    Recycled::new_from(pool_reference, t, source)
  }

  #[inline]
  pub fn size(&self) -> usize {
    self.values.borrow().len()
  }
}
<commit_msg>Impl Debug if T does<commit_after>#![allow(dead_code)]
use std::rc::Rc;
use std::cell::RefCell;
use std::fmt;
use std::ops::{Drop, Deref, DerefMut};
use std::convert::{AsRef, AsMut};

pub trait Recycleable {
  fn new() -> Self;
  fn reset(&mut self);
}

pub trait InitializeWith<T> {
  fn initialize_with(&mut self, source: T);
}

impl Recycleable for String {
  #[inline]
  fn new() -> String {
    String::new()
  }
  #[inline]
  fn reset(&mut self) {
    self.clear();
  }
}

impl <T> Recycleable for Vec<T> {
  #[inline]
  fn new() -> Vec<T> {
    Vec::new()
  }
  #[inline]
  fn reset(&mut self) {
    self.clear();
  }
}

impl <A> InitializeWith<A> for String where A : AsRef<str> {
  #[inline]
  fn initialize_with(&mut self, source: A) {
    let s : &str = source.as_ref();
    self.push_str(s);
  }
}

pub struct Recycled<T> where T : Recycleable {
  pub value: Option<T>,
  pool: Rc<RefCell<Vec<T>>>
}

impl <T> Drop for Recycled<T> where T : Recycleable {
  #[inline]
  fn drop(&mut self) {
    if let Some(mut value) = self.value.take() {
      value.reset();
      self.pool.borrow_mut().push(value);
    }
  }
}

impl <T> AsRef<T> for Recycled<T> where T : Recycleable {
   fn as_ref(&self) -> &T {
    match self.value.as_ref() {
      Some(v) => v,
      None => panic!("Recycled<T> smartpointer missing its value.")
    }
  }
}

impl <T> AsMut<T> for Recycled<T> where T : Recycleable {
   fn as_mut(&mut self) -> &mut T {
    match self.value.as_mut() {
      Some(v) => v,
      None => panic!("Recycled<T> smartpointer missing its value.")
    }
  }
}

impl <T> fmt::Debug for Recycled<T> where T : fmt::Debug + Recycleable {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    match self.value {
      Some(ref s) => s.fmt(f),
      None => write!(f, "Empty Recycled<T>")
    }
  }
}

impl <T> fmt::Display for Recycled<T> where T : fmt::Display + Recycleable {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    match self.value {
      Some(ref s) => s.fmt(f),
      None => write!(f, "Empty Recycled<T>")
    }
  }
}

impl <T> Deref for Recycled<T> where T : Recycleable {
  type Target = T;
  #[inline]
  fn deref<'a>(&'a self) -> &'a T {
    self.as_ref()
  }
}

impl <T> DerefMut for Recycled<T> where T : Recycleable {
  #[inline]
  fn deref_mut<'a>(&'a mut self) -> &'a mut T {
    self.as_mut()
  }
}

impl <T> Recycled<T> where T : Recycleable {
  #[inline]
  pub fn new(pool: Rc<RefCell<Vec<T>>>, value: T) -> Recycled<T> {
    Recycled {
      value: Some(value),
      pool: pool
    }
  }

  #[inline]
  pub fn new_from<A>(pool: Rc<RefCell<Vec<T>>>, mut value: T, source: A) -> Recycled<T> where T : InitializeWith<A> {
    value.initialize_with(source);
    Recycled {
      value: Some(value),
      pool: pool
    }
  }

  #[inline]
  pub fn detach(mut self) -> T {
    let value = self.value.take().unwrap();
    drop(self);
    value
  }
}

pub struct Pool <T> where T : Recycleable {
  values: Rc<RefCell<Vec<T>>>,
}

impl <T> Pool <T> where T: Recycleable {
  #[inline]
  pub fn with_size(size: u32) -> Pool <T> {
    let values: Vec<T> =
      (0..size)
      .map(|_| T::new() )
      .collect();
    Pool {
      values: Rc::new(RefCell::new(values)),
    }
  }

  #[inline]
  pub fn attach(&mut self, value: T) -> Recycled<T> {
    let pool_reference = self.values.clone();
    Recycled::new(pool_reference, value)
  }

  #[inline]
  pub fn detached(&mut self) -> T {
    match self.values.borrow_mut().pop() {
      Some(v) => v,
      None => T::new()
    }
  }

  #[inline]
  pub fn new(&mut self) -> Recycled<T> {
    let t = self.detached();
    let pool_reference = self.values.clone();
    Recycled::new(pool_reference, t)
  }

  #[inline(always)]
  pub fn new_from<A>(&mut self, source: A) -> Recycled<T> where T: InitializeWith<A> {
    let t = self.detached();
    let pool_reference = self.values.clone();
    Recycled::new_from(pool_reference, t, source)
  }

  #[inline]
  pub fn size(&self) -> usize {
    self.values.borrow().len()
  }
}
<|endoftext|>


<commit_before>#![feature(unsafe_destructor)]
#![allow(unstable)]
extern crate cql_ffi;
extern crate uuid;
extern crate libc;

///A Rust create that provides (theoretically) safe bindings to the unsafe cql-ffi crate,
///which in turns wrap the DataStax C++ driver

pub use cass_bytes::*;
pub use cass_types::*;
pub use cass_string::*;
pub use cass_inet::*;
pub use cass_decimal::*;
pub use cass_uuid::*;
pub use cass_cluster::*;
pub use cass_session::*;
pub use cass_statement::*;
pub use cass_batch::*;
pub use cass_future::*;
pub use cass_prepared::*;
pub use cass_result::*;
pub use cass_iterator::*;
pub use cass_row::*;
pub use cass_value::*;
pub use cass_collection::*;
pub use cass_ssl::*;
pub use cass_schema::*;
pub use cass_log::*;
pub use cass_error::*;
pub use cass_consistency::*;
pub use cass_column::*;

mod cass_bytes;
mod cass_types;
mod cass_string;
mod cass_inet;
mod cass_decimal;
mod cass_uuid;
mod cass_cluster;
mod cass_session;
mod cass_statement;
mod cass_batch;
mod cass_future;
mod cass_prepared;
mod cass_result;
mod cass_iterator;
mod cass_row;
mod cass_value;
mod cass_collection;
mod cass_ssl;
mod cass_schema;
mod cass_log;
mod cass_error;
mod cass_consistency;
mod cass_column;
<commit_msg>renaming phase 1<commit_after>#![feature(unsafe_destructor)]
#![allow(unstable)]
extern crate cql_ffi;
extern crate uuid;
extern crate libc;

///A Rust create that provides (theoretically) safe bindings to the unsafe cql-ffi crate,
///which in turns wrap the DataStax C++ driver

pub use bytes::*;
pub use types::*;
pub use string::*;
pub use inet::*;
pub use decimal::*;
pub use uuid::*;
pub use cluster::*;
pub use session::*;
pub use statement::*;
pub use batch::*;
pub use future::*;
pub use prepared::*;
pub use result::*;
pub use iterator::*;
pub use row::*;
pub use value::*;
pub use collection::*;
pub use ssl::*;
pub use schema::*;
pub use log::*;
pub use error::*;
pub use consistency::*;
pub use column::*;

mod bytes;
mod types;
mod string;
mod inet;
mod decimal;
mod uuid;
mod cluster;
mod session;
mod statement;
mod batch;
mod future;
mod prepared;
mod result;
mod iterator;
mod row;
mod value;
mod collection;
mod ssl;
mod schema;
mod log;
mod error;
mod consistency;
mod column;
<|endoftext|>


<commit_before>#[macro_use(expect)]
extern crate expectest;
pub use expectest::prelude::*;

pub type TestResult = Result<(), ()>;

pub struct Context<'a> {
    pub tests: Vec<Box<FnMut() -> TestResult + 'a>>
}

impl<'a> Context<'a> {
    pub fn describe<F>(&mut self, _name: &'a str, mut body: F)
        where F : 'a + FnMut(&mut Context<'a>) -> () {
        body(self)
    }

    pub fn it<F>(&mut self, _name: &'a str, body: F)
        where F : 'a + FnMut() -> TestResult {

        self.tests.push(Box::new(body))
    }
}

pub fn describe<'a, 'b, F>(_block_name: &'b str, body: F) -> Runner<'a>
    where F : 'a + FnOnce(&mut Context<'a>) -> () {

    let mut c = Context { tests: vec!() };
    body(&mut c);
    Runner { describe: c, report: None }
}

pub struct Runner<'a> {
    describe: Context<'a>,
    report: Option<Result<TestReport, TestReport>>
}

#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
pub struct TestReport {
    total_tests: u32,
    success_count: u32,
    error_count: u32
}

impl<'a> Runner<'a> {

    pub fn run(&mut self) -> Result<(), ()> {
        use std::panic::{catch_unwind, AssertUnwindSafe};

        let mut report = TestReport::default();
        let mut result = Ok(());

        for test_function in self.describe.tests.iter_mut() {
            let res = match catch_unwind(AssertUnwindSafe(|| test_function())) {
                Ok(res) => res,
                _ => Err(())
            };

            result = match result {
                Ok(()) => { report.success_count += 1; res },
                old @ _ => { report.error_count += 1; old }
            };

            report.total_tests += 1;
        }

        if let Ok(_) = result {
            self.report = Some(Ok(report))
        } else {
            self.report = Some(Err(report))
        }

        Ok(())
    }

    pub fn result(&self) -> Result<TestReport, TestReport> {
        self.report.unwrap_or(Ok(TestReport::default()))
    }
}

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

    mod describe {
        pub use super::*;

        #[test]
        fn it_has_a_root_describe_function() {
            describe("A Test", |_ctx|{});
        }

        #[test]
        fn it_can_call_describe_inside_describe_body() {
            describe("A Root", |ctx| {
                ctx.describe("nested describe", |_ctx| {})
            });
        }

        #[test]
        fn it_can_call_it_inside_describe_body() {
            describe("A root", |ctx| {
                ctx.it("is a test", || { Ok(()) })
            });
        }
    }

    mod runner {
        pub use super::*;

        mod run {
            pub use super::*;

            #[test]
            fn it_create_a_runner_that_can_be_runned() {
                let mut runner = describe("A root", |ctx| {
                    ctx.it("is expected to run", || {
                        assert_eq!(true, true);
                        Ok(())
                    })
                });
                expect!(runner.run()).to(be_ok());
            }

            #[test]
            fn effectively_run_tests() {
                let ran = &mut false;

                {
                    let mut runner = describe("A root", |ctx| {
                        ctx.it("is expected to run", || {
                            *ran = true;
                            Ok(())
                        })
                    });
                    runner.run().unwrap()
                }

                assert_eq!(true, *ran)
            }

            #[test]
            fn effectively_run_two_tests() {
                use std::sync::atomic::{AtomicUsize, Ordering};
                let ran_counter = &mut AtomicUsize::new(0);

                {
                    let mut runner = describe("A root", |ctx| {
                        ctx.it("first run",  || { ran_counter.fetch_add(1, Ordering::Relaxed); Ok(()) });
                        ctx.it("second run", || { ran_counter.fetch_add(1, Ordering::Relaxed); Ok(()) });
                    });
                    let _ = runner.run().unwrap();
                }

                assert_eq!(2, ran_counter.load(Ordering::Relaxed))
            }

            #[test]
            fn effectively_run_two_tests_in_nested_describe() {
                use std::sync::atomic::{AtomicUsize, Ordering};
                let ran_counter = &mut AtomicUsize::new(0);

                {
                    let mut runner = describe("A root", |ctx| {
                        ctx.describe("first describe", |ctx| {
                            ctx.it("first run",  || {
                                ran_counter.fetch_add(1, Ordering::Relaxed); Ok(())
                            });
                        });
                        ctx.describe("second describe", |ctx| {
                            ctx.it("second run",  || {
                                ran_counter.fetch_add(1, Ordering::Relaxed); Ok(())
                            });
                        });
                        ctx.describe("third describe", |ctx| {
                            ctx.describe("fourth describe", |ctx| {
                                ctx.it("third run",  || {
                                    ran_counter.fetch_add(1, Ordering::Relaxed); Ok(())
                                });
                            })
                        })
                    });
                    let _ = runner.run().unwrap();
                }

                assert_eq!(3, ran_counter.load(Ordering::Relaxed))
            }
        }

        mod results {
            pub use super::*;

            #[test]
            fn tests_can_fail_with_an_error_result() {
                let mut runner = describe("A root", |ctx| {
                    ctx.it("should fail", || {
                        Err(())
                    })
                });
                runner.run().unwrap();

                expect!(runner.result()).to(be_err());
            }

            #[test]
            fn should_be_ok_if_tests_are_ok() {
                let mut runner = describe("A root", |ctx| {
                    ctx.it("should be ok", || { Ok(()) })
                });
                runner.run().unwrap();

                expect!(runner.result()).to(be_ok());
            }

            #[test]
            fn is_ok_if_no_tests_have_been_runned() {
                let mut runner = describe("A root", |_ctx| {});
                runner.run().unwrap();

                expect!(runner.result()).to(be_ok());
            }

            #[test]
            fn is_err_if_one_test_is_err() {
                let mut runner = describe("A root", |ctx| {
                    ctx.it("an err", || { Err(()) });
                    ctx.it("an ok", || { Ok(()) });
                });
                runner.run().unwrap();

                expect!(runner.result()).to(be_err());
            }

            #[test]
            fn is_ok_if_all_tests_are_ok() {
                let mut runner = describe("A root", |ctx| {
                    ctx.it("ok 1", || { Ok(()) });
                    ctx.it("ok 2", || { Ok(()) });
                    ctx.it("ok 3", || { Ok(()) });
                    ctx.it("ok 4", || { Ok(()) });
                });
                runner.run().unwrap();

                expect!(runner.result()).to(be_ok());
            }

            #[test]
            fn tests_can_contains_asserts_that_panic() {
                use std::sync::atomic::{AtomicUsize, Ordering};
                let counter = &mut AtomicUsize::new(0);

                let mut runner = describe("A root", |ctx| {
                    ctx.it("assert_eq fail", || { assert_eq!(true, false); Ok(()) });
                    ctx.it("this should also be runned", || { counter.fetch_add(1, Ordering::Relaxed); Ok(()) })
                });
                runner.run().unwrap();

                expect!(runner.result()).to(be_err());
                expect!(counter.load(Ordering::Relaxed)).to(be_equal_to(1));
            }

            #[test]
            fn can_count_the_tests() {
                let mut runner = describe("a root", |ctx| {
                    ctx.it("first", || { Ok(()) });
                    ctx.it("second", || { Ok(()) });
                    ctx.it("third", || { Ok(()) });
                });
                runner.run().unwrap();
                let result = runner.result();

                expect!(result).to(be_ok());
                if let Ok(report) = result {
                    expect!(report.total_tests).to(be_equal_to(3));
                }
            }

            #[test]
            fn can_count_succes() {
                let mut runner = describe("a root", |ctx| {
                    ctx.it("first", || { Ok(()) });
                    ctx.it("second", || { Ok(()) });
                    ctx.it("third", || { Ok(()) });
                });
                runner.run().unwrap();
                let result = runner.result();

                expect!(result).to(be_ok());
                if let Ok(report) = result {
                    expect!(report.success_count).to(be_equal_to(3));
                }
            }

            #[test]
            fn can_count_errors() {
                let mut runner = describe("a root", |ctx| {
                    ctx.it("first", || { Err(()) });
                    ctx.it("second", || { Err(()) });
                    ctx.it("third", || { Ok(()) });
                });
                runner.run().unwrap();
                let result = runner.result();

                expect!(result).to(be_err());
                if let Err(report) = result {
                    expect!(report.error_count).to(be_equal_to(2));
                }
            }
        }
    }

    /*
     * Test list:
     * x check that tests can call `assert_eq!`
     * x check that tests can return Err or Ok
     * x runner can count the tests
     * x runner can count the success and failures
     * - check that runner displays the tests names and their results
     * - check that we can use before in a describe
     * - check that we can use after in a describe
     * - check that after/before are run in all child contextes
     */

}
<commit_msg> add ctx.before function<commit_after>#[macro_use(expect)]
extern crate expectest;
pub use expectest::prelude::*;

pub type TestResult = Result<(), ()>;

pub struct Context<'a> {
    tests: Vec<Box<FnMut() -> TestResult + 'a>>,
    before_each: Vec<Box<FnMut() -> () + 'a>>
}

impl<'a> Context<'a> {
    pub fn describe<F>(&mut self, _name: &'a str, mut body: F)
        where F : 'a + FnMut(&mut Context<'a>) -> () {
        body(self)
    }

    pub fn it<F>(&mut self, _name: &'a str, body: F)
        where F : 'a + FnMut() -> TestResult {

        self.tests.push(Box::new(body))
    }

    pub fn before<F>(&mut self, body: F)
        where F : 'a + FnMut() -> () {

        self.before_each.push(Box::new(body))
    }
}

pub fn describe<'a, 'b, F>(_block_name: &'b str, body: F) -> Runner<'a>
    where F : 'a + FnOnce(&mut Context<'a>) -> () {

    let mut c = Context { tests: vec!(), before_each: vec!() };
    body(&mut c);
    Runner { describe: c, report: None }
}

pub struct Runner<'a> {
    describe: Context<'a>,
    report: Option<Result<TestReport, TestReport>>
}

#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
pub struct TestReport {
    total_tests: u32,
    success_count: u32,
    error_count: u32
}

impl<'a> Runner<'a> {

    pub fn run(&mut self) -> Result<(), ()> {
        use std::panic::{catch_unwind, AssertUnwindSafe};

        let mut report = TestReport::default();
        let mut result = Ok(());

        let ref mut describe = self.describe;
        let ref mut before_functions = describe.before_each;
        for test_function in describe.tests.iter_mut() {

            let res = catch_unwind(AssertUnwindSafe(|| {
                for before_function in before_functions.iter_mut() {
                    before_function()
                }
                test_function()
            }));

            let res = match res {
                Ok(res) => res,
                _ => Err(())
            };

            result = match result {
                Ok(()) => { report.success_count += 1; res },
                old @ _ => { report.error_count += 1; old }
            };

            report.total_tests += 1;
        }

        if let Ok(_) = result {
            self.report = Some(Ok(report))
        } else {
            self.report = Some(Err(report))
        }

        Ok(())
    }

    pub fn result(&self) -> Result<TestReport, TestReport> {
        self.report.unwrap_or(Ok(TestReport::default()))
    }
}

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

    mod describe {
        pub use super::*;

        #[test]
        fn it_has_a_root_describe_function() {
            describe("A Test", |_ctx|{});
        }

        #[test]
        fn it_can_call_describe_inside_describe_body() {
            describe("A Root", |ctx| {
                ctx.describe("nested describe", |_ctx| {})
            });
        }

        #[test]
        fn it_can_call_it_inside_describe_body() {
            describe("A root", |ctx| {
                ctx.it("is a test", || { Ok(()) })
            });
        }
    }

    mod runner {
        pub use super::*;

        mod run {
            pub use super::*;

            #[test]
            fn it_create_a_runner_that_can_be_runned() {
                let mut runner = describe("A root", |ctx| {
                    ctx.it("is expected to run", || {
                        assert_eq!(true, true);
                        Ok(())
                    })
                });
                expect!(runner.run()).to(be_ok());
            }

            #[test]
            fn effectively_run_tests() {
                let ran = &mut false;

                {
                    let mut runner = describe("A root", |ctx| {
                        ctx.it("is expected to run", || {
                            *ran = true;
                            Ok(())
                        })
                    });
                    runner.run().unwrap()
                }

                assert_eq!(true, *ran)
            }

            #[test]
            fn effectively_run_two_tests() {
                use std::sync::atomic::{AtomicUsize, Ordering};
                let ran_counter = &mut AtomicUsize::new(0);

                {
                    let mut runner = describe("A root", |ctx| {
                        ctx.it("first run",  || { ran_counter.fetch_add(1, Ordering::Relaxed); Ok(()) });
                        ctx.it("second run", || { ran_counter.fetch_add(1, Ordering::Relaxed); Ok(()) });
                    });
                    let _ = runner.run().unwrap();
                }

                assert_eq!(2, ran_counter.load(Ordering::Relaxed))
            }

            #[test]
            fn effectively_run_two_tests_in_nested_describe() {
                use std::sync::atomic::{AtomicUsize, Ordering};
                let ran_counter = &mut AtomicUsize::new(0);

                {
                    let mut runner = describe("A root", |ctx| {
                        ctx.describe("first describe", |ctx| {
                            ctx.it("first run",  || {
                                ran_counter.fetch_add(1, Ordering::Relaxed); Ok(())
                            });
                        });
                        ctx.describe("second describe", |ctx| {
                            ctx.it("second run",  || {
                                ran_counter.fetch_add(1, Ordering::Relaxed); Ok(())
                            });
                        });
                        ctx.describe("third describe", |ctx| {
                            ctx.describe("fourth describe", |ctx| {
                                ctx.it("third run",  || {
                                    ran_counter.fetch_add(1, Ordering::Relaxed); Ok(())
                                });
                            })
                        })
                    });
                    let _ = runner.run().unwrap();
                }

                assert_eq!(3, ran_counter.load(Ordering::Relaxed))
            }
        }

        mod results {
            pub use super::*;

            #[test]
            fn tests_can_fail_with_an_error_result() {
                let mut runner = describe("A root", |ctx| {
                    ctx.it("should fail", || {
                        Err(())
                    })
                });
                runner.run().unwrap();

                expect!(runner.result()).to(be_err());
            }

            #[test]
            fn should_be_ok_if_tests_are_ok() {
                let mut runner = describe("A root", |ctx| {
                    ctx.it("should be ok", || { Ok(()) })
                });
                runner.run().unwrap();

                expect!(runner.result()).to(be_ok());
            }

            #[test]
            fn is_ok_if_no_tests_have_been_runned() {
                let mut runner = describe("A root", |_ctx| {});
                runner.run().unwrap();

                expect!(runner.result()).to(be_ok());
            }

            #[test]
            fn is_err_if_one_test_is_err() {
                let mut runner = describe("A root", |ctx| {
                    ctx.it("an err", || { Err(()) });
                    ctx.it("an ok", || { Ok(()) });
                });
                runner.run().unwrap();

                expect!(runner.result()).to(be_err());
            }

            #[test]
            fn is_ok_if_all_tests_are_ok() {
                let mut runner = describe("A root", |ctx| {
                    ctx.it("ok 1", || { Ok(()) });
                    ctx.it("ok 2", || { Ok(()) });
                    ctx.it("ok 3", || { Ok(()) });
                    ctx.it("ok 4", || { Ok(()) });
                });
                runner.run().unwrap();

                expect!(runner.result()).to(be_ok());
            }

            #[test]
            fn tests_can_contains_asserts_that_panic() {
                use std::sync::atomic::{AtomicUsize, Ordering};
                let counter = &mut AtomicUsize::new(0);

                let mut runner = describe("A root", |ctx| {
                    ctx.it("assert_eq fail", || { assert_eq!(true, false); Ok(()) });
                    ctx.it("this should also be runned", || { counter.fetch_add(1, Ordering::Relaxed); Ok(()) })
                });
                runner.run().unwrap();

                expect!(runner.result()).to(be_err());
                expect!(counter.load(Ordering::Relaxed)).to(be_equal_to(1));
            }

            #[test]
            fn can_count_the_tests() {
                let mut runner = describe("a root", |ctx| {
                    ctx.it("first", || { Ok(()) });
                    ctx.it("second", || { Ok(()) });
                    ctx.it("third", || { Ok(()) });
                });
                runner.run().unwrap();
                let result = runner.result();

                expect!(result).to(be_ok());
                if let Ok(report) = result {
                    expect!(report.total_tests).to(be_equal_to(3));
                }
            }

            #[test]
            fn can_count_succes() {
                let mut runner = describe("a root", |ctx| {
                    ctx.it("first", || { Ok(()) });
                    ctx.it("second", || { Ok(()) });
                    ctx.it("third", || { Ok(()) });
                });
                runner.run().unwrap();
                let result = runner.result();

                expect!(result).to(be_ok());
                if let Ok(report) = result {
                    expect!(report.success_count).to(be_equal_to(3));
                }
            }

            #[test]
            fn can_count_errors() {
                let mut runner = describe("a root", |ctx| {
                    ctx.it("first", || { Err(()) });
                    ctx.it("second", || { Err(()) });
                    ctx.it("third", || { Ok(()) });
                });
                runner.run().unwrap();
                let result = runner.result();

                expect!(result).to(be_err());
                if let Err(report) = result {
                    expect!(report.error_count).to(be_equal_to(2));
                }
            }
        }
    }

    mod before {
        pub use super::*;

        #[test]
        fn can_be_called_inside_describe() {
            use std::sync::atomic::{AtomicUsize, Ordering};
            let ran_counter = &mut AtomicUsize::new(0);

            {
                let mut runner = describe("a root", |ctx| {
                    ctx.before(|| { ran_counter.fetch_add(1, Ordering::Relaxed); });
                    ctx.it("first", || { Ok(()) });
                    ctx.it("second", || { Ok(()) });
                    ctx.it("third", || { Ok(()) });
                });
                runner.run().unwrap();
            }

            expect!(ran_counter.load(Ordering::Relaxed)).to(be_equal_to(3));
        }
    }

    /*
     * Test list:
     * x check that tests can call `assert_eq!`
     * x check that tests can return Err or Ok
     * x runner can count the tests
     * x runner can count the success and failures
     * - check that runner displays the tests names and their results
     * - check that we can use before in a describe
     * - check that we can use after in a describe
     * - check that after/before are run in all child contextes
     */
}
<|endoftext|>


<commit_before>#![recursion_limit = "1024"]

#[macro_use]
extern crate error_chain;
extern crate regex;
extern crate stringreader;

pub mod errors {
	error_chain! {
		errors {
			InvalidRulesLine(line: String) {
				description("Invalid rules line"),
				display("Invalid rules definition in line '{}'", line),
			}
		}
	}
}
mod game_descriptor;
mod parsers;

pub use game_descriptor::GameDescriptor;
pub use game_descriptor::Coord;
pub use parsers::Parser;
pub use parsers::Life105Parser;
<commit_msg>whitespace<commit_after>#![recursion_limit = "1024"]

#[macro_use]
extern crate error_chain;
extern crate regex;
extern crate stringreader;

pub mod errors {
	error_chain! {
		errors {
			InvalidRulesLine(line: String) {
				description("Invalid rules line"),
				display("Invalid rules definition in line '{}'", line),
			}
		}
	}
}

mod game_descriptor;
mod parsers;

pub use game_descriptor::GameDescriptor;
pub use game_descriptor::Coord;
pub use parsers::Parser;
pub use parsers::Life105Parser;
<|endoftext|>