<commit_before>// Copyright 2013 Tommy M. McGuire
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[ link(name = "fashhashmap", vers="1.0") ];
#[ crate_type = "lib" ];

use std::rt::io::Writer;
use std::to_bytes::IterBytes;
use std::vec;
use std::uint;
use std::util;

// Simple Writer/IterBytes based implementation of the DJB hash
// (See http://cr.yp.to/cdb/cdb.txt and http://www.cse.yorku.ca/~oz/hash.html)
struct DJBState {
    hash : u64
}

impl DJBState {
    fn new() -> DJBState { DJBState { hash : 5381u64 } }

    #[inline]
    fn djbhash<T:IterBytes>(t : &T) -> u64 {
        let mut state = DJBState::new();
        t.iter_bytes(true, |b| { state.write(b); true });
        state.flush();
        return state.hash();
    }

    fn hash(&self) -> u64 { self.hash }
}

impl Writer for DJBState {
    #[inline]
    fn write(&mut self, buf : &[u8]) {
        let len = buf.len();
        let mut i = 0;
        while i < len { self.hash = (33u64 * self.hash) ^ buf[i] as u64; i += 1; }
    }
    fn flush(&mut self) { }
}

/* ----------------------------------------------- */

// This is an implementation of the Container, Mutable, Map, and
// MutableMap traits based on the DJB hash and Python's dictionaries.
// See:
//
// * http://stackoverflow.com/questions/327311/how-are-pythons-built-in-dictionaries-implemented
//   (especially the links in the first answer),
//
// * http://www.laurentluce.com/posts/python-dictionary-implementation/
//
// * http://pybites.blogspot.com/2008/10/pure-python-dictionary-implementation.html

static PERTURB_SHIFT : uint = 5;

enum Entry<K,V> {
    Empty,                      // This slot is empty
    Full(K,V),                  // This slot is holding a key and value
    Ghost(K),                   // This slot once held key k
}

impl<K : Eq, V> Entry<K,V> {
    fn is_empty(&self) -> bool { match *self { Empty => true, _ => false } }
    fn is_full(&self)  -> bool { match *self { Full(*) => true, _ => false } }
    fn is_ghost(&self) -> bool { match *self { Ghost(*) => true, _ => false } }

    #[inline]
    fn matches(&self, key : &K) -> bool {
        match *self {
            Empty                        => true,
            Full(ref k,_) | Ghost(ref k) => k == key,
        }
    }
}

pub struct HashMap<K,V> {
    table      : ~[Entry<K,V>],
    capacity   : uint,
    mask       : u64,
    length     : uint,
    ghosts     : uint,
}

impl<K : Eq + IterBytes,V> HashMap<K,V> {
    pub fn new() -> HashMap<K,V> { HashMap::with_capacity(8) }

    pub fn with_capacity(sz : uint) -> HashMap<K,V> {
        let capacity = uint::next_power_of_two(sz);
        HashMap {
            table : vec::from_fn(capacity, |_| Empty),
            capacity : capacity,
            mask : (capacity as u64) - 1,
            length : 0,
            ghosts : 0,
        }
    }

    pub fn capacity(&self) -> uint { self.capacity }

    // This algorithm gleefully stolen from Python
    #[inline]
    fn probe(&self, key : &K) -> uint {
        let mut hash = DJBState::djbhash(key);
        let mut free = None;
        let mut i = hash & self.mask;
        while !self.table[i].matches(key) {
            if free.is_none() && self.table[i].is_ghost() { free = Some(i); }
            i = ((5 * i) + 1 + hash) & self.mask;
            hash = hash >> PERTURB_SHIFT;
        }
        if self.table[i].is_full() || free.is_none() {
            i as uint
        } else {
            free.unwrap() as uint
        }
    }

    #[inline]
    fn do_expand(&mut self, new_capacity : uint) {
        let mut new_tbl = HashMap::with_capacity( new_capacity );
        for elt in self.table.mut_iter() {
            match util::replace(elt, Empty) {
                Full(k,v)        => { new_tbl.insert(k,v); },
                Empty | Ghost(_) => { },
            }
        }
        // Copy new table's elements into self.  Note: attempting
        // to do this more directly causes: "use of partially moved
        // value"
        let cap = new_tbl.capacity;
        let mask = new_tbl.mask;
        let len = new_tbl.length;
        let ghosts = new_tbl.ghosts;
        self.table = new_tbl.table;
        self.capacity = cap;
        self.mask = mask;
        self.length = len;
        self.ghosts = ghosts;
    }

    #[inline]
    fn expand(&mut self) {
        if self.length * 3 > self.capacity * 2 {
            // Expand table if live entries nearing capacity
            self.do_expand( self.capacity * 2 );
        } else if (self.length + self.ghosts) * 3 >= self.capacity * 2 {
            // Rehash to flush out excess ghosts
            self.do_expand( self.capacity );
        }
    }
}

impl<K,V> Container for HashMap<K,V> {
    fn len(&self) -> uint { self.length }
}

impl<K,V> Mutable for HashMap<K,V> {
    fn clear(&mut self) {
        for elt in self.table.mut_iter() { *elt = Empty; }
        self.length = 0;
        self.ghosts = 0;
    }
}

impl<K : Eq + IterBytes,V> Map<K,V> for HashMap<K,V> {
    fn find<'a>(&'a self, key: &K) -> Option<&'a V> {
        let i = self.probe(key);
        match self.table[i] {
            Empty | Ghost(_) => None,
            Full(_, ref val) => Some(val),
        }
    }
}

impl<K : Eq + IterBytes,V> MutableMap<K,V> for HashMap<K,V> {

    fn swap(&mut self, key: K, value: V) -> Option<V> {
        self.expand();
        let i = self.probe(&key);
        match self.table[i] {
            Empty => {
                self.table[i] = Full(key,value);
                self.length += 1;
                None
            },
            Ghost(_) => {
                self.table[i] = Full(key,value);
                self.length += 1;
                self.ghosts -= 1;
                None
            },
            Full(_,ref mut v) => {
                Some( util::replace(v, value) )
            },
        }
    }

    fn pop(&mut self, key: &K) -> Option<V> {
        self.expand();
        let i = self.probe(key);
        let (result,replacement) = match util::replace(&mut self.table[i], Empty) {
            Empty     => (None,Empty),
            Ghost(k)  => (None,Ghost(k)),
            Full(k,v) => {
                self.length -= 1;
                self.ghosts += 1;
                (Some(v),Ghost(k))
            },
        };
        self.table[i] = replacement;
        result
    }

    fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> {
        let i = self.probe(key);
        match self.table[i] {
            Empty | Ghost(_)  => None,
            Full(_,ref mut val) => Some(val),
        }
    }
}

/* ----------------------------------------------- */

pub struct HashSet<T> {
    priv map : HashMap<T,()>
}

impl<T : Eq + IterBytes> HashSet<T> {
    pub fn new() -> HashSet<T> { HashSet { map : HashMap::new() } }
}

impl<T> Container for HashSet<T> {
    fn len(&self) -> uint { self.map.len() }
}

impl<T> Mutable for HashSet<T> {
    fn clear(&mut self) { self.map.clear() }
}

impl<T : Eq + IterBytes> Set<T> for HashSet<T> {
    fn contains(&self, elt : &T) -> bool { self.map.contains_key(elt) }

    fn is_disjoint(&self, other : &HashSet<T>) -> bool {
        for elt in self.map.table.iter() {
            match *elt {
                Full(ref k,_) => {
                    if other.contains(k) { return false; }
                },
                _ => { },
            }
        }
        return true;
    }

    fn is_subset(&self, other : &HashSet<T>) -> bool {
        for elt in self.map.table.iter() {
            match *elt {
                Full(ref k,_) => {
                    if !other.contains(k) { return false; }
                },
                _ => { },
            }
        }
        return true;
    }

    fn is_superset(&self, other : &HashSet<T>) -> bool {
        other.is_subset(self)
    }
}

impl<T : Eq + IterBytes> MutableSet<T> for HashSet<T> {
    fn insert(&mut self, value: T) -> bool {
        self.map.insert(value,())
    }

    fn remove(&mut self, value: &T) -> bool {
        self.map.remove(value)
    }
}

/* ----------------------------------------------- */

#[cfg(test)]
mod tests {
    extern mod extra;

    use super::*;

    #[test]
    fn test_empty() {
        let m : HashMap<uint,uint> = HashMap::new();
        assert_eq!(m.len(), 0);
        assert_eq!(m.capacity(), 8);
        assert_eq!(m.find(&1), None);
    }

    #[test]
    fn test_one() {
        let mut m : HashMap<uint,uint> = HashMap::new();
        assert_eq!(m.len(), 0);
        assert!(m.insert(1,400));
        assert_eq!(m.len(), 1);
        assert_eq!(m.capacity(), 8);
        match m.find(&1) {
            Some(y) => assert_eq!(*y,400),
            None => fail!("failure!")
        }
        match m.find_mut(&1) {
            Some(y) => *y = 500,
            _ => fail!("failed!")
        }
        match m.find(&1) {
            Some(y) => assert_eq!(*y,500),
            None => fail!("failure again!")
        }
        match m.pop(&1) {
            Some(y) => assert_eq!(y,500),
            None => fail!("oh, noes!")
        }
        assert_eq!(m.len(), 0);
    }

    #[test]
    fn test_eight() {
        let mut m : HashMap<uint,uint> = HashMap::new();
        let v = [1,3,5,7,9,11,13,15];
        for i in v.iter() {
            assert!(m.insert(*i,100 * *i));
        }
        assert_eq!(m.len(),8);
        assert_eq!(m.capacity(),16);
        assert!( !m.insert(3, 12000) );
    }

    #[bench]
    fn hash_bench_siphash(b: &mut extra::test::BenchHarness) {
        let s = "abcdefghijklmnopqrstuvwxyz";
        do b.iter { s.hash(); }
    }

    #[bench]
    fn hashmap_bench_stdlib(b: &mut extra::test::BenchHarness) {
        let list = ["abashed", "acrid", "dachshund's", "hackle", "zigzagging"];
        do b.iter {
            let mut m = std::hashmap::HashMap::new();
            for w in list.iter() { m.insert(w, 27); }
        }
    }

    #[bench]
    fn hash_bench_djbhash(b: &mut extra::test::BenchHarness) {
        let s = "abcdefghijklmnopqrstuvwxyz";
        do b.iter { DJBState::djbhash(&s); }
    }

    #[bench]
    fn hashmap_bench_fasthashmap(b: &mut extra::test::BenchHarness) {
        let list = ["abashed", "acrid", "dachshund's", "hackle", "zigzagging"];
        do b.iter {
            let mut m = HashMap::new();
            for w in list.iter() { m.insert(w, 27); }
        }
    }
}
<commit_msg>update for Rust 0.9<commit_after>// Copyright 2013 Tommy M. McGuire
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[ crate_id = "fasthashmap#1.1" ];
#[ crate_type = "lib" ];

use std::io::Writer;
use std::to_bytes::IterBytes;
use std::vec;
use std::uint;
use std::util;

// Simple Writer/IterBytes based implementation of the DJB hash
// (See http://cr.yp.to/cdb/cdb.txt and http://www.cse.yorku.ca/~oz/hash.html)
struct DJBState {
    hash : u64
}

impl DJBState {
    fn new() -> DJBState { DJBState { hash : 5381u64 } }

    #[inline]
    fn djbhash<T:IterBytes>(t : &T) -> u64 {
        let mut state = DJBState::new();
        t.iter_bytes(true, |b| { state.write(b); true });
        state.flush();
        return state.hash();
    }

    fn hash(&self) -> u64 { self.hash }
}

impl Writer for DJBState {
    #[inline]
    fn write(&mut self, buf : &[u8]) {
        let len = buf.len();
        let mut i = 0;
        while i < len { self.hash = (33u64 * self.hash) ^ buf[i] as u64; i += 1; }
    }
    fn flush(&mut self) { }
}

/* ----------------------------------------------- */

// This is an implementation of the Container, Mutable, Map, and
// MutableMap traits based on the DJB hash and Python's dictionaries.
// See:
//
// * http://stackoverflow.com/questions/327311/how-are-pythons-built-in-dictionaries-implemented
//   (especially the links in the first answer),
//
// * http://www.laurentluce.com/posts/python-dictionary-implementation/
//
// * http://pybites.blogspot.com/2008/10/pure-python-dictionary-implementation.html

static PERTURB_SHIFT : uint = 5;

enum Entry<K,V> {
    Empty,                      // This slot is empty
    Full(K,V),                  // This slot is holding a key and value
    Ghost(K),                   // This slot once held key k
}

impl<K : Eq, V> Entry<K,V> {
    #[allow(dead_code)]
    fn is_empty(&self) -> bool { match *self { Empty => true,    _ => false } }
    fn is_full(&self)  -> bool { match *self { Full(..) => true,  _ => false } }
    fn is_ghost(&self) -> bool { match *self { Ghost(..) => true, _ => false } }

    #[inline]
    fn matches(&self, key : &K) -> bool {
        match *self {
            Empty                        => true,
            Full(ref k,_) | Ghost(ref k) => k == key,
        }
    }
}

pub struct HashMap<K,V> {
    table      : ~[Entry<K,V>],
    capacity   : uint,
    mask       : u64,
    length     : uint,
    ghosts     : uint,
}

impl<K : Eq + IterBytes,V> HashMap<K,V> {
    pub fn new() -> HashMap<K,V> { HashMap::with_capacity(8) }

    pub fn with_capacity(sz : uint) -> HashMap<K,V> {
        let capacity = uint::next_power_of_two(sz);
        HashMap {
            table : vec::from_fn(capacity, |_| Empty),
            capacity : capacity,
            mask : (capacity as u64) - 1,
            length : 0,
            ghosts : 0,
        }
    }

    pub fn capacity(&self) -> uint { self.capacity }

    // This algorithm gleefully stolen from Python
    #[inline]
    fn probe(&self, key : &K) -> uint {
        let mut shifted_hash = DJBState::djbhash(key);
        let mut free = None;
        let mut i = shifted_hash & self.mask;
        while !self.table[i].matches(key) {
            if free.is_none() && self.table[i].is_ghost() { free = Some(i); }
            i = ((5 * i) + 1 + shifted_hash) & self.mask;
            shifted_hash = shifted_hash >> PERTURB_SHIFT;
        }
        if self.table[i].is_full() || free.is_none() {
            i as uint
        } else {
            free.unwrap() as uint
        }
    }

    #[inline]
    fn do_expand(&mut self, new_capacity : uint) {
        let mut new_tbl = HashMap::with_capacity( new_capacity );
        for elt in self.table.mut_iter() {
            match util::replace(elt, Empty) {
                Full(k,v)        => { new_tbl.insert(k,v); },
                Empty | Ghost(_) => { },
            }
        }
        // Copy new table's elements into self.  Note: attempting
        // to do this more directly causes: "use of partially moved
        // value"
        let cap = new_tbl.capacity;
        let mask = new_tbl.mask;
        let len = new_tbl.length;
        let ghosts = new_tbl.ghosts;
        self.table = new_tbl.table;
        self.capacity = cap;
        self.mask = mask;
        self.length = len;
        self.ghosts = ghosts;
    }

    #[inline]
    fn expand(&mut self) {
        if self.length * 3 > self.capacity * 2 {
            // Expand table if live entries nearing capacity
            self.do_expand( self.capacity * 2 );
        } else if (self.length + self.ghosts) * 3 >= self.capacity * 2 {
            // Rehash to flush out excess ghosts
            self.do_expand( self.capacity );
        }
    }
}

impl<K,V> Container for HashMap<K,V> {
    fn len(&self) -> uint { self.length }
}

impl<K,V> Mutable for HashMap<K,V> {
    fn clear(&mut self) {
        for elt in self.table.mut_iter() { *elt = Empty; }
        self.length = 0;
        self.ghosts = 0;
    }
}

impl<K : Eq + IterBytes,V> Map<K,V> for HashMap<K,V> {
    fn find<'a>(&'a self, key: &K) -> Option<&'a V> {
        let i = self.probe(key);
        match self.table[i] {
            Empty | Ghost(_) => None,
            Full(_, ref val) => Some(val),
        }
    }
}

impl<K : Eq + IterBytes,V> MutableMap<K,V> for HashMap<K,V> {

    fn swap(&mut self, key: K, value: V) -> Option<V> {
        self.expand();
        let i = self.probe(&key);
        match self.table[i] {
            Empty => {
                self.table[i] = Full(key,value);
                self.length += 1;
                None
            },
            Ghost(_) => {
                self.table[i] = Full(key,value);
                self.length += 1;
                self.ghosts -= 1;
                None
            },
            Full(_,ref mut v) => {
                Some( util::replace(v, value) )
            },
        }
    }

    fn pop(&mut self, key: &K) -> Option<V> {
        self.expand();
        let i = self.probe(key);
        let (result,replacement) = match util::replace(&mut self.table[i], Empty) {
            Empty     => (None,Empty),
            Ghost(k)  => (None,Ghost(k)),
            Full(k,v) => {
                self.length -= 1;
                self.ghosts += 1;
                (Some(v),Ghost(k))
            },
        };
        self.table[i] = replacement;
        result
    }

    fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> {
        let i = self.probe(key);
        match self.table[i] {
            Empty | Ghost(_)    => None,
            Full(_,ref mut val) => Some(val),
        }
    }
}

/* ----------------------------------------------- */

pub struct HashSet<T> {
    priv map : HashMap<T,()>
}

impl<T : Eq + IterBytes> HashSet<T> {
    pub fn new() -> HashSet<T> { HashSet { map : HashMap::new() } }
}

impl<T> Container for HashSet<T> {
    fn len(&self) -> uint { self.map.len() }
}

impl<T> Mutable for HashSet<T> {
    fn clear(&mut self) { self.map.clear() }
}

impl<T : Eq + IterBytes> Set<T> for HashSet<T> {
    fn contains(&self, elt : &T) -> bool { self.map.contains_key(elt) }

    fn is_disjoint(&self, other : &HashSet<T>) -> bool {
        for elt in self.map.table.iter() {
            match *elt {
                Full(ref k,_) => { if other.contains(k) { return false; } },
                _             => { },
            }
        }
        return true;
    }

    fn is_subset(&self, other : &HashSet<T>) -> bool {
        for elt in self.map.table.iter() {
            match *elt {
                Full(ref k,_) => { if !other.contains(k) { return false; } },
                _             => { },
            }
        }
        return true;
    }

    fn is_superset(&self, other : &HashSet<T>) -> bool { other.is_subset(self) }
}

impl<T : Eq + IterBytes> MutableSet<T> for HashSet<T> {
    fn insert(&mut self, value: T)  -> bool { self.map.insert(value,()) }
    fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
}

/* ----------------------------------------------- */

#[cfg(test)]
mod tests {
    extern mod extra;

    use std;
    use std::io::buffered::BufferedReader;
    use super::{DJBState,HashMap};

    fn get_words() -> ~[~str] {
        let path = std::path::Path::new("/usr/share/dict/words");
        let mut bufferedFile = BufferedReader::new( std::io::File::open(&path) );
        bufferedFile.lines().collect()
    }

    #[test]
    fn test_empty() {
        let m : HashMap<uint,uint> = HashMap::new();
        assert_eq!(m.len(), 0);
        assert_eq!(m.capacity(), 8);
        assert_eq!(m.find(&1), None);
    }

    #[test]
    fn test_one() {
        let mut m : HashMap<uint,uint> = HashMap::new();
        assert_eq!(m.len(), 0);
        assert!(m.insert(1,400));
        assert_eq!(m.len(), 1);
        assert_eq!(m.capacity(), 8);
        match m.find(&1) {
            Some(y) => assert_eq!(*y,400),
            None => fail!("failure!")
        }
        match m.find_mut(&1) {
            Some(y) => *y = 500,
            _ => fail!("failed!")
        }
        match m.find(&1) {
            Some(y) => assert_eq!(*y,500),
            None => fail!("failure again!")
        }
        match m.pop(&1) {
            Some(y) => assert_eq!(y,500),
            None => fail!("oh, noes!")
        }
        assert_eq!(m.len(), 0);
    }

    #[test]
    fn test_eight() {
        let mut m : HashMap<uint,uint> = HashMap::new();
        let v = [1,3,5,7,9,11,13,15];
        for i in v.iter() {
            assert!(m.insert(*i,100 * *i));
        }
        assert_eq!(m.len(),8);
        assert_eq!(m.capacity(),16);
        assert!( !m.insert(3, 12000) );
    }

    #[bench]
    fn hash_bench_siphash(b: &mut extra::test::BenchHarness) {
        let s = "abcdefghijklmnopqrstuvwxyz";
        b.iter( || { s.hash(); } );
    }

    #[bench]
    fn hashmap_bench_stdlib(b: &mut extra::test::BenchHarness) {
        let list = ["abashed", "acrid", "dachshund's", "hackle", "zigzagging"];
        b.iter( || {
            let mut m = std::hashmap::HashMap::new();
            for w in list.iter() { m.insert(w, 27); }
        } );
    }

    #[bench]
    fn hash_bench_djbhash(b: &mut extra::test::BenchHarness) {
        let s = "abcdefghijklmnopqrstuvwxyz";
        b.iter( || { DJBState::djbhash(&s); } );
    }

    #[bench]
    fn hashmap_bench_fasthashmap(b: &mut extra::test::BenchHarness) {
        let list = ["abashed", "acrid", "dachshund's", "hackle", "zigzagging"];
        b.iter( || {
            let mut m = HashMap::new();
            for w in list.iter() { m.insert(w, 27); }
        } );
    }

    #[bench]
    fn big_hashmap_bench_fasthashmap(b: &mut extra::test::BenchHarness) {
        let words = get_words();
        b.iter( || {
            let mut m = HashMap::new(); // with_capacity(2 * words.len());
            for w in words.iter() { m.insert(w, 27); }
        } );
    }

    #[bench]
    fn big_hashmap_bench_siphashmap(b: &mut extra::test::BenchHarness) {
        let words = get_words();
        b.iter( || {
            let mut m = std::hashmap::HashMap::new(); // with_capacity(2 * words.len());
            for w in words.iter() { m.insert(w, 27); }
        } );
    }

}
<|endoftext|>


<commit_before>use std::process::Command;

use cmd::call_on_path;
use error::FatalError;

pub fn status() -> Result<bool, FatalError> {
    let output = try!(Command::new("git")
        .arg("diff")
        .arg("--exit-code")
        .output()
        .map_err(FatalError::from));
    Ok(output.status.success())
}

pub fn commit_all(dir: &str, msg: &str, sign: bool, dry_run: bool) -> Result<bool, FatalError> {
    call_on_path(vec!["git", "commit", if sign { "-S" } else { "" }, "-am", msg],
                 dir,
                 dry_run)
}

pub fn remote_get_url(remote: &str) -> Result<String, FatalError> {
    let output = try!(Command::new("git")
        .arg("remote")
        .arg("get-url")
        .arg(remote)
        .output()
        .map_err(FatalError::from));
    String::from_utf8(output.stdout).map_err(FatalError::from)
}

pub fn init(dir: &str, dry_run: bool) -> Result<bool, FatalError> {
    call_on_path(vec!["git", "init"], dir, dry_run)
}

pub fn add_all(dir: &str, dry_run: bool) -> Result<bool, FatalError> {
    call_on_path(vec!["git", "add", "."], dir, dry_run)
}

pub fn force_push(dir: &str,
                  remote: &str,
                  refspec: &str,
                  dry_run: bool)
                  -> Result<bool, FatalError> {
    call_on_path(vec!["git", "push", "-f", remote, refspec], dir, dry_run)
}
<commit_msg>Reorder commit_all into main.rs call order. (#10)<commit_after>use std::process::Command;

use cmd::call_on_path;
use error::FatalError;

pub fn status() -> Result<bool, FatalError> {
    let output = try!(Command::new("git")
        .arg("diff")
        .arg("--exit-code")
        .output()
        .map_err(FatalError::from));
    Ok(output.status.success())
}

pub fn remote_get_url(remote: &str) -> Result<String, FatalError> {
    let output = try!(Command::new("git")
        .arg("remote")
        .arg("get-url")
        .arg(remote)
        .output()
        .map_err(FatalError::from));
    String::from_utf8(output.stdout).map_err(FatalError::from)
}

pub fn init(dir: &str, dry_run: bool) -> Result<bool, FatalError> {
    call_on_path(vec!["git", "init"], dir, dry_run)
}

pub fn add_all(dir: &str, dry_run: bool) -> Result<bool, FatalError> {
    call_on_path(vec!["git", "add", "."], dir, dry_run)
}

pub fn commit_all(dir: &str, msg: &str, sign: bool, dry_run: bool) -> Result<bool, FatalError> {
    call_on_path(vec!["git", "commit", if sign { "-S" } else { "" }, "-am", msg],
                 dir,
                 dry_run)
}

pub fn force_push(dir: &str,
                  remote: &str,
                  refspec: &str,
                  dry_run: bool)
                  -> Result<bool, FatalError> {
    call_on_path(vec!["git", "push", "-f", remote, refspec], dir, dry_run)
}
<|endoftext|>


<commit_before>use std::cmp::max;
use image::Pixel;

pub struct HSL {
    pub h: f64,
    pub s: f64,
    pub l: f64,
}

impl HSL {
    pub fn from_pixel<P>(pixel: &P) -> HSL
        where P: Pixel<Subpixel = u8>
    {
        let pixel = pixel.clone();
        let rgb = pixel.to_rgb();
        let rgb = rgb.channels();
        let (r, g, b) = (rgb[0] as f64, rgb[1] as f64, rgb[2] as f64);

        let max = *rgb.iter().max().unwrap_or(&255) as f64;
        let min = *rgb.iter().min().unwrap_or(&0) as f64;

        let h: f64;
        let l: f64 = (max + min) as f64 / 2.0f64;
        let s: f64;
        if max == min {
            h = 0;
            s = 0;
        } else {
            let d = max - min;
            s = if l > 0.5 {
                d / (2 - max - min)
            } else {
                d / (max + min)
            };

            h = match max {
                x if x == r => (g - b) / d +
                               (if g < b { 6 } else { 0 }),
                x if x == g => (b - r) / d + 2,
                _ => (r - g) / d + 4,
            } / 6;
        }

        HSL { h: h as f64, s: s as f64, l: l }
    }
}

#[cfg(test)]
mod test {
    macro_rules! test_rgb_to_hsl {
        ($rgb:expr => ($h:expr, $s:expr, $l:expr)) => {
            {
                use std::f64::EPSILON;
                let hsl = HSL::from_pixel(&$rgb);
                assert!(
                    $h - hsl.h <= EPSILON,
                    "Converting {:?} to HSL: H differs too much. Expected {}, got {}.",
                    $rgb, $h, hsl.h
                );
                assert!(
                    $s - hsl.s <= EPSILON,
                    "Converting {:?} to HSL: S differs too much. Expected {}, got {}.",
                    $rgb, $s, hsl.s
                );
                assert!(
                    $l - hsl.l <= EPSILON,
                    "Converting {:?} to HSL: L differs too much. Expected {}, got {}.", $rgb, $l, hsl.l
                );
            }
        };
    }

    use image::{Rgb, Pixel};
    use super::HSL;

    #[test]
    fn rgb_to_hsl() {
        test_rgb_to_hsl!(
            Rgb::from_channels(18u8, 35u8, 67u8, 0u8)
            => (219.0f64, 0.58f64, 0.17f64)
        )
    }
}
<commit_msg>RGB to HSL<commit_after>use std::cmp;
use image::Pixel;

pub struct HSL {
    pub h: f64, // 0-360 Degree
    pub s: f64, // 0-100 Percent
    pub l: f64, // 0-100 Percent
}

impl HSL {
    /// Convert Pixel value to HSL
    ///
    /// Algorithm from [go-color] by Brandon Thomson <bt@brandonthomson.com>.
    ///
    /// [go-color]: https://github.com/bthomson/go-color
    pub fn from_pixel<P>(pixel: &P) -> HSL
        where P: Pixel<Subpixel = u8>
    {
        let mut h: f64;
        let mut s: f64;
        let mut l: f64;

        let pixel = pixel.clone();
        let rgb = pixel.to_rgb();
        let rgb = rgb.channels();
        let (r, g, b) = (rgb[0], rgb[1], rgb[2]);

        let max = cmp::max(cmp::max(r, g), b);
        let min = cmp::min(cmp::min(r, g), b);

        // Normalized RGB: Divide everything by 255 to get percentages of colors.
        let (r, g, b) = (r as f64 / 255_f64, g as f64 / 255_f64, b as f64 / 255_f64);
        let (min, max) = (min as f64 / 255_f64, max as f64 / 255_f64);

        // Luminosity is the average of the max and min rgb color intensities.
        l = (max + min) / 2_f64;

        // Saturation
        let delta: f64 = max - min;
        if delta == 0_f64 {
    		// it's gray
            return HSL { h: 0_f64, s: 0_f64, l: l};
        }

        // it's not gray
        if l < 0.5_f64 {
            s = delta / (max + min);
        } else {
            s = delta / (2_f64 - max - min);
        }

        // Hue
        let r2 = (((max - r) / 6_f64) + (delta / 2_f64)) / delta;
        let g2 = (((max - g) / 6_f64) + (delta / 2_f64)) / delta;
        let b2 = (((max - b) / 6_f64) + (delta / 2_f64)) / delta;

        h = match max {
            x if x == r => b2 - g2,
            x if x == g => (1_f64 / 3_f64) + r2 - b2,
            _ => (2_f64 / 3_f64) + g2 - r2,
        };

        // Fix wraparounds
        if h < 0 as f64 {
            h += 1_f64;
        } else if h > 1 as f64 {
            h -= 1_f64;
        }

        HSL { h: h * 360_f64, s: s, l: l }
    }
}

#[cfg(test)]
mod test {
    macro_rules! test_rgb_to_hsl {
        (($r:expr, $g:expr, $b:expr) => ($h:expr, $s:expr, $l:expr)) => {
            {
                // Round gracefully to half a percent
                const EPSILON: f64 = 0.05;
                // Round gracefully to half a degree
                const EPSILON_DEGREE: f64 = 0.5;

                let rgb = Rgb::from_channels($r as u8, $g as u8, $b as u8, 0_u8);
                let hsl = HSL::from_pixel(&rgb);

                assert!(
                    $h - hsl.h <= EPSILON_DEGREE,
                    "Converting {:?} to HSL: H differs too much. Expected {}, got {}.",
                        rgb, $h, hsl.h
                );
                assert!(
                    $s - hsl.s <= EPSILON,
                    "Converting {:?} to HSL: S differs too much. Expected {}, got {}.",
                        rgb, $s, hsl.s
                );
                assert!(
                    $l - hsl.l <= EPSILON,
                    "Converting {:?} to HSL: L differs too much. Expected {}, got {}.",
                        rgb, $l, hsl.l
                );
            }
        };
    }

    use image::{Rgb, Pixel};
    use super::HSL;

    #[test]
    fn rgb_to_hsl() {
        // black
        test_rgb_to_hsl!( (0, 0, 0) => (0_f64, 0_f64, 0_f64) );

        // white
        test_rgb_to_hsl!( (255, 255, 255) => (0_f64, 0_f64, 1_f64) );

        // http://rgb.to/rgb/18,35,67
        test_rgb_to_hsl!( (18, 35, 67) => (219_f64, 0.58_f64, 0.17_f64) );

        // http://rgb.to/hex/93c6cd
        test_rgb_to_hsl!( (147, 198, 205) => (187_f64, 0.37_f64, 0.69_f64) );

        // http://rgb.to/hex/bada55
        test_rgb_to_hsl!( (186, 218, 85) => (74_f64, 0.64_f64, 0.59_f64) );

        // http://rgb.to/hex/ff0
        test_rgb_to_hsl!( (255, 255, 0) => (60_f64, 1_f64, 0.5_f64) );

        // http://rgb.to/rgb/198,250,172
        test_rgb_to_hsl!( (198, 250, 172) => (100_f64, 0.89_f64, 0.83_f64) );

        // http://rgb.to/hex/faadc7
        test_rgb_to_hsl!( (250, 173, 199) => (340_f64, 0.89_f64, 0.83_f64) );
    }
}
<|endoftext|>


<commit_before>pub use amq_protocol::protocol::BasicProperties;

use amq_protocol::{protocol::AMQPClass, frame::AMQPFrame};
use log::trace;

use std::collections::{HashMap, HashSet, VecDeque};

use crate::api::{Answer, ChannelState};
use crate::queue::*;

#[derive(Debug)]
pub struct Channel {
  pub id:             u16,
  pub state:          ChannelState,
  pub frame_queue:    VecDeque<AMQPFrame>,
  pub send_flow:      bool,
  pub receive_flow:   bool,
  pub queues:         HashMap<String, Queue>,
  pub prefetch_size:  u32,
  pub prefetch_count: u16,
  pub awaiting:       VecDeque<Answer>,
  pub confirm:        bool,
  pub message_count:  u64,
  pub acked:          HashSet<u64>,
  pub nacked:         HashSet<u64>,
  pub unacked:        HashSet<u64>,
}

impl Channel {
  pub fn new(channel_id: u16) -> Channel {
    Channel {
      id:             channel_id,
      state:          ChannelState::Initial,
      frame_queue:    VecDeque::new(),
      send_flow:      true,
      receive_flow:   true,
      queues:         HashMap::new(),
      prefetch_size:  0,
      prefetch_count: 0,
      awaiting:       VecDeque::new(),
      confirm:        false,
      message_count:  0,
      acked:          HashSet::new(),
      nacked:         HashSet::new(),
      unacked:        HashSet::new(),
    }
  }

  pub fn global() -> Channel {
    Channel::new(0)
  }

  pub fn received_method(&mut self, m: AMQPClass) {
    trace!("channel[{}] received {:?}", self.id, m);
    //FIXME: handle method here instead of queuing
    self.frame_queue.push_back(AMQPFrame::Method(self.id,m));
  }

  pub fn is_connected(&self) -> bool {
    self.state != ChannelState::Initial && self.state != ChannelState::Closed && self.state != ChannelState::Error
  }
}
<commit_msg>async: drop dead code<commit_after>pub use amq_protocol::protocol::BasicProperties;

use std::collections::{HashMap, HashSet, VecDeque};

use crate::api::{Answer, ChannelState};
use crate::queue::*;

#[derive(Debug)]
pub struct Channel {
  pub id:             u16,
  pub state:          ChannelState,
  pub send_flow:      bool,
  pub receive_flow:   bool,
  pub queues:         HashMap<String, Queue>,
  pub prefetch_size:  u32,
  pub prefetch_count: u16,
  pub awaiting:       VecDeque<Answer>,
  pub confirm:        bool,
  pub message_count:  u64,
  pub acked:          HashSet<u64>,
  pub nacked:         HashSet<u64>,
  pub unacked:        HashSet<u64>,
}

impl Channel {
  pub fn new(channel_id: u16) -> Channel {
    Channel {
      id:             channel_id,
      state:          ChannelState::Initial,
      send_flow:      true,
      receive_flow:   true,
      queues:         HashMap::new(),
      prefetch_size:  0,
      prefetch_count: 0,
      awaiting:       VecDeque::new(),
      confirm:        false,
      message_count:  0,
      acked:          HashSet::new(),
      nacked:         HashSet::new(),
      unacked:        HashSet::new(),
    }
  }

  pub fn global() -> Channel {
    Channel::new(0)
  }

  pub fn is_connected(&self) -> bool {
    self.state != ChannelState::Initial && self.state != ChannelState::Closed && self.state != ChannelState::Error
  }
}
<|endoftext|>


<commit_before>// test1.rs
// This is a test for the following sections:
// - Variables
// - Functions

// Mary is buying apples. One apple usually costs 2 dollars, but if you buy
// more than 40 at once, each apple only costs 1! Write a function that calculates
// the price of an order of apples given the order amount. No hints this time!

// Put your function here!
// fn ..... {

// Don't modify this function!
#[test]
fn verify_test() {
    let price1 = calculate_price(55);
    let price2 = calculate_price(40);

    assert_eq!(55, price1);
    assert_eq!(80, price2);
}
<commit_msg>Auto merge of #225 - ssweeny:fix/test1-wording, r=fmoko<commit_after>// test1.rs
// This is a test for the following sections:
// - Variables
// - Functions

// Mary is buying apples. One apple usually costs 2 dollars, but if you buy
// 40 or more at once, each apple only costs 1! Write a function that calculates
// the price of an order of apples given the order amount. No hints this time!

// Put your function here!
// fn ..... {

// Don't modify this function!
#[test]
fn verify_test() {
    let price1 = calculate_price(55);
    let price2 = calculate_price(40);

    assert_eq!(55, price1);
    assert_eq!(80, price2);
}
<|endoftext|>


<commit_before>// Copyright 2013-2015 Simon Sapin.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Parser and serializer for the [`application/x-www-form-urlencoded` format](
//! http://url.spec.whatwg.org/#application/x-www-form-urlencoded),
//! as used by HTML forms.
//!
//! Converts between a string (such as an URL’s query string)
//! and a sequence of (name, value) pairs.

use std::borrow::Borrow;
use std::ascii::AsciiExt;
use encoding::EncodingOverride;
use percent_encoding::{percent_encode_to, percent_decode, FORM_URLENCODED_ENCODE_SET};

/// Convert a byte string in the `application/x-www-form-urlencoded` format
/// into a vector of (name, value) pairs.
///
/// Use `parse(input.as_bytes())` to parse a `&str` string.
#[inline]
pub fn parse(input: &[u8]) -> Vec<(String, String)> {
    parse_internal(input, EncodingOverride::utf8(), false).unwrap()
}

/// Convert a byte string in the `application/x-www-form-urlencoded` format
/// into a vector of (name, value) pairs.
///
/// Use `parse(input.as_bytes())` to parse a `&str` string.
///
/// This function is only available if the `query_encoding` Cargo feature is enabled.
///
/// Arguments:
///
/// * `encoding_override`: The character encoding each name and values is decoded as
///    after percent-decoding. Defaults to UTF-8.
/// * `use_charset`: The *use _charset_ flag*. If in doubt, set to `false`.
#[cfg(feature = "query_encoding")]
#[inline]
pub fn parse_with_encoding(input: &[u8], encoding_override: Option<::encoding::EncodingRef>,
                           use_charset: bool)
                           -> Option<Vec<(String, String)>> {
    parse_internal(input, EncodingOverride::from_opt_encoding(encoding_override), use_charset)
}

fn parse_internal(input: &[u8], mut encoding_override: EncodingOverride, mut use_charset: bool)
                  -> Option<Vec<(String, String)>> {
    let mut pairs = Vec::new();
    for piece in input.split(|&b| b == b'&') {
        if !piece.is_empty() {
            let (name, value) = match piece.iter().position(|b| *b == b'=') {
                Some(position) => (&piece[..position], &piece[position + 1..]),
                None => (piece, &[][..])
            };

            #[inline]
            fn replace_plus(input: &[u8]) -> Vec<u8> {
                input.iter().map(|&b| if b == b'+' { b' ' } else { b }).collect()
            }

            let name = replace_plus(name);
            let value = replace_plus(value);
            if use_charset && name == b"_charset_" {
                if let Some(encoding) = EncodingOverride::lookup(&value) {
                    encoding_override = encoding;
                }
                use_charset = false;
            }
            pairs.push((name, value));
        }
    }
    if !(encoding_override.is_utf8() || input.is_ascii()) {
        return None
    }

    Some(pairs.into_iter().map(|(name, value)| (
        encoding_override.decode(&percent_decode(&name)),
        encoding_override.decode(&percent_decode(&value))
    )).collect())
}

/// Convert an iterator of (name, value) pairs
/// into a string in the `application/x-www-form-urlencoded` format.
#[inline]
pub fn serialize<I, K, V>(pairs: I) -> String
where I: IntoIterator, I::Item: Borrow<(K, V)>, K: AsRef<str>, V: AsRef<str> {
    serialize_internal(pairs, EncodingOverride::utf8())
}

/// Convert an iterator of (name, value) pairs
/// into a string in the `application/x-www-form-urlencoded` format.
///
/// This function is only available if the `query_encoding` Cargo feature is enabled.
///
/// Arguments:
///
/// * `encoding_override`: The character encoding each name and values is encoded as
///    before percent-encoding. Defaults to UTF-8.
#[cfg(feature = "query_encoding")]
#[inline]
pub fn serialize_with_encoding<I, K, V>(pairs: I,
                                        encoding_override: Option<::encoding::EncodingRef>)
                                        -> String
where I: IntoIterator, I::Item: Borrow<(K, V)>, K: AsRef<str>, V: AsRef<str> {
    serialize_internal(pairs, EncodingOverride::from_opt_encoding(encoding_override))
}

fn serialize_internal<I, K, V>(pairs: I, encoding_override: EncodingOverride) -> String
where I: IntoIterator, I::Item: Borrow<(K, V)>, K: AsRef<str>, V: AsRef<str> {
    #[inline]
    fn byte_serialize(input: &str, output: &mut String,
                      encoding_override: EncodingOverride) {
        for &byte in encoding_override.encode(input).iter() {
            if byte == b' ' {
                output.push_str("+")
            } else {
                percent_encode_to(&[byte], FORM_URLENCODED_ENCODE_SET, output)
            }
        }
    }

    let mut output = String::new();
    for pair in pairs {
        let &(ref name, ref value) = pair.borrow();
        if output.len() > 0 {
            output.push_str("&");
        }
        byte_serialize(name.as_ref(), &mut output, encoding_override);
        output.push_str("=");
        byte_serialize(value.as_ref(), &mut output, encoding_override);
    }
    output
}

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

    #[test]
    fn test_form_urlencoded() {
        let pairs = &[
            ("foo".to_string(), "é&".to_string()),
            ("bar".to_string(), "".to_string()),
            ("foo".to_string(), "#".to_string())
        ];
        let encoded = serialize(pairs);
        assert_eq!(encoded, "foo=%C3%A9%26&bar=&foo=%23");
        assert_eq!(parse(encoded.as_bytes()), pairs.to_vec());
    }

    #[test]
    fn test_form_serialize() {
        let pairs = [("foo", "é&"),
                     ("bar", ""),
                     ("foo", "#")];

        let want = "foo=%C3%A9%26&bar=&foo=%23";
        // Works with referenced tuples
        assert_eq!(serialize(pairs.iter()), want);
        // Works with owned tuples
        assert_eq!(serialize(pairs.iter().map(|p| (p.0, p.1))), want);

    }
}
<commit_msg>adds docs for form_urlencoded::parse<commit_after>// Copyright 2013-2015 Simon Sapin.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Parser and serializer for the [`application/x-www-form-urlencoded` format](
//! http://url.spec.whatwg.org/#application/x-www-form-urlencoded),
//! as used by HTML forms.
//!
//! Converts between a string (such as an URL’s query string)
//! and a sequence of (name, value) pairs.

use std::borrow::Borrow;
use std::ascii::AsciiExt;
use encoding::EncodingOverride;
use percent_encoding::{percent_encode_to, percent_decode, FORM_URLENCODED_ENCODE_SET};

/// Convert a byte string in the `application/x-www-form-urlencoded` format
/// into a vector of (name, value) pairs.
///
/// Use `parse(input.as_bytes())` to parse a `&str` string.
///
/// The names and values are URL-decoded. For instance, `%23first=%25try%25` will be
/// converted to `[("#first", "%try%")]`.
#[inline]
pub fn parse(input: &[u8]) -> Vec<(String, String)> {
    parse_internal(input, EncodingOverride::utf8(), false).unwrap()
}

/// Convert a byte string in the `application/x-www-form-urlencoded` format
/// into a vector of (name, value) pairs.
///
/// Use `parse(input.as_bytes())` to parse a `&str` string.
///
/// This function is only available if the `query_encoding` Cargo feature is enabled.
///
/// Arguments:
///
/// * `encoding_override`: The character encoding each name and values is decoded as
///    after percent-decoding. Defaults to UTF-8.
/// * `use_charset`: The *use _charset_ flag*. If in doubt, set to `false`.
#[cfg(feature = "query_encoding")]
#[inline]
pub fn parse_with_encoding(input: &[u8], encoding_override: Option<::encoding::EncodingRef>,
                           use_charset: bool)
                           -> Option<Vec<(String, String)>> {
    parse_internal(input, EncodingOverride::from_opt_encoding(encoding_override), use_charset)
}

fn parse_internal(input: &[u8], mut encoding_override: EncodingOverride, mut use_charset: bool)
                  -> Option<Vec<(String, String)>> {
    let mut pairs = Vec::new();
    for piece in input.split(|&b| b == b'&') {
        if !piece.is_empty() {
            let (name, value) = match piece.iter().position(|b| *b == b'=') {
                Some(position) => (&piece[..position], &piece[position + 1..]),
                None => (piece, &[][..])
            };

            #[inline]
            fn replace_plus(input: &[u8]) -> Vec<u8> {
                input.iter().map(|&b| if b == b'+' { b' ' } else { b }).collect()
            }

            let name = replace_plus(name);
            let value = replace_plus(value);
            if use_charset && name == b"_charset_" {
                if let Some(encoding) = EncodingOverride::lookup(&value) {
                    encoding_override = encoding;
                }
                use_charset = false;
            }
            pairs.push((name, value));
        }
    }
    if !(encoding_override.is_utf8() || input.is_ascii()) {
        return None
    }

    Some(pairs.into_iter().map(|(name, value)| (
        encoding_override.decode(&percent_decode(&name)),
        encoding_override.decode(&percent_decode(&value))
    )).collect())
}

/// Convert an iterator of (name, value) pairs
/// into a string in the `application/x-www-form-urlencoded` format.
#[inline]
pub fn serialize<I, K, V>(pairs: I) -> String
where I: IntoIterator, I::Item: Borrow<(K, V)>, K: AsRef<str>, V: AsRef<str> {
    serialize_internal(pairs, EncodingOverride::utf8())
}

/// Convert an iterator of (name, value) pairs
/// into a string in the `application/x-www-form-urlencoded` format.
///
/// This function is only available if the `query_encoding` Cargo feature is enabled.
///
/// Arguments:
///
/// * `encoding_override`: The character encoding each name and values is encoded as
///    before percent-encoding. Defaults to UTF-8.
#[cfg(feature = "query_encoding")]
#[inline]
pub fn serialize_with_encoding<I, K, V>(pairs: I,
                                        encoding_override: Option<::encoding::EncodingRef>)
                                        -> String
where I: IntoIterator, I::Item: Borrow<(K, V)>, K: AsRef<str>, V: AsRef<str> {
    serialize_internal(pairs, EncodingOverride::from_opt_encoding(encoding_override))
}

fn serialize_internal<I, K, V>(pairs: I, encoding_override: EncodingOverride) -> String
where I: IntoIterator, I::Item: Borrow<(K, V)>, K: AsRef<str>, V: AsRef<str> {
    #[inline]
    fn byte_serialize(input: &str, output: &mut String,
                      encoding_override: EncodingOverride) {
        for &byte in encoding_override.encode(input).iter() {
            if byte == b' ' {
                output.push_str("+")
            } else {
                percent_encode_to(&[byte], FORM_URLENCODED_ENCODE_SET, output)
            }
        }
    }

    let mut output = String::new();
    for pair in pairs {
        let &(ref name, ref value) = pair.borrow();
        if output.len() > 0 {
            output.push_str("&");
        }
        byte_serialize(name.as_ref(), &mut output, encoding_override);
        output.push_str("=");
        byte_serialize(value.as_ref(), &mut output, encoding_override);
    }
    output
}

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

    #[test]
    fn test_form_urlencoded() {
        let pairs = &[
            ("foo".to_string(), "é&".to_string()),
            ("bar".to_string(), "".to_string()),
            ("foo".to_string(), "#".to_string())
        ];
        let encoded = serialize(pairs);
        assert_eq!(encoded, "foo=%C3%A9%26&bar=&foo=%23");
        assert_eq!(parse(encoded.as_bytes()), pairs.to_vec());
    }

    #[test]
    fn test_form_serialize() {
        let pairs = [("foo", "é&"),
                     ("bar", ""),
                     ("foo", "#")];

        let want = "foo=%C3%A9%26&bar=&foo=%23";
        // Works with referenced tuples
        assert_eq!(serialize(pairs.iter()), want);
        // Works with owned tuples
        assert_eq!(serialize(pairs.iter().map(|p| (p.0, p.1))), want);

    }
}
<|endoftext|>


<commit_before>use handler::ErrorHandler;
use response::Response;
use codegen::StaticCatchInfo;
use error::Error;
use request::Request;

use std::fmt;
use term_painter::ToStyle;
use term_painter::Color::*;

pub struct Catcher {
    pub code: u16,
    handler: ErrorHandler,
    is_default: bool
}

// TODO: Should `Catcher` be an interface? Should there be an `ErrorHandler`
// that takes in a `RoutingError` and returns a `Response`? What's the right
// interface here?

impl Catcher {
    pub fn new(code: u16, handler: ErrorHandler) -> Catcher {
        Catcher::new_with_default(code, handler, false)
    }

    pub fn handle<'r>(&self, error: Error, request: &'r Request<'r>) -> Response<'r> {
        (self.handler)(error, request)
    }

    fn new_with_default(code: u16, handler: ErrorHandler, default: bool) -> Catcher {
        Catcher {
            code: code,
            handler: handler,
            is_default: default
        }
    }

    pub fn is_default(&self) -> bool {
        self.is_default
    }
}

impl<'a> From<&'a StaticCatchInfo> for Catcher {
    fn from(info: &'a StaticCatchInfo) -> Catcher {
        Catcher::new(info.code, info.handler)
    }
}

impl fmt::Display for Catcher {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", Blue.paint(&self.code))
    }
}

pub mod defaults {
    use request::Request;
    use response::{StatusCode, Response, HTML};
    use super::Catcher;
    use error::Error;
	use std::collections::HashMap;

    pub fn not_found<'r>(_error: Error, _request: &'r Request<'r>) -> Response<'r> {
        Response::with_status(StatusCode::NotFound, HTML("\
			\
  				<meta charset=\"utf-8\">\
				<title>404: Not Found</title>\
	  		\
			\

404: Not Found
\

The page you were looking for could not be found.
\

\
            Rocket\
			\
        "))
    }

    pub fn internal_error<'r>(_error: Error, _request: &'r Request<'r>)
        -> Response<'r> {
        Response::with_status(StatusCode::InternalServerError, HTML("\
			\
  				<meta charset=\"utf-8\">\
				<title>404: Not Found</title>\
	  		\
			\

500: Internal Server Error
\

The server encountered a problem processing your request.
\

\
            Rocket\
        "))
    }

    pub fn get() -> HashMap<u16, Catcher> {
		let mut map = HashMap::new();
		map.insert(404, Catcher::new_with_default(404, not_found, true));
		map.insert(500, Catcher::new_with_default(500, internal_error, true));
		map
    }
}
<commit_msg>Improve default catcher error messages.<commit_after>use handler::ErrorHandler;
use response::Response;
use codegen::StaticCatchInfo;
use error::Error;
use request::Request;

use std::fmt;
use term_painter::ToStyle;
use term_painter::Color::*;

pub struct Catcher {
    pub code: u16,
    handler: ErrorHandler,
    is_default: bool,
}

// TODO: Should `Catcher` be an interface? Should there be an `ErrorHandler`
// that takes in a `RoutingError` and returns a `Response`? What's the right
// interface here?

impl Catcher {
    pub fn new(code: u16, handler: ErrorHandler) -> Catcher {
        Catcher::new_with_default(code, handler, false)
    }

    pub fn handle<'r>(&self, err: Error, request: &'r Request<'r>) -> Response<'r> {
        (self.handler)(err, request)
    }

    fn new_with_default(code: u16, handler: ErrorHandler, default: bool) -> Catcher {
        Catcher {
            code: code,
            handler: handler,
            is_default: default,
        }
    }

    pub fn is_default(&self) -> bool {
        self.is_default
    }
}

impl<'a> From<&'a StaticCatchInfo> for Catcher {
    fn from(info: &'a StaticCatchInfo) -> Catcher {
        Catcher::new(info.code, info.handler)
    }
}

impl fmt::Display for Catcher {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", Blue.paint(&self.code))
    }
}

pub mod defaults {
    use request::Request;
    use response::{StatusCode, Response, HTML};
    use super::Catcher;
    use error::Error;
    use std::collections::HashMap;

    pub fn not_found<'r>(_error: Error, _request: &'r Request<'r>) -> Response<'r> {
        Response::with_status(StatusCode::NotFound, HTML(r#"
            <!DOCTYPE html>

                <meta charset="utf-8">
                <title>404: Not Found</title>

404: Not Found

The page you were looking for could not be found.

                    Rocket

        "#))
    }

    pub fn internal_error<'r>(_error: Error,
                              _request: &'r Request<'r>)
                              -> Response<'r> {
        Response::with_status(StatusCode::InternalServerError, HTML(r#"
            <!DOCTYPE html>

                <meta charset="utf-8">
                <title>500: Internal Server Error</title>

500: Internal Server Error

The server encountered a problem processing your request.

                    Rocket

        "#))
    }

    pub fn get() -> HashMap<u16, Catcher> {
        let mut map = HashMap::new();
        map.insert(404, Catcher::new_with_default(404, not_found, true));
        map.insert(500, Catcher::new_with_default(500, internal_error, true));
        map
    }
}
<|endoftext|>


<commit_before>#![feature(collections)]
#![feature(slice_patterns)]
extern crate rustc_serialize;
extern crate cbor;
extern crate websocket;
extern crate time;
extern crate hyper;
extern crate cookie;
extern crate url;
extern crate mime;

macro_rules! time {
    ($name:expr, $expr:expr) => {{
        let start = ::time::precise_time_s();
        let result = $expr;
        let end = ::time::precise_time_s();
        println!("{} took {}s", $name, end - start);
        result
    }};
}

macro_rules! string {
    ($($args:expr),*) => (::value::Value::String(format!($($args),*)))
}

pub mod value;
// pub mod map;
pub mod relation;
pub mod view;
pub mod flow;
pub mod primitive;
pub mod compiler;
pub mod server;
pub mod authenticate;
pub mod client;
// pub mod test;
<commit_msg>Remove authenticate from lib<commit_after>#![feature(collections)]
#![feature(slice_patterns)]
extern crate rustc_serialize;
extern crate cbor;
extern crate websocket;
extern crate time;
extern crate hyper;
extern crate cookie;
extern crate url;
extern crate mime;

macro_rules! time {
    ($name:expr, $expr:expr) => {{
        let start = ::time::precise_time_s();
        let result = $expr;
        let end = ::time::precise_time_s();
        println!("{} took {}s", $name, end - start);
        result
    }};
}

macro_rules! string {
    ($($args:expr),*) => (::value::Value::String(format!($($args),*)))
}

pub mod value;
// pub mod map;
pub mod relation;
pub mod view;
pub mod flow;
pub mod primitive;
pub mod compiler;
pub mod server;
pub mod client;
// pub mod test;
<|endoftext|>


<commit_before>// Find Cargo's source cache directory for a crate
use super::es;
use std::fs;
use es::traits::*;
use std::env;
use std::path::{Path,PathBuf};
use std::collections::HashMap;

lazy_static! {
    pub static ref RUSTUP_LIB: String = shell("rustc --print sysroot") + "/lib";
    pub static ref UNSTABLE: bool = RUSTUP_LIB.find("stable").is_none();
}

pub fn shell(cmd: &str) -> String {
    let o = ::std::process::Command::new("sh")
     .arg("-c")
     .arg(&format!("{} 2>&1",cmd))
     .output()
     .expect("failed to execute shell");
    String::from_utf8(o.stdout).expect("not UTF-8 output").trim_right_matches('\n').to_string()
}

pub fn proper_crate_name(crate_name: &str) -> String {
    crate_name.replace('-',"_")
}

pub fn path_file_name(p: &Path) -> String {
    if let Some(file_name) = p.file_name() {
        file_name.to_string_lossy().to_string()
    } else
    if let Ok(full_path) = p.canonicalize() {
        path_file_name(&full_path)
    } else {
        p.to_string_lossy().to_string()
    }
}

// there's a Crate for This...
fn semver_i (s: &str) -> u64 {
    let v = s.split('.').filter_map(|s| s.parse::<u64>().ok()).to_vec();
    (((v[0] << 8) + v[1]) << 8) + v[2]
}

pub fn cargo_home() -> PathBuf {
    if let Ok(home) = env::var("CARGO_HOME") { // set in cargo runs
        home.into()
    } else {
        env::home_dir().or_die("no home!").join(".cargo")
    }
}

pub fn cache_path(crate_name: &str) -> PathBuf {
    let home = cargo_home();
    let crate_root = PathBuf::from(home.join("registry/src"));
    // actual crate source is in some fairly arbitrary subdirectory of this
    let mut crate_dir = crate_root.clone();
    crate_dir.push(es::files(&crate_root).next().or_die("no crate cache directory"));

    let mut crates = Vec::new();
    for (p,d) in es::paths(&crate_dir) {
        if ! d.is_dir() { continue; }
        let filename = path_file_name(&p);
        if let Some(endc) = filename.rfind('-') {
            if &filename[0..endc] == crate_name {
                crates.push((p,semver_i(&filename[endc+1..])));
            }
        }
    }
    // crate versions in ascending order by semver rules
    crates.sort_by(|a,b| a.1.cmp(&b.1));
    crates.pop().or_die(&format!("no such crate: {}",crate_name)).0
}

// Very hacky stuff - we want the ACTUAL crate name, not the project name
// So look just past [package] and scrape the name...
fn crate_name(cargo_toml: &Path) -> String {
    let name_line = es::lines(es::open(cargo_toml))
        .skip_while(|line| line.trim() != "[package]")
        .skip(1)
        .skip_while(|line| ! line.starts_with("name "))
        .next().or_die("totally fked Cargo.toml");
    let idx = name_line.find('"').or_die("no name?");
    (&name_line[(idx+1)..(name_line.len()-1)]).into()

}

pub fn crate_path(file: &Path, first_arg: &str) -> Result<(PathBuf,String),String> {
    if file.exists() {
        if file.is_dir() { // assumed to be Cargo directory
            let cargo_toml = file.join("Cargo.toml");
            if ! cargo_toml.exists() {
                return Err(format!("not a Cargo project directory: {}",file.display()));
            }
            Ok((file.join("src").join("lib.rs"), crate_name(&cargo_toml)))
        } else { // should be just a Rust source file
            if file.extension().or_die("expecting extension") != "rs" {
                return Err("expecting Rust source file".into());
            }
            let name = path_file_name(&file.with_extension(""));
            Ok((file.to_path_buf(), name))
        }
    } else {
        let project_dir = cache_path(first_arg);
        let cargo_toml = project_dir.join("Cargo.toml");
        Ok((project_dir.join("src").join("lib.rs"), crate_name(&cargo_toml)))
    }
}

pub fn full_crate_name(deps: &Path, crate_name: &str) -> Option<String> {
    let mut res = Vec::new();
    let patt = format!("lib{}-",crate_name);
    for entry in fs::read_dir(deps).or_die("cannot access dependencies dir") {
        let entry = entry.or_die("cannot access deps entry");
        let path = entry.path();
        if let Some(f) = path.file_name() {
            let name = f.to_string_lossy();
            //println!("got {}",name);
            if name.starts_with(&patt) {
                let cname = &name[3..(name.len()-5) ];
                res.push(cname.to_string());
            }
        }
    }
    res.pop()
}

pub type Crates = HashMap<String,Vec<PathBuf>>;

pub fn get_cache_deps(deps: &Path) ->  Crates {
    let mut res: Crates = HashMap::new();
    for entry in fs::read_dir(deps).or_die("cannot access dependencies dir") {
        let entry = entry.or_die("cannot access deps entry");
        let path = entry.path();
        if let Some(f) = path.file_name() {
            let rlib = f.to_string_lossy();
            // pull out the crate name
            if let Some(idx) = rlib.rfind('-') {
                let name = &rlib[3..idx];
                let v = res.entry(name.into())
                    .or_insert_with(|| Vec::new());
                v.push(path.clone());
            }
        }
    }
    res
}

pub fn remove_duplicates(crates: Crates) {
    for (name,paths) in crates {
        if paths.len() > 1 {
            // Sort the paths in ascending time of modification
            let mut mpaths: Vec<_> = paths.into_iter()
                .map(|p| {
                    let time = p.metadata().unwrap().modified().unwrap();
                    (p,time)
                }).collect();
            mpaths.sort_by(|a,b| a.1.cmp(&b.1));

            // ignore the latest, and delete the rest
            mpaths.pop();
            println!("crate {} removing {} items",name,mpaths.len());
            for (p,_) in mpaths {
                fs::remove_file(&p).expect("can't remove rlib");
            }
        }
    }
}

pub fn remove_duplicate_cache_deps(deps: &Path) {
    let deps = get_cache_deps(deps);
    remove_duplicates(deps);
}

<commit_msg>do last fix properly cross-platform<commit_after>// Find Cargo's source cache directory for a crate
use super::es;
use std::fs;
use es::traits::*;
use std::env;
use std::path::{Path,PathBuf};
use std::collections::HashMap;

lazy_static! {
    pub static ref RUSTUP_LIB: String = shell("rustc --print sysroot") + "/lib";
    pub static ref UNSTABLE: bool = RUSTUP_LIB.find("stable").is_none();
}

pub fn shell(cmd: &str) -> String {
    let o = ::std::process::Command::new(if cfg!(windows) {"cmd.exe"} else {"sh"})
     .arg(if cfg!(windows) {"/c"} else {"-c"})
     .arg(&format!("{} 2>&1",cmd))
     .output()
     .expect("failed to execute shell");
    String::from_utf8(o.stdout).expect("not UTF-8 output").trim_right_matches('\n').to_string()
}

pub fn proper_crate_name(crate_name: &str) -> String {
    crate_name.replace('-',"_")
}

pub fn path_file_name(p: &Path) -> String {
    if let Some(file_name) = p.file_name() {
        file_name.to_string_lossy().to_string()
    } else
    if let Ok(full_path) = p.canonicalize() {
        path_file_name(&full_path)
    } else {
        p.to_string_lossy().to_string()
    }
}

// there's a Crate for This...
fn semver_i (s: &str) -> u64 {
    let v = s.split('.').filter_map(|s| s.parse::<u64>().ok()).to_vec();
    (((v[0] << 8) + v[1]) << 8) + v[2]
}

pub fn cargo_home() -> PathBuf {
    if let Ok(home) = env::var("CARGO_HOME") { // set in cargo runs
        home.into()
    } else {
        env::home_dir().or_die("no home!").join(".cargo")
    }
}

pub fn cache_path(crate_name: &str) -> PathBuf {
    let home = cargo_home();
    let crate_root = PathBuf::from(home.join("registry/src"));
    // actual crate source is in some fairly arbitrary subdirectory of this
    let mut crate_dir = crate_root.clone();
    crate_dir.push(es::files(&crate_root).next().or_die("no crate cache directory"));

    let mut crates = Vec::new();
    for (p,d) in es::paths(&crate_dir) {
        if ! d.is_dir() { continue; }
        let filename = path_file_name(&p);
        if let Some(endc) = filename.rfind('-') {
            if &filename[0..endc] == crate_name {
                crates.push((p,semver_i(&filename[endc+1..])));
            }
        }
    }
    // crate versions in ascending order by semver rules
    crates.sort_by(|a,b| a.1.cmp(&b.1));
    crates.pop().or_die(&format!("no such crate: {}",crate_name)).0
}

// Very hacky stuff - we want the ACTUAL crate name, not the project name
// So look just past [package] and scrape the name...
fn crate_name(cargo_toml: &Path) -> String {
    let name_line = es::lines(es::open(cargo_toml))
        .skip_while(|line| line.trim() != "[package]")
        .skip(1)
        .skip_while(|line| ! line.starts_with("name "))
        .next().or_die("totally fked Cargo.toml");
    let idx = name_line.find('"').or_die("no name?");
    (&name_line[(idx+1)..(name_line.len()-1)]).into()

}

pub fn crate_path(file: &Path, first_arg: &str) -> Result<(PathBuf,String),String> {
    if file.exists() {
        if file.is_dir() { // assumed to be Cargo directory
            let cargo_toml = file.join("Cargo.toml");
            if ! cargo_toml.exists() {
                return Err(format!("not a Cargo project directory: {}",file.display()));
            }
            Ok((file.join("src").join("lib.rs"), crate_name(&cargo_toml)))
        } else { // should be just a Rust source file
            if file.extension().or_die("expecting extension") != "rs" {
                return Err("expecting Rust source file".into());
            }
            let name = path_file_name(&file.with_extension(""));
            Ok((file.to_path_buf(), name))
        }
    } else {
        let project_dir = cache_path(first_arg);
        let cargo_toml = project_dir.join("Cargo.toml");
        Ok((project_dir.join("src").join("lib.rs"), crate_name(&cargo_toml)))
    }
}

pub fn full_crate_name(deps: &Path, crate_name: &str) -> Option<String> {
    let mut res = Vec::new();
    let patt = format!("lib{}-",crate_name);
    for entry in fs::read_dir(deps).or_die("cannot access dependencies dir") {
        let entry = entry.or_die("cannot access deps entry");
        let path = entry.path();
        if let Some(f) = path.file_name() {
            let name = f.to_string_lossy();
            //println!("got {}",name);
            if name.starts_with(&patt) {
                let cname = &name[3..(name.len()-5) ];
                res.push(cname.to_string());
            }
        }
    }
    res.pop()
}

pub type Crates = HashMap<String,Vec<PathBuf>>;

pub fn get_cache_deps(deps: &Path) ->  Crates {
    let mut res: Crates = HashMap::new();
    for entry in fs::read_dir(deps).or_die("cannot access dependencies dir") {
        let entry = entry.or_die("cannot access deps entry");
        let path = entry.path();
        if let Some(f) = path.file_name() {
            let rlib = f.to_string_lossy();
            // pull out the crate name
            if let Some(idx) = rlib.rfind('-') {
                let name = &rlib[3..idx];
                let v = res.entry(name.into())
                    .or_insert_with(|| Vec::new());
                v.push(path.clone());
            }
        }
    }
    res
}

pub fn remove_duplicates(crates: Crates) {
    for (name,paths) in crates {
        if paths.len() > 1 {
            // Sort the paths in ascending time of modification
            let mut mpaths: Vec<_> = paths.into_iter()
                .map(|p| {
                    let time = p.metadata().unwrap().modified().unwrap();
                    (p,time)
                }).collect();
            mpaths.sort_by(|a,b| a.1.cmp(&b.1));

            // ignore the latest, and delete the rest
            mpaths.pop();
            println!("crate {} removing {} items",name,mpaths.len());
            for (p,_) in mpaths {
                fs::remove_file(&p).expect("can't remove rlib");
            }
        }
    }
}

pub fn remove_duplicate_cache_deps(deps: &Path) {
    let deps = get_cache_deps(deps);
    remove_duplicates(deps);
}

<|endoftext|>


<commit_before>/* Copyright (c) 2014, Peter Nelson
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#![crate_name = "jit"]
#![allow(raw_pointer_derive, non_camel_case_types, non_upper_case_globals)]
#![deny(unused_attributes, dead_code, unused_parens, unknown_lints, unreachable_code, unused_allocation, unused_allocation, unused_must_use)]
#![feature(alloc, libc, core, convert, plugin, unboxed_closures, optin_builtin_traits, associated_consts)]
#![plugin(rustc_bitflags)]
#![stable]
//! This crate wraps LibJIT in an idiomatic style.
//! For example, here's a quick example which makes a multiply function using LibJIT:
//!
//! ```rust
//! #![feature(plugin)]
//! #![plugin(jit_macros)]
//! extern crate jit;
//! #[no_link] #[macro_use]
//! extern crate jit_macros;
//! use jit::{Context, get, Type};
//! fn main() {
//!     // make a new context to make functions on
//!     let mut ctx = Context::<()>::new();
//!     jit_func!(ctx, func, mul(x: isize, y: isize) -> isize, {
//!         func.insn_return(x * y);
//!     }, |mul| {
//!         assert_eq!(mul((4, 5)), 20);
//!     });
//! }
//! ```
#[no_link] #[macro_use]
extern crate rustc_bitflags;
extern crate alloc;
extern crate libc;
extern crate libjit_sys as raw;
use raw::*;
use libc::c_void;
use std::mem;
pub use compile::Compile;
pub use context::{Builder, Context};
pub use elf::*;
pub use function::{flags, Abi, UncompiledFunction, Func, CompiledFunction};
pub use function::flags::CallFlags;
pub use label::Label;
pub use insn::{Block, Instruction, InstructionIter};
pub use types::kind::TypeKind;
pub use types::{kind, get, Type, Field, Fields, Params, CowType, StaticType, Ty, TaggedType};
pub use types::consts as typecs;
pub use value::Val;

extern fn free_data<T>(data: *mut c_void) {
    unsafe {
        let actual_data:Box<T> = mem::transmute(data);
        mem::drop(actual_data);
    }
}

/// Initialise the library and prepare for operations
#[inline]
pub fn init() -> () {
    unsafe {
        jit_init()
    }
}
/// Check if the JIT is using a fallback interpreter
#[inline]
pub fn uses_interpreter() -> bool {
    unsafe {
        jit_uses_interpreter() != 0
    }
}
/// Check if the JIT supports theads
#[inline]
pub fn supports_threads() -> bool {
    unsafe {
        jit_supports_threads() != 0
    }
}
/// Check if the JIT supports virtual memory
#[inline]
pub fn supports_virtual_memory() -> bool {
    unsafe {
        jit_supports_virtual_memory() != 0
    }
}
#[macro_use]
mod macros;
mod context;
mod compile;
mod elf;
mod function;
mod insn;
mod label;
mod types;
mod util;
mod value;
<commit_msg>Remove stability attribute (no longer allowed)<commit_after>/* Copyright (c) 2014, Peter Nelson
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#![crate_name = "jit"]
#![allow(raw_pointer_derive, non_camel_case_types, non_upper_case_globals)]
#![deny(unused_attributes, dead_code, unused_parens, unknown_lints, unreachable_code, unused_allocation, unused_allocation, unused_must_use)]
#![feature(alloc, libc, core, convert, plugin, unboxed_closures, optin_builtin_traits, associated_consts)]
#![plugin(rustc_bitflags)]

//! This crate wraps LibJIT in an idiomatic style.
//! For example, here's a quick example which makes a multiply function using LibJIT:
//!
//! ```rust
//! #![feature(plugin)]
//! #![plugin(jit_macros)]
//! extern crate jit;
//! #[no_link] #[macro_use]
//! extern crate jit_macros;
//! use jit::{Context, get, Type};
//! fn main() {
//!     // make a new context to make functions on
//!     let mut ctx = Context::<()>::new();
//!     jit_func!(ctx, func, mul(x: isize, y: isize) -> isize, {
//!         func.insn_return(x * y);
//!     }, |mul| {
//!         assert_eq!(mul((4, 5)), 20);
//!     });
//! }
//! ```
#[no_link] #[macro_use]
extern crate rustc_bitflags;
extern crate alloc;
extern crate libc;
extern crate libjit_sys as raw;
use raw::*;
use libc::c_void;
use std::mem;
pub use compile::Compile;
pub use context::{Builder, Context};
pub use elf::*;
pub use function::{flags, Abi, UncompiledFunction, Func, CompiledFunction};
pub use function::flags::CallFlags;
pub use label::Label;
pub use insn::{Block, Instruction, InstructionIter};
pub use types::kind::TypeKind;
pub use types::{kind, get, Type, Field, Fields, Params, CowType, StaticType, Ty, TaggedType};
pub use types::consts as typecs;
pub use value::Val;

extern fn free_data<T>(data: *mut c_void) {
    unsafe {
        let actual_data:Box<T> = mem::transmute(data);
        mem::drop(actual_data);
    }
}

/// Initialise the library and prepare for operations
#[inline]
pub fn init() -> () {
    unsafe {
        jit_init()
    }
}
/// Check if the JIT is using a fallback interpreter
#[inline]
pub fn uses_interpreter() -> bool {
    unsafe {
        jit_uses_interpreter() != 0
    }
}
/// Check if the JIT supports theads
#[inline]
pub fn supports_threads() -> bool {
    unsafe {
        jit_supports_threads() != 0
    }
}
/// Check if the JIT supports virtual memory
#[inline]
pub fn supports_virtual_memory() -> bool {
    unsafe {
        jit_supports_virtual_memory() != 0
    }
}
#[macro_use]
mod macros;
mod context;
mod compile;
mod elf;
mod function;
mod insn;
mod label;
mod types;
mod util;
mod value;
<|endoftext|>


<commit_before>use std::{result, io, fmt};
use std::error;

use protobuf::ProtobufError;

#[derive(Debug)]
pub enum Error {
    Io(io::Error),
    NotFound,
    Protobuf(ProtobufError),
    Other(String),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::NotFound => write!(f, "not found"),
            Error::Io(ref error) => fmt::Display::fmt(error, f),
            _ => fmt::Display::fmt(self, f),
        }
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match self {
            // not sure that cause should be included in message
            &Error::Io(ref e) => e.description(),
            &Error::NotFound => "not found",
            &Error::Protobuf(ref e) => e.description(),
            &Error::Other(ref e) => &e,
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match self {
            &Error::Io(ref e) => Some(e),
            &Error::Protobuf(ref e) => Some(e),
            _ => None,
        }
    }
}

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

impl From<ProtobufError> for Error {
    fn from(err: ProtobufError) -> Error{
        Error::Protobuf(err)
    }
 }

pub type Result<T> = result::Result<T, Error>;
<commit_msg>raft: format code.<commit_after>use std::{result, io, fmt};
use std::error;

use protobuf::ProtobufError;

#[derive(Debug)]
pub enum Error {
    Io(io::Error),
    NotFound,
    Protobuf(ProtobufError),
    Other(String),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::NotFound => write!(f, "not found"),
            Error::Io(ref error) => fmt::Display::fmt(error, f),
            _ => fmt::Display::fmt(self, f),
        }
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match self {
            // not sure that cause should be included in message
            &Error::Io(ref e) => e.description(),
            &Error::NotFound => "not found",
            &Error::Protobuf(ref e) => e.description(),
            &Error::Other(ref e) => &e,
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match self {
            &Error::Io(ref e) => Some(e),
            &Error::Protobuf(ref e) => Some(e),
            _ => None,
        }
    }
}

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

impl From<ProtobufError> for Error {
    fn from(err: ProtobufError) -> Error {
        Error::Protobuf(err)
    }
}

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


<commit_before>use std::env;

#[derive(PartialEq, Debug)]
enum CiService {
    Travis,
    Circle,
    Unknown,
}

macro_rules! err {
    ($expr:expr) => {
        match $expr {
            Ok(val) => Some(val),
            Err(e) => match e {
                ::std::env::VarError::NotPresent => None,
                _ => panic!(e),
            }
        }
    }
}

macro_rules! lang_version {
    ($lang:expr, $name:ident) => {
        /// **Travis only**: Returns the $lang version that is used.
        fn $name(&self) -> Option<String> {
            match self.service {
                CiService::Travis => err!(env::var(format!("TRAVIS_{}_VERSION", $lang))),
                _ => None,
            }
        }
    }
}

struct Ci {
    service: CiService,
}
impl Ci {
    fn new() -> Option<Self> {
        let s = Ci::which_ci();
        match s {
            CiService::Travis | CiService::Circle => Some(Ci { service: s }),
            _ => None,
        }
    }

    fn which_ci() -> CiService {
        match (err!(env::var("TRAVIS")), err!(env::var("CIRCLECI"))) {
            (Some(_), None) => CiService::Travis,
            (None, Some(_)) => CiService::Circle,
            _ => CiService::Unknown,
        }
    }

    /// Returns the locale setting, g.e. `en_US.UTF-8`.
    fn lang() -> Option<String> {
        err!(env::var("LANG"))
    }

    /// Returns the search path.
    fn path() -> Option<String> {
        err!(env::var("PATH"))
    }

    /// Returns the path to the users home directory.
    fn home() -> Option<String> {
        err!(env::var("HOME"))
    }

    fn is_travis(&self) -> bool {
        match self.service {
            CiService::Travis => true,
            _ => false,
        }
    }

    fn is_circle(&self) -> bool {
        match self.service {
            CiService::Circle => true,
            _ => false,
        }
    }

    fn branch(&self) -> Option<String> {
        match self.service {
            CiService::Circle => err!(env::var("CIRCLE_BRANCH")),
            CiService::Travis => err!(env::var("TRAVIS_BRANCH")),
            _ => None,
        }
    }

    /// **Circle only**
    /// A permanent link to the current build, for example,
    /// https://circleci.com/gh/circleci/frontend/933
    fn build_url(&self) -> Option<String> {
        match self.service {
            CiService::Circle => err!(env::var("CIRCLE_BUILD_URL")),
            _ => None,
        }
    }

    /// Returns the build number.
    /// TODO: convert this to a number.
    fn build_id(&self) -> Option<String> {
        match self.service {
            CiService::Circle => err!(env::var("CIRCLE_BUILD_NUM")),
            CiService::Travis => err!(env::var("TRAVIS_BUILD_NUMBER")),
            _ => None,
        }
    }

    /// **Travis only**: The absolute path to the directory where the repository
    /// being built has been copied on the worker.
    /// TODO: Return a filesystem path instead?
    fn build_dir(&self) -> Option<String> {
        match self.service {
            CiService::Travis => err!(env::var("TRAVIS_BUILD_DIR")),
            _ => None,
        }
    }

    /// The sha1 hash of the commit being tested.
    fn commit(&self) -> Option<String> {
        match self.service {
            CiService::Circle => err!(env::var("CIRCLE_SHA1")),
            CiService::Travis => err!(env::var("TRAVIS_COMMIT")),
            _ => None,
        }
    }

    /// The number of the pull request this build forms part of.
    /// If this build is not part of a pull request, `None` is returned.
    /// TODO: convert this to a number.
    fn pull_request(&self) -> Option<String> {
        match self.service {
            CiService::Circle => err!(env::var("CIRCLE_PR_NUMBER")),
            CiService::Travis => {
                let pr = err!(env::var("TRAVIS_PULL_REQUEST")).unwrap_or("false".to_string());
                if pr == "false" {
                    None
                } else {
                    Some(pr)
                }
            }
            _ => None,
        }
    }

    lang_version!("DART", dart);
    lang_version!("GO", go);
    lang_version!("HAXE", haxe);
    lang_version!("JDK", java);
    lang_version!("JULIA", julia);
    lang_version!("NODE", node);
    lang_version!("OTP", otp);
    lang_version!("PERL", perl);
    lang_version!("PHP", php);
    lang_version!("PYTHON", python);
    lang_version!("R", r);
    lang_version!("RUBY", ruby);
    lang_version!("RUST", rust);
    lang_version!("SCALA", scala);
}

#[test]
fn test_unknown() {
    assert!(Ci::lang().is_some());
    assert!(Ci::path().is_some());
    assert!(Ci::home().is_some());
    let ci = Ci::new();
    if ci.is_some() {
        return;
    }
    assert_eq!(Ci::which_ci(), CiService::Unknown);
}

#[test]
fn test_travis() {
    assert!(Ci::lang().is_some());
    assert!(Ci::path().is_some());
    assert!(Ci::home().is_some());
    let ci = match Ci::new() {
        None => return,
        Some(ci) => {
            if ci.is_travis() {
                ci
            } else {
                return;
            }
        }
    };
    assert!(ci.is_travis());
    assert!(ci.rust().is_some());
    assert!(ci.commit().is_some());
    assert!(ci.build_dir().is_some());
}

#[test]
fn test_circle() {
    assert!(Ci::lang().is_some());
    assert!(Ci::path().is_some());
    assert!(Ci::home().is_some());
    let ci = match Ci::new() {
        None => return,
        Some(ci) => {
            if ci.is_circle() {
                ci
            } else {
                return;
            }
        }
    };
    assert!(ci.is_circle());
    assert!(ci.commit().is_some());
    assert!(ci.build_url().is_some());
}
<commit_msg>Publicize everything!<commit_after>use std::env;

#[derive(PartialEq, Debug)]
pub enum CiService {
    Travis,
    Circle,
    Unknown,
}

macro_rules! err {
    ($expr:expr) => {
        match $expr {
            Ok(val) => Some(val),
            Err(e) => match e {
                ::std::env::VarError::NotPresent => None,
                _ => panic!(e),
            }
        }
    }
}

macro_rules! lang_version {
    ($lang:expr, $name:ident) => {
        /// **Travis only**: Returns the $lang version that is used.
        pub fn $name(&self) -> Option<String> {
            match self.service {
                CiService::Travis => err!(env::var(format!("TRAVIS_{}_VERSION", $lang))),
                _ => None,
            }
        }
    }
}

pub struct Ci {
    service: CiService,
}
impl Ci {
    pub fn new() -> Option<Self> {
        let s = Ci::which_ci();
        match s {
            CiService::Travis | CiService::Circle => Some(Ci { service: s }),
            _ => None,
        }
    }

    pub fn which_ci() -> CiService {
        match (err!(env::var("TRAVIS")), err!(env::var("CIRCLECI"))) {
            (Some(_), None) => CiService::Travis,
            (None, Some(_)) => CiService::Circle,
            _ => CiService::Unknown,
        }
    }

    /// Returns the locale setting, g.e. `en_US.UTF-8`.
    pub fn lang() -> Option<String> {
        err!(env::var("LANG"))
    }

    /// Returns the search path.
    pub fn path() -> Option<String> {
        err!(env::var("PATH"))
    }

    /// Returns the path to the users home directory.
    pub fn home() -> Option<String> {
        err!(env::var("HOME"))
    }

    pub fn is_travis(&self) -> bool {
        match self.service {
            CiService::Travis => true,
            _ => false,
        }
    }

    pub fn is_circle(&self) -> bool {
        match self.service {
            CiService::Circle => true,
            _ => false,
        }
    }

    pub fn branch(&self) -> Option<String> {
        match self.service {
            CiService::Circle => err!(env::var("CIRCLE_BRANCH")),
            CiService::Travis => err!(env::var("TRAVIS_BRANCH")),
            _ => None,
        }
    }

    /// **Circle only**
    /// A permanent link to the current build, for example,
    /// https://circleci.com/gh/circleci/frontend/933
    pub fn build_url(&self) -> Option<String> {
        match self.service {
            CiService::Circle => err!(env::var("CIRCLE_BUILD_URL")),
            _ => None,
        }
    }

    /// Returns the build number.
    /// TODO: convert this to a number.
    pub fn build_id(&self) -> Option<String> {
        match self.service {
            CiService::Circle => err!(env::var("CIRCLE_BUILD_NUM")),
            CiService::Travis => err!(env::var("TRAVIS_BUILD_NUMBER")),
            _ => None,
        }
    }

    /// **Travis only**: The absolute path to the directory where the repository
    /// being built has been copied on the worker.
    /// TODO: Return a filesystem path instead?
    pub fn build_dir(&self) -> Option<String> {
        match self.service {
            CiService::Travis => err!(env::var("TRAVIS_BUILD_DIR")),
            _ => None,
        }
    }

    /// The sha1 hash of the commit being tested.
    pub fn commit(&self) -> Option<String> {
        match self.service {
            CiService::Circle => err!(env::var("CIRCLE_SHA1")),
            CiService::Travis => err!(env::var("TRAVIS_COMMIT")),
            _ => None,
        }
    }

    /// The number of the pull request this build forms part of.
    /// If this build is not part of a pull request, `None` is returned.
    /// TODO: convert this to a number.
    pub fn pull_request(&self) -> Option<String> {
        match self.service {
            CiService::Circle => err!(env::var("CIRCLE_PR_NUMBER")),
            CiService::Travis => {
                let pr = err!(env::var("TRAVIS_PULL_REQUEST")).unwrap_or("false".to_string());
                if pr == "false" {
                    None
                } else {
                    Some(pr)
                }
            }
            _ => None,
        }
    }

    lang_version!("DART", dart);
    lang_version!("GO", go);
    lang_version!("HAXE", haxe);
    lang_version!("JDK", java);
    lang_version!("JULIA", julia);
    lang_version!("NODE", node);
    lang_version!("OTP", otp);
    lang_version!("PERL", perl);
    lang_version!("PHP", php);
    lang_version!("PYTHON", python);
    lang_version!("R", r);
    lang_version!("RUBY", ruby);
    lang_version!("RUST", rust);
    lang_version!("SCALA", scala);
}

#[test]
fn test_unknown() {
    assert!(Ci::lang().is_some());
    assert!(Ci::path().is_some());
    assert!(Ci::home().is_some());
    let ci = Ci::new();
    if ci.is_some() {
        return;
    }
    assert_eq!(Ci::which_ci(), CiService::Unknown);
}

#[test]
fn test_travis() {
    assert!(Ci::lang().is_some());
    assert!(Ci::path().is_some());
    assert!(Ci::home().is_some());
    let ci = match Ci::new() {
        None => return,
        Some(ci) => {
            if ci.is_travis() {
                ci
            } else {
                return;
            }
        }
    };
    assert!(ci.is_travis());
    assert!(ci.rust().is_some());
    assert!(ci.commit().is_some());
    assert!(ci.build_dir().is_some());
}

#[test]
fn test_circle() {
    assert!(Ci::lang().is_some());
    assert!(Ci::path().is_some());
    assert!(Ci::home().is_some());
    let ci = match Ci::new() {
        None => return,
        Some(ci) => {
            if ci.is_circle() {
                ci
            } else {
                return;
            }
        }
    };
    assert!(ci.is_circle());
    assert!(ci.commit().is_some());
    assert!(ci.build_url().is_some());
}
<|endoftext|>


<commit_before>extern crate toml;

// Import traits
use std::io::prelude::Read;

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}

pub fn test() {
    println!("Hello from lib.rs");
}

#[derive(Debug)]
enum Steps {
    Echo,
    Run,
    Shell,
    SetEnv,
}

fn parse_toml(filename: &str) -> Vec<Steps> {

    println!("Reading toml file {}", filename);

    // Read toml file content
    let mut input = String::new();
    std::fs::File::open(&filename).and_then(|mut f| {
        f.read_to_string(&mut input)
    }).unwrap();

    // Pase toml file
    let mut parser = toml::Parser::new(&input);

    let toml = parser.parse().unwrap_or_else(|| {
        for err in &parser.errors {
            let (loline, locol) = parser.to_linecol(err.lo);
            let (hiline, hicol) = parser.to_linecol(err.hi);
            println!("{}:{}:{}-{}:{} error: {}",
                     filename, loline, locol, hiline, hicol, err.desc);
        }
        panic!("Error parsing toml file.");
    });

    println!("toml: {:#?}", toml);
    println!("toml: {:?}", toml.len());

    // Parse "on" table
    // unimplemented!();

    // Parse "variables" table
    // unimplemented!();

    // Parse "steps" table
    let steps: Vec<Steps> = Vec::with_capacity(10);

    steps
}

pub fn execute_steps(filename: &str) {

    let steps = parse_toml(filename);

    println!("Steps: {:#?}", steps);
}
<commit_msg>Change vec allocation<commit_after>extern crate toml;

// Import traits
use std::io::prelude::Read;

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}

pub fn test() {
    println!("Hello from lib.rs");
}

#[derive(Debug)]
enum Steps {
    Echo,
    Run,
    Shell,
    SetEnv,
}

fn parse_toml(filename: &str) -> Vec<Steps> {

    println!("Reading toml file {}", filename);

    // Read toml file content
    let mut input = String::new();
    std::fs::File::open(&filename).and_then(|mut f| {
        f.read_to_string(&mut input)
    }).unwrap();

    // Pase toml file
    let mut parser = toml::Parser::new(&input);

    let toml = parser.parse().unwrap_or_else(|| {
        for err in &parser.errors {
            let (loline, locol) = parser.to_linecol(err.lo);
            let (hiline, hicol) = parser.to_linecol(err.hi);
            println!("{}:{}:{}-{}:{} error: {}",
                     filename, loline, locol, hiline, hicol, err.desc);
        }
        panic!("Error parsing toml file.");
    });

    println!("toml: {:#?}", toml);
    println!("toml: {:?}", toml.len());

    // Parse "on" table
    // unimplemented!();

    // Parse "variables" table
    // unimplemented!();

    // Parse "steps" table
    let mut steps = Vec::<Steps>::with_capacity(10);

    steps
}

pub fn execute_steps(filename: &str) {

    let steps = parse_toml(filename);

    println!("Steps: {:#?}", steps);
}
<|endoftext|>


<commit_before>//! MicroState
//!
//! A minimal Finite State Machine.
//!
//! Example:
//!
//! ```
//! #[macro_use] extern crate microstate;
//! microstate! {
//!     Simple { A }
//!     states { A, B }
//!
//!     next {
//!         A => B
//!         B => A
//!     }
//! }
//!
//! # fn main() {
//! use Simple::State::*;
//!
//! let mut machine = Simple::new();
//! assert_eq!(A, machine.state());
//! assert_eq!(Some(B), machine.next());
//! assert_eq!(Some(A), machine.next());
//! # }
//! ```

/// Create a new state machine
///
/// It takes a name, the initial value, all possible states
/// and the transitions.
///
/// See the main documentation for a proper example.
#[macro_export]
macro_rules! microstate (
  (
      $machine:ident { $initial:ident }
      states { $($states:ident),* }

      $($meth:ident {
          $($from:ident => $to:ident)*
      })*
  ) => (
      #[allow(non_snake_case)]
      pub mod $machine {
          #[derive(Clone,PartialEq,Eq,Debug)]
          pub enum State {
              __InvalidState__, // Just be able to match _ further down
              $($states),*
          }
          #[derive(PartialEq,Eq,Debug)]
          pub struct Machine {
              state: State,
          }

          pub fn new() -> Machine {
              Machine::new()
          }

          impl Machine {
              pub fn new() -> Machine {
                  Machine {
                      state: State::$initial
                  }
              }

              pub fn state(&self) -> State {
                  self.state.clone()
              }

              $(pub fn $meth(&mut self) -> Option<State> {
                  match self.state {
                      $( State::$from => { self.state = State::$to; Some(State::$to) } ),*
                          _ => None
                  }
              })*
          }
      }
));

#[cfg(test)]
mod tests {
    microstate!{
        Micro { New }
        states { New, Confirmed, Ignored }

        confirm {
            New => Confirmed
        }

        ignore {
            New => Ignored
        }

        reset {
            Confirmed => New
            Ignored   => New
        }
    }
    use self::Micro::State::*;

    #[test]
    fn test_transition_works() {
        let mut machine = Micro::new();

        assert_eq!(New, machine.state());

        assert_eq!(Some(Confirmed), machine.confirm());
        assert_eq!(Confirmed, machine.state());

        assert_eq!(None, machine.ignore());
        assert_eq!(Confirmed, machine.state());

        assert_eq!(Some(New), machine.reset());
        assert_eq!(New, machine.state());

        assert_eq!(Some(Ignored), machine.ignore());
        assert_eq!(Ignored, machine.state());
    }
}
<commit_msg>Hide __InvalidState__ in generated doc.<commit_after>//! MicroState
//!
//! A minimal Finite State Machine.
//!
//! Example:
//!
//! ```
//! #[macro_use] extern crate microstate;
//! microstate! {
//!     Simple { A }
//!     states { A, B }
//!
//!     next {
//!         A => B
//!         B => A
//!     }
//! }
//!
//! # fn main() {
//! use Simple::State::*;
//!
//! let mut machine = Simple::new();
//! assert_eq!(A, machine.state());
//! assert_eq!(Some(B), machine.next());
//! assert_eq!(Some(A), machine.next());
//! # }
//! ```

/// Create a new state machine
///
/// It takes a name, the initial value, all possible states
/// and the transitions.
///
/// See the main documentation for a proper example.
#[macro_export]
macro_rules! microstate (
  (
      $machine:ident { $initial:ident }
      states { $($states:ident),* }

      $($meth:ident {
          $($from:ident => $to:ident)*
      })*
  ) => (
      #[allow(non_snake_case)]
      pub mod $machine {
          #[derive(Clone,PartialEq,Eq,Debug)]
          pub enum State {
              #[doc(hidden)]
              __InvalidState__, // Just be able to match _ further down
              $($states),*
          }
          #[derive(PartialEq,Eq,Debug)]
          pub struct Machine {
              state: State,
          }

          pub fn new() -> Machine {
              Machine::new()
          }

          impl Machine {
              pub fn new() -> Machine {
                  Machine {
                      state: State::$initial
                  }
              }

              pub fn state(&self) -> State {
                  self.state.clone()
              }

              $(pub fn $meth(&mut self) -> Option<State> {
                  match self.state {
                      $( State::$from => { self.state = State::$to; Some(State::$to) } ),*
                          _ => None
                  }
              })*
          }
      }
));

#[cfg(test)]
mod tests {
    microstate!{
        Micro { New }
        states { New, Confirmed, Ignored }

        confirm {
            New => Confirmed
        }

        ignore {
            New => Ignored
        }

        reset {
            Confirmed => New
            Ignored   => New
        }
    }
    use self::Micro::State::*;

    #[test]
    fn test_transition_works() {
        let mut machine = Micro::new();

        assert_eq!(New, machine.state());

        assert_eq!(Some(Confirmed), machine.confirm());
        assert_eq!(Confirmed, machine.state());

        assert_eq!(None, machine.ignore());
        assert_eq!(Confirmed, machine.state());

        assert_eq!(Some(New), machine.reset());
        assert_eq!(New, machine.state());

        assert_eq!(Some(Ignored), machine.ignore());
        assert_eq!(Ignored, machine.state());
    }
}
<|endoftext|>