<commit_before>use serde::de;
use Value;
use super::{Decoder, DecodeError, DecodeErrorKind};
use std::collections::BTreeMap;

struct MapVisitor<'a, I> {
    iter: I,
    toml: &'a mut Option<Value>,
    key: Option<String>,
    value: Option<Value>,
}

fn se2toml(err: de::value::Error, ty: &'static str) -> DecodeError {
    match err {
        de::value::Error::SyntaxError => de::Error::syntax(ty),
        de::value::Error::EndOfStreamError => de::Error::end_of_stream(),
        de::value::Error::MissingFieldError(s) => {
            DecodeError {
                field: Some(s.to_string()),
                kind: DecodeErrorKind::ExpectedField(Some(ty)),
            }
        },
        de::value::Error::UnknownFieldError(s) => {
            DecodeError {
                field: Some(s.to_string()),
                kind: DecodeErrorKind::UnknownField,
            }
        },
    }
}

impl de::Deserializer for Decoder {
    type Error = DecodeError;

    fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, DecodeError>
        where V: de::Visitor
    {
        match self.toml.take() {
            Some(Value::String(s)) => {
                visitor.visit_string(s).map_err(|e| se2toml(e, "string"))
            }
            Some(Value::Integer(i)) => {
                visitor.visit_i64(i).map_err(|e| se2toml(e, "integer"))
            }
            Some(Value::Float(f)) => {
                visitor.visit_f64(f).map_err(|e| se2toml(e, "float"))
            }
            Some(Value::Boolean(b)) => {
                visitor.visit_bool(b).map_err(|e| se2toml(e, "bool"))
            }
            Some(Value::Datetime(s)) => {
                visitor.visit_string(s).map_err(|e| se2toml(e, "date"))
            }
            Some(Value::Array(a)) => {
                let len = a.len();
                let iter = a.into_iter();
                visitor.visit_seq(SeqDeserializer::new(iter, len, &mut self.toml))
            }
            Some(Value::Table(t)) => {
                visitor.visit_map(MapVisitor {
                    iter: t.into_iter(),
                    toml: &mut self.toml,
                    key: None,
                    value: None,
                })
            }
            None => Err(de::Error::end_of_stream()),
        }
    }

    fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, DecodeError>
        where V: de::Visitor
    {
        if self.toml.is_none() {
            visitor.visit_none()
        } else {
            visitor.visit_some(self)
        }
    }

    fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, DecodeError>
        where V: de::Visitor,
    {
        if self.toml.is_none() {
            let iter = None::<i32>.into_iter();
            let e = visitor.visit_seq(de::value::SeqDeserializer::new(iter, 0));
            e.map_err(|e| se2toml(e, "array"))
        } else {
            self.visit(visitor)
        }
    }
}

struct SeqDeserializer<'a, I> {
    iter: I,
    len: usize,
    toml: &'a mut Option<Value>,
}

impl<'a, I> SeqDeserializer<'a, I> where I: Iterator<Item=Value> {
    fn new(iter: I, len: usize, toml: &'a mut Option<Value>) -> Self {
        SeqDeserializer {
            iter: iter,
            len: len,
            toml: toml,
        }
    }

    fn put_value_back(&mut self, v: Value) {
        *self.toml = self.toml.take().or(Some(Value::Array(Vec::new())));
        match self.toml.as_mut().unwrap() {
            &mut Value::Array(ref mut a) => {
                a.push(v);
            },
            _ => unreachable!(),
        }
    }
}

impl<'a, I> de::Deserializer for SeqDeserializer<'a, I>
    where I: Iterator<Item=Value>,
{
    type Error = DecodeError;

    fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, DecodeError>
        where V: de::Visitor,
    {
        visitor.visit_seq(self)
    }
}

impl<'a, I> de::SeqVisitor for SeqDeserializer<'a, I>
    where I: Iterator<Item=Value>
{
    type Error = DecodeError;

    fn visit<V>(&mut self) -> Result<Option<V>, DecodeError>
        where V: de::Deserialize
    {
        match self.iter.next() {
            Some(value) => {
                self.len -= 1;
                let mut de = Decoder::new(value);
                let v = try!(de::Deserialize::deserialize(&mut de));
                if let Some(t) = de.toml {
                    self.put_value_back(t);
                }
                Ok(Some(v))
            }
            None => Ok(None),
        }
    }

    fn end(&mut self) -> Result<(), DecodeError> {
        if self.len == 0 {
            Ok(())
        } else {
            Err(de::Error::end_of_stream())
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.len, Some(self.len))
    }
}

impl de::Error for DecodeError {
    fn syntax(_: &str) -> DecodeError {
        DecodeError { field: None, kind: DecodeErrorKind::SyntaxError }
    }
    fn end_of_stream() -> DecodeError {
        DecodeError { field: None, kind: DecodeErrorKind::EndOfStream }
    }
    fn missing_field(name: &'static str) -> DecodeError {
        DecodeError {
            field: Some(name.to_string()),
            kind: DecodeErrorKind::ExpectedField(None),
        }
    }
    fn unknown_field(name: &str) -> DecodeError {
        DecodeError {
            field: Some(name.to_string()),
            kind: DecodeErrorKind::UnknownField,
        }
    }
}

impl<'a, I> MapVisitor<'a, I> {
    fn put_value_back(&mut self, v: Value) {
        *self.toml = self.toml.take().or_else(|| {
            Some(Value::Table(BTreeMap::new()))
        });
        match self.toml.as_mut().unwrap() {
            &mut Value::Table(ref mut t) => {
                t.insert(self.key.take().unwrap(), v);
            },
            _ => unreachable!(),
        }
    }
}

impl<'a, I> de::MapVisitor for MapVisitor<'a, I>
    where I: Iterator<Item=(String, Value)>
{
    type Error = DecodeError;

    fn visit_key<K>(&mut self) -> Result<Option<K>, DecodeError>
        where K: de::Deserialize
    {
        while let Some((k, v)) = self.iter.next() {
            self.key = Some(k.clone());
            let mut dec = Decoder::new(Value::String(k));
            match de::Deserialize::deserialize(&mut dec) {
                Ok(val) => {
                    self.value = Some(v);
                    return Ok(Some(val))
                }

                // If this was an unknown field, then we put the toml value
                // back into the map and keep going.
                Err(DecodeError {kind: DecodeErrorKind::UnknownField, ..}) => {
                    self.put_value_back(v);
                }
                Err(e) => return Err(e),
            }
        }
        Ok(None)
    }

    fn visit_value<V>(&mut self) -> Result<V, DecodeError>
        where V: de::Deserialize
    {
        match self.value.take() {
            Some(t) => {
                let mut dec = Decoder::new(t);
                let v = try!(de::Deserialize::deserialize(&mut dec));
                if let Some(t) = dec.toml {
                    self.put_value_back(t);
                }
                Ok(v)
            },
            None => Err(de::Error::end_of_stream())
        }
    }

    fn end(&mut self) -> Result<(), DecodeError> {
        Ok(())
    }

    fn missing_field<V>(&mut self, field_name: &'static str)
                        -> Result<V, DecodeError> where V: de::Deserialize {
        // See if the type can deserialize from a unit.
        match de::Deserialize::deserialize(&mut UnitDeserializer) {
            Err(DecodeError {
                kind: DecodeErrorKind::SyntaxError,
                field,
            }) => Err(DecodeError {
                field: field.or(Some(field_name.to_string())),
                kind: DecodeErrorKind::ExpectedField(None),
            }),
            v => v,
        }
    }
}

struct UnitDeserializer;

impl de::Deserializer for UnitDeserializer {
    type Error = DecodeError;

    fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, DecodeError>
        where V: de::Visitor,
    {
        visitor.visit_unit()
    }

    fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, DecodeError>
        where V: de::Visitor,
    {
        visitor.visit_none()
    }
}

// Based on https://github.com/serde-rs/serde/blob/199ed417bd6afc2071d17759b8c7e0ab8d0ba4cc/serde_json/src/value.rs#L265
impl de::Deserialize for Value {
    fn deserialize<D>(deserializer: &mut D) -> Result<Value, D::Error> where D: de::Deserializer {
        struct ValueVisitor;

        impl de::Visitor for ValueVisitor {
            type Value = Value;

            fn visit_bool<E>(&mut self, value: bool) -> Result<Value, E> {
                Ok(Value::Boolean(value))
            }

            fn visit_i64<E>(&mut self, value: i64) -> Result<Value, E> {
                Ok(Value::Integer(value))
            }

            fn visit_f64<E>(&mut self, value: f64) -> Result<Value, E> {
                Ok(Value::Float(value))
            }

            fn visit_str<E>(&mut self, value: &str) -> Result<Value, E> {
                Ok(Value::String(value.into()))
            }

            fn visit_string<E>(&mut self, value: String) -> Result<Value, E> {
                Ok(Value::String(value))
            }

            fn visit_seq<V>(&mut self, visitor: V) -> Result<Value, V::Error> where V: de::SeqVisitor {
                let values = try!(de::impls::VecVisitor::new().visit_seq(visitor));
                Ok(Value::Array(values))
            }

            fn visit_map<V>(&mut self, visitor: V) -> Result<Value, V::Error> where V: de::MapVisitor {
                let values = try!(de::impls::BTreeMapVisitor::new().visit_map(visitor));
                Ok(Value::Table(values))
            }
        }

        deserializer.visit(ValueVisitor)
    }
}
<commit_msg>Add a Deserialize::visit_enum that tries to deserialize into each variant<commit_after>use serde::de;
use Value;
use super::{Decoder, DecodeError, DecodeErrorKind};
use std::collections::BTreeMap;

struct MapVisitor<'a, I> {
    iter: I,
    toml: &'a mut Option<Value>,
    key: Option<String>,
    value: Option<Value>,
}

fn se2toml(err: de::value::Error, ty: &'static str) -> DecodeError {
    match err {
        de::value::Error::SyntaxError => de::Error::syntax(ty),
        de::value::Error::EndOfStreamError => de::Error::end_of_stream(),
        de::value::Error::MissingFieldError(s) => {
            DecodeError {
                field: Some(s.to_string()),
                kind: DecodeErrorKind::ExpectedField(Some(ty)),
            }
        },
        de::value::Error::UnknownFieldError(s) => {
            DecodeError {
                field: Some(s.to_string()),
                kind: DecodeErrorKind::UnknownField,
            }
        },
    }
}

impl de::Deserializer for Decoder {
    type Error = DecodeError;

    fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, DecodeError>
        where V: de::Visitor
    {
        match self.toml.take() {
            Some(Value::String(s)) => {
                visitor.visit_string(s).map_err(|e| se2toml(e, "string"))
            }
            Some(Value::Integer(i)) => {
                visitor.visit_i64(i).map_err(|e| se2toml(e, "integer"))
            }
            Some(Value::Float(f)) => {
                visitor.visit_f64(f).map_err(|e| se2toml(e, "float"))
            }
            Some(Value::Boolean(b)) => {
                visitor.visit_bool(b).map_err(|e| se2toml(e, "bool"))
            }
            Some(Value::Datetime(s)) => {
                visitor.visit_string(s).map_err(|e| se2toml(e, "date"))
            }
            Some(Value::Array(a)) => {
                let len = a.len();
                let iter = a.into_iter();
                visitor.visit_seq(SeqDeserializer::new(iter, len, &mut self.toml))
            }
            Some(Value::Table(t)) => {
                visitor.visit_map(MapVisitor {
                    iter: t.into_iter(),
                    toml: &mut self.toml,
                    key: None,
                    value: None,
                })
            }
            None => Err(de::Error::end_of_stream()),
        }
    }

    fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, DecodeError>
        where V: de::Visitor
    {
        if self.toml.is_none() {
            visitor.visit_none()
        } else {
            visitor.visit_some(self)
        }
    }

    fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, DecodeError>
        where V: de::Visitor,
    {
        if self.toml.is_none() {
            let iter = None::<i32>.into_iter();
            let e = visitor.visit_seq(de::value::SeqDeserializer::new(iter, 0));
            e.map_err(|e| se2toml(e, "array"))
        } else {
            self.visit(visitor)
        }
    }

    fn visit_enum<V>(&mut self,
                     _enum: &str,
                     variants: &[&str],
                     mut visitor: V) -> Result<V::Value, DecodeError>
        where V: de::EnumVisitor,
    {
        // When decoding enums, this crate takes the strategy of trying to
        // decode the current TOML as all of the possible variants, returning
        // success on the first one that succeeds.
        //
        // Note that fidelity of the errors returned here is a little nebulous,
        // but we try to return the error that had the relevant field as the
        // longest field. This way we hopefully match an error against what was
        // most likely being written down without losing too much info.
        let mut first_error = None::<DecodeError>;

        for variant in 0 .. variants.len() {
            let mut de = VariantVisitor {
                de: self.sub_decoder(self.toml.clone(), ""),
                variant: variant,
            };

            match visitor.visit(&mut de) {
                Ok(value) => {
                    self.toml = de.de.toml;
                    return Ok(value);
                }
                Err(e) => {
                    if let Some(ref first) = first_error {
                        let my_len = e.field.as_ref().map(|s| s.len());
                        let first_len = first.field.as_ref().map(|s| s.len());
                        if my_len <= first_len {
                            continue
                        }
                    }
                    first_error = Some(e);
                }
            }
        }

        Err(first_error.unwrap_or_else(|| self.err(DecodeErrorKind::NoEnumVariants)))
    }
}

struct VariantVisitor {
    de: Decoder,
    variant: usize,
}

impl de::VariantVisitor for VariantVisitor {
    type Error = DecodeError;

    fn visit_variant<V>(&mut self) -> Result<V, DecodeError>
        where V: de::Deserialize
    {
        use serde::de::value::ValueDeserializer;

        let mut de = self.variant.into_deserializer();

        de::Deserialize::deserialize(&mut de).map_err(|e| se2toml(e, "variant"))
    }

    fn visit_unit(&mut self) -> Result<(), DecodeError> {
        de::Deserialize::deserialize(&mut self.de)
    }

    fn visit_newtype<T>(&mut self) -> Result<T, DecodeError>
        where T: de::Deserialize,
    {
        de::Deserialize::deserialize(&mut self.de)
    }

    fn visit_tuple<V>(&mut self,
                      _len: usize,
                      visitor: V) -> Result<V::Value, DecodeError>
        where V: de::Visitor,
    {
        de::Deserializer::visit(&mut self.de, visitor)
    }

    fn visit_struct<V>(&mut self,
                       _fields: &'static [&'static str],
                       visitor: V) -> Result<V::Value, DecodeError>
        where V: de::Visitor,
    {
        de::Deserializer::visit(&mut self.de, visitor)
    }
}

struct SeqDeserializer<'a, I> {
    iter: I,
    len: usize,
    toml: &'a mut Option<Value>,
}

impl<'a, I> SeqDeserializer<'a, I> where I: Iterator<Item=Value> {
    fn new(iter: I, len: usize, toml: &'a mut Option<Value>) -> Self {
        SeqDeserializer {
            iter: iter,
            len: len,
            toml: toml,
        }
    }

    fn put_value_back(&mut self, v: Value) {
        *self.toml = self.toml.take().or(Some(Value::Array(Vec::new())));
        match self.toml.as_mut().unwrap() {
            &mut Value::Array(ref mut a) => {
                a.push(v);
            },
            _ => unreachable!(),
        }
    }
}

impl<'a, I> de::Deserializer for SeqDeserializer<'a, I>
    where I: Iterator<Item=Value>,
{
    type Error = DecodeError;

    fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, DecodeError>
        where V: de::Visitor,
    {
        visitor.visit_seq(self)
    }
}

impl<'a, I> de::SeqVisitor for SeqDeserializer<'a, I>
    where I: Iterator<Item=Value>
{
    type Error = DecodeError;

    fn visit<V>(&mut self) -> Result<Option<V>, DecodeError>
        where V: de::Deserialize
    {
        match self.iter.next() {
            Some(value) => {
                self.len -= 1;
                let mut de = Decoder::new(value);
                let v = try!(de::Deserialize::deserialize(&mut de));
                if let Some(t) = de.toml {
                    self.put_value_back(t);
                }
                Ok(Some(v))
            }
            None => Ok(None),
        }
    }

    fn end(&mut self) -> Result<(), DecodeError> {
        if self.len == 0 {
            Ok(())
        } else {
            Err(de::Error::end_of_stream())
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.len, Some(self.len))
    }
}

impl de::Error for DecodeError {
    fn syntax(_: &str) -> DecodeError {
        DecodeError { field: None, kind: DecodeErrorKind::SyntaxError }
    }
    fn end_of_stream() -> DecodeError {
        DecodeError { field: None, kind: DecodeErrorKind::EndOfStream }
    }
    fn missing_field(name: &'static str) -> DecodeError {
        DecodeError {
            field: Some(name.to_string()),
            kind: DecodeErrorKind::ExpectedField(None),
        }
    }
    fn unknown_field(name: &str) -> DecodeError {
        DecodeError {
            field: Some(name.to_string()),
            kind: DecodeErrorKind::UnknownField,
        }
    }
}

impl<'a, I> MapVisitor<'a, I> {
    fn put_value_back(&mut self, v: Value) {
        *self.toml = self.toml.take().or_else(|| {
            Some(Value::Table(BTreeMap::new()))
        });
        match self.toml.as_mut().unwrap() {
            &mut Value::Table(ref mut t) => {
                t.insert(self.key.take().unwrap(), v);
            },
            _ => unreachable!(),
        }
    }
}

impl<'a, I> de::MapVisitor for MapVisitor<'a, I>
    where I: Iterator<Item=(String, Value)>
{
    type Error = DecodeError;

    fn visit_key<K>(&mut self) -> Result<Option<K>, DecodeError>
        where K: de::Deserialize
    {
        while let Some((k, v)) = self.iter.next() {
            self.key = Some(k.clone());
            let mut dec = Decoder::new(Value::String(k));
            match de::Deserialize::deserialize(&mut dec) {
                Ok(val) => {
                    self.value = Some(v);
                    return Ok(Some(val))
                }

                // If this was an unknown field, then we put the toml value
                // back into the map and keep going.
                Err(DecodeError {kind: DecodeErrorKind::UnknownField, ..}) => {
                    self.put_value_back(v);
                }
                Err(e) => return Err(e),
            }
        }
        Ok(None)
    }

    fn visit_value<V>(&mut self) -> Result<V, DecodeError>
        where V: de::Deserialize
    {
        match self.value.take() {
            Some(t) => {
                let mut dec = Decoder::new(t);
                let v = try!(de::Deserialize::deserialize(&mut dec));
                if let Some(t) = dec.toml {
                    self.put_value_back(t);
                }
                Ok(v)
            },
            None => Err(de::Error::end_of_stream())
        }
    }

    fn end(&mut self) -> Result<(), DecodeError> {
        Ok(())
    }

    fn missing_field<V>(&mut self, field_name: &'static str)
                        -> Result<V, DecodeError> where V: de::Deserialize {
        // See if the type can deserialize from a unit.
        match de::Deserialize::deserialize(&mut UnitDeserializer) {
            Err(DecodeError {
                kind: DecodeErrorKind::SyntaxError,
                field,
            }) => Err(DecodeError {
                field: field.or(Some(field_name.to_string())),
                kind: DecodeErrorKind::ExpectedField(None),
            }),
            v => v,
        }
    }
}

struct UnitDeserializer;

impl de::Deserializer for UnitDeserializer {
    type Error = DecodeError;

    fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, DecodeError>
        where V: de::Visitor,
    {
        visitor.visit_unit()
    }

    fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, DecodeError>
        where V: de::Visitor,
    {
        visitor.visit_none()
    }
}

// Based on https://github.com/serde-rs/serde/blob/199ed417bd6afc2071d17759b8c7e0ab8d0ba4cc/serde_json/src/value.rs#L265
impl de::Deserialize for Value {
    fn deserialize<D>(deserializer: &mut D) -> Result<Value, D::Error> where D: de::Deserializer {
        struct ValueVisitor;

        impl de::Visitor for ValueVisitor {
            type Value = Value;

            fn visit_bool<E>(&mut self, value: bool) -> Result<Value, E> {
                Ok(Value::Boolean(value))
            }

            fn visit_i64<E>(&mut self, value: i64) -> Result<Value, E> {
                Ok(Value::Integer(value))
            }

            fn visit_f64<E>(&mut self, value: f64) -> Result<Value, E> {
                Ok(Value::Float(value))
            }

            fn visit_str<E>(&mut self, value: &str) -> Result<Value, E> {
                Ok(Value::String(value.into()))
            }

            fn visit_string<E>(&mut self, value: String) -> Result<Value, E> {
                Ok(Value::String(value))
            }

            fn visit_seq<V>(&mut self, visitor: V) -> Result<Value, V::Error> where V: de::SeqVisitor {
                let values = try!(de::impls::VecVisitor::new().visit_seq(visitor));
                Ok(Value::Array(values))
            }

            fn visit_map<V>(&mut self, visitor: V) -> Result<Value, V::Error> where V: de::MapVisitor {
                let values = try!(de::impls::BTreeMapVisitor::new().visit_map(visitor));
                Ok(Value::Table(values))
            }
        }

        deserializer.visit(ValueVisitor)
    }
}
<|endoftext|>


<commit_before>extern crate num_traits;

use std::collections::BTreeMap;
use std::collections::BTreeSet;
use std::fmt::{self, Display, Formatter};
use std::hash::Hash;
use std::iter::FromIterator;
use std::vec::Vec;
use self::num_traits::One;
use recognisable::Transition;
use pmcfg::{PMCFG, PMCFGRule, VarT};
use tree_stack_automaton::{TreeStack, TreeStackAutomaton, TreeStackInstruction};

// types for analysis of derivation trees of PMCFGs
pub type RuleCallerMap<N, T, W> = BTreeMap<PMCFGRule<N, T, W>, Vec<(usize, Vec<T>)>>;
pub type DerivationSnippet<N, T, W> = (PMCFGRule<N, T, W>, Vec<Vec<PMCFGRule<N, T, W>>>);

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
pub enum PosState<X> {
    Designated,
    Initial,
    Position(X, usize, usize),
}

impl<X> PosState<X> {
    pub fn map<F, Y>(&self, f: F) -> PosState<Y>
        where F: Fn(&X) -> Y,
    {
        match *self {
            PosState::Designated => PosState::Designated,
            PosState::Initial => PosState::Initial,
            PosState::Position(ref x, i, j) => PosState::Position(f(x), i, j),
        }
    }
}

impl<X: Display> Display for PosState<X> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        match *self {
            PosState::Designated
                => write!(f, "@"),
            PosState::Initial
                => write!(f, "I"),
            PosState::Position(ref x, i, j)
                => write!(f, "({}, {}, {})", x, i, j)
        }
    }
}

// TODO assumes that the PMCFG is monotonic on the visit-order of components
impl<N: Clone + Ord + PartialEq + Hash,
     T: Clone + Ord + PartialEq + Hash,
     W: Clone + Ord + PartialEq + One
     > From<PMCFG<N, T, W>> for TreeStackAutomaton<PosState<PMCFGRule<N, T, W>>, T, W> {
    fn from(g: PMCFG<N, T, W>) -> Self {
        let mut transitions = Vec::new();

        let mut rule_map: BTreeMap<N, Vec<PMCFGRule<N, T, W>>>
            = BTreeSet::from_iter(
                g.rules
                    .iter()
                    .map(|r| r.head.clone())
            )
            .iter()
            .map(|n| (
                n.clone(),
                Vec::<PMCFGRule<N, T, W>>::new()
            ))
            .collect();

        let mut down_info: RuleCallerMap<N, T, W>
            = BTreeMap::new();

        let mut initial_rules: Vec<PMCFGRule<N, T, W>>
            = Vec::new();

        for r in g.rules.clone() {
            if g.initial.contains(&r.head) {
                initial_rules.push(r.clone())
            }
            rule_map.get_mut(&r.head).unwrap().push(r.clone());

            let mut var_cnt_vec = Vec::new();
            let mut i: usize;
            let mut down_buffer: Vec<T> = Vec::new();
            for component in &r.composition.composition {
                i = 0;
                for ntt in component {
                    down_buffer.clear();
                    match *ntt {
                        VarT::Var(_, _)
                            => {
                                i += 1;
                                down_buffer.clear();
                            },
                        VarT::T(ref t)
                            => {
                                down_buffer.push(t.clone());
                            }
                    }
                }
                var_cnt_vec.push((i, down_buffer.clone()));
            }
            down_info.insert(r.clone(), var_cnt_vec);
        }

        for r in initial_rules {
            transitions.push(
                Transition {
                    word: Vec::new(),
                    weight: r.weight.clone(),
                    instruction: TreeStackInstruction::Push {
                        n: 0,
                        current_val: PosState::Initial,
                        new_val: PosState::Position(r.clone(), 0, 0)
                    }
                }
            );

            match down_info[&r][0] {
                (j, ref word) => {
                    transitions.push(
                        Transition {
                            word: word.clone(),
                            weight: W::one(),
                            instruction: TreeStackInstruction::Down {
                                current_val: PosState::Position(r.clone(), 0, j),
                                old_val: PosState::Initial,
                                new_val: PosState::Designated
                            }
                        }
                    );
                }
            }
        }
        // each [r, [r₁, …, rₖ]] on the agenda signifies that r(r₁(…), …, rₖ(…)) is a possible subderivation
        let mut agenda: Vec<DerivationSnippet<N, T, W>>
            = Vec::new();

        for r in g.rules {
            agenda.push(
                ( r.clone(),
                  r.tail.iter().map(|n| rule_map[n].clone()).collect()
                )
            );
        }

        let mut buffer: Vec<T>;

        let mut j: usize;
        let mut k: usize;

        for (r, rss) in agenda {
            j = 0;
            let mut previous_component: Vec<Option<usize>> = rss.iter().map(|_| None).collect();
            for component in r.composition.composition.clone() {
                buffer = Vec::new();
                k = 0;
                for token in component {
                    match token {
                        VarT::Var(i1, j1) => {
                            for ri in &rss[i1] {
                                transitions.push(Transition {
                                    word: buffer.clone(),
                                    weight: match previous_component[i1] {
                                        None => ri.weight.clone(),
                                        Some(_) => W::one(),
                                    },
                                    instruction: match previous_component[i1] {
                                        None => {
                                            TreeStackInstruction::Push {
                                                n: i1,
                                                current_val: PosState::Position(r.clone(), j, k),
                                                new_val: PosState::Position(ri.clone(), j1, 0)
                                            }
                                        },
                                        Some(j0) => {
                                            TreeStackInstruction::Up {
                                                n: i1,
                                                current_val: PosState::Position(r.clone(), j, k),
                                                old_val: PosState::Position(
                                                    ri.clone(),
                                                    j0,
                                                    down_info[ri][j0].0
                                                ),
                                                new_val: PosState::Position(ri.clone(), j1, 0)
                                            }
                                        }
                                    }
                                });

                                transitions.push(Transition {
                                    word: down_info[ri][j1].1.clone(),
                                    weight: W::one(),
                                    instruction: TreeStackInstruction::Down {
                                        current_val: PosState::Position(
                                            ri.clone(),
                                            j1,
                                            down_info[ri][j1].0
                                        ),
                                        old_val: PosState::Position(r.clone(), j, k),
                                        new_val: PosState::Position(r.clone(), j, k + 1)
                                    }
                                });
                            }

                            previous_component[i1] = Some(j1);
                            k += 1;
                            buffer.clear();
                        },

                        VarT::T(t) => {
                            buffer.push(t);
                        }
                    }
                }

                j += 1;
            }
        }

        TreeStackAutomaton::new(
            transitions,
            TreeStack::new(PosState::Initial)
        )
    }
}

pub fn to_abstract_syntax_tree<A>((tree_map, _): (BTreeMap<Vec<usize>, PosState<A>>, Vec<usize>)) -> BTreeMap<Vec<usize>, A> {
    let mut abstract_syntax_tree = BTreeMap::new();

    for (address, pos_state) in tree_map {
        let (curr_root_child, relative_address) = if let Some((first, rest)) = address.split_first() {
            (first.clone(), rest.to_vec())
        } else {
            continue;
        };

        if curr_root_child != 0 {
            continue;
        }

        if let PosState::Position(value, _, _) = pos_state {
            abstract_syntax_tree.insert(relative_address, value);
        } else {
            panic!("The given tree map contains 'designated' or 'initial' nodes that are not the root!");
        }
    }

    abstract_syntax_tree
}
<commit_msg>src/tree_stack_automaton/from_pmcfg.rs: added tests for to_abstract_syntax_tree()<commit_after>extern crate num_traits;

use std::collections::BTreeMap;
use std::collections::BTreeSet;
use std::fmt::{self, Display, Formatter};
use std::hash::Hash;
use std::iter::FromIterator;
use std::vec::Vec;
use self::num_traits::One;
use recognisable::Transition;
use pmcfg::{PMCFG, PMCFGRule, VarT};
use tree_stack_automaton::{TreeStack, TreeStackAutomaton, TreeStackInstruction};

// types for analysis of derivation trees of PMCFGs
pub type RuleCallerMap<N, T, W> = BTreeMap<PMCFGRule<N, T, W>, Vec<(usize, Vec<T>)>>;
pub type DerivationSnippet<N, T, W> = (PMCFGRule<N, T, W>, Vec<Vec<PMCFGRule<N, T, W>>>);

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
pub enum PosState<X> {
    Designated,
    Initial,
    Position(X, usize, usize),
}

impl<X> PosState<X> {
    pub fn map<F, Y>(&self, f: F) -> PosState<Y>
        where F: Fn(&X) -> Y,
    {
        match *self {
            PosState::Designated => PosState::Designated,
            PosState::Initial => PosState::Initial,
            PosState::Position(ref x, i, j) => PosState::Position(f(x), i, j),
        }
    }
}

impl<X: Display> Display for PosState<X> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        match *self {
            PosState::Designated
                => write!(f, "@"),
            PosState::Initial
                => write!(f, "I"),
            PosState::Position(ref x, i, j)
                => write!(f, "({}, {}, {})", x, i, j)
        }
    }
}

// TODO assumes that the PMCFG is monotonic on the visit-order of components
impl<N: Clone + Ord + PartialEq + Hash,
     T: Clone + Ord + PartialEq + Hash,
     W: Clone + Ord + PartialEq + One
     > From<PMCFG<N, T, W>> for TreeStackAutomaton<PosState<PMCFGRule<N, T, W>>, T, W> {
    fn from(g: PMCFG<N, T, W>) -> Self {
        let mut transitions = Vec::new();

        let mut rule_map: BTreeMap<N, Vec<PMCFGRule<N, T, W>>>
            = BTreeSet::from_iter(
                g.rules
                    .iter()
                    .map(|r| r.head.clone())
            )
            .iter()
            .map(|n| (
                n.clone(),
                Vec::<PMCFGRule<N, T, W>>::new()
            ))
            .collect();

        let mut down_info: RuleCallerMap<N, T, W>
            = BTreeMap::new();

        let mut initial_rules: Vec<PMCFGRule<N, T, W>>
            = Vec::new();

        for r in g.rules.clone() {
            if g.initial.contains(&r.head) {
                initial_rules.push(r.clone())
            }
            rule_map.get_mut(&r.head).unwrap().push(r.clone());

            let mut var_cnt_vec = Vec::new();
            let mut i: usize;
            let mut down_buffer: Vec<T> = Vec::new();
            for component in &r.composition.composition {
                i = 0;
                for ntt in component {
                    down_buffer.clear();
                    match *ntt {
                        VarT::Var(_, _)
                            => {
                                i += 1;
                                down_buffer.clear();
                            },
                        VarT::T(ref t)
                            => {
                                down_buffer.push(t.clone());
                            }
                    }
                }
                var_cnt_vec.push((i, down_buffer.clone()));
            }
            down_info.insert(r.clone(), var_cnt_vec);
        }

        for r in initial_rules {
            transitions.push(
                Transition {
                    word: Vec::new(),
                    weight: r.weight.clone(),
                    instruction: TreeStackInstruction::Push {
                        n: 0,
                        current_val: PosState::Initial,
                        new_val: PosState::Position(r.clone(), 0, 0)
                    }
                }
            );

            match down_info[&r][0] {
                (j, ref word) => {
                    transitions.push(
                        Transition {
                            word: word.clone(),
                            weight: W::one(),
                            instruction: TreeStackInstruction::Down {
                                current_val: PosState::Position(r.clone(), 0, j),
                                old_val: PosState::Initial,
                                new_val: PosState::Designated
                            }
                        }
                    );
                }
            }
        }
        // each [r, [r₁, …, rₖ]] on the agenda signifies that r(r₁(…), …, rₖ(…)) is a possible subderivation
        let mut agenda: Vec<DerivationSnippet<N, T, W>>
            = Vec::new();

        for r in g.rules {
            agenda.push(
                ( r.clone(),
                  r.tail.iter().map(|n| rule_map[n].clone()).collect()
                )
            );
        }

        let mut buffer: Vec<T>;

        let mut j: usize;
        let mut k: usize;

        for (r, rss) in agenda {
            j = 0;
            let mut previous_component: Vec<Option<usize>> = rss.iter().map(|_| None).collect();
            for component in r.composition.composition.clone() {
                buffer = Vec::new();
                k = 0;
                for token in component {
                    match token {
                        VarT::Var(i1, j1) => {
                            for ri in &rss[i1] {
                                transitions.push(Transition {
                                    word: buffer.clone(),
                                    weight: match previous_component[i1] {
                                        None => ri.weight.clone(),
                                        Some(_) => W::one(),
                                    },
                                    instruction: match previous_component[i1] {
                                        None => {
                                            TreeStackInstruction::Push {
                                                n: i1,
                                                current_val: PosState::Position(r.clone(), j, k),
                                                new_val: PosState::Position(ri.clone(), j1, 0)
                                            }
                                        },
                                        Some(j0) => {
                                            TreeStackInstruction::Up {
                                                n: i1,
                                                current_val: PosState::Position(r.clone(), j, k),
                                                old_val: PosState::Position(
                                                    ri.clone(),
                                                    j0,
                                                    down_info[ri][j0].0
                                                ),
                                                new_val: PosState::Position(ri.clone(), j1, 0)
                                            }
                                        }
                                    }
                                });

                                transitions.push(Transition {
                                    word: down_info[ri][j1].1.clone(),
                                    weight: W::one(),
                                    instruction: TreeStackInstruction::Down {
                                        current_val: PosState::Position(
                                            ri.clone(),
                                            j1,
                                            down_info[ri][j1].0
                                        ),
                                        old_val: PosState::Position(r.clone(), j, k),
                                        new_val: PosState::Position(r.clone(), j, k + 1)
                                    }
                                });
                            }

                            previous_component[i1] = Some(j1);
                            k += 1;
                            buffer.clear();
                        },

                        VarT::T(t) => {
                            buffer.push(t);
                        }
                    }
                }

                j += 1;
            }
        }

        TreeStackAutomaton::new(
            transitions,
            TreeStack::new(PosState::Initial)
        )
    }
}

pub fn to_abstract_syntax_tree<A>((tree_map, _): (BTreeMap<Vec<usize>, PosState<A>>, Vec<usize>)) -> BTreeMap<Vec<usize>, A> {
    let mut abstract_syntax_tree = BTreeMap::new();

    for (address, pos_state) in tree_map {
        let (curr_root_child, relative_address) = if let Some((first, rest)) = address.split_first() {
            (first.clone(), rest.to_vec())
        } else {
            continue;
        };

        if curr_root_child != 0 {
            continue;
        }

        if let PosState::Position(value, _, _) = pos_state {
            abstract_syntax_tree.insert(relative_address, value);
        } else {
            panic!("The given tree map contains 'designated' or 'initial' nodes that are not the root!");
        }
    }

    abstract_syntax_tree
}

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

    #[test]
    fn test_to_abstract_syntax_tree() {
        let mut tree_map = BTreeMap::new();
        tree_map.insert(vec![], PosState::Initial);
        tree_map.insert(vec![0], PosState::Position('a', 0, 0));
        tree_map.insert(vec![0,0], PosState::Position('b', 0, 0));
        tree_map.insert(vec![0,2], PosState::Position('c', 0, 0));
        tree_map.insert(vec![2], PosState::Position('d', 0, 0));

        let mut abstract_syntax_tree = BTreeMap::new();
        abstract_syntax_tree.insert(vec![], 'a');
        abstract_syntax_tree.insert(vec![0], 'b');
        abstract_syntax_tree.insert(vec![2], 'c');

        assert_eq!(abstract_syntax_tree, to_abstract_syntax_tree((tree_map, vec![])));
    }

    #[test]
    fn test_to_abstract_syntax_tree_empty_tree() {
        let tree_map: BTreeMap<_, PosState<u8>> = BTreeMap::new();
        assert_eq!(BTreeMap::new(), to_abstract_syntax_tree((tree_map, vec![])));
    }

    #[test]
    #[should_panic(
        expected="The given tree map contains 'designated' or 'initial' nodes that are not the root!"
    )]
    fn test_to_abstract_syntax_tree_invalid_tree() {
        let mut tree_map: BTreeMap<_, PosState<u8>> = BTreeMap::new();
        tree_map.insert(vec![], PosState::Initial);
        tree_map.insert(vec![0], PosState::Initial);

        to_abstract_syntax_tree((tree_map, vec![]));
    }
}
<|endoftext|>


<commit_before>// The Computer Language Benchmarks Game
// http://benchmarksgame.alioth.debian.org/
//
// contributed by the Rust Project Developers

// Copyright (c) 2013-2014 The Rust Project Developers
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// - Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in
//   the documentation and/or other materials provided with the
//   distribution.
//
// - Neither the name of "The Computer Language Benchmarks Game" nor
//   the name of "The Computer Language Shootout Benchmarks" nor the
//   names of its contributors may be used to endorse or promote
//   products derived from this software without specific prior
//   written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.

use std::cmp::min;
use std::env;
use std::io;
use std::io::prelude::*;

const LINE_LEN: usize = 60;
const LOOKUP_SIZE: usize = 4 * 1024;
const LOOKUP_SCALE: f32 = (LOOKUP_SIZE - 1) as f32;

// Random number generator constants
const IM: u32 = 139968;
const IA: u32 = 3877;
const IC: u32 = 29573;

const ALU: &'static str = "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTG\
                            GGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGA\
                            GACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAA\
                            AATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAAT\
                            CCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAAC\
                            CCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTG\
                            CACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";

const NULL_AMINO_ACID: AminoAcid = AminoAcid { c: ' ' as u8, p: 0.0 };

static IUB: [AminoAcid;15] = [
    AminoAcid { c: 'a' as u8, p: 0.27 },
    AminoAcid { c: 'c' as u8, p: 0.12 },
    AminoAcid { c: 'g' as u8, p: 0.12 },
    AminoAcid { c: 't' as u8, p: 0.27 },
    AminoAcid { c: 'B' as u8, p: 0.02 },
    AminoAcid { c: 'D' as u8, p: 0.02 },
    AminoAcid { c: 'H' as u8, p: 0.02 },
    AminoAcid { c: 'K' as u8, p: 0.02 },
    AminoAcid { c: 'M' as u8, p: 0.02 },
    AminoAcid { c: 'N' as u8, p: 0.02 },
    AminoAcid { c: 'R' as u8, p: 0.02 },
    AminoAcid { c: 'S' as u8, p: 0.02 },
    AminoAcid { c: 'V' as u8, p: 0.02 },
    AminoAcid { c: 'W' as u8, p: 0.02 },
    AminoAcid { c: 'Y' as u8, p: 0.02 },
];

static HOMO_SAPIENS: [AminoAcid;4] = [
    AminoAcid { c: 'a' as u8, p: 0.3029549426680 },
    AminoAcid { c: 'c' as u8, p: 0.1979883004921 },
    AminoAcid { c: 'g' as u8, p: 0.1975473066391 },
    AminoAcid { c: 't' as u8, p: 0.3015094502008 },
];

fn sum_and_scale(a: &'static [AminoAcid]) -> Vec<AminoAcid> {
    let mut p = 0f32;
    let mut result: Vec<AminoAcid> = a.iter().map(|a_i| {
        p += a_i.p;
        AminoAcid { c: a_i.c, p: p * LOOKUP_SCALE }
    }).collect();
    let result_len = result.len();
    result[result_len - 1].p = LOOKUP_SCALE;
    result
}

#[derive(Copy, Clone)]
struct AminoAcid {
    c: u8,
    p: f32,
}

struct RepeatFasta<'a, W:'a> {
    alu: &'static str,
    out: &'a mut W
}

impl<'a, W: Write> RepeatFasta<'a, W> {
    fn new(alu: &'static str, w: &'a mut W) -> RepeatFasta<'a, W> {
        RepeatFasta { alu: alu, out: w }
    }

    fn make(&mut self, n: usize) -> io::Result<()> {
        let alu_len = self.alu.len();
        let mut buf = vec![0; alu_len + LINE_LEN];
        let alu: &[u8] = self.alu.as_bytes();

        for (slot, val) in buf.iter_mut().zip(alu) {
            *slot = *val;
        }
        let buf_len = buf.len();
        for (slot, val) in buf[alu_len..buf_len].iter_mut().zip(&alu[..LINE_LEN]) {
            *slot = *val;
        }

        let mut pos = 0;
        let mut bytes;
        let mut n = n;
        while n > 0 {
            bytes = min(LINE_LEN, n);
            try!(self.out.write_all(&buf[pos..pos + bytes]));
            try!(self.out.write_all(&[b'\n']));
            pos += bytes;
            if pos > alu_len {
                pos -= alu_len;
            }
            n -= bytes;
        }
        Ok(())
    }
}

fn make_lookup(a: &[AminoAcid]) -> [AminoAcid;LOOKUP_SIZE] {
    let mut lookup = [ NULL_AMINO_ACID;LOOKUP_SIZE ];
    let mut j = 0;
    for (i, slot) in lookup.iter_mut().enumerate() {
        while a[j].p < (i as f32) {
            j += 1;
        }
        *slot = a[j];
    }
    lookup
}

struct RandomFasta<'a, W:'a> {
    seed: u32,
    lookup: [AminoAcid;LOOKUP_SIZE],
    out: &'a mut W,
}

impl<'a, W: Write> RandomFasta<'a, W> {
    fn new(w: &'a mut W, a: &[AminoAcid]) -> RandomFasta<'a, W> {
        RandomFasta {
            seed: 42,
            out: w,
            lookup: make_lookup(a),
        }
    }

    fn rng(&mut self, max: f32) -> f32 {
        self.seed = (self.seed * IA + IC) % IM;
        (max * self.seed as f32) / (IM as f32)
    }

    fn nextc(&mut self) -> u8 {
        let r = self.rng(LOOKUP_SCALE);
        for i in (r as usize..LOOKUP_SIZE) {
            if self.lookup[i].p >= r {
                return self.lookup[i].c;
            }
        }
        unreachable!();
    }

    fn make(&mut self, n: usize) -> io::Result<()> {
        let lines = n / LINE_LEN;
        let chars_left = n % LINE_LEN;
        let mut buf = [0;LINE_LEN + 1];

        for _ in 0..lines {
            for i in 0..LINE_LEN {
                buf[i] = self.nextc();
            }
            buf[LINE_LEN] = '\n' as u8;
            try!(self.out.write(&buf));
        }
        for i in 0..chars_left {
            buf[i] = self.nextc();
        }
        self.out.write_all(&buf[..chars_left])
    }
}

fn main() {
    let mut args = env::args();
    let n = if args.len() > 1 {
        args.nth(1).unwrap().parse::<usize>().unwrap()
    } else {
        5
    };

    let stdout = io::stdout();
    let mut out = stdout.lock();

    out.write_all(b">ONE Homo sapiens alu\n").unwrap();
    {
        let mut repeat = RepeatFasta::new(ALU, &mut out);
        repeat.make(n * 2).unwrap();
    }

    out.write_all(b">TWO IUB ambiguity codes\n").unwrap();
    let iub = sum_and_scale(&IUB);
    let mut random = RandomFasta::new(&mut out, &iub);
    random.make(n * 3).unwrap();

    random.out.write_all(b">THREE Homo sapiens frequency\n").unwrap();
    let homo_sapiens = sum_and_scale(&HOMO_SAPIENS);
    random.lookup = make_lookup(&homo_sapiens);
    random.make(n * 5).unwrap();

    random.out.write_all(b"\n").unwrap();
}
<commit_msg>Use BufWriter in fasta-redux for a nice speedup<commit_after>// The Computer Language Benchmarks Game
// http://benchmarksgame.alioth.debian.org/
//
// contributed by the Rust Project Developers

// Copyright (c) 2013-2014 The Rust Project Developers
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// - Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in
//   the documentation and/or other materials provided with the
//   distribution.
//
// - Neither the name of "The Computer Language Benchmarks Game" nor
//   the name of "The Computer Language Shootout Benchmarks" nor the
//   names of its contributors may be used to endorse or promote
//   products derived from this software without specific prior
//   written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.

use std::cmp::min;
use std::env;
use std::io;
use std::io::BufWriter;
use std::io::prelude::*;

const LINE_LEN: usize = 60;
const LOOKUP_SIZE: usize = 4 * 1024;
const LOOKUP_SCALE: f32 = (LOOKUP_SIZE - 1) as f32;

// Random number generator constants
const IM: u32 = 139968;
const IA: u32 = 3877;
const IC: u32 = 29573;

const ALU: &'static str = "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTG\
                            GGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGA\
                            GACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAA\
                            AATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAAT\
                            CCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAAC\
                            CCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTG\
                            CACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";

const NULL_AMINO_ACID: AminoAcid = AminoAcid { c: ' ' as u8, p: 0.0 };

static IUB: [AminoAcid;15] = [
    AminoAcid { c: 'a' as u8, p: 0.27 },
    AminoAcid { c: 'c' as u8, p: 0.12 },
    AminoAcid { c: 'g' as u8, p: 0.12 },
    AminoAcid { c: 't' as u8, p: 0.27 },
    AminoAcid { c: 'B' as u8, p: 0.02 },
    AminoAcid { c: 'D' as u8, p: 0.02 },
    AminoAcid { c: 'H' as u8, p: 0.02 },
    AminoAcid { c: 'K' as u8, p: 0.02 },
    AminoAcid { c: 'M' as u8, p: 0.02 },
    AminoAcid { c: 'N' as u8, p: 0.02 },
    AminoAcid { c: 'R' as u8, p: 0.02 },
    AminoAcid { c: 'S' as u8, p: 0.02 },
    AminoAcid { c: 'V' as u8, p: 0.02 },
    AminoAcid { c: 'W' as u8, p: 0.02 },
    AminoAcid { c: 'Y' as u8, p: 0.02 },
];

static HOMO_SAPIENS: [AminoAcid;4] = [
    AminoAcid { c: 'a' as u8, p: 0.3029549426680 },
    AminoAcid { c: 'c' as u8, p: 0.1979883004921 },
    AminoAcid { c: 'g' as u8, p: 0.1975473066391 },
    AminoAcid { c: 't' as u8, p: 0.3015094502008 },
];

fn sum_and_scale(a: &'static [AminoAcid]) -> Vec<AminoAcid> {
    let mut p = 0f32;
    let mut result: Vec<AminoAcid> = a.iter().map(|a_i| {
        p += a_i.p;
        AminoAcid { c: a_i.c, p: p * LOOKUP_SCALE }
    }).collect();
    let result_len = result.len();
    result[result_len - 1].p = LOOKUP_SCALE;
    result
}

#[derive(Copy, Clone)]
struct AminoAcid {
    c: u8,
    p: f32,
}

struct RepeatFasta<'a, W:'a> {
    alu: &'static str,
    out: &'a mut W
}

impl<'a, W: Write> RepeatFasta<'a, W> {
    fn new(alu: &'static str, w: &'a mut W) -> RepeatFasta<'a, W> {
        RepeatFasta { alu: alu, out: w }
    }

    fn make(&mut self, n: usize) -> io::Result<()> {
        let alu_len = self.alu.len();
        let mut buf = vec![0; alu_len + LINE_LEN];
        let alu: &[u8] = self.alu.as_bytes();

        for (slot, val) in buf.iter_mut().zip(alu) {
            *slot = *val;
        }
        let buf_len = buf.len();
        for (slot, val) in buf[alu_len..buf_len].iter_mut().zip(&alu[..LINE_LEN]) {
            *slot = *val;
        }

        let mut pos = 0;
        let mut bytes;
        let mut n = n;
        while n > 0 {
            bytes = min(LINE_LEN, n);
            try!(self.out.write_all(&buf[pos..pos + bytes]));
            try!(self.out.write_all(&[b'\n']));
            pos += bytes;
            if pos > alu_len {
                pos -= alu_len;
            }
            n -= bytes;
        }
        Ok(())
    }
}

fn make_lookup(a: &[AminoAcid]) -> [AminoAcid;LOOKUP_SIZE] {
    let mut lookup = [ NULL_AMINO_ACID;LOOKUP_SIZE ];
    let mut j = 0;
    for (i, slot) in lookup.iter_mut().enumerate() {
        while a[j].p < (i as f32) {
            j += 1;
        }
        *slot = a[j];
    }
    lookup
}

struct RandomFasta<'a, W:'a> {
    seed: u32,
    lookup: [AminoAcid;LOOKUP_SIZE],
    out: &'a mut W,
}

impl<'a, W: Write> RandomFasta<'a, W> {
    fn new(w: &'a mut W, a: &[AminoAcid]) -> RandomFasta<'a, W> {
        RandomFasta {
            seed: 42,
            out: w,
            lookup: make_lookup(a),
        }
    }

    fn rng(&mut self, max: f32) -> f32 {
        self.seed = (self.seed * IA + IC) % IM;
        (max * self.seed as f32) / (IM as f32)
    }

    fn nextc(&mut self) -> u8 {
        let r = self.rng(LOOKUP_SCALE);
        for i in (r as usize..LOOKUP_SIZE) {
            if self.lookup[i].p >= r {
                return self.lookup[i].c;
            }
        }
        unreachable!();
    }

    fn make(&mut self, n: usize) -> io::Result<()> {
        let lines = n / LINE_LEN;
        let chars_left = n % LINE_LEN;
        let mut buf = [0;LINE_LEN + 1];

        for _ in 0..lines {
            for i in 0..LINE_LEN {
                buf[i] = self.nextc();
            }
            buf[LINE_LEN] = '\n' as u8;
            try!(self.out.write(&buf));
        }
        for i in 0..chars_left {
            buf[i] = self.nextc();
        }
        self.out.write_all(&buf[..chars_left])
    }
}

fn main() {
    let mut args = env::args();
    let n = if args.len() > 1 {
        args.nth(1).unwrap().parse::<usize>().unwrap()
    } else {
        5
    };

    let stdout = io::stdout();
    let mut out = BufWriter::new(stdout.lock());

    out.write_all(b">ONE Homo sapiens alu\n").unwrap();
    {
        let mut repeat = RepeatFasta::new(ALU, &mut out);
        repeat.make(n * 2).unwrap();
    }

    out.write_all(b">TWO IUB ambiguity codes\n").unwrap();
    let iub = sum_and_scale(&IUB);
    let mut random = RandomFasta::new(&mut out, &iub);
    random.make(n * 3).unwrap();

    random.out.write_all(b">THREE Homo sapiens frequency\n").unwrap();
    let homo_sapiens = sum_and_scale(&HOMO_SAPIENS);
    random.lookup = make_lookup(&homo_sapiens);
    random.make(n * 5).unwrap();

    random.out.write_all(b"\n").unwrap();
}
<|endoftext|>


<commit_before>// error-pattern:cannot index a value of type `()`
fn main() {
    let z = ();
    log(error, z[0]);
}
<commit_msg>Change error to debug<commit_after>fn main() {
    let z = ();
    log(debug, z[0]); //! ERROR cannot index a value of type `()`
}
<|endoftext|>


<commit_before>use support::{ResultTest,Tap,shell_writes};
use hamcrest::{assert_that};
use std::io::{MemWriter, BufWriter, IoResult};
use std::str::from_utf8_lossy;
use cargo::core::shell::{Shell,ShellConfig};
use term::{Terminal,TerminfoTerminal,color};

fn setup() {
}

fn writer(buf: &mut [u8]) -> Box<Writer> {
    box BufWriter::new(buf) as Box<Writer>
}

test!(non_tty {
    let config = ShellConfig { color: true, verbose: true, tty: false };
    let mut buf: Vec<u8> = Vec::from_elem(9, 0 as u8);

    Shell::create(writer(buf.as_mut_slice()), config).tap(|shell| {
        shell.say("Hey Alex", color::RED).assert();
        assert_that(buf.as_slice(), shell_writes("Hey Alex\n"));
    });
})

test!(color_explicitly_disabled {
    let config = ShellConfig { color: false, verbose: true, tty: true };
    let mut buf: Vec<u8> = Vec::from_elem(9, 0 as u8);

    Shell::create(writer(buf.as_mut_slice()), config).tap(|shell| {
        shell.say("Hey Alex", color::RED).assert();
        assert_that(buf.as_slice(), shell_writes("Hey Alex\n"));
    });
})

test!(colored_shell {
    let config = ShellConfig { color: true, verbose: true, tty: true };
    let mut buf: Vec<u8> = Vec::from_elem(22, 0 as u8);

    Shell::create(writer(buf.as_mut_slice()), config).tap(|shell| {
        shell.say("Hey Alex", color::RED).assert();
        assert_that(buf.as_slice(), shell_writes(colored_output("Hey Alex\n",
                                                       color::RED).assert()));
    });
})

fn colored_output<S: Str>(string: S, color: color::Color) -> IoResult<String> {
    let mut term: TerminfoTerminal<MemWriter> =
        Terminal::new(MemWriter::new()).assert();
    try!(term.reset());
    try!(term.fg(color));
    try!(term.write_str(string.as_slice()));
    try!(term.reset());
    try!(term.flush());
    Ok(from_utf8_lossy(term.get_ref().get_ref()).to_str())
}
<commit_msg>Fix a red test<commit_after>use support::{ResultTest,Tap,shell_writes};
use hamcrest::{assert_that};
use std::io::{MemWriter, BufWriter, IoResult};
use std::str::from_utf8_lossy;
use cargo::core::shell::{Shell,ShellConfig};
use term::{Terminal,TerminfoTerminal,color};

fn setup() {
}

fn writer(buf: &mut [u8]) -> Box<Writer> {
    box BufWriter::new(buf) as Box<Writer>
}

test!(non_tty {
    let config = ShellConfig { color: true, verbose: true, tty: false };
    let mut buf: Vec<u8> = Vec::from_elem(9, 0 as u8);

    Shell::create(writer(buf.as_mut_slice()), config).tap(|shell| {
        shell.say("Hey Alex", color::RED).assert();
        assert_that(buf.as_slice(), shell_writes("Hey Alex\n"));
    });
})

test!(color_explicitly_disabled {
    let config = ShellConfig { color: false, verbose: true, tty: true };
    let mut buf: Vec<u8> = Vec::from_elem(9, 0 as u8);

    Shell::create(writer(buf.as_mut_slice()), config).tap(|shell| {
        shell.say("Hey Alex", color::RED).assert();
        assert_that(buf.as_slice(), shell_writes("Hey Alex\n"));
    });
})

test!(colored_shell {
    let config = ShellConfig { color: true, verbose: true, tty: true };
    let mut buf: Vec<u8> = Vec::from_elem(100, 0 as u8);

    Shell::create(writer(buf.as_mut_slice()), config).tap(|shell| {
        shell.say("Hey Alex", color::RED).assert();
        let buf = buf.as_slice().slice_to(buf.iter().position(|a| *a == 0).unwrap());
        assert_that(buf, shell_writes(colored_output("Hey Alex\n",
                                                     color::RED).assert()));
    });
})

fn colored_output<S: Str>(string: S, color: color::Color) -> IoResult<String> {
    let mut term: TerminfoTerminal<MemWriter> =
        Terminal::new(MemWriter::new()).assert();
    try!(term.reset());
    try!(term.fg(color));
    try!(term.write_str(string.as_slice()));
    try!(term.reset());
    try!(term.flush());
    Ok(from_utf8_lossy(term.get_ref().get_ref()).to_str())
}
<|endoftext|>


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

// This should stop any current running database, and start a new one
// that has the database 'test', containing the table 'test'
// and also has a user named 'bob', with password 'secret'
pub fn setup() {
    //setup code specific to your library's tests would go here
    Command::new("sh")
	.arg("-c")
	.arg("rm -rf tests/rethinkdb_data")
	.spawn()
	.expect("failed to kill databases");

    Command::new("sh")
	.arg("-c")
	.arg("cp -r tests/fresh_data tests/rethinkdb_data")
	.spawn()
	.expect("failed to kill databases");

    Command::new("sh")
	.arg("-c")
	.arg("killall rethinkdb")
	.spawn()
	.expect("failed to kill databases");

    std::thread::sleep(std::time::Duration::from_millis(500));

    Command::new("rethinkdb")
	.arg("--daemon")
	.arg("--directory")
	.arg("tests/rethinkdb_data")
	.spawn()
	.expect("failed to start database");
	// takes time for the test to get tables ready
	std::thread::sleep(std::time::Duration::from_millis(10000));
}
<commit_msg>Increased wait time for database to become ready<commit_after>use std::process::Command;

// This should stop any current running database, and start a new one
// that has the database 'test', containing the table 'test'
// and also has a user named 'bob', with password 'secret'
pub fn setup() {
    //setup code specific to your library's tests would go here
    Command::new("sh")
	.arg("-c")
	.arg("rm -rf tests/rethinkdb_data")
	.spawn()
	.expect("failed to kill databases");

    Command::new("sh")
	.arg("-c")
	.arg("cp -r tests/fresh_data tests/rethinkdb_data")
	.spawn()
	.expect("failed to kill databases");

    Command::new("sh")
	.arg("-c")
	.arg("killall rethinkdb")
	.spawn()
	.expect("failed to kill databases");

    std::thread::sleep(std::time::Duration::from_millis(500));

    Command::new("rethinkdb")
	.arg("--daemon")
	.arg("--directory")
	.arg("tests/rethinkdb_data")
	.spawn()
	.expect("failed to start database");
	// takes time for the test to get tables ready
	std::thread::sleep(std::time::Duration::from_secs(20));
}
<|endoftext|>


<commit_before>macro_rules! json_str {
    ([]) => {
        "[]"
    };
    ([ $e0:tt $(, $e:tt)* ]) => {
        concat!("[",
            json_str!($e0),
            $(",", json_str!($e),)*
        "]")
    };
    ({}) => {
        "{}"
    };
    ({ $k0:tt : $v0:tt $(, $k:tt : $v:tt)* }) => {
        concat!("{",
            stringify!($k0), ":", json_str!($v0),
            $(",", stringify!($k), ":", json_str!($v),)*
        "}")
    };
    (($other:tt)) => {
        $other
    };
    ($other:tt) => {
        stringify!($other)
    };
}

macro_rules! pretty_str {
    ($json:tt) => {
        pretty_str_impl!("", $json)
    };
}

macro_rules! pretty_str_impl {
    ($indent:expr, []) => {
        "[]"
    };
    ($indent:expr, [ $e0:tt $(, $e:tt)* ]) => {
        concat!("[\n  ",
            $indent, pretty_str_impl!(concat!("  ", $indent), $e0),
            $(",\n  ", $indent, pretty_str_impl!(concat!("  ", $indent), $e),)*
        "\n", $indent, "]")
    };
    ($indent:expr, {}) => {
        "{}"
    };
    ($indent:expr, { $k0:tt : $v0:tt $(, $k:tt : $v:tt)* }) => {
        concat!("{\n  ",
            $indent, stringify!($k0), ": ", pretty_str_impl!(concat!("  ", $indent), $v0),
            $(",\n  ", $indent, stringify!($k), ": ", pretty_str_impl!(concat!("  ", $indent), $v),)*
        "\n", $indent, "}")
    };
    ($indent:expr, ($other:tt)) => {
        $other
    };
    ($indent:expr, $other:tt) => {
        stringify!($other)
    };
}
<commit_msg>Allow but ignore trailing comma in test macros<commit_after>macro_rules! json_str {
    ([]) => {
        "[]"
    };
    ([ $e0:tt $(, $e:tt)* $(,)? ]) => {
        concat!("[",
            json_str!($e0),
            $(",", json_str!($e),)*
        "]")
    };
    ({}) => {
        "{}"
    };
    ({ $k0:tt : $v0:tt $(, $k:tt : $v:tt)* $(,)? }) => {
        concat!("{",
            stringify!($k0), ":", json_str!($v0),
            $(",", stringify!($k), ":", json_str!($v),)*
        "}")
    };
    (($other:tt)) => {
        $other
    };
    ($other:tt) => {
        stringify!($other)
    };
}

macro_rules! pretty_str {
    ($json:tt) => {
        pretty_str_impl!("", $json)
    };
}

macro_rules! pretty_str_impl {
    ($indent:expr, []) => {
        "[]"
    };
    ($indent:expr, [ $e0:tt $(, $e:tt)* $(,)? ]) => {
        concat!("[\n  ",
            $indent, pretty_str_impl!(concat!("  ", $indent), $e0),
            $(",\n  ", $indent, pretty_str_impl!(concat!("  ", $indent), $e),)*
        "\n", $indent, "]")
    };
    ($indent:expr, {}) => {
        "{}"
    };
    ($indent:expr, { $k0:tt : $v0:tt $(, $k:tt : $v:tt)* $(,)? }) => {
        concat!("{\n  ",
            $indent, stringify!($k0), ": ", pretty_str_impl!(concat!("  ", $indent), $v0),
            $(",\n  ", $indent, stringify!($k), ": ", pretty_str_impl!(concat!("  ", $indent), $v),)*
        "\n", $indent, "}")
    };
    ($indent:expr, ($other:tt)) => {
        $other
    };
    ($indent:expr, $other:tt) => {
        stringify!($other)
    };
}
<|endoftext|>