<commit_before>use read_token;
use range::Range;
use std::sync::Arc;

use super::{
    ParseResult,
};
use {
    DebugId,
    MetaData,
    ParseError,
};
use tokenizer::{ read_data, TokenizerState };

/// Stores information about text.
#[derive(Clone, Debug, PartialEq)]
pub struct Text {
    /// Whether to allow empty string.
    pub allow_empty: bool,
    /// Which property to set if text is read.
    pub property: Option<Arc<String>>,
    /// A debug id to track down the rule generating an error.
    pub debug_id: DebugId,
}

impl Text {
    /// Parses text.
    pub fn parse(
        &self,
        tokens: &mut Vec<(Range, MetaData)>,
        state: &TokenizerState,
        chars: &[char],
        offset: usize
    ) -> ParseResult<TokenizerState> {
        if let Some(range) = read_token::string(chars, offset) {
            if !self.allow_empty && range.length == 2 {
                Err((range, ParseError::EmptyTextNotAllowed(self.debug_id)))
            } else {
                match read_token::parse_string(
                    chars, offset, range.next_offset()) {
                    // Focus range to invalid string format.
                    Err(err) => Err((err.range(),
                        ParseError::ParseStringError(err, self.debug_id))),
                    Ok(text) => {
                        if let Some(ref property) = self.property {
                            Ok((range, read_data(
                                tokens,
                                MetaData::String(property.clone(), Arc::new(text)),
                                state,
                                range
                            ), None))
                        } else {
                            Ok((range, state.clone(), None))
                        }
                    }
                }
            }
        } else {
            Err((Range::new(offset, 0),
                ParseError::ExpectedText(self.debug_id)))
        }
    }
}

#[cfg(test)]
mod tests {
    use all::*;
    use all::tokenizer::*;
    use meta_rules::Text;
    use range::Range;
    use std::sync::Arc;

    #[test]
    fn expected_text() {
        let text = "23";
        let chars: Vec<char> = text.chars().collect();
        let mut tokens = vec![];
        let s = TokenizerState::new();
        let text = Text {
            debug_id: 0,
            allow_empty: true,
            property: None
        };
        let res = text.parse(&mut tokens, &s, &chars, 0);
        assert_eq!(res, Err((Range::new(0, 0), ParseError::ExpectedText(0))));
    }

    #[test]
    fn empty_string() {
        let text = "\"\"";
        let chars: Vec<char> = text.chars().collect();
        let mut tokens = vec![];
        let s = TokenizerState::new();
        let text = Text {
            debug_id: 0,
            allow_empty: false,
            property: None
        };
        let res = text.parse(&mut tokens, &s, &chars, 0);
        assert_eq!(res, Err((Range::new(0, 2),
            ParseError::EmptyTextNotAllowed(0))));
    }

    #[test]
    fn successful() {
        let text = "foo \"hello\"";
        let chars: Vec<char> = text.chars().collect();
        let mut tokens = vec![];
        let s = TokenizerState::new();
        let foo: Arc<String> = Arc::new("foo".into());
        let text = Text {
            debug_id: 0,
            allow_empty: true,
            property: Some(foo.clone())
        };
        let res = text.parse(&mut tokens, &s, &chars[4..], 4);
        assert_eq!(res, Ok((Range::new(4, 7), TokenizerState(1), None)));
        assert_eq!(tokens.len(), 1);
        assert_eq!(&tokens[0].1,
            &MetaData::String(foo.clone(), Arc::new("hello".into())));
    }
}
<commit_msg>Update to latest range library<commit_after>use read_token;
use range::Range;
use std::sync::Arc;

use super::{
    ParseResult,
};
use {
    DebugId,
    MetaData,
    ParseError,
};
use tokenizer::{ read_data, TokenizerState };

/// Stores information about text.
#[derive(Clone, Debug, PartialEq)]
pub struct Text {
    /// Whether to allow empty string.
    pub allow_empty: bool,
    /// Which property to set if text is read.
    pub property: Option<Arc<String>>,
    /// A debug id to track down the rule generating an error.
    pub debug_id: DebugId,
}

impl Text {
    /// Parses text.
    pub fn parse(
        &self,
        tokens: &mut Vec<(Range, MetaData)>,
        state: &TokenizerState,
        chars: &[char],
        offset: usize
    ) -> ParseResult<TokenizerState> {
        if let Some(range) = read_token::string(chars, offset) {
            if !self.allow_empty && range.length == 2 {
                Err((range, ParseError::EmptyTextNotAllowed(self.debug_id)))
            } else {
                match read_token::parse_string(
                    chars, offset, range.next_offset()) {
                    // Focus range to invalid string format.
                    Err(err) => {
                        let (r, err) = err.decouple();
                        Err((r, ParseError::ParseStringError(err, self.debug_id)))
                    }
                    Ok(text) => {
                        if let Some(ref property) = self.property {
                            Ok((range, read_data(
                                tokens,
                                MetaData::String(property.clone(), Arc::new(text)),
                                state,
                                range
                            ), None))
                        } else {
                            Ok((range, state.clone(), None))
                        }
                    }
                }
            }
        } else {
            Err((Range::new(offset, 0),
                ParseError::ExpectedText(self.debug_id)))
        }
    }
}

#[cfg(test)]
mod tests {
    use all::*;
    use all::tokenizer::*;
    use meta_rules::Text;
    use range::Range;
    use std::sync::Arc;

    #[test]
    fn expected_text() {
        let text = "23";
        let chars: Vec<char> = text.chars().collect();
        let mut tokens = vec![];
        let s = TokenizerState::new();
        let text = Text {
            debug_id: 0,
            allow_empty: true,
            property: None
        };
        let res = text.parse(&mut tokens, &s, &chars, 0);
        assert_eq!(res, Err((Range::new(0, 0), ParseError::ExpectedText(0))));
    }

    #[test]
    fn empty_string() {
        let text = "\"\"";
        let chars: Vec<char> = text.chars().collect();
        let mut tokens = vec![];
        let s = TokenizerState::new();
        let text = Text {
            debug_id: 0,
            allow_empty: false,
            property: None
        };
        let res = text.parse(&mut tokens, &s, &chars, 0);
        assert_eq!(res, Err((Range::new(0, 2),
            ParseError::EmptyTextNotAllowed(0))));
    }

    #[test]
    fn successful() {
        let text = "foo \"hello\"";
        let chars: Vec<char> = text.chars().collect();
        let mut tokens = vec![];
        let s = TokenizerState::new();
        let foo: Arc<String> = Arc::new("foo".into());
        let text = Text {
            debug_id: 0,
            allow_empty: true,
            property: Some(foo.clone())
        };
        let res = text.parse(&mut tokens, &s, &chars[4..], 4);
        assert_eq!(res, Ok((Range::new(4, 7), TokenizerState(1), None)));
        assert_eq!(tokens.len(), 1);
        assert_eq!(&tokens[0].1,
            &MetaData::String(foo.clone(), Arc::new("hello".into())));
    }
}
<|endoftext|>


<commit_before>use super::camera::*;
use super::event_manager::*;
use GameContext;
use glium::glutin::{CursorState, ElementState, Event, MouseButton, VirtualKeyCode};
use base::math::*;
use base::world::*;
use std::rc::Rc;
use super::world_manager::*;

const GRAVITY: f32 = 9.81;
/// Represents a `Player` in the world, the `Player` can move up, right, down
/// left, right with w, a, s, d, jump with space and speed with shift
pub struct Player {
    cam: Camera,
    context: Rc<GameContext>,
    world_manager: WorldManager,
    acceleration: Vector3f,
    velocity: Vector3f,
    timer_jump: f32,
    timer_vel: f32,
    mouselock: bool,
    shift_speed: f32,
}

impl Player {
    pub fn new(context: Rc<GameContext>, world_manager: WorldManager) -> Self {
        Player {
            cam: Camera {
                position: Point3::new(15.0, 10.0, 50.0),
                phi: -0.27,
                theta: 2.6,
            },
            world_manager: world_manager,
            context: context,
            timer_jump: 1.0,
            timer_vel: 1.0,
            acceleration: Vector3::new(0.0, 0.0, 0.0),
            velocity: Vector3::new(0.0, 0.0, 0.0),
            mouselock: false,
            shift_speed: 1.0,
        }
    }
    /// Gets the actual `Height` of the `HexPillar`
    pub fn get_ground_height(&self) -> Option<f32> {
        let world = self.world_manager.get_world();
        let real_pos = Point2f::new(self.cam.position.x, self.cam.position.y);
        let pillar_index = PillarIndex(AxialPoint::from_real(real_pos));

        world.pillar_at(pillar_index).map(|pillar| pillar.sections()[0].top.to_real())
    }
    /// Getter method for the `Camera`
    pub fn get_camera(&self) -> Camera {
        self.cam
    }
    /// Updates the `Player` after every iteration
    pub fn update(&mut self, delta: f32) {
        let mut height = 0.0;
        let mut test = self.get_ground_height();
        if test.is_some() {
            height = test.unwrap();
            height = height + 1.75;
        }
        // Moves the Player forward or backward with the acceleration and delta
        // (1.0 - (-((self.timer_vel * delta) / (1.0))).exp()) -> this is a formula
        // that calculates a
        // number from 0 to 1. So the player has a maximum velocity
        if self.acceleration.x != 0.0 {
            self.cam.move_forward(self.acceleration.x * delta * delta * self.shift_speed *
                                  (1.0 - (-((self.timer_vel * delta) / (1.0))).exp()));
            if self.timer_vel != 100.0 {
                self.timer_vel += 1.0;
            }
            if self.acceleration.x == 0.0 {
                self.timer_vel = 1.0;
            }
        }
        // Moves the Player left an right with the acceleration and delta
        if self.acceleration.y != 0.0 {
            self.cam
                .move_right(self.acceleration.y * delta * delta *
                            (1.0 - (-((self.timer_vel * delta) / (1.0))).exp()));
            if self.timer_vel != 100.0 {
                self.timer_vel += 1.0;
            }
            if self.acceleration.y == 0.0 {
                self.timer_vel = 1.0;
            }
        }
        // Let the player jump with the given start-velocity
        if self.velocity.z != 0.0 {
            self.cam.move_up((self.velocity.z * self.timer_jump * delta -
                              self.timer_jump * self.timer_jump * delta * delta * GRAVITY) /
                             16.0);
            self.timer_jump += 1.0;
            if self.cam.position.z < height {
                self.velocity.z = 0.0;
                self.timer_jump = 1.0;
            }
        }
        // Places the `Player` on the actual `HexPillar` if the position of the
        // `Player` is less than
        // the `HexPillar`
        if self.velocity.z == 0.0 && self.cam.position.z < height {
            self.cam.position.z = height;
        }
        // Checks if the `Player` is higher than the actual `Player` on wich he is
        // standing and let
        // him fall on that
        if self.cam.position.z > height && self.velocity.z == 0.0 {
            self.cam
                .move_down((self.timer_jump * self.timer_jump * delta * delta * GRAVITY) / 16.0);
            self.timer_jump += 1.0;
            if self.cam.position.z < height {
                self.timer_jump = 1.0;
            }
        }
    }
}
/// `EventHandler` for the `Player`
impl EventHandler for Player {
    fn handle_event(&mut self, e: &Event) -> EventResponse {
        match *e {
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::W)) => {
                self.acceleration.x = 500.5;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::W)) => {
                self.acceleration.x = 0.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::S)) => {
                self.acceleration.x = -400.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::S)) => {
                self.acceleration.x = 0.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::A)) => {
                self.acceleration.y = -400.5;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::A)) => {
                self.acceleration.y = 0.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::D)) => {
                self.acceleration.y = 400.5;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::D)) => {
                self.acceleration.y = 0.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::Space)) => {
                self.velocity.z = 6.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::Space)) => {
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::LControl)) => {
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::LControl)) => {
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::LShift)) => {
                self.shift_speed = 2.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::LShift)) => {
                self.shift_speed = 1.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::F)) => {
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::F)) => {
                EventResponse::Continue
            }
            Event::MouseInput(ElementState::Pressed, MouseButton::Left) => {
                if !self.mouselock {
                    self.mouselock = true;
                    if let Some(window) = self.context.get_facade().get_window() {
                        window.set_cursor_state(CursorState::Hide)
                            .expect("failed to set cursor state");
                    } else {
                        warn!("Failed to obtain window from facade");
                    }
                } else if self.mouselock {
                    self.mouselock = false;

                    if let Some(window) = self.context.get_facade().get_window() {
                        window.set_cursor_state(CursorState::Normal)
                            .expect("failed to set cursor state");
                    } else {
                        warn!("Failed to obtain window from facade");
                    }
                }

                EventResponse::Continue
            }

            Event::MouseMoved(x, y) => {
                if self.mouselock {
                    if let Some(window) = self.context.get_facade().get_window() {
                        // Possibility of mouse being outside of window without it resetting to the
                        // middle?
                        if let Some(middle) = window.get_inner_size_pixels() {
                            let middle_x = (middle.0 as i32) / 2;
                            let middle_y = (middle.1 as i32) / 2;
                            let x_diff = x - middle_x;
                            let y_diff = y - middle_y;
                            self.cam.change_dir(y_diff as f32 / 300.0, -x_diff as f32 / 300.0);
                            window.set_cursor_position(middle_x as i32, middle_y as i32)
                                .expect("setting cursor position failed");
                        }
                    }
                }
                EventResponse::Continue
            }

            _ => EventResponse::NotHandled,
        }
    }
}
<commit_msg>Improvement of get_ground_height<commit_after>use super::camera::*;
use super::event_manager::*;
use GameContext;
use glium::glutin::{CursorState, ElementState, Event, MouseButton, VirtualKeyCode};
use base::math::*;
use base::world::*;
use std::rc::Rc;
use super::world_manager::*;

const GRAVITY: f32 = 9.81;
/// Represents a `Player` in the world, the `Player` can move up, right, down
/// left, right with w, a, s, d, jump with space and speed with shift
pub struct Player {
    cam: Camera,
    context: Rc<GameContext>,
    world_manager: WorldManager,
    acceleration: Vector3f,
    velocity: Vector3f,
    timer_jump: f32,
    timer_vel: f32,
    mouselock: bool,
    shift_speed: f32,
}

impl Player {
    pub fn new(context: Rc<GameContext>, world_manager: WorldManager) -> Self {
        Player {
            cam: Camera {
                position: Point3::new(15.0, 10.0, 50.0),
                phi: -0.27,
                theta: 2.6,
            },
            world_manager: world_manager,
            context: context,
            timer_jump: 1.0,
            timer_vel: 1.0,
            acceleration: Vector3::new(0.0, 0.0, 0.0),
            velocity: Vector3::new(0.0, 0.0, 0.0),
            mouselock: false,
            shift_speed: 1.0,
        }
    }
    /// Gets the actual `Height` of the `HexPillar`
    pub fn get_ground_height(&self) -> Option<f32> {
        let world = self.world_manager.get_world();
        let real_pos = Point2f::new(self.cam.position.x, self.cam.position.y);
        let pillar_index = PillarIndex(AxialPoint::from_real(real_pos));

        world.pillar_at(pillar_index).map(|pillar| pillar.sections()[0].top.to_real())
    }
    /// Getter method for the `Camera`
    pub fn get_camera(&self) -> Camera {
        self.cam
    }
    /// Updates the `Player` after every iteration
    pub fn update(&mut self, delta: f32) {
        let height = self.get_ground_height().unwrap_or(0.0) + 1.70;

        // Moves the Player forward or backward with the acceleration and delta
        // (1.0 - (-((self.timer_vel * delta) / (1.0))).exp()) -> this is a formula
        // that calculates a
        // number from 0 to 1. So the player has a maximum velocity
        if self.acceleration.x != 0.0 {
            self.cam.move_forward(self.acceleration.x * delta * delta * self.shift_speed *
                                  (1.0 - (-((self.timer_vel * delta) / (1.0))).exp()));
            if self.timer_vel != 100.0 {
                self.timer_vel += 1.0;
            }
            if self.acceleration.x == 0.0 {
                self.timer_vel = 1.0;
            }
        }
        // Moves the Player left an right with the acceleration and delta
        if self.acceleration.y != 0.0 {
            self.cam
                .move_right(self.acceleration.y * delta * delta *
                            (1.0 - (-((self.timer_vel * delta) / (1.0))).exp()));
            if self.timer_vel != 100.0 {
                self.timer_vel += 1.0;
            }
            if self.acceleration.y == 0.0 {
                self.timer_vel = 1.0;
            }
        }
        // Let the player jump with the given start-velocity
        if self.velocity.z != 0.0 {
            self.cam.move_up((self.velocity.z * self.timer_jump * delta -
                              self.timer_jump * self.timer_jump * delta * delta * GRAVITY) /
                             16.0);
            self.timer_jump += 1.0;
            if self.cam.position.z < height {
                self.velocity.z = 0.0;
                self.timer_jump = 1.0;
            }
        }
        // Places the `Player` on the actual `HexPillar` if the position of the
        // `Player` is less than
        // the `HexPillar`
        if self.velocity.z == 0.0 && self.cam.position.z < height {
            self.cam.position.z = height;
        }
        // Checks if the `Player` is higher than the actual `Player` on wich he is
        // standing and let
        // him fall on that
        if self.cam.position.z > height && self.velocity.z == 0.0 {
            self.cam
                .move_down((self.timer_jump * self.timer_jump * delta * delta * GRAVITY) / 16.0);
            self.timer_jump += 1.0;
            if self.cam.position.z < height {
                self.timer_jump = 1.0;
            }
        }
    }
}
/// `EventHandler` for the `Player`
impl EventHandler for Player {
    fn handle_event(&mut self, e: &Event) -> EventResponse {
        match *e {
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::W)) => {
                self.acceleration.x = 500.5;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::W)) => {
                self.acceleration.x = 0.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::S)) => {
                self.acceleration.x = -400.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::S)) => {
                self.acceleration.x = 0.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::A)) => {
                self.acceleration.y = -400.5;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::A)) => {
                self.acceleration.y = 0.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::D)) => {
                self.acceleration.y = 400.5;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::D)) => {
                self.acceleration.y = 0.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::Space)) => {
                self.velocity.z = 6.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::Space)) => {
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::LControl)) => {
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::LControl)) => {
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::LShift)) => {
                self.shift_speed = 2.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::LShift)) => {
                self.shift_speed = 1.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::F)) => {
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::F)) => {
                EventResponse::Continue
            }
            Event::MouseInput(ElementState::Pressed, MouseButton::Left) => {
                if !self.mouselock {
                    self.mouselock = true;
                    if let Some(window) = self.context.get_facade().get_window() {
                        window.set_cursor_state(CursorState::Hide)
                            .expect("failed to set cursor state");
                    } else {
                        warn!("Failed to obtain window from facade");
                    }
                } else if self.mouselock {
                    self.mouselock = false;

                    if let Some(window) = self.context.get_facade().get_window() {
                        window.set_cursor_state(CursorState::Normal)
                            .expect("failed to set cursor state");
                    } else {
                        warn!("Failed to obtain window from facade");
                    }
                }

                EventResponse::Continue
            }

            Event::MouseMoved(x, y) => {
                if self.mouselock {
                    if let Some(window) = self.context.get_facade().get_window() {
                        // Possibility of mouse being outside of window without it resetting to the
                        // middle?
                        if let Some(middle) = window.get_inner_size_pixels() {
                            let middle_x = (middle.0 as i32) / 2;
                            let middle_y = (middle.1 as i32) / 2;
                            let x_diff = x - middle_x;
                            let y_diff = y - middle_y;
                            self.cam.change_dir(y_diff as f32 / 300.0, -x_diff as f32 / 300.0);
                            window.set_cursor_position(middle_x as i32, middle_y as i32)
                                .expect("setting cursor position failed");
                        }
                    }
                }
                EventResponse::Continue
            }

            _ => EventResponse::NotHandled,
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>set the correct Listener type<commit_after><|endoftext|>


<commit_before>use ::{Player, RED, BLUE};

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Direction {
    Forward,
    Back,
    Left,
    Right,
    ForwardLeft,
    ForwardRight,
    BackLeft,
    BackRight,
}

impl Direction {
    pub fn apply(&self, player: Player, from: (usize, usize)) -> (usize, usize) {
        let (x, y) = from;
        let (x, y) = (x as i32, y as i32);

        let (dx, dy) = match player {
            RED => { (1, 1) },
            BLUE => { (1, -1) },
        };

        let (to_x, to_y) = match *self {
            Direction::Forward => (x, y + dy),
            Direction::Back => (x, y - dy),
            Direction::Left => (x - dx, y),
            Direction::Right => (x + dx, y),
            Direction::ForwardLeft => (x - dx, y + dy),
            Direction::ForwardRight => (x + dx, y + dy),
            Direction::BackLeft => (x - dx, y - dy),
            Direction::BackRight => (x + dx, y - dy),
        };

        (to_x as usize, to_y as usize)
    }
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Move {
    pub from: (usize, usize),
    pub direction: Direction,
}

impl Move {
    pub fn new(x: usize, y: usize, direction: Direction) -> Move {
        Move {
            from: (x, y),
            direction: direction,
        }
    }

    pub fn apply(&self, player: Player) -> (usize, usize) {
        self.direction.apply(player, self.from)
    }
}

pub trait MoveCondition {
    fn is_valid (&self, movement: Move) -> bool;
}

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

impl MoveCondition for OnlyForwardMove {
    fn is_valid (&self, movement: Move) -> bool {
        movement.direction == Direction::Forward
    }
}
<commit_msg>Added RustcEncodable/Decodable for Move<commit_after>use ::{Player, RED, BLUE};

#[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
pub enum Direction {
    Forward,
    Back,
    Left,
    Right,
    ForwardLeft,
    ForwardRight,
    BackLeft,
    BackRight,
}

impl Direction {
    pub fn apply(&self, player: Player, from: (usize, usize)) -> (usize, usize) {
        let (x, y) = from;
        let (x, y) = (x as i32, y as i32);

        let (dx, dy) = match player {
            RED => { (1, 1) },
            BLUE => { (1, -1) },
        };

        let (to_x, to_y) = match *self {
            Direction::Forward => (x, y + dy),
            Direction::Back => (x, y - dy),
            Direction::Left => (x - dx, y),
            Direction::Right => (x + dx, y),
            Direction::ForwardLeft => (x - dx, y + dy),
            Direction::ForwardRight => (x + dx, y + dy),
            Direction::BackLeft => (x - dx, y - dy),
            Direction::BackRight => (x + dx, y - dy),
        };

        (to_x as usize, to_y as usize)
    }
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
pub struct Move {
    pub from: (usize, usize),
    pub direction: Direction,
}

impl Move {
    pub fn new(x: usize, y: usize, direction: Direction) -> Move {
        Move {
            from: (x, y),
            direction: direction,
        }
    }

    pub fn apply(&self, player: Player) -> (usize, usize) {
        self.direction.apply(player, self.from)
    }
}

pub trait MoveCondition {
    fn is_valid (&self, movement: Move) -> bool;
}

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

impl MoveCondition for OnlyForwardMove {
    fn is_valid (&self, movement: Move) -> bool {
        movement.direction == Direction::Forward
    }
}
<|endoftext|>


<commit_before>//Input: two words
//Output: True if the two words song alike
pub fn soundex(word1: &str, word2: &str) -> bool {
  let sword1 = SoundexWord::new(word1);
  let sword2 = SoundexWord::new(word2);
  sword1.word == sword2.word
}

pub struct SoundexWord {
  word: Vec<char>
}

impl SoundexWord {

  pub fn new(word: &str) -> SoundexWord {
    let mut chars: Vec<char> = Vec::new();

    for c in word.chars() {
      chars.push(c);
    }
    chars = soundex_encoding(chars);
    let s = SoundexWord { word: chars };
    s
  }

  pub fn sounds_like(&self, second_word: SoundexWord) -> bool {
    self.word == second_word.word
  }

  pub fn sounds_like_str(&self, second_word: &str) -> bool {
    let sec_word = SoundexWord::new(second_word);
    self.word == sec_word.word
  }
}

fn soundex_encoding(chars: Vec<char>) -> Vec<char> {
  fix_length(strip_similar_chars(chars))
}

fn strip_similar_chars(chars: Vec<char>) -> Vec<char> {
  let mut enc_chars = Vec::new();
  enc_chars.push(chars[0]);
  for i in range(1, chars.len()) {
    enc_chars.push(get_char_digit(chars[i]));
  }
  let mut chars_no_hw = Vec::new();
  let mut chars_no_vowels = Vec::new();
  for c in enc_chars.move_iter() {
    if c != '9' {
      chars_no_hw.push(c);
    }
  }
  chars_no_hw.dedup();
  for c in chars_no_hw.move_iter() {
    if c != '0' {
      chars_no_vowels.push(c);
    }
  }
  chars_no_vowels
}

fn fix_length(mut chars: Vec<char>) -> Vec<char> {
  match chars.len() {
    4 => chars,
    0..3 => add_more_zeros(chars),
    _ => { chars.truncate(4); chars} //truncate doesn't return self?
  }
}

fn add_more_zeros(chars: Vec<char>) -> Vec<char> {
  Vec::from_fn(4, |idx| {
    if idx < chars.len() {
      chars[idx]
    }
    else {
      '0'
    }
  })
}

fn get_char_digit(c: char) -> char {
  match c {
    'b' | 'f' | 'p' | 'v' => '1',
    'c' | 'g' | 'j' | 'k' | 'q' | 's' | 'x' | 'z' => '2',
    'd' | 't' => '3',
    'l' => '4',
    'm' | 'n' => '5',
    'r' => '6',
    'h' | 'w' => '9', //0 and 9 are removed later, this is just to separate vowels from h and w
    _ => '0' //Vowels
  }
}<commit_msg>Resolve breaking change, .. to ...<commit_after>//Input: two words
//Output: True if the two words song alike
pub fn soundex(word1: &str, word2: &str) -> bool {
  let sword1 = SoundexWord::new(word1);
  let sword2 = SoundexWord::new(word2);
  sword1.word == sword2.word
}

pub struct SoundexWord {
  word: Vec<char>
}

impl SoundexWord {

  pub fn new(word: &str) -> SoundexWord {
    let mut chars: Vec<char> = Vec::new();

    for c in word.chars() {
      chars.push(c);
    }
    chars = soundex_encoding(chars);
    let s = SoundexWord { word: chars };
    s
  }

  pub fn sounds_like(&self, second_word: SoundexWord) -> bool {
    self.word == second_word.word
  }

  pub fn sounds_like_str(&self, second_word: &str) -> bool {
    let sec_word = SoundexWord::new(second_word);
    self.word == sec_word.word
  }
}

fn soundex_encoding(chars: Vec<char>) -> Vec<char> {
  fix_length(strip_similar_chars(chars))
}

fn strip_similar_chars(chars: Vec<char>) -> Vec<char> {
  let mut enc_chars = Vec::new();
  enc_chars.push(chars[0]);
  for i in range(1, chars.len()) {
    enc_chars.push(get_char_digit(chars[i]));
  }
  let mut chars_no_hw = Vec::new();
  let mut chars_no_vowels = Vec::new();
  for c in enc_chars.move_iter() {
    if c != '9' {
      chars_no_hw.push(c);
    }
  }
  chars_no_hw.dedup();
  for c in chars_no_hw.move_iter() {
    if c != '0' {
      chars_no_vowels.push(c);
    }
  }
  chars_no_vowels
}

fn fix_length(mut chars: Vec<char>) -> Vec<char> {
  match chars.len() {
    4 => chars,
    0...3 => add_more_zeros(chars),
    _ => { chars.truncate(4); chars} //truncate doesn't return self?
  }
}

fn add_more_zeros(chars: Vec<char>) -> Vec<char> {
  Vec::from_fn(4, |idx| {
    if idx < chars.len() {
      chars[idx]
    }
    else {
      '0'
    }
  })
}

fn get_char_digit(c: char) -> char {
  match c {
    'b' | 'f' | 'p' | 'v' => '1',
    'c' | 'g' | 'j' | 'k' | 'q' | 's' | 'x' | 'z' => '2',
    'd' | 't' => '3',
    'l' => '4',
    'm' | 'n' => '5',
    'r' => '6',
    'h' | 'w' => '9', //0 and 9 are removed later, this is just to separate vowels from h and w
    _ => '0' //Vowels
  }
}<|endoftext|>


<commit_before>use chrono::prelude::*;
use regex::Regex;
use std::path::PathBuf;
use yaml_rust::Yaml;

static DateRx: &'static str = r"(?x)
    -?
    (?P<year>\d{4})               # 4-digit year
    -
    (?P<month>\d{1,2}             # 1- or 2-digit month
        | jan | feb | mar | apr
        | may | jun | jul | aug   # or 3-letter named
        | sep | oct | nov | dec
    )
    -
    (?P<day>\d{1,2})              # 1- or 2-digit day
    -?
";

pub fn from_path(path: &PathBuf) -> Option<DateTime<UTC>> {
    lazy_static! {
        static ref DATE: Regex = Regex::new(DateRx).unwrap();
    }

    match DATE.find_iter(
        &String::from(path.to_str().unwrap()).to_lowercase()
    ).last() {
        None => None,
        Some(date) => match DATE.captures(date.as_str()) {
            None => None,
            Some(caps) => Some(UTC.ymd(
                // The unwraps are safe given the regex matches digits.
                (&caps["year"]).parse::<i32>().unwrap(),
                match &caps["month"] {
                    "jan" =>  1, "feb" =>  2, "mar" =>  3, "apr" =>  4,
                    "may" =>  5, "jun" =>  6, "jul" =>  7, "aug" =>  8,
                    "sep" =>  9, "oct" => 10, "nov" => 11, "dec" => 12,
                    m @ _ => m.parse::<u32>().unwrap()
                },
                (&caps["day"]).parse::<u32>().unwrap()
            ).and_hms(0, 0, 0))
        }
    }
}

pub fn strip(path: &PathBuf) -> String {
    lazy_static! {
        static ref DATE: Regex = Regex::new(DateRx).unwrap();
        static ref SLASHED: Regex = Regex::new(r"-*/-*").unwrap();
        static ref DASHED: Regex = Regex::new(r"(^-|-$|-{2,}|^/)").unwrap();
    }

    let lowered = String::from(path.to_str().unwrap()).to_lowercase();

    String::from(DASHED.replace_all(
        &String::from(SLASHED.replace_all(
            &String::from(DATE.replace_all(
                &lowered,
                "-"
            )),
            "/"
        )),
        ""
    ))
}

#[cfg(test)]
mod test {
    use chrono::prelude::*;
    use std::path::PathBuf;
    use super::*;

    #[test]
    fn with_alpha_month() {
        assert_eq!(from_path(
            &PathBuf::from("2017-feb-18")),
            Some(UTC.ymd(2017, 02, 18).and_hms(0, 0, 0))
        );
    }

    #[test]
    fn with_upper_month() {
        assert_eq!(from_path(
            &PathBuf::from("2017-FEB-18")),
            Some(UTC.ymd(2017, 02, 18).and_hms(0, 0, 0))
        );
    }

    #[test]
    fn with_mixed_month() {
        assert_eq!(from_path(
            &PathBuf::from("2017-Feb-18")),
            Some(UTC.ymd(2017, 02, 18).and_hms(0, 0, 0))
        );
    }

    #[test]
    fn with_number_month() {
        assert_eq!(from_path(
            &PathBuf::from("2017-02-18")),
            Some(UTC.ymd(2017, 02, 18).and_hms(0, 0, 0))
        );
    }

    #[test]
    fn as_infix() {
        assert_eq!(from_path(
            &PathBuf::from("posts/2017-feb-18-hello-world.md")),
            Some(UTC.ymd(2017, 02, 18).and_hms(0, 0, 0))
        );
    }

    #[test]
    fn with_prefix() {
        assert_eq!(from_path(
            &PathBuf::from("posts/2017-feb-18")),
            Some(UTC.ymd(2017, 02, 18).and_hms(0, 0, 0))
        );
    }

    #[test]
    fn with_suffix() {
        assert_eq!(from_path(
            &PathBuf::from("2017-feb-18-hello-world.pre.md")),
            Some(UTC.ymd(2017, 02, 18).and_hms(0, 0, 0))
        );
    }

    #[test]
    fn with_two_dates() {
        assert_eq!(from_path(
            &PathBuf::from("2017-feb-18/2016-jul-03-hello-world.md")),
            Some(UTC.ymd(2016, 07, 03).and_hms(0, 0, 0))
        );
    }

    #[test]
    fn with_no_date() {
        assert_eq!(from_path(
            &PathBuf::from("hello-world.md")),
            None
        );
    }

    #[test]
    fn strip_infix() {
        assert_eq!(strip(
            &PathBuf::from("posts/2017-feb-18-hello-world.md")),
            String::from("posts/hello-world.md")
        );
    }

    #[test]
    fn strip_suffix() {
        assert_eq!(strip(
            &PathBuf::from("posts/2017-feb-18")),
            String::from("posts/")
        );
    }

    #[test]
    fn strip_front_slash() {
        assert_eq!(strip(
            &PathBuf::from("/2017-feb-18-hello")),
            String::from("hello")
        );
    }

    #[test]
    fn strip_prefix() {
        assert_eq!(strip(
            &PathBuf::from("2017-feb-18-hello-world.pre.md")),
            String::from("hello-world.pre.md")
        );
    }

    #[test]
    fn strip_two_dates() {
        assert_eq!(strip(
            &PathBuf::from("2017-feb-18-and-2016-jul-03-hello-world.md")),
            String::from("and-hello-world.md")
        );
    }

    #[test]
    fn strip_two_dates_subpath() {
        assert_eq!(strip(
            &PathBuf::from("2017-feb-18-hello/2016-jul-03-world.md")),
            String::from("hello/world.md")
        );
    }

    #[test]
    fn strip_two_dates_subpath_bare() {
        assert_eq!(strip(
            &PathBuf::from("2017-feb-18/2016-jul-03-hello-world.md")),
            String::from("hello-world.md")
        );
    }

    #[test]
    fn strip_no_date() {
        assert_eq!(strip(
            &PathBuf::from("hello-world.md")),
            String::from("hello-world.md")
        );
    }

    #[test]
    fn strip_not_a_date() {
        assert_eq!(strip(
            &PathBuf::from("not-2017-and-18")),
            String::from("not-2017-and-18")
        );
    }

    #[test]
    fn strip_just_date() {
        assert_eq!(strip(
            &PathBuf::from("2017-feb-18")),
            String::from("")
        );
    }
}
<commit_msg>Dates can be slash-separated now<commit_after>use chrono::prelude::*;
use regex::Regex;
use std::path::PathBuf;
use yaml_rust::Yaml;

static DateRx: &'static str = r"(?x)
    -?
    (?P<year>\d{4})               # 4-digit year
    [-/]
    (?P<month>\d{1,2}             # 1- or 2-digit month
        | jan | feb | mar | apr
        | may | jun | jul | aug   # or 3-letter named
        | sep | oct | nov | dec
    )
    [-/]
    (?P<day>\d{1,2})              # 1- or 2-digit day
    -?
";

pub fn from_path(path: &PathBuf) -> Option<DateTime<UTC>> {
    lazy_static! {
        static ref DATE: Regex = Regex::new(DateRx).unwrap();
    }

    match DATE.find_iter(
        &String::from(path.to_str().unwrap()).to_lowercase()
    ).last() {
        None => None,
        Some(date) => match DATE.captures(date.as_str()) {
            None => None,
            Some(caps) => Some(UTC.ymd(
                // The unwraps are safe given the regex matches digits.
                (&caps["year"]).parse::<i32>().unwrap(),
                match &caps["month"] {
                    "jan" =>  1, "feb" =>  2, "mar" =>  3, "apr" =>  4,
                    "may" =>  5, "jun" =>  6, "jul" =>  7, "aug" =>  8,
                    "sep" =>  9, "oct" => 10, "nov" => 11, "dec" => 12,
                    m @ _ => m.parse::<u32>().unwrap()
                },
                (&caps["day"]).parse::<u32>().unwrap()
            ).and_hms(0, 0, 0))
        }
    }
}

pub fn strip(path: &PathBuf) -> String {
    lazy_static! {
        static ref DATE: Regex = Regex::new(DateRx).unwrap();
        static ref SLASHED: Regex = Regex::new(r"-*/-*").unwrap();
        static ref DASHED: Regex = Regex::new(r"(^-|-$|-{2,}|^/)").unwrap();
    }

    let lowered = String::from(path.to_str().unwrap()).to_lowercase();

    String::from(DASHED.replace_all(
        &String::from(SLASHED.replace_all(
            &String::from(DATE.replace_all(
                &lowered,
                "-"
            )),
            "/"
        )),
        ""
    ))
}

#[cfg(test)]
mod test {
    use chrono::prelude::*;
    use std::path::PathBuf;
    use super::*;

    #[test]
    fn with_alpha_month() {
        assert_eq!(from_path(
            &PathBuf::from("2017-feb-18")),
            Some(UTC.ymd(2017, 02, 18).and_hms(0, 0, 0))
        );
    }

    #[test]
    fn with_upper_month() {
        assert_eq!(from_path(
            &PathBuf::from("2017-FEB-18")),
            Some(UTC.ymd(2017, 02, 18).and_hms(0, 0, 0))
        );
    }

    #[test]
    fn with_mixed_month() {
        assert_eq!(from_path(
            &PathBuf::from("2017-Feb-18")),
            Some(UTC.ymd(2017, 02, 18).and_hms(0, 0, 0))
        );
    }

    #[test]
    fn with_number_month() {
        assert_eq!(from_path(
            &PathBuf::from("2017-02-18")),
            Some(UTC.ymd(2017, 02, 18).and_hms(0, 0, 0))
        );
    }

    #[test]
    fn with_slashes() {
        assert_eq!(from_path(
            &PathBuf::from("2017/02/18")),
            Some(UTC.ymd(2017, 02, 18).and_hms(0, 0, 0))
        );
    }

    #[test]
    fn as_infix() {
        assert_eq!(from_path(
            &PathBuf::from("posts/2017-feb-18-hello-world.md")),
            Some(UTC.ymd(2017, 02, 18).and_hms(0, 0, 0))
        );
    }

    #[test]
    fn with_prefix() {
        assert_eq!(from_path(
            &PathBuf::from("posts/2017-feb-18")),
            Some(UTC.ymd(2017, 02, 18).and_hms(0, 0, 0))
        );
    }

    #[test]
    fn with_suffix() {
        assert_eq!(from_path(
            &PathBuf::from("2017-feb-18-hello-world.pre.md")),
            Some(UTC.ymd(2017, 02, 18).and_hms(0, 0, 0))
        );
    }

    #[test]
    fn with_two_dates() {
        assert_eq!(from_path(
            &PathBuf::from("2017-feb-18/2016-jul-03-hello-world.md")),
            Some(UTC.ymd(2016, 07, 03).and_hms(0, 0, 0))
        );
    }

    #[test]
    fn with_no_date() {
        assert_eq!(from_path(
            &PathBuf::from("hello-world.md")),
            None
        );
    }

    #[test]
    fn strip_infix() {
        assert_eq!(strip(
            &PathBuf::from("posts/2017-feb-18-hello-world.md")),
            String::from("posts/hello-world.md")
        );
    }

    #[test]
    fn strip_suffix() {
        assert_eq!(strip(
            &PathBuf::from("posts/2017-feb-18")),
            String::from("posts/")
        );
    }

    #[test]
    fn strip_front_slash() {
        assert_eq!(strip(
            &PathBuf::from("/2017-feb-18-hello")),
            String::from("hello")
        );
    }

    #[test]
    fn strip_prefix() {
        assert_eq!(strip(
            &PathBuf::from("2017-feb-18-hello-world.pre.md")),
            String::from("hello-world.pre.md")
        );
    }

    #[test]
    fn strip_two_dates() {
        assert_eq!(strip(
            &PathBuf::from("2017-feb-18-and-2016-jul-03-hello-world.md")),
            String::from("and-hello-world.md")
        );
    }

    #[test]
    fn strip_two_dates_subpath() {
        assert_eq!(strip(
            &PathBuf::from("2017-feb-18-hello/2016-jul-03-world.md")),
            String::from("hello/world.md")
        );
    }

    #[test]
    fn strip_two_dates_subpath_bare() {
        assert_eq!(strip(
            &PathBuf::from("2017-feb-18/2016-jul-03-hello-world.md")),
            String::from("hello-world.md")
        );
    }

    #[test]
    fn strip_no_date() {
        assert_eq!(strip(
            &PathBuf::from("hello-world.md")),
            String::from("hello-world.md")
        );
    }

    #[test]
    fn strip_not_a_date() {
        assert_eq!(strip(
            &PathBuf::from("not-2017-and-18")),
            String::from("not-2017-and-18")
        );
    }

    #[test]
    fn strip_just_date() {
        assert_eq!(strip(
            &PathBuf::from("2017-feb-18")),
            String::from("")
        );
    }
}
<|endoftext|>


<commit_before>use config::Config;

pub fn check(config: &Config) -> Vec<String> {
    let mut warnings = vec!();

    if config.gh_token.is_none() {
        warnings.push("The GH_TOKEN environment variable is not configured".into());
    }

    if let Err(ref err) = config.remote {
        warnings.push(format!("Could not determine the origin remote url: {:?}", err));
        warnings.push("semantic-rs can't push changes or create a release on GitHub".into());
    }

    warnings
}
<commit_msg>feat: Check if CARGO_TOKEN is defined or not<commit_after>use config::Config;

pub fn check(config: &Config) -> Vec<String> {
    let mut warnings = vec!();

    if config.gh_token.is_none() {
        warnings.push("The GH_TOKEN environment variable is not configured".into());
    }

    if config.cargo_token.is_none() {
        warnings.push("The CARGO_TOKEN environment variable is not configured. Cannot create release on crates.io".into());
    }

    if let Err(ref err) = config.remote {
        warnings.push(format!("Could not determine the origin remote url: {:?}", err));
        warnings.push("semantic-rs can't push changes or create a release on GitHub".into());
    }

    warnings
}
<|endoftext|>


<commit_before>//! Endpoints for server administration.
<commit_msg>Implement server administration endpoints.<commit_after>//! Endpoints for server administration.

/// [GET /_matrix/client/r0/admin/whois/{userId}](https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-admin-whois-userid)
pub mod get_user_info {
    use ruma_identifiers::UserId;

    use std::collections::HashMap;

    /// Information about a connection in a user session.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct ConnectionInfo {
        /// Most recently seen IP address of the session.
        pub ip: String,
        /// Unix timestamp that the session was last active.
        pub last_seen: u64,
        /// User agent string last seen in the session.
        pub user_agent: String,
    }

    /// Information about a user's device.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct DeviceInfo {
        /// A list of user sessions on this device.
        pub sessions: Vec<SessionInfo>,
    }

    /// Details about this API endpoint.
    #[derive(Clone, Copy, Debug)]
    pub struct Endpoint;

    /// This API endpoint's path parameters.
    #[derive(Clone, Debug)]
    pub struct PathParams {
        /// The user to look up.
        pub user_id: UserId,
    }

    /// This API endpoint's response.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct Response {
        /// The Matrix user ID of the user.
        pub user_id: UserId,
        /// A map of the user's device identifiers to information about that device.
        pub devices: HashMap<String, DeviceInfo>,
    }

    /// Information about a user session.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct SessionInfo {
        /// A list of connections in this session.
        pub connections: Vec<ConnectionInfo>,
    }

    impl ::Endpoint for Endpoint {
        type BodyParams = ();
        type PathParams = PathParams;
        type QueryParams = ();
        type Response = Response;

        fn method() -> ::Method {
            ::Method::Get
        }

        fn request_path(params: Self::PathParams) -> String {
            format!(
                "/_matrix/client/r0/admin/whois/{}",
                params.user_id
            )
        }

        fn router_path() -> String {
            "/_matrix/client/r0/admin/whois/:user_id".to_string()
        }
    }
}
<|endoftext|>


<commit_before>//! redis-rs is a rust implementation of a Redis client library.  It exposes
//! a general purpose interface to Redis and also provides specific helpers for
//! commonly used functionality.
//!
//! ```rust,no_run
//! extern crate redis;
//!
//! fn main() {
//!     let client = redis::Client::open("redis://127.0.0.1/").unwrap();
//!     let con = client.get_connection().unwrap();
//!     redis::cmd("SET").arg("my_key").arg(42i).execute(&con);
//!     assert_eq!(redis::cmd("GET").arg("my_key").query(&con), Ok(42i));
//! }
//! ```
//!
//! Because redis inherently is mostly type-less and the protocol is not
//! exactly friendly to developers, this library provides flexible support
//! for casting values to the intended results.  This is driven through the
//! `FromRedisValue` trait.
//!
//! The `query` method of a `Cmd` can convert the value to what you expect
//! the function to return.  This is quite flexible, allows vectors, tuples,
//! hashsets and maps as well as optional values:
//!
//! ```rust,no_run
//! # use std::collections::{HashMap, HashSet};
//! # let client = redis::Client::open("redis://127.0.0.1/").unwrap();
//! # let con = client.get_connection().unwrap();
//! let count : i32 = redis::cmd("GET").arg("my_counter").query(&con).unwrap();
//! let count = redis::cmd("GET").arg("my_counter").query(&con).unwrap_or(0i32);
//! let k : Option<String> = redis::cmd("GET").arg("missing_key").query(&con).unwrap();
//! let name : String = redis::cmd("GET").arg("my_name").query(&con).unwrap();
//! let bin : Vec<u8> = redis::cmd("GET").arg("my_binary").query(&con).unwrap();
//! let map : HashMap<String, i32> = redis::cmd("HGETALL").arg("my_hash").query(&con).unwrap();
//! let keys : Vec<String> = redis::cmd("KEYS").query(&con).unwrap();
//! let mems : HashSet<i32> = redis::cmd("SMEMBERS").arg("s").query(&con).unwrap();
//! let (k1, k2) : (String, String) = redis::cmd("MGET").arg("k1").arg("k2").query(&con).unwrap();
//! ```

#![crate_name = "redis"]
#![crate_type = "lib"]
#![license = "BSD"]
#![comment = "Bindings and wrapper functions for redis."]

#![deny(non_camel_case_types)]

#![feature(macro_rules)]
#![feature(default_type_params)]

#![experimental]

extern crate url;
extern crate serialize;

/* public api */
pub use parser::{parse_redis_value, Parser};
pub use client::Client;
pub use connection::Connection;
pub use cmd::{cmd, Cmd, Iter};

#[doc(hidden)]
pub use types::{
    /* low level values */
    Value,
        Nil,
        Int,
        Data,
        Bulk,
        Okay,
        Status,

    /* error and result types */
    Error,
    RedisResult,

    /* error kinds */
    ErrorKind,
        ResponseError,
        TypeError,
        ExecAbortError,
        BusyLoadingError,
        NoScriptError,
        ExtensionError,
        InternalIoError,

    /* utility types */
    InfoDict,

    /* conversion traits */
    FromRedisValue,
    ToRedisArgs,
};

pub mod macros;

mod parser;
mod client;
mod connection;
mod types;
mod cmd;
<commit_msg>Updated the library documentation.<commit_after>//! redis-rs is a rust implementation of a Redis client library.  It exposes
//! a general purpose interface to Redis and also provides specific helpers for
//! commonly used functionality.
//!
//! # Basic Operation
//!
//! To open a connection you need to create a client and then to fetch a
//! connection from it.  In the future there will be a connection pool for
//! those, currently each connection is separate and not pooled.
//!
//! Queries are then performed through the `execute` and `query` methods.
//!
//! ```rust,no_run
//! extern crate redis;
//!
//! fn main() {
//!     let client = redis::Client::open("redis://127.0.0.1/").unwrap();
//!     let con = client.get_connection().unwrap();
//!     redis::cmd("SET").arg("my_key").arg(42i).execute(&con);
//!     assert_eq!(redis::cmd("GET").arg("my_key").query(&con), Ok(42i));
//! }
//! ```
//!
//! ## Type Conversions
//!
//! Because redis inherently is mostly type-less and the protocol is not
//! exactly friendly to developers, this library provides flexible support
//! for casting values to the intended results.  This is driven through the
//! `FromRedisValue` and `ToRedisArgs` traits.
//!
//! The `arg` method of the command will accept a wide range of types through
//! the `ToRedisArgs` trait and the `query` method of a command can convert the
//! value to what you expect the function to return through the `FromRedisValue`
//! trait.  This is quite flexible and allows vectors, tuples, hashsets, hashmaps
//! as well as optional values:
//!
//! ```rust,no_run
//! # use std::collections::{HashMap, HashSet};
//! # let client = redis::Client::open("redis://127.0.0.1/").unwrap();
//! # let con = client.get_connection().unwrap();
//! let count : i32 = redis::cmd("GET").arg("my_counter").query(&con).unwrap();
//! let count = redis::cmd("GET").arg("my_counter").query(&con).unwrap_or(0i32);
//! let k : Option<String> = redis::cmd("GET").arg("missing_key").query(&con).unwrap();
//! let name : String = redis::cmd("GET").arg("my_name").query(&con).unwrap();
//! let bin : Vec<u8> = redis::cmd("GET").arg("my_binary").query(&con).unwrap();
//! let map : HashMap<String, i32> = redis::cmd("HGETALL").arg("my_hash").query(&con).unwrap();
//! let keys : Vec<String> = redis::cmd("KEYS").query(&con).unwrap();
//! let mems : HashSet<i32> = redis::cmd("SMEMBERS").arg("s").query(&con).unwrap();
//! let (k1, k2) : (String, String) = redis::cmd("MGET").arg("k1").arg("k2").query(&con).unwrap();
//! ```
//!
//! ## Iteration Protocol
//!
//! In addition to sending a single query you iterators are also supported.  When
//! used with regular bulk responses they don't give you much over querying and
//! converting into a vector (both use a vector internally) but they can also
//! be used with `SCAN` like commands in which case iteration will send more
//! queries until the cursor is exhausted:
//!
//! ```rust,no_run
//! # use std::collections::{HashMap, HashSet};
//! # let client = redis::Client::open("redis://127.0.0.1/").unwrap();
//! # let con = client.get_connection().unwrap();
//! let mut cmd = redis::cmd("SSCAN");
//! let mut iter : redis::Iter<int> = cmd.arg("my_set").cursor_arg(0).iter(&con).unwrap();
//! for x in iter {
//!     // do something with the item
//! }
//! ```
//!
//! As you can see the cursor argument needs to be defined with `cursor_arg` instead
//! of `arg` so that the library knows which argument needs updating as the
//! query is run for more items.

#![crate_name = "redis"]
#![crate_type = "lib"]
#![license = "BSD"]
#![comment = "Bindings and wrapper functions for redis."]

#![deny(non_camel_case_types)]

#![feature(macro_rules)]
#![feature(default_type_params)]

#![experimental]

extern crate url;
extern crate serialize;

/* public api */
pub use parser::{parse_redis_value, Parser};
pub use client::Client;
pub use connection::Connection;
pub use cmd::{cmd, Cmd, Iter};

#[doc(hidden)]
pub use types::{
    /* low level values */
    Value,
        Nil,
        Int,
        Data,
        Bulk,
        Okay,
        Status,

    /* error and result types */
    Error,
    RedisResult,

    /* error kinds */
    ErrorKind,
        ResponseError,
        TypeError,
        ExecAbortError,
        BusyLoadingError,
        NoScriptError,
        ExtensionError,
        InternalIoError,

    /* utility types */
    InfoDict,

    /* conversion traits */
    FromRedisValue,
    ToRedisArgs,
};

pub mod macros;

mod parser;
mod client;
mod connection;
mod types;
mod cmd;
<|endoftext|>


<commit_before>use rusqlite::Connection;

#[derive(Debug)]
pub struct JobProvide {
    id: i32,
    fk_job: i32,
    fk_variable: i32,
}

pub fn table_create_job_provide(conn: &Connection) -> Result<(), &'static str> {
    let load_table = conn.execute_batch(
        "CREATE TABLE JOBPROVIDE (
                  id            INTEGER PRIMARY KEY ASC,
                  fk_job           INTEGER,
                  fk_variable      INTEGER,
                  FOREIGN KEY(fk_job) REFERENCES JOB(id) ON UPDATE CASCADE
                  FOREIGN KEY(fk_variable) REFERENCES VARIABLE_NAME(id) ON UPDATE CASCADE
                  )",
    );
    if load_table.is_err() {
        return Err("table_create_session Failed");
    }
    load_table.unwrap();
    return Ok(());
}

pub fn insert_job_provide(
    conn: &Connection,
    job: &i32,
    provider: &i32,
) -> Result<i32, &'static str> {

    let me = JobProvide {
        id: 0,
        fk_job: *job,
        fk_variable: *provider,
    };
    let load_instance = conn.execute(
        "INSERT INTO JOBPROVIDE (fk_job, fk_variable)
                  VALUES (?1, ?2)",
        &[&me.fk_job, &me.fk_variable],
    );
    if load_instance.is_err() {
        return Err("Insert failed");
    }
    load_instance.unwrap();
    return Ok(0);
}

pub fn list_job_provide(conn: &Connection) -> Vec<JobProvide> {
    let mut stmt = conn.prepare("SELECT id, fk_job, fk_variable FROM JOBPROVIDE")
        .unwrap();
    let wraped_fs_file_iter = stmt.query_map(&[], |row| {
        JobProvide {
            id: row.get(0),
            fk_job: row.get(1),
            fk_variable: row.get(2),
        }
    });
    let mut items = Vec::<JobProvide>::new();
    if wraped_fs_file_iter.is_err() {
        return items;
    }
    let fs_file_iter = wraped_fs_file_iter.unwrap();
    for person in fs_file_iter {
        items.push(person.unwrap());
    }
    return items;
}

pub fn pk_job_provide_by_all(
    conn: &Connection,
    fk_job: &i32,
    provider: &i32,
    pk: &mut i32,
) -> Result<i32, &'static str> {
    let mut stmt = conn.prepare("SELECT JOBPROVIDE.id, JOBPROVIDE.fk_job, JOBPROVIDE.fk_variable FROM JOBPROVIDE WHERE JOBPROVIDE.fk_job = ?1 AND JOBPROVIDE.fk_variable=?2").unwrap();
    let job_provide_iter = stmt.query_map(&[fk_job, provider], |row| {
        JobProvide {
            id: row.get(0),
            fk_job: row.get(1),
            fk_variable: row.get(2),
        }
    });
    if job_provide_iter.is_err() {
        return Err("Insert failed");
    }
    let result = job_provide_iter.unwrap();
    let mut found = 0;
    for person in result {
        let bill = person.unwrap();
        *pk = bill.id;
        found = 1;
    }
    if found != 0 {
        return Ok(found);
    }
    return Err("None found");
}
<commit_msg>Bugfix improve error message<commit_after>use rusqlite::Connection;

#[derive(Debug)]
pub struct JobProvide {
    id: i32,
    fk_job: i32,
    fk_variable: i32,
}

pub fn table_create_job_provide(conn: &Connection) -> Result<(), &'static str> {
    let load_table = conn.execute_batch(
        "CREATE TABLE JOBPROVIDE (
                  id            INTEGER PRIMARY KEY ASC,
                  fk_job           INTEGER,
                  fk_variable      INTEGER,
                  UNIQUE (fk_job, fk_variable) ON CONFLICT REPLACE
                  FOREIGN KEY(fk_job) REFERENCES JOB(id) ON UPDATE CASCADE
                  FOREIGN KEY(fk_variable) REFERENCES VARIABLE_NAME(id) ON UPDATE CASCADE
                  )",
    );
    if load_table.is_err() {
        return Err("table_create_session Failed");
    }
    load_table.unwrap();
    return Ok(());
}

pub fn insert_job_provide(
    conn: &Connection,
    job: &i32,
    provider: &i32,
) -> Result<i32, &'static str> {

    let me = JobProvide {
        id: 0,
        fk_job: *job,
        fk_variable: *provider,
    };
    let load_instance = conn.execute(
        "INSERT INTO JOBPROVIDE (fk_job, fk_variable)
                  VALUES (?1, ?2)",
        &[&me.fk_job, &me.fk_variable],
    );
    if load_instance.is_err() {
        return Err("failed trying to INSERT INTO JOBPROVIDE");
    }
    load_instance.unwrap();
    return Ok(0);
}

pub fn list_job_provide(conn: &Connection) -> Vec<JobProvide> {
    let mut stmt = conn.prepare("SELECT id, fk_job, fk_variable FROM JOBPROVIDE")
        .unwrap();
    let wraped_fs_file_iter = stmt.query_map(&[], |row| {
        JobProvide {
            id: row.get(0),
            fk_job: row.get(1),
            fk_variable: row.get(2),
        }
    });
    let mut items = Vec::<JobProvide>::new();
    if wraped_fs_file_iter.is_err() {
        return items;
    }
    let fs_file_iter = wraped_fs_file_iter.unwrap();
    for person in fs_file_iter {
        items.push(person.unwrap());
    }
    return items;
}

pub fn pk_job_provide_by_all(
    conn: &Connection,
    fk_job: &i32,
    provider: &i32,
    pk: &mut i32,
) -> Result<i32, &'static str> {
    let mut stmt = conn.prepare("SELECT JOBPROVIDE.id, JOBPROVIDE.fk_job, JOBPROVIDE.fk_variable FROM JOBPROVIDE WHERE JOBPROVIDE.fk_job = ?1 AND JOBPROVIDE.fk_variable=?2").unwrap();
    let job_provide_iter = stmt.query_map(&[fk_job, provider], |row| {
        JobProvide {
            id: row.get(0),
            fk_job: row.get(1),
            fk_variable: row.get(2),
        }
    });
    if job_provide_iter.is_err() {
        return Err("Insert failed");
    }
    let result = job_provide_iter.unwrap();
    let mut found = 0;
    for person in result {
        let bill = person.unwrap();
        *pk = bill.id;
        found = 1;
    }
    if found != 0 {
        return Ok(found);
    }
    return Err("None found");
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Mark Lee
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! Low-level bindings to OSX/macOS/iOS's `CommonCrypto` library.

#![warn(missing_docs)]

extern crate libc;

use libc::{c_int, c_uint};

/// Total number of operations.
const MD5_CBLOCK: usize = 64;
/// Number of operations per round.
const MD5_LBLOCK: usize = MD5_CBLOCK / 4;
/// Number of bytes for an MD5 hash.
pub const MD5_DIGEST_LENGTH: usize = 16;

const SHA_LBLOCK: usize = 16;
/// Number of bytes for an SHA1 hash.
pub const SHA1_DIGEST_LENGTH: usize = 20;
/// Number of bytes for an SHA256 hash.
pub const SHA256_DIGEST_LENGTH: usize = 32;
/// Number of bytes for an SHA384 hash.
pub const SHA384_DIGEST_LENGTH: usize = 48;
/// Number of bytes for an SHA512 hash.
pub const SHA512_DIGEST_LENGTH: usize = 64;

/// Struct used to generate MD5 hashes.
#[allow(non_camel_case_types, non_snake_case)]
#[derive(Clone, Debug, Default, PartialEq)]
#[repr(C)]
pub struct CC_MD5_CTX {
    A: c_uint,
    B: c_uint,
    C: c_uint,
    D: c_uint,
    Nl: c_uint,
    Nh: c_uint,
    data: [c_uint; MD5_LBLOCK],
    num: c_uint,
}

/// Struct used to generate SHA1 hashes.
#[allow(non_camel_case_types, non_snake_case)]
#[derive(Clone, Debug, Default, PartialEq)]
#[repr(C)]
pub struct CC_SHA_CTX {
    h0: c_uint,
    h1: c_uint,
    h2: c_uint,
    h3: c_uint,
    h4: c_uint,
    Nl: c_uint,
    Nh: c_uint,
    data: [c_uint; SHA_LBLOCK],
    num: c_uint,
}

macro_rules! cc_sha2_struct {
    ($ctx_name: ident, $ty: ty) => {
        /// Struct used to generate SHA2 hashes with the given bits.
        #[allow(non_camel_case_types, non_snake_case)]
        #[derive(Clone, Debug, Default, PartialEq)]
        #[repr(C)]
        pub struct $ctx_name {
            count: [$ty; 2],
            hash: [$ty; 8],
            wbuf: [$ty; 16],
        }
    }
}

cc_sha2_struct!(CC_SHA256_CTX, u32);
cc_sha2_struct!(CC_SHA512_CTX, u64);

/// Digest algorithm used in `CCDigest*()` functions.
#[repr(C)]
pub enum CCDigestAlgorithm {
    /// No digest algorithm
    kCCDigestNone = 0,
    /// MD2
    kCCDigestMD2 = 1,
    /// MD4
    kCCDigestMD4 = 2,
    /// MD5
    kCCDigestMD5 = 3,
    /// RIPEMD-128
    kCCDigestRMD128 = 4,
    /// RIPEMD-160
    kCCDigestRMD160 = 5,
    /// RIPEMD-256
    kCCDigestRMD256 = 6,
    /// RIPEMD-320
    kCCDigestRMD320 = 7,
    /// SHA1
    kCCDigestSHA1 = 8,
    /// SHA224
    kCCDigestSHA224 = 9,
    /// SHA256
    kCCDigestSHA256 = 10,
    /// SHA384
    kCCDigestSHA384 = 11,
    /// SHA512
    kCCDigestSHA512 = 12,
    /// Skein, 128 bit (Deprecated in iPhoneOS 6.0 and MacOSX10.9)
    kCCDigestSkein128 = 13,
    /// Skein, 160 bit (Deprecated in iPhoneOS 6.0 and MacOSX10.9)
    kCCDigestSkein160 = 14,
    /// Skein, 224 bit (Deprecated in iPhoneOS 6.0 and MacOSX10.9)
    kCCDigestSkein224 = 16,
    /// Skein, 256 bit (Deprecated in iPhoneOS 6.0 and MacOSX10.9)
    kCCDigestSkein256 = 17,
    /// Skein, 384 bit (Deprecated in iPhoneOS 6.0 and MacOSX10.9)
    kCCDigestSkein384 = 18,
    /// Skein, 512 bit (Deprecated in iPhoneOS 6.0 and MacOSX10.9)
    kCCDigestSkein512 = 19,
}

const CC_DIGEST_SIZE: usize = 1032;

/// Context used in `CCDigest*()` functions.
#[allow(non_camel_case_types, non_snake_case)]
#[repr(C)]
pub struct CCDigestCtx {
    context: [u8; CC_DIGEST_SIZE],
}

/// Algorithm for use with `CCKeyDerivationPBKDF()``
#[repr(C)]
pub enum CCPBKDFAlgorithm {
    /// PBKDF2
    kCCPBKDF2 = 2,
}

/// Pseudo-random algorithm to use with `CCKeyDerivationPBKDF()`
#[repr(C)]
pub enum CCPseudoRandomAlgorithm {
    /// SHA-1
    kCCPRFHmacAlgSHA1 = 1,
    /// SHA-224
    kCCPRFHmacAlgSHA224 = 2,
    /// SHA-256
    kCCPRFHmacAlgSHA256 = 3,
    /// SHA-384
    kCCPRFHmacAlgSHA384 = 4,
    /// SHA-512
    kCCPRFHmacAlgSHA512 = 5,
}

extern "C" {
    /// Initializes MD5 hasher. See `man 3cc CC_MD5` for details.
    pub fn CC_MD5_Init(ctx: *mut CC_MD5_CTX) -> c_int;
    /// Appends data to be hashed. See `man 3cc CC_MD5` for details.
    pub fn CC_MD5_Update(ctx: *mut CC_MD5_CTX, data: *const u8, n: usize) -> c_int;
    /// Generates MD5 hash. See `man 3cc CC_MD5` for details.
    pub fn CC_MD5_Final(md: *mut u8, ctx: *mut CC_MD5_CTX) -> c_int;
    /// Initializes SHA1 hasher. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA1_Init(ctx: *mut CC_SHA_CTX) -> c_int;
    /// Appends data to be hashed. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA1_Update(ctx: *mut CC_SHA_CTX, data: *const u8, n: usize) -> c_int;
    /// Generates SHA1 hash. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA1_Final(md: *mut u8, ctx: *mut CC_SHA_CTX) -> c_int;
    /// Initializes SHA256 hasher. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA256_Init(ctx: *mut CC_SHA256_CTX) -> c_int;
    /// Appends data to be hashed. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA256_Update(ctx: *mut CC_SHA256_CTX, data: *const u8, n: usize) -> c_int;
    /// Generates SHA256 hash. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA256_Final(md: *mut u8, ctx: *mut CC_SHA256_CTX) -> c_int;
    /// Initializes SHA384 hasher. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA384_Init(ctx: *mut CC_SHA512_CTX) -> c_int;
    /// Appends data to be hashed. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA384_Update(ctx: *mut CC_SHA512_CTX, data: *const u8, n: usize) -> c_int;
    /// Generates SHA384 hash. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA384_Final(md: *mut u8, ctx: *mut CC_SHA512_CTX) -> c_int;
    /// Initializes SHA512 hasher. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA512_Init(ctx: *mut CC_SHA512_CTX) -> c_int;
    /// Appends data to be hashed. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA512_Update(ctx: *mut CC_SHA512_CTX, data: *const u8, n: usize) -> c_int;
    /// Generates SHA512 hash. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA512_Final(md: *mut u8, ctx: *mut CC_SHA512_CTX) -> c_int;
    /// Generic digest hasher.
    pub fn CCDigest(algorithm: CCDigestAlgorithm,
                    data: *const u8,
                    length: usize,
                    output: *mut u8)
                    -> c_int;
    /// Allocate and initialize a `CCDigestCtx` for a digest.
    pub fn CCDigestCreate(algorithm: CCDigestAlgorithm) -> *mut CCDigestCtx;
    /// Continue to digest data. Returns `0` on success.
    pub fn CCDigestUpdate(ctx: *mut CCDigestCtx, data: *const u8, length: usize) -> c_int;
    /// Conclude digest operations and produce the digest output. Returns `0` on success.
    pub fn CCDigestFinal(ctx: *mut CCDigestCtx, output: *mut u8) -> c_int;
    /// Clear and free a `CCDigestCtx`.
    pub fn CCDigestDestroy(ctx: *mut CCDigestCtx);
    /// Clear and re-initialize a `CCDigestCtx` for the same algorithm.
    pub fn CCDigestReset(ctx: *mut CCDigestCtx);
    /// Produce the digest output result for the bytes currently processed. Returns `0` on success.
    pub fn CCDigestGetDigest(ctx: *mut CCDigestCtx, output: *mut u8) -> c_int;
    /// Provides the block size of the digest algorithm. Returns `0` on failure.
    pub fn CCDigestGetBlockSize(algorithm: CCDigestAlgorithm) -> usize;
    /// Provides the digest output size of the digest algorithm. Returns `0` on failure.
    pub fn CCDigestGetOutputSize(algorithm: CCDigestAlgorithm) -> usize;
    /// Provides the block size of the digest algorithm. Returns `0` on failure.
    pub fn CCDigestGetBlockSizeFromRef(ctx: *mut CCDigestCtx) -> usize;
    /// Provides the digest output size of the digest algorithm. Returns `0` on failure.
    pub fn CCDigestGetOutputSizeFromRef(ctx: *mut CCDigestCtx) -> usize;

    /// Derive a key from a user-supplied password via PBKDF2
    pub fn CCKeyDerivationPBKDF(algorithm: CCPBKDFAlgorithm, password: *const u8, passwordLen: usize, salt: *const u8, saltLen: usize, prf: CCPseudoRandomAlgorithm, rounds: u32, derivedKey: *mut u8, derivedKeyLen: usize) -> c_int;
}
<commit_msg>Fix doc typo<commit_after>// Copyright (c) 2016 Mark Lee
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! Low-level bindings to OSX/macOS/iOS's `CommonCrypto` library.

#![warn(missing_docs)]

extern crate libc;

use libc::{c_int, c_uint};

/// Total number of operations.
const MD5_CBLOCK: usize = 64;
/// Number of operations per round.
const MD5_LBLOCK: usize = MD5_CBLOCK / 4;
/// Number of bytes for an MD5 hash.
pub const MD5_DIGEST_LENGTH: usize = 16;

const SHA_LBLOCK: usize = 16;
/// Number of bytes for an SHA1 hash.
pub const SHA1_DIGEST_LENGTH: usize = 20;
/// Number of bytes for an SHA256 hash.
pub const SHA256_DIGEST_LENGTH: usize = 32;
/// Number of bytes for an SHA384 hash.
pub const SHA384_DIGEST_LENGTH: usize = 48;
/// Number of bytes for an SHA512 hash.
pub const SHA512_DIGEST_LENGTH: usize = 64;

/// Struct used to generate MD5 hashes.
#[allow(non_camel_case_types, non_snake_case)]
#[derive(Clone, Debug, Default, PartialEq)]
#[repr(C)]
pub struct CC_MD5_CTX {
    A: c_uint,
    B: c_uint,
    C: c_uint,
    D: c_uint,
    Nl: c_uint,
    Nh: c_uint,
    data: [c_uint; MD5_LBLOCK],
    num: c_uint,
}

/// Struct used to generate SHA1 hashes.
#[allow(non_camel_case_types, non_snake_case)]
#[derive(Clone, Debug, Default, PartialEq)]
#[repr(C)]
pub struct CC_SHA_CTX {
    h0: c_uint,
    h1: c_uint,
    h2: c_uint,
    h3: c_uint,
    h4: c_uint,
    Nl: c_uint,
    Nh: c_uint,
    data: [c_uint; SHA_LBLOCK],
    num: c_uint,
}

macro_rules! cc_sha2_struct {
    ($ctx_name: ident, $ty: ty) => {
        /// Struct used to generate SHA2 hashes with the given bits.
        #[allow(non_camel_case_types, non_snake_case)]
        #[derive(Clone, Debug, Default, PartialEq)]
        #[repr(C)]
        pub struct $ctx_name {
            count: [$ty; 2],
            hash: [$ty; 8],
            wbuf: [$ty; 16],
        }
    }
}

cc_sha2_struct!(CC_SHA256_CTX, u32);
cc_sha2_struct!(CC_SHA512_CTX, u64);

/// Digest algorithm used in `CCDigest*()` functions.
#[repr(C)]
pub enum CCDigestAlgorithm {
    /// No digest algorithm
    kCCDigestNone = 0,
    /// MD2
    kCCDigestMD2 = 1,
    /// MD4
    kCCDigestMD4 = 2,
    /// MD5
    kCCDigestMD5 = 3,
    /// RIPEMD-128
    kCCDigestRMD128 = 4,
    /// RIPEMD-160
    kCCDigestRMD160 = 5,
    /// RIPEMD-256
    kCCDigestRMD256 = 6,
    /// RIPEMD-320
    kCCDigestRMD320 = 7,
    /// SHA1
    kCCDigestSHA1 = 8,
    /// SHA224
    kCCDigestSHA224 = 9,
    /// SHA256
    kCCDigestSHA256 = 10,
    /// SHA384
    kCCDigestSHA384 = 11,
    /// SHA512
    kCCDigestSHA512 = 12,
    /// Skein, 128 bit (Deprecated in iPhoneOS 6.0 and MacOSX10.9)
    kCCDigestSkein128 = 13,
    /// Skein, 160 bit (Deprecated in iPhoneOS 6.0 and MacOSX10.9)
    kCCDigestSkein160 = 14,
    /// Skein, 224 bit (Deprecated in iPhoneOS 6.0 and MacOSX10.9)
    kCCDigestSkein224 = 16,
    /// Skein, 256 bit (Deprecated in iPhoneOS 6.0 and MacOSX10.9)
    kCCDigestSkein256 = 17,
    /// Skein, 384 bit (Deprecated in iPhoneOS 6.0 and MacOSX10.9)
    kCCDigestSkein384 = 18,
    /// Skein, 512 bit (Deprecated in iPhoneOS 6.0 and MacOSX10.9)
    kCCDigestSkein512 = 19,
}

const CC_DIGEST_SIZE: usize = 1032;

/// Context used in `CCDigest*()` functions.
#[allow(non_camel_case_types, non_snake_case)]
#[repr(C)]
pub struct CCDigestCtx {
    context: [u8; CC_DIGEST_SIZE],
}

/// Algorithm for use with `CCKeyDerivationPBKDF()`
#[repr(C)]
pub enum CCPBKDFAlgorithm {
    /// PBKDF2
    kCCPBKDF2 = 2,
}

/// Pseudo-random algorithm to use with `CCKeyDerivationPBKDF()`
#[repr(C)]
pub enum CCPseudoRandomAlgorithm {
    /// SHA-1
    kCCPRFHmacAlgSHA1 = 1,
    /// SHA-224
    kCCPRFHmacAlgSHA224 = 2,
    /// SHA-256
    kCCPRFHmacAlgSHA256 = 3,
    /// SHA-384
    kCCPRFHmacAlgSHA384 = 4,
    /// SHA-512
    kCCPRFHmacAlgSHA512 = 5,
}

extern "C" {
    /// Initializes MD5 hasher. See `man 3cc CC_MD5` for details.
    pub fn CC_MD5_Init(ctx: *mut CC_MD5_CTX) -> c_int;
    /// Appends data to be hashed. See `man 3cc CC_MD5` for details.
    pub fn CC_MD5_Update(ctx: *mut CC_MD5_CTX, data: *const u8, n: usize) -> c_int;
    /// Generates MD5 hash. See `man 3cc CC_MD5` for details.
    pub fn CC_MD5_Final(md: *mut u8, ctx: *mut CC_MD5_CTX) -> c_int;
    /// Initializes SHA1 hasher. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA1_Init(ctx: *mut CC_SHA_CTX) -> c_int;
    /// Appends data to be hashed. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA1_Update(ctx: *mut CC_SHA_CTX, data: *const u8, n: usize) -> c_int;
    /// Generates SHA1 hash. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA1_Final(md: *mut u8, ctx: *mut CC_SHA_CTX) -> c_int;
    /// Initializes SHA256 hasher. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA256_Init(ctx: *mut CC_SHA256_CTX) -> c_int;
    /// Appends data to be hashed. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA256_Update(ctx: *mut CC_SHA256_CTX, data: *const u8, n: usize) -> c_int;
    /// Generates SHA256 hash. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA256_Final(md: *mut u8, ctx: *mut CC_SHA256_CTX) -> c_int;
    /// Initializes SHA384 hasher. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA384_Init(ctx: *mut CC_SHA512_CTX) -> c_int;
    /// Appends data to be hashed. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA384_Update(ctx: *mut CC_SHA512_CTX, data: *const u8, n: usize) -> c_int;
    /// Generates SHA384 hash. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA384_Final(md: *mut u8, ctx: *mut CC_SHA512_CTX) -> c_int;
    /// Initializes SHA512 hasher. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA512_Init(ctx: *mut CC_SHA512_CTX) -> c_int;
    /// Appends data to be hashed. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA512_Update(ctx: *mut CC_SHA512_CTX, data: *const u8, n: usize) -> c_int;
    /// Generates SHA512 hash. See `man 3cc CC_SHA` for details.
    pub fn CC_SHA512_Final(md: *mut u8, ctx: *mut CC_SHA512_CTX) -> c_int;
    /// Generic digest hasher.
    pub fn CCDigest(algorithm: CCDigestAlgorithm,
                    data: *const u8,
                    length: usize,
                    output: *mut u8)
                    -> c_int;
    /// Allocate and initialize a `CCDigestCtx` for a digest.
    pub fn CCDigestCreate(algorithm: CCDigestAlgorithm) -> *mut CCDigestCtx;
    /// Continue to digest data. Returns `0` on success.
    pub fn CCDigestUpdate(ctx: *mut CCDigestCtx, data: *const u8, length: usize) -> c_int;
    /// Conclude digest operations and produce the digest output. Returns `0` on success.
    pub fn CCDigestFinal(ctx: *mut CCDigestCtx, output: *mut u8) -> c_int;
    /// Clear and free a `CCDigestCtx`.
    pub fn CCDigestDestroy(ctx: *mut CCDigestCtx);
    /// Clear and re-initialize a `CCDigestCtx` for the same algorithm.
    pub fn CCDigestReset(ctx: *mut CCDigestCtx);
    /// Produce the digest output result for the bytes currently processed. Returns `0` on success.
    pub fn CCDigestGetDigest(ctx: *mut CCDigestCtx, output: *mut u8) -> c_int;
    /// Provides the block size of the digest algorithm. Returns `0` on failure.
    pub fn CCDigestGetBlockSize(algorithm: CCDigestAlgorithm) -> usize;
    /// Provides the digest output size of the digest algorithm. Returns `0` on failure.
    pub fn CCDigestGetOutputSize(algorithm: CCDigestAlgorithm) -> usize;
    /// Provides the block size of the digest algorithm. Returns `0` on failure.
    pub fn CCDigestGetBlockSizeFromRef(ctx: *mut CCDigestCtx) -> usize;
    /// Provides the digest output size of the digest algorithm. Returns `0` on failure.
    pub fn CCDigestGetOutputSizeFromRef(ctx: *mut CCDigestCtx) -> usize;

    /// Derive a key from a user-supplied password via PBKDF2
    pub fn CCKeyDerivationPBKDF(algorithm: CCPBKDFAlgorithm, password: *const u8, passwordLen: usize, salt: *const u8, saltLen: usize, prf: CCPseudoRandomAlgorithm, rounds: u32, derivedKey: *mut u8, derivedKeyLen: usize) -> c_int;
}
<|endoftext|>


<commit_before>use std::fmt;
use std::path;

use super::files;
use crate::error::*;
use crate::syntax_highlight;
use liquid;
use log::warn;
use log::{debug, trace};
use serde::Serialize;

type Partials = liquid::partials::EagerCompiler<liquid::partials::InMemorySource>;

fn load_partials_from_path(root: path::PathBuf) -> Result<Partials> {
    let mut source = Partials::empty();

    debug!("Loading snippets from `{}`", root.display());
    let template_files = files::FilesBuilder::new(root)?
        .ignore_hidden(false)?
        .build()?;
    for file_path in template_files.files() {
        let rel_path = file_path
            .strip_prefix(template_files.root())
            .expect("file was found under the root")
            .to_str()
            .expect("only UTF-8 characters supported in paths")
            .to_owned();
        trace!("Loading snippet `{}`", rel_path);
        let content = files::read_file(file_path)?;
        source.add(rel_path, content);
    }
    Ok(source)
}

#[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct LiquidBuilder {
    pub includes_path: path::PathBuf,
    pub theme: Option<liquid::model::KString>,
}

impl LiquidBuilder {
    pub fn build(self) -> Result<Liquid> {
        let highlight = Self::highlight(self.theme)?;
        let parser = liquid::ParserBuilder::with_stdlib()
            .filter(liquid_lib::extra::DateInTz)
            .filter(liquid_lib::shopify::Pluralize)
            // Intentionally staying with `stdlib::IncludeTag` rather than `jekyll::IncludeTag`
            .filter(liquid_lib::jekyll::Slugify)
            .filter(liquid_lib::jekyll::Pop)
            .filter(liquid_lib::jekyll::Push)
            .filter(liquid_lib::jekyll::Shift)
            .filter(liquid_lib::jekyll::Unshift)
            .filter(liquid_lib::jekyll::ArrayToSentenceString)
            .partials(load_partials_from_path(self.includes_path)?)
            .block(highlight)
            .build()?;
        Ok(Liquid { parser })
    }

    fn highlight(
        theme: Option<liquid::model::KString>,
    ) -> Result<Box<dyn liquid_core::ParseBlock>> {
        let theme = if let Some(theme) = theme {
            let result: Result<()> = match syntax_highlight::has_syntax_theme(&theme) {
                Ok(true) => Ok(()),
                Ok(false) => Err(failure::format_err!(
                    "Syntax theme '{}' is unsupported",
                    theme
                )),
                Err(err) => {
                    warn!("Syntax theme named '{}' ignored. Reason: {}", theme, err);
                    Ok(())
                }
            };
            result?;
            theme
        } else {
            "".into()
        };
        let block = syntax_highlight::CodeBlockParser::new(theme);
        Ok(Box::new(block))
    }
}

pub struct Liquid {
    parser: liquid::Parser,
}

impl Liquid {
    pub fn parse(&self, template: &str) -> Result<liquid::Template> {
        let template = self.parser.parse(template)?;
        Ok(template)
    }
}

impl fmt::Debug for Liquid {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "Liquid{{}}")
    }
}
<commit_msg>fix(build): Binary files stop build<commit_after>use std::fmt;
use std::path;

use super::files;
use crate::error::*;
use crate::syntax_highlight;
use liquid;
use log::warn;
use log::{debug, trace};
use serde::Serialize;

type Partials = liquid::partials::EagerCompiler<liquid::partials::InMemorySource>;

fn load_partials_from_path(root: path::PathBuf) -> Result<Partials> {
    let mut source = Partials::empty();

    debug!("Loading snippets from `{}`", root.display());
    let template_files = files::FilesBuilder::new(root)?
        .ignore_hidden(false)?
        .build()?;
    for file_path in template_files.files() {
        let rel_path = file_path
            .strip_prefix(template_files.root())
            .expect("file was found under the root")
            .to_str()
            .expect("only UTF-8 characters supported in paths")
            .to_owned();
        trace!("Loading snippet `{}`", rel_path);
        match files::read_file(file_path) {
            Ok(content) => {
                source.add(rel_path, content);
            }
            Err(err) => {
                warn!("Ignoring snippet {}: {}", rel_path, err);
            }
        }
    }
    Ok(source)
}

#[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct LiquidBuilder {
    pub includes_path: path::PathBuf,
    pub theme: Option<liquid::model::KString>,
}

impl LiquidBuilder {
    pub fn build(self) -> Result<Liquid> {
        let highlight = Self::highlight(self.theme)?;
        let parser = liquid::ParserBuilder::with_stdlib()
            .filter(liquid_lib::extra::DateInTz)
            .filter(liquid_lib::shopify::Pluralize)
            // Intentionally staying with `stdlib::IncludeTag` rather than `jekyll::IncludeTag`
            .filter(liquid_lib::jekyll::Slugify)
            .filter(liquid_lib::jekyll::Pop)
            .filter(liquid_lib::jekyll::Push)
            .filter(liquid_lib::jekyll::Shift)
            .filter(liquid_lib::jekyll::Unshift)
            .filter(liquid_lib::jekyll::ArrayToSentenceString)
            .partials(load_partials_from_path(self.includes_path)?)
            .block(highlight)
            .build()?;
        Ok(Liquid { parser })
    }

    fn highlight(
        theme: Option<liquid::model::KString>,
    ) -> Result<Box<dyn liquid_core::ParseBlock>> {
        let theme = if let Some(theme) = theme {
            let result: Result<()> = match syntax_highlight::has_syntax_theme(&theme) {
                Ok(true) => Ok(()),
                Ok(false) => Err(failure::format_err!(
                    "Syntax theme '{}' is unsupported",
                    theme
                )),
                Err(err) => {
                    warn!("Syntax theme named '{}' ignored. Reason: {}", theme, err);
                    Ok(())
                }
            };
            result?;
            theme
        } else {
            "".into()
        };
        let block = syntax_highlight::CodeBlockParser::new(theme);
        Ok(Box::new(block))
    }
}

pub struct Liquid {
    parser: liquid::Parser,
}

impl Liquid {
    pub fn parse(&self, template: &str) -> Result<liquid::Template> {
        let template = self.parser.parse(template)?;
        Ok(template)
    }
}

impl fmt::Debug for Liquid {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "Liquid{{}}")
    }
}
<|endoftext|>