<commit_before>use std::slice;
use num::Integer;
use std::num::FromPrimitive;
use std::f32::consts::PI;
use calx::V2;

/// Hex grid directions.
#[deriving(Eq, PartialEq, Clone, Show, FromPrimitive, Encodable, Decodable)]
pub enum Dir6 {
    North = 0,
    NorthEast,
    SouthEast,
    South,
    SouthWest,
    NorthWest,
}

impl Dir6 {
    /// Convert a vector into the closest hex direction.
    pub fn from_v2(v: V2<int>) -> Dir6 {
        let hexadecant = {
            let width = PI / 8.0;
            let mut radian = (v.0 as f32).atan2(-v.1 as f32);
            if radian < 0.0 { radian += 2.0 * PI }
            (radian / width).floor() as int
        };

        // The hexadecants (00 to 15) and the hex directions (*0* to *5*) around
        // the origin.
        //
        //    *0*       *1*
        //       \ 14 15 | 00 01
        //       13\     |      02
        //           \   |
        //     12      \ |        03
        // *5* ----------O-X------- *2*
        //     11        Y \      04
        //               |   \
        //       10      |     \05
        //         09 08 | 07 06 \
        //              *4*       *3*
        //
        // Vectors that are in a space between two hex direction vectors are
        // snapped to the hex direction vector nearer to them. The hexadecants
        // are a convenience structure that lets us assign every vector using
        // the single hexadecant value.
        Dir6::from_int(match hexadecant {
            13 | 14 => 0,
            15 | 0 | 1 => 1,
            2 | 3 | 4 => 2,
            5 | 6 => 3,
            7 | 8 | 9 => 4,
            10 | 11 | 12 => 5,
            _ => panic!("Bad hexadecant")
        })
    }

    /// Convert an integer to a hex dir using modular arithmetic.
    pub fn from_int(i: int) -> Dir6 {
        FromPrimitive::from_int(i.mod_floor(&6)).unwrap()
    }

    /// Convert a hex dir into the corresponding unit vector.
    pub fn to_v2(&self) -> V2<int> {
        [V2(-1, -1),
         V2( 0, -1),
         V2( 1,  0),
         V2( 1,  1),
         V2( 0,  1),
         V2(-1,  0)][*self as uint]
    }

    /// Iterate through the six hex dirs in the standard order.
    pub fn iter() -> slice::Items<'static, Dir6> {
        static DIRS: [Dir6, ..6] = [
            North,
            NorthEast,
            SouthEast,
            South,
            SouthWest,
            NorthWest];

        DIRS.iter()
    }
}

#[cfg(test)]
mod test {
    use calx::V2;
    // XXX: Why doesn't super::* work here?
    use super::{Dir6, North, NorthEast, SouthEast, South, SouthWest, NorthWest};

    #[test]
    fn test_dir6() {
        assert_eq!(North, Dir6::from_int(0));
        assert_eq!(NorthWest, Dir6::from_int(-1));
        assert_eq!(NorthWest, Dir6::from_int(5));
        assert_eq!(NorthEast, Dir6::from_int(1));

        assert_eq!(NorthEast, Dir6::from_v2(V2(20, -21)));
        assert_eq!(SouthEast, Dir6::from_v2(V2(20, -10)));
        assert_eq!(North, Dir6::from_v2(V2(-10, -10)));
        assert_eq!(South, Dir6::from_v2(V2(1, 1)));

        for i in range(0, 6) {
            let d = Dir6::from_int(i);
            let v = d.to_v2();
            let v1 = Dir6::from_int(i - 1).to_v2();
            let v2 = Dir6::from_int(i + 1).to_v2();

            // Test static iter
            assert_eq!(Some(d), Dir6::iter().nth(i as uint).map(|&x| x));

            // Test vector mapping.
            assert_eq!(d, Dir6::from_v2(v));

            // Test opposite dir vector mapping.
            assert_eq!(Dir6::from_int(i + 3), Dir6::from_v2(-v));

            // Test approximation of longer vectors.
            assert_eq!(d, Dir6::from_v2(v * 3));
            assert_eq!(d, Dir6::from_v2(v * 3 + v1));
            assert_eq!(d, Dir6::from_v2(v * 3 + v2));
        }
    }
}
<commit_msg>Put the ascii art in a doc comment<commit_after>use std::slice;
use num::Integer;
use std::num::FromPrimitive;
use std::f32::consts::PI;
use calx::V2;

/// Hex grid directions.
#[deriving(Eq, PartialEq, Clone, Show, FromPrimitive, Encodable, Decodable)]
pub enum Dir6 {
    North = 0,
    NorthEast,
    SouthEast,
    South,
    SouthWest,
    NorthWest,
}

impl Dir6 {
    /// Convert a vector into the closest hex direction.
    ///
    /// ```notrust
    ///        *0*       *1*
    ///           \ 14 15 | 00 01
    ///           13\     |      02
    ///               \   |
    ///         12      \ |        03
    ///     *5* ----------O-X------- *2*
    ///         11        Y \      04
    ///                   |   \
    ///           10      |     \05
    ///             09 08 | 07 06 \
    ///                  *4*       *3*
    ///
    /// The hexadecants (00 to 15) and the hex
    /// directions (*0* to *5*) around the origin.
    /// ```
    ///
    /// Vectors that are in a space between two hex direction vectors are
    /// rounded to a hexadecant, then assigned the hex direction whose vector
    /// is nearest to that hexadecant.
    pub fn from_v2(v: V2<int>) -> Dir6 {
        let hexadecant = {
            let width = PI / 8.0;
            let mut radian = (v.0 as f32).atan2(-v.1 as f32);
            if radian < 0.0 { radian += 2.0 * PI }
            (radian / width).floor() as int
        };

        Dir6::from_int(match hexadecant {
            13 | 14 => 0,
            15 | 0 | 1 => 1,
            2 | 3 | 4 => 2,
            5 | 6 => 3,
            7 | 8 | 9 => 4,
            10 | 11 | 12 => 5,
            _ => panic!("Bad hexadecant")
        })
    }

    /// Convert an integer to a hex dir using modular arithmetic.
    pub fn from_int(i: int) -> Dir6 {
        FromPrimitive::from_int(i.mod_floor(&6)).unwrap()
    }

    /// Convert a hex dir into the corresponding unit vector.
    pub fn to_v2(&self) -> V2<int> {
        [V2(-1, -1),
         V2( 0, -1),
         V2( 1,  0),
         V2( 1,  1),
         V2( 0,  1),
         V2(-1,  0)][*self as uint]
    }

    /// Iterate through the six hex dirs in the standard order.
    pub fn iter() -> slice::Items<'static, Dir6> {
        static DIRS: [Dir6, ..6] = [
            North,
            NorthEast,
            SouthEast,
            South,
            SouthWest,
            NorthWest];

        DIRS.iter()
    }
}

#[cfg(test)]
mod test {
    use calx::V2;
    // XXX: Why doesn't super::* work here?
    use super::{Dir6, North, NorthEast, SouthEast, South, SouthWest, NorthWest};

    #[test]
    fn test_dir6() {
        assert_eq!(North, Dir6::from_int(0));
        assert_eq!(NorthWest, Dir6::from_int(-1));
        assert_eq!(NorthWest, Dir6::from_int(5));
        assert_eq!(NorthEast, Dir6::from_int(1));

        assert_eq!(NorthEast, Dir6::from_v2(V2(20, -21)));
        assert_eq!(SouthEast, Dir6::from_v2(V2(20, -10)));
        assert_eq!(North, Dir6::from_v2(V2(-10, -10)));
        assert_eq!(South, Dir6::from_v2(V2(1, 1)));

        for i in range(0, 6) {
            let d = Dir6::from_int(i);
            let v = d.to_v2();
            let v1 = Dir6::from_int(i - 1).to_v2();
            let v2 = Dir6::from_int(i + 1).to_v2();

            // Test static iter
            assert_eq!(Some(d), Dir6::iter().nth(i as uint).map(|&x| x));

            // Test vector mapping.
            assert_eq!(d, Dir6::from_v2(v));

            // Test opposite dir vector mapping.
            assert_eq!(Dir6::from_int(i + 3), Dir6::from_v2(-v));

            // Test approximation of longer vectors.
            assert_eq!(d, Dir6::from_v2(v * 3));
            assert_eq!(d, Dir6::from_v2(v * 3 + v1));
            assert_eq!(d, Dir6::from_v2(v * 3 + v2));
        }
    }
}
<|endoftext|>


<commit_before>#[derive(Debug, Clone)]
struct Tree {
    enter: Node,
    left: Option<Box<Tree>>,
    right: Option<Box<Tree>>,
}

//for red-black tree
#[derive(Debug, Clone)]
enum Color {
    Black,
    Red,
    White,
}

#[derive(Debug, Clone)]
struct Node {
    val: i32,
    color: Color,
}

impl Node {
    fn new(v: &i32) -> Node {
        Node {
            val: *v,
            color: Color::White,
        }
    }

    fn make_black(&mut self) {
        self.color = Color::Black;
    }

    fn make_red(&mut self) {
        self.color = Color::Red;
    }
}

type ReTr<'a> = Result<&'a mut Tree, String>;

impl Tree {
    fn new(v: &i32) -> Tree {
        let mut root = Node::new(v);
        root.make_black();
        Tree {
            enter: root,
            left: None,
            right: None,
        }
    }

    fn insert(&mut self, v: &i32) {
        let target = if *v > self.enter.val {
            &mut self.right
        } else {
            &mut self.left
        };

        match target {
            Some(next) => next.insert(v),
            None => {
                let mut new_node = Node::new(v);
                new_node.make_red();
                let new_tree = Tree {
                    enter: new_node,
                    left: None,
                    right: None,
                };
                *target = Some(Box::new(new_tree));
            }
        }
    }

    fn look_up_recursive(&mut self, v: &i32) -> ReTr {
        if *v == self.enter.val {
            return Ok(self);
        } else if *v > self.enter.val {
            if let Some(_) = self.right {
                let next = self.right.as_mut().unwrap();
                return next.look_up(v);
            } else {
                Err("not find".to_string())
            }
        } else {
            if let Some(_) = self.left {
                let next = self.left.as_mut().unwrap();
                return next.look_up(v);
            } else {
                Err("not find".to_string())
            }
        }
    }

    fn look_up(&mut self, v: &i32) -> ReTr {
        let mut this: &mut Self = self;
        loop {
            if *v == this.enter.val {
                return Ok(this);
            } else if *v > this.enter.val {
                if let None = this.right {
                    return Err("not find".to_string());
                }
                this = { this }.right.as_mut().unwrap();
            } else {
                if let None = this.left {
                    return Err("not find".to_string());
                }
                this = { this }.left.as_mut().unwrap();
            }
        }
    }

    fn look_up_father(&mut self, v: &i32) -> (ReTr, String) {
        let mut this: &mut Self = self;
        loop {
            if *v == this.right.as_ref().unwrap().enter.val {
                return (Ok(this), "right".to_string());
            } else if *v == this.left.as_ref().unwrap().enter.val {
                return (Ok(this), "left".to_string());
            } else if *v > this.enter.val {
                if let None = this.right {
                    return (Err("not find".to_string()), "Error".to_string());
                }
                this = { this }.right.as_mut().unwrap();
            } else {
                if let None = this.left {
                    return (Err("not find".to_string()), "Error".to_string());
                }
                this = { this }.left.as_mut().unwrap();
            }
        }
    }

    fn cut_left_tree(&mut self) -> Option<Box<Self>> {
        self.left.clone()
    }

    fn cut_right_tree(&mut self) -> Option<Box<Self>> {
        self.right.clone()
    }

    fn left_shift(&mut self, v: &i32) {
        let father = self.look_up_father(v).0.unwrap();
        let mut this = father.cut_left_tree().unwrap();
        let mut son = this.cut_right_tree().unwrap();
        let grand_son = son.cut_left_tree().unwrap();

        this.right = Some(grand_son);
        son.left = Some(this);
        father.left = Some(son);
    }

    fn right_shift(&mut self, v: &i32) {
        let father = self.look_up_father(v).0.unwrap();
        let mut this = father.cut_right_tree().unwrap();
        let mut son = this.cut_left_tree().unwrap();
        let grand_son = son.cut_right_tree().unwrap();

        this.left = Some(grand_son);
        son.right = Some(this);
        father.right = Some(son);
    }
}

fn main() {
    //let mut a = Tree::new(&3);
    //a.insert(&2);
    //a.insert(&1);
    //a.insert(&4);
    //a.insert(&5);

    //println!("{:?}", a);
    //println!("{:?}", a.look_up(&1));
    //println!("{:?}", a.look_up_father(&4));
    //println!("{:?}", a);

    //let mut b = Tree::new(&10);
    //b.insert(&2);
    //b.insert(&1);
    //b.insert(&5);
    //b.insert(&3);
    //b.insert(&6);
    //b.insert(&11);

    //println!("{:?}", b);
    //println!("{:?}", b.look_up_father(&2));
    //b.left_shift(&2);
    //println!("{:?}", b);

    let mut c = Tree::new(&2);
    c.insert(&8);
    c.insert(&1);
    c.insert(&5);
    c.insert(&4);
    c.insert(&7);
    c.insert(&9);
    //println!("{:?}", c.look_up_father(&8));
    c.right_shift(&8);
    println!("{:?}", c);
}
<commit_msg>fix when this node is root node then no father<commit_after>use std::fmt;

#[derive(Debug, Clone)]
struct Tree {
    enter: Node,
    left: Option<Box<Tree>>,
    right: Option<Box<Tree>>,
}

/*impl fmt::Display for Tree {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "(this: {:#?}, \nleft: {:#?}, \nright: {:#?})",
            self.enter, self.left, self.right
        )
    }
}*/

//for red-black tree
#[derive(Debug, Clone)]
enum Color {
    Black,
    Red,
    White,
}

#[derive(Debug, Clone)]
struct Node {
    val: i32,
    color: Color,
}

impl Node {
    fn new(v: &i32) -> Node {
        Node {
            val: *v,
            color: Color::White,
        }
    }

    fn make_black(&mut self) {
        self.color = Color::Black;
    }

    fn make_red(&mut self) {
        self.color = Color::Red;
    }
}

type ReTr<'a> = Result<&'a mut Tree, String>;

impl Tree {
    fn new(v: &i32) -> Tree {
        let mut root = Node::new(v);
        root.make_black();
        Tree {
            enter: root,
            left: None,
            right: None,
        }
    }

    fn insert(&mut self, v: &i32) {
        let target = if *v > self.enter.val {
            &mut self.right
        } else {
            &mut self.left
        };

        match target {
            Some(next) => next.insert(v),
            None => {
                let mut new_node = Node::new(v);
                new_node.make_red();
                let new_tree = Tree {
                    enter: new_node,
                    left: None,
                    right: None,
                };
                *target = Some(Box::new(new_tree));
            }
        }
    }

    fn look_up_recursive(&mut self, v: &i32) -> ReTr {
        if *v == self.enter.val {
            return Ok(self);
        } else if *v > self.enter.val {
            if let Some(_) = self.right {
                let next = self.right.as_mut().unwrap();
                return next.look_up(v);
            } else {
                Err("not find".to_string())
            }
        } else {
            if let Some(_) = self.left {
                let next = self.left.as_mut().unwrap();
                return next.look_up(v);
            } else {
                Err("not find".to_string())
            }
        }
    }

    fn look_up(&mut self, v: &i32) -> ReTr {
        let mut this: &mut Self = self;
        loop {
            if *v == this.enter.val {
                return Ok(this);
            } else if *v > this.enter.val {
                if let None = this.right {
                    return Err("not find".to_string());
                }
                this = { this }.right.as_mut().unwrap();
            } else {
                if let None = this.left {
                    return Err("not find".to_string());
                }
                this = { this }.left.as_mut().unwrap();
            }
        }
    }

    fn look_up_father(&mut self, v: &i32) -> (ReTr, String) {
        let mut this: &mut Self = self;
        loop {
            if *v == this.enter.val {
                return (Err("no father".to_string()), "this".to_string());
            } else if *v == this.right.as_ref().unwrap().enter.val {
                return (Ok(this), "right".to_string());
            } else if *v == this.left.as_ref().unwrap().enter.val {
                return (Ok(this), "left".to_string());
            } else if *v > this.enter.val {
                if let None = this.right {
                    return (Err("not find".to_string()), "Error".to_string());
                }
                this = { this }.right.as_mut().unwrap();
            } else {
                if let None = this.left {
                    return (Err("not find".to_string()), "Error".to_string());
                }
                this = { this }.left.as_mut().unwrap();
            }
        }
    }

    fn cut_left_tree(&mut self) -> Option<Box<Self>> {
        self.left.clone()
    }

    fn cut_right_tree(&mut self) -> Option<Box<Self>> {
        self.right.clone()
    }

    fn left_shift(&mut self, v: &i32) {
        match self.look_up_father(v).0 {
            Ok(r) => {
                let father = r;
                let mut this = father.cut_left_tree().unwrap();
                let mut son = this.cut_right_tree().unwrap();
                let grand_son = son.cut_left_tree().unwrap();

                this.right = Some(grand_son);
                son.left = Some(this);
                father.left = Some(son);
                return;
            }
            _ => (),
        }

        let left = self.cut_left_tree().unwrap();
        let mut new_left = Tree::new(&self.enter.val);
        new_left.left = Some(left);

        let mut right = self.cut_right_tree().unwrap();
        let right_left = right.cut_left_tree().unwrap();
        let right_right = right.cut_right_tree().unwrap();
        new_left.right = Some(right_left);

        self.enter = Node::new(&right.enter.val);

        self.right = Some(right_right);

        self.left = Some(Box::new(new_left));
    }

    fn right_shift(&mut self, v: &i32) {
        let father = self.look_up_father(v).0.unwrap();
        let mut this = father.cut_right_tree().unwrap();
        let mut son = this.cut_left_tree().unwrap();
        let grand_son = son.cut_right_tree().unwrap();

        this.left = Some(grand_son);
        son.right = Some(this);
        father.right = Some(son);
    }
}

fn main() {
    //let mut a = Tree::new(&3);
    //a.insert(&2);
    //a.insert(&1);
    //a.insert(&4);
    //a.insert(&5);

    //println!("{:?}", a);
    //println!("{:?}", a.look_up(&1));
    //println!("{:?}", a.look_up_father(&4));
    //println!("{:?}", a);

    let mut b = Tree::new(&10);
    b.insert(&2);
    b.insert(&1);
    b.insert(&5);
    b.insert(&3);
    b.insert(&6);
    b.insert(&11);

    //println!("{:?}", b);
    //println!("{:?}", b.look_up_father(&2));
    let mut c = b.cut_left_tree().unwrap();
    //println!("{:#?}", c);
    c.left_shift(&2);
    println!("{:#?}", c);

    //let mut c = Tree::new(&2);
    //c.insert(&8);
    //c.insert(&1);
    //c.insert(&5);
    //c.insert(&4);
    //c.insert(&7);
    //c.insert(&9);
    //println!("{:?}", c.look_up_father(&8));
    //c.right_shift(&8);
    //println!("{:#?}", c);
}
<|endoftext|>


<commit_before>use super::*;
use internal::RwLockExt;

#[cfg(all(feature = "model", feature = "utils"))]
use std::error::Error as StdError;
#[cfg(all(feature = "model", feature = "utils"))]
use std::result::Result as StdResult;
#[cfg(all(feature = "model", feature = "utils"))]
use std::str::FromStr;
#[cfg(all(feature = "model", feature = "utils"))]
use std::fmt;
#[cfg(all(feature = "model", any(feature = "cache", feature = "utils")))]
use utils;

/// Allows something - such as a channel or role - to be mentioned in a message.
pub trait Mentionable {
    /// Creates a mentionable string, that will be able to notify and/or create
    /// a link to the item.
    fn mention(&self) -> String;
}

impl Mentionable for ChannelId {
    fn mention(&self) -> String { format!("<#{}>", self.0) }
}

impl Mentionable for Channel {
    fn mention(&self) -> String {
        match *self {
            Channel::Guild(ref x) => format!("<#{}>", x.with(|x| x.id.0)),
            Channel::Private(ref x) => format!("<#{}>", x.with(|x| x.id.0)),
            Channel::Group(ref x) => format!("<#{}>", x.with(|x| x.channel_id.0)),
            Channel::Category(_) => panic!("Categories can't be mentioned"),
        }
    }
}

impl Mentionable for Emoji {
    fn mention(&self) -> String { format!("<:{}:{}>", self.name, self.id.0) }
}

impl Mentionable for Member {
    fn mention(&self) -> String { format!("<@{}>", self.user.with(|u| u.id.0)) }
}

impl Mentionable for RoleId {
    fn mention(&self) -> String { format!("<@&{}>", self.0) }
}

impl Mentionable for Role {
    fn mention(&self) -> String { format!("<@&{}>", self.id.0) }
}

impl Mentionable for UserId {
    fn mention(&self) -> String { format!("<@{}>", self.0) }
}

impl Mentionable for User {
    fn mention(&self) -> String { format!("<@{}>", self.id.0) }
}

#[cfg(all(feature = "model", feature = "utils"))]
#[derive(Debug)]
pub enum UserParseError {
    InvalidUsername,
    Rest(Box<Error>),
}

#[cfg(all(feature = "model", feature = "utils"))]
impl fmt::Display for UserParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.description()) }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl StdError for UserParseError {
    fn description(&self) -> &str {
        use self::UserParseError::*;

        match *self {
            InvalidUsername => "invalid username",
            Rest(_) => "could not fetch",
        }
    }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl FromStr for User {
    type Err = UserParseError;

    fn from_str(s: &str) -> StdResult<Self, Self::Err> {
        match utils::parse_username(s) {
            Some(x) => UserId(x as u64)
                .get()
                .map_err(|e| UserParseError::Rest(Box::new(e))),
            _ => Err(UserParseError::InvalidUsername),
        }
    }
}

#[cfg(all(feature = "model", feature = "utils"))]
#[derive(Debug)]
pub enum UserIdParseError {
    InvalidFormat,
}

#[cfg(all(feature = "model", feature = "utils"))]
impl fmt::Display for UserIdParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.description()) }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl StdError for UserIdParseError {
    fn description(&self) -> &str {
        use self::UserIdParseError::*;

        match *self {
            InvalidFormat => "invalid user id format",
        }
    }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl FromStr for UserId {
    type Err = UserIdParseError;

    fn from_str(s: &str) -> StdResult<Self, Self::Err> {
        Ok(match utils::parse_username(s) {
            Some(id) => UserId(id),
            None => s.parse::<u64>().map(UserId).map_err(|_| UserIdParseError::InvalidFormat)?,
        })
    }
}

#[cfg(all(feature = "cache", feature = "model", feature = "utils"))]
#[derive(Debug)]
pub enum RoleParseError {
    NotPresentInCache,
    InvalidRole,
}

#[cfg(all(feature = "cache", feature = "model", feature = "utils"))]
impl fmt::Display for RoleParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.description()) }
}

#[cfg(all(feature = "cache", feature = "model", feature = "utils"))]
impl StdError for RoleParseError {
    fn description(&self) -> &str {
        use self::RoleParseError::*;

        match *self {
            NotPresentInCache => "not present in cache",
            InvalidRole => "invalid role",
        }
    }
}

#[cfg(all(feature = "cache", feature = "model", feature = "utils"))]
impl FromStr for Role {
    type Err = RoleParseError;

    fn from_str(s: &str) -> StdResult<Self, Self::Err> {
        match utils::parse_role(s) {
            Some(x) => match RoleId(x).find() {
                Some(user) => Ok(user),
                _ => Err(RoleParseError::NotPresentInCache),
            },
            _ => Err(RoleParseError::InvalidRole),
        }
    }
}

#[cfg(all(feature = "model", feature = "utils"))]
#[derive(Debug)]
pub enum RoleIdParseError {
    InvalidFormat,
}

#[cfg(all(feature = "model", feature = "utils"))]
impl fmt::Display for RoleIdParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.description()) }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl StdError for RoleIdParseError {
    fn description(&self) -> &str {
        use self::RoleIdParseError::*;

        match *self {
            InvalidFormat => "invalid role id format",
        }
    }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl FromStr for RoleId {
    type Err = RoleIdParseError;

    fn from_str(s: &str) -> StdResult<Self, Self::Err> {
        Ok(match utils::parse_role(s) {
            Some(id) => RoleId(id),
            None => s.parse::<u64>().map(RoleId).map_err(|_| RoleIdParseError::InvalidFormat)?,
        })
    }
}

/// A version of an emoji used only when solely the Id and name are known.
#[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct EmojiIdentifier {
    /// The Id of the emoji.
    pub id: EmojiId,
    /// The name of the emoji. It must be at least 2 characters long and can
    /// only contain alphanumeric characters and underscores.
    pub name: String,
}

#[cfg(all(feature = "model", feature = "utils"))]
impl EmojiIdentifier {
    /// Generates a URL to the emoji's image.
    #[inline]
    pub fn url(&self) -> String { format!(cdn!("/emojis/{}.png"), self.id) }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl FromStr for EmojiIdentifier {
    type Err = ();

    fn from_str(s: &str) -> StdResult<Self, ()> { utils::parse_emoji(s).ok_or_else(|| ()) }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl FromStr for ChannelId {
    type Err = ();

    fn from_str(s: &str) -> StdResult<Self, ()> {
        utils::parse_channel(s).ok_or_else(|| ()).map(ChannelId)
    }
}

#[cfg(all(feature = "cache", feature = "model", feature = "utils"))]
impl FromStr for Channel {
    type Err = ();

    fn from_str(s: &str) -> StdResult<Self, ()> {
        match utils::parse_channel(s) {
            Some(x) => match ChannelId(x).find() {
                Some(channel) => Ok(channel),
                _ => Err(()),
            },
            _ => Err(()),
        }
    }
}

/// A component that was affected during a service incident.
///
/// This is pulled from the Discord status page.
#[derive(Clone, Debug, Deserialize)]
pub struct AffectedComponent {
    pub name: String,
}

/// An incident retrieved from the Discord status page.
///
/// This is not necessarily a representation of an ongoing incident.
#[derive(Clone, Debug, Deserialize)]
pub struct Incident {
    pub created_at: String,
    pub id: String,
    pub impact: String,
    pub incident_updates: Vec<IncidentUpdate>,
    pub monitoring_at: Option<String>,
    pub name: String,
    pub page_id: String,
    pub resolved_at: Option<String>,
    pub short_link: String,
    pub status: String,
    pub updated_at: String,
}

/// An update to an incident from the Discord status page.
///
/// This will typically state what new information has been discovered about an
/// incident.
#[derive(Clone, Debug, Deserialize)]
pub struct IncidentUpdate {
    pub affected_components: Vec<AffectedComponent>,
    pub body: String,
    pub created_at: String,
    pub display_at: String,
    pub id: String,
    pub incident_id: String,
    pub status: IncidentStatus,
    pub updated_at: String,
}

/// The type of status update during a service incident.
#[derive(Copy, Clone, Debug, Deserialize, Hash, Eq, PartialEq, PartialOrd, Ord, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum IncidentStatus {
    Identified,
    Investigating,
    Monitoring,
    Postmortem,
    Resolved,
}

/// A Discord status maintenance message. This can be either for active
/// maintenances or for scheduled maintenances.
#[derive(Clone, Debug, Deserialize)]
pub struct Maintenance {
    pub description: String,
    pub id: String,
    pub name: String,
    pub start: String,
    pub stop: String,
}
<commit_msg>Fall back to `str::parse` on `ChannelId` as well<commit_after>use super::*;
use internal::RwLockExt;

#[cfg(all(feature = "model", feature = "utils"))]
use std::error::Error as StdError;
#[cfg(all(feature = "model", feature = "utils"))]
use std::result::Result as StdResult;
#[cfg(all(feature = "model", feature = "utils"))]
use std::str::FromStr;
#[cfg(all(feature = "model", feature = "utils"))]
use std::fmt;
#[cfg(all(feature = "model", any(feature = "cache", feature = "utils")))]
use utils;

/// Allows something - such as a channel or role - to be mentioned in a message.
pub trait Mentionable {
    /// Creates a mentionable string, that will be able to notify and/or create
    /// a link to the item.
    fn mention(&self) -> String;
}

impl Mentionable for ChannelId {
    fn mention(&self) -> String { format!("<#{}>", self.0) }
}

impl Mentionable for Channel {
    fn mention(&self) -> String {
        match *self {
            Channel::Guild(ref x) => format!("<#{}>", x.with(|x| x.id.0)),
            Channel::Private(ref x) => format!("<#{}>", x.with(|x| x.id.0)),
            Channel::Group(ref x) => format!("<#{}>", x.with(|x| x.channel_id.0)),
            Channel::Category(_) => panic!("Categories can't be mentioned"),
        }
    }
}

impl Mentionable for Emoji {
    fn mention(&self) -> String { format!("<:{}:{}>", self.name, self.id.0) }
}

impl Mentionable for Member {
    fn mention(&self) -> String { format!("<@{}>", self.user.with(|u| u.id.0)) }
}

impl Mentionable for RoleId {
    fn mention(&self) -> String { format!("<@&{}>", self.0) }
}

impl Mentionable for Role {
    fn mention(&self) -> String { format!("<@&{}>", self.id.0) }
}

impl Mentionable for UserId {
    fn mention(&self) -> String { format!("<@{}>", self.0) }
}

impl Mentionable for User {
    fn mention(&self) -> String { format!("<@{}>", self.id.0) }
}

#[cfg(all(feature = "model", feature = "utils"))]
#[derive(Debug)]
pub enum UserParseError {
    InvalidUsername,
    Rest(Box<Error>),
}

#[cfg(all(feature = "model", feature = "utils"))]
impl fmt::Display for UserParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.description()) }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl StdError for UserParseError {
    fn description(&self) -> &str {
        use self::UserParseError::*;

        match *self {
            InvalidUsername => "invalid username",
            Rest(_) => "could not fetch",
        }
    }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl FromStr for User {
    type Err = UserParseError;

    fn from_str(s: &str) -> StdResult<Self, Self::Err> {
        match utils::parse_username(s) {
            Some(x) => UserId(x as u64)
                .get()
                .map_err(|e| UserParseError::Rest(Box::new(e))),
            _ => Err(UserParseError::InvalidUsername),
        }
    }
}

#[cfg(all(feature = "model", feature = "utils"))]
#[derive(Debug)]
pub enum UserIdParseError {
    InvalidFormat,
}

#[cfg(all(feature = "model", feature = "utils"))]
impl fmt::Display for UserIdParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.description()) }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl StdError for UserIdParseError {
    fn description(&self) -> &str {
        use self::UserIdParseError::*;

        match *self {
            InvalidFormat => "invalid user id format",
        }
    }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl FromStr for UserId {
    type Err = UserIdParseError;

    fn from_str(s: &str) -> StdResult<Self, Self::Err> {
        Ok(match utils::parse_username(s) {
            Some(id) => UserId(id),
            None => s.parse::<u64>().map(UserId).map_err(|_| UserIdParseError::InvalidFormat)?,
        })
    }
}

#[cfg(all(feature = "cache", feature = "model", feature = "utils"))]
#[derive(Debug)]
pub enum RoleParseError {
    NotPresentInCache,
    InvalidRole,
}

#[cfg(all(feature = "cache", feature = "model", feature = "utils"))]
impl fmt::Display for RoleParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.description()) }
}

#[cfg(all(feature = "cache", feature = "model", feature = "utils"))]
impl StdError for RoleParseError {
    fn description(&self) -> &str {
        use self::RoleParseError::*;

        match *self {
            NotPresentInCache => "not present in cache",
            InvalidRole => "invalid role",
        }
    }
}

#[cfg(all(feature = "cache", feature = "model", feature = "utils"))]
impl FromStr for Role {
    type Err = RoleParseError;

    fn from_str(s: &str) -> StdResult<Self, Self::Err> {
        match utils::parse_role(s) {
            Some(x) => match RoleId(x).find() {
                Some(user) => Ok(user),
                _ => Err(RoleParseError::NotPresentInCache),
            },
            _ => Err(RoleParseError::InvalidRole),
        }
    }
}

#[cfg(all(feature = "model", feature = "utils"))]
#[derive(Debug)]
pub enum RoleIdParseError {
    InvalidFormat,
}

#[cfg(all(feature = "model", feature = "utils"))]
impl fmt::Display for RoleIdParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.description()) }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl StdError for RoleIdParseError {
    fn description(&self) -> &str {
        use self::RoleIdParseError::*;

        match *self {
            InvalidFormat => "invalid role id format",
        }
    }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl FromStr for RoleId {
    type Err = RoleIdParseError;

    fn from_str(s: &str) -> StdResult<Self, Self::Err> {
        Ok(match utils::parse_role(s) {
            Some(id) => RoleId(id),
            None => s.parse::<u64>().map(RoleId).map_err(|_| RoleIdParseError::InvalidFormat)?,
        })
    }
}

/// A version of an emoji used only when solely the Id and name are known.
#[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct EmojiIdentifier {
    /// The Id of the emoji.
    pub id: EmojiId,
    /// The name of the emoji. It must be at least 2 characters long and can
    /// only contain alphanumeric characters and underscores.
    pub name: String,
}

#[cfg(all(feature = "model", feature = "utils"))]
impl EmojiIdentifier {
    /// Generates a URL to the emoji's image.
    #[inline]
    pub fn url(&self) -> String { format!(cdn!("/emojis/{}.png"), self.id) }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl FromStr for EmojiIdentifier {
    type Err = ();

    fn from_str(s: &str) -> StdResult<Self, ()> { utils::parse_emoji(s).ok_or_else(|| ()) }
}

#[cfg(all(feature = "model", feature = "utils"))]
#[derive(Debug)]
pub enum ChannelIdParseError {
    InvalidFormat,
}

#[cfg(all(feature = "model", feature = "utils"))]
impl fmt::Display for ChannelIdParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.description()) }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl StdError for ChannelIdParseError {
    fn description(&self) -> &str {
        use self::ChannelIdParseError::*;

        match *self {
            InvalidFormat => "invalid channel id format",
        }
    }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl FromStr for ChannelId {
    type Err = ChannelIdParseError;

    fn from_str(s: &str) -> StdResult<Self, Self::Err> {
        Ok(match utils::parse_channel(s) {
            Some(channel) => ChannelId(channel),
            None => s.parse::<u64>().map(ChannelId).map_err(|_| ChannelIdParseError::InvalidFormat)?,
        })
    }
}

#[cfg(all(feature = "cache", feature = "model", feature = "utils"))]
#[derive(Debug)]
pub enum ChannelParseError {
    NotPresentInCache,
    InvalidChannel,
}

#[cfg(all(feature = "cache", feature = "model", feature = "utils"))]
impl fmt::Display for ChannelParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.description()) }
}

#[cfg(all(feature = "cache", feature = "model", feature = "utils"))]
impl StdError for ChannelParseError {
    fn description(&self) -> &str {
        use self::ChannelParseError::*;

        match *self {
            NotPresentInCache => "not present in cache",
            InvalidChannel => "invalid channel",
        }
    }
}

#[cfg(all(feature = "cache", feature = "model", feature = "utils"))]
impl FromStr for Channel {
    type Err = ChannelParseError;

    fn from_str(s: &str) -> StdResult<Self, Self::Err> {
        match utils::parse_channel(s) {
            Some(x) => match ChannelId(x).find() {
                Some(channel) => Ok(channel),
                _ => Err(ChannelParseError::NotPresentInCache),
            },
            _ => Err(ChannelParseError::InvalidChannel),
        }
    }
}

/// A component that was affected during a service incident.
///
/// This is pulled from the Discord status page.
#[derive(Clone, Debug, Deserialize)]
pub struct AffectedComponent {
    pub name: String,
}

/// An incident retrieved from the Discord status page.
///
/// This is not necessarily a representation of an ongoing incident.
#[derive(Clone, Debug, Deserialize)]
pub struct Incident {
    pub created_at: String,
    pub id: String,
    pub impact: String,
    pub incident_updates: Vec<IncidentUpdate>,
    pub monitoring_at: Option<String>,
    pub name: String,
    pub page_id: String,
    pub resolved_at: Option<String>,
    pub short_link: String,
    pub status: String,
    pub updated_at: String,
}

/// An update to an incident from the Discord status page.
///
/// This will typically state what new information has been discovered about an
/// incident.
#[derive(Clone, Debug, Deserialize)]
pub struct IncidentUpdate {
    pub affected_components: Vec<AffectedComponent>,
    pub body: String,
    pub created_at: String,
    pub display_at: String,
    pub id: String,
    pub incident_id: String,
    pub status: IncidentStatus,
    pub updated_at: String,
}

/// The type of status update during a service incident.
#[derive(Copy, Clone, Debug, Deserialize, Hash, Eq, PartialEq, PartialOrd, Ord, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum IncidentStatus {
    Identified,
    Investigating,
    Monitoring,
    Postmortem,
    Resolved,
}

/// A Discord status maintenance message. This can be either for active
/// maintenances or for scheduled maintenances.
#[derive(Clone, Debug, Deserialize)]
pub struct Maintenance {
    pub description: String,
    pub id: String,
    pub name: String,
    pub start: String,
    pub stop: String,
}
<|endoftext|>


<commit_before>//! Check the bodies of `const`s, `static`s and `const fn`s for illegal operations.
//!
//! This module will eventually replace the parts of `qualify_consts.rs` that check whether a local
//! has interior mutability or needs to be dropped, as well as the visitor that emits errors when
//! it finds operations that are invalid in a certain context.

use rustc::hir::{self, def_id::DefId};
use rustc::mir;
use rustc::ty::{self, TyCtxt};

use std::fmt;

pub use self::qualifs::Qualif;

pub mod ops;
pub mod qualifs;
mod resolver;
pub mod validation;

/// Information about the item currently being const-checked, as well as a reference to the global
/// context.
pub struct Item<'mir, 'tcx> {
    body: &'mir mir::Body<'tcx>,
    tcx: TyCtxt<'tcx>,
    def_id: DefId,
    param_env: ty::ParamEnv<'tcx>,
    const_kind: Option<ConstKind>,
}

impl Item<'mir, 'tcx> {
    pub fn new(
        tcx: TyCtxt<'tcx>,
        def_id: DefId,
        body: &'mir mir::Body<'tcx>,
    ) -> Self {
        let param_env = tcx.param_env(def_id);
        let const_kind = ConstKind::for_item(tcx, def_id);

        Item {
            body,
            tcx,
            def_id,
            param_env,
            const_kind,
        }
    }

    /// Returns the kind of const context this `Item` represents (`const`, `static`, etc.).
    ///
    /// Panics if this `Item` is not const.
    pub fn const_kind(&self) -> ConstKind {
        self.const_kind.expect("`const_kind` must not be called on a non-const fn")
    }
}

/// The kinds of items which require compile-time evaluation.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ConstKind {
    /// A `static` item.
    Static,
    /// A `static mut` item.
    StaticMut,
    /// A `const fn` item.
    ConstFn,
    /// A `const` item or an anonymous constant (e.g. in array lengths).
    Const,
}

impl ConstKind {
    /// Returns the validation mode for the item with the given `DefId`, or `None` if this item
    /// does not require validation (e.g. a non-const `fn`).
    pub fn for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<Self> {
        use hir::BodyOwnerKind as HirKind;

        let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();

        let mode = match tcx.hir().body_owner_kind(hir_id) {
            HirKind::Closure => return None,

            HirKind::Fn if tcx.is_const_fn(def_id) => ConstKind::ConstFn,
            HirKind::Fn => return None,

            HirKind::Const => ConstKind::Const,

            HirKind::Static(hir::MutImmutable) => ConstKind::Static,
            HirKind::Static(hir::MutMutable) => ConstKind::StaticMut,
        };

        Some(mode)
    }

    pub fn is_static(self) -> bool {
        match self {
            ConstKind::Static | ConstKind::StaticMut => true,
            ConstKind::ConstFn | ConstKind::Const => false,
        }
    }

    /// Returns `true` if the value returned by this item must be `Sync`.
    ///
    /// This returns false for `StaticMut` since all accesses to one are `unsafe` anyway.
    pub fn requires_sync(self) -> bool {
        match self {
            ConstKind::Static => true,
            ConstKind::ConstFn | ConstKind::Const |  ConstKind::StaticMut => false,
        }
    }
}

impl fmt::Display for ConstKind {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            ConstKind::Const => write!(f, "constant"),
            ConstKind::Static | ConstKind::StaticMut => write!(f, "static"),
            ConstKind::ConstFn => write!(f, "constant function"),
        }
    }
}

fn is_lang_panic_fn(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
    Some(def_id) == tcx.lang_items().panic_fn() ||
    Some(def_id) == tcx.lang_items().begin_panic_fn()
}
<commit_msg>Make `Item` fields pub<commit_after>//! Check the bodies of `const`s, `static`s and `const fn`s for illegal operations.
//!
//! This module will eventually replace the parts of `qualify_consts.rs` that check whether a local
//! has interior mutability or needs to be dropped, as well as the visitor that emits errors when
//! it finds operations that are invalid in a certain context.

use rustc::hir::{self, def_id::DefId};
use rustc::mir;
use rustc::ty::{self, TyCtxt};

use std::fmt;

pub use self::qualifs::Qualif;

pub mod ops;
pub mod qualifs;
mod resolver;
pub mod validation;

/// Information about the item currently being const-checked, as well as a reference to the global
/// context.
pub struct Item<'mir, 'tcx> {
    pub body: &'mir mir::Body<'tcx>,
    pub tcx: TyCtxt<'tcx>,
    pub def_id: DefId,
    pub param_env: ty::ParamEnv<'tcx>,
    pub const_kind: Option<ConstKind>,
}

impl Item<'mir, 'tcx> {
    pub fn new(
        tcx: TyCtxt<'tcx>,
        def_id: DefId,
        body: &'mir mir::Body<'tcx>,
    ) -> Self {
        let param_env = tcx.param_env(def_id);
        let const_kind = ConstKind::for_item(tcx, def_id);

        Item {
            body,
            tcx,
            def_id,
            param_env,
            const_kind,
        }
    }

    /// Returns the kind of const context this `Item` represents (`const`, `static`, etc.).
    ///
    /// Panics if this `Item` is not const.
    pub fn const_kind(&self) -> ConstKind {
        self.const_kind.expect("`const_kind` must not be called on a non-const fn")
    }
}

/// The kinds of items which require compile-time evaluation.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ConstKind {
    /// A `static` item.
    Static,
    /// A `static mut` item.
    StaticMut,
    /// A `const fn` item.
    ConstFn,
    /// A `const` item or an anonymous constant (e.g. in array lengths).
    Const,
}

impl ConstKind {
    /// Returns the validation mode for the item with the given `DefId`, or `None` if this item
    /// does not require validation (e.g. a non-const `fn`).
    pub fn for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<Self> {
        use hir::BodyOwnerKind as HirKind;

        let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();

        let mode = match tcx.hir().body_owner_kind(hir_id) {
            HirKind::Closure => return None,

            HirKind::Fn if tcx.is_const_fn(def_id) => ConstKind::ConstFn,
            HirKind::Fn => return None,

            HirKind::Const => ConstKind::Const,

            HirKind::Static(hir::MutImmutable) => ConstKind::Static,
            HirKind::Static(hir::MutMutable) => ConstKind::StaticMut,
        };

        Some(mode)
    }

    pub fn is_static(self) -> bool {
        match self {
            ConstKind::Static | ConstKind::StaticMut => true,
            ConstKind::ConstFn | ConstKind::Const => false,
        }
    }

    /// Returns `true` if the value returned by this item must be `Sync`.
    ///
    /// This returns false for `StaticMut` since all accesses to one are `unsafe` anyway.
    pub fn requires_sync(self) -> bool {
        match self {
            ConstKind::Static => true,
            ConstKind::ConstFn | ConstKind::Const |  ConstKind::StaticMut => false,
        }
    }
}

impl fmt::Display for ConstKind {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            ConstKind::Const => write!(f, "constant"),
            ConstKind::Static | ConstKind::StaticMut => write!(f, "static"),
            ConstKind::ConstFn => write!(f, "constant function"),
        }
    }
}

fn is_lang_panic_fn(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
    Some(def_id) == tcx.lang_items().panic_fn() ||
    Some(def_id) == tcx.lang_items().begin_panic_fn()
}
<|endoftext|>


<commit_before>use std::collections::{HashMap, HashSet};
use std::error::Error;
use std::iter::FromIterator;
use std::time::Duration;

use serialport as sp;
use errors::*;

/// Struct for containing Port information
struct OpenPort {
  /// The opened serial port
  /// SerialPort is not Sized, so it makes hashmap mad
  /// and so we deal with these shennanigans
  port: Box<sp::SerialPort>,
}

impl OpenPort {
  /// Write data to the serial port
  pub fn write_port(&mut self, data: &[u8]) -> Result<()> {
    self
      .port
      .write_all(data)
      .map_err(|err| ErrorKind::Io(err).into())
  }

  /// Read data from the serial port
  pub fn read_port(&mut self, buff: &mut [u8]) -> Result<usize> {
    self
      .port
      .read(buff)
      .map_err(|err| ErrorKind::Io(err).into())
  }
}

/// Manages ports and their locks
pub struct PortManager {
  /// Maintains list of ports
  open_ports: HashMap<String, OpenPort>,
}

impl PortManager {
  /// Create a new PortManager instance
  pub fn new() -> PortManager {
    PortManager { open_ports: HashMap::new() }
  }

  /// Has the port been opened
  pub fn is_port_open(&self, port_name: &String) -> bool {
    self.open_ports.contains_key(port_name)
  }

  /// List all serial ports
  pub fn list_ports(&self) -> Result<Vec<sp::SerialPortInfo>> {
    sp::available_ports().map_err(|e| ErrorKind::Serialport(e).into())
  }

  /// Open a port
  pub fn open_port(&mut self, port_name: &String) -> Result<()> {

    if self.is_port_open(port_name) {
      Ok(())
    } else {

      let sp_settings = sp::SerialPortSettings {
        baud_rate: sp::BaudRate::Baud115200,
        data_bits: sp::DataBits::Eight,
        flow_control: sp::FlowControl::None,
        parity: sp::Parity::None,
        stop_bits: sp::StopBits::One,
        timeout: Duration::from_millis(1),
      };

      match sp::open_with_settings(&port_name, &sp_settings) {
        Ok(serial_port) => {
          let open_port = OpenPort { port: serial_port };
          self.open_ports.insert(port_name.to_string(), open_port);
          Ok(())
        }
        Err(e) => Err(ErrorKind::Serialport(e).into()),
      }
    }
  }

  pub fn close_port(&mut self, port_name: &String) {
    // This drops the underlying serial port and box
    self.open_ports.remove(port_name);
  }

  /// Write data to the port
  /// To write data to a port the port must have been previously locked by sub_id
  pub fn write_port(&mut self, port_name: &String, data: &[u8]) -> Result<()> {
    match self.open_ports.get_mut(port_name) {
      None => Err(ErrorKind::OpenPortNotFound(port_name.to_string()).into()),
      Some(p) => p.write_port(data),
    }
  }

  /// Read data from a port into the buffer buff
  /// If successful, returns Ok(usize) which is the number of
  /// bytes read
  pub fn read_port(&mut self, port_name: &String, buff: &mut [u8]) -> Result<usize> {
    match self.open_ports.get_mut(port_name) {
      None => Err(ErrorKind::OpenPortNotFound(port_name.to_string()).into()),
      Some(p) => p.read_port(buff),
    }
  }

  /// Read all currently open ports, return a hashmap of
  /// ports to Result<Vec<u8>>
  pub fn read_all_ports(&mut self) -> HashMap<String, Result<Vec<u8>>> {
    let mut buffer = vec![0; 4096];
    let mut map = HashMap::new();
    for (port_name, open_port) in self.open_ports.iter_mut() {
      match open_port.read_port(buffer.as_mut_slice()) {
        Ok(bytes_read) => {
          if bytes_read == 0 {
            // EOF
            info!("Received EOF reading from port {}", port_name);
            map.insert(
              port_name.to_string(),
              Err(ErrorKind::PortEOFError(port_name.clone()).into()),
            );
          } else {
            let bytes = buffer[0..bytes_read].to_vec();
            map.insert(port_name.to_string(), Ok(bytes));
          }
        }
        Err(e) => {
          // debug!("Error {} reading from port {}", e, port_name);
          match e.description() {
            "Operation timed out" => {}
            _ => {
              map.insert(port_name.to_string(), Err(e.into()));
            }
          }

        }
      }
    }
    map
  }

  /// Get a vec of open ports
  pub fn open_ports(&self) -> HashSet<String> {
    HashSet::<String>::from_iter(self.open_ports.keys().map(|k| k.clone()))
  }
}
<commit_msg>Added tests for portmanager<commit_after>use std::collections::{HashMap, HashSet};
use std::error::Error;
use std::iter::FromIterator;
use std::time::Duration;

use serialport as sp;
use errors::*;

/// Struct for containing Port information
struct OpenPort {
  /// The opened serial port
  /// SerialPort is not Sized, so it makes hashmap mad
  /// and so we deal with these shennanigans
  port: Box<sp::SerialPort>,
}

impl OpenPort {
  /// Write data to the serial port
  pub fn write_port(&mut self, data: &[u8]) -> Result<()> {
    self
      .port
      .write_all(data)
      .map_err(|err| ErrorKind::Io(err).into())
  }

  /// Read data from the serial port
  pub fn read_port(&mut self, buff: &mut [u8]) -> Result<usize> {
    self
      .port
      .read(buff)
      .map_err(|err| ErrorKind::Io(err).into())
  }
}

/// Manages ports and their locks
pub struct PortManager {
  /// Maintains list of ports
  open_ports: HashMap<String, OpenPort>,
}

impl PortManager {
  /// Create a new PortManager instance
  pub fn new() -> PortManager {
    PortManager { open_ports: HashMap::new() }
  }

  /// Has the port been opened
  pub fn is_port_open(&self, port_name: &String) -> bool {
    self.open_ports.contains_key(port_name)
  }

  /// List all serial ports
  pub fn list_ports(&self) -> Result<Vec<sp::SerialPortInfo>> {
    sp::available_ports().map_err(|e| ErrorKind::Serialport(e).into())
  }

  /// Open a port
  pub fn open_port(&mut self, port_name: &String) -> Result<()> {

    if self.is_port_open(port_name) {
      Ok(())
    } else {

      let sp_settings = sp::SerialPortSettings {
        baud_rate: sp::BaudRate::Baud115200,
        data_bits: sp::DataBits::Eight,
        flow_control: sp::FlowControl::None,
        parity: sp::Parity::None,
        stop_bits: sp::StopBits::One,
        timeout: Duration::from_millis(1),
      };

      match sp::open_with_settings(&port_name, &sp_settings) {
        Ok(serial_port) => {
          let open_port = OpenPort { port: serial_port };
          self.open_ports.insert(port_name.to_string(), open_port);
          Ok(())
        }
        Err(e) => Err(ErrorKind::Serialport(e).into()),
      }
    }
  }

  pub fn close_port(&mut self, port_name: &String) {
    // This drops the underlying serial port and box
    self.open_ports.remove(port_name);
  }

  /// Write data to the port
  pub fn write_port(&mut self, port_name: &String, data: &[u8]) -> Result<()> {
    match self.open_ports.get_mut(port_name) {
      None => Err(ErrorKind::OpenPortNotFound(port_name.to_string()).into()),
      Some(p) => p.write_port(data),
    }
  }

  /// Read data from a port into the buffer buff
  /// If successful, returns Ok(usize) which is the number of
  /// bytes read
  pub fn read_port(&mut self, port_name: &String, buff: &mut [u8]) -> Result<usize> {
    match self.open_ports.get_mut(port_name) {
      None => Err(ErrorKind::OpenPortNotFound(port_name.to_string()).into()),
      Some(p) => p.read_port(buff),
    }
  }

  /// Read all currently open ports, return a hashmap of
  /// ports to Result<Vec<u8>>
  pub fn read_all_ports(&mut self) -> HashMap<String, Result<Vec<u8>>> {
    let mut buffer = vec![0; 4096];
    let mut map = HashMap::new();
    for (port_name, open_port) in self.open_ports.iter_mut() {
      match open_port.read_port(buffer.as_mut_slice()) {
        Ok(bytes_read) => {
          if bytes_read == 0 {
            // EOF
            info!("Received EOF reading from port {}", port_name);
            map.insert(
              port_name.to_string(),
              Err(ErrorKind::PortEOFError(port_name.clone()).into()),
            );
          } else {
            let bytes = buffer[0..bytes_read].to_vec();
            map.insert(port_name.to_string(), Ok(bytes));
          }
        }
        Err(e) => {
          // debug!("Error {} reading from port {}", e, port_name);
          match e.description() {
            "Operation timed out" => {}
            _ => {
              map.insert(port_name.to_string(), Err(e.into()));
            }
          }

        }
      }
    }
    map
  }

  /// Get a vec of open ports
  pub fn open_ports(&self) -> HashSet<String> {
    HashSet::<String>::from_iter(self.open_ports.keys().map(|k| k.clone()))
  }
}

#[cfg(test)]
mod tests {

  use std::io::Write;

  use serialport::SerialPort;
  use serialport::posix::TTYPort;

  use super::*;

  #[test]
  #[cfg(unix)]
  fn test_unix_serialports() {

    let (mut master, mut slave) = TTYPort::pair().expect("Failed to create pseudoterminal pair!");

    slave
      .set_exclusive(false)
      .expect("Failed to set exclusive false");

    let serial_msg = "abcdefg";

    if let Some(s_name) = slave.port_name() {
      let mut port_manager = PortManager::new();

      port_manager
        .open_port(&s_name)
        .expect(&format!("Failed to open slave port {}", s_name));

      master
        .write(serial_msg.as_bytes())
        .expect("Write to master failed!");

      let res = port_manager.read_all_ports();

      assert_eq!(res.len(), 1, "Should have read one port.");

      for (port_name, value) in res {
        match value {
          Ok(bytes) => {
            let read_msg = String::from_utf8_lossy(&bytes);
            assert_eq!(
              serial_msg,
              read_msg,
              "Messages should be same '{}' '{}'",
              serial_msg,
              read_msg
            );
          }
          Err(e) => panic!("Got error reading port {}", e),
        }
      }
    } else {
      panic!("Failed to get slave pty name");
    }
  }

  // TODO: write to slave, read from master

}<|endoftext|>


<commit_before>use std::collections::HashSet;
use std::io::{Write, BufWriter};
use std::fs::File;
use std::path::{Path, PathBuf};

use ops::{Context, Unit};
use util::{CargoResult, internal};
use util::paths;
use ops::cargo_rustc::fingerprint;

fn render_filename<P: AsRef<Path>>(path: P, basedir: Option<&str>) -> CargoResult<String> {
    let path = path.as_ref();
    let relpath = match basedir {
        None => path,
        Some(base) => match path.strip_prefix(base) {
            Ok(relpath) => relpath,
            _ => path,
        }
    };
    relpath.to_str().ok_or_else(|| internal("path not utf-8")).map(|f| f.replace(" ", "\\ "))
}

fn add_deps_for_unit<'a, 'b>(
    deps: &mut HashSet<PathBuf>,
    context: &mut Context<'a, 'b>,
    unit: &Unit<'a>,
    visited: &mut HashSet<Unit<'a>>,
)
    -> CargoResult<()>
{
    if !visited.insert(*unit) {
        return Ok(());
    }

    // units representing the execution of a build script don't actually
    // generate a dep info file, so we just keep on going below
    if !unit.profile.run_custom_build {
        // Add dependencies from rustc dep-info output (stored in fingerprint directory)
        let dep_info_loc = fingerprint::dep_info_loc(context, unit);
        if let Some(paths) = fingerprint::parse_dep_info(unit.pkg, &dep_info_loc)? {
            for path in paths {
                deps.insert(path);
            }
        } else {
            debug!("can't find dep_info for {:?} {:?}",
                unit.pkg.package_id(), unit.profile);
            return Err(internal("dep_info missing"));
        }
    }

    // Add rerun-if-changed dependencies
    let key = (unit.pkg.package_id().clone(), unit.kind);
    if let Some(output) = context.build_state.outputs.lock().unwrap().get(&key) {
        for path in &output.rerun_if_changed {
            deps.insert(path.into());
        }
    }

    // Recursively traverse all transitive dependencies
    for dep_unit in &context.dep_targets(unit)? {
        let source_id = dep_unit.pkg.package_id().source_id();
        if source_id.is_path() {
            add_deps_for_unit(deps, context, dep_unit, visited)?;
        }
    }
    Ok(())
}

pub fn output_depinfo<'a, 'b>(context: &mut Context<'a, 'b>, unit: &Unit<'a>) -> CargoResult<()> {
    let mut deps = HashSet::new();
    let mut visited = HashSet::new();
    let success = add_deps_for_unit(&mut deps, context, unit, &mut visited).is_ok();
    let basedir_string;
    let basedir = match context.config.get_string("dep-info-basedir") {
        Ok(config) => {
            match config {
                Some(value) => {
                    basedir_string = value.val;
                    Some(basedir_string.as_str())
                }
                None => None,
            }
        },
        _ => None
    };
    for &(_, ref link_dst, _) in context.target_filenames(unit)?.iter() {
        if let Some(ref link_dst) = *link_dst {
            let output_path = link_dst.with_extension("d");
            if success {
                let mut outfile = BufWriter::new(File::create(output_path)?);
                let target_fn = render_filename(link_dst, basedir)?;
                write!(outfile, "{}:", target_fn)?;
                for dep in &deps {
                    write!(outfile, " {}", render_filename(dep, basedir)?)?;
                }
                writeln!(outfile, "")?;

            // dep-info generation failed, so delete output file. This will
            // usually cause the build system to always rerun the build
            // rule, which is correct if inefficient.
            } else if output_path.exists() {
                paths::remove_file(output_path)?;
            }
        }
    }
    Ok(())
}
<commit_msg>Return errors instead of ignoring them<commit_after>use std::collections::HashSet;
use std::io::{Write, BufWriter};
use std::fs::File;
use std::path::{Path, PathBuf};

use ops::{Context, Unit};
use util::{CargoResult, internal};
use util::paths;
use ops::cargo_rustc::fingerprint;

fn render_filename<P: AsRef<Path>>(path: P, basedir: Option<&str>) -> CargoResult<String> {
    let path = path.as_ref();
    let relpath = match basedir {
        None => path,
        Some(base) => match path.strip_prefix(base) {
            Ok(relpath) => relpath,
            _ => path,
        }
    };
    relpath.to_str().ok_or_else(|| internal("path not utf-8")).map(|f| f.replace(" ", "\\ "))
}

fn add_deps_for_unit<'a, 'b>(
    deps: &mut HashSet<PathBuf>,
    context: &mut Context<'a, 'b>,
    unit: &Unit<'a>,
    visited: &mut HashSet<Unit<'a>>,
)
    -> CargoResult<()>
{
    if !visited.insert(*unit) {
        return Ok(());
    }

    // units representing the execution of a build script don't actually
    // generate a dep info file, so we just keep on going below
    if !unit.profile.run_custom_build {
        // Add dependencies from rustc dep-info output (stored in fingerprint directory)
        let dep_info_loc = fingerprint::dep_info_loc(context, unit);
        if let Some(paths) = fingerprint::parse_dep_info(unit.pkg, &dep_info_loc)? {
            for path in paths {
                deps.insert(path);
            }
        } else {
            debug!("can't find dep_info for {:?} {:?}",
                unit.pkg.package_id(), unit.profile);
            return Err(internal("dep_info missing"));
        }
    }

    // Add rerun-if-changed dependencies
    let key = (unit.pkg.package_id().clone(), unit.kind);
    if let Some(output) = context.build_state.outputs.lock().unwrap().get(&key) {
        for path in &output.rerun_if_changed {
            deps.insert(path.into());
        }
    }

    // Recursively traverse all transitive dependencies
    for dep_unit in &context.dep_targets(unit)? {
        let source_id = dep_unit.pkg.package_id().source_id();
        if source_id.is_path() {
            add_deps_for_unit(deps, context, dep_unit, visited)?;
        }
    }
    Ok(())
}

pub fn output_depinfo<'a, 'b>(context: &mut Context<'a, 'b>, unit: &Unit<'a>) -> CargoResult<()> {
    let mut deps = HashSet::new();
    let mut visited = HashSet::new();
    let success = add_deps_for_unit(&mut deps, context, unit, &mut visited).is_ok();
    let basedir_string;
    let basedir = match context.config.get_string("dep-info-basedir")? {
        Some(value) => {
            basedir_string = value.val;
            Some(basedir_string.as_str())
        }
        None => None,
    };
    for &(_, ref link_dst, _) in context.target_filenames(unit)?.iter() {
        if let Some(ref link_dst) = *link_dst {
            let output_path = link_dst.with_extension("d");
            if success {
                let mut outfile = BufWriter::new(File::create(output_path)?);
                let target_fn = render_filename(link_dst, basedir)?;
                write!(outfile, "{}:", target_fn)?;
                for dep in &deps {
                    write!(outfile, " {}", render_filename(dep, basedir)?)?;
                }
                writeln!(outfile, "")?;

            // dep-info generation failed, so delete output file. This will
            // usually cause the build system to always rerun the build
            // rule, which is correct if inefficient.
            } else if output_path.exists() {
                paths::remove_file(output_path)?;
            }
        }
    }
    Ok(())
}
<|endoftext|>


<commit_before>mod error;
mod state;
mod thread;

use self::error::Error;
pub use self::state::{PlayerState, PlayerStatus};
use self::thread::spawn_player;

use ao;
use pandora::{Pandora, Station};

use std::thread::JoinHandle;
use std::sync::{Arc, Mutex, MutexGuard};
use std::sync::mpsc::{channel, Sender, Receiver};

/// Player type for playing audio in a separate thread, with a channel
/// for communication.
pub struct Player {
    #[allow(dead_code)]
    ao: ao::Ao,
    player_handle: Option<JoinHandle<()>>,

    // Player state.
    state: Arc<Mutex<PlayerState>>,

    // Sender for notifying the player thread of different actions.
    // Receiver for getting player status.
    sender: Sender<PlayerAction>,
    receiver: Receiver<Result<PlayerStatus, Error>>,
}

impl Drop for Player {
    fn drop(&mut self) {
        // Thread needs to be running to receive a message
        // so we need to unpause it.
        self.unpause();

        // Notifies the thread to exit.
        self.sender.send(PlayerAction::Exit).unwrap();

        // Waits for the thread to stop.
        if let Some(player_handle) = self.player_handle.take() {
            player_handle.join().unwrap();
        }
    }
}

impl Player {
    /// Creates a new Player.
    pub fn new(pandora: &Arc<Pandora>) -> Self {
        // Initialize AO before anything else.
        let ao = ao::Ao::new();

        let state = Arc::new(Mutex::new(PlayerState::new()));

        let (external_sender, receiver) = channel();
        let (sender, external_receiver) = channel();
        let player_handle = spawn_player(pandora, &state, sender, receiver);

        Player {
            ao: ao,
            player_handle: Some(player_handle),

            state: state,

            sender: external_sender,
            receiver: external_receiver,
        }
    }

    /// Returns the player state. Note that this function is synchronized with the player
    /// thread, meaning that it blocks until "state" is available.
    pub fn state(&self) -> MutexGuard<PlayerState> {
        self.state.lock().unwrap()
    }

    //
    // Player control functions
    //

    /// Starts playing the given station.
    pub fn play(&mut self, station: Station) {
        self.sender.send(PlayerAction::Play(station)).unwrap();
    }

    /// Stops the current station.
    pub fn stop(&mut self) {
        self.sender.send(PlayerAction::Stop).unwrap();
    }

    /// Pauses the audio thread.
    pub fn pause(&mut self) {
        self.sender.send(PlayerAction::Pause).unwrap();;
    }

    /// Unpauses the audio thread.
    pub fn unpause(&mut self) {
        self.sender.send(PlayerAction::Unpause).unwrap();
    }

    /// Skips the current track (if any is playing).
    pub fn skip(&mut self) {
        self.unpause();
        self.sender.send(PlayerAction::Skip).unwrap();
    }

    /// Toggles pause / unpause.
    pub fn toggle_pause(&mut self) {
        if self.is_paused() {
            self.unpause();
        }
        else {
            self.pause();
        }
    }

    /// Requests the player to send an event reporting its current status.
    pub fn report(&self) {
        self.sender.send(PlayerAction::Report).unwrap();
    }

    //
    // PLayer state functions
    //

    /// Returns true if the player is starting.
    pub fn is_started(&self) -> bool {
        self.state.lock().unwrap().status().is_started()
    }

    /// Returns true if the player is stopped (waiting for a Play action).
    pub fn is_stopped(&self) -> bool {
        self.state.lock().unwrap().status().is_stopped()
    }

    /// Returns true if the player is fetching tracks.
    pub fn is_fetching(&self) -> bool {
        self.state.lock().unwrap().status().is_fetching()
    }

    /// Returns true if the player is playing audio.
    pub fn is_playing(&self) -> bool {
        self.state.lock().unwrap().status().is_playing()
    }

    /// Returns true if the player has just finished audio.
    pub fn is_finished(&self) -> bool {
        self.state.lock().unwrap().status().is_finished()
    }

    /// Returns true if the player is paused.
    pub fn is_paused(&self) -> bool {
        self.state.lock().unwrap().status().is_paused()
    }

    /// Returns true if the player is shutdown.
    pub fn is_shutdown(&self) -> bool {
        self.state.lock().unwrap().status().is_shutdown()
    }

    /// Returns the most recent status from the player.
    ///
    /// # Returns
    /// * Result(PlayerStatus) when the thread is running and emitting
    /// messages.
    /// * Error(err) when the thread sent an error instead.
    pub fn next_status(&self) -> Result<PlayerStatus, Error> {
        self.receiver.recv().unwrap()
    }

    /// Returns the most recent status from the player without blocking.
    ///
    /// # Returns
    /// * Result(PlayerStatus) when the thread is running and emitting
    /// messages.
    /// * Error(err) when the thread sent an error instead.
    pub fn try_next_status(&self) -> Option<Result<PlayerStatus, Error>> {
        if let Ok(s) = self.receiver.try_recv() {
            Some(s)
        }
        else {
            None
        }
    }
}

/// Enumeration type for sending player actions.
pub enum PlayerAction {
    // Station related actions.
    Play(Station),
    Stop,

    // Track related actions.
    Pause,
    Unpause,
    Skip,

    // Misc actions.
    Report,
    Exit,
}
<commit_msg>Unpauses when playing new station<commit_after>mod error;
mod state;
mod thread;

use self::error::Error;
pub use self::state::{PlayerState, PlayerStatus};
use self::thread::spawn_player;

use ao;
use pandora::{Pandora, Station};

use std::thread::JoinHandle;
use std::sync::{Arc, Mutex, MutexGuard};
use std::sync::mpsc::{channel, Sender, Receiver};

/// Player type for playing audio in a separate thread, with a channel
/// for communication.
pub struct Player {
    #[allow(dead_code)]
    ao: ao::Ao,
    player_handle: Option<JoinHandle<()>>,

    // Player state.
    state: Arc<Mutex<PlayerState>>,

    // Sender for notifying the player thread of different actions.
    // Receiver for getting player status.
    sender: Sender<PlayerAction>,
    receiver: Receiver<Result<PlayerStatus, Error>>,
}

impl Drop for Player {
    fn drop(&mut self) {
        // Thread needs to be running to receive a message
        // so we need to unpause it.
        self.unpause();

        // Notifies the thread to exit.
        self.sender.send(PlayerAction::Exit).unwrap();

        // Waits for the thread to stop.
        if let Some(player_handle) = self.player_handle.take() {
            player_handle.join().unwrap();
        }
    }
}

impl Player {
    /// Creates a new Player.
    pub fn new(pandora: &Arc<Pandora>) -> Self {
        // Initialize AO before anything else.
        let ao = ao::Ao::new();

        let state = Arc::new(Mutex::new(PlayerState::new()));

        let (external_sender, receiver) = channel();
        let (sender, external_receiver) = channel();
        let player_handle = spawn_player(pandora, &state, sender, receiver);

        Player {
            ao: ao,
            player_handle: Some(player_handle),

            state: state,

            sender: external_sender,
            receiver: external_receiver,
        }
    }

    /// Returns the player state. Note that this function is synchronized with the player
    /// thread, meaning that it blocks until "state" is available.
    pub fn state(&self) -> MutexGuard<PlayerState> {
        self.state.lock().unwrap()
    }

    //
    // Player control functions
    //

    /// Starts playing the given station.
    pub fn play(&mut self, station: Station) {
        self.unpause();
        self.sender.send(PlayerAction::Play(station)).unwrap();
    }

    /// Stops the current station.
    pub fn stop(&mut self) {
        self.sender.send(PlayerAction::Stop).unwrap();
    }

    /// Pauses the audio thread.
    pub fn pause(&mut self) {
        self.sender.send(PlayerAction::Pause).unwrap();;
    }

    /// Unpauses the audio thread.
    pub fn unpause(&mut self) {
        self.sender.send(PlayerAction::Unpause).unwrap();
    }

    /// Skips the current track (if any is playing).
    pub fn skip(&mut self) {
        self.unpause();
        self.sender.send(PlayerAction::Skip).unwrap();
    }

    /// Toggles pause / unpause.
    pub fn toggle_pause(&mut self) {
        if self.is_paused() {
            self.unpause();
        }
        else {
            self.pause();
        }
    }

    /// Requests the player to send an event reporting its current status.
    pub fn report(&self) {
        self.sender.send(PlayerAction::Report).unwrap();
    }

    //
    // PLayer state functions
    //

    /// Returns true if the player is starting.
    pub fn is_started(&self) -> bool {
        self.state.lock().unwrap().status().is_started()
    }

    /// Returns true if the player is stopped (waiting for a Play action).
    pub fn is_stopped(&self) -> bool {
        self.state.lock().unwrap().status().is_stopped()
    }

    /// Returns true if the player is fetching tracks.
    pub fn is_fetching(&self) -> bool {
        self.state.lock().unwrap().status().is_fetching()
    }

    /// Returns true if the player is playing audio.
    pub fn is_playing(&self) -> bool {
        self.state.lock().unwrap().status().is_playing()
    }

    /// Returns true if the player has just finished audio.
    pub fn is_finished(&self) -> bool {
        self.state.lock().unwrap().status().is_finished()
    }

    /// Returns true if the player is paused.
    pub fn is_paused(&self) -> bool {
        self.state.lock().unwrap().status().is_paused()
    }

    /// Returns true if the player is shutdown.
    pub fn is_shutdown(&self) -> bool {
        self.state.lock().unwrap().status().is_shutdown()
    }

    /// Returns the most recent status from the player.
    ///
    /// # Returns
    /// * Result(PlayerStatus) when the thread is running and emitting
    /// messages.
    /// * Error(err) when the thread sent an error instead.
    pub fn next_status(&self) -> Result<PlayerStatus, Error> {
        self.receiver.recv().unwrap()
    }

    /// Returns the most recent status from the player without blocking.
    ///
    /// # Returns
    /// * Result(PlayerStatus) when the thread is running and emitting
    /// messages.
    /// * Error(err) when the thread sent an error instead.
    pub fn try_next_status(&self) -> Option<Result<PlayerStatus, Error>> {
        if let Ok(s) = self.receiver.try_recv() {
            Some(s)
        }
        else {
            None
        }
    }
}

/// Enumeration type for sending player actions.
pub enum PlayerAction {
    // Station related actions.
    Play(Station),
    Stop,

    // Track related actions.
    Pause,
    Unpause,
    Skip,

    // Misc actions.
    Report,
    Exit,
}
<|endoftext|>


<commit_before>//! Hack-y crate used for development until canonical_json supports serde 0.9
// TODO remove me

use itoa;
use json;
use std::collections::BTreeMap;
use std::io;

// TODO this is actually borked. Beacuse we pass in JSON that has already been parsed
// something like the sequence"\n" has been converted into an actual new line.
// Either unescape everthing in the convert function or (ideally) to patch the
// canonical_json lib. However, this works for testing which is good enough for
// development for now. (sorry future self)
pub fn canonicalize(jsn: json::Value) -> Result<Vec<u8>, String> {
    let converted = convert(jsn)?;
    let mut buf = Vec::new();
    let _ = converted.write(&mut buf); // Vec<u8> impl always succeeds (or panics).
    Ok(buf)
}

enum Value {
    Array(Vec<Value>),
    Bool(bool),
    Null,
    Number(Number),
    Object(BTreeMap<String, Value>),
    String(String),
}

impl Value {
    fn write(&self, mut buf: &mut Vec<u8>) -> Result<(), String> {
        match self {
            &Value::Null => Ok(buf.extend(b"null")),
            &Value::Bool(true) => Ok(buf.extend(b"true")),
            &Value::Bool(false) => Ok(buf.extend(b"false")),
            &Value::Number(Number::I64(n)) => {
                itoa::write(buf, n)
                    .map(|_| ())
                    .map_err(|err| format!("Write error: {}", err))
            }
            &Value::Number(Number::U64(n)) => {
                itoa::write(buf, n)
                    .map(|_| ())
                    .map_err(|err| format!("Write error: {}", err))
            }
            &Value::String(ref s) => {
                escape_str(&mut buf, &s).map_err(|err| format!("Write error: {}", err))
            }
            &Value::Array(ref arr) => {
                buf.push(b'[');
                let mut first = true;
                for a in arr.iter() {
                    if !first {
                        buf.push(b',');
                    }
                    a.write(&mut buf)?;
                    first = false;
                }
                Ok(buf.push(b']'))
            }
            &Value::Object(ref obj) => {
                buf.push(b'{');
                let mut first = true;
                for (k, v) in obj.iter() {
                    if !first {
                        buf.push(b',');
                    }
                    first = false;
                    escape_str(&mut buf, &k).map_err(|err| format!("Write error: {}", err))?;
                    buf.push(b':');
                    v.write(&mut buf)?;
                }
                Ok(buf.push(b'}'))
            }
        }
    }
}

enum Number {
    I64(i64),
    U64(u64),
}

fn convert(jsn: json::Value) -> Result<Value, String> {
    match jsn {
        json::Value::Null => Ok(Value::Null),
        json::Value::Bool(b) => Ok(Value::Bool(b)),
        json::Value::Number(n) => {
            n.as_i64()
                .map(Number::I64)
                .or(n.as_u64().map(Number::U64))
                .map(Value::Number)
                .ok_or_else(|| String::from("only i64 and u64 are supported"))
        }
        json::Value::Array(arr) => {
            let mut out = Vec::new();
            for res in arr.iter().cloned().map(|v| convert(v)) {
                out.push(res?)
            }
            Ok(Value::Array(out))
        }
        json::Value::Object(obj) => {
            let mut out = BTreeMap::new();
            for (k, v) in obj.iter() {
                let _ = out.insert(k.clone(), convert(v.clone())?);
            }
            Ok(Value::Object(out))
        }
        json::Value::String(s) => Ok(Value::String(s)),
    }
}

/// Serializes and escapes a `&str` into a JSON string.
fn escape_str<W>(wr: &mut W, value: &str) -> Result<(), io::Error>
    where W: io::Write
{
    let bytes = value.as_bytes();

    wr.write_all(b"\"")?;

    let mut start = 0;

    for (i, &byte) in bytes.iter().enumerate() {
        let escape = ESCAPE[byte as usize];
        if escape == 0 {
            continue;
        }

        if start < i {
            wr.write_all(&bytes[start..i])?;
        }

        wr.write_all(&[b'\\', escape])?;

        start = i + 1;
    }

    if start != bytes.len() {
        wr.write_all(&bytes[start..])?;
    }

    wr.write_all(b"\"")?;
    Ok(())
}

const QU: u8 = b'"'; // \x22
const BS: u8 = b'\\'; // \x5C

// Lookup table of escape sequences. A value of b'x' at index i means that byte
// i is escaped as "\x" in JSON. A value of 0 means that byte i is not escaped.
#[cfg_attr(rustfmt, rustfmt_skip)]
static ESCAPE: [u8; 256] = [
    //  1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 0
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 1
    0,  0, QU,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 2
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 3
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 4
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, BS,  0,  0,  0, // 5
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 6
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 7
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 8
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 9
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // A
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // B
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // C
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // D
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // E
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // F
];

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

    use std::fs::File;
    use std::io::Read;

    #[test]
    fn write_str() {
        let jsn = Value::String(String::from("wat"));
        let mut out = Vec::new();
        jsn.write(&mut out).expect("write failed");
        assert_eq!(&out, b"\"wat\"");
    }

    #[test]
    fn write_arr() {
        let jsn = Value::Array(vec![Value::String(String::from("wat")),
                                    Value::String(String::from("lol")),
                                    Value::String(String::from("no"))]);
        let mut out = Vec::new();
        jsn.write(&mut out).expect("write failed");
        assert_eq!(&out, b"[\"wat\",\"lol\",\"no\"]");
    }

    #[test]
    fn write_obj() {
        let mut map = BTreeMap::new();
        let arr = Value::Array(vec![Value::String(String::from("haha")),
                                    Value::String(String::from("omg so tired"))]);
        let _ = map.insert(String::from("lol"), arr);
        let jsn = Value::Object(map);
        let mut out = Vec::new();
        jsn.write(&mut out).expect("write failed");
        assert_eq!(&out, b"{\"lol\":[\"haha\",\"omg so tired\"]}");
    }

    #[test]
    fn root_json() {
        let mut file = File::open("./tests/cjson/root.json").expect("couldn't open root.json");
        let mut buf = Vec::new();
        file.read_to_end(&mut buf).expect("couldn't read root.json");
        let jsn = json::from_slice(&buf).expect("not json");
        let out = canonicalize(jsn).expect("couldn't canonicalize");
        assert_eq!(out, buf);
    }
}
<commit_msg>updated todos/warnings in cjson module<commit_after>use itoa;
use json;
use std::collections::BTreeMap;
use std::io;

pub fn canonicalize(jsn: json::Value) -> Result<Vec<u8>, String> {
    let converted = convert(jsn)?;
    let mut buf = Vec::new();
    let _ = converted.write(&mut buf); // Vec<u8> impl always succeeds (or panics).
    Ok(buf)
}

enum Value {
    Array(Vec<Value>),
    Bool(bool),
    Null,
    Number(Number),
    // TODO this needs to be &[u8] and not String
    Object(BTreeMap<String, Value>),
    String(String),
}

impl Value {
    fn write(&self, mut buf: &mut Vec<u8>) -> Result<(), String> {
        match self {
            &Value::Null => Ok(buf.extend(b"null")),
            &Value::Bool(true) => Ok(buf.extend(b"true")),
            &Value::Bool(false) => Ok(buf.extend(b"false")),
            &Value::Number(Number::I64(n)) => {
                itoa::write(buf, n)
                    .map(|_| ())
                    .map_err(|err| format!("Write error: {}", err))
            }
            &Value::Number(Number::U64(n)) => {
                itoa::write(buf, n)
                    .map(|_| ())
                    .map_err(|err| format!("Write error: {}", err))
            }
            &Value::String(ref s) => {
                escape_str(&mut buf, &s).map_err(|err| format!("Write error: {}", err))
            }
            &Value::Array(ref arr) => {
                buf.push(b'[');
                let mut first = true;
                for a in arr.iter() {
                    if !first {
                        buf.push(b',');
                    }
                    a.write(&mut buf)?;
                    first = false;
                }
                Ok(buf.push(b']'))
            }
            &Value::Object(ref obj) => {
                buf.push(b'{');
                let mut first = true;
                for (k, v) in obj.iter() {
                    if !first {
                        buf.push(b',');
                    }
                    first = false;
                    escape_str(&mut buf, &k).map_err(|err| format!("Write error: {}", err))?;
                    buf.push(b':');
                    v.write(&mut buf)?;
                }
                Ok(buf.push(b'}'))
            }
        }
    }
}

enum Number {
    I64(i64),
    U64(u64),
}

fn convert(jsn: json::Value) -> Result<Value, String> {
    match jsn {
        json::Value::Null => Ok(Value::Null),
        json::Value::Bool(b) => Ok(Value::Bool(b)),
        json::Value::Number(n) => {
            n.as_i64()
                .map(Number::I64)
                .or(n.as_u64().map(Number::U64))
                .map(Value::Number)
                .ok_or_else(|| String::from("only i64 and u64 are supported"))
        }
        json::Value::Array(arr) => {
            let mut out = Vec::new();
            for res in arr.iter().cloned().map(|v| convert(v)) {
                out.push(res?)
            }
            Ok(Value::Array(out))
        }
        json::Value::Object(obj) => {
            let mut out = BTreeMap::new();
            for (k, v) in obj.iter() {
                let _ = out.insert(k.clone(), convert(v.clone())?);
            }
            Ok(Value::Object(out))
        }
        json::Value::String(s) => Ok(Value::String(s)),
    }
}

/// Serializes and escapes a `&str` into a JSON string.
fn escape_str<W>(wr: &mut W, value: &str) -> Result<(), io::Error>
    where W: io::Write
{
    let bytes = value.as_bytes();

    wr.write_all(b"\"")?;

    let mut start = 0;

    for (i, &byte) in bytes.iter().enumerate() {
        let escape = ESCAPE[byte as usize];
        if escape == 0 {
            continue;
        }

        if start < i {
            wr.write_all(&bytes[start..i])?;
        }

        wr.write_all(&[b'\\', escape])?;

        start = i + 1;
    }

    if start != bytes.len() {
        wr.write_all(&bytes[start..])?;
    }

    wr.write_all(b"\"")?;
    Ok(())
}

const QU: u8 = b'"'; // \x22
const BS: u8 = b'\\'; // \x5C

// Lookup table of escape sequences. A value of b'x' at index i means that byte
// i is escaped as "\x" in JSON. A value of 0 means that byte i is not escaped.
#[cfg_attr(rustfmt, rustfmt_skip)]
static ESCAPE: [u8; 256] = [
    //  1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 0
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 1
    0,  0, QU,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 2
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 3
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 4
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, BS,  0,  0,  0, // 5
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 6
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 7
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 8
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 9
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // A
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // B
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // C
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // D
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // E
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // F
];

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

    use std::fs::File;
    use std::io::Read;

    #[test]
    fn write_str() {
        let jsn = Value::String(String::from("wat"));
        let mut out = Vec::new();
        jsn.write(&mut out).expect("write failed");
        assert_eq!(&out, b"\"wat\"");
    }

    #[test]
    fn write_arr() {
        let jsn = Value::Array(vec![Value::String(String::from("wat")),
                                    Value::String(String::from("lol")),
                                    Value::String(String::from("no"))]);
        let mut out = Vec::new();
        jsn.write(&mut out).expect("write failed");
        assert_eq!(&out, b"[\"wat\",\"lol\",\"no\"]");
    }

    #[test]
    fn write_obj() {
        let mut map = BTreeMap::new();
        let arr = Value::Array(vec![Value::String(String::from("haha")),
                                    Value::String(String::from("omg so tired"))]);
        let _ = map.insert(String::from("lol"), arr);
        let jsn = Value::Object(map);
        let mut out = Vec::new();
        jsn.write(&mut out).expect("write failed");
        assert_eq!(&out, b"{\"lol\":[\"haha\",\"omg so tired\"]}");
    }

    #[test]
    fn root_json() {
        let mut file = File::open("./tests/cjson/root.json").expect("couldn't open root.json");
        let mut buf = Vec::new();
        file.read_to_end(&mut buf).expect("couldn't read root.json");
        let jsn = json::from_slice(&buf).expect("not json");
        let out = canonicalize(jsn).expect("couldn't canonicalize");
        assert_eq!(out, buf);
    }
}
<|endoftext|>


<commit_before>use std::hashmap::HashMap;

use extra::future::Future;
use extra::arc::Arc;

use def::Constant;

mod method;

type JavaClassRef = Arc<JavaClass>;

pub struct JavaClass {
	priv name : ~str,
	priv attrs : uint,
	priv constants : ~[Constant],
	priv parents : ~[ JavaClassRef ],
	priv methods : ~HashMap<~str, ~method::JavaMethod>,
}

impl JavaClass {

	// ----------------------------------------------
	pub fn new(constants : ~[Constant], parents : ~[ JavaClassRef ] )
	-> JavaClass
	{
		JavaClass {
			name: ~"",
			attrs: 0,
			methods : ~HashMap::with_capacity(16),
			constants : constants,
			parents : parents
		}
	}

	// ----------------------------------------------
	/* pub fn get_name<'a>(&'a self) -> &'a str {
		&'a self.name
	} */
}

<commit_msg>fix JavaClass::get_name<commit_after>use std::hashmap::HashMap;

use extra::future::Future;
use extra::arc::Arc;

use def::Constant;

mod method;

type JavaClassRef = Arc<JavaClass>;

pub struct JavaClass {
	priv name : ~str,
	priv attrs : uint,
	priv constants : ~[Constant],
	priv parents : ~[ JavaClassRef ],
	priv methods : ~HashMap<~str, ~method::JavaMethod>,
}

impl JavaClass {

	// ----------------------------------------------
	pub fn new(constants : ~[Constant], parents : ~[ JavaClassRef ] )
	-> JavaClass
	{
		JavaClass {
			name: ~"",
			attrs: 0,
			methods : ~HashMap::with_capacity(16),
			constants : constants,
			parents : parents
		}
	}

	// ----------------------------------------------
	pub fn get_name<'a>(&'a self) -> &'a ~str {
		return &self.name
	}
}

<|endoftext|>


<commit_before>// http://rosettacode.org/wiki/Arithmetric-geometric_mean
// Accepts two command line arguments
// cargo run --name agm arg1 arg2

use std::{num, os};

#[cfg(not(test))]
fn main () {
    let args = os::args();
    let args = args.as_slice();

    let x = from_str::<f32>(args[1].as_slice()).unwrap() ;
    let y = from_str::<f32>(args[2].as_slice()).unwrap() ;

    let result = agm(x,y);
    println!("The arithmetic-geometric mean is {}", result);
}

fn agm (x: f32, y: f32) -> f32 {
    let e: f32 = 0.000001;
    let mut a = x;
    let mut g = y;
    let mut a1: f32;
    let mut g1: f32;

    loop {
        a1 = (a + g) / 2f32;
        g1 = (a * g).sqrt();
        a = a1;
        g = g1;
        if num::abs( a - g) < e {  return a; }
    }

}

#[test]
fn test_agm_12_6() {
    assert! ( agm(12f32,6f32) == 8.740746f32 );
}
<commit_msg>Fixed test warning, added negative value test and failure to fn agm<commit_after>// http://rosettacode.org/wiki/Arithmetric-geometric_mean
// Accepts two command line arguments
// cargo run --name agm arg1 arg2

use std::num;

#[cfg(not(test))]
fn main () {
    let args = std::os::args();
    let args = args.as_slice();

    let x = from_str::<f32>(args[1].as_slice()).unwrap() ;
    let y = from_str::<f32>(args[2].as_slice()).unwrap() ;

    let result = agm(x,y);
    println!("The arithmetic-geometric mean is {}", result);
}

fn agm (x: f32, y: f32) -> f32 {
    let e: f32 = 0.000001;
    let mut a = x;
    let mut g = y;
    let mut a1: f32;
    let mut g1: f32;

    if a * g < 0f32 { panic!("The arithmetric-geometric mean is undefined for numbers less than zero!"); }
    else {
        loop {
            a1 = (a + g) / 2f32;
            g1 = (a * g).sqrt();
            a = a1;
            g = g1;
            if num::abs( a - g) < e {  return a; }
        }
    }

}

#[test]
fn test_agm_12_6() {
    assert! ( agm(12f32,6f32) == 8.740746f32 );
}
<|endoftext|>


<commit_before>#![feature(proc_macro_hygiene, decl_macro)]

#[macro_use]
extern crate rocket;

#[macro_use]
extern crate rocket_contrib;

// #[macro_use]
extern crate diesel;

mod schema;
// mod models;

use rocket_contrib::databases::diesel::PgConnection;

#[get("/")]
fn index(_db_conn: RustyDbConn) -> &'static str {
    // Rocket uses the RustyDbConn request guard to provide us with a database
    // connection from a managed pool.
    "Hello, from Rust! (with a database connection!)"
}

#[database("rustydb")]
pub struct RustyDbConn(PgConnection);

fn main() {
    rocket::ignite()
        .attach(RustyDbConn::fairing())
        .mount("/api", routes![index])
        .launch();
}
<commit_msg>Add a sample error catcher to make it nicer if the database isn't working for some reason.<commit_after>#![feature(proc_macro_hygiene, decl_macro)]

#[macro_use]
extern crate rocket;

#[macro_use]
extern crate rocket_contrib;

// #[macro_use]
extern crate diesel;

mod schema;
// mod models;

use rocket::request::Request;
use rocket_contrib::databases::diesel::PgConnection;

#[get("/")]
fn index(_db_conn: RustyDbConn) -> &'static str {
    // Rocket uses the RustyDbConn request guard to provide us with a database
    // connection from a managed pool.
    "Hello, from Rust! (with a database connection!)"
}

#[catch(503)]
fn service_not_available(_req: &Request) -> &'static str {
    "Service is not available. (Is the database up?)"
}

#[database("rustydb")]
pub struct RustyDbConn(PgConnection);

fn main() {
    rocket::ignite()
        .attach(RustyDbConn::fairing())
        .register(catchers![service_not_available])
        .mount("/api", routes![index])
        .launch();
}
<|endoftext|>