<commit_before>//! Structured keys.

use std::borrow::Borrow;
use std::fmt;

/// A type that can be converted into a [`Key`](struct.Key.html).
pub trait ToKey {
    /// Perform the conversion.
    fn to_key(&self) -> Key;
}

impl<'a, T> ToKey for &'a T
where
    T: ToKey + ?Sized,
{
    fn to_key(&self) -> Key {
        (**self).to_key()
    }
}

impl<'k> ToKey for Key<'k> {
    fn to_key(&self) -> Key {
        Key { key: self.key }
    }
}

impl ToKey for str {
    fn to_key(&self) -> Key {
        Key::from_str(self)
    }
}

/// A key in a structured key-value pair.
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Key<'k> {
    key: &'k str,
}

impl<'k> Key<'k> {
    /// Get a key from a borrowed string.
    pub fn from_str(key: &'k str) -> Self {
        Key { key }
    }

    /// Get a borrowed string from this key.
    pub fn as_str(&self) -> &str {
        self.key
    }
}

impl<'k> fmt::Display for Key<'k> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.key.fmt(f)
    }
}

impl<'k> AsRef<str> for Key<'k> {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl<'k> Borrow<str> for Key<'k> {
    fn borrow(&self) -> &str {
        self.as_str()
    }
}

impl<'k> From<&'k str> for Key<'k> {
    fn from(s: &'k str) -> Self {
        Key::from_str(s)
    }
}

#[cfg(feature = "std")]
mod std_support {
    use super::*;

    use std::borrow::Cow;

    impl ToKey for String {
        fn to_key(&self) -> Key {
            Key::from_str(self)
        }
    }

    impl<'a> ToKey for Cow<'a, str> {
        fn to_key(&self) -> Key {
            Key::from_str(self)
        }
    }
}

#[cfg(feature = "kv_unstable_sval")]
mod sval_support {
    use super::*;

    extern crate sval;

    use self::sval::value::{self, Value};

    impl<'a> Value for Key<'a> {
        fn stream(&self, stream: &mut value::Stream) -> value::Result {
            self.key.stream(stream)
        }
    }
}

#[cfg(feature = "kv_unstable_serde")]
mod serde_support {
    use super::*;

    extern crate serde;

    use self::serde::{Serialize, Serializer};

    impl<'a> Serialize for Key<'a> {
        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where
            S: Serializer,
        {
            self.key.serialize(serializer)
        }
    }
}

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

    #[test]
    fn key_from_string() {
        assert_eq!("a key", Key::from_str("a key").as_str());
    }
}
<commit_msg>clarify comment about derive impls<commit_after>//! Structured keys.

use std::borrow::Borrow;
use std::fmt;

/// A type that can be converted into a [`Key`](struct.Key.html).
pub trait ToKey {
    /// Perform the conversion.
    fn to_key(&self) -> Key;
}

impl<'a, T> ToKey for &'a T
where
    T: ToKey + ?Sized,
{
    fn to_key(&self) -> Key {
        (**self).to_key()
    }
}

impl<'k> ToKey for Key<'k> {
    fn to_key(&self) -> Key {
        Key { key: self.key }
    }
}

impl ToKey for str {
    fn to_key(&self) -> Key {
        Key::from_str(self)
    }
}

/// A key in a structured key-value pair.
// These impls must only be based on the as_str() representation of the key
// If a new field (such as an optional index) is added to the key they must not affect comparison
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Key<'k> {
    key: &'k str,
}

impl<'k> Key<'k> {
    /// Get a key from a borrowed string.
    pub fn from_str(key: &'k str) -> Self {
        Key { key }
    }

    /// Get a borrowed string from this key.
    pub fn as_str(&self) -> &str {
        self.key
    }
}

impl<'k> fmt::Display for Key<'k> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.key.fmt(f)
    }
}

impl<'k> AsRef<str> for Key<'k> {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl<'k> Borrow<str> for Key<'k> {
    fn borrow(&self) -> &str {
        self.as_str()
    }
}

impl<'k> From<&'k str> for Key<'k> {
    fn from(s: &'k str) -> Self {
        Key::from_str(s)
    }
}

#[cfg(feature = "std")]
mod std_support {
    use super::*;

    use std::borrow::Cow;

    impl ToKey for String {
        fn to_key(&self) -> Key {
            Key::from_str(self)
        }
    }

    impl<'a> ToKey for Cow<'a, str> {
        fn to_key(&self) -> Key {
            Key::from_str(self)
        }
    }
}

#[cfg(feature = "kv_unstable_sval")]
mod sval_support {
    use super::*;

    extern crate sval;

    use self::sval::value::{self, Value};

    impl<'a> Value for Key<'a> {
        fn stream(&self, stream: &mut value::Stream) -> value::Result {
            self.key.stream(stream)
        }
    }
}

#[cfg(feature = "kv_unstable_serde")]
mod serde_support {
    use super::*;

    extern crate serde;

    use self::serde::{Serialize, Serializer};

    impl<'a> Serialize for Key<'a> {
        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where
            S: Serializer,
        {
            self.key.serialize(serializer)
        }
    }
}

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

    #[test]
    fn key_from_string() {
        assert_eq!("a key", Key::from_str("a key").as_str());
    }
}
<|endoftext|>


<commit_before>/*!

DC (Distance Coding) forward and backward transformation.
Designed to be used on BWT block output for compression.

# Links

http://www.data-compression.info/Algorithms/DC/

# Example

```rust
use compress::bwt::dc;

let bytes = bytes!("abracadabra");
let distances = dc::encode_simple::<uint>(bytes);
let decoded = dc::decode_simple(bytes.len(), distances.as_slice());
```

# Credit

This is an original implementation.
Thanks to Edgar Binder for inventing DC!

*/

use std::{io, iter};
use vec = std::slice;
use super::mtf::MTF;

pub type Symbol = u8;
pub type Rank = u8;
pub static TotalSymbols: uint = 0x100;

/// Distance coding context
/// Has all the information potentially needed by the underlying coding model
#[deriving(Eq, Show)]
pub struct Context {
    /// current symbol
    symbol: Symbol,
    /// last known MTF rank
    last_rank: Rank,
    /// maximum possible distance
    distance_limit: uint,
}

impl Context {
    /// create a new distance context
    pub fn new(s: Symbol, r: Rank, dmax: uint) -> Context {
        Context {
            symbol: s,
            last_rank: r,
            distance_limit: dmax,
        }
    }
}

/// DC body iterator, can be used to encode distances
pub struct EncodeIterator<'a,'b,D> {
    data: iter::Enumerate<iter::Zip<vec::Items<'a,Symbol>,vec::Items<'b,D>>>,
    pos: [uint, ..TotalSymbols],
    last_active: uint,
    size: uint,
}

impl<'a, 'b, D: NumCast> EncodeIterator<'a,'b,D> {
    /// create a new encode iterator
    pub fn new(input: &'a [Symbol], dist: &'b [D], init: [uint, ..TotalSymbols]) -> EncodeIterator<'a,'b,D> {
        assert_eq!(input.len(), dist.len());
        EncodeIterator {
            data: input.iter().zip(dist.iter()).enumerate(),
            pos: init,
            last_active: 0,
            size: input.len()
        }
    }

    /// get the initial symbol positions, to be called before iteration
    pub fn get_init<'c>(&'c self) -> &'c [uint, ..TotalSymbols] {
        assert_eq!(self.last_active, 0);
        &self.pos
    }
}

impl<'a, 'b, D: Clone + Eq + NumCast> Iterator<(D,Context)> for EncodeIterator<'a,'b,D> {
    fn next(&mut self) -> Option<(D,Context)> {
        let filler: D = NumCast::from(self.size).unwrap();
        self.data.find(|&(_,(_,d))| *d != filler).map(|(i,(sym,d))| {
            let rank = self.last_active - self.pos[*sym as uint];
            assert!(rank < TotalSymbols);
            self.last_active = i+1;
            self.pos[*sym as uint] = i + 1 + d.to_uint().unwrap();
            debug!("Encoding distance {} at pos {} for symbol {}, computed rank {}, predicting next at {}",
                d.to_uint().unwrap(), i, *sym, rank, self.pos[*sym as uint]);
            (d.clone(), Context::new(*sym, rank as Rank, self.size-i))
        })
    }
}

/// Encode a block of bytes 'input'
/// write output distance stream into 'distances'
/// return: unique bytes encountered in the order they appear
/// with the corresponding initial distances
pub fn encode<'a, 'b, D: Clone + Copy + Eq + NumCast>(input: &'a [Symbol], distances: &'b mut [D], mtf: &mut MTF) -> EncodeIterator<'a,'b,D> {
    let n = input.len();
    assert_eq!(distances.len(), n);
    let mut num_unique = 0u;
    let mut last = [n, ..TotalSymbols];
    let mut init = [n, ..TotalSymbols];
    let filler: D = NumCast::from(n).unwrap();
    for (i,&sym) in input.iter().enumerate() {
        distances[i] = filler.clone();
        let base = last[sym as uint];
        last[sym as uint] = i;
        debug!("\tProcessing symbol {} at position {}, last known at {}", sym, i, base);
        if base == n {
            let rank = num_unique;
            mtf.symbols[rank] = sym;
            mtf.encode(sym);    //==rank
            // initial distances are not ordered to support re-shuffle
            debug!("\t\tUnique => assigning rank {}, encoding {}", rank, i);
            init[sym as uint] = i;
            num_unique += 1;
        }else {
            let rank = mtf.encode(sym) as uint;
            if rank > 0 {
                debug!("\t\tRegular at rank {}, encoding {}", rank, i-base-rank-1);
                assert!(i >= base+rank+1);
                distances[base] = NumCast::from(i-base-rank-1).unwrap();
            }
        }
    }
    for (rank,&sym) in mtf.symbols.slice_to(num_unique).iter().enumerate() {
        let base = last[sym as uint];
        debug!("\tSweep symbol {} of rank {}, last known at {}, encoding {}", sym, rank, base, n-base-rank-1);
        assert!(n >= base+rank+1);
        distances[base] = NumCast::from(n-base-rank-1).unwrap();
    }
    // a basic but expensive check, to be improved
    //assert_eq!(input.iter().zip(input.iter().skip(1)).zip(distances.iter()).
    //    position(|((&a,&b),d)| *d==filler && a!=b), None);
    EncodeIterator::new(input, distances, init)
}

/// Encode version with "batteries included" for quick testing
pub fn encode_simple<D: Clone + Copy + Eq + NumCast>(input: &[Symbol]) -> ~[D] {
    let n = input.len();
    let mut raw_dist: ~[D] = vec::from_elem(n, NumCast::from(0).unwrap());
    let mut eniter = encode(input, raw_dist, &mut MTF::new());
    let init: ~[D] = vec::from_fn(TotalSymbols, |i| NumCast::from(eniter.get_init()[i]).unwrap());
    init.iter().map(|d| d.clone()).chain(eniter.by_ref().map(|(d,_)| d)).collect()
}

/// Decode a block of distances given the initial symbol positions
pub fn decode(mut next: [uint,..TotalSymbols], output: &mut [Symbol], mtf: &mut MTF,
        fn_dist: |Context|->io::IoResult<uint>) -> io::IoResult<()> {

    let n = output.len();
    let mut i = 0u;
    for (sym,d) in next.iter().enumerate() {
        if *d < n {
            let mut j = i;
            while j>0u && next[mtf.symbols[j-1] as uint] > *d {
                mtf.symbols[j] = mtf.symbols[j-1];
                j -= 1;
            }
            mtf.symbols[j] = sym as Symbol;
            i += 1;
        }
    }
    if i<=1 {
        // redundant alphabet case
        let sym = mtf.symbols[0];
        for out in output.mut_iter()    {
            *out = sym;
        }
        return Ok(())
    }

    let alphabet_size = i;
    let mut ranks = [0 as Rank, ..TotalSymbols];
    for rank in range(0, i) {
        let sym = mtf.symbols[rank];
        debug!("\tRegistering symbol {} of rank {} at position {}",
            sym, rank, next[sym as uint]);
        ranks[sym as uint] = 0; //could use 'rank' but don't know how to derive it during encoding
    }

    i = 0u;
    while i<n {
        let sym = mtf.symbols[0];
        let stop = next[mtf.symbols[1] as uint];
        debug!("\tFilling region [{}-{}) with symbol {}", i, stop, sym);
        while i<stop    {
            output[i] = sym;
            i += 1;
        }
        let ctx = Context::new(sym, ranks[sym as uint], n+1-i);
        let future = match fn_dist(ctx) {
            Ok(d) => stop + d,
            Err(e) => return Err(e)
        };
        debug!("\t\tLooking for future position {}", future);
        assert!(future <= n);
        let mut rank = 1u;
        while rank < alphabet_size && future+rank > next[mtf.symbols[rank] as uint] {
            mtf.symbols[rank-1] = mtf.symbols[rank];
            rank += 1;
        }
        if rank < alphabet_size {
            debug!("\t\tFound sym {} of rank {} at position {}", mtf.symbols[rank],
                rank, next[mtf.symbols[rank] as uint]);
        }else {
            debug!("\t\tNot found");
        }
        mtf.symbols[rank-1] = sym;
        debug!("\t\tAssigning future pos {} for symbol {}", future+rank-1, sym);
        next[sym as uint] = future+rank-1;
        ranks[sym as uint] = (rank-1) as Rank;
    }
    assert_eq!(next.iter().position(|&d| d<n || d>=n+alphabet_size), None);
    assert_eq!(i, n);
    Ok(())
}

/// Decode version with "batteries included" for quick testing
pub fn decode_simple<D: ToPrimitive>(n: uint, distances: &[D]) -> ~[Symbol] {
    let mut output = vec::from_elem(n, 0 as Symbol);
    let mut init = [0u, ..TotalSymbols];
    for i in range(0, TotalSymbols) {
        init[i] = distances[i].to_uint().unwrap();
    }
    let mut di = TotalSymbols;
    decode(init, output.as_mut_slice(), &mut MTF::new(), |_ctx| {
        di += 1;
        if di > distances.len() {
            Err(io::standard_error(io::EndOfFile))
        }else {
            Ok(distances[di-1].to_uint().unwrap())
        }
    }).unwrap();
    output
}

#[cfg(test)]
mod test {
    use vec = std::slice;

    fn roundtrip(bytes: &[u8]) {
        info!("Roundtrip DC of size {}", bytes.len());
        let distances = super::encode_simple::<uint>(bytes);
        debug!("Roundtrip DC input: {:?}, distances: {:?}", bytes, distances);
        let decoded = super::decode_simple(bytes.len(), distances.as_slice());
        assert_eq!(decoded.as_slice(), bytes);
    }

    /// rountrip version that compares the coding contexts on the way
    fn roundtrip_ctx(bytes: &[u8]) {
        let n = bytes.len();
        info!("Roundtrip DC context of size {}", n);
        let mut mtf = super::super::mtf::MTF::new();
        let mut raw_dist = vec::from_elem(n, 0u16);
        let eniter = super::encode(bytes, raw_dist, &mut mtf);
        let mut init = [0u, ..super::TotalSymbols];
        for i in range(0u, super::TotalSymbols) {
            init[i] = eniter.get_init()[i];
        }
        // implicit iterator copies, or we can gather in one pass and then split
        let contexts: ~[super::Context] = eniter.map(|(_,ctx)| ctx).collect();
        let distances: ~[u16] = eniter.map(|(d,_)| d).collect();
        let mut output = vec::from_elem(n, 0u8);
        let mut di = 0u;
        super::decode(init, output.as_mut_slice(), &mut mtf, |ctx| {
            assert_eq!(contexts[di], ctx);
            di += 1;
            Ok(distances[di-1] as uint)
        }).unwrap();
        assert_eq!(di, distances.len());
        assert_eq!(output.as_slice(), bytes);
    }

    #[test]
    fn roundtrips() {
        roundtrip(bytes!("teeesst_dc"));
        roundtrip(bytes!(""));
        roundtrip(include_bin!("../data/test.txt"));
    }

    #[test]
    fn roundtrips_context() {
        roundtrip_ctx(bytes!("teeesst_dc"));
        roundtrip_ctx(bytes!("../data/test.txt"));
    }
}
<commit_msg>DC - made context members public<commit_after>/*!

DC (Distance Coding) forward and backward transformation.
Designed to be used on BWT block output for compression.

# Links

http://www.data-compression.info/Algorithms/DC/

# Example

```rust
use compress::bwt::dc;

let bytes = bytes!("abracadabra");
let distances = dc::encode_simple::<uint>(bytes);
let decoded = dc::decode_simple(bytes.len(), distances.as_slice());
```

# Credit

This is an original implementation.
Thanks to Edgar Binder for inventing DC!

*/

use std::{io, iter};
use vec = std::slice;
use super::mtf::MTF;

pub type Symbol = u8;
pub type Rank = u8;
pub static TotalSymbols: uint = 0x100;

/// Distance coding context
/// Has all the information potentially needed by the underlying coding model
#[deriving(Eq, Show)]
pub struct Context {
    /// current symbol
    pub symbol: Symbol,
    /// last known MTF rank
    pub last_rank: Rank,
    /// maximum possible distance
    pub distance_limit: uint,
}

impl Context {
    /// create a new distance context
    pub fn new(s: Symbol, r: Rank, dmax: uint) -> Context {
        Context {
            symbol: s,
            last_rank: r,
            distance_limit: dmax,
        }
    }
}

/// DC body iterator, can be used to encode distances
pub struct EncodeIterator<'a,'b,D> {
    data: iter::Enumerate<iter::Zip<vec::Items<'a,Symbol>,vec::Items<'b,D>>>,
    pos: [uint, ..TotalSymbols],
    last_active: uint,
    size: uint,
}

impl<'a, 'b, D: NumCast> EncodeIterator<'a,'b,D> {
    /// create a new encode iterator
    pub fn new(input: &'a [Symbol], dist: &'b [D], init: [uint, ..TotalSymbols]) -> EncodeIterator<'a,'b,D> {
        assert_eq!(input.len(), dist.len());
        EncodeIterator {
            data: input.iter().zip(dist.iter()).enumerate(),
            pos: init,
            last_active: 0,
            size: input.len()
        }
    }

    /// get the initial symbol positions, to be called before iteration
    pub fn get_init<'c>(&'c self) -> &'c [uint, ..TotalSymbols] {
        assert_eq!(self.last_active, 0);
        &self.pos
    }
}

impl<'a, 'b, D: Clone + Eq + NumCast> Iterator<(D,Context)> for EncodeIterator<'a,'b,D> {
    fn next(&mut self) -> Option<(D,Context)> {
        let filler: D = NumCast::from(self.size).unwrap();
        self.data.find(|&(_,(_,d))| *d != filler).map(|(i,(sym,d))| {
            let rank = self.last_active - self.pos[*sym as uint];
            assert!(rank < TotalSymbols);
            self.last_active = i+1;
            self.pos[*sym as uint] = i + 1 + d.to_uint().unwrap();
            debug!("Encoding distance {} at pos {} for symbol {}, computed rank {}, predicting next at {}",
                d.to_uint().unwrap(), i, *sym, rank, self.pos[*sym as uint]);
            (d.clone(), Context::new(*sym, rank as Rank, self.size-i))
        })
    }
}

/// Encode a block of bytes 'input'
/// write output distance stream into 'distances'
/// return: unique bytes encountered in the order they appear
/// with the corresponding initial distances
pub fn encode<'a, 'b, D: Clone + Copy + Eq + NumCast>(input: &'a [Symbol], distances: &'b mut [D], mtf: &mut MTF) -> EncodeIterator<'a,'b,D> {
    let n = input.len();
    assert_eq!(distances.len(), n);
    let mut num_unique = 0u;
    let mut last = [n, ..TotalSymbols];
    let mut init = [n, ..TotalSymbols];
    let filler: D = NumCast::from(n).unwrap();
    for (i,&sym) in input.iter().enumerate() {
        distances[i] = filler.clone();
        let base = last[sym as uint];
        last[sym as uint] = i;
        debug!("\tProcessing symbol {} at position {}, last known at {}", sym, i, base);
        if base == n {
            let rank = num_unique;
            mtf.symbols[rank] = sym;
            mtf.encode(sym);    //==rank
            // initial distances are not ordered to support re-shuffle
            debug!("\t\tUnique => assigning rank {}, encoding {}", rank, i);
            init[sym as uint] = i;
            num_unique += 1;
        }else {
            let rank = mtf.encode(sym) as uint;
            if rank > 0 {
                debug!("\t\tRegular at rank {}, encoding {}", rank, i-base-rank-1);
                assert!(i >= base+rank+1);
                distances[base] = NumCast::from(i-base-rank-1).unwrap();
            }
        }
    }
    for (rank,&sym) in mtf.symbols.slice_to(num_unique).iter().enumerate() {
        let base = last[sym as uint];
        debug!("\tSweep symbol {} of rank {}, last known at {}, encoding {}", sym, rank, base, n-base-rank-1);
        assert!(n >= base+rank+1);
        distances[base] = NumCast::from(n-base-rank-1).unwrap();
    }
    // a basic but expensive check, to be improved
    //assert_eq!(input.iter().zip(input.iter().skip(1)).zip(distances.iter()).
    //    position(|((&a,&b),d)| *d==filler && a!=b), None);
    EncodeIterator::new(input, distances, init)
}

/// Encode version with "batteries included" for quick testing
pub fn encode_simple<D: Clone + Copy + Eq + NumCast>(input: &[Symbol]) -> ~[D] {
    let n = input.len();
    let mut raw_dist: ~[D] = vec::from_elem(n, NumCast::from(0).unwrap());
    let mut eniter = encode(input, raw_dist, &mut MTF::new());
    let init: ~[D] = vec::from_fn(TotalSymbols, |i| NumCast::from(eniter.get_init()[i]).unwrap());
    init.iter().map(|d| d.clone()).chain(eniter.by_ref().map(|(d,_)| d)).collect()
}

/// Decode a block of distances given the initial symbol positions
pub fn decode(mut next: [uint,..TotalSymbols], output: &mut [Symbol], mtf: &mut MTF,
        fn_dist: |Context|->io::IoResult<uint>) -> io::IoResult<()> {

    let n = output.len();
    let mut i = 0u;
    for (sym,d) in next.iter().enumerate() {
        if *d < n {
            let mut j = i;
            while j>0u && next[mtf.symbols[j-1] as uint] > *d {
                mtf.symbols[j] = mtf.symbols[j-1];
                j -= 1;
            }
            mtf.symbols[j] = sym as Symbol;
            i += 1;
        }
    }
    if i<=1 {
        // redundant alphabet case
        let sym = mtf.symbols[0];
        for out in output.mut_iter()    {
            *out = sym;
        }
        return Ok(())
    }

    let alphabet_size = i;
    let mut ranks = [0 as Rank, ..TotalSymbols];
    for rank in range(0, i) {
        let sym = mtf.symbols[rank];
        debug!("\tRegistering symbol {} of rank {} at position {}",
            sym, rank, next[sym as uint]);
        ranks[sym as uint] = 0; //could use 'rank' but don't know how to derive it during encoding
    }

    i = 0u;
    while i<n {
        let sym = mtf.symbols[0];
        let stop = next[mtf.symbols[1] as uint];
        debug!("\tFilling region [{}-{}) with symbol {}", i, stop, sym);
        while i<stop    {
            output[i] = sym;
            i += 1;
        }
        let ctx = Context::new(sym, ranks[sym as uint], n+1-i);
        let future = match fn_dist(ctx) {
            Ok(d) => stop + d,
            Err(e) => return Err(e)
        };
        debug!("\t\tLooking for future position {}", future);
        assert!(future <= n);
        let mut rank = 1u;
        while rank < alphabet_size && future+rank > next[mtf.symbols[rank] as uint] {
            mtf.symbols[rank-1] = mtf.symbols[rank];
            rank += 1;
        }
        if rank < alphabet_size {
            debug!("\t\tFound sym {} of rank {} at position {}", mtf.symbols[rank],
                rank, next[mtf.symbols[rank] as uint]);
        }else {
            debug!("\t\tNot found");
        }
        mtf.symbols[rank-1] = sym;
        debug!("\t\tAssigning future pos {} for symbol {}", future+rank-1, sym);
        next[sym as uint] = future+rank-1;
        ranks[sym as uint] = (rank-1) as Rank;
    }
    assert_eq!(next.iter().position(|&d| d<n || d>=n+alphabet_size), None);
    assert_eq!(i, n);
    Ok(())
}

/// Decode version with "batteries included" for quick testing
pub fn decode_simple<D: ToPrimitive>(n: uint, distances: &[D]) -> ~[Symbol] {
    let mut output = vec::from_elem(n, 0 as Symbol);
    let mut init = [0u, ..TotalSymbols];
    for i in range(0, TotalSymbols) {
        init[i] = distances[i].to_uint().unwrap();
    }
    let mut di = TotalSymbols;
    decode(init, output.as_mut_slice(), &mut MTF::new(), |_ctx| {
        di += 1;
        if di > distances.len() {
            Err(io::standard_error(io::EndOfFile))
        }else {
            Ok(distances[di-1].to_uint().unwrap())
        }
    }).unwrap();
    output
}

#[cfg(test)]
mod test {
    use vec = std::slice;

    fn roundtrip(bytes: &[u8]) {
        info!("Roundtrip DC of size {}", bytes.len());
        let distances = super::encode_simple::<uint>(bytes);
        debug!("Roundtrip DC input: {:?}, distances: {:?}", bytes, distances);
        let decoded = super::decode_simple(bytes.len(), distances.as_slice());
        assert_eq!(decoded.as_slice(), bytes);
    }

    /// rountrip version that compares the coding contexts on the way
    fn roundtrip_ctx(bytes: &[u8]) {
        let n = bytes.len();
        info!("Roundtrip DC context of size {}", n);
        let mut mtf = super::super::mtf::MTF::new();
        let mut raw_dist = vec::from_elem(n, 0u16);
        let eniter = super::encode(bytes, raw_dist, &mut mtf);
        let mut init = [0u, ..super::TotalSymbols];
        for i in range(0u, super::TotalSymbols) {
            init[i] = eniter.get_init()[i];
        }
        // implicit iterator copies, or we can gather in one pass and then split
        let contexts: ~[super::Context] = eniter.map(|(_,ctx)| ctx).collect();
        let distances: ~[u16] = eniter.map(|(d,_)| d).collect();
        let mut output = vec::from_elem(n, 0u8);
        let mut di = 0u;
        super::decode(init, output.as_mut_slice(), &mut mtf, |ctx| {
            assert_eq!(contexts[di], ctx);
            di += 1;
            Ok(distances[di-1] as uint)
        }).unwrap();
        assert_eq!(di, distances.len());
        assert_eq!(output.as_slice(), bytes);
    }

    #[test]
    fn roundtrips() {
        roundtrip(bytes!("teeesst_dc"));
        roundtrip(bytes!(""));
        roundtrip(include_bin!("../data/test.txt"));
    }

    #[test]
    fn roundtrips_context() {
        roundtrip_ctx(bytes!("teeesst_dc"));
        roundtrip_ctx(bytes!("../data/test.txt"));
    }
}
<|endoftext|>


<commit_before>use std::process;
use std::process::Command;
use std::{env, fs};

fn main() {
    let usage = r#"tutorial-maker <username> <program-name> <language> <program-type>

    <language> can only be the following:

    - rust

    <program-type> can only be the following:

    - library
"#;
    let args: Vec<String> = env::args().collect();

    if args.len() < 5 {
        println!("{usage}");

        process::exit(1);
    }

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

    let username = args[1].to_lowercase();
    let program_name = args[2].to_lowercase();
    let args3 = args[3].to_lowercase();
    let language = if args3 == "rust" {
        "rust"
    } else {
        println!("{usage}");

        process::exit(1);
    };

    let args4 = args[4].to_lowercase();
    let program_type = if args4 == "library" {
        "library"
    } else {
        println!("{usage}");

        process::exit(1);
    };

    let path_name = format!("repos/github/{username}");

    println!("mkdir -p path_name: {path_name}");

    fs::create_dir_all(&path_name).expect("unable to create path name");

    println!("cd {path_name}");

    env::set_current_dir(&path_name).expect("changing directory failed");

    let app_name = format!("{program_name}-{program_type}");
    let folder_name = format!("{program_name}-{language}-{program_type}");
    let repo_name = format!("{username}/{folder_name}");

    println!("rm -rf {folder_name}");

    let removing_folder_output = Command::new("rm")
        .arg("-rf")
        .arg(&folder_name)
        .output()
        .expect("removing folder failed");

    if removing_folder_output.status.success() {
        println!(
            "cloning stdout: {}",
            String::from_utf8_lossy(&removing_folder_output.stdout)
        );
    } else {
        println!(
            "cloning stderr: {}",
            String::from_utf8_lossy(&removing_folder_output.stderr)
        );

        process::exit(1);
    }

    println!("gh repo clone {repo_name}");

    let cloning_output = Command::new("gh")
        .arg("repo")
        .arg("clone")
        .arg(&repo_name)
        .output()
        .expect("cloning failed");

    if cloning_output.status.success() {
        println!(
            "cloning stdout: {}",
            String::from_utf8_lossy(&cloning_output.stdout)
        );
    } else {
        println!(
            "cloning stderr: {}",
            String::from_utf8_lossy(&cloning_output.stderr)
        );

        process::exit(1);
    }

    println!("cd {folder_name}");

    env::set_current_dir(&folder_name).expect("changing directory failed");

    println!("git rev-list --all --reverse");

    let rev_list_output = Command::new("git")
        .arg("rev-list")
        .arg("--all")
        .arg("--reverse")
        .output()
        .expect("rev-list failed");

    if rev_list_output.status.success() {
        let rev_list_output_cow = String::from_utf8_lossy(&rev_list_output.stdout).to_string();

        for (_, commit_hash) in rev_list_output_cow.split("\n").enumerate() {
            if !commit_hash.is_empty() {
                println!("git checkout {commit_hash}");

                let checkout_output = Command::new("git")
                    .arg("checkout")
                    .arg(commit_hash)
                    .output()
                    .expect("checkout failed");

                if checkout_output.status.success() {
                    println!(
                        "checkout stdout: {}",
                        String::from_utf8_lossy(&checkout_output.stdout)
                    );
                } else {
                    println!(
                        "checkout stderr: {}",
                        String::from_utf8_lossy(&checkout_output.stderr)
                    );

                    process::exit(1);
                }

                println!("cd {app_name}");

                env::set_current_dir(&app_name).expect("changing directory failed");

                println!("cargo test");

                let test_output = Command::new("cargo")
                    .arg("test")
                    .output()
                    .expect("test failed");

                if test_output.status.success() {
                    println!(
                        "test stdout: {}",
                        String::from_utf8_lossy(&test_output.stdout)
                    );
                } else {
                    println!(
                        "test stderr: {}",
                        String::from_utf8_lossy(&test_output.stderr)
                    );

                    process::exit(1);
                }
            }
        }

        println!(
            "rev-list stdout: {}",
            String::from_utf8_lossy(&rev_list_output.stdout)
        );
    } else {
        println!(
            "rev-list stderr: {}",
            String::from_utf8_lossy(&rev_list_output.stderr)
        );

        process::exit(1);
    }
}
<commit_msg>only cd into directory if it exists<commit_after>use std::process;
use std::process::Command;
use std::{env, fs};

fn main() {
    let usage = r#"tutorial-maker <username> <program-name> <language> <program-type>

    <language> can only be the following:

    - rust

    <program-type> can only be the following:

    - library
"#;
    let args: Vec<String> = env::args().collect();

    if args.len() < 5 {
        println!("{usage}");

        process::exit(1);
    }

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

    let username = args[1].to_lowercase();
    let program_name = args[2].to_lowercase();
    let args3 = args[3].to_lowercase();
    let language = if args3 == "rust" {
        "rust"
    } else {
        println!("{usage}");

        process::exit(1);
    };

    let args4 = args[4].to_lowercase();
    let program_type = if args4 == "library" {
        "library"
    } else {
        println!("{usage}");

        process::exit(1);
    };

    let path_name = format!("repos/github/{username}");

    println!("mkdir -p path_name: {path_name}");

    fs::create_dir_all(&path_name).expect("unable to create path name");

    println!("cd {path_name}");

    env::set_current_dir(&path_name).expect("changing directory failed");

    let app_name = format!("{program_name}-{program_type}");
    let folder_name = format!("{program_name}-{language}-{program_type}");
    let repo_name = format!("{username}/{folder_name}");

    println!("rm -rf {folder_name}");

    let removing_folder_output = Command::new("rm")
        .arg("-rf")
        .arg(&folder_name)
        .output()
        .expect("removing folder failed");

    if removing_folder_output.status.success() {
        println!(
            "cloning stdout: {}",
            String::from_utf8_lossy(&removing_folder_output.stdout)
        );
    } else {
        println!(
            "cloning stderr: {}",
            String::from_utf8_lossy(&removing_folder_output.stderr)
        );

        process::exit(1);
    }

    println!("gh repo clone {repo_name}");

    let cloning_output = Command::new("gh")
        .arg("repo")
        .arg("clone")
        .arg(&repo_name)
        .output()
        .expect("cloning failed");

    if cloning_output.status.success() {
        println!(
            "cloning stdout: {}",
            String::from_utf8_lossy(&cloning_output.stdout)
        );
    } else {
        println!(
            "cloning stderr: {}",
            String::from_utf8_lossy(&cloning_output.stderr)
        );

        process::exit(1);
    }

    println!("cd {folder_name}");

    env::set_current_dir(&folder_name).expect("changing directory failed");

    println!("git rev-list --all --reverse");

    let rev_list_output = Command::new("git")
        .arg("rev-list")
        .arg("--all")
        .arg("--reverse")
        .output()
        .expect("rev-list failed");

    if rev_list_output.status.success() {
        let rev_list_output_cow = String::from_utf8_lossy(&rev_list_output.stdout).to_string();

        for (_, commit_hash) in rev_list_output_cow.split("\n").enumerate() {
            if !commit_hash.is_empty() {
                println!("git checkout {commit_hash}");

                let checkout_output = Command::new("git")
                    .arg("checkout")
                    .arg(commit_hash)
                    .output()
                    .expect("checkout failed");

                if checkout_output.status.success() {
                    println!(
                        "checkout stdout: {}",
                        String::from_utf8_lossy(&checkout_output.stdout)
                    );
                } else {
                    println!(
                        "checkout stderr: {}",
                        String::from_utf8_lossy(&checkout_output.stderr)
                    );

                    process::exit(1);
                }

                let mut path = env::current_dir().expect("getting current directory failed");
                path.push(&app_name);
                let metadata = fs::metadata(path);
                match metadata {
                  Ok(_) => {},
                  Err(_) => {
                      continue;
                  }
                };

                println!("cd {app_name}");

                env::set_current_dir(&app_name).expect("changing directory failed");

                println!("cargo test");

                let test_output = Command::new("cargo")
                    .arg("test")
                    .output()
                    .expect("test failed");

                if test_output.status.success() {
                    println!(
                        "test stdout: {}",
                        String::from_utf8_lossy(&test_output.stdout)
                    );
                } else {
                    println!(
                        "test stderr: {}",
                        String::from_utf8_lossy(&test_output.stderr)
                    );

                    process::exit(1);
                }
            }
        }

        println!(
            "rev-list stdout: {}",
            String::from_utf8_lossy(&rev_list_output.stdout)
        );
    } else {
        println!(
            "rev-list stderr: {}",
            String::from_utf8_lossy(&rev_list_output.stderr)
        );

        process::exit(1);
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 Serde YAML Developers
//
// 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.

//! YAML Serialization
//!
//! This module provides YAML serialization with the type `Serializer`.

use std::{fmt, io, mem};

use yaml_rust::{Yaml, YamlEmitter};
use yaml_rust::yaml;

use serde::ser;

use super::error::{Error, Result};

/// A structure for serializing a Rust value into a YAML value.
pub struct Serializer {
    /// The YAML value to hold the result.
    doc: Yaml,
}

impl Serializer {
    pub fn new() -> Self {
        Serializer {
            doc: Yaml::Null,
        }
    }

    pub fn take(self) -> Yaml {
        self.doc
    }
}

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

impl ser::Serializer for Serializer {
    type Error = Error;
    type SeqState = yaml::Array;
    type TupleState = yaml::Array;
    type TupleStructState = yaml::Array;
    type TupleVariantState = (&'static str, yaml::Array);
    type MapState = (Option<yaml::Yaml>, yaml::Hash);
    type StructState = (Option<yaml::Yaml>, yaml::Hash);
    type StructVariantState = (&'static str, (Option<yaml::Yaml>, yaml::Hash));

    fn serialize_bool(&mut self, v: bool) -> Result<()> {
        self.doc = Yaml::Boolean(v);
        Ok(())
    }

    fn serialize_isize(&mut self, v: isize) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i8(&mut self, v: i8) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i16(&mut self, v: i16) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i32(&mut self, v: i32) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i64(&mut self, v: i64) -> Result<()> {
        self.doc = Yaml::Integer(v);
        Ok(())
    }

    fn serialize_usize(&mut self, v: usize) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_u8(&mut self, v: u8) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_u16(&mut self, v: u16) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_u32(&mut self, v: u32) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_u64(&mut self, v: u64) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_f32(&mut self, v: f32) -> Result<()> {
        self.doc = Yaml::Real(v.to_string());
        Ok(())
    }

    fn serialize_f64(&mut self, v: f64) -> Result<()> {
        self.doc = Yaml::Real(v.to_string());
        Ok(())
    }

    fn serialize_char(&mut self, value: char) -> Result<()> {
        self.doc = Yaml::String(value.to_string());
        Ok(())
    }

    fn serialize_str(&mut self, value: &str) -> Result<()> {
        self.doc = Yaml::String(String::from(value));
        Ok(())
    }

    fn serialize_bytes(&mut self, value: &[u8]) -> Result<()> {
        let mut state = try!(self.serialize_seq(Some(value.len())));
        for c in value {
            try!(self.serialize_seq_elt(&mut state, c));
        }
        self.serialize_seq_end(state)
    }

    fn serialize_unit(&mut self) -> Result<()> {
        self.doc = Yaml::Null;
        Ok(())
    }

    fn serialize_unit_struct(&mut self, _name: &'static str) -> Result<()> {
        self.doc = Yaml::Null;
        Ok(())
    }

    fn serialize_unit_variant(
        &mut self,
        _name: &str,
        _variant_index: usize,
        variant: &str
    ) -> Result<()> {
        self.doc = Yaml::String(String::from(variant));
        Ok(())
    }

    fn serialize_newtype_struct<T>(
        &mut self,
        _name: &'static str,
        value: T
    ) -> Result<()>
        where T: ser::Serialize,
    {
        value.serialize(self)
    }

    fn serialize_newtype_variant<T>(
        &mut self,
        _name: &str,
        _variant_index: usize,
        variant: &str,
        value: T
    ) -> Result<()>
        where T: ser::Serialize,
    {
        self.doc = singleton_hash(try!(to_yaml(variant)), try!(to_yaml(value)));
        Ok(())
    }

    fn serialize_none(&mut self) -> Result<()> {
        self.serialize_unit()
    }

    fn serialize_some<V>(&mut self, value: V) -> Result<()>
        where V: ser::Serialize,
    {
        value.serialize(self)
    }

    fn serialize_seq(&mut self, len: Option<usize>) -> Result<yaml::Array> {
        Ok(match len {
            None => yaml::Array::new(),
            Some(len) => yaml::Array::with_capacity(len),
        })
    }

    fn serialize_seq_elt<T>(
        &mut self,
        state: &mut yaml::Array,
        elem: T
    ) -> Result<()>
        where T: ser::Serialize,
    {
        state.push(try!(to_yaml(elem)));
        Ok(())
    }

    fn serialize_seq_end(&mut self, state: yaml::Array) -> Result<()> {
        self.doc = Yaml::Array(state);
        Ok(())
    }

    fn serialize_seq_fixed_size(&mut self, len: usize) -> Result<yaml::Array> {
        self.serialize_seq(Some(len))
    }

    fn serialize_tuple(&mut self, len: usize) -> Result<yaml::Array> {
        self.serialize_seq(Some(len))
    }

    fn serialize_tuple_elt<T>(
        &mut self,
        state: &mut yaml::Array,
        elem: T
    ) -> Result<()>
        where T: ser::Serialize,
    {
        self.serialize_seq_elt(state, elem)
    }

    fn serialize_tuple_end(&mut self, state: yaml::Array) -> Result<()> {
        self.serialize_seq_end(state)
    }

    fn serialize_tuple_struct(
        &mut self,
        _name: &'static str,
        len: usize
    ) -> Result<yaml::Array> {
        self.serialize_seq(Some(len))
    }

    fn serialize_tuple_struct_elt<V>(
        &mut self,
        state: &mut yaml::Array,
        value: V
    ) -> Result<()>
        where V: ser::Serialize,
    {
        self.serialize_seq_elt(state, value)
    }

    fn serialize_tuple_struct_end(&mut self, state: yaml::Array) -> Result<()> {
        self.serialize_seq_end(state)
    }

    fn serialize_tuple_variant(
        &mut self,
        _enum: &'static str,
        _idx: usize,
        variant: &'static str,
        len: usize
    ) -> Result<(&'static str, yaml::Array)> {
        let state = try!(self.serialize_seq(Some(len)));
        Ok((variant, state))
    }

    fn serialize_tuple_variant_elt<V>(
        &mut self,
        state: &mut (&'static str, yaml::Array),
        v: V
    ) -> Result<()>
        where V: ser::Serialize,
    {
        self.serialize_seq_elt(&mut state.1, v)
    }

    fn serialize_tuple_variant_end(
        &mut self,
        state: (&'static str, yaml::Array)
    ) -> Result<()> {
        try!(self.serialize_seq_end(state.1));
        self.doc = singleton_hash(try!(to_yaml(state.0)),
                                  mem::replace(&mut self.doc, Yaml::Null));
        Ok(())
    }

    fn serialize_map(&mut self, _len: Option<usize>) -> Result<(Option<yaml::Yaml>, yaml::Hash)> {
        Ok((None, yaml::Hash::new()))
    }

    fn serialize_map_key<T>(
        &mut self,
        state: &mut (Option<yaml::Yaml>, yaml::Hash),
        key: T
    ) -> Result<()>
        where T: ser::Serialize
    {
        state.0 = Some(try!(to_yaml(key)));
        Ok(())
    }

    fn serialize_map_value<T>(
        &mut self,
        state: &mut (Option<yaml::Yaml>, yaml::Hash),
        value: T
    ) -> Result<()>
        where T: ser::Serialize
    {
        match state.0.take() {
            Some(key) => state.1.insert(key, try!(to_yaml(value))),
            None => {
                return Err(Error::Custom("serialize_map_value called without matching \
                                          serialize_map_key call".to_owned()));
            }
        };
        Ok(())
    }

    fn serialize_map_end(&mut self, state: (Option<yaml::Yaml>, yaml::Hash)) -> Result<()> {
        self.doc = Yaml::Hash(state.1);
        Ok(())
    }

    fn serialize_struct(
        &mut self,
        _name: &'static str,
        len: usize
    ) -> Result<(Option<yaml::Yaml>, yaml::Hash)> {
        self.serialize_map(Some(len))
    }

    fn serialize_struct_elt<V>(
        &mut self,
        state: &mut (Option<yaml::Yaml>, yaml::Hash),
        key: &'static str,
        value: V
    ) -> Result<()>
        where V: ser::Serialize,
    {
        try!(self.serialize_map_key(state, key));
        self.serialize_map_value(state, value)
    }

    fn serialize_struct_end(&mut self, state: (Option<yaml::Yaml>, yaml::Hash)) -> Result<()> {
        self.serialize_map_end(state)
    }

    fn serialize_struct_variant(
        &mut self,
        _enum: &'static str,
        _idx: usize,
        variant: &'static str,
        len: usize
    ) -> Result<(&'static str, (Option<yaml::Yaml>, yaml::Hash))> {
        let state = try!(self.serialize_map(Some(len)));
        Ok((variant, state))
    }

    fn serialize_struct_variant_elt<V>(
        &mut self,
        state: &mut (&'static str, (Option<yaml::Yaml>, yaml::Hash)),
        field: &'static str,
        v: V
    ) -> Result<()>
        where V: ser::Serialize,
    {
        try!(self.serialize_map_key(&mut state.1, field));
        self.serialize_map_value(&mut state.1, v)
    }

    fn serialize_struct_variant_end(
        &mut self,
        state: (&'static str, (Option<yaml::Yaml>, yaml::Hash))
    ) -> Result<()> {
        try!(self.serialize_map_end(state.1));
        self.doc = singleton_hash(try!(to_yaml(state.0)),
                                  mem::replace(&mut self.doc, Yaml::Null));
        Ok(())
    }
}

pub fn to_writer<W, T>(writer: &mut W, value: &T) -> Result<()>
    where W: io::Write,
          T: ser::Serialize,
{
    let doc = try!(to_yaml(value));
    let mut writer_adapter = FmtToIoWriter {
        writer: writer,
    };
    try!(YamlEmitter::new(&mut writer_adapter).dump(&doc));
    Ok(())
}

pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
    where T: ser::Serialize,
{
    let mut vec = Vec::with_capacity(128);
    try!(to_writer(&mut vec, value));
    Ok(vec)
}

pub fn to_string<T>(value: &T) -> Result<String>
    where T: ser::Serialize,
{
    Ok(try!(String::from_utf8(try!(to_vec(value)))))
}

/// The yaml-rust library uses `fmt.Write` intead of `io.Write` so this is a
/// simple adapter.
struct FmtToIoWriter<'a, W>
    where W: io::Write + 'a,
{
    writer: &'a mut W,
}

impl<'a, W> fmt::Write for FmtToIoWriter<'a, W>
    where W: io::Write + 'a,
{
    fn write_str(&mut self, s: &str) -> fmt::Result {
        if self.writer.write(s.as_bytes()).is_err() {
            return Err(fmt::Error);
        }
        if self.writer.flush().is_err() {
            return Err(fmt::Error);
        }
        Ok(())
    }
}

fn to_yaml<T>(elem: T) -> Result<Yaml>
    where T: ser::Serialize,
{
    let mut ser = Serializer::new();
    try!(elem.serialize(&mut ser));
    Ok(ser.take())
}

fn singleton_hash(k: Yaml, v: Yaml) -> Yaml {
    let mut hash = yaml::Hash::new();
    hash.insert(k, v);
    Yaml::Hash(hash)
}
<commit_msg>Flush once per to_writer<commit_after>// Copyright 2016 Serde YAML Developers
//
// 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.

//! YAML Serialization
//!
//! This module provides YAML serialization with the type `Serializer`.

use std::{fmt, io, mem};

use yaml_rust::{Yaml, YamlEmitter};
use yaml_rust::yaml;

use serde::ser;

use super::error::{Error, Result};

/// A structure for serializing a Rust value into a YAML value.
pub struct Serializer {
    /// The YAML value to hold the result.
    doc: Yaml,
}

impl Serializer {
    pub fn new() -> Self {
        Serializer {
            doc: Yaml::Null,
        }
    }

    pub fn take(self) -> Yaml {
        self.doc
    }
}

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

impl ser::Serializer for Serializer {
    type Error = Error;
    type SeqState = yaml::Array;
    type TupleState = yaml::Array;
    type TupleStructState = yaml::Array;
    type TupleVariantState = (&'static str, yaml::Array);
    type MapState = (Option<yaml::Yaml>, yaml::Hash);
    type StructState = (Option<yaml::Yaml>, yaml::Hash);
    type StructVariantState = (&'static str, (Option<yaml::Yaml>, yaml::Hash));

    fn serialize_bool(&mut self, v: bool) -> Result<()> {
        self.doc = Yaml::Boolean(v);
        Ok(())
    }

    fn serialize_isize(&mut self, v: isize) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i8(&mut self, v: i8) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i16(&mut self, v: i16) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i32(&mut self, v: i32) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i64(&mut self, v: i64) -> Result<()> {
        self.doc = Yaml::Integer(v);
        Ok(())
    }

    fn serialize_usize(&mut self, v: usize) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_u8(&mut self, v: u8) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_u16(&mut self, v: u16) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_u32(&mut self, v: u32) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_u64(&mut self, v: u64) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_f32(&mut self, v: f32) -> Result<()> {
        self.doc = Yaml::Real(v.to_string());
        Ok(())
    }

    fn serialize_f64(&mut self, v: f64) -> Result<()> {
        self.doc = Yaml::Real(v.to_string());
        Ok(())
    }

    fn serialize_char(&mut self, value: char) -> Result<()> {
        self.doc = Yaml::String(value.to_string());
        Ok(())
    }

    fn serialize_str(&mut self, value: &str) -> Result<()> {
        self.doc = Yaml::String(String::from(value));
        Ok(())
    }

    fn serialize_bytes(&mut self, value: &[u8]) -> Result<()> {
        let mut state = try!(self.serialize_seq(Some(value.len())));
        for c in value {
            try!(self.serialize_seq_elt(&mut state, c));
        }
        self.serialize_seq_end(state)
    }

    fn serialize_unit(&mut self) -> Result<()> {
        self.doc = Yaml::Null;
        Ok(())
    }

    fn serialize_unit_struct(&mut self, _name: &'static str) -> Result<()> {
        self.doc = Yaml::Null;
        Ok(())
    }

    fn serialize_unit_variant(
        &mut self,
        _name: &str,
        _variant_index: usize,
        variant: &str
    ) -> Result<()> {
        self.doc = Yaml::String(String::from(variant));
        Ok(())
    }

    fn serialize_newtype_struct<T>(
        &mut self,
        _name: &'static str,
        value: T
    ) -> Result<()>
        where T: ser::Serialize,
    {
        value.serialize(self)
    }

    fn serialize_newtype_variant<T>(
        &mut self,
        _name: &str,
        _variant_index: usize,
        variant: &str,
        value: T
    ) -> Result<()>
        where T: ser::Serialize,
    {
        self.doc = singleton_hash(try!(to_yaml(variant)), try!(to_yaml(value)));
        Ok(())
    }

    fn serialize_none(&mut self) -> Result<()> {
        self.serialize_unit()
    }

    fn serialize_some<V>(&mut self, value: V) -> Result<()>
        where V: ser::Serialize,
    {
        value.serialize(self)
    }

    fn serialize_seq(&mut self, len: Option<usize>) -> Result<yaml::Array> {
        Ok(match len {
            None => yaml::Array::new(),
            Some(len) => yaml::Array::with_capacity(len),
        })
    }

    fn serialize_seq_elt<T>(
        &mut self,
        state: &mut yaml::Array,
        elem: T
    ) -> Result<()>
        where T: ser::Serialize,
    {
        state.push(try!(to_yaml(elem)));
        Ok(())
    }

    fn serialize_seq_end(&mut self, state: yaml::Array) -> Result<()> {
        self.doc = Yaml::Array(state);
        Ok(())
    }

    fn serialize_seq_fixed_size(&mut self, len: usize) -> Result<yaml::Array> {
        self.serialize_seq(Some(len))
    }

    fn serialize_tuple(&mut self, len: usize) -> Result<yaml::Array> {
        self.serialize_seq(Some(len))
    }

    fn serialize_tuple_elt<T>(
        &mut self,
        state: &mut yaml::Array,
        elem: T
    ) -> Result<()>
        where T: ser::Serialize,
    {
        self.serialize_seq_elt(state, elem)
    }

    fn serialize_tuple_end(&mut self, state: yaml::Array) -> Result<()> {
        self.serialize_seq_end(state)
    }

    fn serialize_tuple_struct(
        &mut self,
        _name: &'static str,
        len: usize
    ) -> Result<yaml::Array> {
        self.serialize_seq(Some(len))
    }

    fn serialize_tuple_struct_elt<V>(
        &mut self,
        state: &mut yaml::Array,
        value: V
    ) -> Result<()>
        where V: ser::Serialize,
    {
        self.serialize_seq_elt(state, value)
    }

    fn serialize_tuple_struct_end(&mut self, state: yaml::Array) -> Result<()> {
        self.serialize_seq_end(state)
    }

    fn serialize_tuple_variant(
        &mut self,
        _enum: &'static str,
        _idx: usize,
        variant: &'static str,
        len: usize
    ) -> Result<(&'static str, yaml::Array)> {
        let state = try!(self.serialize_seq(Some(len)));
        Ok((variant, state))
    }

    fn serialize_tuple_variant_elt<V>(
        &mut self,
        state: &mut (&'static str, yaml::Array),
        v: V
    ) -> Result<()>
        where V: ser::Serialize,
    {
        self.serialize_seq_elt(&mut state.1, v)
    }

    fn serialize_tuple_variant_end(
        &mut self,
        state: (&'static str, yaml::Array)
    ) -> Result<()> {
        try!(self.serialize_seq_end(state.1));
        self.doc = singleton_hash(try!(to_yaml(state.0)),
                                  mem::replace(&mut self.doc, Yaml::Null));
        Ok(())
    }

    fn serialize_map(&mut self, _len: Option<usize>) -> Result<(Option<yaml::Yaml>, yaml::Hash)> {
        Ok((None, yaml::Hash::new()))
    }

    fn serialize_map_key<T>(
        &mut self,
        state: &mut (Option<yaml::Yaml>, yaml::Hash),
        key: T
    ) -> Result<()>
        where T: ser::Serialize
    {
        state.0 = Some(try!(to_yaml(key)));
        Ok(())
    }

    fn serialize_map_value<T>(
        &mut self,
        state: &mut (Option<yaml::Yaml>, yaml::Hash),
        value: T
    ) -> Result<()>
        where T: ser::Serialize
    {
        match state.0.take() {
            Some(key) => state.1.insert(key, try!(to_yaml(value))),
            None => {
                return Err(Error::Custom("serialize_map_value called without matching \
                                          serialize_map_key call".to_owned()));
            }
        };
        Ok(())
    }

    fn serialize_map_end(&mut self, state: (Option<yaml::Yaml>, yaml::Hash)) -> Result<()> {
        self.doc = Yaml::Hash(state.1);
        Ok(())
    }

    fn serialize_struct(
        &mut self,
        _name: &'static str,
        len: usize
    ) -> Result<(Option<yaml::Yaml>, yaml::Hash)> {
        self.serialize_map(Some(len))
    }

    fn serialize_struct_elt<V>(
        &mut self,
        state: &mut (Option<yaml::Yaml>, yaml::Hash),
        key: &'static str,
        value: V
    ) -> Result<()>
        where V: ser::Serialize,
    {
        try!(self.serialize_map_key(state, key));
        self.serialize_map_value(state, value)
    }

    fn serialize_struct_end(&mut self, state: (Option<yaml::Yaml>, yaml::Hash)) -> Result<()> {
        self.serialize_map_end(state)
    }

    fn serialize_struct_variant(
        &mut self,
        _enum: &'static str,
        _idx: usize,
        variant: &'static str,
        len: usize
    ) -> Result<(&'static str, (Option<yaml::Yaml>, yaml::Hash))> {
        let state = try!(self.serialize_map(Some(len)));
        Ok((variant, state))
    }

    fn serialize_struct_variant_elt<V>(
        &mut self,
        state: &mut (&'static str, (Option<yaml::Yaml>, yaml::Hash)),
        field: &'static str,
        v: V
    ) -> Result<()>
        where V: ser::Serialize,
    {
        try!(self.serialize_map_key(&mut state.1, field));
        self.serialize_map_value(&mut state.1, v)
    }

    fn serialize_struct_variant_end(
        &mut self,
        state: (&'static str, (Option<yaml::Yaml>, yaml::Hash))
    ) -> Result<()> {
        try!(self.serialize_map_end(state.1));
        self.doc = singleton_hash(try!(to_yaml(state.0)),
                                  mem::replace(&mut self.doc, Yaml::Null));
        Ok(())
    }
}

pub fn to_writer<W, T>(writer: &mut W, value: &T) -> Result<()>
    where W: io::Write,
          T: ser::Serialize,
{
    let doc = try!(to_yaml(value));
    {
        let mut writer_adapter = FmtToIoWriter {
            writer: writer,
        };
        try!(YamlEmitter::new(&mut writer_adapter).dump(&doc));
    }
    try!(writer.flush());
    Ok(())
}

pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
    where T: ser::Serialize,
{
    let mut vec = Vec::with_capacity(128);
    try!(to_writer(&mut vec, value));
    Ok(vec)
}

pub fn to_string<T>(value: &T) -> Result<String>
    where T: ser::Serialize,
{
    Ok(try!(String::from_utf8(try!(to_vec(value)))))
}

/// The yaml-rust library uses `fmt.Write` intead of `io.Write` so this is a
/// simple adapter.
struct FmtToIoWriter<'a, W>
    where W: io::Write + 'a,
{
    writer: &'a mut W,
}

impl<'a, W> fmt::Write for FmtToIoWriter<'a, W>
    where W: io::Write + 'a,
{
    fn write_str(&mut self, s: &str) -> fmt::Result {
        if self.writer.write(s.as_bytes()).is_err() {
            return Err(fmt::Error);
        }
        Ok(())
    }
}

fn to_yaml<T>(elem: T) -> Result<Yaml>
    where T: ser::Serialize,
{
    let mut ser = Serializer::new();
    try!(elem.serialize(&mut ser));
    Ok(ser.take())
}

fn singleton_hash(k: Yaml, v: Yaml) -> Yaml {
    let mut hash = yaml::Hash::new();
    hash.insert(k, v);
    Yaml::Hash(hash)
}
<|endoftext|>


<commit_before>//! Utility macros

/// Expands into a series of for loops with the given block of code which should
/// treat each type uniformly.
///
/// This is to avoid dynamic dispatch when chaining iterators over generic
/// collections when the types are known.
#[macro_export]
macro_rules! for_sequence {
  (
    $pattern:pat in $($collection:ident),* $do:block
  ) => {
    $(for $pattern in $collection $do)+
  }
}

/// Print the stringified expression followed by its debug formatting
#[macro_export]
macro_rules! show {
  ($e:expr) => {
    println!("{}: {:?}", stringify!($e), $e);
  }
}

/// Print the stringified expression followed by its pretty debug formatting
#[macro_export]
macro_rules! pretty {
  ($e:expr) => {
    println!("{}: {:#?}", stringify!($e), $e);
  }
}

/// Print the stringified expression followed by its display formatting
#[macro_export]
macro_rules! display {
  ($e:expr) => {
    println!("{}: {}", stringify!($e), $e);
  }
}

/// Print the stringified expression followed by its bitstring formatting
#[macro_export]
macro_rules! bits {
  ($e:expr) => {
    println!("{}: {:b}", stringify!($e), $e);
  }
}

/// Print the stringified expression followed by its hexadecimal formatting
#[macro_export]
macro_rules! hex {
  ($e:expr) => {
    println!("{}: {:x}", stringify!($e), $e);
  }
}

/// Print the stringified expression followed by its pointer formatting
#[macro_export]
macro_rules! address {
  ($e:expr) => {
    println!("{}: {:p}", stringify!($e), $e);
  }
}
<commit_msg>change for_sequence! macro to take expressions for iterators<commit_after>//! Utility macros

/// Expands into a series of for loops with the given block of code which should
/// treat each type uniformly.
///
/// This is to avoid dynamic dispatch when chaining iterators over generic
/// collections when the types are known.
#[macro_export]
macro_rules! for_sequence {
  (
    $pattern:pat in $($iter:expr),* $do:block
  ) => {
    $(for $pattern in $iter $do)+
  }
}

/// Print the stringified expression followed by its debug formatting
#[macro_export]
macro_rules! show {
  ($e:expr) => {
    println!("{}: {:?}", stringify!($e), $e);
  }
}

/// Print the stringified expression followed by its pretty debug formatting
#[macro_export]
macro_rules! pretty {
  ($e:expr) => {
    println!("{}: {:#?}", stringify!($e), $e);
  }
}

/// Print the stringified expression followed by its display formatting
#[macro_export]
macro_rules! display {
  ($e:expr) => {
    println!("{}: {}", stringify!($e), $e);
  }
}

/// Print the stringified expression followed by its bitstring formatting
#[macro_export]
macro_rules! bits {
  ($e:expr) => {
    println!("{}: {:b}", stringify!($e), $e);
  }
}

/// Print the stringified expression followed by its hexadecimal formatting
#[macro_export]
macro_rules! hex {
  ($e:expr) => {
    println!("{}: {:x}", stringify!($e), $e);
  }
}

/// Print the stringified expression followed by its pointer formatting
#[macro_export]
macro_rules! address {
  ($e:expr) => {
    println!("{}: {:p}", stringify!($e), $e);
  }
}
<|endoftext|>


<commit_before>
#[macro_export]
macro_rules! impl_func_delegate {
	($name:ident) => (
		impl FuncDelegate for $name {
		    fn delegate(&mut self) -> &mut Function {
    		    &mut self.delegate
    		}
		}

	)
}

#[macro_export]
macro_rules! impl_mod_delegate {
	($name:ident) => (
        impl<T: ::tensor::NumLimits<T>> ModDelegate<T> for $name<T> {
		    fn delegate(&mut self) -> &mut Module<T> {
    		    &mut self.delegate
    		}
            fn params_iter_mut(&mut self) -> ::std::vec::IntoIter<Variable<T>> {
                let mut v : Vec<Variable<T>> = Vec::new();
                for name in self.delegate()._params.clone().iter() {
                    if let Some(id) = self.get_param(name) {
                        v.push(id.into())
                    }
                }
                v.into_iter()
            }
    fn _apply(&mut self, callback: fn(&mut ::tensor::Tensor<T>)) {
        let mod_names = self.delegate()._modules.clone();
        for name in mod_names {
            let module = self.get_module(name);
            module._apply(callback)
        }
        for mut param in self.params_iter_mut() {
            param.apply(callback);
            if let &mut Some(ref mut g) = param.grad() {
                g.apply(callback)
            }
            /* see also _buffers */
        }
    }
    fn apply(&mut self, callback: fn(&mut ModIntf<T>)) {
        let mod_names = self.delegate()._modules.clone();
        for name in mod_names {
            let module = self.get_module(name);
            module.apply(callback)
        }
        callback(self)
    }
    }

	)
}

#[macro_export]
macro_rules! typecast {
    ($value:expr, $type:ident) => {$value as *mut $type}
}

#[macro_export]
macro_rules! impl_func {
	($name:ident) => (
		#[derive(Clone)]
		pub struct $name {
    		delegate: Function,
		}
		impl $name {
    		pub fn new() -> FIWrap<Self> {
        		FIWrap::new($name { delegate: Function::new() })
    		}
		}
		impl FuncDelegate for $name {
		    fn delegate(&mut self) -> &mut Function {
    		    &mut self.delegate
    		}
		}

	)
}

#[macro_export]
macro_rules! impl_func_args {
	($name:ident, $args:ident) => (

#[derive(Clone)]
pub struct $name {
    delegate: Function,
    args: $args,
}

impl $name {
    pub fn new(args: & $args) -> FIWrap<Self> {
        FIWrap::new($name {
                        delegate: Function::new(),
                        args: args.clone(),
                    })
    }
}

impl FuncDelegate for $name {
    fn delegate(&mut self) -> &mut Function {
        &mut self.delegate
    }
}
)}

#[macro_export]
macro_rules! map(
    { $($key:expr => $value:expr),+ } => {
        {
            let mut m = ::std::collections::HashMap::new();
            $(
                m.insert($key, $value);
            )+
            m
        }
     };
);

#[macro_export]
macro_rules! map_opt(
    { $($key:expr => $value:expr),+ } => {
        {
            let mut m = ::std::collections::HashMap::<&'static str, OptimVal>::new();
            $(
                m.insert($key, $value .into());
            )+
            m
        }
     };
);
<commit_msg>implement tensor_impl macro<commit_after>
#[macro_export]
macro_rules! impl_func_delegate {
	($name:ident) => (
		impl FuncDelegate for $name {
		    fn delegate(&mut self) -> &mut Function {
    		    &mut self.delegate
    		}
		}

	)
}

#[macro_export]
macro_rules! impl_mod_delegate {
	($name:ident) => (
        impl<T: ::tensor::NumLimits<T>> ModDelegate<T> for $name<T> {
		    fn delegate(&mut self) -> &mut Module<T> {
    		    &mut self.delegate
    		}
            fn params_iter_mut(&mut self) -> ::std::vec::IntoIter<Variable<T>> {
                let mut v : Vec<Variable<T>> = Vec::new();
                for name in self.delegate()._params.clone().iter() {
                    if let Some(id) = self.get_param(name) {
                        v.push(id.into())
                    }
                }
                v.into_iter()
            }
    fn _apply(&mut self, callback: fn(&mut ::tensor::Tensor<T>)) {
        let mod_names = self.delegate()._modules.clone();
        for name in mod_names {
            let module = self.get_module(name);
            module._apply(callback)
        }
        for mut param in self.params_iter_mut() {
            param.apply(callback);
            if let &mut Some(ref mut g) = param.grad() {
                g.apply(callback)
            }
            /* see also _buffers */
        }
    }
    fn apply(&mut self, callback: fn(&mut ModIntf<T>)) {
        let mod_names = self.delegate()._modules.clone();
        for name in mod_names {
            let module = self.get_module(name);
            module.apply(callback)
        }
        callback(self)
    }
    }

	)
}

#[macro_export]
macro_rules! typecast {
    ($value:expr, $type:ident) => {$value as *mut $type}
}

#[macro_export]
macro_rules! impl_tensor_impl {
    ($name:ident, $type:ident, $thname:ident) => {
    impl TensorImpl<$type> for $name {
    fn new(&self) -> RefTI<$type> {
        RcMutNew($name ::new())
    }
    fn add(&self, value: $type, output: &TIArg<$type>) {
        let out = typecast!(output.inner(), $thname);
        unsafe {
            concat_idents!(TH, $name, _add)(out, self.t, value);
        };
    }
    fn inner(&self) -> *mut ::std::os::raw::c_void {
        self.t as *mut ::std::os::raw::c_void
    }
    fn addt(&self, value: $type, rhs: &TIArg<$type>, output: &TIArg<$type>) {
        let out = typecast!(output.inner(), $thname);
        let rhsp = typecast!(rhs.inner(), $thname);
        unsafe {
            concat_idents!(TH, $name, _add)(out, rhsp, value);
        };
    }
    }
    impl<'a> Index<&'a [isize]> for $name {
    type Output = $type;

    fn index(&self, idx: &'a [isize]) -> &Self::Output {
        let mut index: isize = 0;
        let lastidx = max(0, idx.len() as isize - 1) as usize;
        if idx.len() != self.dims.len() {
            panic!("bad dimlen")
        }
        for i in 0..lastidx {
            if idx[i] >= self.dims[i] {
                panic!("bad dimlen")
            }
            index += idx[i] * self.dims[i]
        }
        if idx[lastidx] >= self.dims[lastidx] {
            panic!("bad dimlen")
        }
        index += idx[lastidx];
        &self.storage[index]
    }
    }

    impl<'a> IndexMut<&'a [isize]> for $name {
    fn index_mut(&mut self, idx: &'a [isize]) -> &mut Self::Output {
        let mut index: isize = 0;
        let lastidx = max(0, idx.len() as isize - 1) as usize;
        if idx.len() != self.dims.len() {
            panic!("bad dimlen")
        }
        for i in 0..lastidx {
            if idx[i] >= self.dims[i] {
                panic!("bad dimlen")
            }
            index += idx[i] * self.dims[i]
        }
        if idx[lastidx] >= self.dims[lastidx] {
            panic!("bad dimlen")
        }
        index += idx[lastidx];
        &mut self.storage[index]
    }
    }

    }
}

#[macro_export]
macro_rules! impl_func {
	($name:ident) => (
		#[derive(Clone)]
		pub struct $name {
    		delegate: Function,
		}
		impl $name {
    		pub fn new() -> FIWrap<Self> {
        		FIWrap::new($name { delegate: Function::new() })
    		}
		}
		impl FuncDelegate for $name {
		    fn delegate(&mut self) -> &mut Function {
    		    &mut self.delegate
    		}
		}

	)
}

#[macro_export]
macro_rules! impl_func_args {
	($name:ident, $args:ident) => (

#[derive(Clone)]
pub struct $name {
    delegate: Function,
    args: $args,
}

impl $name {
    pub fn new(args: & $args) -> FIWrap<Self> {
        FIWrap::new($name {
                        delegate: Function::new(),
                        args: args.clone(),
                    })
    }
}

impl FuncDelegate for $name {
    fn delegate(&mut self) -> &mut Function {
        &mut self.delegate
    }
}
)}

#[macro_export]
macro_rules! map(
    { $($key:expr => $value:expr),+ } => {
        {
            let mut m = ::std::collections::HashMap::new();
            $(
                m.insert($key, $value);
            )+
            m
        }
     };
);

#[macro_export]
macro_rules! map_opt(
    { $($key:expr => $value:expr),+ } => {
        {
            let mut m = ::std::collections::HashMap::<&'static str, OptimVal>::new();
            $(
                m.insert($key, $value .into());
            )+
            m
        }
     };
);
<|endoftext|>


<commit_before>macro_rules! t_number {
    ($val:expr, $span:expr) => (::lexer::Token::Number { val: $val, span: $span, });
}

macro_rules! t_string {
    ($val:expr, $span:expr) => (::lexer::Token::String { val: $val.to_string(), span: $span, });
}

macro_rules! t_symbol {
    ($name:expr, $span:expr) => (::lexer::Token::Symbol {
        ns: None,
        name: $name.to_string(),
        span: $span,
    });
    ($ns:expr, $name:expr, $span:expr) => (::lexer::Token::Symbol {
        ns: Some($ns.to_string()),
        name: $name.to_string(),
        span: $span,
    });
}

macro_rules! t_keyword {
    ($name:expr, $span:expr) => (::lexer::Token::Keyword {
        ns: None,
        name: $name.to_string(),
        span: $span,
    });
    ($ns:expr, $name:expr, $span:expr) => (::lexer::Token::Keyword {
        ns: Some($ns.to_string()),
        name: $name.to_string(),
        span: $span,
    });
}

macro_rules! t_list_start {
    ($span:expr) => (::lexer::Token::ListStart { span: $span });
}

macro_rules! t_list_end {
    ($span:expr) => (::lexer::Token::ListEnd { span: $span });
}

macro_rules! t_vec_start {
    ($span:expr) => (::lexer::Token::VecStart { span: $span });
}

macro_rules! t_vec_end {
    ($span:expr) => (::lexer::Token::VecEnd { span: $span });
}

macro_rules! t_quote {
    ($span:expr) => (::lexer::Token::Quote { span: $span });
}

macro_rules! t_unquote {
    ($span:expr) => (::lexer::Token::Unquote { span: $span });
}

macro_rules! t_unquote_splicing {
    ($span:expr) => (::lexer::Token::UnquoteSplicing { span: $span });
}

macro_rules! t_syntax_quote {
    ($span:expr) => (::lexer::Token::SyntaxQuote { span: $span });
}

macro_rules! span {
    ($start_line:expr, $start_col:expr, $end_line:expr, $end_col:expr) => (
        ::lexer::Span::new($start_line, $start_col, $end_line, $end_col);
    )
}

#[macro_export]
macro_rules! n_number {
    ($e:expr) => ($crate::Node::Number($e))
}

#[macro_export]
macro_rules! n_bool {
    ($e:expr) => ($crate::Node::Bool($e))
}

#[macro_export]
macro_rules! n_string {
    ($e:expr) => ($crate::Node::String($e.to_string()))
}

#[macro_export]
macro_rules! n_symbol {
    ($name:expr) => ($crate::Node::Symbol {
        ns: None,
        name: $name.to_string(),
    });
    ($ns:expr, $name:expr) => ($crate::Node::Symbol {
        ns: Some($ns.to_string()),
        name: $name.to_string(),
    });
}

#[macro_export]
macro_rules! n_keyword {
    ($name:expr) => ($crate::Node::Keyword {
        ns: None,
        name: $name.to_string(),
    });
    ($ns:expr, $name:expr) => ($crate::Node::Keyword {
        ns: Some($ns.to_string()),
        name: $name.to_string(),
    });
}

#[macro_export]
macro_rules! n_list {
    ($($e:expr),*) => ($crate::Node::List(vec![$($e),*]))
}

#[macro_export]
macro_rules! n_vec {
    ($($e:expr),*) => ($crate::Node::Vec(vec![$($e),*]))
}

#[macro_export]
macro_rules! n_def {
    ($sym:expr, $e:expr) => ($crate::Node::Def {
        sym: $sym.to_string(),
        expr: Box::new($e),
    })
}

#[macro_export]
macro_rules! n_fn {
    ([$($params:expr),*], [$($e:expr),*]) => ($crate::Node::Fn {
        params: vec![$($params),*],
        body: vec![$($e),*],
    })
}

#[macro_export]
macro_rules! n_macro {
    ([$($params:expr),*], [$($e:expr),*]) => ($crate::Node::Macro {
        params: vec![$($params),*],
        body: vec![$($e),*],
    })
}

#[macro_export]
macro_rules! n_call {
    ($name:expr, $($arg:expr),*) => ($crate::Node::Call {
        ns: None,
        name: $name.to_string(),
        args: vec![$($arg),*],
    });
    ($ns:expr, $name:expr, $($arg:expr),*) => ($crate::Node::Call {
        ns: Some($ns.to_string()),
        name: $name.to_string(),
        args: vec![$($arg),*],
    });
}

#[macro_export]
macro_rules! n_let {
    ([$($s:expr, $e:expr),*], $($body:expr),*) => ($crate::Node::Let {
        bindings: vec![$($s, $e),*],
        body: vec![$($body),*],
    })
}

#[macro_export]
macro_rules! is_file {
    ($md:expr) => ($md.map(|s| s.is_file()).unwrap_or(false))
}

#[macro_export]
macro_rules! is_file_exists {
    ($md:expr) => ($md.is_ok())
}
<commit_msg>Add macros for Alias variant of Node<commit_after>macro_rules! t_number {
    ($val:expr, $span:expr) => (::lexer::Token::Number { val: $val, span: $span, });
}

macro_rules! t_string {
    ($val:expr, $span:expr) => (::lexer::Token::String { val: $val.to_string(), span: $span, });
}

macro_rules! t_symbol {
    ($name:expr, $span:expr) => (::lexer::Token::Symbol {
        ns: None,
        name: $name.to_string(),
        span: $span,
    });
    ($ns:expr, $name:expr, $span:expr) => (::lexer::Token::Symbol {
        ns: Some($ns.to_string()),
        name: $name.to_string(),
        span: $span,
    });
}

macro_rules! t_keyword {
    ($name:expr, $span:expr) => (::lexer::Token::Keyword {
        ns: None,
        name: $name.to_string(),
        span: $span,
    });
    ($ns:expr, $name:expr, $span:expr) => (::lexer::Token::Keyword {
        ns: Some($ns.to_string()),
        name: $name.to_string(),
        span: $span,
    });
}

macro_rules! t_list_start {
    ($span:expr) => (::lexer::Token::ListStart { span: $span });
}

macro_rules! t_list_end {
    ($span:expr) => (::lexer::Token::ListEnd { span: $span });
}

macro_rules! t_vec_start {
    ($span:expr) => (::lexer::Token::VecStart { span: $span });
}

macro_rules! t_vec_end {
    ($span:expr) => (::lexer::Token::VecEnd { span: $span });
}

macro_rules! t_quote {
    ($span:expr) => (::lexer::Token::Quote { span: $span });
}

macro_rules! t_unquote {
    ($span:expr) => (::lexer::Token::Unquote { span: $span });
}

macro_rules! t_unquote_splicing {
    ($span:expr) => (::lexer::Token::UnquoteSplicing { span: $span });
}

macro_rules! t_syntax_quote {
    ($span:expr) => (::lexer::Token::SyntaxQuote { span: $span });
}

macro_rules! span {
    ($start_line:expr, $start_col:expr, $end_line:expr, $end_col:expr) => (
        ::lexer::Span::new($start_line, $start_col, $end_line, $end_col);
    )
}

#[macro_export]
macro_rules! n_number {
    ($e:expr) => ($crate::Node::Number($e))
}

#[macro_export]
macro_rules! n_bool {
    ($e:expr) => ($crate::Node::Bool($e))
}

#[macro_export]
macro_rules! n_string {
    ($e:expr) => ($crate::Node::String($e.to_string()))
}

#[macro_export]
macro_rules! n_symbol {
    ($name:expr) => ($crate::Node::Symbol {
        ns: None,
        name: $name.to_string(),
    });
    ($ns:expr, $name:expr) => ($crate::Node::Symbol {
        ns: Some($ns.to_string()),
        name: $name.to_string(),
    });
}

#[macro_export]
macro_rules! n_keyword {
    ($name:expr) => ($crate::Node::Keyword {
        ns: None,
        name: $name.to_string(),
    });
    ($ns:expr, $name:expr) => ($crate::Node::Keyword {
        ns: Some($ns.to_string()),
        name: $name.to_string(),
    });
}

#[macro_export]
macro_rules! n_list {
    ($($e:expr),*) => ($crate::Node::List(vec![$($e),*]))
}

#[macro_export]
macro_rules! n_vec {
    ($($e:expr),*) => ($crate::Node::Vec(vec![$($e),*]))
}

#[macro_export]
macro_rules! n_def {
    ($sym:expr, $e:expr) => ($crate::Node::Def {
        sym: $sym.to_string(),
        expr: Box::new($e),
    })
}

#[macro_export]
macro_rules! n_fn {
    ([$($params:expr),*], [$($e:expr),*]) => ($crate::Node::Fn {
        params: vec![$($params),*],
        body: vec![$($e),*],
    })
}

#[macro_export]
macro_rules! n_macro {
    ([$($params:expr),*], [$($e:expr),*]) => ($crate::Node::Macro {
        params: vec![$($params),*],
        body: vec![$($e),*],
    })
}

#[macro_export]
macro_rules! n_call {
    ($name:expr, $($arg:expr),*) => ($crate::Node::Call {
        ns: None,
        name: $name.to_string(),
        args: vec![$($arg),*],
    });
    ($ns:expr, $name:expr, $($arg:expr),*) => ($crate::Node::Call {
        ns: Some($ns.to_string()),
        name: $name.to_string(),
        args: vec![$($arg),*],
    });
}

#[macro_export]
macro_rules! n_let {
    ([$($s:expr, $e:expr),*], $($body:expr),*) => ($crate::Node::Let {
        bindings: vec![$($s, $e),*],
        body: vec![$($body),*],
    })
}

#[macro_export]
macro_rules! n_alias {
    ($ns:expr, $name:expr) => ($crate::Node::Alias {
        ns: $ns.to_string(),
        name: $name.to_string(),
    });
}

#[macro_export]
macro_rules! is_file {
    ($md:expr) => ($md.map(|s| s.is_file()).unwrap_or(false))
}

#[macro_export]
macro_rules! is_file_exists {
    ($md:expr) => ($md.is_ok())
}
<|endoftext|>


<commit_before>#[macro_export]
macro_rules! parse {
    // RET_TYPED := '<' $ty ',' $ty '>' $expr
    // special case for _, since it is not a $ty
    ( @RET($i:expr); < _        , $e_ty:ty > $e:expr ) => { $i.ret::<_, $e_ty>($e) }; // allows for skipping type
    ( @RET($i:expr); < $t_ty:ty , $e_ty:ty > $e:expr ) => { $i.ret::<$t_ty, $e_ty>($e) };

    // RET_PLAIN := $expr
    ( @RET($i:expr); $e:expr ) => { $i.ret($e) };

    // ERR_TYPED := '<' $ty ',' $ty '>' $expr
    // special case for _, since it is not a $ty
    ( @ERR($i:expr); < $t_ty:ty , _        > $e:expr ) => { $i.err::<$t_ty, _>($e) }; // allows for skipping type
    ( @ERR($i:expr); < $t_ty:ty , $e_ty:ty > $e:expr ) => { $i.err::<$t_ty, $e_ty>($e) };

    // ERR_PLAIN := $expr
    ( @ERR($i:expr); $e:expr ) => { $i.err($e) };

    // VAR    := $ident ':' $ty / $pat
    ( @BIND($i:expr); $v:ident : $v_ty:ty = $($t:tt)* ) => { parse!{ @ACTION($i, $v: $v_ty); $($t)* } };
    ( @BIND($i:expr); $v:pat              = $($t:tt)* ) => { parse!{ @ACTION($i, $v); $($t)* } };

    // ACTION := INLINE_ACTION / NAMED_ACTION

    // INLINE_ACTION := $ident '->' $expr
    // version with expression following, nonterminal:
    ( @ACTION($i:expr, $($v:tt)+); $v:ident -> $e:expr ; $($t:tt)*) => { parse!{ @CONCAT({ let $v = $i; $e }; $($v)+); $($t)* } };
    ( @ACTION($i:expr, $($v:tt)+); $v:ident -> $e:expr )            => { { let $v = $i; $e } };

    // NAMED_ACTION  := $ident '(' ($expr ',')* ','? ')'
    // version with expression following, nonterminal:
    ( @ACTION($i:expr, $($v:tt)+); $f:ident ( $($p:expr),* $(,)*) ; $($t:tt)* ) => { parse!{ @CONCAT($f($i, $($p),*); $($v)+); $($t)* } };
    ( @ACTION($i:expr, $($v:tt)+); $f:ident ( $($p:expr),* $(,)*) )             => { $f($i, $($p),*) };

    // Ties an expression together with the next, using the bind operator
    // invoked from @ACTION and @BIND (via @ACTION)
    ( @CONCAT($i:expr; _); $($tail:tt)* )         => { $i.bind(|i, _| parse!{ i; $($tail)* }) };
    ( @CONCAT($i:expr; $($v:tt)+); $($tail:tt)* ) => { $i.bind(|i, $($v)+| parse!{ i; $($tail)* }) };

    // EXPR := ( BIND ';' / THEN ';' )* (RET / ERR / THEN)

    // BIND   := 'let' VAR '=' ACTION
    ( $i:expr ; let $($tail:tt)+ ) => { parse!{ @BIND($i); $($tail)* } };
    // RET := 'ret' ( RET_TYPED / RET_PLAIN )
    ( $i:expr ; ret $($tail:tt)+ ) => { parse!{ @RET($i); $($tail)* } };
    // ERR := 'err' ( ERR_TYPED / ERR_PLAIN )
    ( $i:expr ; err $($tail:tt)+ ) => { parse!{ @ERR($i); $($tail)* } };
    // THEN   := ACTION
    // needs to be last since it is the most general
    ( $i:expr ; $($tail:tt)+ )     => { parse!{ @ACTION($i, _); $($tail)+ } };

    // Terminals:
    ( $i:expr ; ) => { $i };
    ( $i:expr )   => { $i };
}

#[cfg(test)]
mod test {
    /// Simplified implementation of the emulated monad using linear types.
    #[derive(Debug, Eq, PartialEq)]
    struct Input(i64);
    /// Simplified implementation of the emulated monad using linear types.
    #[derive(Debug, Eq, PartialEq)]
    enum Data<T, E> {
        Value(i64, T),
        Error(i64, E),
    }

    impl Input {
        fn ret<T, E>(self, t: T) -> Data<T, E> {
            Data::Value(self.0, t)
        }

        fn err<T, E>(self, e: E) -> Data<T, E> {
            Data::Error(self.0, e)
        }
    }

    impl<T, E> Data<T, E> {
        fn bind<F, U, V = E>(self, f: F) -> Data<U, V>
          where F: FnOnce(Input, T) -> Data<U, V>,
                V: From<E> {
            match self {
                Data::Value(i, t) => f(Input(i), t).map_err(From::from),
                Data::Error(i, e) => Data::Error(i, From::from(e)),
            }
        }

        fn map_err<F, V>(self, f: F) -> Data<T, V>
          where F: FnOnce(E) -> V {
            match self {
                Data::Value(i, t) => Data::Value(i, t),
                Data::Error(i, e) => Data::Error(i, f(e)),
            }
        }
    }

    #[test]
    fn empty() {
        let i = 123;

        let r = parse!{i};

        assert_eq!(r, 123);
    }

    #[test]
    fn empty_expr() {
        let r = parse!{1 + 2};

        assert_eq!(r, 3);
    }

    #[test]
    fn ret() {
        let i = Input(123);

        // Type annotation necessary since ret leaves E free
        let r: Data<_, ()> = parse!{i; ret "foo"};

        assert_eq!(r, Data::Value(123, "foo"));
    }

    #[test]
    fn ret_typed() {
        let i = Input(123);

        let r = parse!{i; ret <_, ()> "foo"};

        assert_eq!(r, Data::Value(123, "foo"));
    }

    #[test]
    fn ret_typed2() {
        let i = Input(123);

        let r = parse!{i; ret <&str, ()> "foo"};

        assert_eq!(r, Data::Value(123, "foo"));
    }

    #[test]
    fn err() {
        let i = Input(123);

        // Type annotation necessary since err leaves T free
        let r: Data<(), _> = parse!{i; err "foo"};

        assert_eq!(r, Data::Error(123, "foo"));
    }

    #[test]
    fn err_typed() {
        let i = Input(123);

        let r = parse!{i; err <(), _> "foo"};

        assert_eq!(r, Data::Error(123, "foo"));
    }

    #[test]
    fn err_typed2() {
        let i = Input(123);

        let r = parse!{i; err <(), &str> "foo"};

        assert_eq!(r, Data::Error(123, "foo"));
    }

    #[test]
    fn action() {
        fn doit(i: Input) -> Data<&'static str, ()> {
            Data::Value(i.0, "doit")
        }

        let i = Input(123);

        let r = parse!(i; doit());

        assert_eq!(r, Data::Value(123, "doit"));
    }

    #[test]
    fn action2() {
        fn doit(i: Input, p: &str) -> Data<&str, ()> {
            Data::Value(i.0, p)
        }

        let i = Input(123);

        let r = parse!(i; doit("doit"));

        assert_eq!(r, Data::Value(123, "doit"));
    }

    #[test]
    fn action3() {
        fn doit(i: Input, p: &str, u: u32) -> Data<(&str, u32), ()> {
            Data::Value(i.0, (p, u))
        }

        let i = Input(123);

        let r = parse!(i; doit("doit", 1337));

        assert_eq!(r, Data::Value(123, ("doit", 1337)));
    }

    #[test]
    fn two_actions() {
        fn doit(i: Input) -> Data<u32, ()> {
            assert_eq!(i.0, 123);

            Data::Value(321, 1)
        }
        fn something(i: Input) -> Data<u32, ()> {
            assert_eq!(i.0, 321);

            Data::Value(123, 2)
        }

        let i = Input(123);

        let r = parse!(i; doit(); something());

        assert_eq!(r, Data::Value(123, 2));
    }

    #[test]
    fn two_actions2() {
        fn doit(i: Input, n: u32) -> Data<u32, ()> {
            assert_eq!(i.0, 123);

            Data::Value(321, n)
        }
        fn something(i: Input, n: u32) -> Data<u32, ()> {
            assert_eq!(i.0, 321);

            Data::Value(123, n)
        }

        let i = Input(123);

        let r = parse!(i; doit(22); something(33));

        assert_eq!(r, Data::Value(123, 33));
    }

    #[test]
    fn two_actions3() {
        fn doit(i: Input, n: u32, x: i32) -> Data<(u32, i32), ()> {
            assert_eq!(i.0, 123);

            Data::Value(321, (n, x))
        }
        fn something(i: Input, n: u32, x: i32) -> Data<(u32, i32), ()> {
            assert_eq!(i.0, 321);

            Data::Value(123, (n, x))
        }

        let i = Input(123);

        let r = parse!(i; doit(22, 1); something(33, 2));

        assert_eq!(r, Data::Value(123, (33, 2)));
    }
}
<commit_msg>Hopefully fixed issue with token types in macro<commit_after>/// Macro emulating `do`-notation for the parser monad, automatically threading the linear type.
///
/// ```
/// # #[macro_use] extern crate parsed;
/// # fn main() {
/// use parsed::{Input, Data, Error};
/// use parsed::{take_while1, token};
///
/// let i = Input::new("martin wernstål\n".as_bytes());
///
/// #[derive(Debug, Eq, PartialEq)]
/// struct Name<'a> {
///     first: &'a [u8],
///     last:  &'a [u8],
/// }
///
/// fn name(i: Input<u8>) -> Data<u8, Name, Error<u8>> {
///     parse!{i;
///         let first = take_while1(|c| c != b' ');
///                     token(b' ');
///         let last  = take_while1(|c| c != b'\n');
///
///         ret Name{
///             first: first,
///             last:  last,
///         }
///     }
/// }
///
/// assert_eq!(name(i).unwrap(), Name{first: b"martin", last: "wernstål".as_bytes()});
/// # }
/// ```
#[macro_export]
macro_rules! parse {
    // RET_TYPED := '<' $ty ',' $ty '>' $expr
    // special case for _, since it is not a $ty
    ( @RET($i:expr); < _        , $e_ty:ty > $e:expr ) => { $i.ret::<_, $e_ty>($e) }; // allows for skipping type
    ( @RET($i:expr); < $t_ty:ty , $e_ty:ty > $e:expr ) => { $i.ret::<$t_ty, $e_ty>($e) };

    // RET_PLAIN := $expr
    ( @RET($i:expr); $e:expr ) => { $i.ret($e) };

    // ERR_TYPED := '<' $ty ',' $ty '>' $expr
    // special case for _, since it is not a $ty
    ( @ERR($i:expr); < $t_ty:ty , _        > $e:expr ) => { $i.err::<$t_ty, _>($e) }; // allows for skipping type
    ( @ERR($i:expr); < $t_ty:ty , $e_ty:ty > $e:expr ) => { $i.err::<$t_ty, $e_ty>($e) };

    // ERR_PLAIN := $expr
    ( @ERR($i:expr); $e:expr ) => { $i.err($e) };

    // VAR    := $ident ':' $ty / $pat
    // pattern must be before ident
    ( @BIND($i:expr); $v:pat              = $($t:tt)* ) => { parse!{ @ACTION($i, $v      ); $($t)* } };
    ( @BIND($i:expr); $v:ident : $v_ty:ty = $($t:tt)* ) => { parse!{ @ACTION($i, $v:$v_ty); $($t)* } };

    // ACTION := INLINE_ACTION / NAMED_ACTION

    // INLINE_ACTION := $ident '->' $expr
    // version with expression following, nonterminal:
    ( @ACTION($i:expr, $($v:tt)*); $m:ident -> $e:expr ; $($t:tt)*) => { parse!{ @CONCAT({ let $m = $i; $e }, $($v)*); $($t)* } };
    // terminal:
    ( @ACTION($i:expr, $($v:tt)*); $m:ident -> $e:expr )            => { { let $m = $i; $e } };

    // NAMED_ACTION  := $ident '(' ($expr ',')* ','? ')'
    // version with expression following, nonterminal:
    ( @ACTION($i:expr, $($v:tt)*); $f:ident ( $($p:expr),* $(,)*) ; $($t:tt)* ) => { parse!{ @CONCAT($f($i, $($p),*), $($v)*); $($t)*} };
    // terminal:
    ( @ACTION($i:expr, $($v:tt)*); $f:ident ( $($p:expr),* $(,)*) )             => { $f($i, $($p),*) };

    // Ties an expression together with the next, using the bind operator
    // invoked from @ACTION and @BIND (via @ACTION)
    ( @CONCAT($i:expr, _                  ); $($tail:tt)* ) => { $i.bind(|i, _|        parse!{ i; $($tail)* }) };
    ( @CONCAT($i:expr, $v:pat             ); $($tail:tt)* ) => { $i.bind(|i, $v|       parse!{ i; $($tail)* }) };
    ( @CONCAT($i:expr, $v:ident : $v_ty:ty); $($tail:tt)* ) => { $i.bind(|i, $v:$v_ty| parse!{ i; $($tail)* }) };

    // EXPR := ( BIND ';' / THEN ';' )* (RET / ERR / THEN)

    // BIND   := 'let' VAR '=' ACTION
    ( $i:expr ; let $($tail:tt)* ) => { parse!{ @BIND($i); $($tail)* } };
    // RET := 'ret' ( RET_TYPED / RET_PLAIN )
    ( $i:expr ; ret $($tail:tt)+ ) => { parse!{ @RET($i); $($tail)* } };
    // ERR := 'err' ( ERR_TYPED / ERR_PLAIN )
    ( $i:expr ; err $($tail:tt)+ ) => { parse!{ @ERR($i); $($tail)* } };
    // THEN   := ACTION
    // needs to be last since it is the most general
    ( $i:expr ; $($tail:tt)* )     => { parse!{ @ACTION($i, _); $($tail)* } };

    // Terminals:
    ( $i:expr ; ) => { $i };
    ( $i:expr )   => { $i };
}

#[cfg(test)]
mod test {
    /// Simplified implementation of the emulated monad using linear types.
    #[derive(Debug, Eq, PartialEq)]
    struct Input(i64);
    /// Simplified implementation of the emulated monad using linear types.
    #[derive(Debug, Eq, PartialEq)]
    enum Data<T, E> {
        Value(i64, T),
        Error(i64, E),
    }

    impl Input {
        fn ret<T, E>(self, t: T) -> Data<T, E> {
            Data::Value(self.0, t)
        }

        fn err<T, E>(self, e: E) -> Data<T, E> {
            Data::Error(self.0, e)
        }
    }

    impl<T, E> Data<T, E> {
        fn bind<F, U, V = E>(self, f: F) -> Data<U, V>
          where F: FnOnce(Input, T) -> Data<U, V>,
                V: From<E> {
            match self {
                Data::Value(i, t) => f(Input(i), t).map_err(From::from),
                Data::Error(i, e) => Data::Error(i, From::from(e)),
            }
        }

        fn map_err<F, V>(self, f: F) -> Data<T, V>
          where F: FnOnce(E) -> V {
            match self {
                Data::Value(i, t) => Data::Value(i, t),
                Data::Error(i, e) => Data::Error(i, f(e)),
            }
        }
    }

    #[test]
    fn empty() {
        let i = 123;

        let r = parse!{i};

        assert_eq!(r, 123);
    }

    #[test]
    fn empty_expr() {
        let r = parse!{1 + 2};

        assert_eq!(r, 3);
    }

    #[test]
    fn ret() {
        let i = Input(123);

        // Type annotation necessary since ret leaves E free
        let r: Data<_, ()> = parse!{i; ret "foo"};

        assert_eq!(r, Data::Value(123, "foo"));
    }

    #[test]
    fn ret_typed() {
        let i = Input(123);

        let r = parse!{i; ret <_, ()> "foo"};

        assert_eq!(r, Data::Value(123, "foo"));
    }

    #[test]
    fn ret_typed2() {
        let i = Input(123);

        let r = parse!{i; ret <&str, ()> "foo"};

        assert_eq!(r, Data::Value(123, "foo"));
    }

    #[test]
    fn err() {
        let i = Input(123);

        // Type annotation necessary since err leaves T free
        let r: Data<(), _> = parse!{i; err "foo"};

        assert_eq!(r, Data::Error(123, "foo"));
    }

    #[test]
    fn err_typed() {
        let i = Input(123);

        let r = parse!{i; err <(), _> "foo"};

        assert_eq!(r, Data::Error(123, "foo"));
    }

    #[test]
    fn err_typed2() {
        let i = Input(123);

        let r = parse!{i; err <(), &str> "foo"};

        assert_eq!(r, Data::Error(123, "foo"));
    }

    #[test]
    fn action() {
        fn doit(i: Input) -> Data<&'static str, ()> {
            Data::Value(i.0, "doit")
        }

        let i = Input(123);

        let r = parse!(i; doit());

        assert_eq!(r, Data::Value(123, "doit"));
    }

    #[test]
    fn action2() {
        fn doit(i: Input, p: &str) -> Data<&str, ()> {
            Data::Value(i.0, p)
        }

        let i = Input(123);

        let r = parse!(i; doit("doit"));

        assert_eq!(r, Data::Value(123, "doit"));
    }

    #[test]
    fn action3() {
        fn doit(i: Input, p: &str, u: u32) -> Data<(&str, u32), ()> {
            Data::Value(i.0, (p, u))
        }

        let i = Input(123);

        let r = parse!(i; doit("doit", 1337));

        assert_eq!(r, Data::Value(123, ("doit", 1337)));
    }

    #[test]
    fn two_actions() {
        fn doit(i: Input) -> Data<u32, ()> {
            assert_eq!(i.0, 123);

            Data::Value(321, 1)
        }
        fn something(i: Input) -> Data<u32, ()> {
            assert_eq!(i.0, 321);

            Data::Value(123, 2)
        }

        let i = Input(123);

        let r = parse!(i; doit(); something());

        assert_eq!(r, Data::Value(123, 2));
    }

    #[test]
    fn two_actions2() {
        fn doit(i: Input, n: u32) -> Data<u32, ()> {
            assert_eq!(i.0, 123);

            Data::Value(321, n)
        }
        fn something(i: Input, n: u32) -> Data<u32, ()> {
            assert_eq!(i.0, 321);

            Data::Value(123, n)
        }

        let i = Input(123);

        let r = parse!(i; doit(22); something(33));

        assert_eq!(r, Data::Value(123, 33));
    }

    #[test]
    fn two_actions3() {
        fn doit(i: Input, n: u32, x: i32) -> Data<(u32, i32), ()> {
            assert_eq!(i.0, 123);

            Data::Value(321, (n, x))
        }
        fn something(i: Input, n: u32, x: i32) -> Data<(u32, i32), ()> {
            assert_eq!(i.0, 321);

            Data::Value(123, (n, x))
        }

        let i = Input(123);

        let r = parse!(i; doit(22, 1); something(33, 2));

        assert_eq!(r, Data::Value(123, (33, 2)));
    }
}
<|endoftext|>