<commit_before>//! Some unit tests for all the internal functionality of lrs

#[cfg(test)]
#[allow(dead_code)]
#[allow(unused_macros)]
#[allow(unused_imports)]
mod tests {
    use terms::*;
    use clause::*;
    use result::*;

    #[test]
     fn lrs_symbol_create() {
        let s = symbol!["A"];
        assert!(s.val == 'A');
        assert!(s.state == true);
    }

    #[test]
    fn lrs_term_create() {
        let term = term!["A", "!🐎", "🍝", "!📰"];

        assert!(term.contains(&symbol!["A"]));
        assert!(term.contains(&symbol!["!🐎"]));
        assert!(term.contains(&symbol!["🍝"]));
        assert!(term.contains(&symbol!["!📰"]));
    }

    #[test]
    fn lrs_term_remove() {
        let mut term = term!["A", "!🐎", "🍝", "!📰"];

        /* Try to remove something that doesn't exist */
        term.remove(symbol!["!A"]);

        term.remove(symbol!["A"]);
        assert!(! term.contains(&symbol!["A"]));

        term.remove(symbol!["!🐎"]);
        assert!(! term.contains(&symbol!["!🐎"]));

        term.remove(symbol!["🍝"]);
        assert!(! term.contains(&symbol!["🍝"]));

        term.remove(symbol!["!📰"]);
        assert!(! term.contains(&symbol!["!📰"]));
    }

    #[test]
    fn lrs_term_insert() {
        let mut term = term!["A"];
        term.insert(symbol!["!A"]);
        term.insert(symbol!["B"]);

        assert!(term.contains(&symbol!["A"]));
        assert!(term.contains(&symbol!["!A"]));
        assert!(term.contains(&symbol!["B"]));

        /* Fail an insert */
        term.insert(symbol!["B"]);
        assert!(term.contains(&symbol!["B"]));
    }

    #[test]
    fn lrs_find_fuzzy() {
        let a = term!["A", "B"];
        let b = term!["A", "!A"];
        let c = term!["A"];

        assert!(a.is_fuzzy() == true);
        assert!(b.is_fuzzy() == false);
        assert!(c.is_fuzzy() == false);
    }

    #[test]
    fn lrs_compare_terms() {
        let a = term!["A", "B"];
        let b = term!["B", "C"];
        let clause = clause![a, b];

        assert!(clause.contains(&term!["A", "B"]));
        assert!(clause.contains(&term!["B", "A"]));

        assert!(clause.contains(&term!["C", "B"]));
        assert!(! clause.contains(&term!["C", "D"]));
    }

    #[test]
    fn lrs_compare_clauses() {
        let c1 = clause![term!["A"]];
        let c2 = clause![term!["A"]];
        assert_eq!(c1, c2);

        let c3 = clause![term!["A", "B"], term!["!B"]];
        let c4 = clause![term!["B", "A"], term!["!B"]];
        assert_eq!(c3, c4);

        let c5 = clause![term!["A", "B"], term!["B"]];
        let c6 = clause![term!["A"], term!["!B"]];
        assert!(c5 != c6);
    }

    #[test]
    fn lrs_simple_reduce1() {
        let a = term!["A", "!B"];
        let b = term!["C", "!D"];
        let c = term!["E"];

        let mut cl = clause![a, b, c];
        cl.reduce();

        /* We should no longer contain "E" */
        assert!(! cl.contains(&term!["E"]));
    }

    #[test]
    fn lrs_simple_reduce2() {
        let a = term!["A", "!B"];
        let b = term!["C", "!D"];
        let c = term!["E"];
        let d = term!["F"];

        let mut cl = clause![a.clone(), b.clone(), c, d];
        cl.reduce();
        cl.reduce();

        /* Should now look like {A, !B} & {C, !D} */
        assert_eq!(cl, clause![a, b]);
    }

    #[test]
    fn lrs_result_create() {
        let r = result![true, ("A", false), ("B", true)];
        assert_eq!(r.symbols.get(&symbol!["A"]).unwrap(), &false);
        assert_eq!(r.symbols.get(&symbol!["B"]).unwrap(), &true);
        assert_eq!(r.solvable, true);

        println!("{:?}", r);
    }

    // #[test]
    // fn lrs_merge_reduce_1() {
    //     let a1 = term!["A", "!B"];
    //     let b1 = term!["A", "B"];
    //     let c1 = term!["C", "!D"];

    //     let mut cl = clause![a1, b1, c1];
    //     cl.reduce();
    //     assert_eq!(cl, clause![term!["A"], term!["C", "!D"]]);
    // }

    // #[test]
    // fn lrs_merge_reduce_2() {

    //     /* ...Oh fuck this is a difficult one... */
    //     let a2 = term!["A", "!B"];
    //     let b2 = term!["A", "B"];
    //     let c2 = term!["!A", "D"];

    //     let mut cl = clause![a2, b2, c2];
    //     cl.reduce();
    //     cl.reduce();

    //     /* It needs to have picked a2 and b2 first 😟 */
    //     assert_eq!(cl, clause![term!["D"]]);
    // }
}
<commit_msg>Adding function and unit test described in #8<commit_after>//! Some unit tests for all the internal functionality of lrs

#[cfg(test)]
#[allow(dead_code)]
#[allow(unused_macros)]
#[allow(unused_imports)]
mod tests {
    use terms::*;
    use clause::*;
    use result::*;

    /// Create a basic symbol
    #[test]
     fn lrs_symbol_create() {
        let s = symbol!["A"];
        assert!(s.val == 'A');
        assert!(s.state == true);
    }

    /// Create a basic terms with a macro helper and symbols
    #[test]
    fn lrs_term_create() {
        let term = term!["A", "!🐎", "🍝", "!📰"];

        assert!(term.contains(&symbol!["A"]));
        assert!(term.contains(&symbol!["!🐎"]));
        assert!(term.contains(&symbol!["🍝"]));
        assert!(term.contains(&symbol!["!📰"]));
    }

    /// Create a term, then remove symbols from it
    #[test]
    fn lrs_term_remove() {
        let mut term = term!["A", "!🐎", "🍝", "!📰"];

        /* Try to remove something that doesn't exist */
        term.remove(symbol!["!A"]);

        term.remove(symbol!["A"]);
        assert!(! term.contains(&symbol!["A"]));

        term.remove(symbol!["!🐎"]);
        assert!(! term.contains(&symbol!["!🐎"]));

        term.remove(symbol!["🍝"]);
        assert!(! term.contains(&symbol!["🍝"]));

        term.remove(symbol!["!📰"]);
        assert!(! term.contains(&symbol!["!📰"]));
    }

    /// Create a term, then insert further symbols
    #[test]
    fn lrs_term_insert() {
        let mut term = term!["A"];
        term.insert(symbol!["!A"]);
        term.insert(symbol!["B"]);

        assert!(term.contains(&symbol!["A"]));
        assert!(term.contains(&symbol!["!A"]));
        assert!(term.contains(&symbol!["B"]));

        /* Fail an insert */
        term.insert(symbol!["B"]);
        assert!(term.contains(&symbol!["B"]));
    }

    #[test]
    fn lrs_find_fuzzy() {
        let a = term!["A", "B"];
        let b = term!["A", "!A"];
        let c = term!["A"];

        assert!(a.is_fuzzy() == true);
        assert!(b.is_fuzzy() == false);
        assert!(c.is_fuzzy() == false);
    }

    #[test]
    fn lrs_compare_terms() {
        let a = term!["A", "B"];
        let b = term!["B", "C"];
        let clause = clause![a, b];

        assert!(clause.contains(&term!["A", "B"]));
        assert!(clause.contains(&term!["B", "A"]));

        assert!(clause.contains(&term!["C", "B"]));
        assert!(! clause.contains(&term!["C", "D"]));
    }

    #[test]
    fn lrs_compare_clauses() {
        let c1 = clause![term!["A"]];
        let c2 = clause![term!["A"]];
        assert_eq!(c1, c2);

        let c3 = clause![term!["A", "B"], term!["!B"]];
        let c4 = clause![term!["B", "A"], term!["!B"]];
        assert_eq!(c3, c4);

        let c5 = clause![term!["A", "B"], term!["B"]];
        let c6 = clause![term!["A"], term!["!B"]];
        assert!(c5 != c6);
    }

    #[test]
    fn lrs_simple_reduce1() {
        let a = term!["A", "!B"];
        let b = term!["C", "!D"];
        let c = term!["E"];

        let mut cl = clause![a, b, c];
        cl.reduce();

        /* We should no longer contain "E" */
        assert!(! cl.contains(&term!["E"]));
    }

    #[test]
    fn lrs_simple_reduce2() {
        let a = term!["A", "!B"];
        let b = term!["C", "!D"];
        let c = term!["E"];
        let d = term!["F"];

        let mut cl = clause![a.clone(), b.clone(), c, d];
        cl.reduce();
        cl.reduce();

        /* Should now look like {A, !B} & {C, !D} */
        assert_eq!(cl, clause![a, b]);
    }

    #[test]
    fn lrs_result_create() {
        let r = result![true, ("A", false), ("B", true)];
        assert_eq!(r.symbols.get(&symbol!["A"]).unwrap(), &false);
        assert_eq!(r.symbols.get(&symbol!["B"]).unwrap(), &true);
        assert_eq!(r.solvable, true);

        println!("{:?}", r);
    }

    #[test]
    fn lrs_count_symbols() {
        let cl = clause![   term!["A", "B"],
                            term!["A", "!C"],
                            term!["C"],
                            term!["B"],
                            term!["A"]
                        ];

        let count = cl.count_symbols();
        let a: i32 = *count.get(&symbol!["A"]).unwrap();
        let b: i32 = *count.get(&symbol!["B"]).unwrap();
        let c: i32 = *count.get(&symbol!["C"]).unwrap();
        let nc: i32 = *count.get(&symbol!["!C"]).unwrap();

        assert_eq!(a, 3);
        assert_eq!(b, 2);
        assert_eq!(c, 1);
        assert_eq!(nc, 1);
    }

    // #[test]
    // fn lrs_merge_reduce_1() {
    //     let a1 = term!["A", "!B"];
    //     let b1 = term!["A", "B"];
    //     let c1 = term!["C", "!D"];

    //     let mut cl = clause![a1, b1, c1];
    //     cl.reduce();
    //     assert_eq!(cl, clause![term!["A"], term!["C", "!D"]]);
    // }

    // #[test]
    // fn lrs_merge_reduce_2() {

    //     /* ...Oh fuck this is a difficult one... */
    //     let a2 = term!["A", "!B"];
    //     let b2 = term!["A", "B"];
    //     let c2 = term!["!A", "D"];

    //     let mut cl = clause![a2, b2, c2];
    //     cl.reduce();
    //     cl.reduce();

    //     /* It needs to have picked a2 and b2 first 😟 */
    //     assert_eq!(cl, clause![term!["D"]]);
    // }
}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use consts::SECTOR_SIZE;
use dbus;

use nix;
use serde;
use std::borrow::Cow;
use std::error::Error;
use std::fmt;
use std::fmt::Display;
use std::io;
use std::ops::{Div, Mul, Rem};
use term;

pub type StratisResult<T> = Result<T, StratisError>;

// macros for unsigned operations on Sectors and Bytes
macro_rules! unsigned_div {
    ($t: ty, $T: ident) => {
        impl Div<$t> for $T {
            type Output = $T;
            fn div(self, rhs: $t) -> $T {
                $T(self.0 / rhs as u64)
            }
        }
    }
}

macro_rules! unsigned_mul {
    ($t: ty, $T: ident) => {
        impl Mul<$t> for $T {
            type Output = $T;
            fn mul(self, rhs: $t) -> $T {
                $T(self.0 * rhs as u64)
            }
        }

        impl Mul<$T> for $t {
            type Output = $T;
            fn mul(self, rhs: $T) -> $T {
                $T(self as u64 * rhs.0)
            }
        }
    }
}

macro_rules! unsigned_rem {
    ($t: ty, $T: ident) => {
        impl Rem<$t> for $T {
            type Output = $T;
            fn rem(self, rhs: $t) -> $T {
                $T(self.0 % rhs as u64)
            }
        }
    }
}

custom_derive! {
    #[derive(NewtypeAdd, NewtypeAddAssign,
             NewtypeDeref,
             NewtypeFrom,
             NewtypeSub,
             Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)]
    pub struct Bytes(pub u64);
}

impl Bytes {
    /// Return the number of Sectors fully contained in these bytes.
    pub fn sectors(self) -> Sectors {
        Sectors(self.0 / SECTOR_SIZE as u64)
    }
}

unsigned_mul!(u64, Bytes);
unsigned_mul!(u32, Bytes);
unsigned_mul!(u16, Bytes);
unsigned_mul!(u8, Bytes);
unsigned_mul!(usize, Bytes);

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

// Use distinct 'newtype' types for sectors and sector offsets for type safety.
// When needed, these can still be derefed to u64.
// Derive a bunch of stuff so we can do ops on them.
//
custom_derive! {
    #[derive(NewtypeAdd, NewtypeAddAssign,
             NewtypeDeref,
             NewtypeFrom,
             NewtypeSub,
             Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)]
    pub struct Sectors(pub u64);
}

impl Sectors {
    /// The number of bytes in these sectors.
    pub fn bytes(&self) -> Bytes {
        Bytes(self.0 * SECTOR_SIZE as u64)
    }
}

unsigned_div!(u64, Sectors);
unsigned_div!(u32, Sectors);
unsigned_div!(u16, Sectors);
unsigned_div!(u8, Sectors);
unsigned_div!(usize, Sectors);

unsigned_mul!(u64, Sectors);
unsigned_mul!(u32, Sectors);
unsigned_mul!(u16, Sectors);
unsigned_mul!(u8, Sectors);
unsigned_mul!(usize, Sectors);

unsigned_rem!(u64, Sectors);
unsigned_rem!(u32, Sectors);
unsigned_rem!(u16, Sectors);
unsigned_rem!(u8, Sectors);
unsigned_rem!(usize, Sectors);

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

impl serde::Serialize for Sectors {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: serde::Serializer
    {
        serializer.serialize_u64(**self)
    }
}

impl serde::Deserialize for Sectors {
    fn deserialize<D>(deserializer: D) -> Result<Sectors, D::Error>
        where D: serde::de::Deserializer
    {
        let val = try!(serde::Deserialize::deserialize(deserializer));
        Ok(Sectors(val))
    }
}

// A type for Data Blocks as used by the thin pool.
custom_derive! {
    #[derive(NewtypeFrom, NewtypeAdd, NewtypeSub, NewtypeDeref,
             NewtypeBitAnd, NewtypeNot, NewtypeDiv, NewtypeRem,
             NewtypeMul,
             Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)]
    pub struct DataBlocks(pub u64);
}

impl serde::Serialize for DataBlocks {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: serde::Serializer
    {
        serializer.serialize_u64(**self)
    }
}

impl serde::Deserialize for DataBlocks {
    fn deserialize<D>(deserializer: D) -> Result<DataBlocks, D::Error>
        where D: serde::de::Deserializer
    {
        let val = try!(serde::Deserialize::deserialize(deserializer));
        Ok(DataBlocks(val))
    }
}

// An error type for errors generated within Stratis
//
#[derive(Debug)]
pub struct InternalError(pub Cow<'static, str>);

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

impl Error for InternalError {
    fn description(&self) -> &str {
        &self.0
    }
}

// Define a common error enum.
// See http://blog.burntsushi.net/rust-error-handling/
#[derive(Debug)]
pub enum StratisError {
    Stratis(InternalError),
    Io(io::Error),
    Nix(nix::Error),
    Dbus(dbus::Error),
    Term(term::Error),
}

impl fmt::Display for StratisError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            StratisError::Stratis(ref err) => write!(f, "Stratis error: {}", err.0),
            StratisError::Io(ref err) => write!(f, "IO error: {}", err),
            StratisError::Nix(ref err) => write!(f, "Nix error: {}", err.errno().desc()),
            StratisError::Dbus(ref err) => {
                write!(f, "Dbus error: {}", err.message().unwrap_or("Unknown"))
            }
            StratisError::Term(ref err) => write!(f, "Term error: {}", err),
        }
    }
}

impl Error for StratisError {
    fn description(&self) -> &str {
        match *self {
            StratisError::Stratis(ref err) => &err.0,
            StratisError::Io(ref err) => err.description(),
            StratisError::Nix(ref err) => err.errno().desc(),
            StratisError::Dbus(ref err) => err.message().unwrap_or("D-Bus Error"),
            StratisError::Term(ref err) => Error::description(err),
        }
    }

    fn cause(&self) -> Option<&Error> {
        match *self {
            StratisError::Stratis(ref err) => Some(err),
            StratisError::Io(ref err) => Some(err),
            StratisError::Nix(ref err) => Some(err),
            StratisError::Dbus(ref err) => Some(err),
            StratisError::Term(ref err) => Some(err),
        }
    }
}

impl From<InternalError> for StratisError {
    fn from(err: InternalError) -> StratisError {
        StratisError::Stratis(err)
    }
}

impl From<io::Error> for StratisError {
    fn from(err: io::Error) -> StratisError {
        StratisError::Io(err)
    }
}

impl From<nix::Error> for StratisError {
    fn from(err: nix::Error) -> StratisError {
        StratisError::Nix(err)
    }
}

impl From<dbus::Error> for StratisError {
    fn from(err: dbus::Error) -> StratisError {
        StratisError::Dbus(err)
    }
}

impl From<term::Error> for StratisError {
    fn from(err: term::Error) -> StratisError {
        StratisError::Term(err)
    }
}
<commit_msg>Avoid using references for Copy types<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use consts::SECTOR_SIZE;
use dbus;

use nix;
use serde;
use std::borrow::Cow;
use std::error::Error;
use std::fmt;
use std::fmt::Display;
use std::io;
use std::ops::{Div, Mul, Rem};
use term;

pub type StratisResult<T> = Result<T, StratisError>;

// macros for unsigned operations on Sectors and Bytes
macro_rules! unsigned_div {
    ($t: ty, $T: ident) => {
        impl Div<$t> for $T {
            type Output = $T;
            fn div(self, rhs: $t) -> $T {
                $T(self.0 / rhs as u64)
            }
        }
    }
}

macro_rules! unsigned_mul {
    ($t: ty, $T: ident) => {
        impl Mul<$t> for $T {
            type Output = $T;
            fn mul(self, rhs: $t) -> $T {
                $T(self.0 * rhs as u64)
            }
        }

        impl Mul<$T> for $t {
            type Output = $T;
            fn mul(self, rhs: $T) -> $T {
                $T(self as u64 * rhs.0)
            }
        }
    }
}

macro_rules! unsigned_rem {
    ($t: ty, $T: ident) => {
        impl Rem<$t> for $T {
            type Output = $T;
            fn rem(self, rhs: $t) -> $T {
                $T(self.0 % rhs as u64)
            }
        }
    }
}

custom_derive! {
    #[derive(NewtypeAdd, NewtypeAddAssign,
             NewtypeDeref,
             NewtypeFrom,
             NewtypeSub,
             Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)]
    pub struct Bytes(pub u64);
}

impl Bytes {
    /// Return the number of Sectors fully contained in these bytes.
    pub fn sectors(self) -> Sectors {
        Sectors(self.0 / SECTOR_SIZE as u64)
    }
}

unsigned_mul!(u64, Bytes);
unsigned_mul!(u32, Bytes);
unsigned_mul!(u16, Bytes);
unsigned_mul!(u8, Bytes);
unsigned_mul!(usize, Bytes);

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

// Use distinct 'newtype' types for sectors and sector offsets for type safety.
// When needed, these can still be derefed to u64.
// Derive a bunch of stuff so we can do ops on them.
//
custom_derive! {
    #[derive(NewtypeAdd, NewtypeAddAssign,
             NewtypeDeref,
             NewtypeFrom,
             NewtypeSub,
             Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)]
    pub struct Sectors(pub u64);
}

impl Sectors {
    /// The number of bytes in these sectors.
    pub fn bytes(&self) -> Bytes {
        Bytes(self.0 * SECTOR_SIZE as u64)
    }
}

unsigned_div!(u64, Sectors);
unsigned_div!(u32, Sectors);
unsigned_div!(u16, Sectors);
unsigned_div!(u8, Sectors);
unsigned_div!(usize, Sectors);

unsigned_mul!(u64, Sectors);
unsigned_mul!(u32, Sectors);
unsigned_mul!(u16, Sectors);
unsigned_mul!(u8, Sectors);
unsigned_mul!(usize, Sectors);

unsigned_rem!(u64, Sectors);
unsigned_rem!(u32, Sectors);
unsigned_rem!(u16, Sectors);
unsigned_rem!(u8, Sectors);
unsigned_rem!(usize, Sectors);

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

impl serde::Serialize for Sectors {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: serde::Serializer
    {
        serializer.serialize_u64(**self)
    }
}

impl serde::Deserialize for Sectors {
    fn deserialize<D>(deserializer: D) -> Result<Sectors, D::Error>
        where D: serde::de::Deserializer
    {
        let val = try!(serde::Deserialize::deserialize(deserializer));
        Ok(Sectors(val))
    }
}

// A type for Data Blocks as used by the thin pool.
custom_derive! {
    #[derive(NewtypeAdd, NewtypeAddAssign,
             NewtypeDeref,
             NewtypeFrom,
             NewtypeSub,
             Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)]
    pub struct DataBlocks(pub u64);
}

impl serde::Serialize for DataBlocks {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: serde::Serializer
    {
        serializer.serialize_u64(**self)
    }
}

impl serde::Deserialize for DataBlocks {
    fn deserialize<D>(deserializer: D) -> Result<DataBlocks, D::Error>
        where D: serde::de::Deserializer
    {
        let val = try!(serde::Deserialize::deserialize(deserializer));
        Ok(DataBlocks(val))
    }
}

// An error type for errors generated within Stratis
//
#[derive(Debug)]
pub struct InternalError(pub Cow<'static, str>);

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

impl Error for InternalError {
    fn description(&self) -> &str {
        &self.0
    }
}

// Define a common error enum.
// See http://blog.burntsushi.net/rust-error-handling/
#[derive(Debug)]
pub enum StratisError {
    Stratis(InternalError),
    Io(io::Error),
    Nix(nix::Error),
    Dbus(dbus::Error),
    Term(term::Error),
}

impl fmt::Display for StratisError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            StratisError::Stratis(ref err) => write!(f, "Stratis error: {}", err.0),
            StratisError::Io(ref err) => write!(f, "IO error: {}", err),
            StratisError::Nix(ref err) => write!(f, "Nix error: {}", err.errno().desc()),
            StratisError::Dbus(ref err) => {
                write!(f, "Dbus error: {}", err.message().unwrap_or("Unknown"))
            }
            StratisError::Term(ref err) => write!(f, "Term error: {}", err),
        }
    }
}

impl Error for StratisError {
    fn description(&self) -> &str {
        match *self {
            StratisError::Stratis(ref err) => &err.0,
            StratisError::Io(ref err) => err.description(),
            StratisError::Nix(ref err) => err.errno().desc(),
            StratisError::Dbus(ref err) => err.message().unwrap_or("D-Bus Error"),
            StratisError::Term(ref err) => Error::description(err),
        }
    }

    fn cause(&self) -> Option<&Error> {
        match *self {
            StratisError::Stratis(ref err) => Some(err),
            StratisError::Io(ref err) => Some(err),
            StratisError::Nix(ref err) => Some(err),
            StratisError::Dbus(ref err) => Some(err),
            StratisError::Term(ref err) => Some(err),
        }
    }
}

impl From<InternalError> for StratisError {
    fn from(err: InternalError) -> StratisError {
        StratisError::Stratis(err)
    }
}

impl From<io::Error> for StratisError {
    fn from(err: io::Error) -> StratisError {
        StratisError::Io(err)
    }
}

impl From<nix::Error> for StratisError {
    fn from(err: nix::Error) -> StratisError {
        StratisError::Nix(err)
    }
}

impl From<dbus::Error> for StratisError {
    fn from(err: dbus::Error) -> StratisError {
        StratisError::Dbus(err)
    }
}

impl From<term::Error> for StratisError {
    fn from(err: term::Error) -> StratisError {
        StratisError::Term(err)
    }
}
<|endoftext|>


<commit_before>use raw::*;
use compile::Compile;
use function::ABI;
use libc::{c_uint, c_void};
use std::fmt;
use std::kinds::marker::{ContravariantLifetime, NoCopy};
use std::mem;
use std::c_str::ToCStr;
use util::{mod, from_ptr, NativeRef};
/// The integer representation of a type
pub mod kind {
    use libc::c_int;
    bitflags!(
        flags TypeKind: c_int {
            const Void = 0,
            const SByte = 1,
            const UByte = 2,
            const Short = 3,
            const UShort = 4,
            const Int = 5,
            const UInt = 6,
            const NInt = 7,
            const NUInt = 8,
            const Long = 9,
            const ULong = 10,
            const Float32 = 11,
            const Float64 = 12,
            const NFloat = 13,
            const Struct = 14,
            const Union = 15,
            const Signature = 16,
            const Pointer = 17,
            const FirstTagged = 2,
            const SysBool = 10009,
            const SysChar = 10010
        }
    );
}
impl fmt::Show for Type {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let kind = self.get_kind();
        if kind.contains(kind::Pointer) {
            write!(fmt, "*mut {}", self.get_ref().unwrap())
        } else if kind.contains(kind::Signature) {
            try!("fn(".fmt(fmt));
            for arg in self.params() {
                try!(arg.fmt(fmt));
            }
            try!(") -> ".fmt(fmt));
            match self.get_return() {
                Some(x) => x.fmt(fmt),
                None => "()".fmt(fmt)
            }
        } else {
            write!(fmt, "{}", try!(util::dump(|fd| {
                unsafe { jit_dump_type(mem::transmute(fd), self.as_ptr()) };
            })))
        }
    }
}
/// A single field of a struct
#[deriving(PartialEq)]
pub struct Field<'a> {
    /// The index of the field
    pub index: c_uint,
    _type: jit_type_t,
    marker: ContravariantLifetime<'a>
}
impl<'a> Field<'a> {
    #[inline]
    /// Get the field's name or none if it lacks one
    pub fn get_name(&self) -> Option<String> {
        unsafe {
            let c_name = jit_type_get_name(self._type, self.index);
            if c_name.is_null() {
                None
            } else {
                Some(String::from_raw_buf(mem::transmute(c_name)))
            }
        }
    }
    #[inline(always)]
    /// Get the type of the field
    pub fn get_type(&self) -> Type {
        unsafe {
            from_ptr(jit_type_get_field(self._type, self.index))
        }
    }
    #[inline(always)]
    /// Get the offset of the field
    pub fn get_offset(&self) -> uint {
        unsafe {
            jit_type_get_offset(self._type, self.index) as uint
        }
    }
}
/// Iterates through all the fields of a struct
pub struct Fields<'a> {
    _type: jit_type_t,
    index: c_uint,
    length: c_uint,
    marker: ContravariantLifetime<'a>
}
impl<'a> Fields<'a> {
    #[inline(always)]
    fn new(ty:Type) -> Fields<'a> {
        unsafe {
            Fields {
                _type: ty.as_ptr(),
                index: 0 as c_uint,
                length: jit_type_num_fields(ty.as_ptr()),
                marker: ContravariantLifetime::<'a>
            }
        }
    }
}
impl<'a> Iterator<Field<'a>> for Fields<'a> {
    fn next(&mut self) -> Option<Field<'a>> {
        if self.index < self.length {
            let index = self.index;
            self.index += 1;
            Some(Field {
                index: index,
                _type: self._type,
                marker: ContravariantLifetime::<'a>
            })
        } else {
            None
        }
    }
    fn size_hint(&self) -> (uint, Option<uint>) {
        ((self.length - self.index) as uint, None)
    }
}
/// Iterator through all the arguments a function takes
pub struct Params<'a> {
    _type: jit_type_t,
    index: c_uint,
    length: c_uint,
    marker: ContravariantLifetime<'a>
}
impl<'a> Params<'a> {
    fn new(ty:Type) -> Params<'a> {
        unsafe {
            Params {
                _type: ty.as_ptr(),
                index: 0,
                length: jit_type_num_params(ty.as_ptr()),
                marker: ContravariantLifetime::<'a>
            }
        }
    }
}
impl<'a> Iterator<Type> for Params<'a> {
    fn next(&mut self) -> Option<Type> {
        if self.index < self.length {
            let index = self.index;
            self.index += 1;
            unsafe { from_ptr(jit_type_get_param(self._type, index)) }
        } else {
            None
        }
    }
    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        ((self.length - self.index) as uint, None)
    }
}
/// An object that represents a native system type.
/// Each `Type` represents a basic system type, be it a primitive, a struct, a
/// union, a pointer, or a function signature. The library uses this information
/// to lay out values in memory.
/// Types are not attached to a context so they are reference-counted by LibJIT,
/// so internally they are represented as `Rc<TypeData>`.
#[deriving(PartialEq)]
pub struct Type {
    _type: jit_type_t,
    no_copy: NoCopy
}
impl NativeRef for Type {
    #[inline(always)]
    unsafe fn as_ptr(&self) -> jit_type_t {
        self._type
    }
    #[inline(always)]
    unsafe fn from_ptr(ptr:jit_type_t) -> Type {
        Type {
            _type: ptr,
            no_copy: NoCopy
        }
    }
}
impl Clone for Type {
    #[inline]
    /// Make a copy of the type descriptor by increasing its reference count.
    fn clone(&self) -> Type {
        unsafe {
            from_ptr(jit_type_copy(self.as_ptr()))
        }
    }
}
#[unsafe_destructor]
impl Drop for Type {
    #[inline(always)]
    /// Free a type descriptor by decreasing its reference count.
    /// This function is safe to use on pre-defined types, which are never
    /// actually freed.
    fn drop(&mut self) {
        unsafe {
            jit_type_free(self.as_ptr());
        }
    }
}
extern fn free_data<T:'static>(data: *mut c_void) {
    unsafe {
        let actual_data:Box<T> = mem::transmute(data);
        mem::drop(actual_data);
    }
}
impl Type {
    /// Create a type descriptor for a function signature.
    pub fn create_signature(abi: ABI, return_type: Type, params: &mut [Type]) -> Type {
        unsafe {
            let mut native_params:Vec<jit_type_t> = params.iter().map(|param| param.as_ptr()).collect();
            let signature = jit_type_create_signature(abi as jit_abi_t, return_type.as_ptr(), native_params.as_mut_ptr(), params.len() as c_uint, 1);
            from_ptr(signature)
        }
    }
    #[inline(always)]
    /// Create a type descriptor for a structure.
    pub fn create_struct(fields: &mut [Type]) -> Type {
        unsafe {
            let mut native_fields:Vec<_> = fields.iter().map(|field| field.as_ptr()).collect();
            from_ptr(jit_type_create_struct(native_fields.as_mut_ptr(), fields.len() as c_uint, 1))
        }
    }
    #[inline(always)]
    /// Create a type descriptor for a union.
    pub fn create_union(fields: &mut [Type]) -> Type {
        unsafe {
            let mut native_fields:Vec<_> = fields.iter().map(|field| field.as_ptr()).collect();
            from_ptr(jit_type_create_union(native_fields.as_mut_ptr(), fields.len() as c_uint, 1))
        }
    }
    #[inline(always)]
    /// Create a type descriptor for a pointer to another type.
    pub fn create_pointer(pointee: Type) -> Type {
        unsafe {
            let ptr = jit_type_create_pointer(pointee.as_ptr(), 1);
            from_ptr(ptr)
        }
    }
    #[inline(always)]
    /// Create a new tagged type
    pub fn create_tagged<T:'static>(ty:Type, kind: kind::TypeKind, data: Box<T>) -> Type {
        unsafe {
            let free_data:extern fn(*mut c_void) = free_data::<T>;
            let ty = jit_type_create_tagged(ty.as_ptr(), kind.bits(), mem::transmute(&*data), Some(free_data), 1);
            mem::forget(data);
            from_ptr(ty)
        }
    }
    #[inline(always)]
    /// Get the size of this type in bytes.
    pub fn get_size(&self) -> uint {
        unsafe {
            jit_type_get_size(self.as_ptr()) as uint
        }
    }
    #[inline(always)]
    /// Get the alignment of this type in bytes.
    pub fn get_alignment(&self) -> uint {
        unsafe {
            jit_type_get_alignment(self.as_ptr()) as uint
        }
    }
    #[inline]
    /// Get a value that indicates the kind of this type. This allows callers to
    /// quickly classify a type to determine how it should be handled further.
    pub fn get_kind(&self) -> kind::TypeKind {
        unsafe {
            mem::transmute(jit_type_get_kind(self.as_ptr()))
        }
    }
    #[inline(always)]
    /// Get the type that is referred to by this pointer type.
    pub fn get_ref(&self) -> Option<Type> {
        unsafe {
            from_ptr(jit_type_get_ref(self.as_ptr()))
        }
    }

    #[inline(always)]
    pub fn get_tagged_data<T:'static>(&self) -> Option<&T> {
        unsafe {
            mem::transmute(jit_type_get_tagged_data(self.as_ptr()))
        }
    }
    #[inline(always)]
    pub fn set_tagged_data<T:'static>(&self, data: Box<T>) {
        unsafe {
            let free_data:extern fn(*mut c_void) = free_data::<T>;
            jit_type_set_tagged_data(self.as_ptr(), mem::transmute(&*data), Some(free_data));
            mem::forget(data);
        }
    }
    #[inline(always)]
    /// Get the type returned by this function type.
    pub fn get_return(&self) -> Option<Type> {
        unsafe {
            from_ptr(jit_type_get_return(self.as_ptr()))
        }
    }
    /// Set the field or parameter names of this type.
    pub fn set_names<T:ToCStr>(&self, names:&[T]) -> bool {
        unsafe {
            let native_names : Vec<*const i8> = names.iter().map(|name| name.to_c_str().into_inner()).collect();
            jit_type_set_names(self.as_ptr(), native_names.as_ptr() as *mut *mut i8, names.len() as u32) != 0
        }
    }
    #[inline(always)]
    /// Iterator over the type's fields
    pub fn fields<'a>(&'a self) -> Fields<'a> {
        Fields::new(self.clone())
    }
    #[inline(always)]
    /// Iterator over the function signature's parameters
    pub fn params<'a>(&'a self) -> Params<'a> {
        Params::new(self.clone())
    }
    #[inline]
    /// Find the field/parameter index for a particular name.
    pub fn find_name<'b, T:ToCStr>(&'b self, name:T) -> Field<'b> {
        name.with_c_str(|c_name| unsafe {
            Field {
                index: jit_type_find_name(self.as_ptr(), c_name),
                _type: self.as_ptr(),
                marker: ContravariantLifetime::<'b>
            }
        })
    }
    #[inline(always)]
    /// Check if this is a pointer
    pub fn is_pointer(&self) -> bool {
        unsafe {
            jit_type_is_pointer(self.as_ptr()) != 0
        }
    }
}
#[inline(always)]
/// Get the Rust type given as a type descriptor
pub fn get<T: Compile>() -> Type {
    Compile::jit_type(None::<T>)
}<commit_msg>Add the rest of the `type.is_*' functions<commit_after>use raw::*;
use compile::Compile;
use function::ABI;
use libc::{c_uint, c_void};
use std::fmt;
use std::kinds::marker::{ContravariantLifetime, NoCopy};
use std::mem;
use std::c_str::ToCStr;
use util::{mod, from_ptr, NativeRef};
/// The integer representation of a type
pub mod kind {
    use libc::c_int;
    bitflags!(
        flags TypeKind: c_int {
            const Void = 0,
            const SByte = 1,
            const UByte = 2,
            const Short = 3,
            const UShort = 4,
            const Int = 5,
            const UInt = 6,
            const NInt = 7,
            const NUInt = 8,
            const Long = 9,
            const ULong = 10,
            const Float32 = 11,
            const Float64 = 12,
            const NFloat = 13,
            const Struct = 14,
            const Union = 15,
            const Signature = 16,
            const Pointer = 17,
            const FirstTagged = 2,
            const SysBool = 10009,
            const SysChar = 10010
        }
    );
}
impl fmt::Show for Type {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let kind = self.get_kind();
        if kind.contains(kind::Pointer) {
            write!(fmt, "*mut {}", self.get_ref().unwrap())
        } else if kind.contains(kind::Signature) {
            try!("fn(".fmt(fmt));
            for arg in self.params() {
                try!(arg.fmt(fmt));
            }
            try!(") -> ".fmt(fmt));
            match self.get_return() {
                Some(x) => x.fmt(fmt),
                None => "()".fmt(fmt)
            }
        } else {
            write!(fmt, "{}", try!(util::dump(|fd| {
                unsafe { jit_dump_type(mem::transmute(fd), self.as_ptr()) };
            })))
        }
    }
}
/// A single field of a struct
#[deriving(PartialEq)]
pub struct Field<'a> {
    /// The index of the field
    pub index: c_uint,
    _type: jit_type_t,
    marker: ContravariantLifetime<'a>
}
impl<'a> Field<'a> {
    #[inline]
    /// Get the field's name or none if it lacks one
    pub fn get_name(&self) -> Option<String> {
        unsafe {
            let c_name = jit_type_get_name(self._type, self.index);
            if c_name.is_null() {
                None
            } else {
                Some(String::from_raw_buf(mem::transmute(c_name)))
            }
        }
    }
    #[inline(always)]
    /// Get the type of the field
    pub fn get_type(&self) -> Type {
        unsafe {
            from_ptr(jit_type_get_field(self._type, self.index))
        }
    }
    #[inline(always)]
    /// Get the offset of the field
    pub fn get_offset(&self) -> uint {
        unsafe {
            jit_type_get_offset(self._type, self.index) as uint
        }
    }
}
/// Iterates through all the fields of a struct
pub struct Fields<'a> {
    _type: jit_type_t,
    index: c_uint,
    length: c_uint,
    marker: ContravariantLifetime<'a>
}
impl<'a> Fields<'a> {
    #[inline(always)]
    fn new(ty:Type) -> Fields<'a> {
        unsafe {
            Fields {
                _type: ty.as_ptr(),
                index: 0 as c_uint,
                length: jit_type_num_fields(ty.as_ptr()),
                marker: ContravariantLifetime::<'a>
            }
        }
    }
}
impl<'a> Iterator<Field<'a>> for Fields<'a> {
    fn next(&mut self) -> Option<Field<'a>> {
        if self.index < self.length {
            let index = self.index;
            self.index += 1;
            Some(Field {
                index: index,
                _type: self._type,
                marker: ContravariantLifetime::<'a>
            })
        } else {
            None
        }
    }
    fn size_hint(&self) -> (uint, Option<uint>) {
        ((self.length - self.index) as uint, None)
    }
}
/// Iterator through all the arguments a function takes
pub struct Params<'a> {
    _type: jit_type_t,
    index: c_uint,
    length: c_uint,
    marker: ContravariantLifetime<'a>
}
impl<'a> Params<'a> {
    fn new(ty:Type) -> Params<'a> {
        unsafe {
            Params {
                _type: ty.as_ptr(),
                index: 0,
                length: jit_type_num_params(ty.as_ptr()),
                marker: ContravariantLifetime::<'a>
            }
        }
    }
}
impl<'a> Iterator<Type> for Params<'a> {
    fn next(&mut self) -> Option<Type> {
        if self.index < self.length {
            let index = self.index;
            self.index += 1;
            unsafe { from_ptr(jit_type_get_param(self._type, index)) }
        } else {
            None
        }
    }
    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        ((self.length - self.index) as uint, None)
    }
}
/// An object that represents a native system type.
/// Each `Type` represents a basic system type, be it a primitive, a struct, a
/// union, a pointer, or a function signature. The library uses this information
/// to lay out values in memory.
/// Types are not attached to a context so they are reference-counted by LibJIT,
/// so internally they are represented as `Rc<TypeData>`.
#[deriving(PartialEq)]
pub struct Type {
    _type: jit_type_t,
    no_copy: NoCopy
}
impl NativeRef for Type {
    #[inline(always)]
    unsafe fn as_ptr(&self) -> jit_type_t {
        self._type
    }
    #[inline(always)]
    unsafe fn from_ptr(ptr:jit_type_t) -> Type {
        Type {
            _type: ptr,
            no_copy: NoCopy
        }
    }
}
impl Clone for Type {
    #[inline]
    /// Make a copy of the type descriptor by increasing its reference count.
    fn clone(&self) -> Type {
        unsafe {
            from_ptr(jit_type_copy(self.as_ptr()))
        }
    }
}
#[unsafe_destructor]
impl Drop for Type {
    #[inline(always)]
    /// Free a type descriptor by decreasing its reference count.
    /// This function is safe to use on pre-defined types, which are never
    /// actually freed.
    fn drop(&mut self) {
        unsafe {
            jit_type_free(self.as_ptr());
        }
    }
}
extern fn free_data<T:'static>(data: *mut c_void) {
    unsafe {
        let actual_data:Box<T> = mem::transmute(data);
        mem::drop(actual_data);
    }
}
impl Type {
    /// Create a type descriptor for a function signature.
    pub fn create_signature(abi: ABI, return_type: Type, params: &mut [Type]) -> Type {
        unsafe {
            let mut native_params:Vec<jit_type_t> = params.iter().map(|param| param.as_ptr()).collect();
            let signature = jit_type_create_signature(abi as jit_abi_t, return_type.as_ptr(), native_params.as_mut_ptr(), params.len() as c_uint, 1);
            from_ptr(signature)
        }
    }
    #[inline(always)]
    /// Create a type descriptor for a structure.
    pub fn create_struct(fields: &mut [Type]) -> Type {
        unsafe {
            let mut native_fields:Vec<_> = fields.iter().map(|field| field.as_ptr()).collect();
            from_ptr(jit_type_create_struct(native_fields.as_mut_ptr(), fields.len() as c_uint, 1))
        }
    }
    #[inline(always)]
    /// Create a type descriptor for a union.
    pub fn create_union(fields: &mut [Type]) -> Type {
        unsafe {
            let mut native_fields:Vec<_> = fields.iter().map(|field| field.as_ptr()).collect();
            from_ptr(jit_type_create_union(native_fields.as_mut_ptr(), fields.len() as c_uint, 1))
        }
    }
    #[inline(always)]
    /// Create a type descriptor for a pointer to another type.
    pub fn create_pointer(pointee: Type) -> Type {
        unsafe {
            let ptr = jit_type_create_pointer(pointee.as_ptr(), 1);
            from_ptr(ptr)
        }
    }
    #[inline(always)]
    /// Create a new tagged type
    pub fn create_tagged<T:'static>(ty:Type, kind: kind::TypeKind, data: Box<T>) -> Type {
        unsafe {
            let free_data:extern fn(*mut c_void) = free_data::<T>;
            let ty = jit_type_create_tagged(ty.as_ptr(), kind.bits(), mem::transmute(&*data), Some(free_data), 1);
            mem::forget(data);
            from_ptr(ty)
        }
    }
    #[inline(always)]
    /// Get the size of this type in bytes.
    pub fn get_size(&self) -> uint {
        unsafe {
            jit_type_get_size(self.as_ptr()) as uint
        }
    }
    #[inline(always)]
    /// Get the alignment of this type in bytes.
    pub fn get_alignment(&self) -> uint {
        unsafe {
            jit_type_get_alignment(self.as_ptr()) as uint
        }
    }
    #[inline]
    /// Get a value that indicates the kind of this type. This allows callers to
    /// quickly classify a type to determine how it should be handled further.
    pub fn get_kind(&self) -> kind::TypeKind {
        unsafe {
            mem::transmute(jit_type_get_kind(self.as_ptr()))
        }
    }
    #[inline(always)]
    /// Get the type that is referred to by this pointer type.
    pub fn get_ref(&self) -> Option<Type> {
        unsafe {
            from_ptr(jit_type_get_ref(self.as_ptr()))
        }
    }

    #[inline(always)]
    pub fn get_tagged_data<T:'static>(&self) -> Option<&T> {
        unsafe {
            mem::transmute(jit_type_get_tagged_data(self.as_ptr()))
        }
    }
    #[inline(always)]
    pub fn set_tagged_data<T:'static>(&self, data: Box<T>) {
        unsafe {
            let free_data:extern fn(*mut c_void) = free_data::<T>;
            jit_type_set_tagged_data(self.as_ptr(), mem::transmute(&*data), Some(free_data));
            mem::forget(data);
        }
    }
    #[inline(always)]
    /// Get the type returned by this function type.
    pub fn get_return(&self) -> Option<Type> {
        unsafe {
            from_ptr(jit_type_get_return(self.as_ptr()))
        }
    }
    /// Set the field or parameter names of this type.
    pub fn set_names<T:ToCStr>(&self, names:&[T]) -> bool {
        unsafe {
            let native_names : Vec<*const i8> = names.iter().map(|name| name.to_c_str().into_inner()).collect();
            jit_type_set_names(self.as_ptr(), native_names.as_ptr() as *mut *mut i8, names.len() as u32) != 0
        }
    }
    #[inline(always)]
    /// Iterator over the type's fields
    pub fn fields<'a>(&'a self) -> Fields<'a> {
        Fields::new(self.clone())
    }
    #[inline(always)]
    /// Iterator over the function signature's parameters
    pub fn params<'a>(&'a self) -> Params<'a> {
        Params::new(self.clone())
    }
    #[inline]
    /// Find the field/parameter index for a particular name.
    pub fn find_name<'b, T:ToCStr>(&'b self, name:T) -> Field<'b> {
        name.with_c_str(|c_name| unsafe {
            Field {
                index: jit_type_find_name(self.as_ptr(), c_name),
                _type: self.as_ptr(),
                marker: ContravariantLifetime::<'b>
            }
        })
    }
    #[inline(always)]
    /// Check if this is a pointer
    pub fn is_primitive(&self) -> bool {
        unsafe {
            jit_type_is_primitive(self.as_ptr()) != 0
        }
    }
    #[inline(always)]
    /// Check if this is a struct
    pub fn is_struct(&self) -> bool {
        unsafe {
            jit_type_is_struct(self.as_ptr()) != 0
        }
    }
    #[inline(always)]
    /// Check if this is a union
    pub fn is_union(&self) -> bool {
        unsafe {
            jit_type_is_union(self.as_ptr()) != 0
        }
    }
    #[inline(always)]
    /// Check if this is a signature
    pub fn is_signature(&self) -> bool {
        unsafe {
            jit_type_is_signature(self.as_ptr()) != 0
        }
    }
    #[inline(always)]
    /// Check if this is a pointer
    pub fn is_pointer(&self) -> bool {
        unsafe {
            jit_type_is_pointer(self.as_ptr()) != 0
        }
    }
    #[inline(always)]
    /// Check if this is tagged
    pub fn is_tagged(&self) -> bool {
        unsafe {
            jit_type_is_tagged(self.as_ptr()) != 0
        }
    }
}
#[inline(always)]
/// Get the Rust type given as a type descriptor
pub fn get<T: Compile>() -> Type {
    Compile::jit_type(None::<T>)
}<|endoftext|>


<commit_before>use crate::{peer::DisconnectReason, util::*};
use arrayvec::ArrayString;
use async_trait::async_trait;
use auto_impl::auto_impl;
use bytes::Bytes;
use derive_more::Display;
use educe::Educe;
pub use ethereum_types::H512 as PeerId;
use rlp::{DecoderError, Rlp, RlpStream};
use std::{collections::HashMap, fmt::Debug, net::SocketAddr, str::FromStr};

/// Record that specifies information necessary to connect to RLPx node
#[derive(Clone, Copy, Debug)]
pub struct NodeRecord {
    /// Node ID.
    pub id: PeerId,
    /// Address of RLPx TCP server.
    pub addr: SocketAddr,
}

impl FromStr for NodeRecord {
    type Err = Box<dyn std::error::Error + Send + Sync>;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        const PREFIX: &str = "enode://";

        let (prefix, data) = s.split_at(PREFIX.len());
        if prefix != PREFIX {
            return Err("Not an enode".into());
        }

        let mut parts = data.split('@');
        let id = parts
            .next()
            .ok_or_else(|| "Failed to read remote ID")?
            .parse()?;
        let addr = parts
            .next()
            .ok_or_else(|| "Failed to read address")?
            .parse()?;

        Ok(Self { id, addr })
    }
}

#[derive(Clone, Copy, Debug, Display, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CapabilityName(pub ArrayString<[u8; 4]>);

impl rlp::Encodable for CapabilityName {
    fn rlp_append(&self, s: &mut RlpStream) {
        self.0.as_bytes().rlp_append(s);
    }
}

impl rlp::Decodable for CapabilityName {
    fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
        Ok(Self(
            ArrayString::from(
                std::str::from_utf8(rlp.data()?)
                    .map_err(|_| DecoderError::Custom("should be a UTF-8 string"))?,
            )
            .map_err(|_| DecoderError::RlpIsTooBig)?,
        ))
    }
}

pub type CapabilityLength = usize;
pub type CapabilityVersion = usize;

#[derive(Clone, Debug, Copy, PartialEq, Eq)]
/// Capability information
pub struct CapabilityInfo {
    pub name: CapabilityName,
    pub version: CapabilityVersion,
    pub length: CapabilityLength,
}

impl CapabilityInfo {
    pub fn new(CapabilityId { name, version }: CapabilityId, length: CapabilityLength) -> Self {
        Self {
            name,
            version,
            length,
        }
    }
}

#[derive(Clone, Debug, Display, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[display(fmt = "{}/{}", name, version)]
pub struct CapabilityId {
    pub name: CapabilityName,
    pub version: CapabilityVersion,
}

impl From<CapabilityInfo> for CapabilityId {
    fn from(CapabilityInfo { name, version, .. }: CapabilityInfo) -> Self {
        Self { name, version }
    }
}

#[derive(Clone, Debug, Display)]
pub enum InboundEvent {
    #[display(
        fmt = "disconnect/{}",
        "reason.map(|r| r.to_string()).unwrap_or_else(|| \"(no reason)\".to_string())"
    )]
    Disconnect { reason: Option<DisconnectReason> },
    #[display(fmt = "message/{}/{}", capability_name, "message.id.to_string()")]
    Message {
        capability_name: CapabilityName,
        message: Message,
    },
}

#[derive(Clone, Debug)]
pub enum OutboundEvent {
    Disconnect {
        reason: DisconnectReason,
    },
    Message {
        capability_name: CapabilityName,
        message: Message,
    },
}

#[async_trait]
#[auto_impl(&, Box, Arc)]
pub trait CapabilityServer: Send + Sync + 'static {
    /// Should be used to set up relevant state for the peer.
    fn on_peer_connect(&self, peer: PeerId, caps: HashMap<CapabilityName, CapabilityVersion>);
    /// Called on the next event for peer.
    async fn on_peer_event(&self, peer: PeerId, event: InboundEvent);
    /// Get the next event for peer.
    async fn next(&self, peer: PeerId) -> OutboundEvent;
}

#[async_trait]
impl CapabilityServer for () {
    fn on_peer_connect(&self, _: PeerId, _: HashMap<CapabilityName, CapabilityVersion>) {}

    async fn on_peer_event(&self, _: PeerId, _: InboundEvent) {}

    async fn next(&self, _: PeerId) -> OutboundEvent {
        futures::future::pending().await
    }
}

#[derive(Clone, Educe)]
#[educe(Debug)]
pub struct Message {
    pub id: usize,
    #[educe(Debug(method = "hex_debug"))]
    pub data: Bytes,
}
<commit_msg>Fix clippy warnings<commit_after>use crate::{peer::DisconnectReason, util::*};
use arrayvec::ArrayString;
use async_trait::async_trait;
use auto_impl::auto_impl;
use bytes::Bytes;
use derive_more::Display;
use educe::Educe;
pub use ethereum_types::H512 as PeerId;
use rlp::{DecoderError, Rlp, RlpStream};
use std::{collections::HashMap, fmt::Debug, net::SocketAddr, str::FromStr};

/// Record that specifies information necessary to connect to RLPx node
#[derive(Clone, Copy, Debug)]
pub struct NodeRecord {
    /// Node ID.
    pub id: PeerId,
    /// Address of RLPx TCP server.
    pub addr: SocketAddr,
}

impl FromStr for NodeRecord {
    type Err = Box<dyn std::error::Error + Send + Sync>;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        const PREFIX: &str = "enode://";

        let (prefix, data) = s.split_at(PREFIX.len());
        if prefix != PREFIX {
            return Err("Not an enode".into());
        }

        let mut parts = data.split('@');
        let id = parts.next().ok_or("Failed to read remote ID")?.parse()?;
        let addr = parts.next().ok_or("Failed to read address")?.parse()?;

        Ok(Self { id, addr })
    }
}

#[derive(Clone, Copy, Debug, Display, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CapabilityName(pub ArrayString<[u8; 4]>);

impl rlp::Encodable for CapabilityName {
    fn rlp_append(&self, s: &mut RlpStream) {
        self.0.as_bytes().rlp_append(s);
    }
}

impl rlp::Decodable for CapabilityName {
    fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
        Ok(Self(
            ArrayString::from(
                std::str::from_utf8(rlp.data()?)
                    .map_err(|_| DecoderError::Custom("should be a UTF-8 string"))?,
            )
            .map_err(|_| DecoderError::RlpIsTooBig)?,
        ))
    }
}

pub type CapabilityLength = usize;
pub type CapabilityVersion = usize;

#[derive(Clone, Debug, Copy, PartialEq, Eq)]
/// Capability information
pub struct CapabilityInfo {
    pub name: CapabilityName,
    pub version: CapabilityVersion,
    pub length: CapabilityLength,
}

impl CapabilityInfo {
    pub fn new(CapabilityId { name, version }: CapabilityId, length: CapabilityLength) -> Self {
        Self {
            name,
            version,
            length,
        }
    }
}

#[derive(Clone, Debug, Display, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[display(fmt = "{}/{}", name, version)]
pub struct CapabilityId {
    pub name: CapabilityName,
    pub version: CapabilityVersion,
}

impl From<CapabilityInfo> for CapabilityId {
    fn from(CapabilityInfo { name, version, .. }: CapabilityInfo) -> Self {
        Self { name, version }
    }
}

#[derive(Clone, Debug, Display)]
pub enum InboundEvent {
    #[display(
        fmt = "disconnect/{}",
        "reason.map(|r| r.to_string()).unwrap_or_else(|| \"(no reason)\".to_string())"
    )]
    Disconnect { reason: Option<DisconnectReason> },
    #[display(fmt = "message/{}/{}", capability_name, "message.id.to_string()")]
    Message {
        capability_name: CapabilityName,
        message: Message,
    },
}

#[derive(Clone, Debug)]
pub enum OutboundEvent {
    Disconnect {
        reason: DisconnectReason,
    },
    Message {
        capability_name: CapabilityName,
        message: Message,
    },
}

#[async_trait]
#[auto_impl(&, Box, Arc)]
pub trait CapabilityServer: Send + Sync + 'static {
    /// Should be used to set up relevant state for the peer.
    fn on_peer_connect(&self, peer: PeerId, caps: HashMap<CapabilityName, CapabilityVersion>);
    /// Called on the next event for peer.
    async fn on_peer_event(&self, peer: PeerId, event: InboundEvent);
    /// Get the next event for peer.
    async fn next(&self, peer: PeerId) -> OutboundEvent;
}

#[async_trait]
impl CapabilityServer for () {
    fn on_peer_connect(&self, _: PeerId, _: HashMap<CapabilityName, CapabilityVersion>) {}

    async fn on_peer_event(&self, _: PeerId, _: InboundEvent) {}

    async fn next(&self, _: PeerId) -> OutboundEvent {
        futures::future::pending().await
    }
}

#[derive(Clone, Educe)]
#[educe(Debug)]
pub struct Message {
    pub id: usize,
    #[educe(Debug(method = "hex_debug"))]
    pub data: Bytes,
}
<|endoftext|>


<commit_before>use std::cell::Cell;
use std::slice;

use cairo::prelude::SurfaceExt;
use cairo::{self, ImageSurface};
use cairo_sys;
use libc::c_char;

use attributes::Attribute;
use handle::RsvgHandle;
use length::{LengthDir, RsvgLength};
use node::{boxed_node_new, NodeResult, NodeTrait, NodeType, RsvgCNodeImpl, RsvgNode};
use parsers::{parse, Parse};
use property_bag::PropertyBag;

use super::context::{FilterContext, FilterOutput, FilterResult};
use super::{get_surface, Filter, FilterError, PrimitiveWithInput};

/// The `feOffset` filter primitive.
struct Offset {
    base: PrimitiveWithInput,
    dx: Cell<RsvgLength>,
    dy: Cell<RsvgLength>,
}

impl Offset {
    /// Constructs a new `Offset` with empty properties.
    #[inline]
    fn new() -> Offset {
        Offset {
            base: PrimitiveWithInput::new::<Self>(),
            dx: Cell::new(RsvgLength::parse("0", LengthDir::Horizontal).unwrap()),
            dy: Cell::new(RsvgLength::parse("0", LengthDir::Vertical).unwrap()),
        }
    }
}

impl NodeTrait for Offset {
    fn set_atts(
        &self,
        node: &RsvgNode,
        handle: *const RsvgHandle,
        pbag: &PropertyBag,
    ) -> NodeResult {
        self.base.set_atts(node, handle, pbag)?;

        for (_key, attr, value) in pbag.iter() {
            match attr {
                Attribute::Dx => self
                    .dx
                    .set(parse("dx", value, LengthDir::Horizontal, None)?),
                Attribute::Dy => self.dy.set(parse("dy", value, LengthDir::Vertical, None)?),
                _ => (),
            }
        }

        Ok(())
    }

    #[inline]
    fn get_c_impl(&self) -> *const RsvgCNodeImpl {
        self.base.get_c_impl()
    }
}

impl Filter for Offset {
    fn render(&self, node: &RsvgNode, ctx: &FilterContext) -> Result<FilterResult, FilterError> {
        let cascaded = node.get_cascaded_values();
        let values = cascaded.get();

        let bounds = self.base.get_bounds(ctx);

        let dx = self.dx.get().normalize(&values, ctx.drawing_context());
        let dy = self.dy.get().normalize(&values, ctx.drawing_context());
        let paffine = ctx.paffine();
        let ox = (paffine.xx * dx + paffine.xy * dy) as i32;
        let oy = (paffine.yx * dx + paffine.yy * dy) as i32;

        let input_surface = get_surface(self.base.get_input(ctx))?;

        let width = input_surface.get_width();
        let height = input_surface.get_height();
        let input_stride = input_surface.get_stride();

        // TODO: this currently gives "non-exclusive access" (can we make read-only borrows?)
        // let input_data = input_surface.get_data().unwrap();
        input_surface.flush();
        if input_surface.status() != cairo::Status::Success {
            return Err(FilterError::BadInputSurfaceStatus(input_surface.status()));
        }
        let input_data_ptr =
            unsafe { cairo_sys::cairo_image_surface_get_data(input_surface.to_raw_none()) };
        assert!(!input_data_ptr.is_null());
        let input_data_len = input_stride as usize * height as usize;
        let input_data = unsafe { slice::from_raw_parts(input_data_ptr, input_data_len) };

        let mut output_surface = ImageSurface::create(cairo::Format::ARgb32, width, height)
            .map_err(FilterError::OutputSurfaceCreation)?;

        let output_stride = output_surface.get_stride();
        {
            let mut output_data = output_surface.get_data().unwrap();

            for y in bounds.y0..bounds.y1 {
                for x in bounds.x0..bounds.x1 {
                    if x - ox < bounds.x0
                        || x - ox >= bounds.x1
                        || y - oy < bounds.y0
                        || y - oy >= bounds.y1
                    {
                        continue;
                    }

                    for ch in 0..4 {
                        let input_index = ((y - oy) * input_stride + (x - ox) * 4 + ch) as usize;
                        let output_index = (y * output_stride + x * 4 + ch) as usize;

                        output_data[output_index] = input_data[input_index];
                    }
                }
            }
        }

        Ok(FilterResult {
            name: self.base.result.borrow().clone(),
            output: FilterOutput {
                surface: output_surface,
                bounds,
            },
        })
    }
}

/// Returns a new `feOffset` node.
#[no_mangle]
pub unsafe extern "C" fn rsvg_new_filter_primitive_offset(
    _element_name: *const c_char,
    parent: *mut RsvgNode,
) -> *mut RsvgNode {
    let filter = Offset::new();
    boxed_node_new(NodeType::FilterPrimitiveOffset, parent, Box::new(filter))
}
<commit_msg>Refactor feOffset to use the new iterator<commit_after>use std::cell::Cell;

use cairo::{self, ImageSurface};
use libc::c_char;

use attributes::Attribute;
use handle::RsvgHandle;
use length::{LengthDir, RsvgLength};
use node::{boxed_node_new, NodeResult, NodeTrait, NodeType, RsvgCNodeImpl, RsvgNode};
use parsers::{parse, Parse};
use property_bag::PropertyBag;
use util::clamp;

use super::context::{FilterContext, FilterOutput, FilterResult, IRect};
use super::iterators::{ImageSurfaceDataShared, Pixels};
use super::{get_surface, Filter, FilterError, PrimitiveWithInput};

/// The `feOffset` filter primitive.
struct Offset {
    base: PrimitiveWithInput,
    dx: Cell<RsvgLength>,
    dy: Cell<RsvgLength>,
}

impl Offset {
    /// Constructs a new `Offset` with empty properties.
    #[inline]
    fn new() -> Offset {
        Offset {
            base: PrimitiveWithInput::new::<Self>(),
            dx: Cell::new(RsvgLength::parse("0", LengthDir::Horizontal).unwrap()),
            dy: Cell::new(RsvgLength::parse("0", LengthDir::Vertical).unwrap()),
        }
    }
}

impl NodeTrait for Offset {
    fn set_atts(
        &self,
        node: &RsvgNode,
        handle: *const RsvgHandle,
        pbag: &PropertyBag,
    ) -> NodeResult {
        self.base.set_atts(node, handle, pbag)?;

        for (_key, attr, value) in pbag.iter() {
            match attr {
                Attribute::Dx => self
                    .dx
                    .set(parse("dx", value, LengthDir::Horizontal, None)?),
                Attribute::Dy => self.dy.set(parse("dy", value, LengthDir::Vertical, None)?),
                _ => (),
            }
        }

        Ok(())
    }

    #[inline]
    fn get_c_impl(&self) -> *const RsvgCNodeImpl {
        self.base.get_c_impl()
    }
}

impl Filter for Offset {
    fn render(&self, node: &RsvgNode, ctx: &FilterContext) -> Result<FilterResult, FilterError> {
        let cascaded = node.get_cascaded_values();
        let values = cascaded.get();

        let bounds = self.base.get_bounds(ctx);

        let dx = self.dx.get().normalize(&values, ctx.drawing_context());
        let dy = self.dy.get().normalize(&values, ctx.drawing_context());
        let paffine = ctx.paffine();
        let ox = (paffine.xx * dx + paffine.xy * dy) as i32;
        let oy = (paffine.yx * dx + paffine.yy * dy) as i32;

        let input_surface = get_surface(self.base.get_input(ctx))?;
        let input_data = ImageSurfaceDataShared::new(&input_surface)?;

        // input_bounds contains all pixels within bounds,
        // for which (x + ox) and (y + oy) also lie within bounds.
        let input_bounds = IRect {
            x0: clamp(bounds.x0 - ox, bounds.x0, bounds.x1),
            y0: clamp(bounds.y0 - oy, bounds.y0, bounds.y1),
            x1: clamp(bounds.x1 - ox, bounds.x0, bounds.x1),
            y1: clamp(bounds.y1 - oy, bounds.y0, bounds.y1),
        };

        let mut output_surface = ImageSurface::create(
            cairo::Format::ARgb32,
            input_data.width as i32,
            input_data.height as i32,
        ).map_err(FilterError::OutputSurfaceCreation)?;

        let output_stride = output_surface.get_stride() as usize;
        {
            let mut output_data = output_surface.get_data().unwrap();

            for (x, y, pixel) in Pixels::new(input_data, input_bounds) {
                let output_x = (x as i32 + ox) as usize;
                let output_y = (y as i32 + oy) as usize;

                let output_base = output_y * output_stride + output_x * 4;
                output_data[output_base + 0] = pixel.r;
                output_data[output_base + 1] = pixel.g;
                output_data[output_base + 2] = pixel.b;
                output_data[output_base + 3] = pixel.a;
            }
        }

        Ok(FilterResult {
            name: self.base.result.borrow().clone(),
            output: FilterOutput {
                surface: output_surface,
                bounds,
            },
        })
    }
}

/// Returns a new `feOffset` node.
#[no_mangle]
pub unsafe extern "C" fn rsvg_new_filter_primitive_offset(
    _element_name: *const c_char,
    parent: *mut RsvgNode,
) -> *mut RsvgNode {
    let filter = Offset::new();
    boxed_node_new(NodeType::FilterPrimitiveOffset, parent, Box::new(filter))
}
<|endoftext|>


<commit_before>//! Server discovery endpoints.

use std::{collections::BTreeMap, time::SystemTime};

use ruma_identifiers::{ServerKeyId, ServerNameBox};
use serde::{Deserialize, Serialize};

pub mod discover_homeserver;
pub mod get_remote_server_keys;
pub mod get_remote_server_keys_batch;
pub mod get_server_keys;
pub mod get_server_version;

/// Public key of the homeserver for verifying digital signatures.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct VerifyKey {
    /// The Unpadded Base64 encoded key.
    pub key: String,
}

impl VerifyKey {
    /// Creates a new `VerifyKey` from the given key.
    pub fn new(key: String) -> Self {
        Self { key }
    }
}

/// A key the server used to use, but stopped using.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct OldVerifyKey {
    /// Timestamp when this key expired.
    #[serde(with = "ruma_serde::time::ms_since_unix_epoch")]
    pub expired_ts: SystemTime,
    /// The Unpadded Base64 encoded key.
    pub key: String,
}

impl OldVerifyKey {
    /// Creates a new `OldVerifyKey` with the given expiry time and key.
    pub fn new(expired_ts: SystemTime, key: String) -> Self {
        Self { expired_ts, key }
    }
}

// Spec is wrong, all fields are required (see https://github.com/matrix-org/matrix-doc/issues/2508)
/// Queried server key, signed by the notary server.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct ServerKey {
    /// DNS name of the homeserver.
    pub server_name: ServerNameBox,
    /// Public keys of the homeserver for verifying digital signatures.
    pub verify_keys: BTreeMap<String, VerifyKey>,
    /// Public keys that the homeserver used to use and when it stopped using them.
    pub old_verify_keys: BTreeMap<String, OldVerifyKey>,
    /// Digital signatures of this object signed using the verify_keys. Map of
    /// server name to keys by key ID
    pub signatures: BTreeMap<ServerNameBox, BTreeMap<ServerKeyId, String>>,
    /// Timestamp when the keys should be refreshed. This field MUST be ignored in room
    /// versions 1, 2, 3, and 4.
    #[serde(with = "ruma_serde::time::ms_since_unix_epoch")]
    pub valid_until_ts: SystemTime,
}

impl ServerKey {
    /// Creates a new `ServerKey` with the given server name and validity timestamp.
    ///
    /// All other fields will be empty.
    pub fn new(server_name: ServerNameBox, valid_until_ts: SystemTime) -> Self {
        Self {
            server_name,
            verify_keys: BTreeMap::new(),
            old_verify_keys: BTreeMap::new(),
            signatures: BTreeMap::new(),
            valid_until_ts,
        }
    }
}
<commit_msg>federation-api: Use ServerKeys for verify_keys, old_verify_keys<commit_after>//! Server discovery endpoints.

use std::{collections::BTreeMap, time::SystemTime};

use ruma_identifiers::{ServerKeyId, ServerNameBox};
use serde::{Deserialize, Serialize};

pub mod discover_homeserver;
pub mod get_remote_server_keys;
pub mod get_remote_server_keys_batch;
pub mod get_server_keys;
pub mod get_server_version;

/// Public key of the homeserver for verifying digital signatures.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct VerifyKey {
    /// The Unpadded Base64 encoded key.
    pub key: String,
}

impl VerifyKey {
    /// Creates a new `VerifyKey` from the given key.
    pub fn new(key: String) -> Self {
        Self { key }
    }
}

/// A key the server used to use, but stopped using.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct OldVerifyKey {
    /// Timestamp when this key expired.
    #[serde(with = "ruma_serde::time::ms_since_unix_epoch")]
    pub expired_ts: SystemTime,
    /// The Unpadded Base64 encoded key.
    pub key: String,
}

impl OldVerifyKey {
    /// Creates a new `OldVerifyKey` with the given expiry time and key.
    pub fn new(expired_ts: SystemTime, key: String) -> Self {
        Self { expired_ts, key }
    }
}

// Spec is wrong, all fields are required (see https://github.com/matrix-org/matrix-doc/issues/2508)
/// Queried server key, signed by the notary server.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct ServerKey {
    /// DNS name of the homeserver.
    pub server_name: ServerNameBox,
    /// Public keys of the homeserver for verifying digital signatures.
    pub verify_keys: BTreeMap<ServerKeyId, VerifyKey>,
    /// Public keys that the homeserver used to use and when it stopped using them.
    pub old_verify_keys: BTreeMap<ServerKeyId, OldVerifyKey>,
    /// Digital signatures of this object signed using the verify_keys. Map of
    /// server name to keys by key ID
    pub signatures: BTreeMap<ServerNameBox, BTreeMap<ServerKeyId, String>>,
    /// Timestamp when the keys should be refreshed. This field MUST be ignored in room
    /// versions 1, 2, 3, and 4.
    #[serde(with = "ruma_serde::time::ms_since_unix_epoch")]
    pub valid_until_ts: SystemTime,
}

impl ServerKey {
    /// Creates a new `ServerKey` with the given server name and validity timestamp.
    ///
    /// All other fields will be empty.
    pub fn new(server_name: ServerNameBox, valid_until_ts: SystemTime) -> Self {
        Self {
            server_name,
            verify_keys: BTreeMap::new(),
            old_verify_keys: BTreeMap::new(),
            signatures: BTreeMap::new(),
            valid_until_ts,
        }
    }
}
<|endoftext|>


<commit_before>/// Internal namespace.
pub( crate ) mod private
{
  use crate::prelude::*;
  // use std::collections::HashSet;
  use indexmap::IndexSet;
  use std::fmt;

  ///
  /// Canonical implementation of node.
  ///

  pub struct Node< Kind = crate::NodeKindless >
  where
    Kind : NodeKindInterface,
  {
    /// Input node.
    pub out_nodes : IndexSet< < Self as HasId >::Id >,
    /// Kind of the node.
    pub kind : Kind,
    /// Name.
    pub name : < Self as HasId >::Id,
  }

  //

  impl Node
  {

    /// Construct a name instance of the node.
    pub fn make_named< Name >( name : Name ) ->Self
    where
      Name : Into< < Self as HasId >::Id >,
    {
      let out_nodes = IndexSet::new();
      let kind = Default::default();
      Self
      {
        out_nodes,
        kind,
        name : name.into(),
      }
    }

  }

  //

  impl< Kind > HasId
  for Node< Kind >
  where
    Kind : NodeKindInterface,
  {

    type Id = crate::IdentityWithInt;

    fn id( &self ) -> Self::Id
    {
      self.name
    }

  }

  //

  // impl< Id, Kind > HasId
  // for Node< Id, Kind >
  // where
  //   Kind : NodeKindInterface,
  //   Id : IdentityInterface,
  // {
  //   type Id = Id;
  //   fn id( &self ) -> Self::Id
  //   {
  //     self.name
  //   }
  // }

  //

  impl< Kind > NodeBasicInterface
  for Node< Kind >
  where
    Kind : NodeKindInterface,
  {
  }

  //

  impl Extend< < Self as HasId >::Id >
  for Node
  {
    fn extend< Iter >( &mut self, iter : Iter )
    where
      Iter : IntoIterator< Item = < Self as HasId >::Id >
    {
      for node in iter
      {
        self.out_nodes.insert( node );
      }
    }
  }

  //

  impl< Kind > fmt::Debug
  for Node< Kind >
  where
    Kind : NodeKindInterface,
  {
    fn fmt( &self, f : &mut fmt::Formatter<'_> ) -> fmt::Result
    {
      f.write_fmt( format_args!( "node::{:?}", self.id() ) )?;
      for e in &self.out_nodes
      {
        f.write_fmt( format_args!( "\n - {:?}", e ) )?;
      }
      f.write_fmt( format_args!( "" ) )
    }
  }

  //

  impl< Kind > PartialEq for Node< Kind >
  where
    Kind : NodeKindInterface,
  {
    fn eq( &self, other : &Self ) -> bool
    {
      self.id() == other.id()
    }
  }

}

/// Protected namespace of the module.
pub mod protected
{
  pub use super::orphan::*;
}

pub use protected::*;

/// Parented namespace of the module.
pub mod orphan
{
  pub use super::exposed::*;
  pub use super::private::{ Node };
}

/// Exposed namespace of the module.
pub mod exposed
{
  pub use super::prelude::*;
}

/// Prelude to use essentials: `use my_module::prelude::*`.
pub mod prelude
{
}
<commit_msg>evolve automata_tools<commit_after>/// Internal namespace.
pub( crate ) mod private
{
  use crate::prelude::*;
  // use std::collections::HashSet;
  use indexmap::IndexSet;
  use std::fmt;

  ///
  /// Canonical implementation of node.
  ///

  pub struct Node< Id = crate::IdentityWithInt, Kind = crate::NodeKindless >
  where
    Id : IdentityInterface,
    Kind : NodeKindInterface,
  {
    /// Input node.
    pub out_nodes : IndexSet< Id >,
    // pub out_nodes : IndexSet< < Self as HasId >::Id >,
    /// Kind of the node.
    pub kind : Kind,
    /// Name.
    pub name : Id,
    // pub name : < Self as HasId >::Id,
  }

  //

  impl< Id, Kind > Node< Id, Kind >
  where
    Id : IdentityInterface,
    Kind : NodeKindInterface,
  {

    /// Construct a name instance of the node.
    pub fn make_named< Name >( name : Name ) ->Self
    where
      Name : Into< < Self as HasId >::Id >,
    {
      let out_nodes = IndexSet::new();
      let kind = Default::default();
      Self
      {
        out_nodes,
        kind,
        name : name.into(),
      }
    }

  }

  //

//   impl< Kind > HasId
//   for Node< Kind >
//   where
//     Kind : NodeKindInterface,
//   {
//
//     type Id = crate::IdentityWithInt;
//
//     fn id( &self ) -> Self::Id
//     {
//       self.name
//     }
//
//   }

  //

  impl< Id, Kind > HasId
  for Node< Id, Kind >
  where
    Id : IdentityInterface,
    Kind : NodeKindInterface,
  {
    type Id = Id;
    fn id( &self ) -> Self::Id
    {
      self.name
    }
  }

  //

  impl< Id, Kind > NodeBasicInterface
  for Node< Id, Kind >
  where
    Id : IdentityInterface,
    Kind : NodeKindInterface,
  {
  }

  //

  impl Extend< < Self as HasId >::Id >
  for Node
  {
    fn extend< Iter >( &mut self, iter : Iter )
    where
      Iter : IntoIterator< Item = < Self as HasId >::Id >
    {
      for node in iter
      {
        self.out_nodes.insert( node );
      }
    }
  }

  //

  impl< Id, Kind > fmt::Debug
  for Node< Id, Kind >
  where
    Id : IdentityInterface,
    Kind : NodeKindInterface,
  {
    fn fmt( &self, f : &mut fmt::Formatter<'_> ) -> fmt::Result
    {
      f.write_fmt( format_args!( "node::{:?}", self.id() ) )?;
      for e in &self.out_nodes
      {
        f.write_fmt( format_args!( "\n - {:?}", e ) )?;
      }
      f.write_fmt( format_args!( "" ) )
    }
  }

  //

  impl< Id, Kind > PartialEq for Node< Id, Kind >
  where
    Id : IdentityInterface,
    Kind : NodeKindInterface,
  {
    fn eq( &self, other : &Self ) -> bool
    {
      self.id() == other.id()
    }
  }

}

/// Protected namespace of the module.
pub mod protected
{
  pub use super::orphan::*;
}

pub use protected::*;

/// Parented namespace of the module.
pub mod orphan
{
  pub use super::exposed::*;
  pub use super::private::{ Node };
}

/// Exposed namespace of the module.
pub mod exposed
{
  pub use super::prelude::*;
}

/// Prelude to use essentials: `use my_module::prelude::*`.
pub mod prelude
{
}
<|endoftext|>


<commit_before>#![feature(macro_rules)]
#![allow(non_snake_case_functions)]

extern crate getopts;
extern crate inlined_parser;

use getopts::{optflag, getopts, optopt};
use std::os;
use std::str;
use std::io::File;
use std::io::TempDir;
use std::io::Command;
use std::path::Path;
use self::prelude::PRELUDE;
use self::printer::PRINTER_MAIN;
use inlined_parser::parse;

mod generator;
mod prelude;
mod printer;

fn inputFromFile( input_file: &str ) -> Vec<u8> {
  match File::open( &Path::new( input_file ) ).read_to_end() {
    Ok( x ) => x,
    _ => fail!( "Couldn't read input file: {}", input_file )
  }
}

fn indentLines( input: &str, num_spaces: uint ) -> String {
  let indent = " ".repeat( num_spaces );
  input.split( '\n' ).map(
    |x| [ indent.as_slice(), x, "\n" ].concat() )
    .collect::<Vec<String>>().concat()
}

fn printUsage( opts: &[getopts::OptGroup] ) {
  let program = Path::new( os::args().get( 0 ).as_slice() );
  let short = getopts::short_usage( program.filename_str().unwrap(), opts );
  let usage = getopts::usage( short.as_slice(), opts );
  println!( "{}", usage );
}

fn codeForGrammar( input: &[u8] ) -> Option<String> {
  match parse( input ) {
    Some( ref node ) => {
      let parse_rules = indentLines( generator::codeForNode( node ).as_slice(),
                                     2 );
      Some( [ PRELUDE.slice_to( PRELUDE.len() -1 ),
              "\n",
              parse_rules.as_slice(),
              "}" ].concat() )
    }
    _ => None
  }
}

fn printParseTree( grammar_code: &str, input_path: &str ) {
  let final_code = grammar_code.to_string().append( PRINTER_MAIN );
  let temp_dir = TempDir::new( "temp" ).unwrap();
  let code_file = temp_dir.path().join( "printer.rs" );
  let printer = temp_dir.path().join( "printer" );

  match File::create( &code_file ).write( final_code.as_bytes() ) {
    Err( e ) => fail!( "File error: {}", e ),
    _ => {}
  };

  match Command::new( "rustc" ).arg( "-o" )
                               .arg( printer.as_str().unwrap() )
                               .arg( code_file.as_str().unwrap() )
                               .status() {
    Ok( status ) if !status.success() =>
      fail!( "Compiling with rustc failed." ),
    Err( e ) => fail!( "Failed to execute process: {}", e ),
    _ => {}
  };

  let printer = temp_dir.path().join( "printer" );
  let output = match Command::new(
      printer.as_str().unwrap() ).arg( input_path ).output() {
    Ok( output ) => output.output,
    Err( e ) => fail!( "Failed to execute process: {}", e ),
  };

  println!( "{}", str::from_utf8_lossy( output.as_slice() ) );
}

#[cfg(not(test))]
fn main() {
  let opts = [
    optflag( "h", "help", "Print this help menu." ),
    optopt( "i", "input",
            "Path to input file to parse with grammar given to -g option",
            "FILE" ),
    optopt( "g", "grammar",
            "Path to PEG grammar. Prints code for grammar if -i not given.",
            "FILE" )

  ];

  let args = os::args();
  let matches = match getopts( args.tail(), opts ) {
    Ok( m ) => m,
    Err( erorr ) => fail!( erorr )
  };

  if matches.opt_present( "h" ) || args.len() < 2 {
    printUsage( opts );
    return;
  }

  let grammar_code = if matches.opt_present( "g" ) {
    codeForGrammar( inputFromFile(
        matches.opt_str( "g" ).unwrap().as_slice() ).as_slice() )
    .unwrap_or_else( || fail!( "Couldn't parse given PEG grammar" ) )
  } else {
    fail!( "Missing -g option." )
  };

  if matches.opt_present( "i" ) {
    printParseTree(
      grammar_code.as_slice(),
      matches.opt_str( "i" ).unwrap().as_slice() );
  } else {
    println!( "{}", grammar_code );
  }
}

<commit_msg>Replaced usage of deprecated function<commit_after>#![feature(macro_rules)]
#![allow(non_snake_case_functions)]

extern crate getopts;
extern crate inlined_parser;

use getopts::{optflag, getopts, optopt};
use std::os;
use std::io::File;
use std::io::TempDir;
use std::io::Command;
use std::path::Path;
use self::prelude::PRELUDE;
use self::printer::PRINTER_MAIN;
use inlined_parser::parse;

mod generator;
mod prelude;
mod printer;

fn inputFromFile( input_file: &str ) -> Vec<u8> {
  match File::open( &Path::new( input_file ) ).read_to_end() {
    Ok( x ) => x,
    _ => fail!( "Couldn't read input file: {}", input_file )
  }
}

fn indentLines( input: &str, num_spaces: uint ) -> String {
  let indent = " ".repeat( num_spaces );
  input.split( '\n' ).map(
    |x| [ indent.as_slice(), x, "\n" ].concat() )
    .collect::<Vec<String>>().concat()
}

fn printUsage( opts: &[getopts::OptGroup] ) {
  let program = Path::new( os::args().get( 0 ).as_slice() );
  let short = getopts::short_usage( program.filename_str().unwrap(), opts );
  let usage = getopts::usage( short.as_slice(), opts );
  println!( "{}", usage );
}

fn codeForGrammar( input: &[u8] ) -> Option<String> {
  match parse( input ) {
    Some( ref node ) => {
      let parse_rules = indentLines( generator::codeForNode( node ).as_slice(),
                                     2 );
      Some( [ PRELUDE.slice_to( PRELUDE.len() -1 ),
              "\n",
              parse_rules.as_slice(),
              "}" ].concat() )
    }
    _ => None
  }
}

fn printParseTree( grammar_code: &str, input_path: &str ) {
  let final_code = grammar_code.to_string().append( PRINTER_MAIN );
  let temp_dir = TempDir::new( "temp" ).unwrap();
  let code_file = temp_dir.path().join( "printer.rs" );
  let printer = temp_dir.path().join( "printer" );

  match File::create( &code_file ).write( final_code.as_bytes() ) {
    Err( e ) => fail!( "File error: {}", e ),
    _ => {}
  };

  match Command::new( "rustc" ).arg( "-o" )
                               .arg( printer.as_str().unwrap() )
                               .arg( code_file.as_str().unwrap() )
                               .status() {
    Ok( status ) if !status.success() =>
      fail!( "Compiling with rustc failed." ),
    Err( e ) => fail!( "Failed to execute process: {}", e ),
    _ => {}
  };

  let printer = temp_dir.path().join( "printer" );
  let output = match Command::new(
      printer.as_str().unwrap() ).arg( input_path ).output() {
    Ok( output ) => output.output,
    Err( e ) => fail!( "Failed to execute process: {}", e ),
  };

  println!( "{}", String::from_utf8_lossy( output.as_slice() ) );
}

#[cfg(not(test))]
fn main() {
  let opts = [
    optflag( "h", "help", "Print this help menu." ),
    optopt( "i", "input",
            "Path to input file to parse with grammar given to -g option",
            "FILE" ),
    optopt( "g", "grammar",
            "Path to PEG grammar. Prints code for grammar if -i not given.",
            "FILE" )

  ];

  let args = os::args();
  let matches = match getopts( args.tail(), opts ) {
    Ok( m ) => m,
    Err( erorr ) => fail!( erorr )
  };

  if matches.opt_present( "h" ) || args.len() < 2 {
    printUsage( opts );
    return;
  }

  let grammar_code = if matches.opt_present( "g" ) {
    codeForGrammar( inputFromFile(
        matches.opt_str( "g" ).unwrap().as_slice() ).as_slice() )
    .unwrap_or_else( || fail!( "Couldn't parse given PEG grammar" ) )
  } else {
    fail!( "Missing -g option." )
  };

  if matches.opt_present( "i" ) {
    printParseTree(
      grammar_code.as_slice(),
      matches.opt_str( "i" ).unwrap().as_slice() );
  } else {
    println!( "{}", grammar_code );
  }
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013, David Renshaw (dwrenshaw@gmail.com)
 *
 * See the LICENSE file in the capnproto-rust root directory.
 */

use std::rt::io::Writer;

pub struct BufferedOutputStream<W> {
    priv inner: W,
    priv buf: ~[u8],
    priv pos: uint
}

impl<W: Writer> BufferedOutputStream<W> {
    pub fn getWriteBuffer<'a>(&'a mut self) -> &'a mut [u8] {
        fail!("unimplemented")
    }
}

impl<W: Writer> Writer for BufferedOutputStream<W> {
    fn write(&mut self, _buf: &[u8]) {
        // like BufferedWriter, but first check if buf is a prefix of our inner buf.
        fail!("unimplemented");
    }

    fn flush(&mut self) {
        fail!("unimplemented")
    }
}
<commit_msg>implement BufferedOutputStream<commit_after>/*
 * Copyright (c) 2013, David Renshaw (dwrenshaw@gmail.com)
 *
 * See the LICENSE file in the capnproto-rust root directory.
 */

use std;
use std::rt::io::Writer;

pub struct BufferedOutputStream<W> {
    priv inner: W,
    priv buf: ~[u8],
    priv pos: uint
}

impl<W: Writer> BufferedOutputStream<W> {

    #[inline]
    pub fn getWriteBuffer(&mut self) -> (*mut u8, uint) {
        unsafe {
            (self.buf.unsafe_mut_ref(self.pos), self.pos)
        }
    }

    pub fn advance(&mut self, n : uint) {
        self.pos += n;
        assert!(self.pos < self.buf.len());
    }
}

impl<W: Writer> Writer for BufferedOutputStream<W> {
    fn write(&mut self, buf: &[u8]) {
        let available = self.buf.len() - self.pos;
        let mut size = buf.len();
        if size <= available {
            let dst = self.buf.mut_slice_from(self.pos);
            std::vec::bytes::copy_memory(dst, buf, buf.len());
            self.pos += size;
        } else if size <= self.buf.len() {
            //# Too much for this buffer, but not a full buffer's
            //# worth, so we'll go ahead and copy.
            {
                let dst = self.buf.mut_slice_from(self.pos);
                std::vec::bytes::copy_memory(dst, buf, available);
            }
            self.inner.write(self.buf);

            size -= available;
            let src = buf.slice(available, buf.len());
            let dst = self.buf.mut_slice_from(0);
            std::vec::bytes::copy_memory(dst, src, size);
            self.pos = size;
        } else {
            //# Writing so much data that we might as well write
            //# directly to avoid a copy.
            self.inner.write(self.buf.slice(0, self.pos));
            self.pos = 0;
            self.inner.write(buf);
        }
    }

    fn flush(&mut self) {
        if (self.pos > 0) {
            self.inner.write(self.buf.slice(0, self.pos));
            self.pos = 0;
        }
    }
}
<|endoftext|>