<commit_before>extern crate hyper;
extern crate json;

pub mod request;
pub mod response;

pub use request::{get, post, put, head, delete};
pub use response::Response;

pub type RequestsResult = hyper::Result<Response>;

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

    #[test]
    fn simple_get() {
        const URL: &'static str = "http://httpbin.org/get";
        let res = get(URL).unwrap();
        assert_eq!(res.url(), URL);
        assert_eq!(res.status_code(), hyper::Ok);
        assert_eq!(res.reason(), "OK");
        let data = res.json().unwrap();
        println!("{:?}", data);
        assert!(data["url"].is(URL));
        assert!(data["headers"]["Host"].is("httpbin.org"));
        assert!(data["headers"]["User-Agent"].is(concat!("requests-rs/", env!("CARGO_PKG_VERSION"))));
    }

    #[test]
    fn simple_post() {
        const URL: &'static str = "http://httpbin.org/post";
        let res = post(URL).unwrap();
        assert_eq!(res.url(), URL);
        assert_eq!(res.status_code(), hyper::Ok);
        assert_eq!(res.reason(), "OK");
    }

    #[test]
    fn simple_put() {
        const URL: &'static str = "http://httpbin.org/put";
        let res = put(URL).unwrap();
        assert_eq!(res.url(), URL);
        assert_eq!(res.status_code(), hyper::Ok);
        assert_eq!(res.reason(), "OK");
    }

    #[test]
    fn simple_head() {
        const URL: &'static str = "http://httpbin.org/get";
        let res = head(URL).unwrap();
        assert_eq!(res.url(), URL);
        assert_eq!(res.status_code(), hyper::Ok);
        assert_eq!(res.reason(), "OK");
    }

    #[test]
    fn simple_delete() {
        const URL: &'static str = "http://httpbin.org/delete";
        let res = delete(URL).unwrap();
        assert_eq!(res.url(), URL);
        assert_eq!(res.status_code(), hyper::Ok);
        assert_eq!(res.reason(), "OK");
    }

    #[test]
    fn user_agent() {
        let useragent = concat!("{\n  \"user-agent\": \"requests-rs/",
                                env!("CARGO_PKG_VERSION"),
                                "\"\n}\n");
        const URL: &'static str = "http://httpbin.org/user-agent";
        let res = get(URL).unwrap();
        assert_eq!(res.url(), URL);
        assert_eq!(res.status_code(), hyper::Ok);
        assert_eq!(res.reason(), "OK");
        assert_eq!(res.text(), Some(useragent));
    }

    #[test]
    fn user_agent_json() {

        const URL: &'static str = "http://httpbin.org/user-agent";
        let res = get(URL).unwrap();
        assert!(res.is_json());

        let ua = res.json().unwrap();
        assert!(ua["user-agent"].is(concat!("requests-rs/", env!("CARGO_PKG_VERSION"))));
    }
}
<commit_msg>rustfmt<commit_after>extern crate hyper;
extern crate json;

pub mod request;
pub mod response;

pub use request::{get, post, put, head, delete};
pub use response::Response;

pub type RequestsResult = hyper::Result<Response>;

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

    #[test]
    fn simple_get() {
        const URL: &'static str = "http://httpbin.org/get";
        let res = get(URL).unwrap();
        assert_eq!(res.url(), URL);
        assert_eq!(res.status_code(), hyper::Ok);
        assert_eq!(res.reason(), "OK");
        let data = res.json().unwrap();
        println!("{:?}", data);
        assert!(data["url"].is(URL));
        assert!(data["headers"]["Host"].is("httpbin.org"));
        assert!(data["headers"]["User-Agent"]
            .is(concat!("requests-rs/", env!("CARGO_PKG_VERSION"))));
    }

    #[test]
    fn simple_post() {
        const URL: &'static str = "http://httpbin.org/post";
        let res = post(URL).unwrap();
        assert_eq!(res.url(), URL);
        assert_eq!(res.status_code(), hyper::Ok);
        assert_eq!(res.reason(), "OK");
    }

    #[test]
    fn simple_put() {
        const URL: &'static str = "http://httpbin.org/put";
        let res = put(URL).unwrap();
        assert_eq!(res.url(), URL);
        assert_eq!(res.status_code(), hyper::Ok);
        assert_eq!(res.reason(), "OK");
    }

    #[test]
    fn simple_head() {
        const URL: &'static str = "http://httpbin.org/get";
        let res = head(URL).unwrap();
        assert_eq!(res.url(), URL);
        assert_eq!(res.status_code(), hyper::Ok);
        assert_eq!(res.reason(), "OK");
    }

    #[test]
    fn simple_delete() {
        const URL: &'static str = "http://httpbin.org/delete";
        let res = delete(URL).unwrap();
        assert_eq!(res.url(), URL);
        assert_eq!(res.status_code(), hyper::Ok);
        assert_eq!(res.reason(), "OK");
    }

    #[test]
    fn user_agent() {
        let useragent = concat!("{\n  \"user-agent\": \"requests-rs/",
                                env!("CARGO_PKG_VERSION"),
                                "\"\n}\n");
        const URL: &'static str = "http://httpbin.org/user-agent";
        let res = get(URL).unwrap();
        assert_eq!(res.url(), URL);
        assert_eq!(res.status_code(), hyper::Ok);
        assert_eq!(res.reason(), "OK");
        assert_eq!(res.text(), Some(useragent));
    }

    #[test]
    fn user_agent_json() {

        const URL: &'static str = "http://httpbin.org/user-agent";
        let res = get(URL).unwrap();
        assert!(res.is_json());

        let ua = res.json().unwrap();
        assert!(ua["user-agent"].is(concat!("requests-rs/", env!("CARGO_PKG_VERSION"))));
    }
}
<|endoftext|>


<commit_before>pub mod board;

use board::Board;

use std::i32;
use std::ops::Neg;
use std::collections::HashMap;

#[derive(Copy,Clone,Debug)]
pub enum Team
{
    Enemy,
    Ally,
}

impl Team
{
    pub fn other_team(self) -> Team
    {
        match self
        {
            Team::Enemy => Team::Ally,
            Team::Ally => Team::Enemy,
        }
    }
}

#[derive(PartialEq,Eq,PartialOrd,Ord,Copy,Clone,Debug)]
pub enum Score
{
    Lose,
    Heuristic(i32),
    Win,
}

impl Neg for Score
{
    type Output = Self;
    fn neg(self) -> Self
    {
        match self
        {
            Score::Win => Score::Lose,
            Score::Lose => Score::Win,
            Score::Heuristic(val) => Score::Heuristic(-val),
        }
    }
}

#[derive(Clone,Debug,PartialEq,Eq)]
pub struct MoveStats<M>
{
    pub mv: Option<M>,
    pub score: Score,
    pub turns: u32,
    pub nodes_visited: u64,
}

#[derive(Clone,Debug)]
pub struct Minimax<B: Board>
{
    ally_move_cache: HashMap<B, Vec<B::Move>>,
    enemy_move_cache: HashMap<B, Vec<B::Move>>,
}

impl<B: Board> Minimax<B>
{
    pub fn new() -> Minimax<B>
    {
        Minimax
        {
            ally_move_cache: HashMap::new(),
            enemy_move_cache: HashMap::new(),
        }
    }

    /// Minimax driver function.
    ///
    /// `turn` is the current player.
    pub fn minimax(&mut self, board: &B, turn: Team, plies: u32) -> MoveStats<B::Move>
    {
        match turn
        {
            Team::Ally =>
                self.max(board, plies),
            Team::Enemy =>
                self.min(board, plies),
        }
    }

    /// Generates best move for ally
    fn max(&mut self, board: &B, plies: u32) -> MoveStats<B::Move>
    {
        let moves;
//        if let Some(cached_moves) = self.ally_move_cache.get(board).map(|m| m.to_owned())
//        {
//            moves = cached_moves;
//        }
//        else
//        {
            moves = board.gen_ally_moves();
//            self.ally_move_cache.insert(board.clone(), moves.clone());
//        }

        /* Fail state if you can't move */
        if moves.len() == 0
        {
            return MoveStats
            {
                mv: None,
                score: Score::Lose,
                turns: 0,
                nodes_visited: 0,
            };
        }

        /* If you cannot proceed further */
        if plies == 0 || board.is_game_over()
        {
            MoveStats
            {
                mv: None,
                score: board.score(),
                turns: 0,
                nodes_visited: 0,
            }
        }
        else
        {
            let mut best = MoveStats {
                mv: None,
                score: Score::Lose,
                turns: 0,
                nodes_visited: 0,
            };

            for mv in moves
            {
                if plies == 7
                {
//                    println!("Move {:#?}", mv);
                }

                /* Make a clone of the board so we don't break this one */
                let mut board_clone = board.clone();
                board_clone.do_move(&mv);

                /* Find enemy's best move */
                let enemy_move = self.min(&board_clone, plies - 1);
                if plies == 7
                {
//                    println!("ENEMY {:#?}", enemy_move);
                }

                /* TODO: Try to postpone losing */
                if best.mv.is_none() || enemy_move.score > best.score || (enemy_move.score == best.score && enemy_move.turns < best.turns)
                {
                    best.mv = Some(mv);
                    best.score = enemy_move.score;
                    best.turns = enemy_move.turns + 1;
                }
                best.nodes_visited += enemy_move.nodes_visited + 1;
            }
            best
        }
    }

    /// Generates best move for enemy
    fn min(&mut self, board: &B, plies: u32) -> MoveStats<B::Move>
    {
        let moves;
//        if let Some(cached_moves) = self.enemy_move_cache.get(board).map(|m| m.to_owned())
//        {
//            moves = cached_moves;
//        }
//        else
//        {
            moves = board.gen_enemy_moves();
//            self.enemy_move_cache.insert(board.clone(), moves.clone());
//        }

        /* Fail state if you can't move */
        if moves.len() == 0
        {
            return MoveStats
            {
                mv: None,
                /* If enemy can't move, we win. */
                score: Score::Win,
                turns: 0,
                nodes_visited: 0,
            };
        }

        /* If you cannot proceed further */
        if plies == 0 || board.is_game_over()
        {
            MoveStats
            {
                mv: None,
                score: board.score(),
                turns: 0,
                nodes_visited: 0,
            }
        }
        else
        {
            let mut best = MoveStats {
                mv: None,
                /* Technically doesn't matter, but for consistancy's sake */
                score: Score::Win,
                turns: 0,
                nodes_visited: 0,
            };

            for mv in moves
            {
                /* Make a clone of the board so we don't break this one */
                let mut board_clone = board.clone();
                board_clone.do_move(&mv);

                /* Find ally's best move */
                let ally_move = self.max(&board_clone, plies - 1);

                /* TODO: Try to postpone losing */
                if best.mv.is_none() || ally_move.score < best.score || (ally_move.score == best.score && ally_move.turns < best.turns)
                {
                    best.mv = Some(mv);
                    best.score = ally_move.score;
                    best.turns = ally_move.turns + 1;
                }
                best.nodes_visited += ally_move.nodes_visited + 1;
            }
            best
        }
    }
}

#[test]
fn test_score_ord()
{
    assert!(Score::Win > Score::Heuristic(0));
    assert!(Score::Heuristic(0) > Score::Lose);
    assert!(Score::Win > Score::Lose);
    assert!(Score::Heuristic(100) > Score::Heuristic(0));
    assert!(Score::Heuristic(0) > Score::Heuristic(-100));
    assert!(Score::Win == Score::Win);
    assert!(Score::Lose == Score::Lose);
    assert!(Score::Heuristic(0) == Score::Heuristic(0));
}
<commit_msg>minimax: cleaned code<commit_after>pub mod board;

use board::Board;

use std::i32;
use std::ops::Neg;
use std::marker::PhantomData;

#[derive(Copy,Clone,Debug)]
pub enum Team
{
    Enemy,
    Ally,
}

impl Team
{
    pub fn other_team(self) -> Team
    {
        match self
        {
            Team::Enemy => Team::Ally,
            Team::Ally => Team::Enemy,
        }
    }
}

#[derive(PartialEq,Eq,PartialOrd,Ord,Copy,Clone,Debug)]
pub enum Score
{
    Lose,
    Heuristic(i32),
    Win,
}

impl Neg for Score
{
    type Output = Self;
    fn neg(self) -> Self
    {
        match self
        {
            Score::Win => Score::Lose,
            Score::Lose => Score::Win,
            Score::Heuristic(val) => Score::Heuristic(-val),
        }
    }
}

#[derive(Clone,Debug,PartialEq,Eq)]
pub struct MoveStats<M>
{
    pub mv: Option<M>,
    pub score: Score,
    pub turns: u32,
    pub nodes_visited: u64,
}

#[derive(Clone,Debug)]
pub struct Minimax<B: Board>
{
    /* TODO: Some sort of caching */
    phantom: PhantomData<B>
}

impl<B: Board> Minimax<B>
{
    pub fn new() -> Minimax<B>
    {
        Minimax
        {
            phantom: PhantomData,
        }
    }

    /// Minimax driver function.
    ///
    /// `turn` is the current player.
    pub fn minimax(&mut self, board: &B, turn: Team, plies: u32) -> MoveStats<B::Move>
    {
        match turn
        {
            Team::Ally =>
                self.max(board, plies),
            Team::Enemy =>
                self.min(board, plies),
        }
    }

    /// Generates best move for ally
    fn max(&mut self, board: &B, plies: u32) -> MoveStats<B::Move>
    {
        let moves = board.gen_ally_moves();

        /* Fail state if you can't move */
        if moves.len() == 0
        {
            return MoveStats
            {
                mv: None,
                score: Score::Lose,
                turns: 0,
                nodes_visited: 0,
            };
        }

        /* If you cannot proceed further */
        if plies == 0 || board.is_game_over()
        {
            MoveStats
            {
                mv: None,
                score: board.score(),
                turns: 0,
                nodes_visited: 0,
            }
        }
        else
        {
            let mut best = MoveStats {
                mv: None,
                score: Score::Lose,
                turns: 0,
                nodes_visited: 0,
            };

            for mv in moves
            {

                /* Make a clone of the board so we don't break this one */
                let mut board_clone = board.clone();
                board_clone.do_move(&mv);

                /* Find enemy's best move */
                let enemy_move = self.min(&board_clone, plies - 1);

                /* TODO: Try to postpone losing */
                if best.mv.is_none() || enemy_move.score > best.score || (enemy_move.score == best.score && enemy_move.turns < best.turns)
                {
                    best.mv = Some(mv);
                    best.score = enemy_move.score;
                    best.turns = enemy_move.turns + 1;
                }
                best.nodes_visited += enemy_move.nodes_visited + 1;
            }
            best
        }
    }

    /// Generates best move for enemy
    fn min(&mut self, board: &B, plies: u32) -> MoveStats<B::Move>
    {
        let moves = board.gen_enemy_moves();

        /* Fail state if you can't move */
        if moves.len() == 0
        {
            return MoveStats
            {
                mv: None,
                /* If enemy can't move, we win. */
                score: Score::Win,
                turns: 0,
                nodes_visited: 0,
            };
        }

        /* If you cannot proceed further */
        if plies == 0 || board.is_game_over()
        {
            MoveStats
            {
                mv: None,
                score: board.score(),
                turns: 0,
                nodes_visited: 0,
            }
        }
        else
        {
            let mut best = MoveStats {
                mv: None,
                /* Technically doesn't matter, but for consistancy's sake */
                score: Score::Win,
                turns: 0,
                nodes_visited: 0,
            };

            for mv in moves
            {
                /* Make a clone of the board so we don't break this one */
                let mut board_clone = board.clone();
                board_clone.do_move(&mv);

                /* Find ally's best move */
                let ally_move = self.max(&board_clone, plies - 1);

                /* TODO: Try to postpone losing */
                if best.mv.is_none() || ally_move.score < best.score || (ally_move.score == best.score && ally_move.turns < best.turns)
                {
                    best.mv = Some(mv);
                    best.score = ally_move.score;
                    best.turns = ally_move.turns + 1;
                }
                best.nodes_visited += ally_move.nodes_visited + 1;
            }
            best
        }
    }
}

#[test]
fn test_score_ord()
{
    assert!(Score::Win > Score::Heuristic(0));
    assert!(Score::Heuristic(0) > Score::Lose);
    assert!(Score::Win > Score::Lose);
    assert!(Score::Heuristic(100) > Score::Heuristic(0));
    assert!(Score::Heuristic(0) > Score::Heuristic(-100));
    assert!(Score::Win == Score::Win);
    assert!(Score::Lose == Score::Lose);
    assert!(Score::Heuristic(0) == Score::Heuristic(0));
}

/* TODO: minimax tests */
<|endoftext|>


<commit_before>extern crate rustc_serialize;

pub mod datastore;
pub mod redis_store;

use std::collections::BTreeMap;

use rustc_serialize::json::{Json, ToJson};

/// An Optional value can contain Optional::Some<T> or Optional::Absent.
/// It is similar to an Option, but Optional::Absent means it will be
/// omitted when serialized.
pub enum Optional<T> {
    Value(T),
    Absent,
}

pub struct Location {
    pub address: Optional<String>,
    pub lat: f64,
    pub lon: f64,
}

pub struct Spacefed {
    pub spacenet: bool,
    pub spacesaml: bool,
    pub spacephone: bool,
}

pub struct Icon {
    pub open: String,
    pub close: String,
}

pub struct State {
    pub open: Option<bool>,
    pub lastchange: Optional<u64>,
    pub trigger_person: Optional<String>,
    pub message: Optional<String>,
    pub icon: Optional<Icon>,
}

pub struct Event {
    pub name: String,
    pub _type: String,
    pub timestamp: u64,
    pub extra: Optional<String>,
}

pub struct Contact {
    pub irc: Optional<String>,
    pub twitter: Optional<String>,
    pub foursquare: Optional<String>,
    pub email: Optional<String>,
}

pub struct Feed {
    pub _type: Optional<String>,
    pub url: String,
}

pub struct Feeds {
    pub blog: Optional<Feed>,
    pub wiki: Optional<Feed>,
    pub calendar: Optional<Feed>,
    pub flickr: Optional<Feed>,
}

pub struct Sensors {
    pub people_now_present: Optional<Vec<PeopleNowPresentSensor>>,
    pub temperature: Optional<Vec<TemperatureSensor>>,
}

pub struct PeopleNowPresentSensor {
    pub value: u32,
    pub location: Optional<String>,
    pub name: Optional<String>,
    pub names: Optional<Vec<String>>,
    pub description: Optional<String>,
}

pub struct TemperatureSensor {
    pub value: f32,
    pub unit: String,
    pub location: String,
    pub name: Optional<String>,
    pub description: Optional<String>,
}

pub struct Cache {
    pub schedule: String,
}

pub struct RadioShow {
    pub name: String,
    pub url: String,
    pub _type: String,
    pub start: String,
    pub end: String,
}

pub struct Status {

    // Hackerspace properties
    pub api: String,
    pub space: String,
    pub logo: String,
    pub url: String,
    pub location: Location,
    pub contact: Contact,

    // Hackerspace features / projects
    pub spacefed: Optional<Spacefed>,
    pub projects: Optional<Vec<String>>,
    pub cam: Optional<Vec<String>>,
    pub feeds: Optional<Feeds>,
    pub events: Optional<Vec<Event>>,
    pub radio_show: Optional<Vec<RadioShow>>,

    // SpaceAPI internal usage
    pub cache: Optional<Cache>,
    pub issue_report_channels: Vec<String>,

    // Mutable data
    pub state: State,
    pub sensors: Optional<Sensors>,

}

impl ToJson for Status {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();

        d.insert("api".to_string(), self.api.to_json());
        d.insert("space".to_string(), self.space.to_json());
        d.insert("logo".to_string(), self.logo.to_json());
        d.insert("url".to_string(), self.url.to_json());
        d.insert("location".to_string(), self.location.to_json());
        d.insert("contact".to_string(), self.contact.to_json());

        match self.spacefed {
            Optional::Value(ref spacefed) => { d.insert("spacefed".to_string(), spacefed.to_json()); },
            Optional::Absent => (),
        };
        match self.projects {
            Optional::Value(ref projects) => { d.insert("projects".to_string(), projects.to_json()); },
            Optional::Absent => (),
        };
        match self.cam {
            Optional::Value(ref cam) => { d.insert("cam".to_string(), cam.to_json()); },
            Optional::Absent => (),
        };
        match self.feeds {
            Optional::Value(ref feeds) => { d.insert("feeds".to_string(), feeds.to_json()); },
            Optional::Absent => (),
        };
        match self.events {
            Optional::Value(ref events) => { d.insert("events".to_string(), events.to_json()); },
            Optional::Absent => (),
        };
        match self.radio_show {
            Optional::Value(ref radio_show) => { d.insert("radio_show".to_string(), radio_show.to_json()); },
            Optional::Absent => (),
        };

        match self.cache {
            Optional::Value(ref cache) => { d.insert("cache".to_string(), cache.to_json()); },
            Optional::Absent => (),
        };
        d.insert("issue_report_channels".to_string(), self.issue_report_channels.to_json());

        d.insert("state".to_string(), self.state.to_json());
        match self.sensors {
            Optional::Value(ref sensors) => { d.insert("sensors".to_string(), sensors.to_json()); },
            Optional::Absent => (),
        };

        Json::Object(d)
    }
}

impl ToJson for Location {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("lat".to_string(), self.lat.to_json());
        d.insert("lon".to_string(), self.lon.to_json());
        match self.address {
            Optional::Value(ref address) => {
                d.insert("address".to_string(), address.to_json());
            },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Spacefed {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("spacenet".to_string(), self.spacenet.to_json());
        d.insert("spacesaml".to_string(), self.spacesaml.to_json());
        d.insert("spacephone".to_string(), self.spacephone.to_json());
        Json::Object(d)
    }
}

impl ToJson for Icon {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("open".to_string(), self.open.to_json());
        d.insert("close".to_string(), self.close.to_json());
        Json::Object(d)
    }
}

impl ToJson for State {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("open".to_string(), self.open.to_json());
        match self.lastchange {
            Optional::Value(ref lastchange) => { d.insert("lastchange".to_string(), lastchange.to_json()); },
            Optional::Absent => (),
        };
        match self.trigger_person {
            Optional::Value(ref trigger_person) => { d.insert("trigger_person".to_string(), trigger_person.to_json()); },
            Optional::Absent => (),
        };
        match self.message {
            Optional::Value(ref message) => { d.insert("message".to_string(), message.to_json()); },
            Optional::Absent => (),
        };
        match self.icon {
            Optional::Value(ref icon) => { d.insert("icon".to_string(), icon.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Event {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("name".to_string(), self.name.to_json());
        d.insert("type".to_string(), self._type.to_json());
        d.insert("timestamp".to_string(), self.timestamp.to_json());
        match self.extra {
            Optional::Value(ref extra) => { d.insert("extra".to_string(), extra.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Contact {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        match self.irc {
            Optional::Value(ref irc) => { d.insert("irc".to_string(), irc.to_json()); },
            Optional::Absent => (),
        };
        match self.twitter {
            Optional::Value(ref twitter) => { d.insert("twitter".to_string(), twitter.to_json()); },
            Optional::Absent => (),
        };
        match self.foursquare {
            Optional::Value(ref foursquare) => { d.insert("foursquare".to_string(), foursquare.to_json()); },
            Optional::Absent => (),
        };
        match self.email {
            Optional::Value(ref email) => { d.insert("email".to_string(), email.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Feed {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("url".to_string(), self.url.to_json());
        match self._type {
            Optional::Value(ref _type) => { d.insert("type".to_string(), _type.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Feeds {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        match self.blog {
            Optional::Value(ref blog) => { d.insert("blog".to_string(), blog.to_json()); },
            Optional::Absent => (),
        };
        match self.wiki {
            Optional::Value(ref wiki) => { d.insert("wiki".to_string(), wiki.to_json()); },
            Optional::Absent => (),
        };
        match self.calendar {
            Optional::Value(ref calendar) => { d.insert("calendar".to_string(), calendar.to_json()); },
            Optional::Absent => (),
        };
        match self.flickr {
            Optional::Value(ref flickr) => { d.insert("flickr".to_string(), flickr.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Sensors {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        match self.people_now_present {
            Optional::Value(ref people_now_present) => { d.insert("people_now_present".to_string(), people_now_present.to_json()); },
            Optional::Absent => (),
        };
        match self.temperature {
            Optional::Value(ref temperature) => { d.insert("temperature".to_string(), temperature.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for PeopleNowPresentSensor {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("value".to_string(), self.value.to_json());
        match self.location {
            Optional::Value(ref location) => { d.insert("location".to_string(), location.to_json()); },
            Optional::Absent => (),
        };
        match self.name {
            Optional::Value(ref name) => { d.insert("name".to_string(), name.to_json()); },
            Optional::Absent => (),
        };
        match self.names {
            Optional::Value(ref names) => { d.insert("names".to_string(), names.to_json()); },
            Optional::Absent => (),
        };
        match self.description {
            Optional::Value(ref description) => { d.insert("description".to_string(), description.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for TemperatureSensor {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("value".to_string(), self.value.to_json());
        d.insert("unit".to_string(), self.unit.to_json());
        d.insert("location".to_string(), self.location.to_json());
        match self.name {
            Optional::Value(ref name) => { d.insert("name".to_string(), name.to_json()); },
            Optional::Absent => (),
        };
        match self.description {
            Optional::Value(ref description) => { d.insert("description".to_string(), description.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Cache {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("schedule".to_string(), self.schedule.to_json());
        Json::Object(d)
    }
}

impl ToJson for RadioShow {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("name".to_string(), self.name.to_json());
        d.insert("url".to_string(), self.url.to_json());
        d.insert("type".to_string(), self._type.to_json());
        d.insert("start".to_string(), self.start.to_json());
        d.insert("end".to_string(), self.end.to_json());
        Json::Object(d)
    }
}
<commit_msg>Started moving server code into spaceapi_server crate<commit_after>extern crate rustc_serialize;

pub mod datastore;
pub mod redis_store;

use std::collections::BTreeMap;

use rustc_serialize::json::{Json, ToJson};

/// An Optional value can contain Optional::Some<T> or Optional::Absent.
/// It is similar to an Option, but Optional::Absent means it will be
/// omitted when serialized.
pub enum Optional<T> {
    Value(T),
    Absent,
}

pub struct Location {
    pub address: Optional<String>,
    pub lat: f64,
    pub lon: f64,
}

pub struct Spacefed {
    pub spacenet: bool,
    pub spacesaml: bool,
    pub spacephone: bool,
}

pub struct Icon {
    pub open: String,
    pub close: String,
}

pub struct State {
    pub open: Option<bool>,
    pub lastchange: Optional<u64>,
    pub trigger_person: Optional<String>,
    pub message: Optional<String>,
    pub icon: Optional<Icon>,
}

pub struct Event {
    pub name: String,
    pub _type: String,
    pub timestamp: u64,
    pub extra: Optional<String>,
}

pub struct Contact {
    pub irc: Optional<String>,
    pub twitter: Optional<String>,
    pub foursquare: Optional<String>,
    pub email: Optional<String>,
}

pub struct Feed {
    pub _type: Optional<String>,
    pub url: String,
}

pub struct Feeds {
    pub blog: Optional<Feed>,
    pub wiki: Optional<Feed>,
    pub calendar: Optional<Feed>,
    pub flickr: Optional<Feed>,
}

pub struct Sensors {
    pub people_now_present: Optional<Vec<PeopleNowPresentSensor>>,
    pub temperature: Optional<Vec<TemperatureSensor>>,
}

pub struct PeopleNowPresentSensor {
    pub value: u32,
    pub location: Optional<String>,
    pub name: Optional<String>,
    pub names: Optional<Vec<String>>,
    pub description: Optional<String>,
}

pub struct TemperatureSensor {
    pub value: f32,
    pub unit: String,
    pub location: String,
    pub name: Optional<String>,
    pub description: Optional<String>,
}

pub struct Cache {
    pub schedule: String,
}

pub struct RadioShow {
    pub name: String,
    pub url: String,
    pub _type: String,
    pub start: String,
    pub end: String,
}

pub struct Status {

    // Hackerspace properties
    pub api: String,
    pub space: String,
    pub logo: String,
    pub url: String,
    pub location: Location,
    pub contact: Contact,

    // Hackerspace features / projects
    pub spacefed: Optional<Spacefed>,
    pub projects: Optional<Vec<String>>,
    pub cam: Optional<Vec<String>>,
    pub feeds: Optional<Feeds>,
    pub events: Optional<Vec<Event>>,
    pub radio_show: Optional<Vec<RadioShow>>,

    // SpaceAPI internal usage
    pub cache: Optional<Cache>,
    pub issue_report_channels: Vec<String>,

    // Mutable data
    pub state: State,
    pub sensors: Optional<Sensors>,

}

impl Status {

    /// Create a new Status object with only the minimum amount of fields
    pub fn new(space: String, logo: String, url: String, location: Location, contact: Contact, issue_report_channels: Vec<String>) -> Status {
        Status {
            api: "0.13".to_string(),
            space: space,
            logo: logo,
            url: url,
            location: location,
            contact: contact,

            spacefed: Optional::Absent,
            projects: Optional::Absent,
            cam: Optional::Absent,
            feeds: Optional::Absent,
            events: Optional::Absent,
            radio_show: Optional::Absent,

            cache: Optional::Absent,
            issue_report_channels: issue_report_channels,

            state: State {
                open: None,
                lastchange: Optional::Absent,
                trigger_person: Optional::Absent,
                message: Optional::Absent,
                icon: Optional::Absent,
            },
            sensors: Optional::Absent,
        }
    }

}

impl ToJson for Status {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();

        d.insert("api".to_string(), self.api.to_json());
        d.insert("space".to_string(), self.space.to_json());
        d.insert("logo".to_string(), self.logo.to_json());
        d.insert("url".to_string(), self.url.to_json());
        d.insert("location".to_string(), self.location.to_json());
        d.insert("contact".to_string(), self.contact.to_json());

        match self.spacefed {
            Optional::Value(ref spacefed) => { d.insert("spacefed".to_string(), spacefed.to_json()); },
            Optional::Absent => (),
        };
        match self.projects {
            Optional::Value(ref projects) => { d.insert("projects".to_string(), projects.to_json()); },
            Optional::Absent => (),
        };
        match self.cam {
            Optional::Value(ref cam) => { d.insert("cam".to_string(), cam.to_json()); },
            Optional::Absent => (),
        };
        match self.feeds {
            Optional::Value(ref feeds) => { d.insert("feeds".to_string(), feeds.to_json()); },
            Optional::Absent => (),
        };
        match self.events {
            Optional::Value(ref events) => { d.insert("events".to_string(), events.to_json()); },
            Optional::Absent => (),
        };
        match self.radio_show {
            Optional::Value(ref radio_show) => { d.insert("radio_show".to_string(), radio_show.to_json()); },
            Optional::Absent => (),
        };

        match self.cache {
            Optional::Value(ref cache) => { d.insert("cache".to_string(), cache.to_json()); },
            Optional::Absent => (),
        };
        d.insert("issue_report_channels".to_string(), self.issue_report_channels.to_json());

        d.insert("state".to_string(), self.state.to_json());
        match self.sensors {
            Optional::Value(ref sensors) => { d.insert("sensors".to_string(), sensors.to_json()); },
            Optional::Absent => (),
        };

        Json::Object(d)
    }
}

impl ToJson for Location {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("lat".to_string(), self.lat.to_json());
        d.insert("lon".to_string(), self.lon.to_json());
        match self.address {
            Optional::Value(ref address) => {
                d.insert("address".to_string(), address.to_json());
            },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Spacefed {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("spacenet".to_string(), self.spacenet.to_json());
        d.insert("spacesaml".to_string(), self.spacesaml.to_json());
        d.insert("spacephone".to_string(), self.spacephone.to_json());
        Json::Object(d)
    }
}

impl ToJson for Icon {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("open".to_string(), self.open.to_json());
        d.insert("close".to_string(), self.close.to_json());
        Json::Object(d)
    }
}

impl ToJson for State {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("open".to_string(), self.open.to_json());
        match self.lastchange {
            Optional::Value(ref lastchange) => { d.insert("lastchange".to_string(), lastchange.to_json()); },
            Optional::Absent => (),
        };
        match self.trigger_person {
            Optional::Value(ref trigger_person) => { d.insert("trigger_person".to_string(), trigger_person.to_json()); },
            Optional::Absent => (),
        };
        match self.message {
            Optional::Value(ref message) => { d.insert("message".to_string(), message.to_json()); },
            Optional::Absent => (),
        };
        match self.icon {
            Optional::Value(ref icon) => { d.insert("icon".to_string(), icon.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Event {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("name".to_string(), self.name.to_json());
        d.insert("type".to_string(), self._type.to_json());
        d.insert("timestamp".to_string(), self.timestamp.to_json());
        match self.extra {
            Optional::Value(ref extra) => { d.insert("extra".to_string(), extra.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Contact {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        match self.irc {
            Optional::Value(ref irc) => { d.insert("irc".to_string(), irc.to_json()); },
            Optional::Absent => (),
        };
        match self.twitter {
            Optional::Value(ref twitter) => { d.insert("twitter".to_string(), twitter.to_json()); },
            Optional::Absent => (),
        };
        match self.foursquare {
            Optional::Value(ref foursquare) => { d.insert("foursquare".to_string(), foursquare.to_json()); },
            Optional::Absent => (),
        };
        match self.email {
            Optional::Value(ref email) => { d.insert("email".to_string(), email.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Feed {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("url".to_string(), self.url.to_json());
        match self._type {
            Optional::Value(ref _type) => { d.insert("type".to_string(), _type.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Feeds {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        match self.blog {
            Optional::Value(ref blog) => { d.insert("blog".to_string(), blog.to_json()); },
            Optional::Absent => (),
        };
        match self.wiki {
            Optional::Value(ref wiki) => { d.insert("wiki".to_string(), wiki.to_json()); },
            Optional::Absent => (),
        };
        match self.calendar {
            Optional::Value(ref calendar) => { d.insert("calendar".to_string(), calendar.to_json()); },
            Optional::Absent => (),
        };
        match self.flickr {
            Optional::Value(ref flickr) => { d.insert("flickr".to_string(), flickr.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Sensors {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        match self.people_now_present {
            Optional::Value(ref people_now_present) => { d.insert("people_now_present".to_string(), people_now_present.to_json()); },
            Optional::Absent => (),
        };
        match self.temperature {
            Optional::Value(ref temperature) => { d.insert("temperature".to_string(), temperature.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for PeopleNowPresentSensor {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("value".to_string(), self.value.to_json());
        match self.location {
            Optional::Value(ref location) => { d.insert("location".to_string(), location.to_json()); },
            Optional::Absent => (),
        };
        match self.name {
            Optional::Value(ref name) => { d.insert("name".to_string(), name.to_json()); },
            Optional::Absent => (),
        };
        match self.names {
            Optional::Value(ref names) => { d.insert("names".to_string(), names.to_json()); },
            Optional::Absent => (),
        };
        match self.description {
            Optional::Value(ref description) => { d.insert("description".to_string(), description.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for TemperatureSensor {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("value".to_string(), self.value.to_json());
        d.insert("unit".to_string(), self.unit.to_json());
        d.insert("location".to_string(), self.location.to_json());
        match self.name {
            Optional::Value(ref name) => { d.insert("name".to_string(), name.to_json()); },
            Optional::Absent => (),
        };
        match self.description {
            Optional::Value(ref description) => { d.insert("description".to_string(), description.to_json()); },
            Optional::Absent => (),
        };
        Json::Object(d)
    }
}

impl ToJson for Cache {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("schedule".to_string(), self.schedule.to_json());
        Json::Object(d)
    }
}

impl ToJson for RadioShow {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        d.insert("name".to_string(), self.name.to_json());
        d.insert("url".to_string(), self.url.to_json());
        d.insert("type".to_string(), self._type.to_json());
        d.insert("start".to_string(), self.start.to_json());
        d.insert("end".to_string(), self.end.to_json());
        Json::Object(d)
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 Ilkka Rauta
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! BitReader is a helper type to extract strings of bits from a slice of bytes.
//!
//! Here is how you read first a single bit, then three bits and finally four bits from a byte
//! buffer:
//!
//! ```
//! use bitreader::BitReader;
//!
//! let slice_of_u8 = &[0b1000_1111];
//! let mut reader = BitReader::new(slice_of_u8);
//!
//! // You probably should use try! or some other error handling mechanism in real code if the
//! // length of the input is not known in advance.
//! let a_single_bit = reader.read_u8(1).unwrap();
//! assert_eq!(a_single_bit, 1);
//!
//! let more_bits = reader.read_u8(3).unwrap();
//! assert_eq!(more_bits, 0);
//!
//! let last_bits_of_byte = reader.read_u8(4).unwrap();
//! assert_eq!(last_bits_of_byte, 0b1111);
//! ```
//! You can naturally read bits from longer buffer of data than just a single byte.
//!
//! As you read bits, the internal cursor of BitReader moves on along the stream of bits. Little
//! endian format is assumed when reading the multi-byte values. BitReader supports reading maximum
//! of 64 bits at a time (with read_u64). Reading signed values directly is not supported at the
//! moment.
//!
//! The reads do not need to be aligned in any particular way.
//!
//! Reading zero bits is a no-op.
//!
//! You can also skip over a number of bits, in which case there is no arbitrary small limits like
//! when reading the values to a variable. However, you can not seek past the end of the slice,
//! either when reading or when skipping bits.
//!
//! Note that the code will likely not work correctly if the slice is longer than 2^61 bytes, but
//! exceeding that should be pretty unlikely. Let's get back to this when people read exabytes of
//! information one bit at a time.

use std::fmt;
use std::error::Error;
use std::result;

#[cfg(test)]
mod tests;

/// BitReader reads data from a byte slice at the granularity of a single bit.
pub struct BitReader<'a> {
    bytes: &'a [u8],
    /// Position from the start of the slice, counted as bits instead of bytes
    position: u64,
}

impl<'a> BitReader<'a> {
    /// Construct a new BitReader from a byte slice. The returned reader lives at most as long as
    /// the slice given to is valid.
    pub fn new(bytes: &'a [u8]) -> BitReader<'a> {
        BitReader {
            bytes: bytes,
            position: 0
        }
    }

    /// Read at most 8 bits into a u8.
    pub fn read_u8(&mut self, bit_count: u8) -> Result<u8> {
        let value = try!(self.read_value(bit_count, 8));
        Ok((value & 0xff) as u8)
    }

    /// Read at most 16 bits into a u16.
    pub fn read_u16(&mut self, bit_count: u8) -> Result<u16> {
        let value = try!(self.read_value(bit_count, 16));
        Ok((value & 0xffff) as u16)
    }

    /// Read at most 32 bits into a u32.
    pub fn read_u32(&mut self, bit_count: u8) -> Result<u32> {
        let value = try!(self.read_value(bit_count, 32));
        Ok((value & 0xffffffff) as u32)
    }

    /// Read at most 64 bits into a u64.
    pub fn read_u64(&mut self, bit_count: u8) -> Result<u64> {
        let value = try!(self.read_value(bit_count, 64));
        Ok(value)
    }

    /// Read at most 8 bits into a i8.
    /// Assumes the bits are stored in two's complement format.
    pub fn read_i8(&mut self, bit_count: u8) -> Result<i8> {
        let value = try!(self.read_signed_value(bit_count, 8));
        Ok((value & 0xff) as i8)
    }

    /// Read at most 16 bits into a i16.
    /// Assumes the bits are stored in two's complement format.
    pub fn read_i16(&mut self, bit_count: u8) -> Result<i16> {
        let value = try!(self.read_signed_value(bit_count, 16));
        Ok((value & 0xffff) as i16)
    }

    /// Read at most 32 bits into a i32.
    /// Assumes the bits are stored in two's complement format.
    pub fn read_i32(&mut self, bit_count: u8) -> Result<i32> {
        let value = try!(self.read_signed_value(bit_count, 32));
        Ok((value & 0xffffffff) as i32)
    }

    /// Read at most 64 bits into a i64.
    /// Assumes the bits are stored in two's complement format.
    pub fn read_i64(&mut self, bit_count: u8) -> Result<i64> {
        let value = try!(self.read_signed_value(bit_count, 64));
        Ok(value)
    }

    /// Skip arbitrary number of bits. However, you can skip at most to the end of the byte slice.
    pub fn skip(&mut self, bit_count: u32) -> Result<()> {
        let end_position = self.position + bit_count as u64;
        if end_position > self.bytes.len() as u64 * 8 {
            return Err(BitReaderError::NotEnoughData);
        }
        self.position = end_position;
        Ok(())
    }

    /// Returns the position of the cursor, or how many bits have been read so far.
    pub fn position(&self) -> u64 {
        self.position
    }

    /// Helper to make sure the "bit cursor" is exactly at the beginning of a byte, or at specific
    /// multi-byte alignment position.
    ///
    /// For example `reader.is_aligned(1)` returns true if exactly n bytes, or n * 8 bits, has been
    /// read. Similarly, `reader.is_aligned(4)` returns true if exactly n * 32 bits, or n 4-byte
    /// sequences has been read.
    ///
    /// This function can be used to validate the data is being read properly, for example by
    /// adding invocations wrapped into `debug_assert!()` to places where it is known the data
    /// should be n-byte aligned.
    pub fn is_aligned(&self, alignment_bytes: u32) -> bool {
        self.position % (alignment_bytes as u64 * 8) == 0
    }

    fn read_signed_value(&mut self, bit_count: u8, maximum_count: u8) -> Result<i64> {
        let unsigned = try!(self.read_value(bit_count, maximum_count));
        // Fill the bits above the requested bits with all ones or all zeros,
        // depending on the sign bit.
        let sign_bit = unsigned >> (bit_count - 1) & 1;
        let high_bits = if sign_bit == 1 { -1 } else { 0 };
        Ok(high_bits << bit_count | unsigned as i64)
    }

    fn read_value(&mut self, bit_count: u8, maximum_count: u8) -> Result<u64> {
        if bit_count == 0 {
            return Ok(0);
        }
        if bit_count > maximum_count {
            return Err(BitReaderError::TooManyBitsForType);
        }
        let start_position = self.position;
        let end_position = self.position + bit_count as u64;
        if end_position > self.bytes.len() as u64 * 8 {
            return Err(BitReaderError::NotEnoughData);
        }

        let mut value: u64 = 0;

        for i in start_position..end_position {
            let byte_index = (i / 8) as usize;
            let byte = self.bytes[byte_index];
            let shift = 7 - (i % 8);
            let bit = (byte >> shift) as u64 & 1;
            value = (value << 1) | bit;
        }

        self.position = end_position;
        Ok(value)
    }
}

/// Result type for those BitReader operations that can fail.
pub type Result<T> = result::Result<T, BitReaderError>;

/// Error enumeration of BitReader errors.
#[derive(Debug,PartialEq,Copy,Clone)]
pub enum BitReaderError {
    /// Requested more bits than there are left in the byte slice at the current position.
    NotEnoughData,
    /// Requested more bits than the returned variable can hold, for example more than 8 bits when
    /// reading into a u8.
    TooManyBitsForType
}

impl Error for BitReaderError {
    fn description(&self) -> &str {
        match *self {
            BitReaderError::NotEnoughData => "Requested more bits than the byte slice has left",
            BitReaderError::TooManyBitsForType => "Requested more bits than the requested integer type can hold",
        }
    }
}

impl fmt::Display for BitReaderError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        self.description().fmt(fmt)
    }
}

/// Helper trait to allow reading bits into a variable with the help of type inference.
///
/// If you can't or want, for some reason, to use BitReader's read methods (`read_u8` etc.) but
/// want to rely on type inference instead, you can use the ReadInto trait. The trait is
/// implemented for all basic integer types (8/16/32/64 bits, signed/unsigned).
///
/// ```
/// use bitreader::{BitReader,ReadInto};
///
/// let slice_of_u8 = &[0b1100_0000];
/// let mut reader = BitReader::new(slice_of_u8);
///
/// struct Foo {
///     bar: u8
/// }
///
/// // No type mentioned here, instead the type of `bits` is inferred from the type of Foo::bar,
/// // and consequently the correct "overload" is used.
/// let bits = ReadInto::read(&mut reader, 2).unwrap();
///
/// let foo = Foo { bar: bits };
/// assert_eq!(foo.bar, 3)
/// ```
pub trait ReadInto {
    fn read(reader: &mut BitReader, bits: u8) -> Result<Self>;
}

// There's eight almost identical implementations, let's make this easier.
macro_rules! impl_read_into {
    ($T:ty, $method:ident) => (
        impl ReadInto for $T {
            fn read(reader: &mut BitReader, bits: u8) -> Result<Self> {
                reader.$method(bits)
            }
        }
    )
}

impl_read_into!(u8, read_u8);
impl_read_into!(u16, read_u16);
impl_read_into!(u32, read_u32);
impl_read_into!(u64, read_u64);

impl_read_into!(i8, read_i8);
impl_read_into!(i16, read_i16);
impl_read_into!(i32, read_i32);
impl_read_into!(i64, read_i64);
<commit_msg>Update documentation.<commit_after>// Copyright 2015 Ilkka Rauta
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! BitReader is a helper type to extract strings of bits from a slice of bytes.
//!
//! Here is how you read first a single bit, then three bits and finally four bits from a byte
//! buffer:
//!
//! ```
//! use bitreader::BitReader;
//!
//! let slice_of_u8 = &[0b1000_1111];
//! let mut reader = BitReader::new(slice_of_u8);
//!
//! // You probably should use try! or some other error handling mechanism in real code if the
//! // length of the input is not known in advance.
//! let a_single_bit = reader.read_u8(1).unwrap();
//! assert_eq!(a_single_bit, 1);
//!
//! let more_bits = reader.read_u8(3).unwrap();
//! assert_eq!(more_bits, 0);
//!
//! let last_bits_of_byte = reader.read_u8(4).unwrap();
//! assert_eq!(last_bits_of_byte, 0b1111);
//! ```
//! You can naturally read bits from longer buffer of data than just a single byte.
//!
//! As you read bits, the internal cursor of BitReader moves on along the stream of bits. Little
//! endian format is assumed when reading the multi-byte values. BitReader supports reading maximum
//! of 64 bits at a time (with read_u64). Reading signed values directly is not supported at the
//! moment.
//!
//! The reads do not need to be aligned in any particular way.
//!
//! Reading zero bits is a no-op.
//!
//! You can also skip over a number of bits, in which case there is no arbitrary small limits like
//! when reading the values to a variable. However, you can not seek past the end of the slice,
//! either when reading or when skipping bits.
//!
//! Note that the code will likely not work correctly if the slice is longer than 2^61 bytes, but
//! exceeding that should be pretty unlikely. Let's get back to this when people read exabytes of
//! information one bit at a time.

use std::fmt;
use std::error::Error;
use std::result;

#[cfg(test)]
mod tests;

/// BitReader reads data from a byte slice at the granularity of a single bit.
pub struct BitReader<'a> {
    bytes: &'a [u8],
    /// Position from the start of the slice, counted as bits instead of bytes
    position: u64,
}

impl<'a> BitReader<'a> {
    /// Construct a new BitReader from a byte slice. The returned reader lives at most as long as
    /// the slice given to is valid.
    pub fn new(bytes: &'a [u8]) -> BitReader<'a> {
        BitReader {
            bytes: bytes,
            position: 0
        }
    }

    /// Read at most 8 bits into a u8.
    pub fn read_u8(&mut self, bit_count: u8) -> Result<u8> {
        let value = try!(self.read_value(bit_count, 8));
        Ok((value & 0xff) as u8)
    }

    /// Read at most 16 bits into a u16.
    pub fn read_u16(&mut self, bit_count: u8) -> Result<u16> {
        let value = try!(self.read_value(bit_count, 16));
        Ok((value & 0xffff) as u16)
    }

    /// Read at most 32 bits into a u32.
    pub fn read_u32(&mut self, bit_count: u8) -> Result<u32> {
        let value = try!(self.read_value(bit_count, 32));
        Ok((value & 0xffffffff) as u32)
    }

    /// Read at most 64 bits into a u64.
    pub fn read_u64(&mut self, bit_count: u8) -> Result<u64> {
        let value = try!(self.read_value(bit_count, 64));
        Ok(value)
    }

    /// Read at most 8 bits into a i8.
    /// Assumes the bits are stored in two's complement format.
    pub fn read_i8(&mut self, bit_count: u8) -> Result<i8> {
        let value = try!(self.read_signed_value(bit_count, 8));
        Ok((value & 0xff) as i8)
    }

    /// Read at most 16 bits into a i16.
    /// Assumes the bits are stored in two's complement format.
    pub fn read_i16(&mut self, bit_count: u8) -> Result<i16> {
        let value = try!(self.read_signed_value(bit_count, 16));
        Ok((value & 0xffff) as i16)
    }

    /// Read at most 32 bits into a i32.
    /// Assumes the bits are stored in two's complement format.
    pub fn read_i32(&mut self, bit_count: u8) -> Result<i32> {
        let value = try!(self.read_signed_value(bit_count, 32));
        Ok((value & 0xffffffff) as i32)
    }

    /// Read at most 64 bits into a i64.
    /// Assumes the bits are stored in two's complement format.
    pub fn read_i64(&mut self, bit_count: u8) -> Result<i64> {
        let value = try!(self.read_signed_value(bit_count, 64));
        Ok(value)
    }

    /// Skip arbitrary number of bits. However, you can skip at most to the end of the byte slice.
    pub fn skip(&mut self, bit_count: u32) -> Result<()> {
        let end_position = self.position + bit_count as u64;
        if end_position > self.bytes.len() as u64 * 8 {
            return Err(BitReaderError::NotEnoughData);
        }
        self.position = end_position;
        Ok(())
    }

    /// Returns the position of the cursor, or how many bits have been read so far.
    pub fn position(&self) -> u64 {
        self.position
    }

    /// Helper to make sure the "bit cursor" is exactly at the beginning of a byte, or at specific
    /// multi-byte alignment position.
    ///
    /// For example `reader.is_aligned(1)` returns true if exactly n bytes, or n * 8 bits, has been
    /// read. Similarly, `reader.is_aligned(4)` returns true if exactly n * 32 bits, or n 4-byte
    /// sequences has been read.
    ///
    /// This function can be used to validate the data is being read properly, for example by
    /// adding invocations wrapped into `debug_assert!()` to places where it is known the data
    /// should be n-byte aligned.
    pub fn is_aligned(&self, alignment_bytes: u32) -> bool {
        self.position % (alignment_bytes as u64 * 8) == 0
    }

    fn read_signed_value(&mut self, bit_count: u8, maximum_count: u8) -> Result<i64> {
        let unsigned = try!(self.read_value(bit_count, maximum_count));
        // Fill the bits above the requested bits with all ones or all zeros,
        // depending on the sign bit.
        let sign_bit = unsigned >> (bit_count - 1) & 1;
        let high_bits = if sign_bit == 1 { -1 } else { 0 };
        Ok(high_bits << bit_count | unsigned as i64)
    }

    fn read_value(&mut self, bit_count: u8, maximum_count: u8) -> Result<u64> {
        if bit_count == 0 {
            return Ok(0);
        }
        if bit_count > maximum_count {
            return Err(BitReaderError::TooManyBitsForType);
        }
        let start_position = self.position;
        let end_position = self.position + bit_count as u64;
        if end_position > self.bytes.len() as u64 * 8 {
            return Err(BitReaderError::NotEnoughData);
        }

        let mut value: u64 = 0;

        for i in start_position..end_position {
            let byte_index = (i / 8) as usize;
            let byte = self.bytes[byte_index];
            let shift = 7 - (i % 8);
            let bit = (byte >> shift) as u64 & 1;
            value = (value << 1) | bit;
        }

        self.position = end_position;
        Ok(value)
    }
}

/// Result type for those BitReader operations that can fail.
pub type Result<T> = result::Result<T, BitReaderError>;

/// Error enumeration of BitReader errors.
#[derive(Debug,PartialEq,Copy,Clone)]
pub enum BitReaderError {
    /// Requested more bits than there are left in the byte slice at the current position.
    NotEnoughData,
    /// Requested more bits than the returned variable can hold, for example more than 8 bits when
    /// reading into a u8.
    TooManyBitsForType
}

impl Error for BitReaderError {
    fn description(&self) -> &str {
        match *self {
            BitReaderError::NotEnoughData => "Requested more bits than the byte slice has left",
            BitReaderError::TooManyBitsForType => "Requested more bits than the requested integer type can hold",
        }
    }
}

impl fmt::Display for BitReaderError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        self.description().fmt(fmt)
    }
}

/// Helper trait to allow reading bits into a variable without explicitly mentioning its type.
///
/// If you can't or want, for some reason, to use BitReader's read methods (`read_u8` etc.) but
/// want to rely on type inference instead, you can use the ReadInto trait. The trait is
/// implemented for all basic integer types (8/16/32/64 bits, signed/unsigned).
///
/// ```
/// use bitreader::{BitReader,ReadInto};
///
/// let slice_of_u8 = &[0b1100_0000];
/// let mut reader = BitReader::new(slice_of_u8);
///
/// struct Foo {
///     bar: u8
/// }
///
/// // No type mentioned here, instead the type of bits is inferred from the type of Foo::bar,
/// // and consequently the correct "overload" is used.
/// let bits = ReadInto::read(&mut reader, 2).unwrap();
///
/// let foo = Foo { bar: bits };
/// assert_eq!(foo.bar, 3)
/// ```
pub trait ReadInto {
    fn read(reader: &mut BitReader, bits: u8) -> Result<Self>;
}

// There's eight almost identical implementations, let's make this easier.
macro_rules! impl_read_into {
    ($T:ty, $method:ident) => (
        impl ReadInto for $T {
            fn read(reader: &mut BitReader, bits: u8) -> Result<Self> {
                reader.$method(bits)
            }
        }
    )
}

impl_read_into!(u8, read_u8);
impl_read_into!(u16, read_u16);
impl_read_into!(u32, read_u32);
impl_read_into!(u64, read_u64);

impl_read_into!(i8, read_i8);
impl_read_into!(i16, read_i16);
impl_read_into!(i32, read_i32);
impl_read_into!(i64, read_i64);
<|endoftext|>


<commit_before>extern crate libc;

use std::os::raw;
use std::ffi::CString;
use std::mem::transmute;

#[link(name = "rust")]
extern {
  fn klee_make_symbolic(data: *const raw::c_void, length: raw::size_t, name: *const raw::c_char);
}

pub fn any(data: *const raw::c_void, length: usize, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(data, length as raw::size_t, name_cstr.as_ptr());
  }
}

pub fn i32(data: *const i32, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(transmute(data), 4, name_cstr.as_ptr());
  }
}

pub fn u32(data: *const u32, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(transmute(data), 4, name_cstr.as_ptr());
  }
}
<commit_msg>Update lib.rs<commit_after>extern crate libc;

use std::os::raw;
use std::ffi::CString;
use std::mem::transmute;

#[link(name = "rust")]
extern {
  fn klee_make_symbolic(data: *const raw::c_void, length: libc::size_t, name: *const raw::c_char);
}

pub fn any(data: *const raw::c_void, length: usize, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(data, length as raw::size_t, name_cstr.as_ptr());
  }
}

pub fn i32(data: *const i32, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(transmute(data), 4, name_cstr.as_ptr());
  }
}

pub fn u32(data: *const u32, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(transmute(data), 4, name_cstr.as_ptr());
  }
}
<|endoftext|>


<commit_before>#![allow(non_camel_case_types)]

extern crate libc;
use libc::{c_int, c_uint, c_char, c_uchar, c_void, c_double, int32_t, uint32_t, int16_t, uint16_t, int8_t};

pub const FREENECT_COUNTS_PER_G: 		c_int = 829;
pub const FREENECT_DEPTH_MM_MAX_VALUE: 	c_int = 10000;
pub const FREENECT_DEPTH_MM_NO_VALUE: 	c_int = 0;
pub const FREENECT_DEPTH_RAW_MAX_VALUE: c_int = 2048;
pub const FREENECT_DEPTH_RAW_NO_VALUE: 	c_int = 2047;

#[repr(C)] pub enum freenect_device_flags {
	FREENECT_DEVICE_MOTOR  = 0x01,
	FREENECT_DEVICE_CAMERA = 0x02,
	FREENECT_DEVICE_AUDIO  = 0x04,
}

#[repr(C)] pub struct freenect_device_attributes {
	pub next: *mut freenect_device_attributes,
	pub camera_serial: *const c_char,
}

#[repr(C)] pub enum freenect_resolution {
	FREENECT_RESOLUTION_LOW    = 0, // QVGA - 320x240
	FREENECT_RESOLUTION_MEDIUM = 1, // VGA  - 640x480
	FREENECT_RESOLUTION_HIGH   = 2, // SXGA - 1280x1024
	FREENECT_RESOLUTION_DUMMY  = 2147483647, // Dummy value to force enum to be 32 bits wide
}

#[repr(C)] pub enum freenect_video_format {
	FREENECT_VIDEO_RGB             = 0, // Decompressed RGB mode (demosaicing done by libfreenect)
	FREENECT_VIDEO_BAYER           = 1, // Bayer compressed mode (raw information from camera)
	FREENECT_VIDEO_IR_8BIT         = 2, // 8-bit IR mode
	FREENECT_VIDEO_IR_10BIT        = 3, // 10-bit IR mode
	FREENECT_VIDEO_IR_10BIT_PACKED = 4, // 10-bit packed IR mode
	FREENECT_VIDEO_YUV_RGB         = 5, // YUV RGB mode
	FREENECT_VIDEO_YUV_RAW         = 6, // YUV Raw mode
	FREENECT_VIDEO_DUMMY           = 2147483647, // Dummy value to force enum to be 32 bits wide
}

#[repr(C)] pub enum freenect_depth_format {
	FREENECT_DEPTH_11BIT        = 0, // 11 bit depth information in one uint16_t/pixel
	FREENECT_DEPTH_10BIT        = 1, // 10 bit depth information in one uint16_t/pixel
	FREENECT_DEPTH_11BIT_PACKED = 2, // 11 bit packed depth information
	FREENECT_DEPTH_10BIT_PACKED = 3, // 10 bit packed depth information
	FREENECT_DEPTH_REGISTERED   = 4, // processed depth data in mm, aligned to 640x480 RGB
	FREENECT_DEPTH_MM           = 5, // depth to each pixel in mm, but left unaligned to RGB image
	FREENECT_DEPTH_DUMMY        = 2147483647, // Dummy value to force enum to be 32 bits wide
}

#[repr(C)] pub enum freenect_flag {
	// values written to the CMOS register
	FREENECT_AUTO_EXPOSURE      = 1 << 14,
	FREENECT_AUTO_WHITE_BALANCE = 1 << 1,
	FREENECT_RAW_COLOR          = 1 << 4,
	// registers to be written with 0 or 1
	FREENECT_MIRROR_DEPTH       = 0x0017,
	FREENECT_MIRROR_VIDEO       = 0x0047,
}

#[repr(C)] pub enum freenect_flag_value {
	FREENECT_OFF = 0,
	FREENECT_ON  = 1,
}

#[repr(C)] pub struct freenect_frame_mode {
	pub reserved: uint32_t,              // unique ID used internally.  The meaning of values may change without notice.  Don't touch or depend on the contents of this field.  We mean it.
	pub resolution: freenect_resolution, // Resolution this freenect_frame_mode describes, should you want to find it again with freenect_find_*_frame_mode().
	pub dummy: int32_t,                  // The video or depth format that this freenect_frame_mode describes.  The caller should know which of video_format or depth_format to use, since they called freenect_get_*_frame_mode()
	pub bytes: int32_t,                  // Total buffer size in bytes to hold a single frame of data.  Should be equivalent to width * height * (data_bits_per_pixel+padding_bits_per_pixel) / 8
	pub width: int16_t,                  // Width of the frame, in pixels
	pub height: int16_t,                 // Height of the frame, in pixels
	pub data_bits_per_pixel: int8_t,     // Number of bits of information needed for each pixel
	pub padding_bits_per_pixel: int8_t,  // Number of bits of padding for alignment used for each pixel
	pub framerate: int8_t,               // Approximate expected frame rate, in Hz
	pub is_valid: int8_t,                // If 0, this freenect_frame_mode is invalid and does not describe a supported mode.  Otherwise, the frame_mode is valid.
}

#[repr(C)] pub enum freenect_led_option {
	LED_OFF              = 0, // Turn LED off
	LED_GREEN            = 1, // Turn LED to Green
	LED_RED              = 2, // Turn LED to Red
	LED_YELLOW           = 3, // Turn LED to Yellow
	LED_BLINK_GREEN      = 4, // Make LED blink Green
	// 5 is same as 4, LED blink Green
	LED_BLINK_RED_YELLOW = 6, // Make LED blink Red/Yellow
}

#[repr(C)] pub enum freenect_tilt_status_code {
	TILT_STATUS_STOPPED = 0x00, // Tilt motor is stopped
	TILT_STATUS_LIMIT   = 0x01, // Tilt motor has reached movement limit
	TILT_STATUS_MOVING  = 0x04, // Tilt motor is currently moving to new position
}

#[repr(C)] pub struct freenect_raw_tilt_state {
	pub accelerometer_x: int16_t                  , // Raw accelerometer data for X-axis, see FREENECT_COUNTS_PER_G for conversion
	pub accelerometer_y: int16_t                  , // Raw accelerometer data for Y-axis, see FREENECT_COUNTS_PER_G for conversion
	pub accelerometer_z: int16_t                  , // Raw accelerometer data for Z-axis, see FREENECT_COUNTS_PER_G for conversion
	pub tilt_angle:      int8_t                   , // Raw tilt motor angle encoder information
	pub tilt_status: 	 freenect_tilt_status_code, // State of the tilt motor (stopped, moving, etc...)
}

pub enum freenect_context {}

pub enum freenect_device {}

pub enum freenect_usb_context {}

#[repr(C)] pub enum freenect_loglevel {
	FREENECT_LOG_FATAL = 0,     // Log for crashing/non-recoverable errors
	FREENECT_LOG_ERROR,         // Log for major errors
	FREENECT_LOG_WARNING,       // Log for warning messages
	FREENECT_LOG_NOTICE,        // Log for important messages
	FREENECT_LOG_INFO,          // Log for normal messages
	FREENECT_LOG_DEBUG,         // Log for useful development messages
	FREENECT_LOG_SPEW,          // Log for slightly less useful messages
	FREENECT_LOG_FLOOD,         // Log EVERYTHING. May slow performance.
}

pub type freenect_log_cb   = extern fn(dev: *mut freenect_context, level: freenect_loglevel, msg: *const c_char);
pub type freenect_depth_cb = extern fn(dev: *mut freenect_device, depth: *mut c_void, timestamp: uint32_t);
pub type freenect_video_cb = extern fn(dev: *mut freenect_device, video: *mut c_void, timestamp: uint32_t);
pub type freenect_chunk_cb = extern fn(buffer: *mut c_void, pkt_data: *mut c_void, pkt_num: c_int, datalen: c_int, user_data: *mut c_void);

#[link(name = "freenect")]
extern "C" {
    pub fn freenect_init(ctx: *mut *mut freenect_context, usb_ctx: *mut freenect_usb_context) -> c_int;
	pub fn freenect_shutdown(ctx: *mut freenect_context) -> c_int;
	pub fn freenect_set_log_level(ctx: *mut freenect_context, level: freenect_loglevel);
	pub fn freenect_set_log_callback(ctx: *mut freenect_context, cb: freenect_log_cb);
	pub fn freenect_process_events(ctx: *mut freenect_context) -> c_int;
	pub fn freenect_process_events_timeout(ctx: *mut freenect_context, timeout: libc::timeval) -> c_int;
	pub fn freenect_num_devices(ctx: *mut freenect_context) -> c_int;
	pub fn freenect_list_device_attributes(ctx: *mut freenect_context, attribute_list: *mut *mut freenect_device_attributes) -> c_int;
	pub fn freenect_free_device_attributes(attribute_list: *mut freenect_device_attributes);
	pub fn freenect_supported_subdevices() -> c_int;
	pub fn freenect_select_subdevices(ctx: *mut freenect_context, subdevs: u32); // Not enum type as bitfield can have multiple choices
	pub fn freenect_enabled_subdevices(ctx: *mut freenect_context) -> freenect_device_flags;
	pub fn freenect_open_device(ctx: *mut freenect_context, dev: *mut *mut freenect_device, index: c_int) -> c_int;
	pub fn freenect_open_device_by_camera_serial(ctx: *mut freenect_context, dev: *mut *mut freenect_device, camera_serial: *const c_char) -> c_int;
	pub fn freenect_close_device(dev: *mut freenect_device) -> c_int;
	pub fn freenect_set_user(dev: *mut freenect_device, user: *mut c_void);
	pub fn freenect_get_user(dev: *mut freenect_device) -> *mut c_void;
	pub fn freenect_set_depth_callback(dev: *mut freenect_device, cb: freenect_depth_cb);
	pub fn freenect_set_video_callback(dev: *mut freenect_device, cb: freenect_video_cb);
	pub fn freenect_set_depth_chunk_callback(dev: *mut freenect_device, cb: freenect_chunk_cb);
	pub fn freenect_set_video_chunk_callback(dev: *mut freenect_device, cb: freenect_chunk_cb);
	pub fn freenect_set_depth_buffer(dev: *mut freenect_device, buf: *mut c_void) -> c_int;
	pub fn freenect_set_video_buffer(dev: *mut freenect_device, buf: *mut c_void) -> c_int;
	pub fn freenect_start_depth(dev: *mut freenect_device) -> c_int;
	pub fn freenect_start_video(dev: *mut freenect_device) -> c_int;
	pub fn freenect_stop_depth(dev: *mut freenect_device) -> c_int;
	pub fn freenect_stop_video(dev: *mut freenect_device) -> c_int;
	pub fn freenect_update_tilt_state(dev: *mut freenect_device) -> c_int;
	pub fn freenect_get_tilt_state(dev: *mut freenect_device) -> *mut freenect_raw_tilt_state;
	pub fn freenect_get_tilt_degs(state: *mut freenect_raw_tilt_state) -> c_double;
	pub fn freenect_set_tilt_degs(dev: *mut freenect_device, angle: c_double) -> c_int;
	pub fn freenect_get_tilt_status(state: *mut freenect_raw_tilt_state) -> freenect_tilt_status_code;
	pub fn freenect_set_led(dev: *mut freenect_device, option: freenect_led_option) -> c_int;
	pub fn freenect_get_mks_accel(state: *mut freenect_raw_tilt_state, x: *mut c_double, y: *mut c_double, z: *mut c_double);
	pub fn freenect_get_video_mode_count() -> c_int;
	pub fn freenect_get_video_mode(mode_num: c_int) -> freenect_frame_mode;
	pub fn freenect_get_current_video_mode(dev: *mut freenect_device) -> freenect_frame_mode;
	pub fn freenect_find_video_mode(res: freenect_resolution, fmt: freenect_video_format) -> freenect_frame_mode;
	pub fn freenect_set_video_mode(dev: *mut freenect_device, mode: freenect_frame_mode) -> c_int;
	pub fn freenect_get_depth_mode_count() -> c_int;
	pub fn freenect_get_depth_mode(mode_num: c_int) -> freenect_frame_mode;
	pub fn freenect_get_current_depth_mode(dev: *mut freenect_device) -> freenect_frame_mode;
	pub fn freenect_find_depth_mode(res: freenect_resolution, fmt: freenect_depth_format) -> freenect_frame_mode;
	pub fn freenect_set_depth_mode(dev: *mut freenect_device, mode: freenect_frame_mode) -> c_int;
	pub fn freenect_set_flag(dev: *mut freenect_device, flag: freenect_flag, value: freenect_flag_value) -> c_int;
	pub fn freenect_get_ir_brightness(dev: *mut freenect_device) -> c_int;
	pub fn freenect_set_ir_brightness(dev: *mut freenect_device, brightness: uint16_t) -> c_int;
	pub fn freenect_set_fw_address_nui(ctx: *mut freenect_context, fw_ptr: *mut c_uchar, num_bytes: c_uint);
	pub fn freenect_set_fw_address_k4w(ctx: *mut freenect_context, fw_ptr: *mut c_uchar, num_bytes: c_uint);
}
<commit_msg>Roll back minimum freenect library version to 0.2<commit_after>#![allow(non_camel_case_types)]

extern crate libc;
use libc::{c_int, c_uint, c_char, c_uchar, c_void, c_double, int32_t, uint32_t, int16_t, uint16_t, int8_t};

pub const FREENECT_COUNTS_PER_G: 		c_int = 829;
pub const FREENECT_DEPTH_MM_MAX_VALUE: 	c_int = 10000;
pub const FREENECT_DEPTH_MM_NO_VALUE: 	c_int = 0;
pub const FREENECT_DEPTH_RAW_MAX_VALUE: c_int = 2048;
pub const FREENECT_DEPTH_RAW_NO_VALUE: 	c_int = 2047;

#[repr(C)] pub enum freenect_device_flags {
	FREENECT_DEVICE_MOTOR  = 0x01,
	FREENECT_DEVICE_CAMERA = 0x02,
	FREENECT_DEVICE_AUDIO  = 0x04,
}

#[repr(C)] pub struct freenect_device_attributes {
	pub next: *mut freenect_device_attributes,
	pub camera_serial: *const c_char,
}

#[repr(C)] pub enum freenect_resolution {
	FREENECT_RESOLUTION_LOW    = 0, // QVGA - 320x240
	FREENECT_RESOLUTION_MEDIUM = 1, // VGA  - 640x480
	FREENECT_RESOLUTION_HIGH   = 2, // SXGA - 1280x1024
	FREENECT_RESOLUTION_DUMMY  = 2147483647, // Dummy value to force enum to be 32 bits wide
}

#[repr(C)] pub enum freenect_video_format {
	FREENECT_VIDEO_RGB             = 0, // Decompressed RGB mode (demosaicing done by libfreenect)
	FREENECT_VIDEO_BAYER           = 1, // Bayer compressed mode (raw information from camera)
	FREENECT_VIDEO_IR_8BIT         = 2, // 8-bit IR mode
	FREENECT_VIDEO_IR_10BIT        = 3, // 10-bit IR mode
	FREENECT_VIDEO_IR_10BIT_PACKED = 4, // 10-bit packed IR mode
	FREENECT_VIDEO_YUV_RGB         = 5, // YUV RGB mode
	FREENECT_VIDEO_YUV_RAW         = 6, // YUV Raw mode
	FREENECT_VIDEO_DUMMY           = 2147483647, // Dummy value to force enum to be 32 bits wide
}

#[repr(C)] pub enum freenect_depth_format {
	FREENECT_DEPTH_11BIT        = 0, // 11 bit depth information in one uint16_t/pixel
	FREENECT_DEPTH_10BIT        = 1, // 10 bit depth information in one uint16_t/pixel
	FREENECT_DEPTH_11BIT_PACKED = 2, // 11 bit packed depth information
	FREENECT_DEPTH_10BIT_PACKED = 3, // 10 bit packed depth information
	FREENECT_DEPTH_REGISTERED   = 4, // processed depth data in mm, aligned to 640x480 RGB
	FREENECT_DEPTH_MM           = 5, // depth to each pixel in mm, but left unaligned to RGB image
	FREENECT_DEPTH_DUMMY        = 2147483647, // Dummy value to force enum to be 32 bits wide
}

#[repr(C)] pub enum freenect_flag {
	// values written to the CMOS register
	FREENECT_AUTO_EXPOSURE      = 1 << 14,
	FREENECT_AUTO_WHITE_BALANCE = 1 << 1,
	FREENECT_RAW_COLOR          = 1 << 4,
	// registers to be written with 0 or 1
	FREENECT_MIRROR_DEPTH       = 0x0017,
	FREENECT_MIRROR_VIDEO       = 0x0047,
}

#[repr(C)] pub enum freenect_flag_value {
	FREENECT_OFF = 0,
	FREENECT_ON  = 1,
}

#[repr(C)] pub struct freenect_frame_mode {
	pub reserved: uint32_t,              // unique ID used internally.  The meaning of values may change without notice.  Don't touch or depend on the contents of this field.  We mean it.
	pub resolution: freenect_resolution, // Resolution this freenect_frame_mode describes, should you want to find it again with freenect_find_*_frame_mode().
	pub dummy: int32_t,                  // The video or depth format that this freenect_frame_mode describes.  The caller should know which of video_format or depth_format to use, since they called freenect_get_*_frame_mode()
	pub bytes: int32_t,                  // Total buffer size in bytes to hold a single frame of data.  Should be equivalent to width * height * (data_bits_per_pixel+padding_bits_per_pixel) / 8
	pub width: int16_t,                  // Width of the frame, in pixels
	pub height: int16_t,                 // Height of the frame, in pixels
	pub data_bits_per_pixel: int8_t,     // Number of bits of information needed for each pixel
	pub padding_bits_per_pixel: int8_t,  // Number of bits of padding for alignment used for each pixel
	pub framerate: int8_t,               // Approximate expected frame rate, in Hz
	pub is_valid: int8_t,                // If 0, this freenect_frame_mode is invalid and does not describe a supported mode.  Otherwise, the frame_mode is valid.
}

#[repr(C)] pub enum freenect_led_option {
	LED_OFF              = 0, // Turn LED off
	LED_GREEN            = 1, // Turn LED to Green
	LED_RED              = 2, // Turn LED to Red
	LED_YELLOW           = 3, // Turn LED to Yellow
	LED_BLINK_GREEN      = 4, // Make LED blink Green
	// 5 is same as 4, LED blink Green
	LED_BLINK_RED_YELLOW = 6, // Make LED blink Red/Yellow
}

#[repr(C)] pub enum freenect_tilt_status_code {
	TILT_STATUS_STOPPED = 0x00, // Tilt motor is stopped
	TILT_STATUS_LIMIT   = 0x01, // Tilt motor has reached movement limit
	TILT_STATUS_MOVING  = 0x04, // Tilt motor is currently moving to new position
}

#[repr(C)] pub struct freenect_raw_tilt_state {
	pub accelerometer_x: int16_t                  , // Raw accelerometer data for X-axis, see FREENECT_COUNTS_PER_G for conversion
	pub accelerometer_y: int16_t                  , // Raw accelerometer data for Y-axis, see FREENECT_COUNTS_PER_G for conversion
	pub accelerometer_z: int16_t                  , // Raw accelerometer data for Z-axis, see FREENECT_COUNTS_PER_G for conversion
	pub tilt_angle:      int8_t                   , // Raw tilt motor angle encoder information
	pub tilt_status: 	 freenect_tilt_status_code, // State of the tilt motor (stopped, moving, etc...)
}

pub enum freenect_context {}

pub enum freenect_device {}

pub enum freenect_usb_context {}

#[repr(C)] pub enum freenect_loglevel {
	FREENECT_LOG_FATAL = 0,     // Log for crashing/non-recoverable errors
	FREENECT_LOG_ERROR,         // Log for major errors
	FREENECT_LOG_WARNING,       // Log for warning messages
	FREENECT_LOG_NOTICE,        // Log for important messages
	FREENECT_LOG_INFO,          // Log for normal messages
	FREENECT_LOG_DEBUG,         // Log for useful development messages
	FREENECT_LOG_SPEW,          // Log for slightly less useful messages
	FREENECT_LOG_FLOOD,         // Log EVERYTHING. May slow performance.
}

pub type freenect_log_cb   = extern fn(dev: *mut freenect_context, level: freenect_loglevel, msg: *const c_char);
pub type freenect_depth_cb = extern fn(dev: *mut freenect_device, depth: *mut c_void, timestamp: uint32_t);
pub type freenect_video_cb = extern fn(dev: *mut freenect_device, video: *mut c_void, timestamp: uint32_t);

#[link(name = "freenect")]
extern "C" {
    pub fn freenect_init(ctx: *mut *mut freenect_context, usb_ctx: *mut freenect_usb_context) -> c_int;
	pub fn freenect_shutdown(ctx: *mut freenect_context) -> c_int;
	pub fn freenect_set_log_level(ctx: *mut freenect_context, level: freenect_loglevel);
	pub fn freenect_set_log_callback(ctx: *mut freenect_context, cb: freenect_log_cb);
	pub fn freenect_process_events(ctx: *mut freenect_context) -> c_int;
	pub fn freenect_process_events_timeout(ctx: *mut freenect_context, timeout: libc::timeval) -> c_int;
	pub fn freenect_num_devices(ctx: *mut freenect_context) -> c_int;
	pub fn freenect_list_device_attributes(ctx: *mut freenect_context, attribute_list: *mut *mut freenect_device_attributes) -> c_int;
	pub fn freenect_free_device_attributes(attribute_list: *mut freenect_device_attributes);
	pub fn freenect_supported_subdevices() -> c_int;
	pub fn freenect_select_subdevices(ctx: *mut freenect_context, subdevs: u32); // Not enum type as bitfield can have multiple choices
	pub fn freenect_enabled_subdevices(ctx: *mut freenect_context) -> freenect_device_flags;
	pub fn freenect_open_device(ctx: *mut freenect_context, dev: *mut *mut freenect_device, index: c_int) -> c_int;
	pub fn freenect_open_device_by_camera_serial(ctx: *mut freenect_context, dev: *mut *mut freenect_device, camera_serial: *const c_char) -> c_int;
	pub fn freenect_close_device(dev: *mut freenect_device) -> c_int;
	pub fn freenect_set_user(dev: *mut freenect_device, user: *mut c_void);
	pub fn freenect_get_user(dev: *mut freenect_device) -> *mut c_void;
	pub fn freenect_set_depth_callback(dev: *mut freenect_device, cb: freenect_depth_cb);
	pub fn freenect_set_video_callback(dev: *mut freenect_device, cb: freenect_video_cb);
	pub fn freenect_set_depth_buffer(dev: *mut freenect_device, buf: *mut c_void) -> c_int;
	pub fn freenect_set_video_buffer(dev: *mut freenect_device, buf: *mut c_void) -> c_int;
	pub fn freenect_start_depth(dev: *mut freenect_device) -> c_int;
	pub fn freenect_start_video(dev: *mut freenect_device) -> c_int;
	pub fn freenect_stop_depth(dev: *mut freenect_device) -> c_int;
	pub fn freenect_stop_video(dev: *mut freenect_device) -> c_int;
	pub fn freenect_update_tilt_state(dev: *mut freenect_device) -> c_int;
	pub fn freenect_get_tilt_state(dev: *mut freenect_device) -> *mut freenect_raw_tilt_state;
	pub fn freenect_get_tilt_degs(state: *mut freenect_raw_tilt_state) -> c_double;
	pub fn freenect_set_tilt_degs(dev: *mut freenect_device, angle: c_double) -> c_int;
	pub fn freenect_get_tilt_status(state: *mut freenect_raw_tilt_state) -> freenect_tilt_status_code;
	pub fn freenect_set_led(dev: *mut freenect_device, option: freenect_led_option) -> c_int;
	pub fn freenect_get_mks_accel(state: *mut freenect_raw_tilt_state, x: *mut c_double, y: *mut c_double, z: *mut c_double);
	pub fn freenect_get_video_mode_count() -> c_int;
	pub fn freenect_get_video_mode(mode_num: c_int) -> freenect_frame_mode;
	pub fn freenect_get_current_video_mode(dev: *mut freenect_device) -> freenect_frame_mode;
	pub fn freenect_find_video_mode(res: freenect_resolution, fmt: freenect_video_format) -> freenect_frame_mode;
	pub fn freenect_set_video_mode(dev: *mut freenect_device, mode: freenect_frame_mode) -> c_int;
	pub fn freenect_get_depth_mode_count() -> c_int;
	pub fn freenect_get_depth_mode(mode_num: c_int) -> freenect_frame_mode;
	pub fn freenect_get_current_depth_mode(dev: *mut freenect_device) -> freenect_frame_mode;
	pub fn freenect_find_depth_mode(res: freenect_resolution, fmt: freenect_depth_format) -> freenect_frame_mode;
	pub fn freenect_set_depth_mode(dev: *mut freenect_device, mode: freenect_frame_mode) -> c_int;
	pub fn freenect_set_flag(dev: *mut freenect_device, flag: freenect_flag, value: freenect_flag_value) -> c_int;
}
<|endoftext|>


<commit_before>#![deny(missing_docs)]

//! Meta parsing and encoding for data oriented design

extern crate read_token;
extern crate range;

pub use whitespace::Whitespace;
pub use parse_error_handler::{ ParseErrorHandler, ParseStdErr };
pub use parse_error::ParseError;
pub use token::Token;
pub use select::Select;
pub use node::Node;
pub use optional::Optional;
pub use sequence::Sequence;
pub use separated_by::SeparatedBy;
pub use repeat::Repeat;
pub use until_any::UntilAny;
pub use until_any_or_whitespace::UntilAnyOrWhitespace;
pub use text::Text;
pub use number::Number;
pub use lines::Lines;
pub use rule::Rule;
pub use tokenizer::{ Tokenizer, TokenizerState };

/// The type of debug id used to track down errors in rules.
pub type DebugId = usize;

use std::rc::Rc;
use range::Range;

mod parse_error;
mod parse_error_handler;
mod token;
mod whitespace;
mod select;
mod node;
mod optional;
mod sequence;
mod separated_by;
mod repeat;
mod until_any;
mod until_any_or_whitespace;
mod text;
mod number;
mod lines;
mod rule;
mod tokenizer;

/// Parses text with rules.
pub fn parse(
    rules: &[(Rc<String>, Rule)],
    text: &str
) -> Result<Vec<(Range, MetaData)>, (Range, ParseError)> {
    let chars: Vec<char> = text.chars().collect();
    let mut tokenizer = Tokenizer::new();
    let s = TokenizerState::new();
    let n = match rules.len() {
        0 => { return Err((Range::empty(0), ParseError::NoRules)); }
        x => x
    };
    let res = rules[n - 1].1.parse(&mut tokenizer, &s, &chars, 0, rules);
    match res {
        Ok((range, s, Some((err_range, err)))) => {
            // Report error if did not reach the end of text.
            if range.next_offset() < text.len() {
                Err((err_range, err))
            } else {
                tokenizer.tokens.truncate(s.0);
                Ok(tokenizer.tokens)
            }
        }
        Ok((_, s, None)) => {
            tokenizer.tokens.truncate(s.0);
            Ok(tokenizer.tokens)
        }
        Err((err_range, err)) => {
            Err((err_range, err))
        }
    }
}

/// Updates the references such that they point to each other.
pub fn update_refs(rules: &[(Rc<String>, Rule)]) {
    for r in rules {
        r.1.update_refs(rules);
    }
}

/// A parse result succeeds with a new state,
/// plus an optional error to replace other errors if it is deeper.
/// The deepest error is likely the most useful.
pub type ParseResult<S> = Result<(Range, S, Option<(Range, ParseError)>),
    (Range, ParseError)>;

/// Represents meta data.
#[derive(PartialEq, Clone, Debug)]
pub enum MetaData {
    /// Starts node.
    StartNode(Rc<String>),
    /// Ends node.
    EndNode(Rc<String>),
    /// Sets bool property.
    Bool(Rc<String>, bool),
    /// Sets f64 property.
    F64(Rc<String>, f64),
    /// Sets string property.
    String(Rc<String>, String),
}

/// Updates the parser state.
/// Used by rules that have multiple sub rules.
#[inline(always)]
fn update<'a>(
    range: range::Range,
    err: Option<(Range, ParseError)>,
    chars: &mut &'a [char],
    offset: &mut usize,
    opt_error: &mut Option<(Range, ParseError)>
) {
    let next_offset = range.next_offset();
    *chars = &chars[next_offset - *offset..];
    *offset = next_offset;
    err_update(err, opt_error);
}

/// Picks deepest error, overwriting with the newest one if they are
/// equally deep.
#[inline(always)]
fn err_update(
    err: Option<(Range, ParseError)>,
    opt_error: &mut Option<(Range, ParseError)>
) {
    if let &mut Some(ref mut opt_error) = opt_error {
        if let Some(err) = err {
            if opt_error.0.next_offset() <= err.0.next_offset() {
                *opt_error = err;
            }
        }
    } else {
        *opt_error = err;
    };
}

/// This is used to pick the deepest error or two alternatives,
/// one from a rule that fails certainly and another that could be optional.
#[inline(always)]
fn ret_err(a: (Range, ParseError), b: Option<(Range, ParseError)>) ->
    (Range, ParseError) {
    if let Some(b) = b {
        if b.0.next_offset() > a.0.next_offset() {
            b
        } else {
            a
        }
    } else {
        a
    }
}
<commit_msg>Added unit test for `ParseError::NoRules`<commit_after>#![deny(missing_docs)]

//! Meta parsing and encoding for data oriented design

extern crate read_token;
extern crate range;

pub use whitespace::Whitespace;
pub use parse_error_handler::{ ParseErrorHandler, ParseStdErr };
pub use parse_error::ParseError;
pub use token::Token;
pub use select::Select;
pub use node::Node;
pub use optional::Optional;
pub use sequence::Sequence;
pub use separated_by::SeparatedBy;
pub use repeat::Repeat;
pub use until_any::UntilAny;
pub use until_any_or_whitespace::UntilAnyOrWhitespace;
pub use text::Text;
pub use number::Number;
pub use lines::Lines;
pub use rule::Rule;
pub use tokenizer::{ Tokenizer, TokenizerState };

/// The type of debug id used to track down errors in rules.
pub type DebugId = usize;

use std::rc::Rc;
use range::Range;

mod parse_error;
mod parse_error_handler;
mod token;
mod whitespace;
mod select;
mod node;
mod optional;
mod sequence;
mod separated_by;
mod repeat;
mod until_any;
mod until_any_or_whitespace;
mod text;
mod number;
mod lines;
mod rule;
mod tokenizer;

/// Parses text with rules.
pub fn parse(
    rules: &[(Rc<String>, Rule)],
    text: &str
) -> Result<Vec<(Range, MetaData)>, (Range, ParseError)> {
    let chars: Vec<char> = text.chars().collect();
    let mut tokenizer = Tokenizer::new();
    let s = TokenizerState::new();
    let n = match rules.len() {
        0 => { return Err((Range::empty(0), ParseError::NoRules)); }
        x => x
    };
    let res = rules[n - 1].1.parse(&mut tokenizer, &s, &chars, 0, rules);
    match res {
        Ok((range, s, Some((err_range, err)))) => {
            // Report error if did not reach the end of text.
            if range.next_offset() < text.len() {
                Err((err_range, err))
            } else {
                tokenizer.tokens.truncate(s.0);
                Ok(tokenizer.tokens)
            }
        }
        Ok((_, s, None)) => {
            tokenizer.tokens.truncate(s.0);
            Ok(tokenizer.tokens)
        }
        Err((err_range, err)) => {
            Err((err_range, err))
        }
    }
}

/// Updates the references such that they point to each other.
pub fn update_refs(rules: &[(Rc<String>, Rule)]) {
    for r in rules {
        r.1.update_refs(rules);
    }
}

/// A parse result succeeds with a new state,
/// plus an optional error to replace other errors if it is deeper.
/// The deepest error is likely the most useful.
pub type ParseResult<S> = Result<(Range, S, Option<(Range, ParseError)>),
    (Range, ParseError)>;

/// Represents meta data.
#[derive(PartialEq, Clone, Debug)]
pub enum MetaData {
    /// Starts node.
    StartNode(Rc<String>),
    /// Ends node.
    EndNode(Rc<String>),
    /// Sets bool property.
    Bool(Rc<String>, bool),
    /// Sets f64 property.
    F64(Rc<String>, f64),
    /// Sets string property.
    String(Rc<String>, String),
}

/// Updates the parser state.
/// Used by rules that have multiple sub rules.
#[inline(always)]
fn update<'a>(
    range: range::Range,
    err: Option<(Range, ParseError)>,
    chars: &mut &'a [char],
    offset: &mut usize,
    opt_error: &mut Option<(Range, ParseError)>
) {
    let next_offset = range.next_offset();
    *chars = &chars[next_offset - *offset..];
    *offset = next_offset;
    err_update(err, opt_error);
}

/// Picks deepest error, overwriting with the newest one if they are
/// equally deep.
#[inline(always)]
fn err_update(
    err: Option<(Range, ParseError)>,
    opt_error: &mut Option<(Range, ParseError)>
) {
    if let &mut Some(ref mut opt_error) = opt_error {
        if let Some(err) = err {
            if opt_error.0.next_offset() <= err.0.next_offset() {
                *opt_error = err;
            }
        }
    } else {
        *opt_error = err;
    };
}

/// This is used to pick the deepest error or two alternatives,
/// one from a rule that fails certainly and another that could be optional.
#[inline(always)]
fn ret_err(a: (Range, ParseError), b: Option<(Range, ParseError)>) ->
    (Range, ParseError) {
    if let Some(b) = b {
        if b.0.next_offset() > a.0.next_offset() {
            b
        } else {
            a
        }
    } else {
        a
    }
}

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

    #[test]
    fn no_rules() {
        assert_eq!(parse(&[], ""),
            Err((Range::empty(0), ParseError::NoRules)));
    }
}
<|endoftext|>