<commit_before>use devices::{NodeId, ChannelKind, Channel, Get, Set};
use util::{Exactly, Id};
use values;

use serde::ser::Serializer;
use serde::de::Deserializer;

use std::cmp;

fn merge<T>(mut a: Vec<T>, mut b: Vec<T>) -> Vec<T> where T: Ord {
    a.append(&mut b);
    a.sort();
    a.dedup();
    a
}

/// A selector for one or more nodes.
///
///
/// # Example
///
/// ```
/// use fxbox_taxonomy::selector::*;
/// use fxbox_taxonomy::devices::*;
///
/// let selector = NodeSelector::new()
///   .with_tags(vec!["entrance".to_owned()])
///   .with_inputs(vec![GetSelector::new() /* can be more restrictive */]);
/// ```
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct NodeSelector {
    /// If `Exactly(id)`, return only the node with the corresponding id.
    #[serde(default)]
    pub id: Exactly<Id<NodeId>>,

    ///  Restrict results to nodes that have all the tags in `tags`.
    #[serde(default)]
    pub tags: Vec<String>,

    /// Restrict results to nodes that have all the inputs in `inputs`.
    #[serde(default)]
    pub inputs: Vec<GetSelector>,

    /// Restrict results to nodes that have all the outputs in `outputs`.
    #[serde(default)]
    pub outputs: Vec<SetSelector>,

    /// Make sure that we can't instantiate from another crate.
    #[serde(default, skip_serializing)]
    private: (),
}

impl NodeSelector {
    /// Create a new selector that accepts all nodes.
    pub fn new() -> Self {
        Self::default()
    }

    /// Selector for a node with a specific id.
    pub fn with_id(self, id: Id<NodeId>) -> Self {
        NodeSelector {
            id: self.id.and(Exactly::Exactly(id)),
            .. self
        }
    }

    ///  Restrict results to nodes that have all the tags in `tags`.
    pub fn with_tags(self, tags: Vec<String>) -> Self {
        NodeSelector {
            tags: merge(self.tags, tags),
            .. self
        }
    }

    /// Restrict results to nodes that have all the inputs in `inputs`.
    pub fn with_inputs(mut self, mut inputs: Vec<GetSelector>) -> Self {
        NodeSelector {
            inputs: {self.inputs.append(&mut inputs); self.inputs},
            .. self
        }
    }

    /// Restrict results to nodes that have all the outputs in `outputs`.
    pub fn with_outputs(mut self, mut outputs: Vec<SetSelector>) -> Self {
        NodeSelector {
            outputs: {self.outputs.append(&mut outputs); self.outputs},
            .. self
        }
    }

    /// Restrict results to nodes that are accepted by two selector.
    pub fn and(mut self, mut other: NodeSelector) -> Self {
        NodeSelector {
            id: self.id.and(other.id),
            tags: merge(self.tags, other.tags),
            inputs: {self.inputs.append(&mut other.inputs); self.inputs},
            outputs: {self.outputs.append(&mut other.outputs); self.outputs},
            private: (),
        }
    }
}

/// A selector for one or more input channels.
///
///
/// # Example
///
/// ```
/// use fxbox_taxonomy::selector::*;
/// use fxbox_taxonomy::devices::*;
/// use fxbox_taxonomy::util::Id;
///
/// let selector = GetSelector::new()
///   .with_parent(Id::new("foxbox".to_owned()))
///   .with_kind(ChannelKind::CurrentTimeOfDay);
/// ```
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct GetSelector {
    /// If `Exactly(id)`, return only the channel with the corresponding id.
    #[serde(default)]
    pub id: Exactly<Id<Get>>,

    /// If `Eactly(id)`, return only channels that are children of
    /// node `id`.
    #[serde(default)]
    pub parent: Exactly<Id<NodeId>>,

    ///  Restrict results to channels that have all the tags in `tags`.
    #[serde(default)]
    pub tags: Vec<String>,

    /// If `Exatly(k)`, restrict results to channels that produce values
    /// of kind `k`.
    #[serde(default)]
    pub kind: Exactly<ChannelKind>,

    /// If `Some(r)`, restrict results to channels that support polling
    /// with the acceptable period.
    #[serde(default)]
    pub poll: Option<Period>,

    /// If `Some(r)`, restrict results to channels that support trigger
    /// with the acceptable period.
    #[serde(default)]
    pub trigger: Option<Period>,

    /// Make sure that we can't instantiate from another crate.
    #[serde(default, skip_serializing)]
    private: (),
}
impl GetSelector {
    /// Create a new selector that accepts all input channels.
    pub fn new() -> Self {
        Self::default()
    }

    /// Restrict to a channel with a specific id.
    pub fn with_id(self, id: Id<Get>) -> Self {
        GetSelector {
            id: self.id.and(Exactly::Exactly(id)),
            .. self
        }
    }

    /// Restrict to a channel with a specific parent.
    pub fn with_parent(self, id: Id<NodeId>) -> Self {
        GetSelector {
            parent: self.parent.and(Exactly::Exactly(id)),
            .. self
        }
    }

    /// Restrict to a channel with a specific kind.
    pub fn with_kind(self, kind: ChannelKind) -> Self {
        GetSelector {
            kind: self.kind.and(Exactly::Exactly(kind)),
            .. self
        }
    }

    ///  Restrict to channels that have all the tags in `tags`.
    pub fn with_tags(self, tags: Vec<String>) -> Self {
        GetSelector {
            tags: merge(self.tags, tags),
            .. self
        }
    }

    /// Restrict to channels that support polling with the acceptable
    /// period
    pub fn with_poll(self, period: Period) -> Self {
        GetSelector {
            poll: Period::and_option(self.poll, Some(period)),
            .. self
        }
    }

    /// Restrict to channels that support trigger with the acceptable
    /// period
    pub fn with_trigger(self, period: Period) -> Self {
        GetSelector {
            trigger: Period::and_option(self.trigger, Some(period)),
            .. self
        }
    }

    /// Restrict to channels that are accepted by two selector.
    pub fn and(self, other: Self) -> Self {
        GetSelector {
            id: self.id.and(other.id),
            parent: self.parent.and(other.parent),
            tags: merge(self.tags, other.tags),
            kind: self.kind.and(other.kind),
            poll: Period::and_option(self.poll, other.poll),
            trigger: Period::and_option(self.trigger, other.trigger),
            private: (),
        }
    }

    /// Determine if a channel is matched by this selector.
    pub fn matches(&self, channel: &Channel<Get>) -> bool {
        if !self.id.matches(&channel.id) {
            return false;
        }
        if !self.parent.matches(&channel.node) {
            return false;
        }
        if !self.kind.matches(&channel.mechanism.kind) {
            return false;
        }
        if !Period::matches_option(&self.poll, &channel.mechanism.poll) {
            return false;
        }
        if !Period::matches_option(&self.trigger, &channel.mechanism.trigger) {
            return false;
        }
        if !has_selected_tags(&self.tags, &channel.tags) {
            return false;
        }
        return true;
    }
}

/// A selector for one or more output channels.
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct SetSelector {
    /// If `Exactly(id)`, return only the channel with the corresponding id.
    #[serde(default)]
    pub id: Exactly<Id<Set>>,

    /// If `Exactly(id)`, return only channels that are immediate children
    /// of node `id`.
    #[serde(default)]
    pub parent: Exactly<Id<NodeId>>,

    ///  Restrict results to channels that have all the tags in `tags`.
    #[serde(default)]
    pub tags: Vec<String>,

    /// If `Exactly(k)`, restrict results to channels that accept values
    /// of kind `k`.
    #[serde(default)]
    pub kind: Exactly<ChannelKind>,

    /// If `Some(r)`, restrict results to channels that support pushing
    /// with the acceptable period.
    #[serde(default)]
    pub push: Option<Period>,

    /// Make sure that we can't instantiate from another crate.
    #[serde(default, skip_serializing)]
    private: (),
}

impl SetSelector {
    /// Create a new selector that accepts all input channels.
    pub fn new() -> Self {
        SetSelector::default()
    }

    /// Selector to a channel with a specific id.
    pub fn with_id(self, id: Id<Set>) -> Self {
        SetSelector {
            id: self.id.and(Exactly::Exactly(id)),
            .. self
        }
    }

    /// Selector to channels with a specific parent.
    pub fn with_parent(self, id: Id<NodeId>) -> Self {
        SetSelector {
            parent: self.parent.and(Exactly::Exactly(id)),
            .. self
        }
    }

    /// Selector to channels with a specific kind.
    pub fn with_kind(self, kind: ChannelKind) -> Self {
        SetSelector {
            kind: self.kind.and(Exactly::Exactly(kind)),
            .. self
        }
    }

    ///  Restrict to channels that have all the tags in `tags`.
    pub fn with_tags(self, tags: Vec<String>) -> Self {
        SetSelector {
            tags: merge(self.tags, tags),
            .. self
        }
    }

    /// Restrict to channels that support push with the acceptable
    /// period
    pub fn with_push(self, period: Period) -> Self {
        SetSelector {
            push: Period::and_option(self.push, Some(period)),
            .. self
        }
    }

    /// Restrict results to channels that are accepted by two selector.
    pub fn and(self, other: Self) -> Self {
        SetSelector {
            id: self.id.and(other.id),
            parent: self.parent.and(other.parent),
            tags: merge(self.tags, other.tags),
            kind: self.kind.and(other.kind),
            push: Period::and_option(self.push, other.push),
            private: (),
        }
    }

    /// Determine if a channel is matched by this selector.
    pub fn matches(&self, channel: &Channel<Set>) -> bool {
        if !self.id.matches(&channel.id) {
            return false;
        }
        if !self.parent.matches(&channel.node) {
            return false;
        }
        if !self.kind.matches(&channel.mechanism.kind) {
            return false;
        }
        if !Period::matches_option(&self.push, &channel.mechanism.push) {
            return false;
        }
        if !has_selected_tags(&self.tags, &channel.tags) {
            return false;
        }
        return true;
    }
}

/// An acceptable interval of time.
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct Period {
    #[serde(default)]
    pub min: Option<values::ValDuration>,
    #[serde(default)]
    pub max: Option<values::ValDuration>,
}
impl Period {
    pub fn and(self, other: Self) -> Self {
        let min = match (self.min, other.min) {
            (None, x@_) => x,
            (x@_, None) => x,
            (Some(min1), Some(min2)) => Some(cmp::max(min1, min2))
        };
        let max = match (self.max, other.max) {
            (None, x@_) => x,
            (x@_, None) => x,
            (Some(max1), Some(max2)) => Some(cmp::min(max1, max2))
        };
        Period {
            min: min,
            max: max
        }
    }

    pub fn and_option(a: Option<Self>, b: Option<Self>) -> Option<Self> {
        match (a, b) {
            (None, x@_) => x,
            (x@_, None) => x,
            (Some(a), Some(b)) => Some(a.and(b))
        }
    }

    pub fn matches(&self, duration: &values::ValDuration) -> bool {
        if let Some(ref min) = self.min {
            if min > duration {
                return false;
            }
        }
        if let Some(ref max) = self.max {
            if max < duration {
                return false;
            }
        }
        return true;
    }

    pub fn matches_option(period: &Option<Self>, duration: &Option<values::ValDuration>) -> bool {
        match (period, duration) {
            (&Some(ref period), &Some(ref duration))
                if !period.matches(duration) => false,
            (&Some(_), &None) => false,
            _ => true,
        }
    }
}

fn has_selected_tags(actual: &Vec<String>, requested: &Vec<String>) -> bool {
    for tag in &*actual {
        if requested.iter().find(|x| *x == tag).is_none() {
            return false;
        }
    }
    return true;
}
<commit_msg>[fxbox/taxonomy] Trivial docfix<commit_after>use devices::{NodeId, ChannelKind, Channel, Get, Set};
use util::{Exactly, Id};
use values;

use serde::ser::Serializer;
use serde::de::Deserializer;

use std::cmp;

fn merge<T>(mut a: Vec<T>, mut b: Vec<T>) -> Vec<T> where T: Ord {
    a.append(&mut b);
    a.sort();
    a.dedup();
    a
}

/// A selector for one or more nodes.
///
///
/// # Example
///
/// ```
/// use foxbox_taxonomy::selector::*;
/// use foxbox_taxonomy::devices::*;
///
/// let selector = NodeSelector::new()
///   .with_tags(vec!["entrance".to_owned()])
///   .with_inputs(vec![GetSelector::new() /* can be more restrictive */]);
/// ```
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct NodeSelector {
    /// If `Exactly(id)`, return only the node with the corresponding id.
    #[serde(default)]
    pub id: Exactly<Id<NodeId>>,

    ///  Restrict results to nodes that have all the tags in `tags`.
    #[serde(default)]
    pub tags: Vec<String>,

    /// Restrict results to nodes that have all the inputs in `inputs`.
    #[serde(default)]
    pub inputs: Vec<GetSelector>,

    /// Restrict results to nodes that have all the outputs in `outputs`.
    #[serde(default)]
    pub outputs: Vec<SetSelector>,

    /// Make sure that we can't instantiate from another crate.
    #[serde(default, skip_serializing)]
    private: (),
}

impl NodeSelector {
    /// Create a new selector that accepts all nodes.
    pub fn new() -> Self {
        Self::default()
    }

    /// Selector for a node with a specific id.
    pub fn with_id(self, id: Id<NodeId>) -> Self {
        NodeSelector {
            id: self.id.and(Exactly::Exactly(id)),
            .. self
        }
    }

    ///  Restrict results to nodes that have all the tags in `tags`.
    pub fn with_tags(self, tags: Vec<String>) -> Self {
        NodeSelector {
            tags: merge(self.tags, tags),
            .. self
        }
    }

    /// Restrict results to nodes that have all the inputs in `inputs`.
    pub fn with_inputs(mut self, mut inputs: Vec<GetSelector>) -> Self {
        NodeSelector {
            inputs: {self.inputs.append(&mut inputs); self.inputs},
            .. self
        }
    }

    /// Restrict results to nodes that have all the outputs in `outputs`.
    pub fn with_outputs(mut self, mut outputs: Vec<SetSelector>) -> Self {
        NodeSelector {
            outputs: {self.outputs.append(&mut outputs); self.outputs},
            .. self
        }
    }

    /// Restrict results to nodes that are accepted by two selector.
    pub fn and(mut self, mut other: NodeSelector) -> Self {
        NodeSelector {
            id: self.id.and(other.id),
            tags: merge(self.tags, other.tags),
            inputs: {self.inputs.append(&mut other.inputs); self.inputs},
            outputs: {self.outputs.append(&mut other.outputs); self.outputs},
            private: (),
        }
    }
}

/// A selector for one or more input channels.
///
///
/// # Example
///
/// ```
/// use foxbox_taxonomy::selector::*;
/// use foxbox_taxonomy::devices::*;
/// use foxbox_taxonomy::util::Id;
///
/// let selector = GetSelector::new()
///   .with_parent(Id::new("foxbox".to_owned()))
///   .with_kind(ChannelKind::CurrentTimeOfDay);
/// ```
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct GetSelector {
    /// If `Exactly(id)`, return only the channel with the corresponding id.
    #[serde(default)]
    pub id: Exactly<Id<Get>>,

    /// If `Eactly(id)`, return only channels that are children of
    /// node `id`.
    #[serde(default)]
    pub parent: Exactly<Id<NodeId>>,

    ///  Restrict results to channels that have all the tags in `tags`.
    #[serde(default)]
    pub tags: Vec<String>,

    /// If `Exatly(k)`, restrict results to channels that produce values
    /// of kind `k`.
    #[serde(default)]
    pub kind: Exactly<ChannelKind>,

    /// If `Some(r)`, restrict results to channels that support polling
    /// with the acceptable period.
    #[serde(default)]
    pub poll: Option<Period>,

    /// If `Some(r)`, restrict results to channels that support trigger
    /// with the acceptable period.
    #[serde(default)]
    pub trigger: Option<Period>,

    /// Make sure that we can't instantiate from another crate.
    #[serde(default, skip_serializing)]
    private: (),
}
impl GetSelector {
    /// Create a new selector that accepts all input channels.
    pub fn new() -> Self {
        Self::default()
    }

    /// Restrict to a channel with a specific id.
    pub fn with_id(self, id: Id<Get>) -> Self {
        GetSelector {
            id: self.id.and(Exactly::Exactly(id)),
            .. self
        }
    }

    /// Restrict to a channel with a specific parent.
    pub fn with_parent(self, id: Id<NodeId>) -> Self {
        GetSelector {
            parent: self.parent.and(Exactly::Exactly(id)),
            .. self
        }
    }

    /// Restrict to a channel with a specific kind.
    pub fn with_kind(self, kind: ChannelKind) -> Self {
        GetSelector {
            kind: self.kind.and(Exactly::Exactly(kind)),
            .. self
        }
    }

    ///  Restrict to channels that have all the tags in `tags`.
    pub fn with_tags(self, tags: Vec<String>) -> Self {
        GetSelector {
            tags: merge(self.tags, tags),
            .. self
        }
    }

    /// Restrict to channels that support polling with the acceptable
    /// period
    pub fn with_poll(self, period: Period) -> Self {
        GetSelector {
            poll: Period::and_option(self.poll, Some(period)),
            .. self
        }
    }

    /// Restrict to channels that support trigger with the acceptable
    /// period
    pub fn with_trigger(self, period: Period) -> Self {
        GetSelector {
            trigger: Period::and_option(self.trigger, Some(period)),
            .. self
        }
    }

    /// Restrict to channels that are accepted by two selector.
    pub fn and(self, other: Self) -> Self {
        GetSelector {
            id: self.id.and(other.id),
            parent: self.parent.and(other.parent),
            tags: merge(self.tags, other.tags),
            kind: self.kind.and(other.kind),
            poll: Period::and_option(self.poll, other.poll),
            trigger: Period::and_option(self.trigger, other.trigger),
            private: (),
        }
    }

    /// Determine if a channel is matched by this selector.
    pub fn matches(&self, channel: &Channel<Get>) -> bool {
        if !self.id.matches(&channel.id) {
            return false;
        }
        if !self.parent.matches(&channel.node) {
            return false;
        }
        if !self.kind.matches(&channel.mechanism.kind) {
            return false;
        }
        if !Period::matches_option(&self.poll, &channel.mechanism.poll) {
            return false;
        }
        if !Period::matches_option(&self.trigger, &channel.mechanism.trigger) {
            return false;
        }
        if !has_selected_tags(&self.tags, &channel.tags) {
            return false;
        }
        return true;
    }
}

/// A selector for one or more output channels.
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct SetSelector {
    /// If `Exactly(id)`, return only the channel with the corresponding id.
    #[serde(default)]
    pub id: Exactly<Id<Set>>,

    /// If `Exactly(id)`, return only channels that are immediate children
    /// of node `id`.
    #[serde(default)]
    pub parent: Exactly<Id<NodeId>>,

    ///  Restrict results to channels that have all the tags in `tags`.
    #[serde(default)]
    pub tags: Vec<String>,

    /// If `Exactly(k)`, restrict results to channels that accept values
    /// of kind `k`.
    #[serde(default)]
    pub kind: Exactly<ChannelKind>,

    /// If `Some(r)`, restrict results to channels that support pushing
    /// with the acceptable period.
    #[serde(default)]
    pub push: Option<Period>,

    /// Make sure that we can't instantiate from another crate.
    #[serde(default, skip_serializing)]
    private: (),
}

impl SetSelector {
    /// Create a new selector that accepts all input channels.
    pub fn new() -> Self {
        SetSelector::default()
    }

    /// Selector to a channel with a specific id.
    pub fn with_id(self, id: Id<Set>) -> Self {
        SetSelector {
            id: self.id.and(Exactly::Exactly(id)),
            .. self
        }
    }

    /// Selector to channels with a specific parent.
    pub fn with_parent(self, id: Id<NodeId>) -> Self {
        SetSelector {
            parent: self.parent.and(Exactly::Exactly(id)),
            .. self
        }
    }

    /// Selector to channels with a specific kind.
    pub fn with_kind(self, kind: ChannelKind) -> Self {
        SetSelector {
            kind: self.kind.and(Exactly::Exactly(kind)),
            .. self
        }
    }

    ///  Restrict to channels that have all the tags in `tags`.
    pub fn with_tags(self, tags: Vec<String>) -> Self {
        SetSelector {
            tags: merge(self.tags, tags),
            .. self
        }
    }

    /// Restrict to channels that support push with the acceptable
    /// period
    pub fn with_push(self, period: Period) -> Self {
        SetSelector {
            push: Period::and_option(self.push, Some(period)),
            .. self
        }
    }

    /// Restrict results to channels that are accepted by two selector.
    pub fn and(self, other: Self) -> Self {
        SetSelector {
            id: self.id.and(other.id),
            parent: self.parent.and(other.parent),
            tags: merge(self.tags, other.tags),
            kind: self.kind.and(other.kind),
            push: Period::and_option(self.push, other.push),
            private: (),
        }
    }

    /// Determine if a channel is matched by this selector.
    pub fn matches(&self, channel: &Channel<Set>) -> bool {
        if !self.id.matches(&channel.id) {
            return false;
        }
        if !self.parent.matches(&channel.node) {
            return false;
        }
        if !self.kind.matches(&channel.mechanism.kind) {
            return false;
        }
        if !Period::matches_option(&self.push, &channel.mechanism.push) {
            return false;
        }
        if !has_selected_tags(&self.tags, &channel.tags) {
            return false;
        }
        return true;
    }
}

/// An acceptable interval of time.
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct Period {
    #[serde(default)]
    pub min: Option<values::ValDuration>,
    #[serde(default)]
    pub max: Option<values::ValDuration>,
}
impl Period {
    pub fn and(self, other: Self) -> Self {
        let min = match (self.min, other.min) {
            (None, x@_) => x,
            (x@_, None) => x,
            (Some(min1), Some(min2)) => Some(cmp::max(min1, min2))
        };
        let max = match (self.max, other.max) {
            (None, x@_) => x,
            (x@_, None) => x,
            (Some(max1), Some(max2)) => Some(cmp::min(max1, max2))
        };
        Period {
            min: min,
            max: max
        }
    }

    pub fn and_option(a: Option<Self>, b: Option<Self>) -> Option<Self> {
        match (a, b) {
            (None, x@_) => x,
            (x@_, None) => x,
            (Some(a), Some(b)) => Some(a.and(b))
        }
    }

    pub fn matches(&self, duration: &values::ValDuration) -> bool {
        if let Some(ref min) = self.min {
            if min > duration {
                return false;
            }
        }
        if let Some(ref max) = self.max {
            if max < duration {
                return false;
            }
        }
        return true;
    }

    pub fn matches_option(period: &Option<Self>, duration: &Option<values::ValDuration>) -> bool {
        match (period, duration) {
            (&Some(ref period), &Some(ref duration))
                if !period.matches(duration) => false,
            (&Some(_), &None) => false,
            _ => true,
        }
    }
}

fn has_selected_tags(actual: &Vec<String>, requested: &Vec<String>) -> bool {
    for tag in &*actual {
        if requested.iter().find(|x| *x == tag).is_none() {
            return false;
        }
    }
    return true;
}
<|endoftext|>


<commit_before>use std::str::FromStr;
use std::fmt::{self, Display};

pub mod read;
use read::Error;

pub mod write;

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum TimescaleUnit {
    S, MS, US, NS, PS, FS,
}

impl FromStr for TimescaleUnit {
    type Err = Error;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        use self::TimescaleUnit::*;
        match s {
            "s"  => Ok(S),
            "ms" => Ok(MS),
            "us" => Ok(US),
            "ns" => Ok(NS),
            "ps" => Ok(PS),
            "fs" => Ok(FS),
            _ => Err(Error::Parse("Invalid timescale unit"))
        }
    }
}

impl Display for TimescaleUnit {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::TimescaleUnit::*;
        write!(f, "{}", match *self {
            S  => "s",
            MS => "ms",
            US => "us",
            NS => "ns",
            PS => "ps",
            FS => "fs",
        })
    }
}

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Value {
    V0,
    V1,
    X,
    Z,
}

impl Value {
    fn parse(v: u8) -> Result<Value, Error> {
        use Value::*;
        match v {
            b'0' => Ok(V0),
            b'1' => Ok(V1),
            b'x' | b'X' => Ok(X),
            b'z' | b'Z' => Ok(Z),
            _ => Err(Error::Parse("Invalid wire value"))
        }
    }
}

impl FromStr for Value {
    type Err = Error;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Value::parse(*s.as_bytes().get(0).unwrap_or(&b' '))
    }
}

impl Display for Value {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use Value::*;
        write!(f, "{}", match *self {
            V0  => "0",
            V1 => "1",
            X => "x",
            Z => "z",
        })
    }
}

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum ScopeType {
    Module,
    Task,
    Function,
    Begin,
    Fork,
}

impl FromStr for ScopeType {
    type Err = Error;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        use self::ScopeType::*;
        match s {
            "module" => Ok(Module),
            "task" => Ok(Task),
            "function" => Ok(Function),
            "begin" => Ok(Begin),
            "fork" => Ok(Fork),
            _ => Err(Error::Parse("Invalid scope type"))
        }
    }
}

impl Display for ScopeType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::ScopeType::*;
        write!(f, "{}", match *self {
            Module => "module",
            Task  => "task",
            Function => "function",
            Begin  => "begin",
            Fork  => "fork",
        })
    }
}

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum VarType {
    Wire,
}

impl FromStr for VarType {
    type Err = Error;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        use self::VarType::*;
        match s {
            "wire" => Ok(Wire),
            _ => Err(Error::Parse("Invalid scope type"))
        }
    }
}

impl Display for VarType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::VarType::*;
        write!(f, "{}", match *self {
            Wire => "wire",
        })
    }
}

#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct IdCode(u32);

impl IdCode {
    fn new(v: &[u8]) -> Result<IdCode, Error> {
        let mut result = 0u32;
        for &i in v {
            result = result << 7 | ((i - b'!') as u32);
        }
        Ok(IdCode(result))
    }
}

impl FromStr for IdCode {
    type Err = Error;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        IdCode::new(s.as_bytes())
    }
}

impl Display for IdCode {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut i = self.0;
        loop {
            try!(write!(f, "{}", ((i&0x7f) as u8 + b'!') as char));
            i = i >> 7;
            if i == 0 { break; }
        }
        Ok(())
    }
}

#[derive(Debug, Clone)]
pub struct Scope {
    pub scope_type: ScopeType,
    pub identifier: String,
    pub children: Vec<ScopeItem>
}

impl Default for Scope {
    fn default() -> Scope {
        Scope { scope_type: ScopeType::Module, identifier: "".to_string(), children: Vec::new() }
    }
}

#[derive(Debug, Clone)]
pub struct Var {
    pub var_type: VarType,
    pub size: u32,
    pub code: IdCode,
    pub reference: String,
}

#[derive(Debug, Clone)]
pub enum ScopeItem {
    Scope(Scope),
    Var(Var),
}

#[derive(Debug, PartialEq, Clone)]
pub enum Command {
    Comment(String),
    Date(String),
    Version(String),
    Timescale(u32, TimescaleUnit),
    ScopeDef(ScopeType, String),
    Upscope,
    VarDef(VarType, u32, IdCode, String),
    Enddefinitions,
    Timestamp(u64),
    ChangeScalar(IdCode, Value),
    ChangeVector(IdCode, Vec<Value>),
    ChangeReal(IdCode, f64),
    Begin(SimulationCommand),
    End(SimulationCommand)
}

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum SimulationCommand {
    Dumpall,
    Dumpoff,
    Dumpon,
    Dumpvars,
}

impl Display for SimulationCommand {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::SimulationCommand::*;
        write!(f, "{}", match *self {
            Dumpall  => "dumpall",
            Dumpoff  => "dumpoff",
            Dumpon   => "dumpon",
            Dumpvars => "dumpvars",
        })
    }
}

#[derive(Debug, Default)]
pub struct Header {
    pub comment: Option<String>,
    pub date: Option<String>,
    pub version: Option<String>,
    pub timescale: Option<(u32, TimescaleUnit)>,
    pub scope: Scope,
}
<commit_msg>Create IdCode from u32<commit_after>use std::str::FromStr;
use std::fmt::{self, Display};

pub mod read;
use read::Error;

pub mod write;

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum TimescaleUnit {
    S, MS, US, NS, PS, FS,
}

impl FromStr for TimescaleUnit {
    type Err = Error;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        use self::TimescaleUnit::*;
        match s {
            "s"  => Ok(S),
            "ms" => Ok(MS),
            "us" => Ok(US),
            "ns" => Ok(NS),
            "ps" => Ok(PS),
            "fs" => Ok(FS),
            _ => Err(Error::Parse("Invalid timescale unit"))
        }
    }
}

impl Display for TimescaleUnit {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::TimescaleUnit::*;
        write!(f, "{}", match *self {
            S  => "s",
            MS => "ms",
            US => "us",
            NS => "ns",
            PS => "ps",
            FS => "fs",
        })
    }
}

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Value {
    V0,
    V1,
    X,
    Z,
}

impl Value {
    fn parse(v: u8) -> Result<Value, Error> {
        use Value::*;
        match v {
            b'0' => Ok(V0),
            b'1' => Ok(V1),
            b'x' | b'X' => Ok(X),
            b'z' | b'Z' => Ok(Z),
            _ => Err(Error::Parse("Invalid wire value"))
        }
    }
}

impl FromStr for Value {
    type Err = Error;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Value::parse(*s.as_bytes().get(0).unwrap_or(&b' '))
    }
}

impl Display for Value {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use Value::*;
        write!(f, "{}", match *self {
            V0  => "0",
            V1 => "1",
            X => "x",
            Z => "z",
        })
    }
}

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum ScopeType {
    Module,
    Task,
    Function,
    Begin,
    Fork,
}

impl FromStr for ScopeType {
    type Err = Error;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        use self::ScopeType::*;
        match s {
            "module" => Ok(Module),
            "task" => Ok(Task),
            "function" => Ok(Function),
            "begin" => Ok(Begin),
            "fork" => Ok(Fork),
            _ => Err(Error::Parse("Invalid scope type"))
        }
    }
}

impl Display for ScopeType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::ScopeType::*;
        write!(f, "{}", match *self {
            Module => "module",
            Task  => "task",
            Function => "function",
            Begin  => "begin",
            Fork  => "fork",
        })
    }
}

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum VarType {
    Wire,
}

impl FromStr for VarType {
    type Err = Error;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        use self::VarType::*;
        match s {
            "wire" => Ok(Wire),
            _ => Err(Error::Parse("Invalid scope type"))
        }
    }
}

impl Display for VarType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::VarType::*;
        write!(f, "{}", match *self {
            Wire => "wire",
        })
    }
}

#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct IdCode(u32);

impl IdCode {
    fn new(v: &[u8]) -> Result<IdCode, Error> {
        let mut result = 0u32;
        for &i in v {
            result = result << 7 | ((i - b'!') as u32);
        }
        Ok(IdCode(result))
    }
}

impl FromStr for IdCode {
    type Err = Error;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        IdCode::new(s.as_bytes())
    }
}

impl From<u32> for IdCode {
    fn from(i: u32) -> IdCode { IdCode(i) }
}

impl Display for IdCode {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut i = self.0;
        loop {
            try!(write!(f, "{}", ((i&0x7f) as u8 + b'!') as char));
            i = i >> 7;
            if i == 0 { break; }
        }
        Ok(())
    }
}

#[derive(Debug, Clone)]
pub struct Scope {
    pub scope_type: ScopeType,
    pub identifier: String,
    pub children: Vec<ScopeItem>
}

impl Default for Scope {
    fn default() -> Scope {
        Scope { scope_type: ScopeType::Module, identifier: "".to_string(), children: Vec::new() }
    }
}

#[derive(Debug, Clone)]
pub struct Var {
    pub var_type: VarType,
    pub size: u32,
    pub code: IdCode,
    pub reference: String,
}

#[derive(Debug, Clone)]
pub enum ScopeItem {
    Scope(Scope),
    Var(Var),
}

#[derive(Debug, PartialEq, Clone)]
pub enum Command {
    Comment(String),
    Date(String),
    Version(String),
    Timescale(u32, TimescaleUnit),
    ScopeDef(ScopeType, String),
    Upscope,
    VarDef(VarType, u32, IdCode, String),
    Enddefinitions,
    Timestamp(u64),
    ChangeScalar(IdCode, Value),
    ChangeVector(IdCode, Vec<Value>),
    ChangeReal(IdCode, f64),
    Begin(SimulationCommand),
    End(SimulationCommand)
}

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum SimulationCommand {
    Dumpall,
    Dumpoff,
    Dumpon,
    Dumpvars,
}

impl Display for SimulationCommand {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::SimulationCommand::*;
        write!(f, "{}", match *self {
            Dumpall  => "dumpall",
            Dumpoff  => "dumpoff",
            Dumpon   => "dumpon",
            Dumpvars => "dumpvars",
        })
    }
}

#[derive(Debug, Default)]
pub struct Header {
    pub comment: Option<String>,
    pub date: Option<String>,
    pub version: Option<String>,
    pub timescale: Option<(u32, TimescaleUnit)>,
    pub scope: Scope,
}
<|endoftext|>


<commit_before>use std::io::{self, Write};
use std::f32::consts::PI;
use std::f32::INFINITY;

#[derive(Copy, Clone, Debug)]
pub struct Position(f32, f32);

impl Position {
    pub fn origin() -> Position {
        Position(0.0, 0.0)
    }
}

#[derive(Copy, Clone, Debug)]
pub struct Degree(pub f32);

#[derive(Copy, Clone, Debug)]
pub struct Radiant(pub f32);

impl Into<Degree> for Radiant {
    fn into(self) -> Degree {
        Degree(self.0 * 180.0 / PI)
    }
}

impl Into<Degree> for f32 {
    fn into(self) -> Degree {
        Degree(self)
    }
}

impl Into<Radiant> for Degree {
    fn into(self) -> Radiant {
        Radiant(self.0 * PI / 180.0)
    }
}

#[derive(Copy, Clone, Debug)]
pub struct Distance(f32);

impl Into<Distance> for f32 {
    fn into(self) -> Distance {
        Distance(self)
    }
}

pub trait Turtle {
    /// Move turtle forward by specified `distance`.
    fn forward<T: Into<Distance>>(&mut self, distance: T);

    /// Move turtle backward by specified `distance`.
    fn backward<T: Into<Distance>>(&mut self, distance: T);

    /// Turn turtle right by `angle` degree.
    fn right<T: Into<Degree>>(&mut self, angle: T);

    /// Turn turtle left by `angle` degree.
    fn left<T: Into<Degree>>(&mut self, angle: T);

    /// Put the pen down.
    fn pendown(&mut self);

    /// Put the pen up.
    fn penup(&mut self);

    fn goto(&mut self, pos: Position);

    fn home(&mut self) {
        self.goto(Position::origin());
    }

    /// Push current turtle state on stack.
    fn push(&mut self);

    /// Restore previously saved turtle state.
    fn pop(&mut self);
}

#[derive(Clone)]
struct TurtleState {
    pos: Position,
    angle: Degree,
    pendown: bool,
}

impl TurtleState {
    fn new() -> TurtleState {
        TurtleState {
            pos: Position::origin(),
            angle: Degree(0.0),
            pendown: false,
        }
    }
}

pub struct Canvas {
    states: Vec<TurtleState>,
    paths: Vec<Vec<Position>>,
}

impl Canvas {
    pub fn new() -> Canvas {
        Canvas {
            states: vec![TurtleState::new()],
            paths: vec![],
        }
    }

    #[inline]
    fn current_state_mut(&mut self) -> &mut TurtleState {
        self.states.last_mut().unwrap()
    }

    #[inline]
    fn current_state(&self) -> &TurtleState {
        self.states.last().unwrap()
    }

    #[inline]
    fn direction(&self, distance: Distance) -> (f32, f32) {
        let state = self.current_state();
        let rad: Radiant = state.angle.into();
        let (sin, cos) = rad.0.sin_cos();
        let dx = cos * distance.0;
        let dy = sin * distance.0;
        (dx, dy)
    }

    fn line_to(&mut self, dst: Position) {
        self.paths.last_mut().unwrap().push(dst);
    }

    fn move_to(&mut self, dst: Position) {
        if self.paths.is_empty() {
            self.paths.push(vec![dst]);
        } else {
            let begin_new_path = self.paths.last().unwrap().len() > 1;
            if begin_new_path {
                self.paths.push(vec![dst]);
            } else {
                // Replace first path element with current position
                self.paths.last_mut().unwrap()[0] = dst;
            }
        }
    }

    /// Saves the turtle graphic as Scalable Vector Graphic (SVG).
    pub fn save_svg<W: Write>(&self, wr: &mut W) -> io::Result<()> {
        // Determine extend of canvas
        let mut min = Position(INFINITY, INFINITY);
        let mut max = Position(-INFINITY, -INFINITY);
        for path in self.paths.iter() {
            for pt in path.iter() {
                min.0 = min.0.min(pt.0).min(pt.0);
                max.0 = max.0.max(pt.0).max(pt.0);

                min.1 = min.1.min(pt.1).min(pt.1);
                max.1 = max.1.max(pt.1).max(pt.1);
            }
        }
        let width = (max.0 - min.0).abs().max(10.0);
        let height = (max.1 - min.1).abs().max(10.0);

        println!("width: {}", width);
        println!("height: {}", height);

        let top_left = Position(min.0 - width / 10.0, min.1 - height / 10.0);
        let bottom_right = Position(max.0 + width / 10.0, max.1 + height / 10.0);

        try!(writeln!(wr,
                      r#"<?xml version="1.0" encoding="UTF-8"?>
                <svg xmlns="http://www.w3.org/2000/svg"
                version="1.1" baseProfile="full"
                viewBox="{} {} {} {}">"#,
                      top_left.0.ceil(),
                      top_left.1.ceil(),
                      bottom_right.0.ceil(),
                      bottom_right.1.ceil()));

         try!(writeln!(wr, r#"<g stroke="black" stroke-width="1" fill="none">"#));

        for path in self.paths.iter() {
            if let Some((head, tail)) = path.split_first() {
                try!(write!(wr, r#"<path d="M{} {}"#, head.0.round(), head.1.round()));
                for pos in tail {
                    try!(write!(wr, r#" L{} {}"#, pos.0.round(), pos.1.round()));
                }
                try!(writeln!(wr, r#"" />"#));
            }
        }
        try!(writeln!(wr, r#"</g>"#));

        writeln!(wr, "</svg>")
    }
}

impl Turtle for Canvas {
    /// Move turtle forward by specified `distance`.
    fn forward<T: Into<Distance>>(&mut self, distance: T) {
        let (dx, dy) = self.direction(distance.into());
        let pendown = self.current_state().pendown;
        let src: Position = self.current_state().pos;
        let dst = Position(src.0 + dx, src.1 + dy);
        if pendown {
            self.line_to(dst);
        }
        self.current_state_mut().pos = dst;
    }

    /// Move turtle backward by specified `distance`.
    fn backward<T: Into<Distance>>(&mut self, distance: T) {
        let distance: Distance = distance.into();
        self.forward(Distance(-distance.0))
    }

    /// Turn turtle right by `angle` degrees.
    fn right<T: Into<Degree>>(&mut self, angle: T) {
        let angle: Degree = angle.into();
        self.current_state_mut().angle.0 += angle.0;
    }

    /// Turn turtle left by `angle` degrees.
    fn left<T: Into<Degree>>(&mut self, angle: T) {
        let angle: Degree = angle.into();
        self.current_state_mut().angle.0 -= angle.0;
    }

    /// Put the pen down.
    fn pendown(&mut self) {
        let pos = self.current_state().pos;
        self.move_to(pos);
        self.current_state_mut().pendown = true;
    }

    /// Put the pen up.
    fn penup(&mut self) {
        self.current_state_mut().pendown = false;
    }

    /// Positions the turtle exactly at `position`.
    fn goto(&mut self, position: Position) {
        self.current_state_mut().pos = position;
        self.move_to(position);
    }

    /// Push current turtle state on stack.
    fn push(&mut self) {
        let state = self.current_state_mut().clone();
        self.states.push(state);
    }

    /// Restore previously saved turtle state.
    fn pop(&mut self) {
        self.states.pop();
        let pos = self.current_state().pos;
        self.move_to(pos);
    }
}
<commit_msg>Scale canvas size and stroke width<commit_after>use std::io::{self, Write};
use std::f32::consts::PI;
use std::f32::INFINITY;

#[derive(Copy, Clone, Debug)]
pub struct Position(f32, f32);

impl Position {
    pub fn origin() -> Position {
        Position(0.0, 0.0)
    }
}

#[derive(Copy, Clone, Debug)]
pub struct Degree(pub f32);

#[derive(Copy, Clone, Debug)]
pub struct Radiant(pub f32);

impl Into<Degree> for Radiant {
    fn into(self) -> Degree {
        Degree(self.0 * 180.0 / PI)
    }
}

impl Into<Degree> for f32 {
    fn into(self) -> Degree {
        Degree(self)
    }
}

impl Into<Radiant> for Degree {
    fn into(self) -> Radiant {
        Radiant(self.0 * PI / 180.0)
    }
}

#[derive(Copy, Clone, Debug)]
pub struct Distance(f32);

impl Into<Distance> for f32 {
    fn into(self) -> Distance {
        Distance(self)
    }
}

pub trait Turtle {
    /// Move turtle forward by specified `distance`.
    fn forward<T: Into<Distance>>(&mut self, distance: T);

    /// Move turtle backward by specified `distance`.
    fn backward<T: Into<Distance>>(&mut self, distance: T);

    /// Turn turtle right by `angle` degree.
    fn right<T: Into<Degree>>(&mut self, angle: T);

    /// Turn turtle left by `angle` degree.
    fn left<T: Into<Degree>>(&mut self, angle: T);

    /// Put the pen down.
    fn pendown(&mut self);

    /// Put the pen up.
    fn penup(&mut self);

    fn goto(&mut self, pos: Position);

    fn home(&mut self) {
        self.goto(Position::origin());
    }

    /// Push current turtle state on stack.
    fn push(&mut self);

    /// Restore previously saved turtle state.
    fn pop(&mut self);
}

#[derive(Clone)]
struct TurtleState {
    pos: Position,
    angle: Degree,
    pendown: bool,
}

impl TurtleState {
    fn new() -> TurtleState {
        TurtleState {
            pos: Position::origin(),
            angle: Degree(0.0),
            pendown: false,
        }
    }
}

pub struct Canvas {
    states: Vec<TurtleState>,
    paths: Vec<Vec<Position>>,
}

impl Canvas {
    pub fn new() -> Canvas {
        Canvas {
            states: vec![TurtleState::new()],
            paths: vec![],
        }
    }

    #[inline]
    fn current_state_mut(&mut self) -> &mut TurtleState {
        self.states.last_mut().unwrap()
    }

    #[inline]
    fn current_state(&self) -> &TurtleState {
        self.states.last().unwrap()
    }

    #[inline]
    fn direction(&self, distance: Distance) -> (f32, f32) {
        let state = self.current_state();
        let rad: Radiant = state.angle.into();
        let (sin, cos) = rad.0.sin_cos();
        let dx = cos * distance.0;
        let dy = sin * distance.0;
        (dx, dy)
    }

    fn line_to(&mut self, dst: Position) {
        self.paths.last_mut().unwrap().push(dst);
    }

    fn move_to(&mut self, dst: Position) {
        if self.paths.is_empty() {
            self.paths.push(vec![dst]);
        } else {
            let begin_new_path = self.paths.last().unwrap().len() > 1;
            if begin_new_path {
                self.paths.push(vec![dst]);
            } else {
                // Replace first path element with current position
                self.paths.last_mut().unwrap()[0] = dst;
            }
        }
    }

    /// Saves the turtle graphic as Scalable Vector Graphic (SVG).
    pub fn save_svg<W: Write>(&self, wr: &mut W) -> io::Result<()> {
        // Determine extend of canvas
        let mut min = Position(INFINITY, INFINITY);
        let mut max = Position(-INFINITY, -INFINITY);
        for path in self.paths.iter() {
            for pt in path.iter() {
                min.0 = min.0.min(pt.0).min(pt.0);
                max.0 = max.0.max(pt.0).max(pt.0);

                min.1 = min.1.min(pt.1).min(pt.1);
                max.1 = max.1.max(pt.1).max(pt.1);
            }
        }
        let (min_width, min_height) = (100.0, 100.0);
        let width = (max.0 - min.0).abs().max(min_width);
        let height = (max.1 - min.1).abs().max(min_height);
        let border_percent = 0.1;

        let top_left = Position(min.0 - border_percent*width, min.1 - border_percent*height);

        let scale = 1.0 + 2.0*border_percent;

        try!(writeln!(wr,
                      r#"<?xml version="1.0" encoding="UTF-8"?>
                <svg xmlns="http://www.w3.org/2000/svg"
                version="1.1" baseProfile="full"
                viewBox="{} {} {} {}">"#,
                      top_left.0,
                      top_left.1,
                      scale * width,
                      scale * height));

        // use a stroke width of 0.1% of the width or height of the canvas
        let stroke_width = scale * width.max(height) / 1000.0;
        try!(writeln!(wr, r#"<g stroke="black" stroke-width="{}" fill="none">"#, stroke_width));

        for path in self.paths.iter() {
            if let Some((head, tail)) = path.split_first() {
                try!(write!(wr, r#"<path d="M{} {}"#, head.0, head.1));
                for pos in tail {
                    try!(write!(wr, r#" L{} {}"#, pos.0, pos.1));
                }
                try!(writeln!(wr, r#"" />"#));
            }
        }
        try!(writeln!(wr, r#"</g>"#));

        writeln!(wr, "</svg>")
    }
}

impl Turtle for Canvas {
    /// Move turtle forward by specified `distance`.
    fn forward<T: Into<Distance>>(&mut self, distance: T) {
        let (dx, dy) = self.direction(distance.into());
        let pendown = self.current_state().pendown;
        let src: Position = self.current_state().pos;
        let dst = Position(src.0 + dx, src.1 + dy);
        if pendown {
            self.line_to(dst);
        }
        self.current_state_mut().pos = dst;
    }

    /// Move turtle backward by specified `distance`.
    fn backward<T: Into<Distance>>(&mut self, distance: T) {
        let distance: Distance = distance.into();
        self.forward(Distance(-distance.0))
    }

    /// Turn turtle right by `angle` degrees.
    fn right<T: Into<Degree>>(&mut self, angle: T) {
        let angle: Degree = angle.into();
        self.current_state_mut().angle.0 += angle.0;
    }

    /// Turn turtle left by `angle` degrees.
    fn left<T: Into<Degree>>(&mut self, angle: T) {
        let angle: Degree = angle.into();
        self.current_state_mut().angle.0 -= angle.0;
    }

    /// Put the pen down.
    fn pendown(&mut self) {
        let pos = self.current_state().pos;
        self.move_to(pos);
        self.current_state_mut().pendown = true;
    }

    /// Put the pen up.
    fn penup(&mut self) {
        self.current_state_mut().pendown = false;
    }

    /// Positions the turtle exactly at `position`.
    fn goto(&mut self, position: Position) {
        self.current_state_mut().pos = position;
        self.move_to(position);
    }

    /// Push current turtle state on stack.
    fn push(&mut self) {
        let state = self.current_state_mut().clone();
        self.states.push(state);
    }

    /// Restore previously saved turtle state.
    fn pop(&mut self) {
        self.states.pop();
        let pos = self.current_state().pos;
        self.move_to(pos);
    }
}
<|endoftext|>


<commit_before>//! This library implements basic processing of JavaScript sourcemaps.
//!
//! # Installation
//!
//! The crate is called sourcemap and you can depend on it via cargo:
//!
//! ```toml
//! [dependencies]
//! sourcemap = "*"
//! ```
//!
//! If you want to use the git version:
//!
//! ```toml
//! [dependencies.sourcemap]
//! git = "https://github.com/getsentry/rust-sourcemap.git"
//! ```
//!
//! # Basic Operation
//!
//! This crate can load JavaScript sourcemaps from JSON files.  It uses
//! `serde` for parsing of the JSON data.  Due to the nature of sourcemaps
//! the entirety of the file must be loaded into memory which can be quite
//! memory intensive.
//!
//! Usage:
//!
//! ```rust
//! use sourcemap::SourceMap;
//! let input: &[_] = b"{
//!     \"version\":3,
//!     \"sources\":[\"coolstuff.js\"],
//!     \"names\":[\"x\",\"alert\"],
//!     \"mappings\":\"AAAA,GAAIA,GAAI,EACR,IAAIA,GAAK,EAAG,CACVC,MAAM\"
//! }";
//! let sm = SourceMap::from_reader(input).unwrap();
//! let token = sm.lookup_token(0, 0).unwrap(); // line-number and column
//! println!("token: {}", token);
//! ```
//!
//! # Features
//!
//! Functionality of the crate can be turned on and off by feature flags.  This is the
//! current list of feature flags:
//!
//! * `ram_bundle`: turns on RAM bundle support
//!
#[warn(missing_docs)]
mod macros;

pub use crate::builder::SourceMapBuilder;
pub use crate::decoder::{decode, decode_data_url, decode_slice};
pub use crate::detector::{
    is_sourcemap, is_sourcemap_slice, locate_sourcemap_reference, locate_sourcemap_reference_slice,
    SourceMapRef,
};
pub use crate::errors::{Error, Result};
pub use crate::hermes::SourceMapHermes;
pub use crate::sourceview::SourceView;
pub use crate::types::{
    DecodedMap, RawToken, RewriteOptions, SourceMap, SourceMapIndex, SourceMapSection,
    SourceMapSectionIter, Token, TokenIter,
};
pub use crate::utils::make_relative_path;

mod builder;
mod decoder;
mod detector;
mod encoder;
mod errors;
mod hermes;
mod jsontypes;
mod sourceview;
mod types;
mod utils;

#[cfg(feature = "ram_bundle")]
pub mod ram_bundle;
pub mod vlq;
<commit_msg>export all the Iterator types<commit_after>//! This library implements basic processing of JavaScript sourcemaps.
//!
//! # Installation
//!
//! The crate is called sourcemap and you can depend on it via cargo:
//!
//! ```toml
//! [dependencies]
//! sourcemap = "*"
//! ```
//!
//! If you want to use the git version:
//!
//! ```toml
//! [dependencies.sourcemap]
//! git = "https://github.com/getsentry/rust-sourcemap.git"
//! ```
//!
//! # Basic Operation
//!
//! This crate can load JavaScript sourcemaps from JSON files.  It uses
//! `serde` for parsing of the JSON data.  Due to the nature of sourcemaps
//! the entirety of the file must be loaded into memory which can be quite
//! memory intensive.
//!
//! Usage:
//!
//! ```rust
//! use sourcemap::SourceMap;
//! let input: &[_] = b"{
//!     \"version\":3,
//!     \"sources\":[\"coolstuff.js\"],
//!     \"names\":[\"x\",\"alert\"],
//!     \"mappings\":\"AAAA,GAAIA,GAAI,EACR,IAAIA,GAAK,EAAG,CACVC,MAAM\"
//! }";
//! let sm = SourceMap::from_reader(input).unwrap();
//! let token = sm.lookup_token(0, 0).unwrap(); // line-number and column
//! println!("token: {}", token);
//! ```
//!
//! # Features
//!
//! Functionality of the crate can be turned on and off by feature flags.  This is the
//! current list of feature flags:
//!
//! * `ram_bundle`: turns on RAM bundle support
//!
#[warn(missing_docs)]
mod macros;

pub use crate::builder::SourceMapBuilder;
pub use crate::decoder::{decode, decode_data_url, decode_slice};
pub use crate::detector::{
    is_sourcemap, is_sourcemap_slice, locate_sourcemap_reference, locate_sourcemap_reference_slice,
    SourceMapRef,
};
pub use crate::errors::{Error, Result};
pub use crate::hermes::SourceMapHermes;
pub use crate::sourceview::SourceView;
pub use crate::types::{
    DecodedMap, IndexIter, NameIter, RawToken, RewriteOptions, SourceContentsIter, SourceIter,
    SourceMap, SourceMapIndex, SourceMapSection, SourceMapSectionIter, Token, TokenIter,
};
pub use crate::utils::make_relative_path;

mod builder;
mod decoder;
mod detector;
mod encoder;
mod errors;
mod hermes;
mod jsontypes;
mod sourceview;
mod types;
mod utils;

#[cfg(feature = "ram_bundle")]
pub mod ram_bundle;
pub mod vlq;
<|endoftext|>


<commit_before>#![warn(rust_2018_idioms)]
extern crate conduit;
extern crate route_recognizer as router;

use std::collections::hash_map::{Entry, HashMap};
use std::error::Error;
use std::fmt;

use conduit::{box_error, Handler, HandlerResult, Method, RequestExt};
use router::{Match, Router};

#[derive(Default)]
pub struct RouteBuilder {
    routers: HashMap<Method, Router<WrappedHandler>>,
}

#[derive(Clone, Copy)]
struct RoutePattern(&'static str);

pub struct WrappedHandler {
    pattern: RoutePattern,
    handler: Box<dyn Handler>,
}

#[derive(Debug)]
pub struct RouterError(String);

impl RouteBuilder {
    pub fn new() -> RouteBuilder {
        RouteBuilder {
            routers: HashMap::new(),
        }
    }

    #[allow(clippy::borrowed_box)]
    pub fn recognize<'a>(
        &'a self,
        method: &Method,
        path: &str,
    ) -> Result<Match<&WrappedHandler>, RouterError> {
        match self.routers.get(method) {
            Some(router) => router.recognize(path),
            None => Err(format!("No router found for {:?}", method)),
        }
        .map_err(RouterError)
    }

    pub fn map<'a, H: Handler>(
        &'a mut self,
        method: Method,
        pattern: &'static str,
        handler: H,
    ) -> &'a mut RouteBuilder {
        {
            let router = match self.routers.entry(method) {
                Entry::Occupied(e) => e.into_mut(),
                Entry::Vacant(e) => e.insert(Router::new()),
            };
            let wrapped_handler = WrappedHandler {
                pattern: RoutePattern(pattern),
                handler: Box::new(handler)
            };
            router.add(pattern, wrapped_handler);
        }
        self
    }

    pub fn get<'a, H: Handler>(&'a mut self, pattern: &'static str, handler: H) -> &'a mut RouteBuilder {
        self.map(Method::GET, pattern, handler)
    }

    pub fn post<'a, H: Handler>(&'a mut self, pattern: &'static str, handler: H) -> &'a mut RouteBuilder {
        self.map(Method::POST, pattern, handler)
    }

    pub fn put<'a, H: Handler>(&'a mut self, pattern: &'static str, handler: H) -> &'a mut RouteBuilder {
        self.map(Method::PUT, pattern, handler)
    }

    pub fn delete<'a, H: Handler>(&'a mut self, pattern: &'static str, handler: H) -> &'a mut RouteBuilder {
        self.map(Method::DELETE, pattern, handler)
    }

    pub fn head<'a, H: Handler>(&'a mut self, pattern: &'static str, handler: H) -> &'a mut RouteBuilder {
        self.map(Method::HEAD, pattern, handler)
    }
}

impl conduit::Handler for RouteBuilder {
    fn call(&self, request: &mut dyn RequestExt) -> HandlerResult {
        let m = {
            let method = request.method();
            let path = request.path();

            match self.recognize(&method, path) {
                Ok(m) => m,
                Err(e) => return Err(box_error(e)),
            }
        };

        {
            let extensions = request.mut_extensions();
            extensions.insert(m.handler.pattern);
            extensions.insert(m.params.clone());
        }

        (*m.handler.handler).call(request)
    }
}

impl Error for RouterError {
    fn description(&self) -> &str {
        &self.0
    }
}

impl fmt::Display for RouterError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Display::fmt(&self.0, f)
    }
}

pub trait RequestParams<'a> {
    fn params(self) -> &'a router::Params;
}

pub fn params(req: &dyn RequestExt) -> &router::Params {
    req.extensions()
        .find::<router::Params>()
        .expect("Missing params")
}

impl<'a> RequestParams<'a> for &'a (dyn RequestExt + 'a) {
    fn params(self) -> &'a router::Params {
        params(self)
    }
}

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

    use std::io;
    use std::net::SocketAddr;

    use {RequestParams, RouteBuilder, RoutePattern};

    use self::conduit_test::ResponseExt;
    use conduit::{
        Body, Extensions, Handler, HeaderMap, Host, Method, Response, Scheme, StatusCode, TypeMap,
        Version,
    };

    struct RequestSentinel {
        method: Method,
        path: String,
        extensions: conduit::Extensions,
    }

    impl RequestSentinel {
        fn new(method: Method, path: &'static str) -> RequestSentinel {
            RequestSentinel {
                path: path.to_string(),
                extensions: TypeMap::new(),
                method,
            }
        }
    }

    impl conduit::RequestExt for RequestSentinel {
        fn http_version(&self) -> Version {
            unimplemented!()
        }
        fn method(&self) -> &Method {
            &self.method
        }
        fn scheme(&self) -> Scheme {
            unimplemented!()
        }
        fn host(&self) -> Host<'_> {
            unimplemented!()
        }
        fn virtual_root(&self) -> Option<&str> {
            unimplemented!()
        }
        fn path(&self) -> &str {
            &self.path
        }
        fn path_mut(&mut self) -> &mut String {
            &mut self.path
        }
        fn query_string(&self) -> Option<&str> {
            unimplemented!()
        }
        fn remote_addr(&self) -> SocketAddr {
            unimplemented!()
        }
        fn content_length(&self) -> Option<u64> {
            unimplemented!()
        }
        fn headers(&self) -> &HeaderMap {
            unimplemented!()
        }
        fn body(&mut self) -> &mut dyn io::Read {
            unimplemented!()
        }
        fn extensions(&self) -> &Extensions {
            &self.extensions
        }
        fn mut_extensions(&mut self) -> &mut Extensions {
            &mut self.extensions
        }
    }

    #[test]
    fn basic_get() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::GET, "/posts/1");
        let res = router.call(&mut req).expect("No response");

        assert_eq!(res.status(), StatusCode::OK);
        assert_eq!(*res.into_cow(), b"1, GET, /posts/:id"[..]);
    }

    #[test]
    fn basic_post() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::POST, "/posts/10");
        let res = router.call(&mut req).expect("No response");

        assert_eq!(res.status(), StatusCode::OK);
        assert_eq!(*res.into_cow(), b"10, POST, /posts/:id"[..]);
    }

    #[test]
    fn nonexistent_route() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::POST, "/nonexistent");
        router.call(&mut req).err().expect("No response");
    }

    fn test_router() -> RouteBuilder {
        let mut router = RouteBuilder::new();
        router.post("/posts/:id", test_handler);
        router.get("/posts/:id", test_handler);
        router
    }

    fn test_handler(req: &mut dyn conduit::RequestExt) -> conduit::HttpResult {
        let mut res = vec![];
        res.push(req.params()["id"].clone());
        res.push(format!("{:?}", req.method()));
        res.push(req.extensions().find::<RoutePattern>().unwrap().0.to_string());

        let bytes = res.join(", ").into_bytes();
        Response::builder().body(Body::from_vec(bytes))
    }
}
<commit_msg>Make `RoutePattern` public<commit_after>#![warn(rust_2018_idioms)]
extern crate conduit;
extern crate route_recognizer as router;

use std::collections::hash_map::{Entry, HashMap};
use std::error::Error;
use std::fmt;

use conduit::{box_error, Handler, HandlerResult, Method, RequestExt};
use router::{Match, Router};

#[derive(Default)]
pub struct RouteBuilder {
    routers: HashMap<Method, Router<WrappedHandler>>,
}

#[derive(Clone, Copy)]
pub struct RoutePattern(&'static str);

pub struct WrappedHandler {
    pattern: RoutePattern,
    handler: Box<dyn Handler>,
}

#[derive(Debug)]
pub struct RouterError(String);

impl RouteBuilder {
    pub fn new() -> RouteBuilder {
        RouteBuilder {
            routers: HashMap::new(),
        }
    }

    #[allow(clippy::borrowed_box)]
    pub fn recognize<'a>(
        &'a self,
        method: &Method,
        path: &str,
    ) -> Result<Match<&WrappedHandler>, RouterError> {
        match self.routers.get(method) {
            Some(router) => router.recognize(path),
            None => Err(format!("No router found for {:?}", method)),
        }
        .map_err(RouterError)
    }

    pub fn map<'a, H: Handler>(
        &'a mut self,
        method: Method,
        pattern: &'static str,
        handler: H,
    ) -> &'a mut RouteBuilder {
        {
            let router = match self.routers.entry(method) {
                Entry::Occupied(e) => e.into_mut(),
                Entry::Vacant(e) => e.insert(Router::new()),
            };
            let wrapped_handler = WrappedHandler {
                pattern: RoutePattern(pattern),
                handler: Box::new(handler)
            };
            router.add(pattern, wrapped_handler);
        }
        self
    }

    pub fn get<'a, H: Handler>(&'a mut self, pattern: &'static str, handler: H) -> &'a mut RouteBuilder {
        self.map(Method::GET, pattern, handler)
    }

    pub fn post<'a, H: Handler>(&'a mut self, pattern: &'static str, handler: H) -> &'a mut RouteBuilder {
        self.map(Method::POST, pattern, handler)
    }

    pub fn put<'a, H: Handler>(&'a mut self, pattern: &'static str, handler: H) -> &'a mut RouteBuilder {
        self.map(Method::PUT, pattern, handler)
    }

    pub fn delete<'a, H: Handler>(&'a mut self, pattern: &'static str, handler: H) -> &'a mut RouteBuilder {
        self.map(Method::DELETE, pattern, handler)
    }

    pub fn head<'a, H: Handler>(&'a mut self, pattern: &'static str, handler: H) -> &'a mut RouteBuilder {
        self.map(Method::HEAD, pattern, handler)
    }
}

impl conduit::Handler for RouteBuilder {
    fn call(&self, request: &mut dyn RequestExt) -> HandlerResult {
        let m = {
            let method = request.method();
            let path = request.path();

            match self.recognize(&method, path) {
                Ok(m) => m,
                Err(e) => return Err(box_error(e)),
            }
        };

        {
            let extensions = request.mut_extensions();
            extensions.insert(m.handler.pattern);
            extensions.insert(m.params.clone());
        }

        (*m.handler.handler).call(request)
    }
}

impl Error for RouterError {
    fn description(&self) -> &str {
        &self.0
    }
}

impl fmt::Display for RouterError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Display::fmt(&self.0, f)
    }
}

pub trait RequestParams<'a> {
    fn params(self) -> &'a router::Params;
}

pub fn params(req: &dyn RequestExt) -> &router::Params {
    req.extensions()
        .find::<router::Params>()
        .expect("Missing params")
}

impl<'a> RequestParams<'a> for &'a (dyn RequestExt + 'a) {
    fn params(self) -> &'a router::Params {
        params(self)
    }
}

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

    use std::io;
    use std::net::SocketAddr;

    use {RequestParams, RouteBuilder, RoutePattern};

    use self::conduit_test::ResponseExt;
    use conduit::{
        Body, Extensions, Handler, HeaderMap, Host, Method, Response, Scheme, StatusCode, TypeMap,
        Version,
    };

    struct RequestSentinel {
        method: Method,
        path: String,
        extensions: conduit::Extensions,
    }

    impl RequestSentinel {
        fn new(method: Method, path: &'static str) -> RequestSentinel {
            RequestSentinel {
                path: path.to_string(),
                extensions: TypeMap::new(),
                method,
            }
        }
    }

    impl conduit::RequestExt for RequestSentinel {
        fn http_version(&self) -> Version {
            unimplemented!()
        }
        fn method(&self) -> &Method {
            &self.method
        }
        fn scheme(&self) -> Scheme {
            unimplemented!()
        }
        fn host(&self) -> Host<'_> {
            unimplemented!()
        }
        fn virtual_root(&self) -> Option<&str> {
            unimplemented!()
        }
        fn path(&self) -> &str {
            &self.path
        }
        fn path_mut(&mut self) -> &mut String {
            &mut self.path
        }
        fn query_string(&self) -> Option<&str> {
            unimplemented!()
        }
        fn remote_addr(&self) -> SocketAddr {
            unimplemented!()
        }
        fn content_length(&self) -> Option<u64> {
            unimplemented!()
        }
        fn headers(&self) -> &HeaderMap {
            unimplemented!()
        }
        fn body(&mut self) -> &mut dyn io::Read {
            unimplemented!()
        }
        fn extensions(&self) -> &Extensions {
            &self.extensions
        }
        fn mut_extensions(&mut self) -> &mut Extensions {
            &mut self.extensions
        }
    }

    #[test]
    fn basic_get() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::GET, "/posts/1");
        let res = router.call(&mut req).expect("No response");

        assert_eq!(res.status(), StatusCode::OK);
        assert_eq!(*res.into_cow(), b"1, GET, /posts/:id"[..]);
    }

    #[test]
    fn basic_post() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::POST, "/posts/10");
        let res = router.call(&mut req).expect("No response");

        assert_eq!(res.status(), StatusCode::OK);
        assert_eq!(*res.into_cow(), b"10, POST, /posts/:id"[..]);
    }

    #[test]
    fn nonexistent_route() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::POST, "/nonexistent");
        router.call(&mut req).err().expect("No response");
    }

    fn test_router() -> RouteBuilder {
        let mut router = RouteBuilder::new();
        router.post("/posts/:id", test_handler);
        router.get("/posts/:id", test_handler);
        router
    }

    fn test_handler(req: &mut dyn conduit::RequestExt) -> conduit::HttpResult {
        let mut res = vec![];
        res.push(req.params()["id"].clone());
        res.push(format!("{:?}", req.method()));
        res.push(req.extensions().find::<RoutePattern>().unwrap().0.to_string());

        let bytes = res.join(", ").into_bytes();
        Response::builder().body(Body::from_vec(bytes))
    }
}
<|endoftext|>


<commit_before>//!
//! ```
//! use document::Package;
//! let package = Package::new();
//! let doc = package.as_document();
//!
//! let hello = doc.create_element("hello");
//! hello.set_attribute_value("planet", "Earth");
//! let comment = doc.create_comment("What about other planets?");
//! let text = doc.create_text("Greetings, Earthlings!");
//!
//! hello.append_child(comment);
//! hello.append_child(text);
//! doc.root().append_child(hello);
//! ```
//!
//! ### Design decisions
//!
//! Try to leverage the type system as much as possible.

#![crate_name = "document"]
#![experimental]
#![feature(macro_rules)]
#![feature(default_type_params)]
#![feature(globs)]
#![feature(slicing_syntax)]

extern crate arena;
extern crate test;
extern crate xxhash;

use std::fmt;

mod string_pool;
mod raw;
pub mod peresil;
pub mod thindom4;
pub mod dom4;
pub mod parser;
pub mod writer;

#[derive(Show,PartialEq,Eq,PartialOrd)]
pub struct QName<'s> {
    namespace_uri: Option<&'s str>,
    local_part: &'s str,
}

impl<'s> QName<'s> {
    pub fn new(local_part: &'s str) -> QName<'s> {
        QName::with_namespace_uri(None, local_part)
    }

    pub fn with_namespace_uri(namespace_uri: Option<&'s str>, local_part: &'s str) -> QName<'s> {
        QName {
            namespace_uri: namespace_uri,
            local_part: local_part,
        }
    }

    pub fn namespace_uri(&self) -> Option<&'s str> { self.namespace_uri }
    pub fn local_part(&self) -> &'s str { self.local_part }
}

impl<'s> Ord for QName<'s> {
    fn cmp(&self, other: &QName<'s>) -> std::cmp::Ordering {
        self.partial_cmp(other).unwrap()
    }
}

pub trait ToQName<'s> {
    fn to_qname(self) -> QName<'s>;
}

impl<'s> ToQName<'s> for QName<'s> {
    fn to_qname(self) -> QName<'s> { self }
}

impl<'s> ToQName<'s> for &'s str {
    fn to_qname(self) -> QName<'s> { QName { namespace_uri: None, local_part: self } }
}

pub struct Package {
    storage: raw::Storage,
    connections: raw::Connections,
}

impl Package {
    pub fn new() -> Package {
        let s = raw::Storage::new();
        let root = s.create_root();
        Package {
            storage: s,
            connections: raw::Connections::new(root),
        }
    }

    pub fn as_document(&self) -> dom4::Document {
        dom4::Document::new(&self.storage, &self.connections)
    }

    pub fn as_thin_document(&self) -> (thindom4::Storage, thindom4::Connections) {
        let s = thindom4::Storage::new(&self.storage);
        let c = thindom4::Connections::new(&self.connections);
        (s, c)
    }
}

impl PartialEq for Package {
    fn eq(&self, other: &Package) -> bool {
        self as *const Package == other as *const Package
    }
}

impl fmt::Show for Package {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Package")
    }
}

#[doc(hidden)]
mod document {
    pub use peresil;
}
<commit_msg>Workaround to continue implementing Hash<S><commit_after>//!
//! ```
//! use document::Package;
//! let package = Package::new();
//! let doc = package.as_document();
//!
//! let hello = doc.create_element("hello");
//! hello.set_attribute_value("planet", "Earth");
//! let comment = doc.create_comment("What about other planets?");
//! let text = doc.create_text("Greetings, Earthlings!");
//!
//! hello.append_child(comment);
//! hello.append_child(text);
//! doc.root().append_child(hello);
//! ```
//!
//! ### Design decisions
//!
//! Try to leverage the type system as much as possible.

#![crate_name = "document"]
#![experimental]
#![feature(macro_rules)]
#![feature(default_type_params)]
#![feature(globs)]
#![feature(slicing_syntax)]
#![feature(old_orphan_check)] // https://github.com/rust-lang/rust/issues/20477

extern crate arena;
extern crate test;
extern crate xxhash;

use std::fmt;

mod string_pool;
mod raw;
pub mod peresil;
pub mod thindom4;
pub mod dom4;
pub mod parser;
pub mod writer;

#[derive(Show,PartialEq,Eq,PartialOrd)]
pub struct QName<'s> {
    namespace_uri: Option<&'s str>,
    local_part: &'s str,
}

impl<'s> QName<'s> {
    pub fn new(local_part: &'s str) -> QName<'s> {
        QName::with_namespace_uri(None, local_part)
    }

    pub fn with_namespace_uri(namespace_uri: Option<&'s str>, local_part: &'s str) -> QName<'s> {
        QName {
            namespace_uri: namespace_uri,
            local_part: local_part,
        }
    }

    pub fn namespace_uri(&self) -> Option<&'s str> { self.namespace_uri }
    pub fn local_part(&self) -> &'s str { self.local_part }
}

impl<'s> Ord for QName<'s> {
    fn cmp(&self, other: &QName<'s>) -> std::cmp::Ordering {
        self.partial_cmp(other).unwrap()
    }
}

pub trait ToQName<'s> {
    fn to_qname(self) -> QName<'s>;
}

impl<'s> ToQName<'s> for QName<'s> {
    fn to_qname(self) -> QName<'s> { self }
}

impl<'s> ToQName<'s> for &'s str {
    fn to_qname(self) -> QName<'s> { QName { namespace_uri: None, local_part: self } }
}

pub struct Package {
    storage: raw::Storage,
    connections: raw::Connections,
}

impl Package {
    pub fn new() -> Package {
        let s = raw::Storage::new();
        let root = s.create_root();
        Package {
            storage: s,
            connections: raw::Connections::new(root),
        }
    }

    pub fn as_document(&self) -> dom4::Document {
        dom4::Document::new(&self.storage, &self.connections)
    }

    pub fn as_thin_document(&self) -> (thindom4::Storage, thindom4::Connections) {
        let s = thindom4::Storage::new(&self.storage);
        let c = thindom4::Connections::new(&self.connections);
        (s, c)
    }
}

impl PartialEq for Package {
    fn eq(&self, other: &Package) -> bool {
        self as *const Package == other as *const Package
    }
}

impl fmt::Show for Package {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Package")
    }
}

#[doc(hidden)]
mod document {
    pub use peresil;
}
<|endoftext|>


<commit_before>extern crate nix;

use std::error::Error;
use std::fmt;
use std::path::PathBuf;

use nix::sched::{unshare, setns};
use nix::fcntl::{open};
use nix::unistd::{getpid, gettid};
use nix::sys::stat::Mode;
use nix::Error as NError;

pub struct NetNS {
	id: i32,
	path: PathBuf
}

#[derive(Debug)]
pub enum NetNSError {
	CreateNetNSError,
}

impl Error for NetNSError {
	fn description(&self) -> &str {
		"Cannot create"
	}
}

impl NetNS {
	pub fn new() -> Result<NetNS, NetNSError> {
		unshare(nix::sched::CLONE_NEWNET).expect("failed");
	    NetNS::get()
	}

	pub fn get() -> Result<NetNS, NetNSError> {
		return NetNS::get_from_thread(getpid(), gettid())
	}

	pub fn set(ns: NetNS) -> Result<(), NError> {
		setns(ns.id, nix::sched::CLONE_NEWNET)
	}

	fn get_from_thread(pid: i32, tid: i32) -> Result<NetNS, NetNSError> {
		return NetNS::get_from_path(PathBuf::from(format!("/proc/{}/task/{}/ns/net", pid, tid).as_str()))
	}

	fn get_from_path(path: PathBuf) -> Result<NetNS, NetNSError> {
		let fd = open(&path, nix::fcntl::O_RDONLY, Mode::empty()).expect("Could not open");
	    return Ok(NetNS {id: fd, path: path})
	}
}

impl fmt::Display for NetNSError {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		write!(f, "oops")
	}
}
<commit_msg>Update lib.rs<commit_after>extern crate nix;

use std::error::Error;
use std::fmt;
use std::path::PathBuf;

use nix::sched::{unshare, setns};
use nix::fcntl::{open};
use nix::unistd::{getpid, gettid};
use nix::sys::stat::Mode;
use nix::Error as NError;

pub struct NetNS {
	id: i32,
	path: PathBuf
}

#[derive(Debug)]
pub enum NetNSError {
	CreateNetNSError,
}

impl Error for NetNSError {
	fn description(&self) -> &str {
		"Cannot create"
	}
}

impl NetNS {
	pub fn new() -> Result<NetNS, NetNSError> {
		unshare(nix::sched::CLONE_NEWNET).expect("failed");
	    	NetNS::get()
	}

	pub fn get() -> Result<NetNS, NetNSError> {
		return NetNS::get_from_thread(getpid(), gettid())
	}

	pub fn set(ns: NetNS) -> Result<(), NError> {
		setns(ns.id, nix::sched::CLONE_NEWNET)
	}

	fn get_from_thread(pid: i32, tid: i32) -> Result<NetNS, NetNSError> {
		return NetNS::get_from_path(PathBuf::from(format!("/proc/{}/task/{}/ns/net", pid, tid).as_str()))
	}

	fn get_from_path(path: PathBuf) -> Result<NetNS, NetNSError> {
		let fd = open(&path, nix::fcntl::O_RDONLY, Mode::empty()).expect("Could not open");
	    	return Ok(NetNS {id: fd, path: path})
	}
}

impl fmt::Display for NetNSError {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		write!(f, "oops")
	}
}
<|endoftext|>