<commit_before>use super::treenode::*;
use super::values::*;
use std::rc::*;

///
/// BasicTree is a basic in-memory tree node
///
pub struct BasicTree {
    tag: String,
    value: TreeValue,

    child: Option<Rc<TreeNode>>,
    sibling: Option<Rc<TreeNode>>
}

impl BasicTree {
    ///
    /// Creates a new tree node with a particular tag and no siblings
    ///
    pub fn new<TValue: ToTreeValue>(tag: &str, value: TValue) -> BasicTree {
        BasicTree { tag: tag.to_string(), value: value.to_tree_value(), child: None, sibling: None }
    }

    ///
    /// Copies a node into a new basic node
    ///
    pub fn from<'a, TNode: ToTreeNode>(node: &'a ToTreeNode) -> BasicTree {
        let as_tree_node    = (*node).to_tree_node();
        let child           = (*as_tree_node).get_child_ref().map(|n| (*n).to_owned());
        let sibling         = (*as_tree_node).get_sibling_ref().map(|n| (*n).to_owned());

        BasicTree {
            tag:        (*as_tree_node).get_tag().to_owned(),
            value:      (*as_tree_node).get_value().to_owned(),
            child:      child,
            sibling:    sibling
        }
    }
}

impl TreeNode for BasicTree {
    ///
    /// Retrieves a reference to the child of this tree node (or None if this node has no child)
    ///
    fn get_child_ref(&self) -> Option<&Rc<TreeNode>> {
        match self.child {
            Some(ref child) => Some(child),
            None => None
        }
    }

    ///
    /// Retrieves a reference to the sibling of this tree node (or None if this node has no sibling)
    ///
    fn get_sibling_ref(&self) -> Option<&Rc<TreeNode>> {
        match self.sibling {
            Some(ref sibling) => Some(sibling),
            None => None
        }
    }

    ///
    /// Retrieves the tag attached to this tree node
    ///
    fn get_tag(&self) -> &str {
        &self.tag
    }

    ///
    /// Retrieves the value attached to this node
    ///
    fn get_value(&self) -> &TreeValue {
        &self.value
    }
}

impl MutableTreeNode for BasicTree {
    ///
    /// Sets the child for this tree node
    ///
    fn set_child_ref(&mut self, new_node: Rc<TreeNode>) {
        self.child = Some(new_node);
    }

    ///
    /// Sets the sibling for this tree node
    ///
    fn set_sibling_ref(&mut self, new_node: Rc<TreeNode>) {
        self.sibling = Some(new_node);
    }

    ///
    /// Unsets the child for this node
    ///
    fn clear_child(&mut self) {
        self.child = None;
    }

    ///
    /// Unsets the sibling for this node
    ///
    fn clear_sibling(&mut self) {
        self.sibling = None;
    }

    ///
    /// Changes the value set for this node.
    ///
    fn set_tree_value(&mut self, new_value: TreeValue) {
        self.value = new_value;
    }

    ///
    /// Changes the tag attached to this tree
    ///
    fn set_tag(&mut self, new_tag: &str) {
        self.tag = new_tag.to_string();
    }
}

impl<'a> ToTreeNode for &'a str {
    fn to_tree_node(&self) -> Rc<TreeNode> {
        Rc::new(BasicTree::new(self, ()))
    }
}

impl<'a, TValue: ToTreeValue> ToTreeNode for (&'a str, TValue) {
    fn to_tree_node(&self) -> Rc<TreeNode> {
        let (ref tag, ref value) = *self;
        Rc::new(BasicTree::new(tag, value.to_tree_value()))
    }
}

#[cfg(test)]
mod basictree_tests {
    use super::*;
    use super::super::values::*;
    use super::super::treenode::*;
    use std::rc::*;

    #[test]
    fn can_create_basictree() {
        let tree = BasicTree::new("test", ());

        assert!(tree.get_tag() == "test");
        assert!(tree.get_value().is_nothing());
        assert!(tree.get_child_ref().is_none());
        assert!(tree.get_sibling_ref().is_none());
    }

    #[test]
    fn value_is_set() {
        let tree = BasicTree::new("test", 1);

        assert!(tree.get_tag() == "test");
        assert!(!tree.get_value().is_nothing());
    }

    #[test]
    fn can_set_child() {
        let mut tree = BasicTree::new("test", ());

        tree.set_child(("child", "childvalue"));

        assert!(tree.get_child_ref().is_some());
        assert!((tree.get_child_ref().unwrap().get_tag()) == "child");
        assert!(tree.get_sibling_ref().is_none());
    }

    #[test]
    fn can_set_sibling() {
        let mut tree = BasicTree::new("test", ());
        let sibling = Rc::new(BasicTree::new("sibling", ()));

        tree.set_sibling_ref(sibling);

        assert!(tree.get_sibling_ref().is_some());
        assert!((tree.get_sibling_ref().unwrap().get_tag()) == "sibling");
        assert!(tree.get_child_ref().is_none());
    }

    #[test]
    fn can_set_tag() {
        let mut tree = BasicTree::new("test", ());

        tree.set_tag("newtag");

        assert!(tree.get_tag() == "newtag");
    }

    #[test]
    fn can_set_value() {
        let mut tree = BasicTree::new("test", ());

        assert!(tree.get_value().is_nothing());

        tree.set_tree_value(TreeValue::String("Some value".to_string()));

        assert!(match *tree.get_value() { TreeValue::String(ref x) => x == "Some value", _ => false });
    }
}
<commit_msg>Fix BasicTree::from so it works (didn't use type parameter properly, Rust generated series of nonsensical errors that took ages to debug)<commit_after>use super::treenode::*;
use super::values::*;
use std::rc::*;

///
/// BasicTree is a basic in-memory tree node
///
pub struct BasicTree {
    tag: String,
    value: TreeValue,

    child: Option<Rc<TreeNode>>,
    sibling: Option<Rc<TreeNode>>
}

impl BasicTree {
    ///
    /// Creates a new tree node with a particular tag and no siblings
    ///
    pub fn new<TValue: ToTreeValue>(tag: &str, value: TValue) -> BasicTree {
        BasicTree { tag: tag.to_string(), value: value.to_tree_value(), child: None, sibling: None }
    }

    ///
    /// Copies a node into a new basic node
    ///
    pub fn from<TNode: ToTreeNode>(node: TNode) -> BasicTree {
        let as_tree_node    = node.to_tree_node();
        let child           = (*as_tree_node).get_child_ref().map(|n| (*n).to_owned());
        let sibling         = (*as_tree_node).get_sibling_ref().map(|n| (*n).to_owned());

        BasicTree {
            tag:        (*as_tree_node).get_tag().to_owned(),
            value:      (*as_tree_node).get_value().to_owned(),
            child:      child,
            sibling:    sibling
        }
    }
}

impl TreeNode for BasicTree {
    ///
    /// Retrieves a reference to the child of this tree node (or None if this node has no child)
    ///
    fn get_child_ref(&self) -> Option<&Rc<TreeNode>> {
        match self.child {
            Some(ref child) => Some(child),
            None => None
        }
    }

    ///
    /// Retrieves a reference to the sibling of this tree node (or None if this node has no sibling)
    ///
    fn get_sibling_ref(&self) -> Option<&Rc<TreeNode>> {
        match self.sibling {
            Some(ref sibling) => Some(sibling),
            None => None
        }
    }

    ///
    /// Retrieves the tag attached to this tree node
    ///
    fn get_tag(&self) -> &str {
        &self.tag
    }

    ///
    /// Retrieves the value attached to this node
    ///
    fn get_value(&self) -> &TreeValue {
        &self.value
    }
}

impl MutableTreeNode for BasicTree {
    ///
    /// Sets the child for this tree node
    ///
    fn set_child_ref(&mut self, new_node: Rc<TreeNode>) {
        self.child = Some(new_node);
    }

    ///
    /// Sets the sibling for this tree node
    ///
    fn set_sibling_ref(&mut self, new_node: Rc<TreeNode>) {
        self.sibling = Some(new_node);
    }

    ///
    /// Unsets the child for this node
    ///
    fn clear_child(&mut self) {
        self.child = None;
    }

    ///
    /// Unsets the sibling for this node
    ///
    fn clear_sibling(&mut self) {
        self.sibling = None;
    }

    ///
    /// Changes the value set for this node.
    ///
    fn set_tree_value(&mut self, new_value: TreeValue) {
        self.value = new_value;
    }

    ///
    /// Changes the tag attached to this tree
    ///
    fn set_tag(&mut self, new_tag: &str) {
        self.tag = new_tag.to_string();
    }
}

impl<'a> ToTreeNode for &'a str {
    fn to_tree_node(&self) -> Rc<TreeNode> {
        Rc::new(BasicTree::new(self, ()))
    }
}

impl<'a, TValue: ToTreeValue> ToTreeNode for (&'a str, TValue) {
    fn to_tree_node(&self) -> Rc<TreeNode> {
        let (ref tag, ref value) = *self;
        Rc::new(BasicTree::new(tag, value.to_tree_value()))
    }
}

#[cfg(test)]
mod basictree_tests {
    use super::*;
    use super::super::values::*;
    use super::super::treenode::*;
    use std::rc::*;

    #[test]
    fn can_create_basictree() {
        let tree = BasicTree::new("test", ());

        assert!(tree.get_tag() == "test");
        assert!(tree.get_value().is_nothing());
        assert!(tree.get_child_ref().is_none());
        assert!(tree.get_sibling_ref().is_none());
    }

    #[test]
    fn value_is_set() {
        let tree = BasicTree::new("test", 1);

        assert!(tree.get_tag() == "test");
        assert!(!tree.get_value().is_nothing());
    }

    #[test]
    fn can_set_child() {
        let mut tree = BasicTree::new("test", ());

        tree.set_child(("child", "childvalue"));

        assert!(tree.get_child_ref().is_some());
        assert!((tree.get_child_ref().unwrap().get_tag()) == "child");
        assert!(tree.get_sibling_ref().is_none());
    }

    #[test]
    fn can_set_sibling() {
        let mut tree = BasicTree::new("test", ());
        let sibling = Rc::new(BasicTree::new("sibling", ()));

        tree.set_sibling_ref(sibling);

        assert!(tree.get_sibling_ref().is_some());
        assert!((tree.get_sibling_ref().unwrap().get_tag()) == "sibling");
        assert!(tree.get_child_ref().is_none());
    }

    #[test]
    fn can_set_tag() {
        let mut tree = BasicTree::new("test", ());

        tree.set_tag("newtag");

        assert!(tree.get_tag() == "newtag");
    }

    #[test]
    fn can_set_value() {
        let mut tree = BasicTree::new("test", ());

        assert!(tree.get_value().is_nothing());

        tree.set_tree_value(TreeValue::String("Some value".to_string()));

        assert!(match *tree.get_value() { TreeValue::String(ref x) => x == "Some value", _ => false });
    }

    #[test]
    fn can_clone_from() {
        let tree = "tree".to_tree_node();
        let copy = BasicTree::from(tree);

        assert!(copy.get_tag() == "tree");
    }
}
<|endoftext|>


<commit_before>use crate::FileTime;
use std::ffi::CString;
use std::fs::File;
use std::io;
use std::os::unix::prelude::*;
use std::path::Path;

pub fn set_file_times(p: &Path, atime: FileTime, mtime: FileTime) -> io::Result<()> {
    set_times(p, Some(atime), Some(mtime), false)
}

pub fn set_file_mtime(p: &Path, mtime: FileTime) -> io::Result<()> {
    set_times(p, None, Some(mtime), false)
}

pub fn set_file_atime(p: &Path, atime: FileTime) -> io::Result<()> {
    set_times(p, Some(atime), None, false)
}

pub fn set_file_handle_times(
    f: &File,
    atime: Option<FileTime>,
    mtime: Option<FileTime>,
) -> io::Result<()> {
    let times = [super::to_timespec(&atime), super::to_timespec(&mtime)];
    let rc = unsafe { libc::futimens(f.as_raw_fd(), times.as_ptr()) };
    if rc == 0 {
        Ok(())
    } else {
        Err(io::Error::last_os_error())
    }
}

pub fn set_symlink_file_times(p: &Path, atime: FileTime, mtime: FileTime) -> io::Result<()> {
    set_times(p, Some(atime), Some(mtime), false)
}

fn set_times(
    p: &Path,
    atime: Option<FileTime>,
    mtime: Option<FileTime>,
    symlink: bool,
) -> io::Result<()> {
    let flags = if symlink {
        libc::AT_SYMLINK_NOFOLLOW
    } else {
        0
    };

    let p = CString::new(p.as_os_str().as_bytes())?;
    let times = [super::to_timespec(&atime), super::to_timespec(&mtime)];
    let rc = unsafe { libc::utimensat(libc::AT_FDCWD, p.as_ptr(), times.as_ptr(), flags) };
    if rc == 0 {
        Ok(())
    } else {
        Err(io::Error::last_os_error())
    }
}
<commit_msg>IIUC, we are setting the timestamp of the symlink file rather than (#86)<commit_after>use crate::FileTime;
use std::ffi::CString;
use std::fs::File;
use std::io;
use std::os::unix::prelude::*;
use std::path::Path;

pub fn set_file_times(p: &Path, atime: FileTime, mtime: FileTime) -> io::Result<()> {
    set_times(p, Some(atime), Some(mtime), false)
}

pub fn set_file_mtime(p: &Path, mtime: FileTime) -> io::Result<()> {
    set_times(p, None, Some(mtime), false)
}

pub fn set_file_atime(p: &Path, atime: FileTime) -> io::Result<()> {
    set_times(p, Some(atime), None, false)
}

pub fn set_file_handle_times(
    f: &File,
    atime: Option<FileTime>,
    mtime: Option<FileTime>,
) -> io::Result<()> {
    let times = [super::to_timespec(&atime), super::to_timespec(&mtime)];
    let rc = unsafe { libc::futimens(f.as_raw_fd(), times.as_ptr()) };
    if rc == 0 {
        Ok(())
    } else {
        Err(io::Error::last_os_error())
    }
}

pub fn set_symlink_file_times(p: &Path, atime: FileTime, mtime: FileTime) -> io::Result<()> {
    set_times(p, Some(atime), Some(mtime), true)
}

fn set_times(
    p: &Path,
    atime: Option<FileTime>,
    mtime: Option<FileTime>,
    symlink: bool,
) -> io::Result<()> {
    let flags = if symlink {
        libc::AT_SYMLINK_NOFOLLOW
    } else {
        0
    };

    let p = CString::new(p.as_os_str().as_bytes())?;
    let times = [super::to_timespec(&atime), super::to_timespec(&mtime)];
    let rc = unsafe { libc::utimensat(libc::AT_FDCWD, p.as_ptr(), times.as_ptr(), flags) };
    if rc == 0 {
        Ok(())
    } else {
        Err(io::Error::last_os_error())
    }
}
<|endoftext|>


<commit_before>use super::MessageAction;
use super::MessageActionBuilder;
use super::{InjectMode, INJECT_MODE_DEFAULT};
use config::action::ExecCondition;

use handlebars::Template;
use serde::de::{Deserialize, Deserializer, Error, MapVisitor, Visitor};
use std::collections::BTreeMap;

impl Deserialize for MessageAction {
    fn deserialize<D>(deserializer: &mut D) -> Result<MessageAction, D::Error>
        where D: Deserializer
    {
        deserializer.visit_struct("MessageAction", &[], MessageActionVisitor)
    }
}

enum Field {
    Uuid,
    Name,
    Message,
    Values,
    When,
    InjectMode
}

impl Deserialize for Field {
    fn deserialize<D>(deserializer: &mut D) -> Result<Field, D::Error>
        where D: Deserializer
    {
        struct FieldVisitor;

        impl Visitor for FieldVisitor {
            type Value = Field;

            fn visit_str<E>(&mut self, value: &str) -> Result<Field, E>
                where E: Error
            {
                match value {
                    "name" => Ok(Field::Name),
                    "uuid" => Ok(Field::Uuid),
                    "values" => Ok(Field::Values),
                    "message" => Ok(Field::Message),
                    "when" => Ok(Field::When),
                    "inject_mode" => Ok(Field::InjectMode),
                    _ => Err(Error::syntax(&format!("Unexpected field: {}", value))),
                }
            }
        }

        deserializer.visit(FieldVisitor)
    }
}

struct MessageActionVisitor;

impl MessageActionVisitor {
    fn compile_template<V>(template_string: String, uuid: &String) -> Result<Template, V::Error>
        where V: MapVisitor
    {
        match Template::compile(template_string) {
            Ok(message) => Ok(message),
            Err(error) => {
                return Err(Error::syntax(&format!("Invalid handlebars template in 'message' \
                                                   field: uuid={}, error={}",
                                                  &uuid,
                                                  error)));
            }
        }
    }
}

impl Visitor for MessageActionVisitor {
    type Value = MessageAction;

    fn visit_map<V>(&mut self, mut visitor: V) -> Result<MessageAction, V::Error>
        where V: MapVisitor
    {
        let mut name: Option<String> = None;
        let mut uuid: Option<String> = None;
        let mut message: Option<String> = None;
        let mut values: Option<BTreeMap<String, String>> = None;
        let mut when: ExecCondition = ExecCondition::new();
        let mut inject_mode = INJECT_MODE_DEFAULT;

        loop {
            match try!(visitor.visit_key()) {
                Some(Field::Name) => {
                    name = Some(try!(visitor.visit_value()));
                }
                Some(Field::Uuid) => {
                    uuid = Some(try!(visitor.visit_value()));
                }
                Some(Field::Message) => {
                    message = Some(try!(visitor.visit_value()));
                }
                Some(Field::Values) => {
                    values = Some(try!(visitor.visit_value()));
                }
                Some(Field::When) => {
                    when = try!(visitor.visit_value());
                }
                Some(Field::InjectMode) => {
                    inject_mode = try!(visitor.visit_value());
                }
                None => {
                    break;
                }
            }
        }

        let uuid = match uuid {
            Some(uuid) => uuid,
            None => return visitor.missing_field("uuid"),
        };

        let message = match message {
            Some(message) => {
                try!(MessageActionVisitor::compile_template::<V>(message, &uuid))
            }
            None => {
                error!("Missing 'message' field: uuid={}", &uuid);
                return visitor.missing_field("message");
            }
        };

        let values = match values {
            Some(values) => {
                let mut converted_values = BTreeMap::new();
                for (key, value) in values.into_iter() {
                    let template = try!(MessageActionVisitor::compile_template::<V>(value, &uuid));
                    converted_values.insert(key, template);
                }
                converted_values
            }
            None => BTreeMap::new(),
        };

        try!(visitor.end());

        Ok(MessageActionBuilder::new(uuid, message)
                                .name(name)
                                .values(values)
                                .when(when)
                                .inject_mode(inject_mode)
                                .build())
    }
}

impl Deserialize for InjectMode {
    fn deserialize<D>(deserializer: &mut D) -> Result<InjectMode, D::Error>
        where D: Deserializer
    {
        struct FieldVisitor;

        impl Visitor for FieldVisitor {
            type Value = InjectMode;

            fn visit_str<E>(&mut self, value: &str) -> Result<InjectMode, E>
                where E: Error
            {
                match value {
                    "log" => Ok(InjectMode::Log),
                    "loopback" => Ok(InjectMode::Loopback),
                    "forward" => Ok(InjectMode::Forward),
                    _ => Err(Error::syntax(&format!("Unexpected field: {}", value))),
                }
            }
        }

        deserializer.visit(FieldVisitor)
    }
}

#[cfg(test)]
mod test {
    use config::action::message::{MessageActionBuilder, MessageAction, InjectMode};

    use handlebars::Template;
    use serde_json::from_str;

    #[test]
    fn test_given_message_as_a_json_string_when_it_is_deserialized_then_we_get_the_expected_message
        () {
        let text = r#"
        {
          "uuid": "UUID",
          "name": "NAME",
          "message": "message",
          "values": {
            "key1": "value1",
            "key2": "value2"
          }
        }
        "#;

        let message = Template::compile("message".to_string())
                          .ok()
                          .expect("Failed to compile a handlebars template");
        let value1 = Template::compile("value1".to_string())
                         .ok()
                         .expect("Failed to compile a handlebars template");
        let value2 = Template::compile("value2".to_string())
                         .ok()
                         .expect("Failed to compile a handlebars template");
        let expected_message = MessageActionBuilder::new("UUID", message)
                                   .name(Some("NAME"))
                                   .pair("key1", value1)
                                   .pair("key2", value2)
                                   .build();
        let result = from_str::<MessageAction>(text);
        println!("{:?}", &result);
        let message = result.ok().expect("Failed to deserialize a valid MessageAction object");
        assert_eq!(expected_message, message);
    }

    #[test]
    fn test_given_message_as_a_json_string_when_only_the_required_fields_are_present_then_we_can_deserialize_the_message
        () {
        let text = r#"
        {
          "uuid": "UUID",
          "message": "message"
        }
        "#;

        let message = Template::compile("message".to_string())
                          .ok()
                          .expect("Failed to compile a handlebars template");
        let expected_message = MessageActionBuilder::new("UUID", message).build();
        let result = from_str::<MessageAction>(text);
        println!("{:?}", &result);
        let message = result.ok().expect("Failed to deserialize a valid MessageAction object");
        assert_eq!(expected_message, message);
    }

    #[test]
    fn test_given_message_as_a_json_string_when_one_of_the_required_fields_are_not_present_then_we_get_error
        () {
        let text = r#"
        {
        }
        "#;

        let result = from_str::<MessageAction>(text);
        println!("{:?}", &result);
        let _ = result.err().expect("Successfully deserialized an invalid MessageAction object");
    }

    #[test]
    fn test_given_inject_modes_when_they_are_deserialized_then_we_get_the_right_result() {
        let text = r#"
        ["forward", "log", "loopback", "log"]
        "#;
        let expected = vec![InjectMode::Forward, InjectMode::Log, InjectMode::Loopback, InjectMode::Log];

        let result = from_str::<Vec<InjectMode>>(text);
        println!("{:?}", &result);
        let array = result.ok().expect("Failed to deserialize a valid array of inject modes");
        assert_eq!(&expected, &array);
    }

    #[test]
    fn test_given_invalid_inject_mode_when_it_is_deserialized_then_we_get_the_right_result() {
        let text = r#"
        ["invalid inject mode", "log"]
        "#;

        let result = from_str::<Vec<InjectMode>>(text);
        println!("{:?}", &result);
        let _ = result.err().expect("Successfully deserialized an invalid inject mode");
    }

    #[test]
    fn test_given_message_when_it_contains_inject_mode_then_it_can_be_deserialized() {
        let text = r#"
        {
          "uuid": "UUID",
          "message": "message",
          "inject_mode": "forward"
        }
        "#;

        let message = Template::compile("message".to_string())
                          .ok()
                          .expect("Failed to compile a handlebars template");
        let expected_message = MessageActionBuilder::new("UUID", message).inject_mode(InjectMode::Forward).build();
        let result = from_str::<MessageAction>(text);
        println!("{:?}", &result);
        let message = result.ok().expect("Failed to deserialize a valid MessageAction object");
        assert_eq!(expected_message, message);
    }
}
<commit_msg>MessageActionVisitor: simplify loop in visit_map()<commit_after>use super::MessageAction;
use super::MessageActionBuilder;
use super::{InjectMode, INJECT_MODE_DEFAULT};
use config::action::ExecCondition;

use handlebars::Template;
use serde::de::{Deserialize, Deserializer, Error, MapVisitor, Visitor};
use std::collections::BTreeMap;

impl Deserialize for MessageAction {
    fn deserialize<D>(deserializer: &mut D) -> Result<MessageAction, D::Error>
        where D: Deserializer
    {
        deserializer.visit_struct("MessageAction", &[], MessageActionVisitor)
    }
}

enum Field {
    Uuid,
    Name,
    Message,
    Values,
    When,
    InjectMode
}

impl Deserialize for Field {
    fn deserialize<D>(deserializer: &mut D) -> Result<Field, D::Error>
        where D: Deserializer
    {
        struct FieldVisitor;

        impl Visitor for FieldVisitor {
            type Value = Field;

            fn visit_str<E>(&mut self, value: &str) -> Result<Field, E>
                where E: Error
            {
                match value {
                    "name" => Ok(Field::Name),
                    "uuid" => Ok(Field::Uuid),
                    "values" => Ok(Field::Values),
                    "message" => Ok(Field::Message),
                    "when" => Ok(Field::When),
                    "inject_mode" => Ok(Field::InjectMode),
                    _ => Err(Error::syntax(&format!("Unexpected field: {}", value))),
                }
            }
        }

        deserializer.visit(FieldVisitor)
    }
}

struct MessageActionVisitor;

impl MessageActionVisitor {
    fn compile_template<V>(template_string: String, uuid: &String) -> Result<Template, V::Error>
        where V: MapVisitor
    {
        match Template::compile(template_string) {
            Ok(message) => Ok(message),
            Err(error) => {
                return Err(Error::syntax(&format!("Invalid handlebars template in 'message' \
                                                   field: uuid={}, error={}",
                                                  &uuid,
                                                  error)));
            }
        }
    }
}

impl Visitor for MessageActionVisitor {
    type Value = MessageAction;

    fn visit_map<V>(&mut self, mut visitor: V) -> Result<MessageAction, V::Error>
        where V: MapVisitor
    {
        let mut name: Option<String> = None;
        let mut uuid: Option<String> = None;
        let mut message: Option<String> = None;
        let mut values: Option<BTreeMap<String, String>> = None;
        let mut when: ExecCondition = ExecCondition::new();
        let mut inject_mode = INJECT_MODE_DEFAULT;

        while let Some(field) = try!(visitor.visit_key()) {
            match field {
                Field::Name => name = Some(try!(visitor.visit_value())),
                Field::Uuid => uuid = Some(try!(visitor.visit_value())),
                Field::Message => message = Some(try!(visitor.visit_value())),
                Field::Values => values = Some(try!(visitor.visit_value())),
                Field::When => when = try!(visitor.visit_value()),
                Field::InjectMode => inject_mode = try!(visitor.visit_value())
            }
        }

        let uuid = match uuid {
            Some(uuid) => uuid,
            None => return visitor.missing_field("uuid"),
        };

        let message = match message {
            Some(message) => {
                try!(MessageActionVisitor::compile_template::<V>(message, &uuid))
            }
            None => {
                error!("Missing 'message' field: uuid={}", &uuid);
                return visitor.missing_field("message");
            }
        };

        let values = match values {
            Some(values) => {
                let mut converted_values = BTreeMap::new();
                for (key, value) in values.into_iter() {
                    let template = try!(MessageActionVisitor::compile_template::<V>(value, &uuid));
                    converted_values.insert(key, template);
                }
                converted_values
            }
            None => BTreeMap::new(),
        };

        try!(visitor.end());

        Ok(MessageActionBuilder::new(uuid, message)
                                .name(name)
                                .values(values)
                                .when(when)
                                .inject_mode(inject_mode)
                                .build())
    }
}

impl Deserialize for InjectMode {
    fn deserialize<D>(deserializer: &mut D) -> Result<InjectMode, D::Error>
        where D: Deserializer
    {
        struct FieldVisitor;

        impl Visitor for FieldVisitor {
            type Value = InjectMode;

            fn visit_str<E>(&mut self, value: &str) -> Result<InjectMode, E>
                where E: Error
            {
                match value {
                    "log" => Ok(InjectMode::Log),
                    "loopback" => Ok(InjectMode::Loopback),
                    "forward" => Ok(InjectMode::Forward),
                    _ => Err(Error::syntax(&format!("Unexpected field: {}", value))),
                }
            }
        }

        deserializer.visit(FieldVisitor)
    }
}

#[cfg(test)]
mod test {
    use config::action::message::{MessageActionBuilder, MessageAction, InjectMode};

    use handlebars::Template;
    use serde_json::from_str;

    #[test]
    fn test_given_message_as_a_json_string_when_it_is_deserialized_then_we_get_the_expected_message
        () {
        let text = r#"
        {
          "uuid": "UUID",
          "name": "NAME",
          "message": "message",
          "values": {
            "key1": "value1",
            "key2": "value2"
          }
        }
        "#;

        let message = Template::compile("message".to_string())
                          .ok()
                          .expect("Failed to compile a handlebars template");
        let value1 = Template::compile("value1".to_string())
                         .ok()
                         .expect("Failed to compile a handlebars template");
        let value2 = Template::compile("value2".to_string())
                         .ok()
                         .expect("Failed to compile a handlebars template");
        let expected_message = MessageActionBuilder::new("UUID", message)
                                   .name(Some("NAME"))
                                   .pair("key1", value1)
                                   .pair("key2", value2)
                                   .build();
        let result = from_str::<MessageAction>(text);
        println!("{:?}", &result);
        let message = result.ok().expect("Failed to deserialize a valid MessageAction object");
        assert_eq!(expected_message, message);
    }

    #[test]
    fn test_given_message_as_a_json_string_when_only_the_required_fields_are_present_then_we_can_deserialize_the_message
        () {
        let text = r#"
        {
          "uuid": "UUID",
          "message": "message"
        }
        "#;

        let message = Template::compile("message".to_string())
                          .ok()
                          .expect("Failed to compile a handlebars template");
        let expected_message = MessageActionBuilder::new("UUID", message).build();
        let result = from_str::<MessageAction>(text);
        println!("{:?}", &result);
        let message = result.ok().expect("Failed to deserialize a valid MessageAction object");
        assert_eq!(expected_message, message);
    }

    #[test]
    fn test_given_message_as_a_json_string_when_one_of_the_required_fields_are_not_present_then_we_get_error
        () {
        let text = r#"
        {
        }
        "#;

        let result = from_str::<MessageAction>(text);
        println!("{:?}", &result);
        let _ = result.err().expect("Successfully deserialized an invalid MessageAction object");
    }

    #[test]
    fn test_given_inject_modes_when_they_are_deserialized_then_we_get_the_right_result() {
        let text = r#"
        ["forward", "log", "loopback", "log"]
        "#;
        let expected = vec![InjectMode::Forward, InjectMode::Log, InjectMode::Loopback, InjectMode::Log];

        let result = from_str::<Vec<InjectMode>>(text);
        println!("{:?}", &result);
        let array = result.ok().expect("Failed to deserialize a valid array of inject modes");
        assert_eq!(&expected, &array);
    }

    #[test]
    fn test_given_invalid_inject_mode_when_it_is_deserialized_then_we_get_the_right_result() {
        let text = r#"
        ["invalid inject mode", "log"]
        "#;

        let result = from_str::<Vec<InjectMode>>(text);
        println!("{:?}", &result);
        let _ = result.err().expect("Successfully deserialized an invalid inject mode");
    }

    #[test]
    fn test_given_message_when_it_contains_inject_mode_then_it_can_be_deserialized() {
        let text = r#"
        {
          "uuid": "UUID",
          "message": "message",
          "inject_mode": "forward"
        }
        "#;

        let message = Template::compile("message".to_string())
                          .ok()
                          .expect("Failed to compile a handlebars template");
        let expected_message = MessageActionBuilder::new("UUID", message).inject_mode(InjectMode::Forward).build();
        let result = from_str::<MessageAction>(text);
        println!("{:?}", &result);
        let message = result.ok().expect("Failed to deserialize a valid MessageAction object");
        assert_eq!(expected_message, message);
    }
}
<|endoftext|>


<commit_before>
extern crate twelve_bit;

use twelve_bit::u12::*;

// MARK: - Tests - Addition

#[test]
fn test_add_operator() {
  let zero = U12::min_value();
  let  one = U12::from(1u8);
  let  max = U12::max_value();

  assert_eq!(zero + zero, zero);
  assert_eq!(zero + one, one);
  assert_eq!(one + zero, one);
  assert_eq!(zero + max, max);
  assert_eq!(max + zero, max);
}

#[test]
#[should_panic]
fn test_add_operator_overflow() {
  let one = U12::from(1u8);
  let max = U12::max_value();
  let _ = max + one;
}

#[test]
fn test_checked_add() {
  let zero = U12::min_value();
  let  one = U12::from(1u8);
  let  two = U12::from(2u8);
  let  max = U12::max_value();

  assert_eq!(zero.checked_add(zero), Some(zero));
  assert_eq!(zero.checked_add(one), Some(one));
  assert_eq!(one.checked_add(zero), Some(one));
  assert_eq!(zero.checked_add(max), Some(max));
  assert_eq!(max.checked_add(zero), Some(max));
  assert_eq!(max.checked_add(one), None);
  assert_eq!(max.checked_add(two), None);
  assert_eq!(max.checked_add(max), None);
}

#[test]
fn test_saturating_add() {
  let zero = U12::min_value();
  let  one = U12::from(1u8);
  let  two = U12::from(2u8);
  let  max = U12::max_value();

  assert_eq!(zero.saturating_add(zero), zero);
  assert_eq!(zero.saturating_add(one), one);
  assert_eq!(one.saturating_add(zero), one);
  assert_eq!(zero.saturating_add(max), max);
  assert_eq!(max.saturating_add(zero), max);
  assert_eq!(max.saturating_add(one), max);
  assert_eq!(max.saturating_add(two), max);
  assert_eq!(max.saturating_add(max), max);
}

#[test]
fn test_wrapping_add() {
  let zero = U12::min_value();
  let  one = U12::from(1u8);
  let  two = U12::from(2u8);
  let  max = U12::max_value();

  assert_eq!(zero.wrapping_add(zero), zero);
  assert_eq!(zero.wrapping_add(one), one);
  assert_eq!(one.wrapping_add(zero), one);
  assert_eq!(zero.wrapping_add(max), max);
  assert_eq!(max.wrapping_add(zero), max);
  assert_eq!(max.wrapping_add(one), zero);
  assert_eq!(max.wrapping_add(two), one);
  assert_eq!(max.wrapping_add(max), 0xFFEu16.unchecked_into());
}

// MARK: - Tests - Subtraction

#[test]
fn test_sub_operator() {
  let zero = U12::min_value();
  let  one = U12::from(1u8);
  let  max = U12::max_value();

  assert_eq!(zero - zero, zero);
  assert_eq!(one - zero, one);
  assert_eq!(max - zero, max);
  assert_eq!(max - one, (0xFFE as u16).unchecked_into());
}

#[test]
#[should_panic]
fn test_sub_operator_underflow() {
  let one = U12::from(1u8);
  let min = U12::min_value();
  let _ = min - one;
}

#[test]
fn test_checked_sub() {
  let zero = U12::min_value();
  let  one = U12::from(1u8);
  let  two = U12::from(2u8);
  let  max = U12::max_value();

  assert_eq!(zero.checked_sub(zero), Some(zero));
  assert_eq!(zero.checked_sub(one), None);
  assert_eq!(one.checked_sub(zero), Some(one));
  assert_eq!(zero.checked_sub(max), None);
  assert_eq!(max.checked_sub(zero), Some(max));
  assert_eq!(max.checked_sub(one), Some((0xFFE as u16).unchecked_into()));
  assert_eq!(max.checked_sub(two), Some((0xFFD as u16).unchecked_into()));
  assert_eq!(max.checked_sub(max), Some(zero));
}

#[test]
fn test_saturating_sub() {
  let zero = U12::min_value();
  let  one = U12::from(1u8);
  let  two = U12::from(2u8);
  let  max = U12::max_value();

  assert_eq!(zero.saturating_sub(zero), zero);
  assert_eq!(zero.saturating_sub(one), zero);
  assert_eq!(one.saturating_sub(zero), one);
  assert_eq!(zero.saturating_sub(max), zero);
  assert_eq!(max.saturating_sub(zero), max);
  assert_eq!(max.saturating_sub(one), (0xFFE as u16).unchecked_into());
  assert_eq!(max.saturating_sub(two), (0xFFD as u16).unchecked_into());
  assert_eq!(max.saturating_sub(max), zero);
}

#[test]
fn test_wrapping_sub() {
  let zero = U12::min_value();
  let  one = U12::from(1u8);
  let  two = U12::from(2u8);
  let  max = U12::max_value();

  assert_eq!(zero.wrapping_sub(zero), zero);
  assert_eq!(zero.wrapping_sub(one), max);
  assert_eq!(one.saturating_sub(zero), one);
  assert_eq!(zero.wrapping_sub(max), one);
  assert_eq!(max.wrapping_sub(zero), max);
  assert_eq!(max.wrapping_sub(one), (0xFFE as u16).unchecked_into());
  assert_eq!(max.wrapping_sub(two), (0xFFD as u16).unchecked_into());
  assert_eq!(max.wrapping_sub(max), zero);
}

// MARK: - Tests - Multiplication

#[test]
fn test_mul_operator() {
  assert_eq!(U12::from(2u8) * U12::from(0u8), U12::min_value());
  assert_eq!(U12::max_value() * U12::min_value(), U12::min_value());
  assert_eq!(U12::from(2u8) * U12::from(255u8), (510 as u16).unchecked_into());
  assert_eq!(U12::from(255u8) * U12::from(2u8), (510 as u16).unchecked_into());
}

#[test]
#[should_panic]
fn test_mul_operator_overflow() {
  let _ = U12::from(2u8) * 2048u16.unchecked_into();
}

#[test]
fn test_checked_mul() {
  assert_eq!(U12::from(2u8).checked_mul(0u8.into()), Some(U12::min_value()));
  assert_eq!(U12::from(2u8).checked_mul(255u8.into()), Some((510 as u16).unchecked_into()));
  assert_eq!(U12::from(255u8).checked_mul(2u8.into()), Some((510 as u16).unchecked_into()));
  assert_eq!(U12::from(2u8).checked_mul((2048u16).unchecked_into()), None);
  assert_eq!(U12::from(2u8).checked_mul((4095u16).unchecked_into()), None);
}

#[test]
fn test_saturating_mul() {
  assert_eq!(U12::from(2u8).saturating_mul(0u8.into()), U12::min_value());
  assert_eq!(U12::from(2u8).saturating_mul(255u8.into()), (510 as u16).unchecked_into());
  assert_eq!(U12::from(255u8).saturating_mul(2u8.into()), (510 as u16).unchecked_into());
  assert_eq!(U12::from(2u8).saturating_mul((2048u16).unchecked_into()), U12::max_value());
  assert_eq!(U12::from(2u8).saturating_mul((4095u16).unchecked_into()), U12::max_value());
}

#[test]
fn test_wrapping_mul() {
  assert_eq!(U12::from(2u8).wrapping_mul(0u8.into()), U12::min_value());
  assert_eq!(U12::from(2u8).wrapping_mul(255u8.into()), (510 as u16).unchecked_into());
  assert_eq!(U12::from(255u8).wrapping_mul(2u8.into()), (510 as u16).unchecked_into());
  assert_eq!(U12::from(2u8).wrapping_mul((2048u16).unchecked_into()), U12::min_value());
  assert_eq!(U12::from(2u8).wrapping_mul((4095u16).unchecked_into()), (0xFFE as u16).unchecked_into());
}
<commit_msg>Tests for Division.<commit_after>
extern crate twelve_bit;

use twelve_bit::u12::*;

// MARK: - Tests - Addition

#[test]
fn test_add_operator() {
  let zero = U12::min_value();
  let  one = U12::from(1u8);
  let  max = U12::max_value();

  assert_eq!(zero + zero, zero);
  assert_eq!(zero + one, one);
  assert_eq!(one + zero, one);
  assert_eq!(zero + max, max);
  assert_eq!(max + zero, max);
}

#[test]
#[should_panic]
fn test_add_operator_overflow() {
  let one = U12::from(1u8);
  let max = U12::max_value();
  let _ = max + one;
}

#[test]
fn test_checked_add() {
  let zero = U12::min_value();
  let  one = U12::from(1u8);
  let  two = U12::from(2u8);
  let  max = U12::max_value();

  assert_eq!(zero.checked_add(zero), Some(zero));
  assert_eq!(zero.checked_add(one), Some(one));
  assert_eq!(one.checked_add(zero), Some(one));
  assert_eq!(zero.checked_add(max), Some(max));
  assert_eq!(max.checked_add(zero), Some(max));
  assert_eq!(max.checked_add(one), None);
  assert_eq!(max.checked_add(two), None);
  assert_eq!(max.checked_add(max), None);
}

#[test]
fn test_saturating_add() {
  let zero = U12::min_value();
  let  one = U12::from(1u8);
  let  two = U12::from(2u8);
  let  max = U12::max_value();

  assert_eq!(zero.saturating_add(zero), zero);
  assert_eq!(zero.saturating_add(one), one);
  assert_eq!(one.saturating_add(zero), one);
  assert_eq!(zero.saturating_add(max), max);
  assert_eq!(max.saturating_add(zero), max);
  assert_eq!(max.saturating_add(one), max);
  assert_eq!(max.saturating_add(two), max);
  assert_eq!(max.saturating_add(max), max);
}

#[test]
fn test_wrapping_add() {
  let zero = U12::min_value();
  let  one = U12::from(1u8);
  let  two = U12::from(2u8);
  let  max = U12::max_value();

  assert_eq!(zero.wrapping_add(zero), zero);
  assert_eq!(zero.wrapping_add(one), one);
  assert_eq!(one.wrapping_add(zero), one);
  assert_eq!(zero.wrapping_add(max), max);
  assert_eq!(max.wrapping_add(zero), max);
  assert_eq!(max.wrapping_add(one), zero);
  assert_eq!(max.wrapping_add(two), one);
  assert_eq!(max.wrapping_add(max), 0xFFEu16.unchecked_into());
}

// MARK: - Tests - Subtraction

#[test]
fn test_sub_operator() {
  let zero = U12::min_value();
  let  one = U12::from(1u8);
  let  max = U12::max_value();

  assert_eq!(zero - zero, zero);
  assert_eq!(one - zero, one);
  assert_eq!(max - zero, max);
  assert_eq!(max - one, (0xFFE as u16).unchecked_into());
}

#[test]
#[should_panic]
fn test_sub_operator_underflow() {
  let one = U12::from(1u8);
  let min = U12::min_value();
  let _ = min - one;
}

#[test]
fn test_checked_sub() {
  let zero = U12::min_value();
  let  one = U12::from(1u8);
  let  two = U12::from(2u8);
  let  max = U12::max_value();

  assert_eq!(zero.checked_sub(zero), Some(zero));
  assert_eq!(zero.checked_sub(one), None);
  assert_eq!(one.checked_sub(zero), Some(one));
  assert_eq!(zero.checked_sub(max), None);
  assert_eq!(max.checked_sub(zero), Some(max));
  assert_eq!(max.checked_sub(one), Some((0xFFE as u16).unchecked_into()));
  assert_eq!(max.checked_sub(two), Some((0xFFD as u16).unchecked_into()));
  assert_eq!(max.checked_sub(max), Some(zero));
}

#[test]
fn test_saturating_sub() {
  let zero = U12::min_value();
  let  one = U12::from(1u8);
  let  two = U12::from(2u8);
  let  max = U12::max_value();

  assert_eq!(zero.saturating_sub(zero), zero);
  assert_eq!(zero.saturating_sub(one), zero);
  assert_eq!(one.saturating_sub(zero), one);
  assert_eq!(zero.saturating_sub(max), zero);
  assert_eq!(max.saturating_sub(zero), max);
  assert_eq!(max.saturating_sub(one), (0xFFE as u16).unchecked_into());
  assert_eq!(max.saturating_sub(two), (0xFFD as u16).unchecked_into());
  assert_eq!(max.saturating_sub(max), zero);
}

#[test]
fn test_wrapping_sub() {
  let zero = U12::min_value();
  let  one = U12::from(1u8);
  let  two = U12::from(2u8);
  let  max = U12::max_value();

  assert_eq!(zero.wrapping_sub(zero), zero);
  assert_eq!(zero.wrapping_sub(one), max);
  assert_eq!(one.saturating_sub(zero), one);
  assert_eq!(zero.wrapping_sub(max), one);
  assert_eq!(max.wrapping_sub(zero), max);
  assert_eq!(max.wrapping_sub(one), (0xFFE as u16).unchecked_into());
  assert_eq!(max.wrapping_sub(two), (0xFFD as u16).unchecked_into());
  assert_eq!(max.wrapping_sub(max), zero);
}

// MARK: - Tests - Multiplication

#[test]
fn test_mul_operator() {
  assert_eq!(U12::from(2u8) * U12::from(0u8), U12::min_value());
  assert_eq!(U12::max_value() * U12::min_value(), U12::min_value());
  assert_eq!(U12::from(2u8) * U12::from(255u8), (510 as u16).unchecked_into());
  assert_eq!(U12::from(255u8) * U12::from(2u8), (510 as u16).unchecked_into());
}

#[test]
#[should_panic]
fn test_mul_operator_overflow() {
  let _ = U12::from(2u8) * 2048u16.unchecked_into();
}

#[test]
fn test_checked_mul() {
  assert_eq!(U12::from(2u8).checked_mul(0u8.into()), Some(U12::min_value()));
  assert_eq!(U12::from(2u8).checked_mul(255u8.into()), Some((510 as u16).unchecked_into()));
  assert_eq!(U12::from(255u8).checked_mul(2u8.into()), Some((510 as u16).unchecked_into()));
  assert_eq!(U12::from(2u8).checked_mul((2048u16).unchecked_into()), None);
  assert_eq!(U12::from(2u8).checked_mul((4095u16).unchecked_into()), None);
}

#[test]
fn test_saturating_mul() {
  assert_eq!(U12::from(2u8).saturating_mul(0u8.into()), U12::min_value());
  assert_eq!(U12::from(2u8).saturating_mul(255u8.into()), (510 as u16).unchecked_into());
  assert_eq!(U12::from(255u8).saturating_mul(2u8.into()), (510 as u16).unchecked_into());
  assert_eq!(U12::from(2u8).saturating_mul((2048u16).unchecked_into()), U12::max_value());
  assert_eq!(U12::from(2u8).saturating_mul((4095u16).unchecked_into()), U12::max_value());
}

#[test]
fn test_wrapping_mul() {
  assert_eq!(U12::from(2u8).wrapping_mul(0u8.into()), U12::min_value());
  assert_eq!(U12::from(2u8).wrapping_mul(255u8.into()), (510 as u16).unchecked_into());
  assert_eq!(U12::from(255u8).wrapping_mul(2u8.into()), (510 as u16).unchecked_into());
  assert_eq!(U12::from(2u8).wrapping_mul((2048u16).unchecked_into()), U12::min_value());
  assert_eq!(U12::from(2u8).wrapping_mul((4095u16).unchecked_into()), (0xFFE as u16).unchecked_into());
}

// MARK: - Tests - Division

#[test]
fn test_div_operator() {
  assert_eq!(U12::max_value() / U12::max_value(), U12::from(1u8));
  assert_eq!(U12::from(2u8) / U12::from(255u8), U12::from(0u8));
  assert_eq!(U12::from(255u8) / U12::from(2u8), U12::from(127u8));
}

#[test]
#[should_panic]
fn test_div_operator_divide_by_zero() {
  let _ = U12::from(2u8) / U12::from(0u8);
}

#[test]
fn test_checked_div() {
  assert_eq!(U12::max_value().checked_div(U12::max_value()), Some(U12::from(1u8)));
  assert_eq!(U12::from(2u8).checked_div(U12::from(255u8)), Some(U12::from(0u8)));
  assert_eq!(U12::from(255u8).checked_div(U12::from(2u8)), Some(U12::from(127u8)));
  assert_eq!(U12::from(255u8).checked_div(U12::from(1u8)), Some(U12::from(255u8)));
  assert_eq!(U12::from(255u8).checked_div(U12::from(0u8)), None);
}

#[test]
fn test_wrapping_div() {
  assert_eq!(U12::max_value().wrapping_div(U12::max_value()), U12::from(1u8));
  assert_eq!(U12::from(2u8).wrapping_div(U12::from(255u8)), U12::from(0u8));
  assert_eq!(U12::from(255u8).wrapping_div(U12::from(2u8)), U12::from(127u8));
  assert_eq!(U12::from(255u8).wrapping_div(U12::from(1u8)), U12::from(255u8));
}

#[test]
#[should_panic]
fn test_wrapping_div_overflow() {
  let _ = U12::from(255u8).wrapping_div(U12::from(0u8));
}
<|endoftext|>


<commit_before>use common::take_cell::TakeCell;
use process::{AppId, AppSlice, Container, Callback, Shared};
use hil::Driver;
use hil::uart::{UART, Client};

pub struct App {
    read_callback: Option<Callback>,
    write_callback: Option<Callback>,
    read_buffer: Option<AppSlice<Shared, u8>>,
    write_buffer: Option<AppSlice<Shared, u8>>,
    write_len: usize,
    read_idx: usize
}

impl Default for App {
    fn default() -> App {
        App {
            read_callback: None,
            write_callback: None,
            read_buffer: None,
            write_buffer: None,
            write_len: 0,
            read_idx: 0
        }
    }
}

pub static mut WRITE_BUF : [u8; 64] = [0; 64];

pub struct Console<'a, U: UART + 'a> {
    uart: &'a U,
    apps: Container<App>,
    buffer: TakeCell<&'static mut [u8]>
}

impl<'a, U: UART> Console<'a, U> {
    pub const fn new(uart: &'a U, buffer: &'static mut [u8],
                     container: Container<App>) -> Console<'a, U> {
        Console {
            uart: uart,
            apps: container,
            buffer: TakeCell::new(buffer)
        }
    }

    pub fn initialize(&self) {
        self.uart.enable_tx();
        self.uart.enable_rx();
    }
}

impl<'a, U: UART> Driver for Console<'a, U> {
    fn allow(&self, appid: AppId,
             allow_num: usize, slice: AppSlice<Shared, u8>) -> isize {
        let app = appid.idx();
        match allow_num {
            0 => {
                self.apps.enter(appid, |app, _| {
                    app.read_buffer = Some(slice);
                    app.read_idx = 0;
                });
                0
            },
            1 => {
                self.apps.enter(appid, |app, _| {
                    app.write_buffer = Some(slice);
                });
                0
            }
            _ => -1
        }
    }

    fn subscribe(&self, subscribe_num: usize, callback: Callback) -> isize {
        match subscribe_num {
            0 /* read line */ => {
                self.apps.enter(callback.app_id(), |app, _| {
                    app.read_callback = Some(callback)
                });
                0
            },
            1 /* putstr/write_done */ => {
                self.apps.enter(callback.app_id(), |app, _| {
                    match app.write_buffer.take() {
                        Some(slice) => {
                            app.write_callback = Some(callback);
                            app.write_len = slice.len();
                            self.buffer.take().map(|buffer| {
                                for (i, c) in slice.as_ref().iter().enumerate() {
                                    buffer[i] = *c;
                                }
                                self.uart.send_bytes(buffer, app.write_len);
                            });
                            0
                        },
                        None => -1
                    }
                }).unwrap_or(-1)
            },
            _ => -1
        }
    }

    fn command(&self, cmd_num: usize, arg1: usize, _: AppId) -> isize {
        match cmd_num {
            0 /* putc */ => { self.uart.send_byte(arg1 as u8); 1 },
            _ => -1
        }
    }
}

fn each_some<'a, T, I, F>(lst: I, mut f: F)
        where T: 'a, I: Iterator<Item=&'a TakeCell<T>>, F: FnMut(&mut T) {
    for item in lst {
        item.map(|i| f(i));
    }
}

impl<'a, U: UART> Client for Console<'a, U> {
    fn write_done(&self, buffer: &'static mut [u8]) {
        self.buffer.replace(buffer);
        self.apps.each(|app| {
            app.write_callback.take().map(|mut cb| {
                cb.schedule(app.write_len, 0, 0);
            });
            app.write_len = 0;
        });
    }

    fn read_done(&self, c: u8) {
        match c as char {
            '\r' => {},
            '\n' => {
                self.apps.each(|app| {
                    let idx = app.read_idx;
                    app.read_buffer = app.read_buffer.take().map(|mut rb| {
                        use core::raw::Repr;
                        app.read_callback.as_mut().map(|cb| {
                            let buf = rb.as_mut();
                            cb.schedule(idx, (buf.repr().data as usize), 0);
                        });
                        rb
                    });
                    app.read_idx = 0;
                });
            },
            _ => {
                self.apps.each(|app| {
                    let idx = app.read_idx;
                    if app.read_buffer.is_some() &&
                        app.read_idx < app.read_buffer.as_ref().unwrap().len() {

                        app.read_buffer.as_mut().map(|buf| {
                            buf.as_mut()[idx] = c;
                        });
                        app.read_idx += 1;
                    }
                });
            }
        }
    }
}

<commit_msg>More virtualized console<commit_after>use common::take_cell::TakeCell;
use process::{AppId, AppSlice, Container, Callback, Shared};
use hil::Driver;
use hil::uart::{UART, Client};

pub struct App {
    read_callback: Option<Callback>,
    write_callback: Option<Callback>,
    read_buffer: Option<AppSlice<Shared, u8>>,
    write_buffer: Option<AppSlice<Shared, u8>>,
    write_len: usize,
    pending_write: bool,
    read_idx: usize
}

impl Default for App {
    fn default() -> App {
        App {
            read_callback: None,
            write_callback: None,
            read_buffer: None,
            write_buffer: None,
            write_len: 0,
            pending_write: false,
            read_idx: 0
        }
    }
}

pub static mut WRITE_BUF : [u8; 64] = [0; 64];

pub struct Console<'a, U: UART + 'a> {
    uart: &'a U,
    apps: Container<App>,
    in_progress: TakeCell<AppId>,
    buffer: TakeCell<&'static mut [u8]>
}

impl<'a, U: UART> Console<'a, U> {
    pub const fn new(uart: &'a U, buffer: &'static mut [u8],
                     container: Container<App>) -> Console<'a, U> {
        Console {
            uart: uart,
            apps: container,
            in_progress: TakeCell::empty(),
            buffer: TakeCell::new(buffer)
        }
    }

    pub fn initialize(&self) {
        self.uart.enable_tx();
        self.uart.enable_rx();
    }
}

impl<'a, U: UART> Driver for Console<'a, U> {
    fn allow(&self, appid: AppId,
             allow_num: usize, slice: AppSlice<Shared, u8>) -> isize {
        match allow_num {
            0 => {
                self.apps.enter(appid, |app, _| {
                    app.read_buffer = Some(slice);
                    app.read_idx = 0;
                    0
                }).unwrap_or(-1)
            },
            1 => {
                self.apps.enter(appid, |app, _| {
                    app.write_buffer = Some(slice);
                    0
                }).unwrap_or(-1)
            }
            _ => -1
        }
    }

    fn subscribe(&self, subscribe_num: usize, callback: Callback) -> isize {
        match subscribe_num {
            0 /* read line */ => {
                self.apps.enter(callback.app_id(), |app, _| {
                    app.read_callback = Some(callback);
                    0
                }).unwrap_or(-1)
            },
            1 /* putstr/write_done */ => {
                self.apps.enter(callback.app_id(), |app, _| {
                    match app.write_buffer.take() {
                        Some(slice) => {
                            app.write_callback = Some(callback);
                            app.write_len = slice.len();
                            if self.in_progress.is_none() {
                                self.in_progress.replace(callback.app_id());
                                self.buffer.take().map(|buffer| {
                                    for (i, c) in slice.as_ref().iter().enumerate() {
                                        if buffer.len() <= i {
                                            break;
                                        }
                                        buffer[i] = *c;
                                    }
                                    self.uart.send_bytes(buffer, app.write_len);
                                });
                            } else {
                                app.pending_write = true;
                                app.write_buffer = Some(slice);
                            }
                            0
                        },
                        None => -1
                    }
                }).unwrap_or(-1)
            },
            _ => -1
        }
    }

    fn command(&self, cmd_num: usize, arg1: usize, _: AppId) -> isize {
        match cmd_num {
            0 /* putc */ => { self.uart.send_byte(arg1 as u8); 1 },
            _ => -1
        }
    }
}

impl<'a, U: UART> Client for Console<'a, U> {
    fn write_done(&self, buffer: &'static mut [u8]) {
        // Write TX is done, notify appropriate app and start another
        // transaction if pending
        self.buffer.replace(buffer);
        self.in_progress.take().map(|appid| {
            self.apps.enter(appid, |app, _| {
                app.write_callback.map(|mut cb| {
                    cb.schedule(app.write_len, 0, 0);
                });
                app.write_len = 0;
            })
        });

        for cntr in self.apps.iter() {
            let started_tx = cntr.enter(|app, _| {
                if app.pending_write {
                    app.write_buffer.take().map(|slice| {
                        app.pending_write = false;
                        self.buffer.take().map(|buffer| {
                            for (i, c) in slice.as_ref().iter().enumerate() {
                                if buffer.len() <= i {
                                    break;
                                }
                                buffer[i] = *c;
                            }
                            self.uart.send_bytes(buffer, app.write_len);
                        });
                        self.in_progress.replace(app.appid());
                        true
                    }).unwrap_or(false)
                } else {
                    false
                }
            });
            if started_tx {
                break;
            }
        }
    }

    fn read_done(&self, c: u8) {
        match c as char {
            '\r' => {},
            '\n' => {
                self.apps.each(|app| {
                    let idx = app.read_idx;
                    app.read_buffer = app.read_buffer.take().map(|mut rb| {
                        use core::raw::Repr;
                        app.read_callback.as_mut().map(|cb| {
                            let buf = rb.as_mut();
                            cb.schedule(idx, (buf.repr().data as usize), 0);
                        });
                        rb
                    });
                    app.read_idx = 0;
                });
            },
            _ => {
                self.apps.each(|app| {
                    let idx = app.read_idx;
                    if app.read_buffer.is_some() &&
                        app.read_idx < app.read_buffer.as_ref().unwrap().len() {

                        app.read_buffer.as_mut().map(|buf| {
                            buf.as_mut()[idx] = c;
                        });
                        app.read_idx += 1;
                    }
                });
            }
        }
    }
}

<|endoftext|>


<commit_before>use std::collections::VecDeque;

use bytes::Bytes;

use futures::stream;
use futures::stream::Stream;
use futures::Async;
use futures::Poll;

use error::*;
use httpbis::DataOrTrailers;
use httpbis::HttpStreamAfterHeaders;
use result;

fn read_u32_be(bytes: &[u8]) -> u32 {
    0 | ((bytes[0] as u32) << 24)
        | ((bytes[1] as u32) << 16)
        | ((bytes[2] as u32) << 8)
        | ((bytes[3] as u32) << 0)
}

fn write_u32_be(v: u32) -> [u8; 4] {
    [
        (v >> 24) as u8,
        (v >> 16) as u8,
        (v >> 8) as u8,
        (v >> 0) as u8,
    ]
}

pub const GRPC_HEADER_LEN: usize = 5;

/// Return frame len
pub fn parse_grpc_frame_0(stream: &[u8]) -> result::Result<Option<usize>> {
    if stream.len() < GRPC_HEADER_LEN {
        return Ok(None);
    }
    let compressed = match stream[0] {
        0 => false,
        1 => true,
        _ => return Err(Error::Other("unknown compression flag")),
    };
    if compressed {
        return Err(Error::Other("compression is not implemented"));
    }
    let len = read_u32_be(&stream[1..]) as usize;
    let end = len + GRPC_HEADER_LEN;
    if end > stream.len() {
        return Ok(None);
    }

    Ok(Some(len))
}

// return message and size consumed
pub fn parse_grpc_frame(stream: &[u8]) -> result::Result<Option<(&[u8], usize)>> {
    parse_grpc_frame_0(stream).map(|o| {
        o.map(|len| {
            (
                &stream[GRPC_HEADER_LEN..len + GRPC_HEADER_LEN],
                len + GRPC_HEADER_LEN,
            )
        })
    })
}

pub fn parse_grpc_frame_from_bytes(stream: &mut Bytes) -> result::Result<Option<Bytes>> {
    if let Some(len) = parse_grpc_frame_0(&stream)? {
        let r = stream.slice(GRPC_HEADER_LEN, len + GRPC_HEADER_LEN);
        stream.split_to(len + GRPC_HEADER_LEN);
        Ok(Some(r))
    } else {
        Ok(None)
    }
}

pub fn parse_grpc_frames_from_bytes(stream: &mut Bytes) -> result::Result<Vec<Bytes>> {
    let mut r = Vec::new();
    loop {
        match parse_grpc_frame_from_bytes(stream)? {
            Some(bytes) => {
                r.push(bytes);
            }
            None => {
                return Ok(r);
            }
        }
    }
}

pub fn parse_grpc_frames_completely(stream: &[u8]) -> result::Result<Vec<&[u8]>> {
    let mut r = Vec::new();
    let mut pos = 0;
    while pos < stream.len() {
        let frame_opt = parse_grpc_frame(&stream[pos..])?;
        match frame_opt {
            None => return Err(Error::Other("not complete frames")),
            Some((frame, len)) => {
                r.push(frame);
                pos += len;
            }
        }
    }
    Ok(r)
}

#[allow(dead_code)]
pub fn parse_grpc_frame_completely(stream: &[u8]) -> result::Result<&[u8]> {
    let frames = parse_grpc_frames_completely(stream)?;
    if frames.len() == 1 {
        Ok(frames[0])
    } else {
        Err(Error::Other("expecting exactly one frame"))
    }
}

pub fn write_grpc_frame(stream: &mut Vec<u8>, frame: &[u8]) {
    stream.push(0); // compressed flag
    stream.extend(&write_u32_be(frame.len() as u32));
    stream.extend(frame);
}

pub fn write_grpc_frame_to_vec(frame: &[u8]) -> Vec<u8> {
    let mut r = Vec::new();
    write_grpc_frame(&mut r, frame);
    r
}

trait RequestOrResponse {
    fn need_trailing_header() -> bool;
}

pub struct GrpcFrameFromHttpFramesStreamRequest {
    http_stream_stream: HttpStreamAfterHeaders,
    buf: Bytes,
    parsed_frames: VecDeque<Bytes>,
    error: Option<stream::Once<Bytes, Error>>,
}

impl GrpcFrameFromHttpFramesStreamRequest {
    pub fn new(http_stream_stream: HttpStreamAfterHeaders) -> Self {
        GrpcFrameFromHttpFramesStreamRequest {
            http_stream_stream,
            buf: Bytes::new(),
            parsed_frames: VecDeque::new(),
            error: None,
        }
    }
}

impl Stream for GrpcFrameFromHttpFramesStreamRequest {
    type Item = Bytes;
    type Error = Error;

    fn poll(&mut self) -> Poll<Option<Bytes>, Error> {
        loop {
            if let Some(ref mut error) = self.error {
                return error.poll();
            }

            self.parsed_frames
                .extend(match parse_grpc_frames_from_bytes(&mut self.buf) {
                    Ok(r) => r,
                    Err(e) => {
                        self.error = Some(stream::once(Err(e)));
                        continue;
                    }
                });

            if let Some(frame) = self.parsed_frames.pop_front() {
                return Ok(Async::Ready(Some(frame)));
            }

            let part_opt = match self.http_stream_stream.poll()? {
                Async::NotReady => return Ok(Async::NotReady),
                Async::Ready(part_opt) => part_opt,
            };
            let part = match part_opt {
                None => {
                    if self.buf.is_empty() {
                        return Ok(Async::Ready(None));
                    } else {
                        self.error = Some(stream::once(Err(Error::Other("partial frame"))));
                        continue;
                    }
                }
                Some(part) => part,
            };

            match part {
                // unexpected but OK
                DataOrTrailers::Trailers(..) => (),
                DataOrTrailers::Data(data, ..) => {
                    self.buf.extend_from_slice(&data);
                }
            }
        }
    }
}

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

    #[test]
    fn test_parse_grpc_frame() {
        assert_eq!(None, parse_grpc_frame(b"").unwrap());
        assert_eq!(None, parse_grpc_frame(b"1").unwrap());
        assert_eq!(None, parse_grpc_frame(b"14sc").unwrap());
        assert_eq!(
            None,
            parse_grpc_frame(b"\x00\x00\x00\x00\x07\x0a\x05wo").unwrap()
        );
        assert_eq!(
            Some((&b"\x0a\x05world"[..], 12)),
            parse_grpc_frame(b"\x00\x00\x00\x00\x07\x0a\x05world").unwrap()
        );
    }

    #[test]
    fn test_parse_grpc_frames_from_bytes() {
        fn t(r: &[&[u8]], input: &[u8], trail: &[u8]) {
            let mut b = Bytes::new();
            b.extend_from_slice(input);
            b.extend_from_slice(trail);

            let r: Vec<Bytes> = r.into_iter().map(|&s| Bytes::from(s)).collect();

            let rr = parse_grpc_frames_from_bytes(&mut b).unwrap();
            assert_eq!(r, rr);
            assert_eq!(trail, b.as_ref());
        }

        t(&[], &[], &[]);
        t(&[], &[], &b"1"[..]);
        t(&[], &[], &b"14sc"[..]);
        t(
            &[&b"\x0a\x05world"[..]],
            &b"\x00\x00\x00\x00\x07\x0a\x05world"[..],
            &[],
        );
        t(
            &[&b"ab"[..], &b"cde"[..]],
            &b"\0\x00\x00\x00\x02ab\0\x00\x00\x00\x03cde"[..],
            &b"\x00"[..],
        );
    }
}
<commit_msg>write_grpc_frame: assertion, allocation<commit_after>use std::collections::VecDeque;

use bytes::Bytes;

use futures::stream;
use futures::stream::Stream;
use futures::Async;
use futures::Poll;

use error::*;
use httpbis::DataOrTrailers;
use httpbis::HttpStreamAfterHeaders;
use result;

fn read_u32_be(bytes: &[u8]) -> u32 {
    0 | ((bytes[0] as u32) << 24)
        | ((bytes[1] as u32) << 16)
        | ((bytes[2] as u32) << 8)
        | ((bytes[3] as u32) << 0)
}

fn write_u32_be(v: u32) -> [u8; 4] {
    [
        (v >> 24) as u8,
        (v >> 16) as u8,
        (v >> 8) as u8,
        (v >> 0) as u8,
    ]
}

pub const GRPC_HEADER_LEN: usize = 5;

/// Return frame len
pub fn parse_grpc_frame_0(stream: &[u8]) -> result::Result<Option<usize>> {
    if stream.len() < GRPC_HEADER_LEN {
        return Ok(None);
    }
    let compressed = match stream[0] {
        0 => false,
        1 => true,
        _ => return Err(Error::Other("unknown compression flag")),
    };
    if compressed {
        return Err(Error::Other("compression is not implemented"));
    }
    let len = read_u32_be(&stream[1..]) as usize;
    let end = len + GRPC_HEADER_LEN;
    if end > stream.len() {
        return Ok(None);
    }

    Ok(Some(len))
}

// return message and size consumed
pub fn parse_grpc_frame(stream: &[u8]) -> result::Result<Option<(&[u8], usize)>> {
    parse_grpc_frame_0(stream).map(|o| {
        o.map(|len| {
            (
                &stream[GRPC_HEADER_LEN..len + GRPC_HEADER_LEN],
                len + GRPC_HEADER_LEN,
            )
        })
    })
}

pub fn parse_grpc_frame_from_bytes(stream: &mut Bytes) -> result::Result<Option<Bytes>> {
    if let Some(len) = parse_grpc_frame_0(&stream)? {
        let r = stream.slice(GRPC_HEADER_LEN, len + GRPC_HEADER_LEN);
        stream.split_to(len + GRPC_HEADER_LEN);
        Ok(Some(r))
    } else {
        Ok(None)
    }
}

pub fn parse_grpc_frames_from_bytes(stream: &mut Bytes) -> result::Result<Vec<Bytes>> {
    let mut r = Vec::new();
    loop {
        match parse_grpc_frame_from_bytes(stream)? {
            Some(bytes) => {
                r.push(bytes);
            }
            None => {
                return Ok(r);
            }
        }
    }
}

pub fn parse_grpc_frames_completely(stream: &[u8]) -> result::Result<Vec<&[u8]>> {
    let mut r = Vec::new();
    let mut pos = 0;
    while pos < stream.len() {
        let frame_opt = parse_grpc_frame(&stream[pos..])?;
        match frame_opt {
            None => return Err(Error::Other("not complete frames")),
            Some((frame, len)) => {
                r.push(frame);
                pos += len;
            }
        }
    }
    Ok(r)
}

#[allow(dead_code)]
pub fn parse_grpc_frame_completely(stream: &[u8]) -> result::Result<&[u8]> {
    let frames = parse_grpc_frames_completely(stream)?;
    if frames.len() == 1 {
        Ok(frames[0])
    } else {
        Err(Error::Other("expecting exactly one frame"))
    }
}

/// Encode data into grpc frame (add frame prefix)
pub fn write_grpc_frame(stream: &mut Vec<u8>, frame: &[u8]) {
    assert!(frame.len() <= u32::max_value() as usize);
    stream.reserve(5 + frame.len());
    stream.push(0); // compressed flag
    stream.extend(&write_u32_be(frame.len() as u32));
    stream.extend(frame);
}

pub fn write_grpc_frame_to_vec(frame: &[u8]) -> Vec<u8> {
    let mut r = Vec::new();
    write_grpc_frame(&mut r, frame);
    r
}

trait RequestOrResponse {
    fn need_trailing_header() -> bool;
}

pub struct GrpcFrameFromHttpFramesStreamRequest {
    http_stream_stream: HttpStreamAfterHeaders,
    buf: Bytes,
    parsed_frames: VecDeque<Bytes>,
    error: Option<stream::Once<Bytes, Error>>,
}

impl GrpcFrameFromHttpFramesStreamRequest {
    pub fn new(http_stream_stream: HttpStreamAfterHeaders) -> Self {
        GrpcFrameFromHttpFramesStreamRequest {
            http_stream_stream,
            buf: Bytes::new(),
            parsed_frames: VecDeque::new(),
            error: None,
        }
    }
}

impl Stream for GrpcFrameFromHttpFramesStreamRequest {
    type Item = Bytes;
    type Error = Error;

    fn poll(&mut self) -> Poll<Option<Bytes>, Error> {
        loop {
            if let Some(ref mut error) = self.error {
                return error.poll();
            }

            self.parsed_frames
                .extend(match parse_grpc_frames_from_bytes(&mut self.buf) {
                    Ok(r) => r,
                    Err(e) => {
                        self.error = Some(stream::once(Err(e)));
                        continue;
                    }
                });

            if let Some(frame) = self.parsed_frames.pop_front() {
                return Ok(Async::Ready(Some(frame)));
            }

            let part_opt = match self.http_stream_stream.poll()? {
                Async::NotReady => return Ok(Async::NotReady),
                Async::Ready(part_opt) => part_opt,
            };
            let part = match part_opt {
                None => {
                    if self.buf.is_empty() {
                        return Ok(Async::Ready(None));
                    } else {
                        self.error = Some(stream::once(Err(Error::Other("partial frame"))));
                        continue;
                    }
                }
                Some(part) => part,
            };

            match part {
                // unexpected but OK
                DataOrTrailers::Trailers(..) => (),
                DataOrTrailers::Data(data, ..) => {
                    self.buf.extend_from_slice(&data);
                }
            }
        }
    }
}

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

    #[test]
    fn test_parse_grpc_frame() {
        assert_eq!(None, parse_grpc_frame(b"").unwrap());
        assert_eq!(None, parse_grpc_frame(b"1").unwrap());
        assert_eq!(None, parse_grpc_frame(b"14sc").unwrap());
        assert_eq!(
            None,
            parse_grpc_frame(b"\x00\x00\x00\x00\x07\x0a\x05wo").unwrap()
        );
        assert_eq!(
            Some((&b"\x0a\x05world"[..], 12)),
            parse_grpc_frame(b"\x00\x00\x00\x00\x07\x0a\x05world").unwrap()
        );
    }

    #[test]
    fn test_parse_grpc_frames_from_bytes() {
        fn t(r: &[&[u8]], input: &[u8], trail: &[u8]) {
            let mut b = Bytes::new();
            b.extend_from_slice(input);
            b.extend_from_slice(trail);

            let r: Vec<Bytes> = r.into_iter().map(|&s| Bytes::from(s)).collect();

            let rr = parse_grpc_frames_from_bytes(&mut b).unwrap();
            assert_eq!(r, rr);
            assert_eq!(trail, b.as_ref());
        }

        t(&[], &[], &[]);
        t(&[], &[], &b"1"[..]);
        t(&[], &[], &b"14sc"[..]);
        t(
            &[&b"\x0a\x05world"[..]],
            &b"\x00\x00\x00\x00\x07\x0a\x05world"[..],
            &[],
        );
        t(
            &[&b"ab"[..], &b"cde"[..]],
            &b"\0\x00\x00\x00\x02ab\0\x00\x00\x00\x03cde"[..],
            &b"\x00"[..],
        );
    }
}
<|endoftext|>


<commit_before>macro_rules! skip_bytes (
  ($input: expr, $length: expr, $offset: expr) => (
    {
      match take!($input, $length) {
        $crate::nom::IResult::Done(i, bytes)   => {
          let head        = bytes[0] << $offset;
          let tail        = &bytes[1..];
          let is_all_zero = tail.iter().all(|byte| *byte == 0);

          if head == 0 && is_all_zero {
            $crate::nom::IResult::Done(i, bytes)
          } else {
            $crate::nom::IResult::Error($crate::nom::Err::Position(
              $crate::nom::ErrorCode::Digit as u32, $input))
          }
        }
        $crate::nom::IResult::Error(error)     =>
          $crate::nom::IResult::Error(error),
        $crate::nom::IResult::Incomplete(need) =>
          $crate::nom::IResult::Incomplete(need),
      }
    }
  );
);

macro_rules! count_slice (
  ($input: expr, $submac: ident!( $($args:tt)* ), $result: expr) => (
    {
      let mut input    = $input;
      let mut count    = 0;
      let mut is_error = false;

      for result in $result {
        match $submac!(input, $($args)*) {
          $crate::nom::IResult::Done(i, o)    => {
            *result = o;

            input   = i;
            count  += 1;
          }
          $crate::nom::IResult::Error(_)      => {
            is_error = true;
            break;
          }
          $crate::nom::IResult::Incomplete(_) => break,
        }
      }

      if is_error {
        $crate::nom::IResult::Error($crate::nom::Err::Position(
          $crate::nom::ErrorCode::Count as u32, $input.0))
      } else if count == $result.len() {
        $crate::nom::IResult::Done(input, ())
      } else {
        $crate::nom::IResult::Incomplete($crate::nom::Needed::Unknown)
      }
    }
  );
  ($i: expr, $f: expr, $count: expr) => (
    count_slice!($i, call!($f), $count);
  );
);

macro_rules! count_bits (
  ($input: expr, $submac: ident!( $($args:tt)* ), $count: expr) => (
    {
      let mut input    = $input;
      let mut count    = 0;
      let mut is_error = false;
      let mut result   = Vec::with_capacity($count);

      loop {
        if count == $count {
          break;
        }

        match $submac!(input, $($args)*) {
          $crate::nom::IResult::Done(i, o)    => {
            result.push(o);

            input  = i;
            count += 1;
          }
          $crate::nom::IResult::Error(_)      => {
            is_error = true;
            break;
          }
          $crate::nom::IResult::Incomplete(_) => break,
        }
      }

      if is_error {
        $crate::nom::IResult::Error($crate::nom::Err::Position(
          $crate::nom::ErrorCode::Count as u32, $input.0))
      } else if count == $count {
        $crate::nom::IResult::Done(input, result)
      } else {
        $crate::nom::IResult::Incomplete($crate::nom::Needed::Unknown)
      }
    }
  );
  ($i: expr, $f: expr, $count: expr) => (
    count_bits!($i, call!($f), $count);
  );
);

macro_rules! take_signed_bits (
  ($input: expr, $signed_type: ty, $count: expr) => (
    map!($input, take_bits!(u32, $count), |value| {
      if $count >= 32 || value < (1 << ($count - 1)) {
        value as $signed_type
      } else {
        (value as $signed_type).wrapping_sub(1 << $count)
      }
    });
  );
);
<commit_msg>Add secondary macro call that defaults to i32<commit_after>macro_rules! skip_bytes (
  ($input: expr, $length: expr, $offset: expr) => (
    {
      match take!($input, $length) {
        $crate::nom::IResult::Done(i, bytes)   => {
          let head        = bytes[0] << $offset;
          let tail        = &bytes[1..];
          let is_all_zero = tail.iter().all(|byte| *byte == 0);

          if head == 0 && is_all_zero {
            $crate::nom::IResult::Done(i, bytes)
          } else {
            $crate::nom::IResult::Error($crate::nom::Err::Position(
              $crate::nom::ErrorCode::Digit as u32, $input))
          }
        }
        $crate::nom::IResult::Error(error)     =>
          $crate::nom::IResult::Error(error),
        $crate::nom::IResult::Incomplete(need) =>
          $crate::nom::IResult::Incomplete(need),
      }
    }
  );
);

macro_rules! count_slice (
  ($input: expr, $submac: ident!( $($args:tt)* ), $result: expr) => (
    {
      let mut input    = $input;
      let mut count    = 0;
      let mut is_error = false;

      for result in $result {
        match $submac!(input, $($args)*) {
          $crate::nom::IResult::Done(i, o)    => {
            *result = o;

            input   = i;
            count  += 1;
          }
          $crate::nom::IResult::Error(_)      => {
            is_error = true;
            break;
          }
          $crate::nom::IResult::Incomplete(_) => break,
        }
      }

      if is_error {
        $crate::nom::IResult::Error($crate::nom::Err::Position(
          $crate::nom::ErrorCode::Count as u32, $input.0))
      } else if count == $result.len() {
        $crate::nom::IResult::Done(input, ())
      } else {
        $crate::nom::IResult::Incomplete($crate::nom::Needed::Unknown)
      }
    }
  );
  ($i: expr, $f: expr, $count: expr) => (
    count_slice!($i, call!($f), $count);
  );
);

macro_rules! count_bits (
  ($input: expr, $submac: ident!( $($args:tt)* ), $count: expr) => (
    {
      let mut input    = $input;
      let mut count    = 0;
      let mut is_error = false;
      let mut result   = Vec::with_capacity($count);

      loop {
        if count == $count {
          break;
        }

        match $submac!(input, $($args)*) {
          $crate::nom::IResult::Done(i, o)    => {
            result.push(o);

            input  = i;
            count += 1;
          }
          $crate::nom::IResult::Error(_)      => {
            is_error = true;
            break;
          }
          $crate::nom::IResult::Incomplete(_) => break,
        }
      }

      if is_error {
        $crate::nom::IResult::Error($crate::nom::Err::Position(
          $crate::nom::ErrorCode::Count as u32, $input.0))
      } else if count == $count {
        $crate::nom::IResult::Done(input, result)
      } else {
        $crate::nom::IResult::Incomplete($crate::nom::Needed::Unknown)
      }
    }
  );
  ($i: expr, $f: expr, $count: expr) => (
    count_bits!($i, call!($f), $count);
  );
);

macro_rules! take_signed_bits (
  ($input: expr, $signed_type: ty, $count: expr) => (
    map!($input, take_bits!(u32, $count), |value| {
      if $count >= 32 || value < (1 << ($count - 1)) {
        value as $signed_type
      } else {
        (value as $signed_type).wrapping_sub(1 << $count)
      }
    });
  );
  ($input: expr, $count: expr) => (
    take_signed_bits!($input, i32, $count);
  );
);
<|endoftext|>