<commit_before>pub mod resource;
use resource::*;
use std::collections::HashMap;

pub struct Village {
    pub worker_count : u32,
    resources : Vec<Resource>,
    pub stockpile : HashMap<ResourceType, u32>,
    number_of_resource_sites : u32,
}

impl Village {
    pub fn new(worker_count: u32) -> Village {
        let mut village = Village {
            worker_count: worker_count,
            resources: vec!(),
            stockpile: HashMap::new(),
            number_of_resource_sites: 0,
        };

        //add each resource type to the stockpile
        for resource_type in ResourceType::iterator() {
            village.stockpile.insert(*resource_type, 0);
        }
        village
    }

    pub fn create_resource(&mut self, resource_type: ResourceType) {
        self.resources.push(Resource {
            resource_type: resource_type,
            worker_count: 0,
            resource_id: self.number_of_resource_sites,
        });
        self.number_of_resource_sites += 1;
    }

    pub fn assign_workers(&mut self, resource_id: u32, number_of_workers: u32) {
        if self.idle_worker_count() >= number_of_workers && resource_id < self.number_of_resource_sites {
            self.resources[resource_id as usize].worker_count += number_of_workers;
        }
    }

    // //TODO: Needs to be modified. An empty collection if none
    // pub fn resource(&self, resource_type: ResourceType) -> Option<&Resource> {
    //     self.resources.iter().find(|r| r.resource_type == resource_type)
    // }

    pub fn all_resources(&self) -> &Vec<Resource> {
        &self.resources
    }

    pub fn idle_worker_count(&self) -> u32 {
        let assigned_count : u32 = self.resources.iter()
            .map(|r| r.worker_count)
            .sum();

        self.worker_count - assigned_count
    }

    pub fn collect_resources(&mut self) {
        for resource in self.resources.iter_mut() {
            //update the resource count
            *self.stockpile.get_mut(&resource.resource_type).unwrap() += resource.collect();
        }
    }
}

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

    #[test]
    fn add_resources() {
        let mut v = Village::new(1);
        v.create_resource(ResourceType::Gold);
        v.create_resource(ResourceType::Gold);
        v.create_resource(ResourceType::Wood);

        assert_eq!(3, v.all_resources().len());
    }

    #[test]
    fn assign_workers_to_resource() {
        let mut v = Village::new(4);
        v.create_resource(ResourceType::Gold);
        v.create_resource(ResourceType::Gold);
        v.create_resource(ResourceType::Wood);
        let mut resource_assignments: Vec<(u32, u32)> = Vec::new();
        {
            //get the list of resources and extract the ids of the resources you want to assign workers to
            let x = v.all_resources();
            resource_assignments.push((x[0].resource_id, 2));
            resource_assignments.push((x[1].resource_id, 1));
        }
        v.assign_workers(resource_assignments[0].0, resource_assignments[0].1);
        v.assign_workers(resource_assignments[1].0, resource_assignments[1].1);

        let x = v.all_resources();
        assert_eq!(2, x[0].worker_count);
        assert_eq!(1, x[1].worker_count);
        assert_eq!(0, x[2].worker_count);
    }

    #[test]
    fn assign_workers_to_resource_up_to_limit() {
        let mut v = Village::new(2);
        v.create_resource(ResourceType::Stone);
        v.assign_workers(0, 1);
        v.assign_workers(0, 1);
        v.assign_workers(0, 1);

        assert_eq!(2, v.all_resources()[0].worker_count);
    }

    #[test]
    fn idle_worker_count() {
        let v = Village::new(70);

        assert_eq!(70, v.idle_worker_count());
    }

    #[test]
    fn idle_worker_count_after_assigning() {
        let mut v = Village::new(5);
        v.create_resource(ResourceType::Gold);
        v.assign_workers(0, 2);

        assert_eq!(3, v.idle_worker_count());
    }

    #[test]
    fn stockpile() {
        let v = Village::new(5);
        let value = v.stockpile.get(&ResourceType::Food);
        assert_eq!(0, *value.unwrap());
    }

    #[test]
    fn stockpile_collection() {
        let mut v = Village::new(5);
        v.create_resource(ResourceType::Wood);
        v.assign_workers(0, 5);
        v.collect_resources();

        assert_eq!(5, *v.stockpile.get(&ResourceType::Wood).unwrap());
    }
}<commit_msg>Created remove_workers and added the ability to get a vector of resources by ResourceType<commit_after>pub mod resource;
use resource::*;
use std::collections::HashMap;

pub struct Village {
    pub worker_count : u32,
    resources : Vec<Resource>,
    pub stockpile : HashMap<ResourceType, u32>,
    number_of_resource_sites : u32,
}

impl Village {
    pub fn new(worker_count: u32) -> Village {
        let mut village = Village {
            worker_count: worker_count,
            resources: vec!(),
            stockpile: HashMap::new(),
            number_of_resource_sites: 0,
        };

        //add each resource type to the stockpile
        for resource_type in ResourceType::iterator() {
            village.stockpile.insert(*resource_type, 0);
        }
        village
    }

    pub fn create_resource(&mut self, resource_type: ResourceType) {
        self.resources.push(Resource {
            resource_type: resource_type,
            worker_count: 0,
            resource_id: self.number_of_resource_sites,
        });
        self.number_of_resource_sites += 1;
    }

    pub fn assign_workers(&mut self, resource_id: u32, number_of_workers: u32) {
        if self.idle_worker_count() >= number_of_workers && resource_id < self.number_of_resource_sites {
            self.resources[resource_id as usize].worker_count += number_of_workers;
        }
    }

    pub fn remove_workers(&mut self, resource_id: u32, number_of_workers: u32) {
        if resource_id < self.number_of_resource_sites && self.resources[resource_id as usize].worker_count >= number_of_workers {
            self.resources[resource_id as usize].worker_count -= number_of_workers;
        }
    }

    pub fn resources(&self, resource_type: ResourceType) -> Vec<&Resource> {
        self.resources.iter().filter(|r| r.resource_type == resource_type).collect::<Vec<_>>()
    }

    pub fn all_resources(&self) -> &Vec<Resource> {
        &self.resources
    }

    pub fn idle_worker_count(&self) -> u32 {
        let assigned_count : u32 = self.resources.iter()
            .map(|r| r.worker_count)
            .sum();

        self.worker_count - assigned_count
    }

    pub fn collect_resources(&mut self) {
        for resource in self.resources.iter_mut() {
            //update the resource count
            *self.stockpile.get_mut(&resource.resource_type).unwrap() += resource.collect();
        }
    }
}

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

    #[test]
    fn add_resources() {
        let mut v = Village::new(1);
        v.create_resource(ResourceType::Gold);
        v.create_resource(ResourceType::Gold);
        v.create_resource(ResourceType::Wood);

        assert_eq!(3, v.all_resources().len());
    }

    #[test]
    fn assign_workers_to_resource() {
        let mut v = Village::new(4);
        v.create_resource(ResourceType::Gold);
        v.create_resource(ResourceType::Gold);
        v.create_resource(ResourceType::Wood);
        let mut resource_assignments: Vec<(u32, u32)> = Vec::new();
        {
            //get the list of resources and extract the ids of the resources you want to assign workers to
            let x = v.all_resources();
            resource_assignments.push((x[0].resource_id, 2));
            resource_assignments.push((x[1].resource_id, 1));
        }
        v.assign_workers(resource_assignments[0].0, resource_assignments[0].1);
        v.assign_workers(resource_assignments[1].0, resource_assignments[1].1);

        let x = v.all_resources();
        assert_eq!(2, x[0].worker_count);
        assert_eq!(1, x[1].worker_count);
        assert_eq!(0, x[2].worker_count);
    }

    #[test]
    fn remove_workers_from_resource()
    {
        let mut v = Village::new(4);
        v.create_resource(ResourceType::Gold);
        v.create_resource(ResourceType::Wood);
        v.assign_workers(0, 3);
        v.assign_workers(1, 1);
        v.remove_workers(0, 2);
        v.remove_workers(1, 1);

        let x = v.all_resources();
        assert_eq!(1, x[0].worker_count);
        assert_eq!(0, x[1].worker_count);
    }

    #[test]
    fn assign_workers_to_resource_up_to_limit() {
        let mut v = Village::new(2);
        v.create_resource(ResourceType::Stone);
        v.assign_workers(0, 1);
        v.assign_workers(0, 1);
        v.assign_workers(0, 1);

        assert_eq!(2, v.all_resources()[0].worker_count);
    }

    #[test]
    fn idle_worker_count() {
        let v = Village::new(70);

        assert_eq!(70, v.idle_worker_count());
    }

    #[test]
    fn idle_worker_count_after_assigning() {
        let mut v = Village::new(5);
        v.create_resource(ResourceType::Gold);
        v.assign_workers(0, 2);

        assert_eq!(3, v.idle_worker_count());
    }

    #[test]
    fn stockpile() {
        let v = Village::new(5);
        let value = v.stockpile.get(&ResourceType::Food);
        assert_eq!(0, *value.unwrap());
    }

    #[test]
    fn stockpile_collection() {
        let mut v = Village::new(5);
        v.create_resource(ResourceType::Wood);
        v.assign_workers(0, 5);
        v.collect_resources();

        assert_eq!(5, *v.stockpile.get(&ResourceType::Wood).unwrap());
    }

    #[test]
    fn get_resources_by_type()
    {
        let mut v = Village::new(5);
        v.create_resource(ResourceType::Gold);
        v.create_resource(ResourceType::Gold);
        v.create_resource(ResourceType::Wood);
        v.create_resource(ResourceType::Wood);
        v.create_resource(ResourceType::Wood);
        v.create_resource(ResourceType::Stone);

        assert_eq!(2, v.resources(ResourceType::Gold).len());
        assert_eq!(3, v.resources(ResourceType::Wood).len());
        assert_eq!(1, v.resources(ResourceType::Stone).len());
        assert_eq!(0, v.resources(ResourceType::Food).len());
    }
}<|endoftext|>


<commit_before>// DOCS

#![allow(unstable)]
#![feature(plugin)]
#[plugin] extern crate peg_syntax_ext;

use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};

pub struct Property {
    /// Parameters.
    pub params: HashMap<String, String>,

    /// Value as unparsed string.
    pub raw_value: String,

    /// Property group. E.g. a contentline like `foo.FN:Markus` would result in the group being
    /// `"foo"`.
    pub prop_group: Option<String>
}

impl Property {
    pub fn new(params: HashMap<String, String>, raw_value: String, prop_group: Option<String>) -> Property {
        Property {
            params: params,
            raw_value: raw_value,
            prop_group: prop_group
        }
    }

    /// Create property from unescaped string.
    pub fn new_from_string(s: &str) -> Property {
        Property::new(HashMap::new(), escape_chars(s), None)
    }

    /// Get value as unescaped string.
    pub fn value_as_string(&self) -> String {
        unescape_chars(self.raw_value.as_slice())
    }
}

pub struct Component {
    /// The name of the component, such as `VCARD` or `VEVENT`.
    pub name: String,

    /// The component's properties.
    pub props: HashMap<String, Vec<Property>>,

    /// The component's child- or sub-components.
    pub subcomponents: Vec<Component>
}

impl Component {
    pub fn new(name: String) -> Component {
        Component {
            name: name,
            props: HashMap::new(),
            subcomponents: vec![]
        }
    }

    /// Retrieve one property (from many) by key. Returns `None` if nothing is found.
    pub fn single_prop(&self, key: &str) -> Option<&Property> {
        match self.props.get(key) {
            Some(x) => {
                match x.len() {
                    1 => Some(&x[0]),
                    _ => None
                }
            },
            None => None
        }
    }

    /// Retrieve a mutable vector of properties for this key. Creates one (and inserts it into the
    /// component) if none exists.
    pub fn all_props_mut(&mut self, key: &str) -> &mut Vec<Property> {
        match self.props.entry(String::from_str(key)) {
            Occupied(values) => values.into_mut(),
            Vacant(values) => values.insert(vec![])
        }
    }

    /// Retrieve properties by key. Returns an empty slice if key doesn't exist.
    pub fn all_props(&self, key: &str) -> &[Property] {
        static EMPTY: &'static [Property] = &[];
        match self.props.get(key) {
            Some(values) => values.as_slice(),
            None => EMPTY
        }
    }
}

peg! parser(r#"
use super::{Component,Property};
use std::collections::HashMap;

#[pub]
component -> Component
    = name:component_begin
      ps:props
      cs:components?
      component_end {
        let mut rv = Component::new(name);

        match cs {
            Some(components) => { rv.subcomponents = components; },
            None => ()
        };

        for (k, v) in ps.into_iter() {
            rv.all_props_mut(k).push(v);
        };

        rv
    }

component_begin -> String
    = "BEGIN:" v:value __ { v.to_string() }

component_end -> String
    = "END:" v:value __ { v.to_string() }

components -> Vec<Component>
    = cs:component ++ eols __ { cs }

props -> Vec<(&'input str, Property)>
    = ps:prop ++ eols __ { ps }

prop -> (&'input str, Property)
    = !"BEGIN:" !"END:" g:group? k:name p:params ":" v:value {
        (k, Property::new(p, v, g))
    }

group -> String
    = g:group_name "." { g }

group_name -> String
    = group_char+ { match_str.to_string() }

name -> &'input str
    = iana_token+ { match_str }

params -> HashMap<String, String>
    = ps:(";" p:param {p})* {
        let mut rv: HashMap<String, String> = HashMap::new();
        for (k, v) in ps.into_iter() {
            rv.insert(k.to_string(), v.to_string());
        };
        rv
    }

param -> (&'input str, &'input str)
    // FIXME: Doesn't handle comma-separated values
    = k:param_name v:("=" v:param_value { v })? {
        (k, match v {
            Some(x) => x,
            None => ""
        })
    }

param_name -> &'input str
    = iana_token+ { match_str }

param_value -> &'input str
    = x:(quoted_string / param_text) { x }

param_text -> &'input str
    = safe_char* { match_str }

value -> String
    = value_char+ { match_str.to_string() }

quoted_string -> &'input str
    = dquote x:quoted_content dquote { x }

quoted_content -> &'input str
    = qsafe_char* { match_str }

iana_token = ([a-zA-Z0-9] / "-")+
group_char = ([a-zA-Z0-9] / "-")
qsafe_char = !dquote !ctl value_char
safe_char = !";" !":" qsafe_char

value_char = !eol .

eol = "\r\n" / "\n" / "\r"
dquote = "\""
eols = eol+

// Taken from vCard. vCalendar's is a subset. Together with the definition of "qsafe_char" this
// might reject a bunch of valid iCalendars, but I can't imagine one.
ctl = [\u{00}-\u{1F}] / "\u{7F}"

whitespace = " " / "\t"
__ = (eol / whitespace)*

"#);

/// Parse a component. The error value is a human-readable message.
pub fn parse_component(s: &str) -> Result<Component, String> {
    // XXX: The unfolding should be worked into the PEG
    // See feature request: https://github.com/kevinmehall/rust-peg/issues/26
    let unfolded = unfold_lines(s);
    parser::component(unfolded.as_slice())
}

/// Write a component. The error value is a human-readable message.
pub fn write_component(c: &Component) -> String {
    fn inner(buf: &mut String, c: &Component) {
        buf.push_str("BEGIN:");
        buf.push_str(c.name.as_slice());
        buf.push_str("\r\n");

        for (prop_name, props) in c.props.iter() {
            for prop in props.iter() {
                match prop.prop_group {
                    Some(ref x) => { buf.push_str(x.as_slice()); buf.push('.'); },
                    None => ()
                };
                buf.push_str(prop_name.as_slice());
                for (param_key, param_value) in prop.params.iter() {
                    buf.push(';');
                    buf.push_str(param_key.as_slice());
                    buf.push('=');
                    buf.push_str(param_value.as_slice());
                };
                buf.push(':');
                buf.push_str(fold_line(prop.raw_value.as_slice()).as_slice());
                buf.push_str("\r\n");
            };
        };

        for subcomponent in c.subcomponents.iter() {
            inner(buf, subcomponent);
        };

        buf.push_str("END:");
        buf.push_str(c.name.as_slice());
        buf.push_str("\r\n");
    }

    let mut buf = String::new();
    inner(&mut buf, c);
    buf
}

/// Escape text for a VObject property value.
pub fn escape_chars(s: &str) -> String {
    // Order matters! Lifted from icalendar.parser
    // https://github.com/collective/icalendar/
    s
        .replace("\\N", "\n")
        .replace("\\", "\\\\")
        .replace(";", "\\;")
        .replace(",", "\\,")
        .replace("\r\n", "\\n")
        .replace("\n", "\\n")
}

/// Unescape text from a VObject property value.
pub fn unescape_chars(s: &str) -> String {
    // Order matters! Lifted from icalendar.parser
    // https://github.com/collective/icalendar/
    s
        .replace("\\N", "\\n")
        .replace("\r\n", "\n")
        .replace("\\n", "\n")
        .replace("\\,", ",")
        .replace("\\;", ";")
        .replace("\\\\", "\\")
}

/// Unfold contentline.
pub fn unfold_lines(s: &str) -> String {
    s
        .replace("\r\n ", "").replace("\r\n\t", "")
        .replace("\n ", "").replace("\n\t", "")
        .replace("\r ", "").replace("\r\t", "")
}

/// Fold contentline to 75 chars. This function assumes the input to be unfolded, which means no
/// '\n' or '\r' in it.
pub fn fold_line(s: &str) -> String {
    let mut rv = String::new();
    for (i, c) in s.chars().enumerate() {
        rv.push(c);
        if i % 75 == 0 {
            rv.push_str("\r\n ");
        };
    };
    rv
}
<commit_msg>Don't fold at first char<commit_after>// DOCS

#![allow(unstable)]
#![feature(plugin)]
#[plugin] extern crate peg_syntax_ext;

use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};

pub struct Property {
    /// Parameters.
    pub params: HashMap<String, String>,

    /// Value as unparsed string.
    pub raw_value: String,

    /// Property group. E.g. a contentline like `foo.FN:Markus` would result in the group being
    /// `"foo"`.
    pub prop_group: Option<String>
}

impl Property {
    pub fn new(params: HashMap<String, String>, raw_value: String, prop_group: Option<String>) -> Property {
        Property {
            params: params,
            raw_value: raw_value,
            prop_group: prop_group
        }
    }

    /// Create property from unescaped string.
    pub fn new_from_string(s: &str) -> Property {
        Property::new(HashMap::new(), escape_chars(s), None)
    }

    /// Get value as unescaped string.
    pub fn value_as_string(&self) -> String {
        unescape_chars(self.raw_value.as_slice())
    }
}

pub struct Component {
    /// The name of the component, such as `VCARD` or `VEVENT`.
    pub name: String,

    /// The component's properties.
    pub props: HashMap<String, Vec<Property>>,

    /// The component's child- or sub-components.
    pub subcomponents: Vec<Component>
}

impl Component {
    pub fn new(name: String) -> Component {
        Component {
            name: name,
            props: HashMap::new(),
            subcomponents: vec![]
        }
    }

    /// Retrieve one property (from many) by key. Returns `None` if nothing is found.
    pub fn single_prop(&self, key: &str) -> Option<&Property> {
        match self.props.get(key) {
            Some(x) => {
                match x.len() {
                    1 => Some(&x[0]),
                    _ => None
                }
            },
            None => None
        }
    }

    /// Retrieve a mutable vector of properties for this key. Creates one (and inserts it into the
    /// component) if none exists.
    pub fn all_props_mut(&mut self, key: &str) -> &mut Vec<Property> {
        match self.props.entry(String::from_str(key)) {
            Occupied(values) => values.into_mut(),
            Vacant(values) => values.insert(vec![])
        }
    }

    /// Retrieve properties by key. Returns an empty slice if key doesn't exist.
    pub fn all_props(&self, key: &str) -> &[Property] {
        static EMPTY: &'static [Property] = &[];
        match self.props.get(key) {
            Some(values) => values.as_slice(),
            None => EMPTY
        }
    }
}

peg! parser(r#"
use super::{Component,Property};
use std::collections::HashMap;

#[pub]
component -> Component
    = name:component_begin
      ps:props
      cs:components?
      component_end {
        let mut rv = Component::new(name);

        match cs {
            Some(components) => { rv.subcomponents = components; },
            None => ()
        };

        for (k, v) in ps.into_iter() {
            rv.all_props_mut(k).push(v);
        };

        rv
    }

component_begin -> String
    = "BEGIN:" v:value __ { v.to_string() }

component_end -> String
    = "END:" v:value __ { v.to_string() }

components -> Vec<Component>
    = cs:component ++ eols __ { cs }

props -> Vec<(&'input str, Property)>
    = ps:prop ++ eols __ { ps }

prop -> (&'input str, Property)
    = !"BEGIN:" !"END:" g:group? k:name p:params ":" v:value {
        (k, Property::new(p, v, g))
    }

group -> String
    = g:group_name "." { g }

group_name -> String
    = group_char+ { match_str.to_string() }

name -> &'input str
    = iana_token+ { match_str }

params -> HashMap<String, String>
    = ps:(";" p:param {p})* {
        let mut rv: HashMap<String, String> = HashMap::new();
        for (k, v) in ps.into_iter() {
            rv.insert(k.to_string(), v.to_string());
        };
        rv
    }

param -> (&'input str, &'input str)
    // FIXME: Doesn't handle comma-separated values
    = k:param_name v:("=" v:param_value { v })? {
        (k, match v {
            Some(x) => x,
            None => ""
        })
    }

param_name -> &'input str
    = iana_token+ { match_str }

param_value -> &'input str
    = x:(quoted_string / param_text) { x }

param_text -> &'input str
    = safe_char* { match_str }

value -> String
    = value_char+ { match_str.to_string() }

quoted_string -> &'input str
    = dquote x:quoted_content dquote { x }

quoted_content -> &'input str
    = qsafe_char* { match_str }

iana_token = ([a-zA-Z0-9] / "-")+
group_char = ([a-zA-Z0-9] / "-")
qsafe_char = !dquote !ctl value_char
safe_char = !";" !":" qsafe_char

value_char = !eol .

eol = "\r\n" / "\n" / "\r"
dquote = "\""
eols = eol+

// Taken from vCard. vCalendar's is a subset. Together with the definition of "qsafe_char" this
// might reject a bunch of valid iCalendars, but I can't imagine one.
ctl = [\u{00}-\u{1F}] / "\u{7F}"

whitespace = " " / "\t"
__ = (eol / whitespace)*

"#);

/// Parse a component. The error value is a human-readable message.
pub fn parse_component(s: &str) -> Result<Component, String> {
    // XXX: The unfolding should be worked into the PEG
    // See feature request: https://github.com/kevinmehall/rust-peg/issues/26
    let unfolded = unfold_lines(s);
    parser::component(unfolded.as_slice())
}

/// Write a component. The error value is a human-readable message.
pub fn write_component(c: &Component) -> String {
    fn inner(buf: &mut String, c: &Component) {
        buf.push_str("BEGIN:");
        buf.push_str(c.name.as_slice());
        buf.push_str("\r\n");

        for (prop_name, props) in c.props.iter() {
            for prop in props.iter() {
                match prop.prop_group {
                    Some(ref x) => { buf.push_str(x.as_slice()); buf.push('.'); },
                    None => ()
                };
                buf.push_str(prop_name.as_slice());
                for (param_key, param_value) in prop.params.iter() {
                    buf.push(';');
                    buf.push_str(param_key.as_slice());
                    buf.push('=');
                    buf.push_str(param_value.as_slice());
                };
                buf.push(':');
                buf.push_str(fold_line(prop.raw_value.as_slice()).as_slice());
                buf.push_str("\r\n");
            };
        };

        for subcomponent in c.subcomponents.iter() {
            inner(buf, subcomponent);
        };

        buf.push_str("END:");
        buf.push_str(c.name.as_slice());
        buf.push_str("\r\n");
    }

    let mut buf = String::new();
    inner(&mut buf, c);
    buf
}

/// Escape text for a VObject property value.
pub fn escape_chars(s: &str) -> String {
    // Order matters! Lifted from icalendar.parser
    // https://github.com/collective/icalendar/
    s
        .replace("\\N", "\n")
        .replace("\\", "\\\\")
        .replace(";", "\\;")
        .replace(",", "\\,")
        .replace("\r\n", "\\n")
        .replace("\n", "\\n")
}

/// Unescape text from a VObject property value.
pub fn unescape_chars(s: &str) -> String {
    // Order matters! Lifted from icalendar.parser
    // https://github.com/collective/icalendar/
    s
        .replace("\\N", "\\n")
        .replace("\r\n", "\n")
        .replace("\\n", "\n")
        .replace("\\,", ",")
        .replace("\\;", ";")
        .replace("\\\\", "\\")
}

/// Unfold contentline.
pub fn unfold_lines(s: &str) -> String {
    s
        .replace("\r\n ", "").replace("\r\n\t", "")
        .replace("\n ", "").replace("\n\t", "")
        .replace("\r ", "").replace("\r\t", "")
}

/// Fold contentline to 75 chars. This function assumes the input to be unfolded, which means no
/// '\n' or '\r' in it.
pub fn fold_line(s: &str) -> String {
    let mut rv = String::new();
    for (i, c) in s.chars().enumerate() {
        rv.push(c);
        if i != 0 && i % 75 == 0 {
            rv.push_str("\r\n ");
        };
    };
    rv
}
<|endoftext|>


<commit_before>use crate::constants::*;

#[derive(Clone)]
pub enum Style {
    Old,
    OldInverse,
    New,
    NewInverse,
}

#[derive(Clone)]
pub struct StyledToken {
    token: String,
    style: Style,
}

impl StyledToken {
    pub fn new(token: String, style: Style) -> StyledToken {
        return StyledToken { token, style };
    }
}

pub struct TokenCollector<'a> {
    line_prefix: StyledToken,
    rendered: String,
    color: &'a str,
    is_inverse: bool,
    is_start_of_line: bool,
    finalized: bool,
}

impl Style {
    #[must_use]
    pub fn is_inverse(&self) -> bool {
        match self {
            Style::OldInverse | Style::NewInverse => {
                return true;
            }
            _ => {
                return false;
            }
        }
    }

    #[must_use]
    pub fn color<'a>(&self) -> &'a str {
        match self {
            Style::Old => {
                return OLD;
            }
            Style::OldInverse => {
                return OLD;
            }
            Style::New => {
                return NEW;
            }
            Style::NewInverse => {
                return NEW;
            }
        }
    }
}

impl TokenCollector<'_> {
    #[must_use]
    pub fn create(line_prefix: StyledToken) -> Self {
        return TokenCollector {
            line_prefix,
            rendered: String::new(),
            color: NORMAL,
            is_inverse: false,
            is_start_of_line: true,
            finalized: false,
        };
    }

    pub fn push(&mut self, token: StyledToken) {
        if self.finalized {
            panic!("Already finalized, can't add more tokens");
        }

        if token.token == "\n" {
            self.rendered.push_str(NORMAL);
            self.rendered.push('\n');
            self.is_inverse = false;
            self.is_start_of_line = true;
            self.color = NORMAL;
            return;
        }

        if self.is_start_of_line {
            self.is_start_of_line = false;
            self.push(self.line_prefix.clone());
        }

        if token.style.is_inverse() && !self.is_inverse {
            self.rendered.push_str(INVERSE_VIDEO);
        }
        if self.is_inverse && !token.style.is_inverse() {
            self.rendered.push_str(NOT_INVERSE_VIDEO);
        }
        self.is_inverse = token.style.is_inverse();

        if token.style.color() != self.color {
            self.rendered.push_str(token.style.color());
            self.color = token.style.color();
        }

        self.rendered.push_str(&token.token);
    }

    fn finalize(&mut self) {
        self.finalized = true;

        if !self.rendered.ends_with(&"\n") {
            // Don't forget to reset even if we don't end in a newline
            self.rendered.push_str(NORMAL);
        }
    }

    #[must_use]
    pub fn render(&mut self) -> String {
        self.finalize();

        return self.rendered.clone();
    }
}

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

    #[test]
    fn test_basic() {
        let mut test_me = TokenCollector::create(StyledToken {
            token: "+".to_string(),
            style: Style::New,
        });

        test_me.push(StyledToken {
            token: "hej".to_string(),
            style: Style::New,
        });

        test_me.push(StyledToken {
            token: "\n".to_string(),
            style: Style::New,
        });

        assert_eq!(test_me.render(), format!("{}+hej{}\n", NEW, NORMAL));
    }
}
<commit_msg>Extract render-line into its own method<commit_after>use crate::constants::*;

#[derive(Clone)]
pub enum Style {
    Old,
    OldInverse,
    New,
    NewInverse,
}

#[derive(Clone)]
pub struct StyledToken {
    token: String,
    style: Style,
}

impl StyledToken {
    pub fn new(token: String, style: Style) -> StyledToken {
        return StyledToken { token, style };
    }
}

pub struct TokenCollector {
    line_prefix: StyledToken,
    rendered: String,
    current_row: Vec<StyledToken>,
}

impl Style {
    #[must_use]
    pub fn is_inverse(&self) -> bool {
        match self {
            Style::OldInverse | Style::NewInverse => {
                return true;
            }
            _ => {
                return false;
            }
        }
    }

    #[must_use]
    pub fn color<'a>(&self) -> &'a str {
        match self {
            Style::Old => {
                return OLD;
            }
            Style::OldInverse => {
                return OLD;
            }
            Style::New => {
                return NEW;
            }
            Style::NewInverse => {
                return NEW;
            }
        }
    }
}

impl TokenCollector {
    #[must_use]
    pub fn create(line_prefix: StyledToken) -> Self {
        return TokenCollector {
            line_prefix,
            rendered: String::new(),
            current_row: Vec::new(),
        };
    }

    pub fn push(&mut self, token: StyledToken) {
        if token.token == "\n" {
            self.commit();
            self.rendered.push('\n');
            return;
        }

        self.current_row.push(token);
    }

    fn commit(&mut self) {
        if self.current_row.is_empty() {
            return;
        }

        // Set inverse from prefix
        let mut is_inverse = self.line_prefix.style.is_inverse();
        if is_inverse {
            self.rendered.push_str(INVERSE_VIDEO);
        }

        // Set line color from prefix
        let mut color = self.line_prefix.style.color();
        self.rendered.push_str(self.line_prefix.style.color());

        // Render prefix
        self.rendered.push_str(&self.line_prefix.token);

        for token in &self.current_row {
            if token.style.is_inverse() && !is_inverse {
                self.rendered.push_str(INVERSE_VIDEO);
            }
            if is_inverse && !token.style.is_inverse() {
                self.rendered.push_str(NOT_INVERSE_VIDEO);
            }
            is_inverse = token.style.is_inverse();

            if token.style.color() != color {
                self.rendered.push_str(token.style.color());
                color = token.style.color();
            }

            self.rendered.push_str(&token.token);
        }

        self.rendered.push_str(NORMAL);
        self.current_row.clear();
    }

    #[must_use]
    pub fn render(&mut self) -> String {
        self.commit();

        return self.rendered.clone();
    }
}

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

    #[test]
    fn test_basic() {
        let mut test_me = TokenCollector::create(StyledToken {
            token: "+".to_string(),
            style: Style::New,
        });

        test_me.push(StyledToken {
            token: "hej".to_string(),
            style: Style::New,
        });

        test_me.push(StyledToken {
            token: "\n".to_string(),
            style: Style::New,
        });

        assert_eq!(test_me.render(), format!("{}+hej{}\n", NEW, NORMAL));
    }
}
<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
use std::sync::mpsc;
use std::thread;
use std::result::Result;

use {action, config, context, Message, MiliSec, Response};
use condition::Condition;
use context::base::BaseContextBuilder;
use context::{Context};
use context::linear::LinearContext;
use dispatcher::request::{InternalRequest, Request};
use dispatcher::reactor::RequestReactor;
use dispatcher::{ResponseSender, ResponseHandler};
use dispatcher::response;
use dispatcher::demux::Demultiplexer;
use dispatcher::handlers;
use reactor::{Event, EventHandler, Reactor};
use timer::Timer;

const TIMER_STEP: MiliSec = 100;

use self::exit_handler::ExitHandler;

mod exit_handler;
#[cfg(test)]
mod test;

pub struct Correlator {
    dispatcher_input_channel: mpsc::Sender<Request<Message>>,
    dispatcher_output_channel: mpsc::Receiver<Response>,
    dispatcher_thread_handle: thread::JoinHandle<()>,
    handlers: HashMap<ResponseHandler, Box<EventHandler<Response>>>
}

fn create_context(config_context: config::Context, response_sender: Rc<RefCell<Box<response::ResponseSender<Response>>>>) -> Context {
    let config::Context{name, uuid, conditions, context_id, actions} = config_context;
    let mut boxed_actions = Vec::new();

    for i in actions.into_iter() {
        let action = action::from_config(i, response_sender.clone());
        boxed_actions.push(action);
    }
    let base = BaseContextBuilder::new(uuid, conditions);
    let base = base.name(name);
    let base = base.actions(boxed_actions);
    let base = base.build();
    Context::Linear(LinearContext::from(base))
}

fn create_event_handlers(contexts: Vec<config::Context>, response_sender: Rc<RefCell<Box<response::ResponseSender<Response>>>>) -> Vec<Rc<RefCell<Box<context::event::EventHandler<InternalRequest>>>>> {
    let mut event_handlers = Vec::new();
    for i in contexts.into_iter() {
        let context: context::Context = create_context(i, response_sender.clone());
        let event_handler: Box<context::event::EventHandler<InternalRequest>> = context.into();
        let handler = Rc::new(RefCell::new(event_handler));
        event_handlers.push(handler);
    }
    event_handlers
}

impl Correlator {
    pub fn new(contexts: Vec<config::Context>) -> Correlator {
        let (dispatcher_input_channel, rx) = mpsc::channel();
        let (dispatcher_output_channel_tx, dispatcher_output_channel_rx) = mpsc::channel();
        let _ = Timer::from_chan(TIMER_STEP, dispatcher_input_channel.clone());

        let handle = thread::spawn(move || {
            let dmux = Demultiplexer::new(rx);
            let exit_condition = Condition::new(false);
            let mut reactor = RequestReactor::new(dmux, exit_condition.clone());
            let response_sender = Box::new(ResponseSender::new(dispatcher_output_channel_tx)) as Box<response::ResponseSender<Response>>;
            let response_sender = Rc::new(RefCell::new(response_sender));

            let exit_handler = Box::new(handlers::exit::ExitEventHandler::new(exit_condition, response_sender.clone()));
            let mut timer_event_handler = Box::new(handlers::timer::TimerEventHandler::new());
            let mut message_event_handler = Box::new(handlers::message::MessageEventHandler::new());

            let event_handlers = create_event_handlers(contexts, response_sender);
            println!("event_handlers: {}", event_handlers.len());

            for i in event_handlers {
                timer_event_handler.register_handler(i.clone());
                message_event_handler.register_handler(i.clone())
            }

            reactor.register_handler(exit_handler);
            reactor.register_handler(timer_event_handler);
            reactor.register_handler(message_event_handler);
            reactor.handle_events();
        });

        Correlator {
            dispatcher_input_channel: dispatcher_input_channel,
            dispatcher_output_channel: dispatcher_output_channel_rx,
            dispatcher_thread_handle: handle,
            handlers: HashMap::new()
        }
    }

    pub fn register_handler(&mut self, handler: Box<EventHandler<Response>>) {
        self.handlers.insert(handler.handler(), handler);
    }

    pub fn push_message(&mut self, message: Message) -> Result<(), mpsc::SendError<Request<Message>>> {
        self.consume_results();
        self.dispatcher_input_channel.send(Request::Message(message))
    }

    fn handle_event(&mut self, event: Response) {
        if let Some(handler) = self.handlers.get_mut(&event.handler()) {
            handler.handle_event(event);
        } else {
            println!("no event handler found for handling a Response");
        }
    }

    fn consume_results(&mut self) {
        for i in self.dispatcher_output_channel.try_recv() {
            self.handle_event(i);
        }
    }

    pub fn stop(mut self) -> thread::Result<()> {
        self.consume_results();
        self.stop_dispatcher();
        self.dispatcher_thread_handle.join()
    }

    fn stop_dispatcher(&mut self) {
        let exit_condition = Condition::new(false);
        let exit_handler = Box::new(ExitHandler::new(exit_condition.clone(), self.dispatcher_input_channel.clone()));
        self.register_handler(exit_handler);
        let _ = self.dispatcher_input_channel.send(Request::Exit);
        while !exit_condition.is_active() {
            if let Ok(event) = self.dispatcher_output_channel.recv() {
                self.handle_event(event);
            }
        }
    }
}
<commit_msg>Correlator: use MapContext when a context_id is in the config::Context<commit_after>use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
use std::sync::mpsc;
use std::thread;
use std::result::Result;

use {action, config, context, Message, MiliSec, Response};
use condition::Condition;
use context::base::BaseContextBuilder;
use context::{Context};
use context::linear::LinearContext;
use context::map::MapContext;
use dispatcher::request::{InternalRequest, Request};
use dispatcher::reactor::RequestReactor;
use dispatcher::{ResponseSender, ResponseHandler};
use dispatcher::response;
use dispatcher::demux::Demultiplexer;
use dispatcher::handlers;
use reactor::{Event, EventHandler, Reactor};
use timer::Timer;

const TIMER_STEP: MiliSec = 100;

use self::exit_handler::ExitHandler;

mod exit_handler;
#[cfg(test)]
mod test;

pub struct Correlator {
    dispatcher_input_channel: mpsc::Sender<Request<Message>>,
    dispatcher_output_channel: mpsc::Receiver<Response>,
    dispatcher_thread_handle: thread::JoinHandle<()>,
    handlers: HashMap<ResponseHandler, Box<EventHandler<Response>>>
}

fn create_context(config_context: config::Context, response_sender: Rc<RefCell<Box<response::ResponseSender<Response>>>>) -> Context {
    let config::Context{name, uuid, conditions, context_id, actions} = config_context;
    let mut boxed_actions = Vec::new();

    for i in actions.into_iter() {
        let action = action::from_config(i, response_sender.clone());
        boxed_actions.push(action);
    }
    let base = BaseContextBuilder::new(uuid, conditions);
    let base = base.name(name);
    let base = base.actions(boxed_actions);
    let base = base.build();
    if let Some(context_id) = context_id {
        Context::Map(MapContext::new(base, context_id))
    } else {
        Context::Linear(LinearContext::from(base))
    }
}

fn create_event_handlers(contexts: Vec<config::Context>, response_sender: Rc<RefCell<Box<response::ResponseSender<Response>>>>) -> Vec<Rc<RefCell<Box<context::event::EventHandler<InternalRequest>>>>> {
    let mut event_handlers = Vec::new();
    for i in contexts.into_iter() {
        let context: context::Context = create_context(i, response_sender.clone());
        let event_handler: Box<context::event::EventHandler<InternalRequest>> = context.into();
        let handler = Rc::new(RefCell::new(event_handler));
        event_handlers.push(handler);
    }
    event_handlers
}

impl Correlator {
    pub fn new(contexts: Vec<config::Context>) -> Correlator {
        let (dispatcher_input_channel, rx) = mpsc::channel();
        let (dispatcher_output_channel_tx, dispatcher_output_channel_rx) = mpsc::channel();
        let _ = Timer::from_chan(TIMER_STEP, dispatcher_input_channel.clone());

        let handle = thread::spawn(move || {
            let dmux = Demultiplexer::new(rx);
            let exit_condition = Condition::new(false);
            let mut reactor = RequestReactor::new(dmux, exit_condition.clone());
            let response_sender = Box::new(ResponseSender::new(dispatcher_output_channel_tx)) as Box<response::ResponseSender<Response>>;
            let response_sender = Rc::new(RefCell::new(response_sender));

            let exit_handler = Box::new(handlers::exit::ExitEventHandler::new(exit_condition, response_sender.clone()));
            let mut timer_event_handler = Box::new(handlers::timer::TimerEventHandler::new());
            let mut message_event_handler = Box::new(handlers::message::MessageEventHandler::new());

            let event_handlers = create_event_handlers(contexts, response_sender);
            println!("event_handlers: {}", event_handlers.len());

            for i in event_handlers {
                timer_event_handler.register_handler(i.clone());
                message_event_handler.register_handler(i.clone())
            }

            reactor.register_handler(exit_handler);
            reactor.register_handler(timer_event_handler);
            reactor.register_handler(message_event_handler);
            reactor.handle_events();
        });

        Correlator {
            dispatcher_input_channel: dispatcher_input_channel,
            dispatcher_output_channel: dispatcher_output_channel_rx,
            dispatcher_thread_handle: handle,
            handlers: HashMap::new()
        }
    }

    pub fn register_handler(&mut self, handler: Box<EventHandler<Response>>) {
        self.handlers.insert(handler.handler(), handler);
    }

    pub fn push_message(&mut self, message: Message) -> Result<(), mpsc::SendError<Request<Message>>> {
        self.consume_results();
        self.dispatcher_input_channel.send(Request::Message(message))
    }

    fn handle_event(&mut self, event: Response) {
        if let Some(handler) = self.handlers.get_mut(&event.handler()) {
            handler.handle_event(event);
        } else {
            println!("no event handler found for handling a Response");
        }
    }

    fn consume_results(&mut self) {
        for i in self.dispatcher_output_channel.try_recv() {
            self.handle_event(i);
        }
    }

    pub fn stop(mut self) -> thread::Result<()> {
        self.consume_results();
        self.stop_dispatcher();
        self.dispatcher_thread_handle.join()
    }

    fn stop_dispatcher(&mut self) {
        let exit_condition = Condition::new(false);
        let exit_handler = Box::new(ExitHandler::new(exit_condition.clone(), self.dispatcher_input_channel.clone()));
        self.register_handler(exit_handler);
        let _ = self.dispatcher_input_channel.send(Request::Exit);
        while !exit_condition.is_active() {
            if let Ok(event) = self.dispatcher_output_channel.recv() {
                self.handle_event(event);
            }
        }
    }
}
<|endoftext|>


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

use toml::Value;

use std::collections::BTreeMap;

use libimagstore::store::Store;
use libimagstore::storeid::StoreIdIterator;
use libimagstore::store::FileLockEntry;
use libimagstore::storeid::StoreId;
use libimagstore::storeid::IntoStoreId;

use module_path::ModuleEntryPath;
use result::Result;
use error::CounterError as CE;
use error::CounterErrorKind as CEK;

pub type CounterName = String;

pub struct Counter<'a> {
    fle: FileLockEntry<'a>,
}

impl<'a> Counter<'a> {

    pub fn new(store: &Store, name: CounterName, init: i64) -> Result<Counter> {
        use std::ops::DerefMut;

        debug!("Creating new counter: '{}' with value: {}", name, init);
        let fle = {
            let lockentry = store.create(ModuleEntryPath::new(name.clone()).into_storeid());
            if lockentry.is_err() {
                return Err(CE::new(CEK::StoreWriteError, Some(Box::new(lockentry.err().unwrap()))));
            }
            let mut lockentry = lockentry.unwrap();

            {
                let mut entry  = lockentry.deref_mut();
                let mut header = entry.get_header_mut();
                let setres = header.set("counter", Value::Table(BTreeMap::new()));
                if setres.is_err() {
                    return Err(CE::new(CEK::StoreWriteError, Some(Box::new(setres.err().unwrap()))));
                }

                let setres = header.set("counter.name", Value::String(name));
                if setres.is_err() {
                    return Err(CE::new(CEK::StoreWriteError, Some(Box::new(setres.err().unwrap()))));
                }

                let setres = header.set("counter.value", Value::Integer(init));
                if setres.is_err() {
                    return Err(CE::new(CEK::StoreWriteError, Some(Box::new(setres.err().unwrap()))));
                }
            }

            lockentry
        };

        Ok(Counter { fle: fle })
    }

    pub fn inc(&mut self) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        match header.read("counter.value") {
            Ok(Some(Value::Integer(i))) => {
                header.set("counter.value", Value::Integer(i + 1))
                    .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
                    .map(|_| ())
            },
            Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
            _ => Err(CE::new(CEK::StoreReadError, None)),
        }
    }

    pub fn dec(&mut self) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        match header.read("counter.value") {
            Ok(Some(Value::Integer(i))) => {
                header.set("counter.value", Value::Integer(i - 1))
                    .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
                    .map(|_| ())
            },
            Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
            _ => Err(CE::new(CEK::StoreReadError, None)),
        }
    }

    pub fn reset(&mut self) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        header.set("counter.value", Value::Integer(0))
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .map(|_| ())
    }

    pub fn set(&mut self, v: i64) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        header.set("counter.value", Value::Integer(v))
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .map(|_| ())
    }

    pub fn name(&self) -> Result<CounterName> {
        self.fle.get_header().read("counter.name")
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .and_then(|v| {
                match v {
                    Some(Value::String(s)) => Ok(s),
                    _ => Err(CE::new(CEK::HeaderTypeError, None)),
                }
            })
    }

    pub fn value(&self) -> Result<i64> {
        self.fle.get_header().read("counter.value")
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .and_then(|v| {
                match v {
                    Some(Value::Integer(i)) => Ok(i),
                    _ => Err(CE::new(CEK::HeaderTypeError, None)),
                }
            })
    }

    pub fn load(name: CounterName, store: &Store) -> Result<Counter> {
        debug!("Loading counter: '{}'", name);
        match store.retrieve(ModuleEntryPath::new(name).into_storeid()) {
            Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
            Ok(c)  => Ok(Counter { fle: c }),
        }
    }

    pub fn delete(name: CounterName, store: &Store) -> Result<()> {
        debug!("Deleting counter: '{}'", name);
        store.delete(ModuleEntryPath::new(name).into_storeid())
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
    }

    pub fn all_counters(store: &Store) -> Result<CounterIterator> {
        store.retrieve_for_module("counter")
            .map(|iter| CounterIterator::new(store, iter))
            .map_err(|e| CE::new(CEK::StoreReadError, Some(Box::new(e))))
    }

}

trait FromStoreId {
    fn from_storeid<'a>(&'a Store, StoreId) -> Result<Counter<'a>>;
}

impl<'a> FromStoreId for Counter<'a> {

    fn from_storeid<'b>(store: &'b Store, id: StoreId) -> Result<Counter<'b>> {
        debug!("Loading counter from storeid: '{:?}'", id);
        match store.retrieve(id) {
            Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
            Ok(c)  => Ok(Counter { fle: c }),
        }
    }

}

pub struct CounterIterator<'a> {
    store: &'a Store,
    iditer: StoreIdIterator,
}

impl<'a> CounterIterator<'a> {

    pub fn new(store: &'a Store, iditer: StoreIdIterator) -> CounterIterator<'a> {
        CounterIterator {
            store: store,
            iditer: iditer,
        }
    }

}

impl<'a> Iterator for CounterIterator<'a> {
    type Item = Result<Counter<'a>>;

    fn next(&mut self) -> Option<Result<Counter<'a>>> {
        self.iditer
            .next()
            .map(|id| Counter::from_storeid(self.store, id))
    }

}

<commit_msg>libimagcounter: Replace .err().unwrap() with .unwrap_err()<commit_after>use std::ops::DerefMut;

use toml::Value;

use std::collections::BTreeMap;

use libimagstore::store::Store;
use libimagstore::storeid::StoreIdIterator;
use libimagstore::store::FileLockEntry;
use libimagstore::storeid::StoreId;
use libimagstore::storeid::IntoStoreId;

use module_path::ModuleEntryPath;
use result::Result;
use error::CounterError as CE;
use error::CounterErrorKind as CEK;

pub type CounterName = String;

pub struct Counter<'a> {
    fle: FileLockEntry<'a>,
}

impl<'a> Counter<'a> {

    pub fn new(store: &Store, name: CounterName, init: i64) -> Result<Counter> {
        use std::ops::DerefMut;

        debug!("Creating new counter: '{}' with value: {}", name, init);
        let fle = {
            let lockentry = store.create(ModuleEntryPath::new(name.clone()).into_storeid());
            if lockentry.is_err() {
                return Err(CE::new(CEK::StoreWriteError, Some(Box::new(lockentry.unwrap_err()))));
            }
            let mut lockentry = lockentry.unwrap();

            {
                let mut entry  = lockentry.deref_mut();
                let mut header = entry.get_header_mut();
                let setres = header.set("counter", Value::Table(BTreeMap::new()));
                if setres.is_err() {
                    return Err(CE::new(CEK::StoreWriteError, Some(Box::new(setres.unwrap_err()))));
                }

                let setres = header.set("counter.name", Value::String(name));
                if setres.is_err() {
                    return Err(CE::new(CEK::StoreWriteError, Some(Box::new(setres.unwrap_err()))));
                }

                let setres = header.set("counter.value", Value::Integer(init));
                if setres.is_err() {
                    return Err(CE::new(CEK::StoreWriteError, Some(Box::new(setres.unwrap_err()))));
                }
            }

            lockentry
        };

        Ok(Counter { fle: fle })
    }

    pub fn inc(&mut self) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        match header.read("counter.value") {
            Ok(Some(Value::Integer(i))) => {
                header.set("counter.value", Value::Integer(i + 1))
                    .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
                    .map(|_| ())
            },
            Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
            _ => Err(CE::new(CEK::StoreReadError, None)),
        }
    }

    pub fn dec(&mut self) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        match header.read("counter.value") {
            Ok(Some(Value::Integer(i))) => {
                header.set("counter.value", Value::Integer(i - 1))
                    .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
                    .map(|_| ())
            },
            Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
            _ => Err(CE::new(CEK::StoreReadError, None)),
        }
    }

    pub fn reset(&mut self) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        header.set("counter.value", Value::Integer(0))
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .map(|_| ())
    }

    pub fn set(&mut self, v: i64) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        header.set("counter.value", Value::Integer(v))
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .map(|_| ())
    }

    pub fn name(&self) -> Result<CounterName> {
        self.fle.get_header().read("counter.name")
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .and_then(|v| {
                match v {
                    Some(Value::String(s)) => Ok(s),
                    _ => Err(CE::new(CEK::HeaderTypeError, None)),
                }
            })
    }

    pub fn value(&self) -> Result<i64> {
        self.fle.get_header().read("counter.value")
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .and_then(|v| {
                match v {
                    Some(Value::Integer(i)) => Ok(i),
                    _ => Err(CE::new(CEK::HeaderTypeError, None)),
                }
            })
    }

    pub fn load(name: CounterName, store: &Store) -> Result<Counter> {
        debug!("Loading counter: '{}'", name);
        match store.retrieve(ModuleEntryPath::new(name).into_storeid()) {
            Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
            Ok(c)  => Ok(Counter { fle: c }),
        }
    }

    pub fn delete(name: CounterName, store: &Store) -> Result<()> {
        debug!("Deleting counter: '{}'", name);
        store.delete(ModuleEntryPath::new(name).into_storeid())
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
    }

    pub fn all_counters(store: &Store) -> Result<CounterIterator> {
        store.retrieve_for_module("counter")
            .map(|iter| CounterIterator::new(store, iter))
            .map_err(|e| CE::new(CEK::StoreReadError, Some(Box::new(e))))
    }

}

trait FromStoreId {
    fn from_storeid<'a>(&'a Store, StoreId) -> Result<Counter<'a>>;
}

impl<'a> FromStoreId for Counter<'a> {

    fn from_storeid<'b>(store: &'b Store, id: StoreId) -> Result<Counter<'b>> {
        debug!("Loading counter from storeid: '{:?}'", id);
        match store.retrieve(id) {
            Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
            Ok(c)  => Ok(Counter { fle: c }),
        }
    }

}

pub struct CounterIterator<'a> {
    store: &'a Store,
    iditer: StoreIdIterator,
}

impl<'a> CounterIterator<'a> {

    pub fn new(store: &'a Store, iditer: StoreIdIterator) -> CounterIterator<'a> {
        CounterIterator {
            store: store,
            iditer: iditer,
        }
    }

}

impl<'a> Iterator for CounterIterator<'a> {
    type Item = Result<Counter<'a>>;

    fn next(&mut self) -> Option<Result<Counter<'a>>> {
        self.iditer
            .next()
            .map(|id| Counter::from_storeid(self.store, id))
    }

}

<|endoftext|>


<commit_before>//! Array type node attribute.

use std::fmt;
use std::io;
use std::io::Read;
#[cfg(feature = "flate2")]
use flate2::read::ZlibDecoder;
#[cfg(feature = "libflate")]
use libflate::zlib;

use parser::binary::error::{Result, Error};

/// Array type attribute.
// FIXME: unimplemented.
#[derive(Debug)]
pub struct ArrayAttribute<'a, R: 'a>(&'a mut R);

/// Attribute array decoder.
enum ArrayDecoder<'a, R: 'a> {
    /// Non-compressed stream.
    ///
    /// `encoding` == 0.
    Raw(io::Take<&'a mut R>),
    /// Zlib-compressed stream.
    ///
    /// `encoding` == 1.
    #[cfg(feature = "flate2")]
    Zlib(ZlibDecoder<io::Take<&'a mut R>>),
    /// Zlib-compressed stream.
    ///
    /// `encoding` == 1.
    #[cfg(feature = "libflate")]
    Zlib(zlib::Decoder<io::Take<&'a mut R>>),
}

impl<'a, R: 'a + Read> ArrayDecoder<'a, R> {
    fn new(reader: &'a mut R, header: &ArrayAttributeHeader) -> Result<Self> {
        match header.encoding {
            0 => Ok(ArrayDecoder::Raw(reader.take(header.bytelen_elements as u64))),
            #[cfg(feature = "flate2")]
            1 => Ok(ArrayDecoder::Zlib(ZlibDecoder::new(reader.take(header.bytelen_elements as u64)))),
            #[cfg(feature = "libflate")]
            1 => Ok(ArrayDecoder::Zlib(try!(zlib::Decoder::new(reader.take(header.bytelen_elements as u64))))),
            _ => Err(Error::UnknownArrayAttributeEncoding(header.encoding)),
        }
    }
}

impl<'a, R: 'a + Read> Read for ArrayDecoder<'a, R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        match *self {
            ArrayDecoder::Raw(ref mut reader) => reader.read(buf),
            #[cfg(feature = "flate2")]
            ArrayDecoder::Zlib(ref mut reader) => reader.read(buf),
            #[cfg(feature = "libflate")]
            ArrayDecoder::Zlib(ref mut reader) => reader.read(buf),
        }
    }
}

impl<'a, R: 'a> fmt::Debug for ArrayDecoder<'a, R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "ArrayDecoder::{}",
               match *self {
                   ArrayDecoder::Raw(_) => "Raw",
                   #[cfg(feature = "flate2")]
                   ArrayDecoder::Zlib(_) => "Zlib",
                   #[cfg(feature = "libflate")]
                   ArrayDecoder::Zlib(_) => "Zlib",
               })
    }
}
<commit_msg>Add `ArrayAttributeHeader` and its loader<commit_after>//! Array type node attribute.

use std::fmt;
use std::io;
use std::io::Read;
#[cfg(feature = "flate2")]
use flate2::read::ZlibDecoder;
#[cfg(feature = "libflate")]
use libflate::zlib;

use parser::binary::BinaryParser;
use parser::binary::error::{Result, Error};

/// Header of an array attribute.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
struct ArrayAttributeHeader {
    /// Number of elements.
    num_elements: u32,
    /// Array encoding, i.e. compression method.
    encoding: u32,
    /// Length of the array (excluding this header) in bytes.
    bytelen_elements: u32,
}

impl ArrayAttributeHeader {
    fn read_from_parser<R: Read>(parser: &mut BinaryParser<R>) -> io::Result<Self> {
        let num_elements = try!(parser.source.read_u32());
        let encoding = try!(parser.source.read_u32());
        let bytelen_elements = try!(parser.source.read_u32());

        Ok(ArrayAttributeHeader {
            num_elements: num_elements,
            encoding: encoding,
            bytelen_elements: bytelen_elements,
        })
    }
}

/// Array type attribute.
// FIXME: unimplemented.
#[derive(Debug)]
pub struct ArrayAttribute<'a, R: 'a>(&'a mut R);

/// Attribute array decoder.
enum ArrayDecoder<'a, R: 'a> {
    /// Non-compressed stream.
    ///
    /// `encoding` == 0.
    Raw(io::Take<&'a mut R>),
    /// Zlib-compressed stream.
    ///
    /// `encoding` == 1.
    #[cfg(feature = "flate2")]
    Zlib(ZlibDecoder<io::Take<&'a mut R>>),
    /// Zlib-compressed stream.
    ///
    /// `encoding` == 1.
    #[cfg(feature = "libflate")]
    Zlib(zlib::Decoder<io::Take<&'a mut R>>),
}

impl<'a, R: 'a + Read> ArrayDecoder<'a, R> {
    fn new(reader: &'a mut R, header: &ArrayAttributeHeader) -> Result<Self> {
        match header.encoding {
            0 => Ok(ArrayDecoder::Raw(reader.take(header.bytelen_elements as u64))),
            #[cfg(feature = "flate2")]
            1 => Ok(ArrayDecoder::Zlib(ZlibDecoder::new(reader.take(header.bytelen_elements as u64)))),
            #[cfg(feature = "libflate")]
            1 => Ok(ArrayDecoder::Zlib(try!(zlib::Decoder::new(reader.take(header.bytelen_elements as u64))))),
            _ => Err(Error::UnknownArrayAttributeEncoding(header.encoding)),
        }
    }
}

impl<'a, R: 'a + Read> Read for ArrayDecoder<'a, R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        match *self {
            ArrayDecoder::Raw(ref mut reader) => reader.read(buf),
            #[cfg(feature = "flate2")]
            ArrayDecoder::Zlib(ref mut reader) => reader.read(buf),
            #[cfg(feature = "libflate")]
            ArrayDecoder::Zlib(ref mut reader) => reader.read(buf),
        }
    }
}

impl<'a, R: 'a> fmt::Debug for ArrayDecoder<'a, R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "ArrayDecoder::{}",
               match *self {
                   ArrayDecoder::Raw(_) => "Raw",
                   #[cfg(feature = "flate2")]
                   ArrayDecoder::Zlib(_) => "Zlib",
                   #[cfg(feature = "libflate")]
                   ArrayDecoder::Zlib(_) => "Zlib",
               })
    }
}
<|endoftext|>


<commit_before>#[doc(hidden)];

use std::mem;
use std::rand::{IsaacRng, Rng};
use std::vec;
use std::hash::Hash;
use std::hash::sip::SipState;
use collections::HashMap;
use nalgebra::na;
use nalgebra::na::Iterable;
use ncollide::math::{N, V};

#[deriving(Eq)]
struct ContactIdentifier {
    obj1:    uint,
    obj2:    uint,
    ccenter: V
}

impl Hash for ContactIdentifier {
    #[inline]
    #[cfg(f32)]
    fn hash(&self, state: &mut SipState) {
        for e in self.ccenter.iter() {
            let _ = state.write_le_f32(*e);
        }
    }

    #[inline]
    #[cfg(f64)]
    fn hash(&self, state: &mut SipState) {
        for e in self.ccenter.iter() {
            let _ = state.write_le_f64(*e);
        }
    }
}

impl ContactIdentifier {
    pub fn new(obj1: uint, obj2: uint, center: V, step: &N) -> ContactIdentifier {
        ContactIdentifier {
            obj1:    obj1,
            obj2:    obj2,
            ccenter: (center / *step).trunc()
        }
    }
}

pub struct ImpulseCache {
    priv hash_prev:           HashMap<ContactIdentifier, (uint, uint)>,
    priv cache_prev:          ~[N],
    priv hash_next:           HashMap<ContactIdentifier, (uint, uint)>,
    priv cache_next:          ~[N],
    priv step:                N,
    priv impulse_per_contact: uint
}

impl ImpulseCache {
    pub fn new(step: N, impulse_per_contact: uint) -> ImpulseCache {
        let mut rng = IsaacRng::new_unseeded();

        ImpulseCache {
            hash_prev:           HashMap::with_capacity_and_keys(rng.gen(), rng.gen(), 32),
            hash_next:           HashMap::with_capacity_and_keys(rng.gen(), rng.gen(), 32),
            cache_prev:          vec::from_elem(impulse_per_contact, na::zero()),
            cache_next:          vec::from_elem(impulse_per_contact, na::zero()),
            step:                step,
            impulse_per_contact: impulse_per_contact
        }
    }

    pub fn insert<'a>(&'a mut self, cid: uint, obj1: uint, obj2: uint, center: V) {
        let id = ContactIdentifier::new(obj1, obj2, center, &self.step);
        let imp =
            match self.hash_prev.find_copy(&id) {
                Some((_, i)) => i,
                None         => 0
            };

        self.hash_next.insert(id, (cid, imp));
    }

    pub fn hash<'a>(&'a self) -> &'a HashMap<ContactIdentifier, (uint, uint)> {
        &'a self.hash_next
    }

    pub fn hash_mut<'a>(&'a mut self) -> &'a mut HashMap<ContactIdentifier, (uint, uint)> {
        &'a mut self.hash_next
    }

    pub fn push_impulsions<'a>(&'a mut self) -> &'a mut [N] {
        let begin = self.cache_next.len();

        for _ in range(0, self.impulse_per_contact) {
            self.cache_next.push(na::zero());
        }

        let end = self.cache_next.len();

        self.cache_next.mut_slice(begin, end)
    }

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

    pub fn impulsions_at<'a>(&'a self, at: uint) -> &'a [N] {
        self.cache_prev.slice(at, at + self.impulse_per_contact)
    }

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

    pub fn clear(&mut self) {
        self.cache_prev.clear();
        self.hash_prev.clear();
        self.cache_next.clear();
        self.hash_next.clear();

        self.cache_prev.grow_set(self.impulse_per_contact, &na::zero(), na::zero());
        self.cache_next.grow_set(self.impulse_per_contact, &na::zero(), na::zero());
    }

    pub fn swap(&mut self) {
        mem::swap(&mut self.hash_prev, &mut self.hash_next);
        mem::swap(&mut self.cache_prev,&mut self.cache_next);
        self.hash_next.clear();
        self.cache_next.truncate(self.impulse_per_contact);
    }
}
<commit_msg>Update to the last Rust.<commit_after>#[doc(hidden)];

use std::mem;
use std::rand::{IsaacRng, Rng};
use std::vec;
use std::hash::Hash;
use std::hash::sip::{SipHasher, SipState};
use collections::HashMap;
use nalgebra::na;
use nalgebra::na::Iterable;
use ncollide::math::{N, V};

#[deriving(Eq)]
struct ContactIdentifier {
    obj1:    uint,
    obj2:    uint,
    ccenter: V
}

impl Hash for ContactIdentifier {
    #[inline]
    #[cfg(f32)]
    fn hash(&self, state: &mut SipState) {
        for e in self.ccenter.iter() {
            let _ = state.write_le_f32(*e);
        }
    }

    #[inline]
    #[cfg(f64)]
    fn hash(&self, state: &mut SipState) {
        for e in self.ccenter.iter() {
            let _ = state.write_le_f64(*e);
        }
    }
}

impl ContactIdentifier {
    pub fn new(obj1: uint, obj2: uint, center: V, step: &N) -> ContactIdentifier {
        ContactIdentifier {
            obj1:    obj1,
            obj2:    obj2,
            ccenter: (center / *step).trunc()
        }
    }
}

pub struct ImpulseCache {
    priv hash_prev:           HashMap<ContactIdentifier, (uint, uint)>,
    priv cache_prev:          ~[N],
    priv hash_next:           HashMap<ContactIdentifier, (uint, uint)>,
    priv cache_next:          ~[N],
    priv step:                N,
    priv impulse_per_contact: uint
}

impl ImpulseCache {
    pub fn new(step: N, impulse_per_contact: uint) -> ImpulseCache {
        let mut rng = IsaacRng::new_unseeded();

        ImpulseCache {
            hash_prev:           HashMap::with_capacity_and_hasher(SipHasher::new_with_keys(rng.gen(), rng.gen()), 32),
            hash_next:           HashMap::with_capacity_and_hasher(SipHasher::new_with_keys(rng.gen(), rng.gen()), 32),
            cache_prev:          vec::from_elem(impulse_per_contact, na::zero()),
            cache_next:          vec::from_elem(impulse_per_contact, na::zero()),
            step:                step,
            impulse_per_contact: impulse_per_contact
        }
    }

    pub fn insert<'a>(&'a mut self, cid: uint, obj1: uint, obj2: uint, center: V) {
        let id = ContactIdentifier::new(obj1, obj2, center, &self.step);
        let imp =
            match self.hash_prev.find_copy(&id) {
                Some((_, i)) => i,
                None         => 0
            };

        self.hash_next.insert(id, (cid, imp));
    }

    pub fn hash<'a>(&'a self) -> &'a HashMap<ContactIdentifier, (uint, uint)> {
        &'a self.hash_next
    }

    pub fn hash_mut<'a>(&'a mut self) -> &'a mut HashMap<ContactIdentifier, (uint, uint)> {
        &'a mut self.hash_next
    }

    pub fn push_impulsions<'a>(&'a mut self) -> &'a mut [N] {
        let begin = self.cache_next.len();

        for _ in range(0, self.impulse_per_contact) {
            self.cache_next.push(na::zero());
        }

        let end = self.cache_next.len();

        self.cache_next.mut_slice(begin, end)
    }

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

    pub fn impulsions_at<'a>(&'a self, at: uint) -> &'a [N] {
        self.cache_prev.slice(at, at + self.impulse_per_contact)
    }

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

    pub fn clear(&mut self) {
        self.cache_prev.clear();
        self.hash_prev.clear();
        self.cache_next.clear();
        self.hash_next.clear();

        self.cache_prev.grow_set(self.impulse_per_contact, &na::zero(), na::zero());
        self.cache_next.grow_set(self.impulse_per_contact, &na::zero(), na::zero());
    }

    pub fn swap(&mut self) {
        mem::swap(&mut self.hash_prev, &mut self.hash_next);
        mem::swap(&mut self.cache_prev,&mut self.cache_next);
        self.hash_next.clear();
        self.cache_next.truncate(self.impulse_per_contact);
    }
}
<|endoftext|>


<commit_before>
<commit_msg>circular-buffer: Add template to the stub file (#608)<commit_after>use std::marker::PhantomData;

pub struct CircularBuffer<T> {
    // This field is here to make the template compile and not to
    // complain about unused type parameter 'T'. Once you start
    // solving the exercise, delete this field and the 'std::marker::PhantomData'
    // import.
    field: PhantomData<T>,
}

#[derive(Debug, PartialEq)]
pub enum Error {
    EmptyBuffer,
    FullBuffer,
}

impl<T> CircularBuffer<T> {
    pub fn new(capacity: usize) -> Self {
        unimplemented!(
            "Construct a new CircularBuffer with the capacity to hold {}.",
            match capacity {
                1 => format!("1 element"),
                _ => format!("{} elements", capacity),
            }
        );
    }

    pub fn write(&mut self, _element: T) -> Result<(), Error> {
        unimplemented!("Write the passed element to the CircularBuffer or return FullBuffer error if CircularBuffer is full.");
    }

    pub fn read(&mut self) -> Result<T, Error> {
        unimplemented!("Read the oldest element from the CircularBuffer or return EmptyBuffer error if CircularBuffer is empty.");
    }

    pub fn clear(&mut self) {
        unimplemented!("Clear the CircularBuffer.");
    }

    pub fn overwrite(&mut self, _element: T) {
        unimplemented!("Write the passed element to the CircularBuffer, overwriting the existing elements if CircularBuffer is full.");
    }
}
<|endoftext|>


<commit_before>use std::ptr;
use std::mem;
use std::vec::Vec;
use std;

/// Implementation of insertion sort.
/// CLRS pg 18.
///
///     O(n^2)
///
fn insertion_sort(mut a: Vec<i32>) -> Vec<i32> {
    let len = a.len();
    let cap = a.capacity();
    let p = a.as_mut_ptr();
    unsafe {
        mem::forget(a);
        for j in range(1, len as int) {
            let key = *p.offset(j);
            let mut i = j - 1;
            while i > -1 && *p.offset(i) > key {
                ptr::write(p.offset(i + 1), *p.offset(i));
                i = i - 1;
            }
            ptr::write(p.offset(i+1), key);
        }
        Vec::from_raw_parts(len, cap, p)
    }
}

#[cfg(test)]
mod tests {
    use sorting;

    #[test]
    fn test_insertion_sort_example() {
        // Example from CLRS pg 18.
        let mut sorted = vec!(5, 2, 4, 6, 1, 3);
        sorted = sorting::insertion_sort(sorted);
        assert_eq!(sorted, vec!(1i32, 2, 3, 4, 5, 6));
    }

    #[test]
    fn test_insertion_sort_duplicates() {
        let mut sorted = vec!(5, 5, 4);
        sorted = sorting::insertion_sort(sorted);
        assert_eq!(sorted, vec!(4, 5, 5));
    }

    #[test]
    fn test_insertion_sort_single_element() {
        let mut sorted = vec!(0);
        sorted = sorting::insertion_sort(sorted);
        assert_eq!(sorted, vec!(0));
    }

    #[test]
    fn test_insertion_sort_empty() {
        let mut sorted = vec!();
        sorted = sorting::insertion_sort(sorted);
        assert_eq!(sorted, vec!());
    }
}
<commit_msg>insertion sort: generic version<commit_after>use std::ptr;
use std::mem;
use std::vec::Vec;

/// Implementation of insertion sort.
/// CLRS pg 18. `O(n^2)`.
fn insertion_sort<T: Ord>(mut a: Vec<T>) -> Vec<T> {
    // Break it apart so we can do tricky memory things.
    let len = a.len();
    let cap = a.capacity();
    let p = a.as_mut_ptr();
    unsafe {
        // Stop the memory manager from calling the destructor.
        mem::forget(a);
        for j in range(1, len as int) {
            let key_offset = p.offset(j) as *const T;
            let key = ptr::read(key_offset);
            let mut i = j - 1;
            while i > -1 && *p.offset(i) > key {
                let other_offset = p.offset(i) as *const T;
                ptr::write(p.offset(i + 1), ptr::read(other_offset));
                i = i - 1;
            }
            ptr::write(p.offset(i+1), key);
        }
        Vec::from_raw_parts(len, cap, p)
    }
}

#[cfg(test)]
mod tests {
    use sorting;

    #[test]
    fn test_insertion_sort_example() {
        // Example from CLRS pg 18.
        let mut sorted = vec!(5i32, 2, 4, 6, 1, 3);
        sorted = sorting::insertion_sort(sorted);
        assert_eq!(sorted, vec!(1i32, 2, 3, 4, 5, 6));
    }

    #[test]
    fn test_insertion_sort_duplicates() {
        let mut sorted = vec!(5i32, 5, 4);
        sorted = sorting::insertion_sort(sorted);
        assert_eq!(sorted, vec!(4, 5, 5));
    }

    #[test]
    fn test_insertion_sort_single_element() {
        let mut sorted = vec!(0i32);
        sorted = sorting::insertion_sort(sorted);
        assert_eq!(sorted, vec!(0));
    }

    #[test]
    fn test_insertion_sort_empty() {
        let mut sorted = vec!();
        sorted = sorting::insertion_sort::<i32>(sorted);
        assert_eq!(sorted, vec!());
    }
}
<|endoftext|>