<commit_before>#![feature(test)]
#![feature(asm)]
#![feature(core)]

use std::str::pattern::{Pattern,Searcher,SearchStep};

#[derive(Debug,Copy,Clone)]
pub struct ByteSearch {
    pub needle: u64,
    pub count: u8,
}

impl ByteSearch {
    pub fn new() -> ByteSearch {
        ByteSearch { needle: 0, count: 0 }
    }

    pub fn push(&mut self, byte: u8) {
        assert!(self.count < 8);
        self.needle <<= 8;
        self.needle |= byte as u64;
        self.count += 1;
    }
}

#[derive(Debug,Copy,Clone)]
pub struct ByteSearcher<'a> {
    haystack: &'a str,
    offset: usize,
    needle: ByteSearch,
}

impl<'a> Pattern<'a> for ByteSearch {
    type Searcher = ByteSearcher<'a>;

    fn into_searcher(self, haystack: &'a str) -> ByteSearcher<'a> {
        ByteSearcher { haystack: haystack, offset: 0, needle: self }
    }
}

unsafe impl<'a> Searcher<'a> for ByteSearcher<'a> {
    fn haystack(&self) -> &'a str { self.haystack }

    #[inline]
    fn next(&mut self) -> SearchStep {
        if self.offset >= self.haystack.len() { return SearchStep::Done }

        let left_to_search = &self.haystack[self.offset..]; // TODO: unchecked_slice?
        let idx = find(left_to_search, self.needle);

        let next_offset = idx.unwrap_or(self.haystack.len());

        let (res, next_offset) = if next_offset == 0 {
            (SearchStep::Match(self.offset, self.offset + 1), self.offset + 1)
        } else {
            (SearchStep::Reject(self.offset, next_offset), next_offset)
        };

        self.offset = next_offset;
        res
    }
}

#[inline(never)]
fn find(haystack: &str, needle: ByteSearch) -> Option<usize> {
    let haystack = haystack.as_bytes();

    let ptr = haystack.as_ptr();
    let mut offset = 0;
    let mut len = haystack.len();

    let mut res: usize;

    // Zero-length strings have a pointer set to 0x1. Even though the
    // length is zero, we still trigger a bad access exception. I
    // think this indicates that the instruction reads in 16 bytes
    // worth of memory at a time, regardless of the length instruction.
    //
    // This could also be an indication of a subtle bug, where we
    // might trigger access violations if we are near the end of a
    // page. See the comment by Renat Saifutdinov on
    // http://www.strchr.com/strcmp_and_strlen_using_sse_4.2
    // It is suggested to use an "aligned read with mask false bits"
    // to avoid the problem.
    //
    // We don't do this yet.
    if len == 0 { return None }

    loop {
        unsafe {
            asm!("pcmpestri $$0, ($1, $5), $2"
                 : // output operands
                 "={ecx}"(res)
                 : // input operands
                 "r"(ptr),
                 "x"(needle.needle),
                 "{rdx}"(len),
                 "{rax}"(needle.count),
                 "r"(offset)
                 : // clobbers
                 : // options
                 );
        }

        // We know if it matched if the zero flag is set (or
        // unset?), we shouldn't need to test res...
        if res == 16 {
            if len <= 16 {
                return None;
            }

            offset += 16;
            len -= 16;
        } else {
            return Some(res + offset);
        }
    }
}

#[cfg(test)]
mod test {
    extern crate quickcheck;

    use super::ByteSearch;
    use self::quickcheck::quickcheck;

    pub const SPACE: ByteSearch       = ByteSearch { needle: 0x0000000000000020, count: 1 };
    // < > &
    pub const XML_DELIM_3: ByteSearch = ByteSearch { needle: 0x00000000003c3e26, count: 3 };
    // < > & ' "
    pub const XML_DELIM_5: ByteSearch = ByteSearch { needle: 0x0000003c3e262722, count: 5 };

    pub fn find_space(haystack: &str) -> Option<usize> {
        super::find(haystack, SPACE)
    }

    pub fn find_xml_delim_3(haystack: &str) -> Option<usize> {
        super::find(haystack, XML_DELIM_3)
    }

    pub fn find_xml_delim_5(haystack: &str) -> Option<usize> {
        super::find(haystack, XML_DELIM_5)
    }

    #[test]
    fn works_as_find_does_for_single_character() {
        fn prop(s: String) -> bool {
            find_space(&s) == s.find(' ')
        }
        quickcheck(prop as fn(String) -> bool);
    }

    #[test]
    fn works_as_find_does_for_single_character2() {
        fn prop(s: String) -> bool {
            s.find(SPACE) == s.find(' ')
        }
        quickcheck(prop as fn(String) -> bool);
    }

    #[test]
    fn works_as_find_does_for_single_character3() {
        fn prop(s: String) -> bool {
            s.find(SPACE) == find_space(&s)
        }
        quickcheck(prop as fn(String) -> bool);
    }

    #[test]
    fn space_is_found() {
        // Since the algorithm operates on 16-byte chunks, it's
        // important to cover tests around that boundary. Since 16
        // isn't that big of a number, we might as well do all of
        // them.

        assert_eq!(Some(0),  find_space(" "));
        assert_eq!(Some(1),  find_space("0 "));
        assert_eq!(Some(2),  find_space("01 "));
        assert_eq!(Some(3),  find_space("012 "));
        assert_eq!(Some(4),  find_space("0123 "));
        assert_eq!(Some(5),  find_space("01234 "));
        assert_eq!(Some(6),  find_space("012345 "));
        assert_eq!(Some(7),  find_space("0123456 "));
        assert_eq!(Some(8),  find_space("01234567 "));
        assert_eq!(Some(9),  find_space("012345678 "));
        assert_eq!(Some(10), find_space("0123456789 "));
        assert_eq!(Some(11), find_space("0123456789A "));
        assert_eq!(Some(12), find_space("0123456789AB "));
        assert_eq!(Some(13), find_space("0123456789ABC "));
        assert_eq!(Some(14), find_space("0123456789ABCD "));
        assert_eq!(Some(15), find_space("0123456789ABCDE "));
        assert_eq!(Some(16), find_space("0123456789ABCDEF "));
        assert_eq!(Some(17), find_space("0123456789ABCDEFG "));
    }

    #[test]
    fn space_not_found() {
        // Since the algorithm operates on 16-byte chunks, it's
        // important to cover tests around that boundary. Since 16
        // isn't that big of a number, we might as well do all of
        // them.

        assert_eq!(None, find_space(""));
        assert_eq!(None, find_space("0"));
        assert_eq!(None, find_space("01"));
        assert_eq!(None, find_space("012"));
        assert_eq!(None, find_space("0123"));
        assert_eq!(None, find_space("01234"));
        assert_eq!(None, find_space("012345"));
        assert_eq!(None, find_space("0123456"));
        assert_eq!(None, find_space("01234567"));
        assert_eq!(None, find_space("012345678"));
        assert_eq!(None, find_space("0123456789"));
        assert_eq!(None, find_space("0123456789A"));
        assert_eq!(None, find_space("0123456789AB"));
        assert_eq!(None, find_space("0123456789ABC"));
        assert_eq!(None, find_space("0123456789ABCD"));
        assert_eq!(None, find_space("0123456789ABCDE"));
        assert_eq!(None, find_space("0123456789ABCDEF"));
        assert_eq!(None, find_space("0123456789ABCDEFG"));
    }

    #[test]
    fn xml_delim_3_is_found() {
        assert_eq!(Some(0), find_xml_delim_3("<"));
        assert_eq!(Some(0), find_xml_delim_3(">"));
        assert_eq!(Some(0), find_xml_delim_3("&"));
        assert_eq!(None,    find_xml_delim_3(""));
    }

    #[test]
    fn xml_delim_5_is_found() {
        assert_eq!(Some(0), find_xml_delim_5("<"));
        assert_eq!(Some(0), find_xml_delim_5(">"));
        assert_eq!(Some(0), find_xml_delim_5("&"));
        assert_eq!(Some(0), find_xml_delim_5("'"));
        assert_eq!(Some(0), find_xml_delim_5("\""));
        assert_eq!(None,    find_xml_delim_5(""));
    }
}

#[cfg(test)]
mod bench {
    extern crate test;

    use super::test::{find_space,find_xml_delim_3,find_xml_delim_5};
    use std::iter;

    fn prefix_string() -> String {
        iter::repeat("a").take(5 * 1024 * 1024).collect()
    }

    fn bench_space<F>(b: &mut test::Bencher, f: F)
        where F: Fn(&str) -> Option<usize>
    {
        let mut haystack = prefix_string();
        haystack.push(' ');

        b.iter(|| test::black_box(f(&haystack)));
        b.bytes = haystack.len() as u64;
    }

    #[bench]
    fn space_assembly(b: &mut test::Bencher) {
        bench_space(b, |hs| find_space(hs))
    }

    #[bench]
    fn space_find_string(b: &mut test::Bencher) {
        bench_space(b, |hs| hs.find(" "))
    }

    #[bench]
    fn space_find_char(b: &mut test::Bencher) {
        bench_space(b, |hs| hs.find(' '))
    }

    #[bench]
    fn space_find_char_set(b: &mut test::Bencher) {
        bench_space(b, |hs| hs.find(&[' '][..]))
    }

    #[bench]
    fn space_find_byte(b: &mut test::Bencher) {
        bench_space(b, |hs| hs.as_bytes().iter().position(|&v| v == b' '))
    }

    fn bench_xml_delim_3<F>(b: &mut test::Bencher, f: F)
        where F: Fn(&str) -> Option<usize>
    {
        let mut haystack = prefix_string();
        haystack.push('&');

        b.iter(|| test::black_box(f(&haystack)));
        b.bytes = haystack.len() as u64;
    }

    #[bench]
    fn xml_delim_3_assembly(b: &mut test::Bencher) {
        bench_xml_delim_3(b, |hs| find_xml_delim_3(hs))
    }

    #[bench]
    fn xml_delim_3_find_char_set(b: &mut test::Bencher) {
        bench_xml_delim_3(b, |hs| hs.find(&['<', '>', '&'][..]))
    }

    fn bench_xml_delim_5<F>(b: &mut test::Bencher, f: F)
        where F: Fn(&str) -> Option<usize>
    {
        let mut haystack = prefix_string();
        haystack.push('"');

        b.iter(|| test::black_box(f(&haystack)));
        b.bytes = haystack.len() as u64;
    }

    #[bench]
    fn xml_delim_5_assembly(b: &mut test::Bencher) {
        bench_xml_delim_5(b, |hs| find_xml_delim_5(hs))
    }

    #[bench]
    fn xml_delim_5_find_char_set(b: &mut test::Bencher) {
        bench_xml_delim_5(b, |hs| hs.find(&['<', '>', '&', '\'', '"'][..]))
    }
}
<commit_msg>Make the free function into an inherent method<commit_after>#![feature(test)]
#![feature(asm)]
#![feature(core)]

use std::str::pattern::{Pattern,Searcher,SearchStep};

#[derive(Debug,Copy,Clone)]
pub struct ByteSearch {
    pub needle: u64,
    pub count: u8,
}

impl ByteSearch {
    pub fn new() -> ByteSearch {
        ByteSearch { needle: 0, count: 0 }
    }

    pub fn push(&mut self, byte: u8) {
        assert!(self.count < 8);
        self.needle <<= 8;
        self.needle |= byte as u64;
        self.count += 1;
    }

    #[inline]
    pub fn find(self, haystack: &str) -> Option<usize> {
        let haystack = haystack.as_bytes();

        let ptr = haystack.as_ptr();
        let mut offset = 0;
        let mut len = haystack.len();

        let mut res: usize;

        // Zero-length strings have a pointer set to 0x1. Even though the
        // length is zero, we still trigger a bad access exception. I
        // think this indicates that the instruction reads in 16 bytes
        // worth of memory at a time, regardless of the length instruction.
        //
        // This could also be an indication of a subtle bug, where we
        // might trigger access violations if we are near the end of a
        // page. See the comment by Renat Saifutdinov on
        // http://www.strchr.com/strcmp_and_strlen_using_sse_4.2
        // It is suggested to use an "aligned read with mask false bits"
        // to avoid the problem.
        //
        // We don't do this yet.
        if len == 0 { return None }

        loop {
            unsafe {
                asm!("pcmpestri $$0, ($1, $5), $2"
                     : // output operands
                     "={ecx}"(res)
                     : // input operands
                     "r"(ptr),
                     "x"(self.needle),
                     "{rdx}"(len),
                     "{rax}"(self.count),
                     "r"(offset)
                     : // clobbers
                     : // options
                     );
            }

            // We know if it matched if the zero flag is set (or
            // unset?), we shouldn't need to test res...
            if res == 16 {
                if len <= 16 {
                    return None;
                }

                offset += 16;
                len -= 16;
            } else {
                return Some(res + offset);
            }
        }
    }
}

impl<'a> Pattern<'a> for ByteSearch {
    type Searcher = ByteSearcher<'a>;

    fn into_searcher(self, haystack: &'a str) -> ByteSearcher<'a> {
        ByteSearcher { haystack: haystack, offset: 0, needle: self }
    }
}

#[derive(Debug,Copy,Clone)]
pub struct ByteSearcher<'a> {
    haystack: &'a str,
    offset: usize,
    needle: ByteSearch,
}

unsafe impl<'a> Searcher<'a> for ByteSearcher<'a> {
    fn haystack(&self) -> &'a str { self.haystack }

    #[inline]
    fn next(&mut self) -> SearchStep {
        if self.offset >= self.haystack.len() { return SearchStep::Done }

        let left_to_search = &self.haystack[self.offset..]; // TODO: unchecked_slice?
        let idx = self.needle.find(left_to_search);

        let next_offset = idx.unwrap_or(self.haystack.len());

        let (res, next_offset) = if next_offset == 0 {
            (SearchStep::Match(self.offset, self.offset + 1), self.offset + 1)
        } else {
            (SearchStep::Reject(self.offset, next_offset), next_offset)
        };

        self.offset = next_offset;
        res
    }
}

#[cfg(test)]
mod test {
    extern crate quickcheck;

    use super::ByteSearch;
    use self::quickcheck::quickcheck;

    pub const SPACE: ByteSearch       = ByteSearch { needle: 0x0000000000000020, count: 1 };
    // < > &
    pub const XML_DELIM_3: ByteSearch = ByteSearch { needle: 0x00000000003c3e26, count: 3 };
    // < > & ' "
    pub const XML_DELIM_5: ByteSearch = ByteSearch { needle: 0x0000003c3e262722, count: 5 };

    pub fn find_space(haystack: &str) -> Option<usize> {
        SPACE.find(haystack)
    }

    pub fn find_xml_delim_3(haystack: &str) -> Option<usize> {
        XML_DELIM_3.find(haystack)
    }

    pub fn find_xml_delim_5(haystack: &str) -> Option<usize> {
        XML_DELIM_5.find(haystack)
    }

    #[test]
    fn works_as_find_does_for_single_character() {
        fn prop(s: String) -> bool {
            find_space(&s) == s.find(' ')
        }
        quickcheck(prop as fn(String) -> bool);
    }

    #[test]
    fn works_as_find_does_for_single_character2() {
        fn prop(s: String) -> bool {
            s.find(SPACE) == s.find(' ')
        }
        quickcheck(prop as fn(String) -> bool);
    }

    #[test]
    fn works_as_find_does_for_single_character3() {
        fn prop(s: String) -> bool {
            s.find(SPACE) == find_space(&s)
        }
        quickcheck(prop as fn(String) -> bool);
    }

    #[test]
    fn space_is_found() {
        // Since the algorithm operates on 16-byte chunks, it's
        // important to cover tests around that boundary. Since 16
        // isn't that big of a number, we might as well do all of
        // them.

        assert_eq!(Some(0),  find_space(" "));
        assert_eq!(Some(1),  find_space("0 "));
        assert_eq!(Some(2),  find_space("01 "));
        assert_eq!(Some(3),  find_space("012 "));
        assert_eq!(Some(4),  find_space("0123 "));
        assert_eq!(Some(5),  find_space("01234 "));
        assert_eq!(Some(6),  find_space("012345 "));
        assert_eq!(Some(7),  find_space("0123456 "));
        assert_eq!(Some(8),  find_space("01234567 "));
        assert_eq!(Some(9),  find_space("012345678 "));
        assert_eq!(Some(10), find_space("0123456789 "));
        assert_eq!(Some(11), find_space("0123456789A "));
        assert_eq!(Some(12), find_space("0123456789AB "));
        assert_eq!(Some(13), find_space("0123456789ABC "));
        assert_eq!(Some(14), find_space("0123456789ABCD "));
        assert_eq!(Some(15), find_space("0123456789ABCDE "));
        assert_eq!(Some(16), find_space("0123456789ABCDEF "));
        assert_eq!(Some(17), find_space("0123456789ABCDEFG "));
    }

    #[test]
    fn space_not_found() {
        // Since the algorithm operates on 16-byte chunks, it's
        // important to cover tests around that boundary. Since 16
        // isn't that big of a number, we might as well do all of
        // them.

        assert_eq!(None, find_space(""));
        assert_eq!(None, find_space("0"));
        assert_eq!(None, find_space("01"));
        assert_eq!(None, find_space("012"));
        assert_eq!(None, find_space("0123"));
        assert_eq!(None, find_space("01234"));
        assert_eq!(None, find_space("012345"));
        assert_eq!(None, find_space("0123456"));
        assert_eq!(None, find_space("01234567"));
        assert_eq!(None, find_space("012345678"));
        assert_eq!(None, find_space("0123456789"));
        assert_eq!(None, find_space("0123456789A"));
        assert_eq!(None, find_space("0123456789AB"));
        assert_eq!(None, find_space("0123456789ABC"));
        assert_eq!(None, find_space("0123456789ABCD"));
        assert_eq!(None, find_space("0123456789ABCDE"));
        assert_eq!(None, find_space("0123456789ABCDEF"));
        assert_eq!(None, find_space("0123456789ABCDEFG"));
    }

    #[test]
    fn xml_delim_3_is_found() {
        assert_eq!(Some(0), find_xml_delim_3("<"));
        assert_eq!(Some(0), find_xml_delim_3(">"));
        assert_eq!(Some(0), find_xml_delim_3("&"));
        assert_eq!(None,    find_xml_delim_3(""));
    }

    #[test]
    fn xml_delim_5_is_found() {
        assert_eq!(Some(0), find_xml_delim_5("<"));
        assert_eq!(Some(0), find_xml_delim_5(">"));
        assert_eq!(Some(0), find_xml_delim_5("&"));
        assert_eq!(Some(0), find_xml_delim_5("'"));
        assert_eq!(Some(0), find_xml_delim_5("\""));
        assert_eq!(None,    find_xml_delim_5(""));
    }
}

#[cfg(test)]
mod bench {
    extern crate test;

    use super::test::{find_space,find_xml_delim_3,find_xml_delim_5};
    use std::iter;

    fn prefix_string() -> String {
        iter::repeat("a").take(5 * 1024 * 1024).collect()
    }

    fn bench_space<F>(b: &mut test::Bencher, f: F)
        where F: Fn(&str) -> Option<usize>
    {
        let mut haystack = prefix_string();
        haystack.push(' ');

        b.iter(|| test::black_box(f(&haystack)));
        b.bytes = haystack.len() as u64;
    }

    #[bench]
    fn space_assembly(b: &mut test::Bencher) {
        bench_space(b, |hs| find_space(hs))
    }

    #[bench]
    fn space_find_string(b: &mut test::Bencher) {
        bench_space(b, |hs| hs.find(" "))
    }

    #[bench]
    fn space_find_char(b: &mut test::Bencher) {
        bench_space(b, |hs| hs.find(' '))
    }

    #[bench]
    fn space_find_char_set(b: &mut test::Bencher) {
        bench_space(b, |hs| hs.find(&[' '][..]))
    }

    #[bench]
    fn space_find_byte(b: &mut test::Bencher) {
        bench_space(b, |hs| hs.as_bytes().iter().position(|&v| v == b' '))
    }

    fn bench_xml_delim_3<F>(b: &mut test::Bencher, f: F)
        where F: Fn(&str) -> Option<usize>
    {
        let mut haystack = prefix_string();
        haystack.push('&');

        b.iter(|| test::black_box(f(&haystack)));
        b.bytes = haystack.len() as u64;
    }

    #[bench]
    fn xml_delim_3_assembly(b: &mut test::Bencher) {
        bench_xml_delim_3(b, |hs| find_xml_delim_3(hs))
    }

    #[bench]
    fn xml_delim_3_find_char_set(b: &mut test::Bencher) {
        bench_xml_delim_3(b, |hs| hs.find(&['<', '>', '&'][..]))
    }

    fn bench_xml_delim_5<F>(b: &mut test::Bencher, f: F)
        where F: Fn(&str) -> Option<usize>
    {
        let mut haystack = prefix_string();
        haystack.push('"');

        b.iter(|| test::black_box(f(&haystack)));
        b.bytes = haystack.len() as u64;
    }

    #[bench]
    fn xml_delim_5_assembly(b: &mut test::Bencher) {
        bench_xml_delim_5(b, |hs| find_xml_delim_5(hs))
    }

    #[bench]
    fn xml_delim_5_find_char_set(b: &mut test::Bencher) {
        bench_xml_delim_5(b, |hs| hs.find(&['<', '>', '&', '\'', '"'][..]))
    }
}
<|endoftext|>


<commit_before>//! A parser for the [TGFF][1] (Task Graphs For Free) format.
//!
//! [1]: http://ziyang.eecs.umich.edu/~dickrp/tgff/

#![allow(unstable)]

#[cfg(test)]
#[macro_use]
extern crate assert;

use std::fmt;
use std::iter::Peekable;
use std::str::CharIndices;

pub use content::Content;
pub use content::{Graph, Task, Arc, Deadline};
pub use content::{Table, Column};

mod content;

static READ_CAPACITY: usize = 20;

/// An outcome of parsing.
pub type Result<T> = std::result::Result<T, Error>;

/// A parsing error.
pub struct Error {
    /// The line on which the error occurred.
    pub line: usize,
    /// The description of the error.
    pub message: String,
}

struct Parser<'a> {
    line: usize,
    cursor: Peekable<(usize, char), CharIndices<'a>>,
    content: Content,
}

/// Parse a string containing a TGFF file.
///
/// The input string is the content of a TGFF file generated by the `tgff`
/// command-line utility based on the corresponding TGFFOPT file.
pub fn parse(input: &str) -> Result<Content> {
    Parser::new(input).process()
}

macro_rules! raise(
    ($parser:expr, $($arg:tt)*) => (
        return Err(Error { line: $parser.line, message: format!($($arg)*) });
    );
);

macro_rules! some(
    ($parser:expr, $result:expr, $($arg:tt)*) => (
        match $result {
            Some(result) => result,
            None => raise!($parser, $($arg)*),
        }
    );
);

impl fmt::Debug for Error {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        write!(formatter, "{} on line {}", self.message, self.line)
    }
}

impl fmt::Display for Error {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(self, formatter)
    }
}

impl<'a> Parser<'a> {
    fn new(input: &'a str) -> Parser<'a> {
        Parser {
            line: 1,
            cursor: input.char_indices().peekable(),
            content: content::new(),
        }
    }

    fn process(&mut self) -> Result<Content> {
        loop {
            match self.peek() {
                Some('@') => try!(self.process_at()),
                Some(_) => raise!(self, "found an unknown statement"),
                None => break,
            }
        }
        Ok(std::mem::replace(&mut self.content, content::new()))
    }

    fn process_at(&mut self) -> Result<()> {
        try!(self.skip_char('@'));

        let name = try!(self.get_token());
        let number = try!(self.get_natural());

        if let Some('{') = self.peek() {
            self.process_block(name, number)
        } else {
            self.content.attributes.insert(name, number);
            Ok(())
        }
    }

    fn process_block(&mut self, name: String, id: usize) -> Result<()> {
        try!(self.skip_char('{'));
        if let Some('#') = self.peek() {
            try!(self.process_table(name, id));
        } else {
            try!(self.process_graph(name, id));
        }
        try!(self.skip_char('}'));
        Ok(())
    }

    fn process_graph(&mut self, name: String, id: usize) -> Result<()> {
        let mut graph = content::new_graph(name, id);

        loop {
            match self.read_token() {
                Some(ref token) => match token.as_slice() {
                    "TASK" => {
                        let id = try!(self.get_id());
                        try!(self.skip_str("TYPE"));
                        let kind = try!(self.get_natural());
                        graph.tasks.push(content::new_task(id, kind));
                    },
                    "ARC" => {
                        let id = try!(self.get_id());
                        try!(self.skip_str("FROM"));
                        let from = try!(self.get_id());
                        try!(self.skip_str("TO"));
                        let to = try!(self.get_id());
                        try!(self.skip_str("TYPE"));
                        let kind = try!(self.get_natural());
                        graph.arcs.push(content::new_arc(id, from, to, kind));
                    },
                    "HARD_DEADLINE" => {
                        let id = try!(self.get_id());
                        try!(self.skip_str("ON"));
                        let on = try!(self.get_id());
                        try!(self.skip_str("AT"));
                        let at = try!(self.get_natural());
                        graph.deadlines.push(content::new_deadline(id, on, at));
                    },
                    _ => {
                        let value = try!(self.get_natural());
                        graph.attributes.insert(token.clone(), value);
                    },
                },
                None => break,
            }
        }

        self.content.graphs.push(graph);
        Ok(())
    }

    fn process_table(&mut self, name: String, id: usize) -> Result<()> {
        let mut table = content::new_table(name, id);

        try!(self.skip_char('#'));

        let mut names = vec![];
        loop {
            match self.read_token() {
                Some(token) => names.push(token),
                None => break,
            }
        }
        for name in names.into_iter() {
            table.attributes.insert(name, try!(self.get_real()));
        }

        try!(self.skip_comment());
        try!(self.skip_char('#'));

        loop {
            match self.read_token() {
                Some(name) => table.columns.push(content::new_column(name)),
                None => break,
            }
        }
        let cols = table.columns.len();
        loop {
            match self.peek() {
                Some('}') | None => break,
                _ => {},
            }
            for i in range(0, cols) {
                table.columns[i].data.push(try!(self.get_real()));
            }
        }

        self.content.tables.push(table);
        Ok(())
    }

    #[inline]
    fn peek(&mut self) -> Option<char> {
        match self.cursor.peek() {
            Some(&(_, c)) => Some(c),
            None => None,
        }
    }

    fn skip(&mut self, accept: &Fn(usize, char) -> bool) -> usize {
        let mut count = 0;

        loop {
            match self.peek() {
                Some(c) => {
                    if !accept(count, c) { break; }
                    self.next();
                    count += 1;
                },
                None => break,
            }
        }

        count
    }

    fn skip_char(&mut self, expected: char) -> Result<()> {
        match self.next() {
            Some(c) => {
                if c == expected {
                    self.skip_void();
                    return Ok(());
                }
            },
            None => {},
        }
        raise!(self, "expected `{}`", expected);
    }

    fn skip_str(&mut self, expected: &str) -> Result<()> {
        let len = expected.len();
        if self.skip(&|i, c| i < len && c == expected.char_at(i)) != len {
            raise!(self, "expected `{}`", expected);
        }
        self.skip_void();
        Ok(())
    }

    #[inline]
    fn skip_void(&mut self) {
        self.skip(&|_, c| c == ' ' || c == '\t' || c == '\n');
    }

    fn skip_comment(&mut self) -> Result<()> {
        if self.skip(&|i, c| i == 0 && c == '#' || (i > 0) && c == '-') < 2 {
            raise!(self, "expected a comment line");
        }
        self.skip_void();
        Ok(())
    }

    fn read(&mut self, accept: &Fn(usize, char) -> bool) -> Option<String> {
        let mut result = std::string::String::with_capacity(READ_CAPACITY);
        let mut count = 0;

        loop {
            match self.peek() {
                Some(c) => {
                    if !accept(count, c) { break; }
                    result.push(c);
                    self.next();
                    count += 1;
                },
                None => break,
            }
        }

        if count == 0 {
            None
        } else {
            Some(result)
        }
    }

    fn read_token(&mut self) -> Option<String> {
        let result = self.read(&|i, c| {
            match c {
                'A'...'Z' | 'a'...'z' if i == 0 => true,
                'A'...'Z' | 'a'...'z' | '_' | '0'...'9' if i > 0 => true,
                _ => false,
            }
        });
        self.skip_void();
        result
    }

    fn read_id(&mut self) -> Option<usize> {
        match self.read_token() {
            Some(ref token) => match token.as_slice().split('_').nth(1) {
                Some(id) => std::num::from_str_radix(id, 10),
                None => None,
            },
            None => None,
        }
    }

    fn read_natural(&mut self) -> Option<usize> {
        let result = match self.read(&|_, c| c >= '0' && c <= '9') {
            Some(ref number) => std::num::from_str_radix(number.as_slice(), 10),
            None => None,
        };
        self.skip_void();
        result
    }

    fn read_real(&mut self) -> Option<f64> {
        let result = match self.read(&|_, c| {
            match c {
                '+' | '-' | '.' | '0'...'9' | 'e' | 'E' => true,
                _ => false,
            }
        }) {
            Some(ref number) => number.as_slice().parse(),
            None => None,
        };
        self.skip_void();
        result
    }

    fn get_token(&mut self) -> Result<String> {
        match self.read_token() {
            Some(token) => Ok(token),
            None => raise!(self, "expected a token"),
        }
    }

    fn get_id(&mut self) -> Result<usize> {
        match self.read_id() {
            Some(id) => Ok(id),
            None => raise!(self, "expected an id"),
        }
    }

    fn get_natural(&mut self) -> Result<usize> {
        match self.read_natural() {
            Some(number) => Ok(number),
            None => raise!(self, "expected a natural number"),
        }
    }

    fn get_real(&mut self) -> Result<f64> {
        match self.read_real() {
            Some(number) => Ok(number),
            None => raise!(self, "expected a real number"),
        }
    }
}

impl<'a> std::iter::Iterator for Parser<'a> {
    type Item = char;

    fn next(&mut self) -> Option<char> {
        match self.cursor.next() {
            Some((_, '\n')) => {
                self.line += 1;
                Some('\n')
            },
            Some((_, c)) => Some(c),
            None => None,
        }
    }
}

#[cfg(test)]
mod tests {
    macro_rules! parser(
        ($input:expr) => (super::Parser::new($input));
    );

    #[test]
    fn process_at() {
        assert_ok!(parser!("@abc 12").process_at());
        assert_err!(parser!("@ ").process_at());
        assert_err!(parser!("@abc").process_at());
    }

    #[test]
    fn process_block() {
        assert_ok!(parser!("{}").process_block(String::new(), 0));
    }

    #[test]
    fn process_graph() {
        let mut parser = parser!("TASK t0_0\tTYPE 2   ");
        assert_ok!(parser.process_graph(String::new(), 0));
        {
            let ref task = parser.content.graphs[0].tasks[0];
            assert_eq!(task.id, 0);
            assert_eq!(task.kind, 2);
        }

        parser = parser!("ARC a0_42 \tFROM t0_0  TO  t0_1 TYPE 35   ");
        assert_ok!(parser.process_graph(String::new(), 0));
        {
            let ref arc = parser.content.graphs[0].arcs[0];
            assert_eq!(arc.id, 42);
            assert_eq!(arc.from, 0);
            assert_eq!(arc.to, 1);
            assert_eq!(arc.kind, 35);
        }

        parser = parser!("HARD_DEADLINE d0_9 ON t0_12 AT 1000   ");
        assert_ok!(parser.process_graph(String::new(), 0));
        {
            let ref deadline = parser.content.graphs[0].deadlines[0];
            assert_eq!(deadline.id, 9);
            assert_eq!(deadline.on, 12);
            assert_eq!(deadline.at, 1000);
        }
    }

    #[test]
    fn process_table() {
        let mut parser = parser!("# foo\n 70.07\n#--\n# bar baz\n1 2 3 4 ");
        assert_ok!(parser.process_table(String::new(), 0));
        let ref table = parser.content.tables[0];
        assert_eq!(table.attributes["foo".to_string()], 70.07);
        assert_eq!(table.columns[0].name, "bar".to_string());
        assert_eq!(table.columns[1].name, "baz".to_string());
        assert_eq!(table.columns[0].data, vec![1.0, 3.0]);
        assert_eq!(table.columns[1].data, vec![2.0, 4.0]);
    }

    #[test]
    fn skip_char() {
        let mut parser = parser!("#  \t\n  abc");
        assert_ok!(parser.skip_char('#'));
        assert_eq!(parser.next().unwrap(), 'a');
    }

    #[test]
    fn skip_str() {
        let mut parser = parser!("abc  \t\n  xyz");
        assert_ok!(parser.skip_str("abc"));
        assert_eq!(parser.next().unwrap(), 'x');
    }

    #[test]
    fn skip_void() {
        let mut parser = parser!("  \t  abc");
        parser.skip_void();
        assert_eq!(parser.next().unwrap(), 'a');
    }

    #[test]
    fn skip_comment() {
        let mut parser = parser!("#--------------   \n abc");
        assert_ok!(parser.skip_comment());
        assert_eq!(parser.next().unwrap(), 'a');
    }

    #[test]
    fn get_token() {
        macro_rules! test(
            ($input:expr, $output:expr) => (
                assert_eq!(parser!($input).get_token().unwrap(),
                           String::from_str($output))
            );
        );
        test!("AZ xyz", "AZ");
        test!("az xyz", "az");
        test!("AZ_az_09 xyz", "AZ_az_09");
    }

    #[test]
    fn get_id() {
        assert_eq!(parser!("t0_42").get_id().unwrap(), 42);
    }

    #[test]
    fn get_natural() {
        assert_eq!(parser!("09").get_natural().unwrap(), 9);
    }

    #[test]
    fn get_real() {
        macro_rules! test(
            ($input:expr, $output:expr) => (
                assert_eq!(parser!($input).get_real().unwrap(), $output)
            );
        );
        test!("-1", -1.0);
        test!("0.1", 0.1);
        test!("1.2e3", 1.2e3);
        test!("1.2e+3", 1.2e3);
        test!("-1.2e-3", -1.2e-3);
    }
}
<commit_msg>Added an inlining<commit_after>//! A parser for the [TGFF][1] (Task Graphs For Free) format.
//!
//! [1]: http://ziyang.eecs.umich.edu/~dickrp/tgff/

#![allow(unstable)]

#[cfg(test)]
#[macro_use]
extern crate assert;

use std::fmt;
use std::iter::Peekable;
use std::str::CharIndices;

pub use content::Content;
pub use content::{Graph, Task, Arc, Deadline};
pub use content::{Table, Column};

mod content;

static READ_CAPACITY: usize = 20;

/// An outcome of parsing.
pub type Result<T> = std::result::Result<T, Error>;

/// A parsing error.
pub struct Error {
    /// The line on which the error occurred.
    pub line: usize,
    /// The description of the error.
    pub message: String,
}

struct Parser<'a> {
    line: usize,
    cursor: Peekable<(usize, char), CharIndices<'a>>,
    content: Content,
}

/// Parse a string containing a TGFF file.
///
/// The input string is the content of a TGFF file generated by the `tgff`
/// command-line utility based on the corresponding TGFFOPT file.
pub fn parse(input: &str) -> Result<Content> {
    Parser::new(input).process()
}

macro_rules! raise(
    ($parser:expr, $($arg:tt)*) => (
        return Err(Error { line: $parser.line, message: format!($($arg)*) });
    );
);

macro_rules! some(
    ($parser:expr, $result:expr, $($arg:tt)*) => (
        match $result {
            Some(result) => result,
            None => raise!($parser, $($arg)*),
        }
    );
);

impl fmt::Debug for Error {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        write!(formatter, "{} on line {}", self.message, self.line)
    }
}

impl fmt::Display for Error {
    #[inline]
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(self, formatter)
    }
}

impl<'a> Parser<'a> {
    fn new(input: &'a str) -> Parser<'a> {
        Parser {
            line: 1,
            cursor: input.char_indices().peekable(),
            content: content::new(),
        }
    }

    fn process(&mut self) -> Result<Content> {
        loop {
            match self.peek() {
                Some('@') => try!(self.process_at()),
                Some(_) => raise!(self, "found an unknown statement"),
                None => break,
            }
        }
        Ok(std::mem::replace(&mut self.content, content::new()))
    }

    fn process_at(&mut self) -> Result<()> {
        try!(self.skip_char('@'));

        let name = try!(self.get_token());
        let number = try!(self.get_natural());

        if let Some('{') = self.peek() {
            self.process_block(name, number)
        } else {
            self.content.attributes.insert(name, number);
            Ok(())
        }
    }

    fn process_block(&mut self, name: String, id: usize) -> Result<()> {
        try!(self.skip_char('{'));
        if let Some('#') = self.peek() {
            try!(self.process_table(name, id));
        } else {
            try!(self.process_graph(name, id));
        }
        try!(self.skip_char('}'));
        Ok(())
    }

    fn process_graph(&mut self, name: String, id: usize) -> Result<()> {
        let mut graph = content::new_graph(name, id);

        loop {
            match self.read_token() {
                Some(ref token) => match token.as_slice() {
                    "TASK" => {
                        let id = try!(self.get_id());
                        try!(self.skip_str("TYPE"));
                        let kind = try!(self.get_natural());
                        graph.tasks.push(content::new_task(id, kind));
                    },
                    "ARC" => {
                        let id = try!(self.get_id());
                        try!(self.skip_str("FROM"));
                        let from = try!(self.get_id());
                        try!(self.skip_str("TO"));
                        let to = try!(self.get_id());
                        try!(self.skip_str("TYPE"));
                        let kind = try!(self.get_natural());
                        graph.arcs.push(content::new_arc(id, from, to, kind));
                    },
                    "HARD_DEADLINE" => {
                        let id = try!(self.get_id());
                        try!(self.skip_str("ON"));
                        let on = try!(self.get_id());
                        try!(self.skip_str("AT"));
                        let at = try!(self.get_natural());
                        graph.deadlines.push(content::new_deadline(id, on, at));
                    },
                    _ => {
                        let value = try!(self.get_natural());
                        graph.attributes.insert(token.clone(), value);
                    },
                },
                None => break,
            }
        }

        self.content.graphs.push(graph);
        Ok(())
    }

    fn process_table(&mut self, name: String, id: usize) -> Result<()> {
        let mut table = content::new_table(name, id);

        try!(self.skip_char('#'));

        let mut names = vec![];
        loop {
            match self.read_token() {
                Some(token) => names.push(token),
                None => break,
            }
        }
        for name in names.into_iter() {
            table.attributes.insert(name, try!(self.get_real()));
        }

        try!(self.skip_comment());
        try!(self.skip_char('#'));

        loop {
            match self.read_token() {
                Some(name) => table.columns.push(content::new_column(name)),
                None => break,
            }
        }
        let cols = table.columns.len();
        loop {
            match self.peek() {
                Some('}') | None => break,
                _ => {},
            }
            for i in range(0, cols) {
                table.columns[i].data.push(try!(self.get_real()));
            }
        }

        self.content.tables.push(table);
        Ok(())
    }

    #[inline]
    fn peek(&mut self) -> Option<char> {
        match self.cursor.peek() {
            Some(&(_, c)) => Some(c),
            None => None,
        }
    }

    fn skip(&mut self, accept: &Fn(usize, char) -> bool) -> usize {
        let mut count = 0;

        loop {
            match self.peek() {
                Some(c) => {
                    if !accept(count, c) { break; }
                    self.next();
                    count += 1;
                },
                None => break,
            }
        }

        count
    }

    fn skip_char(&mut self, expected: char) -> Result<()> {
        match self.next() {
            Some(c) => {
                if c == expected {
                    self.skip_void();
                    return Ok(());
                }
            },
            None => {},
        }
        raise!(self, "expected `{}`", expected);
    }

    fn skip_str(&mut self, expected: &str) -> Result<()> {
        let len = expected.len();
        if self.skip(&|i, c| i < len && c == expected.char_at(i)) != len {
            raise!(self, "expected `{}`", expected);
        }
        self.skip_void();
        Ok(())
    }

    #[inline]
    fn skip_void(&mut self) {
        self.skip(&|_, c| c == ' ' || c == '\t' || c == '\n');
    }

    fn skip_comment(&mut self) -> Result<()> {
        if self.skip(&|i, c| i == 0 && c == '#' || (i > 0) && c == '-') < 2 {
            raise!(self, "expected a comment line");
        }
        self.skip_void();
        Ok(())
    }

    fn read(&mut self, accept: &Fn(usize, char) -> bool) -> Option<String> {
        let mut result = std::string::String::with_capacity(READ_CAPACITY);
        let mut count = 0;

        loop {
            match self.peek() {
                Some(c) => {
                    if !accept(count, c) { break; }
                    result.push(c);
                    self.next();
                    count += 1;
                },
                None => break,
            }
        }

        if count == 0 {
            None
        } else {
            Some(result)
        }
    }

    fn read_token(&mut self) -> Option<String> {
        let result = self.read(&|i, c| {
            match c {
                'A'...'Z' | 'a'...'z' if i == 0 => true,
                'A'...'Z' | 'a'...'z' | '_' | '0'...'9' if i > 0 => true,
                _ => false,
            }
        });
        self.skip_void();
        result
    }

    fn read_id(&mut self) -> Option<usize> {
        match self.read_token() {
            Some(ref token) => match token.as_slice().split('_').nth(1) {
                Some(id) => std::num::from_str_radix(id, 10),
                None => None,
            },
            None => None,
        }
    }

    fn read_natural(&mut self) -> Option<usize> {
        let result = match self.read(&|_, c| c >= '0' && c <= '9') {
            Some(ref number) => std::num::from_str_radix(number.as_slice(), 10),
            None => None,
        };
        self.skip_void();
        result
    }

    fn read_real(&mut self) -> Option<f64> {
        let result = match self.read(&|_, c| {
            match c {
                '+' | '-' | '.' | '0'...'9' | 'e' | 'E' => true,
                _ => false,
            }
        }) {
            Some(ref number) => number.as_slice().parse(),
            None => None,
        };
        self.skip_void();
        result
    }

    fn get_token(&mut self) -> Result<String> {
        match self.read_token() {
            Some(token) => Ok(token),
            None => raise!(self, "expected a token"),
        }
    }

    fn get_id(&mut self) -> Result<usize> {
        match self.read_id() {
            Some(id) => Ok(id),
            None => raise!(self, "expected an id"),
        }
    }

    fn get_natural(&mut self) -> Result<usize> {
        match self.read_natural() {
            Some(number) => Ok(number),
            None => raise!(self, "expected a natural number"),
        }
    }

    fn get_real(&mut self) -> Result<f64> {
        match self.read_real() {
            Some(number) => Ok(number),
            None => raise!(self, "expected a real number"),
        }
    }
}

impl<'a> std::iter::Iterator for Parser<'a> {
    type Item = char;

    fn next(&mut self) -> Option<char> {
        match self.cursor.next() {
            Some((_, '\n')) => {
                self.line += 1;
                Some('\n')
            },
            Some((_, c)) => Some(c),
            None => None,
        }
    }
}

#[cfg(test)]
mod tests {
    macro_rules! parser(
        ($input:expr) => (super::Parser::new($input));
    );

    #[test]
    fn process_at() {
        assert_ok!(parser!("@abc 12").process_at());
        assert_err!(parser!("@ ").process_at());
        assert_err!(parser!("@abc").process_at());
    }

    #[test]
    fn process_block() {
        assert_ok!(parser!("{}").process_block(String::new(), 0));
    }

    #[test]
    fn process_graph() {
        let mut parser = parser!("TASK t0_0\tTYPE 2   ");
        assert_ok!(parser.process_graph(String::new(), 0));
        {
            let ref task = parser.content.graphs[0].tasks[0];
            assert_eq!(task.id, 0);
            assert_eq!(task.kind, 2);
        }

        parser = parser!("ARC a0_42 \tFROM t0_0  TO  t0_1 TYPE 35   ");
        assert_ok!(parser.process_graph(String::new(), 0));
        {
            let ref arc = parser.content.graphs[0].arcs[0];
            assert_eq!(arc.id, 42);
            assert_eq!(arc.from, 0);
            assert_eq!(arc.to, 1);
            assert_eq!(arc.kind, 35);
        }

        parser = parser!("HARD_DEADLINE d0_9 ON t0_12 AT 1000   ");
        assert_ok!(parser.process_graph(String::new(), 0));
        {
            let ref deadline = parser.content.graphs[0].deadlines[0];
            assert_eq!(deadline.id, 9);
            assert_eq!(deadline.on, 12);
            assert_eq!(deadline.at, 1000);
        }
    }

    #[test]
    fn process_table() {
        let mut parser = parser!("# foo\n 70.07\n#--\n# bar baz\n1 2 3 4 ");
        assert_ok!(parser.process_table(String::new(), 0));
        let ref table = parser.content.tables[0];
        assert_eq!(table.attributes["foo".to_string()], 70.07);
        assert_eq!(table.columns[0].name, "bar".to_string());
        assert_eq!(table.columns[1].name, "baz".to_string());
        assert_eq!(table.columns[0].data, vec![1.0, 3.0]);
        assert_eq!(table.columns[1].data, vec![2.0, 4.0]);
    }

    #[test]
    fn skip_char() {
        let mut parser = parser!("#  \t\n  abc");
        assert_ok!(parser.skip_char('#'));
        assert_eq!(parser.next().unwrap(), 'a');
    }

    #[test]
    fn skip_str() {
        let mut parser = parser!("abc  \t\n  xyz");
        assert_ok!(parser.skip_str("abc"));
        assert_eq!(parser.next().unwrap(), 'x');
    }

    #[test]
    fn skip_void() {
        let mut parser = parser!("  \t  abc");
        parser.skip_void();
        assert_eq!(parser.next().unwrap(), 'a');
    }

    #[test]
    fn skip_comment() {
        let mut parser = parser!("#--------------   \n abc");
        assert_ok!(parser.skip_comment());
        assert_eq!(parser.next().unwrap(), 'a');
    }

    #[test]
    fn get_token() {
        macro_rules! test(
            ($input:expr, $output:expr) => (
                assert_eq!(parser!($input).get_token().unwrap(),
                           String::from_str($output))
            );
        );
        test!("AZ xyz", "AZ");
        test!("az xyz", "az");
        test!("AZ_az_09 xyz", "AZ_az_09");
    }

    #[test]
    fn get_id() {
        assert_eq!(parser!("t0_42").get_id().unwrap(), 42);
    }

    #[test]
    fn get_natural() {
        assert_eq!(parser!("09").get_natural().unwrap(), 9);
    }

    #[test]
    fn get_real() {
        macro_rules! test(
            ($input:expr, $output:expr) => (
                assert_eq!(parser!($input).get_real().unwrap(), $output)
            );
        );
        test!("-1", -1.0);
        test!("0.1", 0.1);
        test!("1.2e3", 1.2e3);
        test!("1.2e+3", 1.2e3);
        test!("-1.2e-3", -1.2e-3);
    }
}
<|endoftext|>


<commit_before>// This file is part of Genesis.

// Genesis is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Genesis is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.

// You should have received a copy of the GNU Affero General Public License
// along with Genesis.  If not, see <http://www.gnu.org/licenses/>.
#![feature(asm, core, lang_items, no_std)]
#![no_std]

#[macro_use]
extern crate core;
extern crate rlibc;

pub use self::arch::init as arch_init;

#[macro_use]
mod log;

mod arch;
mod console {
    pub use arch::serial::*;
}
mod unwind;
<commit_msg>cfg: Update to new unstable feature names<commit_after>// This file is part of Genesis.

// Genesis is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Genesis is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.

// You should have received a copy of the GNU Affero General Public License
// along with Genesis.  If not, see <http://www.gnu.org/licenses/>.
#![feature(asm, core, core_prelude, core_str_ext, lang_items, no_std)]
#![no_std]

#[macro_use]
extern crate core;
extern crate rlibc;

pub use self::arch::init as arch_init;

#[macro_use]
mod log;

mod arch;
mod console {
    pub use arch::serial::*;
}
mod unwind;
<|endoftext|>


<commit_before>#![feature(asm)]
#![feature(linkage)]
#![feature(naked_functions)]
#![cfg_attr(not(test), no_std)]
#![no_builtins]
// TODO(rust-lang/rust#35021) uncomment when that PR lands
// #![feature(rustc_builtins)]

// We disable #[no_mangle] for tests so that we can verify the test results
// against the native compiler-rt implementations of the builtins.

#[cfg(test)]
#[macro_use]
extern crate quickcheck;

#[cfg(test)]
extern crate core;

#[cfg(all(not(windows), not(target_os = "macos")))]
extern crate rlibc;

#[cfg(target_arch = "arm")]
pub mod arm;

pub mod udiv;
pub mod mul;
pub mod shift;

#[cfg(test)]
mod qc;

/// Trait for some basic operations on integers
trait Int {
    fn bits() -> u32;
}

// TODO: Once i128/u128 support lands, we'll want to add impls for those as well
impl Int for u32 {
    fn bits() -> u32 {
        32
    }
}
impl Int for i32 {
    fn bits() -> u32 {
        32
    }
}
impl Int for u64 {
    fn bits() -> u32 {
        64
    }
}
impl Int for i64 {
    fn bits() -> u32 {
        64
    }
}

/// Trait to convert an integer to/from smaller parts
trait LargeInt {
    type LowHalf;
    type HighHalf;

    fn low(self) -> Self::LowHalf;
    fn high(self) -> Self::HighHalf;
    fn from_parts(low: Self::LowHalf, high: Self::HighHalf) -> Self;
}

// TODO: Once i128/u128 support lands, we'll want to add impls for those as well
impl LargeInt for u64 {
    type LowHalf = u32;
    type HighHalf = u32;

    fn low(self) -> u32 {
        self as u32
    }
    fn high(self) -> u32 {
        (self >> 32) as u32
    }
    fn from_parts(low: u32, high: u32) -> u64 {
        low as u64 | ((high as u64) << 32)
    }
}
impl LargeInt for i64 {
    type LowHalf = u32;
    type HighHalf = i32;

    fn low(self) -> u32 {
        self as u32
    }
    fn high(self) -> i32 {
        (self >> 32) as i32
    }
    fn from_parts(low: u32, high: i32) -> i64 {
        low as i64 | ((high as i64) << 32)
    }
}
<commit_msg>add core_intrinsics feature gate<commit_after>#![feature(asm)]
#![feature(core_intrinsics)]
#![feature(linkage)]
#![feature(naked_functions)]
#![cfg_attr(not(test), no_std)]
#![no_builtins]
// TODO(rust-lang/rust#35021) uncomment when that PR lands
// #![feature(rustc_builtins)]

// We disable #[no_mangle] for tests so that we can verify the test results
// against the native compiler-rt implementations of the builtins.

#[cfg(test)]
#[macro_use]
extern crate quickcheck;

#[cfg(test)]
extern crate core;

#[cfg(all(not(windows), not(target_os = "macos")))]
extern crate rlibc;

#[cfg(target_arch = "arm")]
pub mod arm;

pub mod udiv;
pub mod mul;
pub mod shift;

#[cfg(test)]
mod qc;

/// Trait for some basic operations on integers
trait Int {
    fn bits() -> u32;
}

// TODO: Once i128/u128 support lands, we'll want to add impls for those as well
impl Int for u32 {
    fn bits() -> u32 {
        32
    }
}
impl Int for i32 {
    fn bits() -> u32 {
        32
    }
}
impl Int for u64 {
    fn bits() -> u32 {
        64
    }
}
impl Int for i64 {
    fn bits() -> u32 {
        64
    }
}

/// Trait to convert an integer to/from smaller parts
trait LargeInt {
    type LowHalf;
    type HighHalf;

    fn low(self) -> Self::LowHalf;
    fn high(self) -> Self::HighHalf;
    fn from_parts(low: Self::LowHalf, high: Self::HighHalf) -> Self;
}

// TODO: Once i128/u128 support lands, we'll want to add impls for those as well
impl LargeInt for u64 {
    type LowHalf = u32;
    type HighHalf = u32;

    fn low(self) -> u32 {
        self as u32
    }
    fn high(self) -> u32 {
        (self >> 32) as u32
    }
    fn from_parts(low: u32, high: u32) -> u64 {
        low as u64 | ((high as u64) << 32)
    }
}
impl LargeInt for i64 {
    type LowHalf = u32;
    type HighHalf = i32;

    fn low(self) -> u32 {
        self as u32
    }
    fn high(self) -> i32 {
        (self >> 32) as i32
    }
    fn from_parts(low: u32, high: i32) -> i64 {
        low as i64 | ((high as i64) << 32)
    }
}
<|endoftext|>


<commit_before>//! # Multihash
//!
//! Implementation of [multihash](https://github.com/multiformats/multihash) in Rust.
//!
//! A `Multihash` is a structure that contains a hashing algorithm, plus some hashed data.
//! A `MultihashRef` is the same as a `Multihash`, except that it doesn't own its data.

#![deny(missing_docs)]

mod digests;
mod errors;
mod hashes;
mod storage;

#[cfg(any(test, feature = "test"))]
mod arb;

pub use digests::{wrap, Multihash, MultihashDigest, MultihashGeneric, MultihashRef};
pub use errors::{DecodeError, DecodeOwnedError, EncodeError};
pub use hashes::*;
<commit_msg>fix: also export MultihashRefGeneric<commit_after>//! # Multihash
//!
//! Implementation of [multihash](https://github.com/multiformats/multihash) in Rust.
//!
//! A `Multihash` is a structure that contains a hashing algorithm, plus some hashed data.
//! A `MultihashRef` is the same as a `Multihash`, except that it doesn't own its data.

#![deny(missing_docs)]

mod digests;
mod errors;
mod hashes;
mod storage;

#[cfg(any(test, feature = "test"))]
mod arb;

pub use digests::{
    wrap, Multihash, MultihashDigest, MultihashGeneric, MultihashRef, MultihashRefGeneric,
};
pub use errors::{DecodeError, DecodeOwnedError, EncodeError};
pub use hashes::*;
<|endoftext|>


<commit_before>//! Crate ruma_api contains core types used to define the requests and responses for each endpoint
//! in the various [Matrix](https://matrix.org) API specifications.
//! These types can be shared by client and server code for all Matrix APIs.
//!
//! When implementing a new Matrix API, each endpoint has a type that implements `Endpoint`, plus
//! the necessary associated types.
//! An implementation of `Endpoint` contains all the information about the HTTP method, the path and
//! input parameters for requests, and the structure of a successful response.
//! Such types can then be used by client code to make requests, and by server code to fulfill
//! those requests.

#![deny(
    missing_copy_implementations,
    missing_debug_implementations,
    missing_docs,
    warnings
)]
#![warn(
    clippy::empty_line_after_outer_attr,
    clippy::expl_impl_clone_on_copy,
    clippy::if_not_else,
    clippy::items_after_statements,
    clippy::match_same_arms,
    clippy::mem_forget,
    clippy::missing_docs_in_private_items,
    clippy::multiple_inherent_impl,
    clippy::mut_mut,
    clippy::needless_borrow,
    clippy::needless_continue,
    clippy::single_match_else,
    clippy::unicode_not_nfc,
    clippy::use_self,
    clippy::used_underscore_binding,
    clippy::wrong_pub_self_convention,
    clippy::wrong_self_convention
)]

use std::{
    convert::TryInto,
    error::Error as StdError,
    fmt::{Display, Formatter, Result as FmtResult},
    io,
};

use futures::future::FutureFrom;
use http::{self, Method, Request, Response, StatusCode};
use hyper::{self, Body};
use ruma_identifiers;
use serde_json;
use serde_urlencoded;

/// A Matrix API endpoint.
pub trait Endpoint<T = Body, U = Body> {
    /// Data needed to make a request to the endpoint.
    type Request: TryInto<Request<T>, Error = Error> + FutureFrom<Request<T>, Error = Error>;
    /// Data returned from the endpoint.
    type Response: FutureFrom<Response<U>, Error = Error> + TryInto<Response<U>>;

    /// Metadata about the endpoint.
    const METADATA: Metadata;
}

/// An error when converting an `Endpoint::Request` to a `http::Request` or a `http::Response` to
/// an `Endpoint::Response`.
#[derive(Debug)]
pub struct Error(pub(crate) InnerError);

impl Display for Error {
    fn fmt(&self, f: &mut Formatter) -> FmtResult {
        let message = match self.0 {
            InnerError::Http(_) => "An error converting to or from `http` types occurred.".into(),
            InnerError::Hyper(_) => "A Hyper error occurred.".into(),
            InnerError::Io(_) => "An I/O error occurred.".into(),
            InnerError::SerdeJson(_) => "A JSON error occurred.".into(),
            InnerError::SerdeUrlEncodedDe(_) => {
                "A URL encoding deserialization error occurred.".into()
            }
            InnerError::SerdeUrlEncodedSer(_) => {
                "A URL encoding serialization error occurred.".into()
            }
            InnerError::RumaIdentifiers(_) => "A ruma-identifiers error occurred.".into(),
            InnerError::StatusCode(code) => format!("A HTTP {} error occurred.", code),
        };

        write!(f, "{}", message)
    }
}

impl StdError for Error {}

#[derive(Debug)]
pub(crate) enum InnerError {
    /// An HTTP error.
    Http(http::Error),
    /// An Hyper error.
    Hyper(hyper::Error),
    /// A I/O error.
    Io(io::Error),
    /// A Serde JSON error.
    SerdeJson(serde_json::Error),
    /// A Serde URL decoding error.
    SerdeUrlEncodedDe(serde_urlencoded::de::Error),
    /// A Serde URL encoding error.
    SerdeUrlEncodedSer(serde_urlencoded::ser::Error),
    /// A Ruma Identitifiers error.
    RumaIdentifiers(ruma_identifiers::Error),
    /// An HTTP status code indicating error.
    StatusCode(StatusCode),
}

impl From<http::Error> for Error {
    fn from(error: http::Error) -> Self {
        Self(InnerError::Http(error))
    }
}

impl From<hyper::Error> for Error {
    fn from(error: hyper::Error) -> Self {
        Self(InnerError::Hyper(error))
    }
}

impl From<io::Error> for Error {
    fn from(error: io::Error) -> Self {
        Self(InnerError::Io(error))
    }
}

impl From<serde_json::Error> for Error {
    fn from(error: serde_json::Error) -> Self {
        Self(InnerError::SerdeJson(error))
    }
}

impl From<serde_urlencoded::de::Error> for Error {
    fn from(error: serde_urlencoded::de::Error) -> Self {
        Self(InnerError::SerdeUrlEncodedDe(error))
    }
}

impl From<serde_urlencoded::ser::Error> for Error {
    fn from(error: serde_urlencoded::ser::Error) -> Self {
        Self(InnerError::SerdeUrlEncodedSer(error))
    }
}

impl From<ruma_identifiers::Error> for Error {
    fn from(error: ruma_identifiers::Error) -> Self {
        Self(InnerError::RumaIdentifiers(error))
    }
}

impl From<StatusCode> for Error {
    fn from(error: StatusCode) -> Self {
        Self(InnerError::StatusCode(error))
    }
}

/// Metadata about an API endpoint.
#[derive(Clone, Debug)]
pub struct Metadata {
    /// A human-readable description of the endpoint.
    pub description: &'static str,
    /// The HTTP method used by this endpoint.
    pub method: Method,
    /// A unique identifier for this endpoint.
    pub name: &'static str,
    /// The path of this endpoint's URL, with variable names where path parameters should be filled
    /// in during a request.
    pub path: &'static str,
    /// Whether or not this endpoint is rate limited by the server.
    pub rate_limited: bool,
    /// Whether or not the server requires an authenticated user for this endpoint.
    pub requires_authentication: bool,
}

#[cfg(test)]
mod tests {
    /// PUT /_matrix/client/r0/directory/room/:room_alias
    pub mod create {
        use std::convert::TryFrom;

        use futures::future::{err, ok, FutureFrom, FutureResult};
        use http::{
            header::CONTENT_TYPE, method::Method, Request as HttpRequest, Response as HttpResponse,
        };
        use ruma_identifiers::{RoomAliasId, RoomId};
        use serde::{de::IntoDeserializer, Deserialize, Serialize};
        use serde_json;
        use url::percent_encoding;

        use super::super::{Endpoint as ApiEndpoint, Error, Metadata};

        #[derive(Debug)]
        pub struct Endpoint;

        impl ApiEndpoint<Vec<u8>, Vec<u8>> for Endpoint {
            type Request = Request;
            type Response = Response;

            const METADATA: Metadata = Metadata {
                description: "Add an alias to a room.",
                method: Method::PUT,
                name: "create_alias",
                path: "/_matrix/client/r0/directory/room/:room_alias",
                rate_limited: false,
                requires_authentication: true,
            };
        }

        /// A request to create a new room alias.
        #[derive(Debug)]
        pub struct Request {
            pub room_id: RoomId,         // body
            pub room_alias: RoomAliasId, // path
        }

        #[derive(Debug, Serialize, Deserialize)]
        struct RequestBody {
            room_id: RoomId,
        }

        impl TryFrom<Request> for HttpRequest<Vec<u8>> {
            type Error = Error;

            fn try_from(request: Request) -> Result<HttpRequest<Vec<u8>>, Self::Error> {
                let metadata = Endpoint::METADATA;

                let path = metadata
                    .path
                    .to_string()
                    .replace(":room_alias", &request.room_alias.to_string());

                let request_body = RequestBody {
                    room_id: request.room_id,
                };

                let http_request = HttpRequest::builder()
                    .method(metadata.method)
                    .uri(path)
                    .body(serde_json::to_vec(&request_body).map_err(Error::from)?)?;

                Ok(http_request)
            }
        }

        impl FutureFrom<HttpRequest<Vec<u8>>> for Request {
            type Future = FutureResult<Self, Self::Error>;
            type Error = Error;

            fn future_from(request: HttpRequest<Vec<u8>>) -> Self::Future {
                FutureResult::from(Self::try_from(request))
            }
        }

        impl TryFrom<HttpRequest<Vec<u8>>> for Request {
            type Error = Error;

            fn try_from(request: HttpRequest<Vec<u8>>) -> Result<Request, Self::Error> {
                let request_body: RequestBody =
                    ::serde_json::from_slice(request.body().as_slice())?;
                let path_segments: Vec<&str> = request.uri().path()[1..].split('/').collect();
                Ok(Request {
                    room_id: request_body.room_id,
                    room_alias: {
                        let segment = path_segments.get(5).unwrap().as_bytes();
                        let decoded = percent_encoding::percent_decode(segment).decode_utf8_lossy();
                        RoomAliasId::deserialize(decoded.into_deserializer())
                            .map_err(|e: serde_json::error::Error| e)?
                    },
                })
            }
        }

        /// The response to a request to create a new room alias.
        #[derive(Clone, Copy, Debug)]
        pub struct Response;

        impl FutureFrom<HttpResponse<Vec<u8>>> for Response {
            type Future = FutureResult<Self, Self::Error>;
            type Error = Error;

            fn future_from(
                http_response: HttpResponse<Vec<u8>>,
            ) -> FutureResult<Self, Self::Error> {
                if http_response.status().is_success() {
                    ok(Response)
                } else {
                    err(http_response.status().clone().into())
                }
            }
        }

        impl TryFrom<Response> for HttpResponse<Vec<u8>> {
            type Error = Error;

            fn try_from(_response: Response) -> Result<HttpResponse<Vec<u8>>, Self::Error> {
                let response = HttpResponse::builder()
                    .header(CONTENT_TYPE, "application/json")
                    .body("{}".as_bytes().to_vec())
                    .unwrap();
                Ok(response)
            }
        }
    }
}
<commit_msg>Address clippy warnings.<commit_after>//! Crate ruma_api contains core types used to define the requests and responses for each endpoint
//! in the various [Matrix](https://matrix.org) API specifications.
//! These types can be shared by client and server code for all Matrix APIs.
//!
//! When implementing a new Matrix API, each endpoint has a type that implements `Endpoint`, plus
//! the necessary associated types.
//! An implementation of `Endpoint` contains all the information about the HTTP method, the path and
//! input parameters for requests, and the structure of a successful response.
//! Such types can then be used by client code to make requests, and by server code to fulfill
//! those requests.

#![deny(
    missing_copy_implementations,
    missing_debug_implementations,
    missing_docs,
    warnings
)]
#![warn(
    clippy::empty_line_after_outer_attr,
    clippy::expl_impl_clone_on_copy,
    clippy::if_not_else,
    clippy::items_after_statements,
    clippy::match_same_arms,
    clippy::mem_forget,
    clippy::missing_docs_in_private_items,
    clippy::multiple_inherent_impl,
    clippy::mut_mut,
    clippy::needless_borrow,
    clippy::needless_continue,
    clippy::single_match_else,
    clippy::unicode_not_nfc,
    clippy::used_underscore_binding,
    clippy::wrong_pub_self_convention,
    clippy::wrong_self_convention
)]

use std::{
    convert::TryInto,
    error::Error as StdError,
    fmt::{Display, Formatter, Result as FmtResult},
    io,
};

use futures::future::FutureFrom;
use http::{self, Method, Request, Response, StatusCode};
use hyper::{self, Body};
use ruma_identifiers;
use serde_json;
use serde_urlencoded;

/// A Matrix API endpoint.
pub trait Endpoint<T = Body, U = Body> {
    /// Data needed to make a request to the endpoint.
    type Request: TryInto<Request<T>, Error = Error> + FutureFrom<Request<T>, Error = Error>;
    /// Data returned from the endpoint.
    type Response: FutureFrom<Response<U>, Error = Error> + TryInto<Response<U>>;

    /// Metadata about the endpoint.
    const METADATA: Metadata;
}

/// An error when converting an `Endpoint::Request` to a `http::Request` or a `http::Response` to
/// an `Endpoint::Response`.
#[derive(Debug)]
pub struct Error(pub(crate) InnerError);

impl Display for Error {
    fn fmt(&self, f: &mut Formatter) -> FmtResult {
        let message = match self.0 {
            InnerError::Http(_) => "An error converting to or from `http` types occurred.".into(),
            InnerError::Hyper(_) => "A Hyper error occurred.".into(),
            InnerError::Io(_) => "An I/O error occurred.".into(),
            InnerError::SerdeJson(_) => "A JSON error occurred.".into(),
            InnerError::SerdeUrlEncodedDe(_) => {
                "A URL encoding deserialization error occurred.".into()
            }
            InnerError::SerdeUrlEncodedSer(_) => {
                "A URL encoding serialization error occurred.".into()
            }
            InnerError::RumaIdentifiers(_) => "A ruma-identifiers error occurred.".into(),
            InnerError::StatusCode(code) => format!("A HTTP {} error occurred.", code),
        };

        write!(f, "{}", message)
    }
}

impl StdError for Error {}

/// Internal representation of errors.
#[derive(Debug)]
pub(crate) enum InnerError {
    /// An HTTP error.
    Http(http::Error),
    /// An Hyper error.
    Hyper(hyper::Error),
    /// A I/O error.
    Io(io::Error),
    /// A Serde JSON error.
    SerdeJson(serde_json::Error),
    /// A Serde URL decoding error.
    SerdeUrlEncodedDe(serde_urlencoded::de::Error),
    /// A Serde URL encoding error.
    SerdeUrlEncodedSer(serde_urlencoded::ser::Error),
    /// A Ruma Identitifiers error.
    RumaIdentifiers(ruma_identifiers::Error),
    /// An HTTP status code indicating error.
    StatusCode(StatusCode),
}

impl From<http::Error> for Error {
    fn from(error: http::Error) -> Self {
        Self(InnerError::Http(error))
    }
}

impl From<hyper::Error> for Error {
    fn from(error: hyper::Error) -> Self {
        Self(InnerError::Hyper(error))
    }
}

impl From<io::Error> for Error {
    fn from(error: io::Error) -> Self {
        Self(InnerError::Io(error))
    }
}

impl From<serde_json::Error> for Error {
    fn from(error: serde_json::Error) -> Self {
        Self(InnerError::SerdeJson(error))
    }
}

impl From<serde_urlencoded::de::Error> for Error {
    fn from(error: serde_urlencoded::de::Error) -> Self {
        Self(InnerError::SerdeUrlEncodedDe(error))
    }
}

impl From<serde_urlencoded::ser::Error> for Error {
    fn from(error: serde_urlencoded::ser::Error) -> Self {
        Self(InnerError::SerdeUrlEncodedSer(error))
    }
}

impl From<ruma_identifiers::Error> for Error {
    fn from(error: ruma_identifiers::Error) -> Self {
        Self(InnerError::RumaIdentifiers(error))
    }
}

impl From<StatusCode> for Error {
    fn from(error: StatusCode) -> Self {
        Self(InnerError::StatusCode(error))
    }
}

/// Metadata about an API endpoint.
#[derive(Clone, Debug)]
pub struct Metadata {
    /// A human-readable description of the endpoint.
    pub description: &'static str,
    /// The HTTP method used by this endpoint.
    pub method: Method,
    /// A unique identifier for this endpoint.
    pub name: &'static str,
    /// The path of this endpoint's URL, with variable names where path parameters should be filled
    /// in during a request.
    pub path: &'static str,
    /// Whether or not this endpoint is rate limited by the server.
    pub rate_limited: bool,
    /// Whether or not the server requires an authenticated user for this endpoint.
    pub requires_authentication: bool,
}

#[cfg(test)]
mod tests {
    /// PUT /_matrix/client/r0/directory/room/:room_alias
    pub mod create {
        use std::convert::TryFrom;

        use futures::future::{err, ok, FutureFrom, FutureResult};
        use http::{
            header::CONTENT_TYPE, method::Method, Request as HttpRequest, Response as HttpResponse,
        };
        use ruma_identifiers::{RoomAliasId, RoomId};
        use serde::{de::IntoDeserializer, Deserialize, Serialize};
        use serde_json;
        use url::percent_encoding;

        use super::super::{Endpoint as ApiEndpoint, Error, Metadata};

        #[derive(Debug)]
        pub struct Endpoint;

        impl ApiEndpoint<Vec<u8>, Vec<u8>> for Endpoint {
            type Request = Request;
            type Response = Response;

            const METADATA: Metadata = Metadata {
                description: "Add an alias to a room.",
                method: Method::PUT,
                name: "create_alias",
                path: "/_matrix/client/r0/directory/room/:room_alias",
                rate_limited: false,
                requires_authentication: true,
            };
        }

        /// A request to create a new room alias.
        #[derive(Debug)]
        pub struct Request {
            pub room_id: RoomId,         // body
            pub room_alias: RoomAliasId, // path
        }

        #[derive(Debug, Serialize, Deserialize)]
        struct RequestBody {
            room_id: RoomId,
        }

        impl TryFrom<Request> for HttpRequest<Vec<u8>> {
            type Error = Error;

            fn try_from(request: Request) -> Result<HttpRequest<Vec<u8>>, Self::Error> {
                let metadata = Endpoint::METADATA;

                let path = metadata
                    .path
                    .to_string()
                    .replace(":room_alias", &request.room_alias.to_string());

                let request_body = RequestBody {
                    room_id: request.room_id,
                };

                let http_request = HttpRequest::builder()
                    .method(metadata.method)
                    .uri(path)
                    .body(serde_json::to_vec(&request_body).map_err(Error::from)?)?;

                Ok(http_request)
            }
        }

        impl FutureFrom<HttpRequest<Vec<u8>>> for Request {
            type Future = FutureResult<Self, Self::Error>;
            type Error = Error;

            fn future_from(request: HttpRequest<Vec<u8>>) -> Self::Future {
                FutureResult::from(Self::try_from(request))
            }
        }

        impl TryFrom<HttpRequest<Vec<u8>>> for Request {
            type Error = Error;

            fn try_from(request: HttpRequest<Vec<u8>>) -> Result<Self, Self::Error> {
                let request_body: RequestBody =
                    ::serde_json::from_slice(request.body().as_slice())?;
                let path_segments: Vec<&str> = request.uri().path()[1..].split('/').collect();
                Ok(Request {
                    room_id: request_body.room_id,
                    room_alias: {
                        let segment = path_segments.get(5).unwrap().as_bytes();
                        let decoded = percent_encoding::percent_decode(segment).decode_utf8_lossy();
                        RoomAliasId::deserialize(decoded.into_deserializer())
                            .map_err(|e: serde_json::error::Error| e)?
                    },
                })
            }
        }

        /// The response to a request to create a new room alias.
        #[derive(Clone, Copy, Debug)]
        pub struct Response;

        impl FutureFrom<HttpResponse<Vec<u8>>> for Response {
            type Future = FutureResult<Self, Self::Error>;
            type Error = Error;

            fn future_from(
                http_response: HttpResponse<Vec<u8>>,
            ) -> FutureResult<Self, Self::Error> {
                if http_response.status().is_success() {
                    ok(Response)
                } else {
                    err(http_response.status().into())
                }
            }
        }

        impl TryFrom<Response> for HttpResponse<Vec<u8>> {
            type Error = Error;

            fn try_from(_response: Response) -> Result<HttpResponse<Vec<u8>>, Self::Error> {
                let response = HttpResponse::builder()
                    .header(CONTENT_TYPE, "application/json")
                    .body(b"{}".to_vec())
                    .unwrap();
                Ok(response)
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate hyper;
extern crate serde_json;

use hyper::{Client, Error as HttpError};
use serde_json::StreamDeserializer;
 use std::io::Read;
use std::sync::mpsc::{channel, Receiver};
use std::thread;

include!(concat!(env!("OUT_DIR"), "/main.rs"));

pub type Result<T> = std::result::Result<T, Error>;

#[derive(Debug)]
pub enum Error {
    Transport(HttpError),
}

impl From<HttpError> for Error {
    fn from(error: HttpError) -> Error {
        Error::Transport(error)
    }
}

pub struct Cluster {
    host: String,
}

pub trait Events {
    fn events(&mut self) -> Result<Receiver<Event>>;

    fn generator<Iter>(&self, iter: Iter) -> Result<Receiver<Event>>
        where Iter: Iterator<Item = std::io::Result<u8>>,
              Iter: Send + 'static
    {
        let (tx, rx) = channel();
        let src: StreamDeserializer<Event, _> = StreamDeserializer::new(iter);
        thread::spawn(move || {
            for e in src {
                match e {
                    Ok(event) => tx.send(event).unwrap(),
                    Err(e) => {
                        println!("{:#?}", e);
                        break;
                    }
                }
            }
        });
        Ok(rx)
    }
}

impl Cluster {
    pub fn new() -> Cluster {
        Cluster { host: "http://localhost:8001".to_owned() }
    }
}

impl Events for Cluster {
    fn events(&mut self) -> Result<Receiver<Event>> {
        let res = try!(Client::new()
            .get(&format!("{}/api/v1/events?watch=true", self.host))
            .send());
        self.generator(res.bytes())
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {}
}
<commit_msg>properly handle send errors<commit_after>extern crate hyper;
extern crate serde_json;

use hyper::{Client, Error as HttpError};
use serde_json::StreamDeserializer;
 use std::io::Read;
use std::sync::mpsc::{channel, Receiver};
use std::thread;

include!(concat!(env!("OUT_DIR"), "/main.rs"));

pub type Result<T> = std::result::Result<T, Error>;

#[derive(Debug)]
pub enum Error {
    Transport(HttpError),
}

impl From<HttpError> for Error {
    fn from(error: HttpError) -> Error {
        Error::Transport(error)
    }
}

pub struct Cluster {
    host: String,
}

pub trait Events {
    fn events(&mut self) -> Result<Receiver<Event>>;

    fn generator<Iter>(&self, iter: Iter) -> Result<Receiver<Event>>
        where Iter: Iterator<Item = std::io::Result<u8>>,
              Iter: Send + 'static
    {
        let (tx, rx) = channel();
        let src: StreamDeserializer<Event, _> = StreamDeserializer::new(iter);
        thread::spawn(move || {
            for e in src {
                match e {
                    Ok(event) => match tx.send(event) {
                        Err(e) => {
                            println!("{:#?}", e);
                            break
                        },_ => ()
                    },
                    Err(e) => {
                        println!("{:#?}", e);
                        break
                    }
                }
            }
        });
        Ok(rx)
    }
}

impl Cluster {
    pub fn new() -> Cluster {
        Cluster { host: "http://localhost:8001".to_owned() }
    }
}

impl Events for Cluster {
    fn events(&mut self) -> Result<Receiver<Event>> {
        let res = try!(Client::new()
            .get(&format!("{}/api/v1/events?watch=true", self.host))
            .send());
        self.generator(res.bytes())
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {}
}
<|endoftext|>


<commit_before>
use std::ops::Deref;

pub mod graph {
    use std::collections::HashMap;

    #[derive(Debug)]
    pub struct Graph {
        elements: i64,
        vertices: HashMap<i64, Box<Vertex>>,
    }

    impl Graph {
        pub fn new() -> Box<Graph> {
            let vertices: HashMap<i64, Box<Vertex>> = HashMap::new();
            Box::new(Graph{elements:0, vertices:vertices})
        }

        pub fn add_vertex(&mut self) -> VertexProxy {
            let new_id = self.elements + 1;
            self.elements += 1;
            let mut v = Vertex::new(new_id);

            let ptr: *mut Box<Vertex> = &mut v as *mut Box<Vertex>;

            self.vertices.insert(new_id, v);

            // return the proxy which knows it's own id
            VertexProxy{id:new_id, v: ptr}
        }
    }

    /*
    I'm not sure on this, but it feels reasonable.  a vertex can own it's out_edges.
    this should? make it easier to manage the memory?

    additionally, it should cut down on the number of "things" i have to traverse
    if a vertex has 10k edges (5k in and out 5k out) then doing something like

    g(v).outV()

    should be faster to iterate over

    the cost is a little code complexity but i think that won't be too bad
     */
    #[derive(Debug)]
    struct Vertex {
        id: i64,
        out_edges: Vec<Edge>,
        in_edges: *mut Vec<Edge>,
    }

    impl Vertex {
        pub fn new(id: i64) -> Box<Vertex> {

            let mut edges : Vec<Edge> = Vec::new();
            let edges_ptr : *mut Vec<Edge> = &mut edges;
            let out_edges: Vec<Edge> = Vec::new();
            let vertex = Vertex{id:id, out_edges: out_edges, in_edges:edges_ptr};
            let mut v = Box::new(vertex);
            return v;
        }

        pub fn add_out_edge(&mut self, edge: Edge ) {
            self.out_edges.push(edge)
        }

        pub fn add_in_edge() {

        }

    }

    #[derive(Debug)]
    pub struct VertexProxy {
        pub id: i64,
        v: *mut Box<Vertex>,
    }

    //let i: u32 = 1;
    //// explicit cast
    //let p_imm: *const u32 = &i as *const u32;
    //let mut m: u32 = 2;
    //// implicit coercion
    //let p_mut: *mut u32 = &mut m;
    //
    //unsafe {
    //let ref_imm: &u32 = &*p_imm;
    //let ref_mut: &mut u32 = &mut *p_mut;
    //}

    impl VertexProxy {
        pub fn add_edge(&mut self, to_vertex: &mut VertexProxy) {
            let in_vertex: &mut Box<Vertex>;
            let out_vertex: &mut Box<Vertex>;

            unsafe {
                in_vertex =  &mut *(self.v);
                out_vertex = &mut *(to_vertex.v);
            }

            // create the edge
            let mut e = Edge{from_vertex: self.v, to_vertex: to_vertex.v};
            in_vertex.add_out_edge(e);
        }
        pub fn query(self) {

        }
    }

    /*
    impl<T> Deref for DerefExample<T> {
        type Target = T;

        fn deref<'a>(&'a self) -> &'a T {
            &self.value
        }
    }
     */

    #[derive(Debug)]
    struct Edge {
        from_vertex: *const Box<Vertex>,
        to_vertex: *const Box<Vertex>
    }
}

mod tests {
    use graph::Graph;

    #[test]
    fn test_unsafe_vertex() {
        let mut g = Graph::new();
        let v1 = g.add_vertex();
        assert!(v1.id == 1);

        let v2 = g.add_vertex();
        assert!(v2.id == 2);
    }

    #[test]
    fn test_add_edge() {
        let mut g = Graph::new();
        let mut v1 = g.add_vertex();
        let mut v2 = g.add_vertex();

        v1.add_edge(&mut v2);
    }
}
<commit_msg>consolidating code<commit_after>

pub mod graph {
    use std::collections::HashMap;

    #[derive(Debug)]
    pub struct Graph {
        elements: i64,
        vertices: HashMap<i64, Box<Vertex>>,
    }

    impl Graph {
        pub fn new() -> Box<Graph> {
            let vertices: HashMap<i64, Box<Vertex>> = HashMap::new();
            Box::new(Graph{elements:0, vertices:vertices})
        }

        pub fn add_vertex(&mut self) -> VertexProxy {
            let new_id = self.elements + 1;
            self.elements += 1;
            let mut v = Vertex::new(new_id);

            let ptr: *mut Box<Vertex> = &mut v as *mut Box<Vertex>;

            self.vertices.insert(new_id, v);

            // return the proxy which knows it's own id
            VertexProxy{id:new_id, v: ptr}
        }
    }

    /*
    I'm not sure on this, but it feels reasonable.  a vertex can own it's out_edges.
    this should? make it easier to manage the memory?

    additionally, it should cut down on the number of "things" i have to traverse
    if a vertex has 10k edges (5k in and out 5k out) then doing something like

    g(v).outV()

    should be faster to iterate over

    the cost is a little code complexity but i think that won't be too bad
     */
    #[derive(Debug)]
    struct Vertex {
        id: i64,
        out_edges: Vec<Edge>,
        in_edges: *mut Vec<Edge>,
    }

    impl Vertex {
        pub fn new(id: i64) -> Box<Vertex> {

            // in edges
            let mut edges : Vec<Edge> = Vec::new();
            let edges_ptr : *mut Vec<Edge> = &mut edges;

            let out_edges: Vec<Edge> = Vec::new();
            Box::new(Vertex{id:id, out_edges: out_edges, in_edges:edges_ptr})
        }

        pub fn add_out_edge(&mut self, edge: Edge ) {
            self.out_edges.push(edge)
        }

        pub fn add_in_edge() {

        }

    }

    pub struct VertexProxy {
        pub id: i64,
        v: *mut Box<Vertex>,
    }

    //let i: u32 = 1;
    //// explicit cast
    //let p_imm: *const u32 = &i as *const u32;
    //let mut m: u32 = 2;
    //// implicit coercion
    //let p_mut: *mut u32 = &mut m;
    //
    //unsafe {
    //let ref_imm: &u32 = &*p_imm;
    //let ref_mut: &mut u32 = &mut *p_mut;
    //}

    impl VertexProxy {
        pub fn add_edge(&mut self, to_vertex: &mut VertexProxy) {
            let in_vertex: &mut Box<Vertex>;
            let out_vertex: &mut Box<Vertex>;

            unsafe {
                in_vertex =  &mut *(self.v);
                out_vertex = &mut *(to_vertex.v);
            }

            // create the edge
            let mut e = Edge{from_vertex: self.v, to_vertex: to_vertex.v};
            in_vertex.add_out_edge(e);
        }
        pub fn query(self) {

        }
    }

    /*
    impl<T> Deref for DerefExample<T> {
        type Target = T;

        fn deref<'a>(&'a self) -> &'a T {
            &self.value
        }
    }
     */

    #[derive(Debug)]
    struct Edge {
        from_vertex: *const Box<Vertex>,
        to_vertex: *const Box<Vertex>
    }
}

mod tests {
    use graph::Graph;

    #[test]
    fn test_unsafe_vertex() {
        let mut g = Graph::new();
        let v1 = g.add_vertex();
        assert!(v1.id == 1);

        let v2 = g.add_vertex();
        assert!(v2.id == 2);
    }

    #[test]
    fn test_add_edge() {
        let mut g = Graph::new();
        let mut v1 = g.add_vertex();
        let mut v2 = g.add_vertex();

        v1.add_edge(&mut v2);
    }
}
<|endoftext|>


<commit_before>//! atty is a simple utility that answers one question
//! > is this a tty?
//!
//! usage is just as simple
//!
//! ```
//! if atty::is(atty::Stream::Stdout) {
//!   println!("i'm a tty")
//! }
//! ```
//!
//! ```
//! if atty::isnt(atty::Stream::Stdout) {
//!   println!("i'm not a tty")
//! }
//! ```

extern crate libc;

/// possible stream sources
pub enum Stream {
    Stdout,
    Stderr,
    Stdin
}

/// returns true if this is a tty
#[cfg(unix)]
pub fn is(stream: Stream) -> bool {
    let fd = match stream {
        Stream::Stdout => libc::STDOUT_FILENO,
        Stream::Stderr => libc::STDERR_FILENO,
        Stream::Stdin => libc::STDIN_FILENO
    };
    unsafe { libc::isatty(fd) != 0 }
}

/// returns true if this is a tty
#[cfg(windows)]
pub fn is(stream: Stream) -> bool {
    extern crate kernel32;
    extern crate winapi;

    let handle = match stream {
        Stream::Stdout => winapi::winbase::STD_OUTPUT_HANDLE,
        Stream::Stderr => winapi::winbase::STD_ERROR_HANDLE,
        Stream::Stdin => winapi::winbase::STD_INPUT_HANDLE
    };
    unsafe {
        let handle = kernel32::GetStdHandle(handle);
        let mut out = 0;
        println!("{:#?}", kernel32::GetConsoleMode(handle, &mut out));
        kernel32::GetConsoleMode(handle, &mut out) != 0
    }
}

/// returns true if this is _not_ a tty
pub fn isnt(stream: Stream) -> bool {
    !is(stream)
}

#[cfg(test)]
mod tests {
    use super::{is, Stream};

    #[test]
    fn is_out() {
        assert!(is(Stream::Stdout))
    }

    #[test]
    fn is_err() {
        assert!(is(Stream::Stderr))
    }

    #[test]
    fn is_in() {
        assert!(is(Stream::Stdin))
    }
}
<commit_msg>result and last err for debugging<commit_after>//! atty is a simple utility that answers one question
//! > is this a tty?
//!
//! usage is just as simple
//!
//! ```
//! if atty::is(atty::Stream::Stdout) {
//!   println!("i'm a tty")
//! }
//! ```
//!
//! ```
//! if atty::isnt(atty::Stream::Stdout) {
//!   println!("i'm not a tty")
//! }
//! ```

extern crate libc;

/// possible stream sources
pub enum Stream {
    Stdout,
    Stderr,
    Stdin
}

/// returns true if this is a tty
#[cfg(unix)]
pub fn is(stream: Stream) -> bool {
    let fd = match stream {
        Stream::Stdout => libc::STDOUT_FILENO,
        Stream::Stderr => libc::STDERR_FILENO,
        Stream::Stdin => libc::STDIN_FILENO
    };
    unsafe { libc::isatty(fd) != 0 }
}

/// returns true if this is a tty
#[cfg(windows)]
pub fn is(stream: Stream) -> bool {
    extern crate kernel32;
    extern crate winapi;

    let handle = match stream {
        Stream::Stdout => winapi::winbase::STD_OUTPUT_HANDLE,
        Stream::Stderr => winapi::winbase::STD_ERROR_HANDLE,
        Stream::Stdin => winapi::winbase::STD_INPUT_HANDLE
    };
    unsafe {
        let handle = kernel32::GetStdHandle(handle);
        let mut out = 0;
        println!("result {:#?} last err {:#?}",
        kernel32::GetConsoleMode(handle, &mut out),
    kernel32::GetLastError());
        kernel32::GetConsoleMode(handle, &mut out) != 0
    }
}

/// returns true if this is _not_ a tty
pub fn isnt(stream: Stream) -> bool {
    !is(stream)
}

#[cfg(test)]
mod tests {
    use super::{is, Stream};

    #[test]
    fn is_out() {
        assert!(is(Stream::Stdout))
    }

    #[test]
    fn is_err() {
        assert!(is(Stream::Stderr))
    }

    #[test]
    fn is_in() {
        assert!(is(Stream::Stdin))
    }
}
<|endoftext|>


<commit_before>

pub mod graph {
    use std::collections::HashMap;

    #[derive(Debug)]
    pub struct Graph {
        elements: i64,
        vertices: HashMap<i64, Box<Vertex>>,
    }

    impl Graph {
        pub fn new() -> Box<Graph> {
            let vertices: HashMap<i64, Box<Vertex>> = HashMap::new();
            Box::new(Graph{elements:0, vertices:vertices})
        }

        pub fn add_vertex(&mut self) -> VertexProxy {
            let new_id = self.elements + 1;
            self.elements += 1;
            let mut v = Vertex::new(new_id);

            let ptr: *mut Box<Vertex> = &mut v as *mut Box<Vertex>;

            self.vertices.insert(new_id, v);

            // return the proxy which knows it's own id
            VertexProxy{id:new_id, v: ptr}
        }
        pub fn get(vertex_id:i64) -> Vertex {
        }
    }

    /*
    I'm not sure on this, but it feels reasonable.  a vertex can own it's out_edges.
    this should? make it easier to manage the memory?

    additionally, it should cut down on the number of "things" i have to traverse
    if a vertex has 10k edges (5k in and out 5k out) then doing something like

    g(v).outV()

    should be faster to iterate over

    the cost is a little code complexity but i think that won't be too bad
     */
    #[derive(Debug)]
    pub struct Vertex {
        pub id: i64,
        out_edges: Vec<Edge>,
        in_edges: *mut Vec<Edge>,
    }

    impl Vertex {
        pub fn new(id: i64) -> Box<Vertex> {

            // in edges
            let mut edges : Vec<Edge> = Vec::new();
            let edges_ptr : *mut Vec<Edge> = &mut edges;

            let out_edges: Vec<Edge> = Vec::new();
            Box::new(Vertex{id:id, out_edges: out_edges, in_edges:edges_ptr})
        }

        pub fn add_out_edge(&mut self, edge: Edge ) {
            self.out_edges.push(edge);
        }

        pub fn add_in_edge() {

        }

    }

    pub struct VertexProxy {
        pub id: i64,
        pub v: *mut Box<Vertex>,
    }

    //let i: u32 = 1;
    //// explicit cast
    //let p_imm: *const u32 = &i as *const u32;
    //let mut m: u32 = 2;
    //// implicit coercion
    //let p_mut: *mut u32 = &mut m;
    //
    //unsafe {
    //let ref_imm: &u32 = &*p_imm;
    //let ref_mut: &mut u32 = &mut *p_mut;
    //}

    impl VertexProxy {
        pub fn add_edge(&mut self, to_vertex: &mut VertexProxy) {
            let in_vertex: &mut Box<Vertex>;
            let out_vertex: &mut Box<Vertex>;

            unsafe {
                in_vertex =  &mut *(self.v);
                out_vertex = &mut *(to_vertex.v);
            }

            // create the edge
            let mut e = Edge{from_vertex: self.v, to_vertex: to_vertex.v};
            in_vertex.add_out_edge(e);
        }
        pub fn query(self) {

        }
    }

    /*
    impl<T> Deref for DerefExample<T> {
        type Target = T;

        fn deref<'a>(&'a self) -> &'a T {
            &self.value
        }
    }
     */

    #[derive(Debug)]
    pub struct Edge {
        from_vertex: *const Box<Vertex>,
        to_vertex: *const Box<Vertex>
    }
}

mod tests {
    use graph::{Graph, Vertex};

    #[test]
    fn test_unsafe_vertex() {
        let mut g = Graph::new();
        let v1 = g.add_vertex();
        assert!(v1.id == 1);

        unsafe {
            let vertex: &mut Box<Vertex> = &mut *(v1.v);
            assert!(vertex.id == 1);
        }

        let v2 = g.add_vertex();
        assert!(v2.id == 2);

    }

    #[test]
    fn test_add_edge() {
        let mut g = Graph::new();
        let mut v1 = g.add_vertex();
        let mut v2 = g.add_vertex();

        v1.add_edge(&mut v2);
    }
}
<commit_msg>hashmap as pointers now<commit_after>

pub mod graph {
    use std::collections::HashMap;

    #[derive(Debug)]
    pub struct Graph {
        elements: i64,
        vertices: HashMap<i64, *mut Box<Vertex>>,
    }

    impl Graph {
        pub fn new() -> Box<Graph> {
            let vertices: HashMap<i64, *mut Box<Vertex>> = HashMap::new();
            Box::new(Graph{elements:0, vertices:vertices})
        }

        pub fn add_vertex(&mut self) -> VertexProxy {
            let new_id = self.elements + 1;
            self.elements += 1;

            let mut v = Vertex::new(new_id);

            let ptr: *mut Box<Vertex> = &mut v as *mut Box<Vertex>;

            self.vertices.insert(new_id, ptr);

            // return the proxy which knows it's own id
            VertexProxy{id:new_id, v: ptr}
        }
        pub fn get(vertex_id:i64)  {
        }
    }

    /*
    I'm not sure on this, but it feels reasonable.  a vertex can own it's out_edges.
    this should? make it easier to manage the memory?

    additionally, it should cut down on the number of "things" i have to traverse
    if a vertex has 10k edges (5k in and out 5k out) then doing something like

    g(v).outV()

    should be faster to iterate over

    the cost is a little code complexity but i think that won't be too bad
     */
    #[derive(Debug)]
    pub struct Vertex {
        pub id: i64,
        out_edges: Vec<Edge>,
        in_edges: *mut Vec<Edge>,
    }

    impl Vertex {
        pub fn new(id: i64) -> Box<Vertex> {

            // in edges
            let mut edges : Vec<Edge> = Vec::new();
            let edges_ptr : *mut Vec<Edge> = &mut edges;

            let out_edges: Vec<Edge> = Vec::new();
            Box::new(Vertex{id:id, out_edges: out_edges, in_edges:edges_ptr})
        }

        pub fn add_out_edge(&mut self, edge: Edge ) {
            self.out_edges.push(edge);
        }

        pub fn add_in_edge() {

        }

    }

    pub struct VertexProxy {
        pub id: i64,
        pub v: *mut Box<Vertex>,
    }

    //let i: u32 = 1;
    //// explicit cast
    //let p_imm: *const u32 = &i as *const u32;
    //let mut m: u32 = 2;
    //// implicit coercion
    //let p_mut: *mut u32 = &mut m;
    //
    //unsafe {
    //let ref_imm: &u32 = &*p_imm;
    //let ref_mut: &mut u32 = &mut *p_mut;
    //}

    impl VertexProxy {
        pub fn add_edge(&mut self, to_vertex: &mut VertexProxy) {
            let in_vertex: &mut Box<Vertex>;
            let out_vertex: &mut Box<Vertex>;

            unsafe {
                in_vertex =  &mut *(self.v);
                out_vertex = &mut *(to_vertex.v);
            }

            // create the edge
            let mut e = Edge{from_vertex: self.v, to_vertex: to_vertex.v};
            in_vertex.add_out_edge(e);
        }
        pub fn query(self) {

        }
    }

    /*
    impl<T> Deref for DerefExample<T> {
        type Target = T;

        fn deref<'a>(&'a self) -> &'a T {
            &self.value
        }
    }
     */

    #[derive(Debug)]
    pub struct Edge {
        from_vertex: *const Box<Vertex>,
        to_vertex: *const Box<Vertex>
    }
}

mod tests {
    use graph::{Graph, Vertex};

    #[test]
    fn test_unsafe_vertex() {
        let v = Vertex::new(1);

    }
    #[test]
    fn test_new_vertex() {
        let mut g = Graph::new();
        let v1 = g.add_vertex();
        assert!(v1.id == 1);

        unsafe {
            let vertex: &mut Box<Vertex> = &mut *(v1.v);
            assert!(vertex.id == 1);
        }

        let v2 = g.add_vertex();
        assert!(v2.id == 2);

    }

    #[test]
    fn test_add_edge() {
        let mut g = Graph::new();
        let mut v1 = g.add_vertex();
        let mut v2 = g.add_vertex();

        v1.add_edge(&mut v2);
    }
}
<|endoftext|>