<commit_before>//! Draw rectangle

use current::{ Get, Modifier, Set };
use internal;
use triangulation;
use Context;
use BackEnd;
use ImageSize;
use Color;

/// Use x, y, half-width, half-height
pub fn centered(rect: internal::Rectangle) -> internal::Rectangle {
    let [cx, cy, rw, rh] = rect;
    [cx - rw, cy - rh, 2.0 * rw, 2.0 * rh]
}

/// Use centered square
pub fn centered_square(
    x: internal::Scalar,
    y: internal::Scalar,
    radius: internal::Scalar
) -> internal::Rectangle {
    [x - radius, y - radius, 2.0 * radius, 2.0 * radius]
}

/// Use square with x, y in upper left corner
pub fn square(
    x: internal::Scalar,
    y: internal::Scalar,
    size: internal::Scalar
) -> internal::Rectangle {
    [x, y, size, size]
}

/// The shape of the rectangle
pub enum Shape {
    /// Square corners
    Square,
    /// Round corners
    Round(internal::Radius),
    /// Bevel corners
    Bevel(internal::Radius),
}

/// Wrapper trait for `Get<Shape>`
pub trait GetShape: Get<Shape> {
    /// Get shape
    #[inline(always)]
    fn get_shape(&self) -> Shape {
        self.get()
    }
}

impl<T: Get<Shape>> GetShape for T {}

/// Wrapper trait for `Set<Shape>`
pub trait SetShape: Set<Shape> {
    /// Set shape
    #[inline(always)]
    fn set_shape(&mut self, val: Shape) {
        self.set_mut(val);
    }
}

impl<T: Set<Shape>> SetShape for T {}

/// The border of the rectangle
pub struct Border {
    /// The color of the border
    pub color: internal::Color,
    /// The radius of the border
    pub radius: internal::Radius,
}

/// Wrapper trait for `Get<Border>`
pub trait GetBorder: Get<Border> {
    /// Get border
    #[inline(always)]
    fn get_border(&self) -> Border {
        self.get()
    }
}

impl<T: Get<Border>> GetBorder for T {}

/// Wrapper trait for `Set<Border>`
pub trait SetBorder: Set<Border> {
    /// Set border
    #[inline(always)]
    fn set_border(&mut self, val: Border) {
        self.set_mut(val);
    }
}

impl<T: Set<Border>> SetBorder for T {}

/// Maybe border property
pub struct MaybeBorder(pub Option<Border>);

/// Wrapper trait for `Get<MaybeBorder>`
pub trait GetMaybeBorder: Get<MaybeBorder> {
    /// Get maybe border
    #[inline(always)]
    fn get_maybe_border(&self) -> MaybeBorder {
        self.get()
    }
}

impl<T: Get<MaybeBorder>> GetMaybeBorder for T {}

/// Wrapper trait for `Set<MaybeBorder>`
pub trait SetMaybeBorder: Set<MaybeBorder> {
    /// Set maybe border
    #[inline(always)]
    fn set_maybe_border(&mut self, val: MaybeBorder) {
        self.set_mut(val);
    }
}

impl<T: Set<MaybeBorder>> SetMaybeBorder for T {}

/// A filled rectangle
#[deriving(Copy)]
pub struct Rectangle {
    /// The rectangle color
    pub color: internal::Color,
    /// The roundness of the rectangle
    pub shape: Shape,
    /// The border
    pub border: Option<Border>,
}

impl Rectangle {
    /// Creates a new rectangle.
    pub fn new(color: internal::Color) -> Rectangle {
        Rectangle {
            color: color,
            shape: Shape::Square,
            border: None,
        }
    }

    /// Draws the rectangle
    pub fn draw<B: BackEnd<I>, I: ImageSize>(
        &self,
        rectangle: internal::Rectangle,
        c: &Context,
        back_end: &mut B
    ) {
        if self.color[3] != 0.0 {
            back_end.color(self.color);
            match self.shape {
                Shape::Square => {
                    back_end.tri_list(
                        &triangulation::rect_tri_list_xy(c.transform, rectangle),
                    );
                }
                Shape::Round(round_radius) => {
                    triangulation::with_round_rectangle_tri_list(
                        32,
                        c.transform,
                        rectangle,
                        round_radius,
                        |vertices| back_end.tri_list(vertices)
                    );
                }
                Shape::Bevel(bevel_radius) => {
                    triangulation::with_round_rectangle_tri_list(
                        2,
                        c.transform,
                        rectangle,
                        bevel_radius,
                        |vertices| back_end.tri_list(vertices)
                    );
                }
            }
        }

        if let Some(Border { color, radius: border_radius }) = self.border {
            if color[3] == 0.0 { return; }
            back_end.color(color);
            match self.shape {
                Shape::Square => {
                    back_end.tri_list(
                        &triangulation::rect_border_tri_list_xy(
                            c.transform, rectangle, border_radius),
                    );
                }
                Shape::Round(round_radius) => {
                    triangulation::with_round_rectangle_border_tri_list(
                        128,
                        c.transform,
                        rectangle,
                        round_radius,
                        border_radius,
                        |vertices| back_end.tri_list(vertices)
                    );
                }
                Shape::Bevel(bevel_radius) => {
                    triangulation::with_round_rectangle_border_tri_list(
                        2,
                        c.transform,
                        rectangle,
                        bevel_radius,
                        border_radius,
                        |vertices| back_end.tri_list(vertices)
                    );
                }
            }
        }
    }
}

impl Modifier<Rectangle> for Color {
    #[inline(always)]
    fn modify(self, r: &mut Rectangle) {
        let Color(val) = self;
        r.color = val;
    }
}

impl Get<Color> for Rectangle {
    #[inline(always)]
    fn get(&self) -> Color {
        Color(self.color)
    }
}

impl Modifier<Rectangle> for Shape {
    #[inline(always)]
    fn modify(self, r: &mut Rectangle) {
        r.shape = self;
    }
}

impl Get<Shape> for Rectangle {
    #[inline(always)]
    fn get(&self) -> Shape {
        self.shape
    }
}

impl Modifier<Rectangle> for Border {
    #[inline(always)]
    fn modify(self, r: &mut Rectangle) {
        r.border = Some(self);
    }
}

impl Modifier<Rectangle> for MaybeBorder {
    #[inline(always)]
    fn modify(self, r: &mut Rectangle) {
        let MaybeBorder(val) = self;
        r.border = val;
    }
}

impl Get<MaybeBorder> for Rectangle {
    #[inline(always)]
    fn get(&self) -> MaybeBorder {
        MaybeBorder(self.border)
    }
}

#[cfg(test)]
mod test {
    use super::Rectangle;
    use super::Shape;
    use super::Border;
    use Color;
    use current::Set;

    #[test]
    fn test_rectangle() {
        let _rectangle = Rectangle::new([1.0, ..4])
            .set(Color([0.0, ..4]))
            .set(Shape::Round(10.0))
            .set(Border { color: [0.0, ..4], radius: 4.0 });
    }
}

<commit_msg>Added border constructor to Rectangle<commit_after>//! Draw rectangle

use current::{ Get, Modifier, Set };
use internal;
use triangulation;
use Context;
use BackEnd;
use ImageSize;
use Color;

/// Use x, y, half-width, half-height
pub fn centered(rect: internal::Rectangle) -> internal::Rectangle {
    let [cx, cy, rw, rh] = rect;
    [cx - rw, cy - rh, 2.0 * rw, 2.0 * rh]
}

/// Use centered square
pub fn centered_square(
    x: internal::Scalar,
    y: internal::Scalar,
    radius: internal::Scalar
) -> internal::Rectangle {
    [x - radius, y - radius, 2.0 * radius, 2.0 * radius]
}

/// Use square with x, y in upper left corner
pub fn square(
    x: internal::Scalar,
    y: internal::Scalar,
    size: internal::Scalar
) -> internal::Rectangle {
    [x, y, size, size]
}

/// The shape of the rectangle
pub enum Shape {
    /// Square corners
    Square,
    /// Round corners
    Round(internal::Radius),
    /// Bevel corners
    Bevel(internal::Radius),
}

/// Wrapper trait for `Get<Shape>`
pub trait GetShape: Get<Shape> {
    /// Get shape
    #[inline(always)]
    fn get_shape(&self) -> Shape {
        self.get()
    }
}

impl<T: Get<Shape>> GetShape for T {}

/// Wrapper trait for `Set<Shape>`
pub trait SetShape: Set<Shape> {
    /// Set shape
    #[inline(always)]
    fn set_shape(&mut self, val: Shape) {
        self.set_mut(val);
    }
}

impl<T: Set<Shape>> SetShape for T {}

/// The border of the rectangle
pub struct Border {
    /// The color of the border
    pub color: internal::Color,
    /// The radius of the border
    pub radius: internal::Radius,
}

/// Wrapper trait for `Get<Border>`
pub trait GetBorder: Get<Border> {
    /// Get border
    #[inline(always)]
    fn get_border(&self) -> Border {
        self.get()
    }
}

impl<T: Get<Border>> GetBorder for T {}

/// Wrapper trait for `Set<Border>`
pub trait SetBorder: Set<Border> {
    /// Set border
    #[inline(always)]
    fn set_border(&mut self, val: Border) {
        self.set_mut(val);
    }
}

impl<T: Set<Border>> SetBorder for T {}

/// Maybe border property
pub struct MaybeBorder(pub Option<Border>);

/// Wrapper trait for `Get<MaybeBorder>`
pub trait GetMaybeBorder: Get<MaybeBorder> {
    /// Get maybe border
    #[inline(always)]
    fn get_maybe_border(&self) -> MaybeBorder {
        self.get()
    }
}

impl<T: Get<MaybeBorder>> GetMaybeBorder for T {}

/// Wrapper trait for `Set<MaybeBorder>`
pub trait SetMaybeBorder: Set<MaybeBorder> {
    /// Set maybe border
    #[inline(always)]
    fn set_maybe_border(&mut self, val: MaybeBorder) {
        self.set_mut(val);
    }
}

impl<T: Set<MaybeBorder>> SetMaybeBorder for T {}

/// A filled rectangle
#[deriving(Copy)]
pub struct Rectangle {
    /// The rectangle color
    pub color: internal::Color,
    /// The roundness of the rectangle
    pub shape: Shape,
    /// The border
    pub border: Option<Border>,
}

impl Rectangle {
    /// Creates a new rectangle.
    pub fn new(color: internal::Color) -> Rectangle {
        Rectangle {
            color: color,
            shape: Shape::Square,
            border: None,
        }
    }

    /// Creates a new rectangle border.
    pub fn border(
        color: internal::Color,
        radius: internal::Radius
    ) -> Rectangle {
        Rectangle {
            color: [0.0, ..4],
            shape: Shape::Square,
            border: Some(Border {
                    color: color,
                    radius: radius
                })
        }
    }

    /// Draws the rectangle
    pub fn draw<B: BackEnd<I>, I: ImageSize>(
        &self,
        rectangle: internal::Rectangle,
        c: &Context,
        back_end: &mut B
    ) {
        if self.color[3] != 0.0 {
            back_end.color(self.color);
            match self.shape {
                Shape::Square => {
                    back_end.tri_list(
                        &triangulation::rect_tri_list_xy(c.transform, rectangle),
                    );
                }
                Shape::Round(round_radius) => {
                    triangulation::with_round_rectangle_tri_list(
                        32,
                        c.transform,
                        rectangle,
                        round_radius,
                        |vertices| back_end.tri_list(vertices)
                    );
                }
                Shape::Bevel(bevel_radius) => {
                    triangulation::with_round_rectangle_tri_list(
                        2,
                        c.transform,
                        rectangle,
                        bevel_radius,
                        |vertices| back_end.tri_list(vertices)
                    );
                }
            }
        }

        if let Some(Border { color, radius: border_radius }) = self.border {
            if color[3] == 0.0 { return; }
            back_end.color(color);
            match self.shape {
                Shape::Square => {
                    back_end.tri_list(
                        &triangulation::rect_border_tri_list_xy(
                            c.transform, rectangle, border_radius),
                    );
                }
                Shape::Round(round_radius) => {
                    triangulation::with_round_rectangle_border_tri_list(
                        128,
                        c.transform,
                        rectangle,
                        round_radius,
                        border_radius,
                        |vertices| back_end.tri_list(vertices)
                    );
                }
                Shape::Bevel(bevel_radius) => {
                    triangulation::with_round_rectangle_border_tri_list(
                        2,
                        c.transform,
                        rectangle,
                        bevel_radius,
                        border_radius,
                        |vertices| back_end.tri_list(vertices)
                    );
                }
            }
        }
    }
}

impl Modifier<Rectangle> for Color {
    #[inline(always)]
    fn modify(self, r: &mut Rectangle) {
        let Color(val) = self;
        r.color = val;
    }
}

impl Get<Color> for Rectangle {
    #[inline(always)]
    fn get(&self) -> Color {
        Color(self.color)
    }
}

impl Modifier<Rectangle> for Shape {
    #[inline(always)]
    fn modify(self, r: &mut Rectangle) {
        r.shape = self;
    }
}

impl Get<Shape> for Rectangle {
    #[inline(always)]
    fn get(&self) -> Shape {
        self.shape
    }
}

impl Modifier<Rectangle> for Border {
    #[inline(always)]
    fn modify(self, r: &mut Rectangle) {
        r.border = Some(self);
    }
}

impl Modifier<Rectangle> for MaybeBorder {
    #[inline(always)]
    fn modify(self, r: &mut Rectangle) {
        let MaybeBorder(val) = self;
        r.border = val;
    }
}

impl Get<MaybeBorder> for Rectangle {
    #[inline(always)]
    fn get(&self) -> MaybeBorder {
        MaybeBorder(self.border)
    }
}

#[cfg(test)]
mod test {
    use super::Rectangle;
    use super::Shape;
    use super::Border;
    use Color;
    use current::Set;

    #[test]
    fn test_rectangle() {
        let _rectangle = Rectangle::new([1.0, ..4])
            .set(Color([0.0, ..4]))
            .set(Shape::Round(10.0))
            .set(Border { color: [0.0, ..4], radius: 4.0 });
    }
}

<|endoftext|>


<commit_before>//! Reminisce is a lightweight library intended to be used for detecting and
//! reading from joysticks.
#![allow(unused_features)]
#![feature(core, std_misc, libc, fs, fs_walk, os, rustc_private, path)]
extern crate libc;
//#[cfg(target_os = "windows")]
#[macro_use] extern crate rustc_bitflags;

#[cfg(feature = "sdl")]
extern crate sdl2;

/// Someday, somehow
#[cfg(target_os = "emscripten")]
mod emscripten;

#[cfg(target_os = "emscripten")]
pub use emscripten as native;

//#[cfg(target_os = "linux")]
//mod linux;

//#[cfg(target_os = "linux")]
//pub use linux as native;

//#[cfg(target_os = "windows")]
mod windows;

//#[cfg(target_os = "windows")]
pub use windows as native;

#[cfg(feature = "sdl")]
mod sdl;

#[cfg(feature = "sdl")]
pub use sdl as native;

pub use native::{NativeJoystick, scan};

/// The maximum axis value
pub static MAX_JOYSTICK_VALUE:i16 = 32767;
/// The minimum axis value
pub static MIN_JOYSTICK_VALUE:i16 = -32767;

use std::mem::transmute as cast;
use std::borrow::Cow;

#[repr(u8)]
#[derive(Copy, Debug, PartialEq, Eq)]
/// A direction on a joystick
pub enum Axis {
	/// The x direction of the left stick
    LeftX,
	/// The y direction of the left stick
    LeftY,
	/// The x direction of the right stick
    RightX,
	/// The y direction of the right stick
    RightY,
	/// How far down the left trigger is pressed
    TriggerLeft,
	/// How far down the right trigger is pressed
    TriggerRight,
}

#[repr(u8)]
#[derive(Copy, Debug, PartialEq, Eq)]
/// A button on a joystick
pub enum Button {
	/// The A button - typically used for jumping
	A,
	/// The B button - typically used for shooting
	B,
	/// The X button
	X,
	/// The Y button
	Y,
	/// The back / select button
	Back,
	/// The guide button
	Guide,
	/// The start button
	Start,
	/// The left stick button
	LeftStick,
	/// The right stick button
	RightStick,
	/// The left shoulder button
	LeftShoulder,
	/// The right shoulder button
	RightShoulder,
	/// The up button on the directional pad
	DPadUp,
	/// The down button on the directional pad
	DPadDown,
	/// The left button on the directional pad
	DPadLeft,
	/// The right button on the directional pad
	DPadRight
}

#[derive(Copy, Debug, Eq, PartialEq)]
/// An event from a joystick
pub enum Event {
	/// Fires when a button is pressed with the button's index
	ButtonPressed(Button),
	/// Fires when a button is released with the button's index
	ButtonReleased(Button),
	/// Fires when a joystick / axis is moved with the axis index and its value,
	/// which is between MIN_JOYSTICK_VALUE and MAX_JOYSTICK_VALUE
	JoystickMoved(Axis, i16)
}
/// Convert a raw event into a Reminisce event
pub trait IntoEvent {
	/// Convert this into a Reminisce event
	fn into_event(self) -> Event;
}

impl IntoEvent for Event {
    fn into_event(self) -> Event {
        self
    }
}

/// A single joystick
pub trait Joystick : Sized {
	/// A joystick that includes the state
	type WithState : StatefulJoystick;

    /// The event that this joystick processes
    type NativeEvent: IntoEvent;

	/// Create a new joystick from its index
	fn new(index: u8) -> Result<Self, &'static str>;

	/// Check if the joystick is still connected
	fn is_connected(&self) -> bool;

	/// Get the identifier of this joystick
    ///
    /// This is a cow because it can be a String
	fn get_id(&self) -> Cow<str>;

	/// Get the index of this joystick
	fn get_index(&self) -> u8;

	/// Get the number of axes this joystick has
	fn get_num_axes(&self) -> u8;

	/// Get the number of buttons this joystick has
	fn get_num_buttons(&self) -> u8;

    /// Get the battery level of this joystick
    ///
    /// Returns none if the joystick is wired or this operation is not supported
    fn get_battery(&self) -> Option<f32>;

    /// Poll the joystick for events in non-blocking mode
	fn poll_native(&mut self) -> Option<Self::NativeEvent>;

    /// Poll the joystick for events in non-blocking mode
    fn poll(&mut self) -> Option<Event> {
        self.poll_native().map(|e| e.into_event())
    }

    /// Iterate through the joystick's event queue in non-blocking mode
    fn iter(&mut self) -> Poller<Self> {
        Poller {
            joystick: self
        }
    }

	/// Get a version of this joystick which includes state
	fn with_state(self) -> Self::WithState;
}
impl Iterator for NativeJoystick {
    type Item = Event;
    fn next(&mut self) -> Option<Event> {
        self.poll()
    }
}

/// A single joystick with its state saved
pub trait StatefulJoystick : Joystick + Sized {
	/// Get the value of a specific axis from its index
	///
	/// Typically the first two of these are the primary analog stick's x and y
	/// co-ordinates
	fn get_axis(&self, index: Axis) -> Option<i16>;

	/// Get the value of a specific axis normalised to between -1.0 and 1.0
	fn get_normalised_axis(&self, index: Axis) -> Option<f32> {
		self.get_axis(index).map(|v| v as f32 / MAX_JOYSTICK_VALUE as f32)
	}

	/// Iterate over the axes in this joystick
	fn axes(&self) -> Axes<Self> {
		use std::mem;
		Axes {
			joystick: self,
			axis: unsafe { mem::zeroed() }
		}
	}

	/// Iterate over the buttons in this joystick
	fn buttons(&self) -> Buttons<Self> {
		use std::mem;
		Buttons {
			joystick: self,
			button: unsafe { mem::zeroed() }
		}
	}

	/// Get the value (if it is pressed or not) of a specific button
	///
	/// The first two buttons are usually the accept and back buttons
	fn get_button(&self, index: Button) -> Option<bool>;

	/// Update the state of this joystick
	fn update(&mut self);
}

/// An iterator over a joystick's axes
pub struct Axes<'a, J> where J:StatefulJoystick+'a {
	joystick: &'a J,
	axis: u8
}
impl<'a, J> Iterator for Axes<'a, J> where J:StatefulJoystick {
	type Item = (Axis, i16);
	fn next(&mut self) -> Option<(Axis, i16)> {
		self.axis += 1;
		let axis = unsafe { cast(self.axis - 1) };
		self.joystick.get_axis(axis).map(|v| (axis, v))
	}
}

/// An iterator over a joystick's buttons
pub struct Buttons<'a, J> where J:StatefulJoystick+'a {
	joystick: &'a J,
	button: u8
}
impl<'a, J> Iterator for Buttons<'a, J> where J:StatefulJoystick {
	type Item = (Button, bool);
	fn next(&mut self) -> Option<(Button, bool)> {
		self.button += 1;
		let button = unsafe { cast(self.button - 1) };
		self.joystick.get_button(button).map(|v| (button, v))
	}
}

/// An iterator over a joystick's event queue
pub struct Poller<'a, J> where J:Joystick+'a {
    joystick: &'a mut J
}

impl<'a, J> Iterator for Poller<'a, J> where J:Joystick {
	type Item = Event;
	fn next(&mut self) -> Option<Event> {
		self.joystick.poll()
	}
}
<commit_msg>Fix non-windows builds<commit_after>//! Reminisce is a lightweight library intended to be used for detecting and
//! reading from joysticks.
#![allow(unused_features)]
#![feature(core, std_misc, libc, fs, fs_walk, os, rustc_private, path)]
extern crate libc;
#[cfg(target_os = "windows")]
#[macro_use] extern crate rustc_bitflags;

#[cfg(feature = "sdl")]
extern crate sdl2;

/// Someday, somehow
#[cfg(target_os = "emscripten")]
mod emscripten;

#[cfg(target_os = "emscripten")]
pub use emscripten as native;

#[cfg(target_os = "linux")]
mod linux;

#[cfg(target_os = "linux")]
pub use linux as native;

#[cfg(target_os = "windows")]
mod windows;

#[cfg(target_os = "windows")]
pub use windows as native;

#[cfg(feature = "sdl")]
mod sdl;

#[cfg(feature = "sdl")]
pub use sdl as native;

pub use native::{NativeJoystick, scan};

/// The maximum axis value
pub static MAX_JOYSTICK_VALUE:i16 = 32767;
/// The minimum axis value
pub static MIN_JOYSTICK_VALUE:i16 = -32767;

use std::mem::transmute as cast;
use std::borrow::Cow;

#[repr(u8)]
#[derive(Copy, Debug, PartialEq, Eq)]
/// A direction on a joystick
pub enum Axis {
	/// The x direction of the left stick
    LeftX,
	/// The y direction of the left stick
    LeftY,
	/// The x direction of the right stick
    RightX,
	/// The y direction of the right stick
    RightY,
	/// How far down the left trigger is pressed
    TriggerLeft,
	/// How far down the right trigger is pressed
    TriggerRight,
}

#[repr(u8)]
#[derive(Copy, Debug, PartialEq, Eq)]
/// A button on a joystick
pub enum Button {
	/// The A button - typically used for jumping
	A,
	/// The B button - typically used for shooting
	B,
	/// The X button
	X,
	/// The Y button
	Y,
	/// The back / select button
	Back,
	/// The guide button
	Guide,
	/// The start button
	Start,
	/// The left stick button
	LeftStick,
	/// The right stick button
	RightStick,
	/// The left shoulder button
	LeftShoulder,
	/// The right shoulder button
	RightShoulder,
	/// The up button on the directional pad
	DPadUp,
	/// The down button on the directional pad
	DPadDown,
	/// The left button on the directional pad
	DPadLeft,
	/// The right button on the directional pad
	DPadRight
}

#[derive(Copy, Debug, Eq, PartialEq)]
/// An event from a joystick
pub enum Event {
	/// Fires when a button is pressed with the button's index
	ButtonPressed(Button),
	/// Fires when a button is released with the button's index
	ButtonReleased(Button),
	/// Fires when a joystick / axis is moved with the axis index and its value,
	/// which is between MIN_JOYSTICK_VALUE and MAX_JOYSTICK_VALUE
	JoystickMoved(Axis, i16)
}
/// Convert a raw event into a Reminisce event
pub trait IntoEvent {
	/// Convert this into a Reminisce event
	fn into_event(self) -> Event;
}

impl IntoEvent for Event {
    fn into_event(self) -> Event {
        self
    }
}

/// A single joystick
pub trait Joystick : Sized {
	/// A joystick that includes the state
	type WithState : StatefulJoystick;

    /// The event that this joystick processes
    type NativeEvent: IntoEvent;

	/// Create a new joystick from its index
	fn new(index: u8) -> Result<Self, &'static str>;

	/// Check if the joystick is still connected
	fn is_connected(&self) -> bool;

	/// Get the identifier of this joystick
    ///
    /// This is a cow because it can be a String
	fn get_id(&self) -> Cow<str>;

	/// Get the index of this joystick
	fn get_index(&self) -> u8;

	/// Get the number of axes this joystick has
	fn get_num_axes(&self) -> u8;

	/// Get the number of buttons this joystick has
	fn get_num_buttons(&self) -> u8;

    /// Get the battery level of this joystick
    ///
    /// Returns none if the joystick is wired or this operation is not supported
    fn get_battery(&self) -> Option<f32>;

    /// Poll the joystick for events in non-blocking mode
	fn poll_native(&mut self) -> Option<Self::NativeEvent>;

    /// Poll the joystick for events in non-blocking mode
    fn poll(&mut self) -> Option<Event> {
        self.poll_native().map(|e| e.into_event())
    }

    /// Iterate through the joystick's event queue in non-blocking mode
    fn iter(&mut self) -> Poller<Self> {
        Poller {
            joystick: self
        }
    }

	/// Get a version of this joystick which includes state
	fn with_state(self) -> Self::WithState;
}
impl Iterator for NativeJoystick {
    type Item = Event;
    fn next(&mut self) -> Option<Event> {
        self.poll()
    }
}

/// A single joystick with its state saved
pub trait StatefulJoystick : Joystick + Sized {
	/// Get the value of a specific axis from its index
	///
	/// Typically the first two of these are the primary analog stick's x and y
	/// co-ordinates
	fn get_axis(&self, index: Axis) -> Option<i16>;

	/// Get the value of a specific axis normalised to between -1.0 and 1.0
	fn get_normalised_axis(&self, index: Axis) -> Option<f32> {
		self.get_axis(index).map(|v| v as f32 / MAX_JOYSTICK_VALUE as f32)
	}

	/// Iterate over the axes in this joystick
	fn axes(&self) -> Axes<Self> {
		use std::mem;
		Axes {
			joystick: self,
			axis: unsafe { mem::zeroed() }
		}
	}

	/// Iterate over the buttons in this joystick
	fn buttons(&self) -> Buttons<Self> {
		use std::mem;
		Buttons {
			joystick: self,
			button: unsafe { mem::zeroed() }
		}
	}

	/// Get the value (if it is pressed or not) of a specific button
	///
	/// The first two buttons are usually the accept and back buttons
	fn get_button(&self, index: Button) -> Option<bool>;

	/// Update the state of this joystick
	fn update(&mut self);
}

/// An iterator over a joystick's axes
pub struct Axes<'a, J> where J:StatefulJoystick+'a {
	joystick: &'a J,
	axis: u8
}
impl<'a, J> Iterator for Axes<'a, J> where J:StatefulJoystick {
	type Item = (Axis, i16);
	fn next(&mut self) -> Option<(Axis, i16)> {
		self.axis += 1;
		let axis = unsafe { cast(self.axis - 1) };
		self.joystick.get_axis(axis).map(|v| (axis, v))
	}
}

/// An iterator over a joystick's buttons
pub struct Buttons<'a, J> where J:StatefulJoystick+'a {
	joystick: &'a J,
	button: u8
}
impl<'a, J> Iterator for Buttons<'a, J> where J:StatefulJoystick {
	type Item = (Button, bool);
	fn next(&mut self) -> Option<(Button, bool)> {
		self.button += 1;
		let button = unsafe { cast(self.button - 1) };
		self.joystick.get_button(button).map(|v| (button, v))
	}
}

/// An iterator over a joystick's event queue
pub struct Poller<'a, J> where J:Joystick+'a {
    joystick: &'a mut J
}

impl<'a, J> Iterator for Poller<'a, J> where J:Joystick {
	type Item = Event;
	fn next(&mut self) -> Option<Event> {
		self.joystick.poll()
	}
}
<|endoftext|>


<commit_before>// Copyright 2017-2022 int08h LLC
//
// 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.

//!
//! Organizes requests and corresponding replies
//!

use std::net::SocketAddr;
use std::time::SystemTime;

use byteorder::{LittleEndian, WriteBytesExt};
use mio::net::UdpSocket;

use crate::{RtMessage, Tag};
use crate::config::ServerConfig;
use crate::grease::Grease;
use crate::key::{LongTermKey, OnlineKey};
use crate::merkle::MerkleTree;
use crate::version::Version;

pub struct Responder {
    version: Version,
    online_key: OnlineKey,
    long_term_public_key: String,
    cert_bytes: Vec<u8>,
    requests: Vec<(Vec<u8>, SocketAddr)>,
    merkle: MerkleTree,
    grease: Grease,
}

impl Responder {
    pub fn new(version: Version, config: &dyn ServerConfig, ltk: &mut LongTermKey) -> Responder {
        let online_key = OnlineKey::new();
        let cert_bytes = ltk.make_cert(&online_key).encode().expect("make_cert");
        let long_term_public_key = hex::encode(ltk.public_key());
        let requests = Vec::with_capacity(config.batch_size() as usize);
        let grease = Grease::new(config.fault_percentage());

        let merkle = if version == Version::Classic {
            MerkleTree::new_sha512()
        } else {
            // MerkleTree::new_sha512_256()
            MerkleTree::new_sha512_256()
        };

        Responder {
            version,
            online_key,
            long_term_public_key,
            cert_bytes,
            merkle,
            requests,
            grease,
        }
    }

    /// Reset internal state to prepare for a new batch of requests
    pub fn reset(&mut self) {
        self.merkle.reset();
        self.requests.clear();
    }

    /// True if there are no requests queued
    pub fn is_empty(&self) -> bool {
        self.requests.is_empty()
    }

    /// Add a request that needs to be responded to
    pub fn add_request(&mut self, nonce: Vec<u8>, src_addr: SocketAddr) {
        self.merkle.push_leaf(&nonce);
        self.requests.push((nonce, src_addr));
    }

    /// Send responses for all queued requests
    pub fn send_responses(&mut self, socket: &mut UdpSocket) {
        if self.is_empty() {
            return;
        }

        let merkle_root = self.merkle.compute_root();

        // The SREP tag is identical for each response
        let srep = self.online_key.make_srep(SystemTime::now(), &merkle_root);

        for (idx, &(ref nonce, ref src_addr)) in self.requests.iter().enumerate() {
            let paths = self.merkle.get_paths(idx);
            let resp_msg = {
                let r = self.make_response(&srep, &self.cert_bytes, &paths, idx as u32);
                if self.grease.should_add_error() {
                    self.grease.add_errors(&r)
                } else {
                    r
                }
            };

            let resp_bytes = match self.version {
                Version::Classic => resp_msg.encode().unwrap(),
                Version::Rfc => resp_msg.encode_framed().unwrap(),
            };

            let bytes_sent = socket
                .send_to(&resp_bytes, &src_addr)
                .expect("send_to failed");

            info!(
                "Responded {} {} bytes to {} for '{}..' (#{} in batch)",
                self.version,
                bytes_sent,
                src_addr,
                hex::encode(&nonce[0..4]),
                idx + 1,
            );
        }
    }

    fn make_response(
        &self,
        srep: &RtMessage,
        cert_bytes: &[u8],
        path: &[u8],
        idx: u32,
    ) -> RtMessage {
        let mut index = [0; 4];
        (&mut index as &mut [u8])
            .write_u32::<LittleEndian>(idx)
            .unwrap();

        let sig_bytes = srep.get_field(Tag::SIG).unwrap();
        let srep_bytes = srep.get_field(Tag::SREP).unwrap();

        let mut response = RtMessage::with_capacity(6);
        response.add_field(Tag::SIG, sig_bytes).unwrap();

        if self.version == Version::Rfc {
            response
                .add_field(Tag::VER, self.version.wire_bytes())
                .unwrap();
        }

        response.add_field(Tag::PATH, path).unwrap();
        response.add_field(Tag::SREP, srep_bytes).unwrap();
        response.add_field(Tag::CERT, cert_bytes).unwrap();
        response.add_field(Tag::INDX, &index).unwrap();

        response
    }

    /// Returns a reference to the long-term public key
    pub fn get_public_key(&self) -> &str {
        &self.long_term_public_key
    }

    /// Returns a reference to the on-line (delegated) key
    pub fn get_online_key(&self) -> &OnlineKey {
        &self.online_key
    }
}
<commit_msg>Superfluous comment<commit_after>// Copyright 2017-2022 int08h LLC
//
// 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.

//!
//! Organizes requests and corresponding replies
//!

use std::net::SocketAddr;
use std::time::SystemTime;

use byteorder::{LittleEndian, WriteBytesExt};
use mio::net::UdpSocket;

use crate::{RtMessage, Tag};
use crate::config::ServerConfig;
use crate::grease::Grease;
use crate::key::{LongTermKey, OnlineKey};
use crate::merkle::MerkleTree;
use crate::version::Version;

pub struct Responder {
    version: Version,
    online_key: OnlineKey,
    long_term_public_key: String,
    cert_bytes: Vec<u8>,
    requests: Vec<(Vec<u8>, SocketAddr)>,
    merkle: MerkleTree,
    grease: Grease,
}

impl Responder {
    pub fn new(version: Version, config: &dyn ServerConfig, ltk: &mut LongTermKey) -> Responder {
        let online_key = OnlineKey::new();
        let cert_bytes = ltk.make_cert(&online_key).encode().expect("make_cert");
        let long_term_public_key = hex::encode(ltk.public_key());
        let requests = Vec::with_capacity(config.batch_size() as usize);
        let grease = Grease::new(config.fault_percentage());

        let merkle = if version == Version::Classic {
            MerkleTree::new_sha512()
        } else {
            MerkleTree::new_sha512_256()
        };

        Responder {
            version,
            online_key,
            long_term_public_key,
            cert_bytes,
            merkle,
            requests,
            grease,
        }
    }

    /// Reset internal state to prepare for a new batch of requests
    pub fn reset(&mut self) {
        self.merkle.reset();
        self.requests.clear();
    }

    /// True if there are no requests queued
    pub fn is_empty(&self) -> bool {
        self.requests.is_empty()
    }

    /// Add a request that needs to be responded to
    pub fn add_request(&mut self, nonce: Vec<u8>, src_addr: SocketAddr) {
        self.merkle.push_leaf(&nonce);
        self.requests.push((nonce, src_addr));
    }

    /// Send responses for all queued requests
    pub fn send_responses(&mut self, socket: &mut UdpSocket) {
        if self.is_empty() {
            return;
        }

        let merkle_root = self.merkle.compute_root();

        // The SREP tag is identical for each response
        let srep = self.online_key.make_srep(SystemTime::now(), &merkle_root);

        for (idx, &(ref nonce, ref src_addr)) in self.requests.iter().enumerate() {
            let paths = self.merkle.get_paths(idx);
            let resp_msg = {
                let r = self.make_response(&srep, &self.cert_bytes, &paths, idx as u32);
                if self.grease.should_add_error() {
                    self.grease.add_errors(&r)
                } else {
                    r
                }
            };

            let resp_bytes = match self.version {
                Version::Classic => resp_msg.encode().unwrap(),
                Version::Rfc => resp_msg.encode_framed().unwrap(),
            };

            let bytes_sent = socket
                .send_to(&resp_bytes, &src_addr)
                .expect("send_to failed");

            info!(
                "Responded {} {} bytes to {} for '{}..' (#{} in batch)",
                self.version,
                bytes_sent,
                src_addr,
                hex::encode(&nonce[0..4]),
                idx + 1,
            );
        }
    }

    fn make_response(
        &self,
        srep: &RtMessage,
        cert_bytes: &[u8],
        path: &[u8],
        idx: u32,
    ) -> RtMessage {
        let mut index = [0; 4];
        (&mut index as &mut [u8])
            .write_u32::<LittleEndian>(idx)
            .unwrap();

        let sig_bytes = srep.get_field(Tag::SIG).unwrap();
        let srep_bytes = srep.get_field(Tag::SREP).unwrap();

        let mut response = RtMessage::with_capacity(6);
        response.add_field(Tag::SIG, sig_bytes).unwrap();

        if self.version == Version::Rfc {
            response
                .add_field(Tag::VER, self.version.wire_bytes())
                .unwrap();
        }

        response.add_field(Tag::PATH, path).unwrap();
        response.add_field(Tag::SREP, srep_bytes).unwrap();
        response.add_field(Tag::CERT, cert_bytes).unwrap();
        response.add_field(Tag::INDX, &index).unwrap();

        response
    }

    /// Returns a reference to the long-term public key
    pub fn get_public_key(&self) -> &str {
        &self.long_term_public_key
    }

    /// Returns a reference to the on-line (delegated) key
    pub fn get_online_key(&self) -> &OnlineKey {
        &self.online_key
    }
}
<|endoftext|>


<commit_before><commit_msg>WIP Config struct.<commit_after>// In heavy WIP

#[derive(Deserialize)]
struct Config {
    download_path: String
}<|endoftext|>


<commit_before>use job::{Job, JobMode, JobRef};
use std::any::Any;
use std::cell::UnsafeCell;
use std::marker::PhantomData;
use std::mem;
use std::ptr;
use std::sync::atomic::{AtomicUsize, AtomicPtr, Ordering};
use std::sync::{Condvar, Mutex};
use thread_pool::{self, WorkerThread};
use unwind;

#[cfg(test)]
mod test;

pub struct Scope<'scope> {
    /// number of jobs created that have not yet completed or errored
    counter: AtomicUsize,

    /// if `#[cfg(debug_assertions)]`, then this counter is
    /// incremented in `HeapJob::new` and decremented in
    /// `HeapJob::drop`. When the scope is closed we assert that it is
    /// zero. It is used to check that we are freeing every heap job.
    leak_counter: AtomicUsize,

    /// if some job panicked, the error is stored here; it will be
    /// propagated to the one who created the scope
    panic: AtomicPtr<Box<Any + Send + 'static>>,

    /// mutex that is used in conjunction with `job_completed_cvar` below
    mutex: Mutex<()>,

    /// condition variable that is notified whenever jobs complete;
    /// used to block while waiting for jobs to complete
    job_completed_cvar: Condvar,

    marker: PhantomData<fn(&'scope ())>,
}

/// Create a "fork-join" scope `s` and invokes the closure with a
/// reference to `s`. This closure can then spawn asynchronous tasks
/// into `s`. Those tasks may run asynchronously with respect to the
/// closure; they may themselves spawn additional tasks into `s`. When
/// the closure returns, it will block until all tasks that have been
/// spawned into `s` complete.
///
/// `scope()` is a more flexible building block compared to `join()`,
/// since a loop can be used to spawn any number of tasks without
/// recursing. However, that flexibility comes at a performance price:
/// tasks spawned using `scope()` must be allocated onto the heap,
/// whereas `join()` can make exclusive use of the stack. **Prefer
/// `join()` (or, even better, parallel iterators) where possible.**
///
/// ### Example
///
/// The Rayon `join()` function launches two closures and waits for them
/// to stop. One could implement `join()` using a scope like so, although
/// it would be less efficient than the real implementation:
///
/// ```rust
/// pub fn join<A,B,RA,RB>(oper_a: A, oper_b: B) -> (RA, RB)
///     where A: FnOnce() -> RA + Send,
///           B: FnOnce() -> RB + Send,
///           RA: Send,
///           RB: Send,
/// {
///     let mut result_a: Option<RA> = None;
///     let mut result_b: Option<RB> = None;
///     rayon::scope(|s| {
///         s.spawn(|_| result_a = Some(oper_a()));
///         s.spawn(|_| result_b = Some(oper_b()));
///     });
///     (result_a.unwrap(), result_b.unwrap())
/// }
/// ```
///
/// ### Task execution
///
/// To see how and when tasks are joined, consider this example:
///
/// ```rust
/// // point start
/// rayon::scope(|s| {
///     s.spawn(|s| { // task s.1
///         s.spawn(|s| { // task s.1.1
///             rayon::scope(|t| {
///                 t.spawn(|_| ()); // task t.1
///                 t.spawn(|_| ()); // task t.2
///             });
///         });
///     });
///     s.spawn(|s| { // task 2
///     });
///     // point mid
/// });
/// // point end
/// ```
///
/// The various tasks that are run will execute roughly like so:
///
/// ```notrust
/// | (start)
/// |
/// | (scope `s` created)
/// +--------------------+ (task s.1)
/// +-------+ (task s.2) |
/// |       |            +---+ (task s.1.1)
/// |       |            |   |
/// |       |            |   | (scope `t` created)
/// |       |            |   +----------------+ (task t.1)
/// |       |            |   +---+ (task t.2) |
/// | (mid) |            |   |   |            |
/// :       |            |   + <-+------------+ (scope `t` ends)
/// :       |            |   |
/// |<------+------------+---+ (scope `s` ends)
/// |
/// | (end)
/// ```
///
/// The point here is that everything spawned into scope `s` will
/// terminate (at latest) at the same point -- right before the
/// original call to `rayon::scope` returns. This includes new
/// subtasks created by other subtasks (e.g., task `s.1.1`). If a new
/// scope is created (such as `t`), the things spawned into that scope
/// will be joined before that scope returns, which in turn occurs
/// before the creating task (task `s.1.1` in this case) finishes.
///
/// ### Accessing stack data
///
/// In general, spawned tasks may access stack data in place that
/// outlives the scope itself. Other data must be fully owned by the
/// spawned task.
///
/// ```rust
/// let ok: Vec<i32> = vec![1, 2, 3];
/// rayon::scope(|s| {
///     let bad: Vec<i32> = vec![4, 5, 6];
///     s.spawn(|_| {
///         // We can access `ok` because outlives the scope `s`.
///         println!("ok: {:?}", ok);
///
///         // If we just try to use `bad` here, the closure will borrow `bad`
///         // (because we are just printing it out, and that only requires a
///         // borrow), which will result in a compilation error. Read on
///         // for options.
///         // println!("bad: {:?}", bad);
///    });
/// });
/// ```
///
/// As the comments example above suggest, to reference `bad` we must
/// take ownership of it. One way to do this is to detach the closure
/// from the surrounding stack frame, using the `move` keyword. This
/// will cause it to take ownership of *all* the variables it touches,
/// in this case including both `ok` *and* `bad`:
///
/// ```rust
/// let ok: Vec<i32> = vec![1, 2, 3];
/// rayon::scope(|s| {
///     let bad: Vec<i32> = vec![4, 5, 6];
///     s.spawn(move |_| {
///         println!("ok: {:?}", ok);
///         println!("bad: {:?}", bad);
///     });
///
///     // That closure is fine, but now we can't use `ok` anywhere else,
///     // since it is owend by the previous task:
///     // s.spawn(|_| println!("ok: {:?}", ok));
/// });
/// ```
///
/// While this works, it could be a problem if we want to use `ok` elsewhere.
/// There are two choices. We can keep the closure as a `move` closure, but
/// instead of referencing the variable `ok`, we create a shadowed variable that
/// is a borrow of `ok` and capture *that*:
///
/// ```rust
/// let ok: Vec<i32> = vec![1, 2, 3];
/// rayon::scope(|s| {
///     let bad: Vec<i32> = vec![4, 5, 6];
///     let ok: &Vec<i32> = &ok; // shadow the original `ok`
///     s.spawn(move |_| {
///         println!("ok: {:?}", ok); // captures the shadowed version
///         println!("bad: {:?}", bad);
///     });
///
///     // Now we too can use the shadowed `ok`, since `&Vec<i32>` references
///     // can be shared freely. Note that we need a `move` closure here though,
///     // because otherwise we'd be trying to borrow the shadowed `ok`,
///     // and that doesn't outlive `scope`.
///     s.spawn(move |_| println!("ok: {:?}", ok));
/// });
/// ```
///
/// Another option is not to use the `move` keyword but instead to take ownership
/// of individual variables:
///
/// ```rust
/// let ok: Vec<i32> = vec![1, 2, 3];
/// rayon::scope(|s| {
///     let bad: Vec<i32> = vec![4, 5, 6];
///     s.spawn(|_| {
///         // Transfer ownership of `bad` into a local variable (also named `bad`).
///         // This will force the closure to take ownership of `bad` from the environment.
///         let bad = bad;
///         println!("ok: {:?}", ok); // `ok` is only borrowed.
///         println!("bad: {:?}", bad); // refers to our local variable, above.
///     });
///
///     s.spawn(|_| println!("ok: {:?}", ok)); // we too can borrow `ok`
/// });
/// ```
pub fn scope<'scope, OP, R>(op: OP) -> R
    where OP: for<'s> FnOnce(&'s Scope<'scope>) -> R
{
    let scope = Scope {
        counter: AtomicUsize::new(1),
        leak_counter: AtomicUsize::new(0),
        panic: AtomicPtr::new(ptr::null_mut()),
        mutex: Mutex::new(()),
        job_completed_cvar: Condvar::new(),
        marker: PhantomData,
    };
    if false { scope.fool_dead_code(); }
    let result = op(&scope);
    scope.job_completed_ok(); // `op` counts as a job
    scope.block_till_jobs_complete();
    result
}

impl<'scope> Scope<'scope> {
    /// just here to full the dead_code lint
    fn fool_dead_code(&self) {
        self.leak_counter.fetch_add(1, Ordering::SeqCst);
    }

    /// Spawns a job into the fork-join scope `self`. This job will
    /// execute sometime before the fork-join scope completes.  The
    /// job is specified as a closure, and this closure receives its
    /// own reference to `self` as argument. This can be used to
    /// inject new jobs into `self`.
    pub fn spawn<BODY>(&self, body: BODY)
        where BODY: FnOnce(&Scope<'scope>) + 'scope
    {
        unsafe {
            let old_value = self.counter.fetch_add(1, Ordering::SeqCst);
            assert!(old_value > 0); // scope can't have completed yet
            let job_ref = Box::new(HeapJob::new(self, body)).as_job_ref();
            let worker_thread = WorkerThread::current();
            if !worker_thread.is_null() {
                let worker_thread = &*worker_thread;
                let spawn_count = worker_thread.spawn_count();
                spawn_count.set(spawn_count.get() + 1);
                worker_thread.push(job_ref);
            } else {
                thread_pool::get_registry().inject(&[job_ref]);
            }
        }
    }

    fn job_panicked(&self, err: Box<Any + Send + 'static>) {
        // capture the first error we see, free the rest
        let nil = ptr::null_mut();
        let mut err = Box::new(err); // box up the fat ptr
        if self.panic.compare_and_swap(nil, &mut *err, Ordering::SeqCst).is_null() {
            mem::forget(err); // ownership now transferred into self.panic
        }

        self.job_completed_ok()
    }

    fn job_completed_ok(&self) {
        let old_value = self.counter.fetch_sub(1, Ordering::Release);
        if old_value == 1 {
            // Important: grab the lock here to avoid a data race with
            // the `block_till_jobs_complete` code. Consider what could
            // otherwise happen:
            //
            // ```
            //    Us          Them
            //              Acquire lock
            //              Read counter: 1
            // Dec counter
            // Notify all
            //              Wait on job_completed_cvar
            // ```
            //
            // By holding the lock, we ensure that the "read counter"
            // and "wait on job_completed_cvar" occur atomically with respect to the
            // notify.
            let _guard = self.mutex.lock().unwrap();
            self.job_completed_cvar.notify_all();
        }
    }

    fn block_till_jobs_complete(&self) {
        // wait for job counter to reach 0:
        //
        // FIXME -- if on a worker thread, we should be helping here
        let mut guard = self.mutex.lock().unwrap();
        while self.counter.load(Ordering::Acquire) > 0 {
            guard = self.job_completed_cvar.wait(guard).unwrap();
        }

        // at this point, we should also have freed all HeapJob that we built
        debug_assert!(self.leak_counter.load(Ordering::SeqCst) == 0,
                      "{} spawned jobs leaked",
                      self.leak_counter.load(Ordering::SeqCst));

        // propagate panic, if any occurred; at this point, all
        // outstanding jobs have completed, so we can use a relaxed
        // ordering:
        let panic = self.panic.swap(ptr::null_mut(), Ordering::Relaxed);
        if !panic.is_null() {
            unsafe {
                let value: Box<Box<Any + Send + 'static>> = mem::transmute(panic);
                unwind::resume_unwinding(*value);
            }
        }
    }

    #[cfg(debug_assertions)]
    fn job_created(&self) {
        self.leak_counter.fetch_add(1, Ordering::SeqCst);
    }

    #[cfg(not(debug_assertions))]
    fn job_created(&self) {
    }

    #[cfg(debug_assertions)]
    fn job_dropped(&self) {
        self.leak_counter.fetch_sub(1, Ordering::SeqCst);
    }
}

struct HeapJob<'scope, BODY>
    where BODY: FnOnce(&Scope<'scope>) + 'scope,
{
    scope: *const Scope<'scope>,
    func: UnsafeCell<Option<BODY>>,
}

impl<'scope, BODY> HeapJob<'scope, BODY>
    where BODY: FnOnce(&Scope<'scope>) + 'scope
{
    fn new(scope: *const Scope<'scope>, func: BODY) -> Self {
        unsafe { (*scope).job_created(); }
        HeapJob {
            scope: scope,
            func: UnsafeCell::new(Some(func))
        }
    }

    unsafe fn as_job_ref(self: Box<Self>) -> JobRef {
        let this: *const Self = mem::transmute(self);
        JobRef::new(this)
    }

    /// We have to maintain an invariant that we pop off any work
    /// that we pushed onto the local thread deque. In other words,
    /// if no thieves are at play, then the height of the local
    /// deque must be the same when we enter and exit. Otherwise,
    /// we get into trouble composing with the main `join` API,
    /// which assumes that -- after it executes the first closure
    /// -- the top-most thing on the stack is the second closure.
    unsafe fn pop_jobs(worker_thread: &WorkerThread, start_count: usize) {
        let spawn_count = worker_thread.spawn_count();
        let current_count = spawn_count.get();
        for _ in start_count .. current_count {
            if let Some(job_ref) = worker_thread.pop() {
                job_ref.execute(JobMode::Execute);
            }
        }
        spawn_count.set(start_count);
    }
}

impl<'scope, BODY> Job for HeapJob<'scope, BODY>
    where BODY: FnOnce(&Scope<'scope>) + 'scope
{
    unsafe fn execute(this: *const Self, mode: JobMode) {
        let this: Box<Self> = mem::transmute(this);
        let scope = &*this.scope;

        match mode {
            JobMode::Execute => {
                let worker_thread = &*WorkerThread::current();
                let start_count = worker_thread.spawn_count().get();

                let func = (*this.func.get()).take().unwrap();
                match unwind::halt_unwinding(|| func(&*scope)) {
                    Ok(()) => { (*scope).job_completed_ok(); }
                    Err(err) => { (*scope).job_panicked(err); }
                }

                Self::pop_jobs(worker_thread, start_count);
            }

            JobMode::Abort => {
                (*this.scope).job_completed_ok();
            }
        }
    }
}

#[cfg(debug_assertions)]
impl<'scope, BODY> Drop for HeapJob<'scope, BODY>
    where BODY: FnOnce(&Scope<'scope>) + 'scope
{
    fn drop(&mut self) {
        unsafe {
            (*self.scope).job_dropped();
        }
    }
}
<commit_msg>drop leak detection, which was racy<commit_after>use job::{Job, JobMode, JobRef};
use std::any::Any;
use std::cell::UnsafeCell;
use std::marker::PhantomData;
use std::mem;
use std::ptr;
use std::sync::atomic::{AtomicUsize, AtomicPtr, Ordering};
use std::sync::{Condvar, Mutex};
use thread_pool::{self, WorkerThread};
use unwind;

#[cfg(test)]
mod test;

pub struct Scope<'scope> {
    /// number of jobs created that have not yet completed or errored
    counter: AtomicUsize,

    /// if some job panicked, the error is stored here; it will be
    /// propagated to the one who created the scope
    panic: AtomicPtr<Box<Any + Send + 'static>>,

    /// mutex that is used in conjunction with `job_completed_cvar` below
    mutex: Mutex<()>,

    /// condition variable that is notified whenever jobs complete;
    /// used to block while waiting for jobs to complete
    job_completed_cvar: Condvar,

    marker: PhantomData<fn(&'scope ())>,
}

/// Create a "fork-join" scope `s` and invokes the closure with a
/// reference to `s`. This closure can then spawn asynchronous tasks
/// into `s`. Those tasks may run asynchronously with respect to the
/// closure; they may themselves spawn additional tasks into `s`. When
/// the closure returns, it will block until all tasks that have been
/// spawned into `s` complete.
///
/// `scope()` is a more flexible building block compared to `join()`,
/// since a loop can be used to spawn any number of tasks without
/// recursing. However, that flexibility comes at a performance price:
/// tasks spawned using `scope()` must be allocated onto the heap,
/// whereas `join()` can make exclusive use of the stack. **Prefer
/// `join()` (or, even better, parallel iterators) where possible.**
///
/// ### Example
///
/// The Rayon `join()` function launches two closures and waits for them
/// to stop. One could implement `join()` using a scope like so, although
/// it would be less efficient than the real implementation:
///
/// ```rust
/// pub fn join<A,B,RA,RB>(oper_a: A, oper_b: B) -> (RA, RB)
///     where A: FnOnce() -> RA + Send,
///           B: FnOnce() -> RB + Send,
///           RA: Send,
///           RB: Send,
/// {
///     let mut result_a: Option<RA> = None;
///     let mut result_b: Option<RB> = None;
///     rayon::scope(|s| {
///         s.spawn(|_| result_a = Some(oper_a()));
///         s.spawn(|_| result_b = Some(oper_b()));
///     });
///     (result_a.unwrap(), result_b.unwrap())
/// }
/// ```
///
/// ### Task execution
///
/// To see how and when tasks are joined, consider this example:
///
/// ```rust
/// // point start
/// rayon::scope(|s| {
///     s.spawn(|s| { // task s.1
///         s.spawn(|s| { // task s.1.1
///             rayon::scope(|t| {
///                 t.spawn(|_| ()); // task t.1
///                 t.spawn(|_| ()); // task t.2
///             });
///         });
///     });
///     s.spawn(|s| { // task 2
///     });
///     // point mid
/// });
/// // point end
/// ```
///
/// The various tasks that are run will execute roughly like so:
///
/// ```notrust
/// | (start)
/// |
/// | (scope `s` created)
/// +--------------------+ (task s.1)
/// +-------+ (task s.2) |
/// |       |            +---+ (task s.1.1)
/// |       |            |   |
/// |       |            |   | (scope `t` created)
/// |       |            |   +----------------+ (task t.1)
/// |       |            |   +---+ (task t.2) |
/// | (mid) |            |   |   |            |
/// :       |            |   + <-+------------+ (scope `t` ends)
/// :       |            |   |
/// |<------+------------+---+ (scope `s` ends)
/// |
/// | (end)
/// ```
///
/// The point here is that everything spawned into scope `s` will
/// terminate (at latest) at the same point -- right before the
/// original call to `rayon::scope` returns. This includes new
/// subtasks created by other subtasks (e.g., task `s.1.1`). If a new
/// scope is created (such as `t`), the things spawned into that scope
/// will be joined before that scope returns, which in turn occurs
/// before the creating task (task `s.1.1` in this case) finishes.
///
/// ### Accessing stack data
///
/// In general, spawned tasks may access stack data in place that
/// outlives the scope itself. Other data must be fully owned by the
/// spawned task.
///
/// ```rust
/// let ok: Vec<i32> = vec![1, 2, 3];
/// rayon::scope(|s| {
///     let bad: Vec<i32> = vec![4, 5, 6];
///     s.spawn(|_| {
///         // We can access `ok` because outlives the scope `s`.
///         println!("ok: {:?}", ok);
///
///         // If we just try to use `bad` here, the closure will borrow `bad`
///         // (because we are just printing it out, and that only requires a
///         // borrow), which will result in a compilation error. Read on
///         // for options.
///         // println!("bad: {:?}", bad);
///    });
/// });
/// ```
///
/// As the comments example above suggest, to reference `bad` we must
/// take ownership of it. One way to do this is to detach the closure
/// from the surrounding stack frame, using the `move` keyword. This
/// will cause it to take ownership of *all* the variables it touches,
/// in this case including both `ok` *and* `bad`:
///
/// ```rust
/// let ok: Vec<i32> = vec![1, 2, 3];
/// rayon::scope(|s| {
///     let bad: Vec<i32> = vec![4, 5, 6];
///     s.spawn(move |_| {
///         println!("ok: {:?}", ok);
///         println!("bad: {:?}", bad);
///     });
///
///     // That closure is fine, but now we can't use `ok` anywhere else,
///     // since it is owend by the previous task:
///     // s.spawn(|_| println!("ok: {:?}", ok));
/// });
/// ```
///
/// While this works, it could be a problem if we want to use `ok` elsewhere.
/// There are two choices. We can keep the closure as a `move` closure, but
/// instead of referencing the variable `ok`, we create a shadowed variable that
/// is a borrow of `ok` and capture *that*:
///
/// ```rust
/// let ok: Vec<i32> = vec![1, 2, 3];
/// rayon::scope(|s| {
///     let bad: Vec<i32> = vec![4, 5, 6];
///     let ok: &Vec<i32> = &ok; // shadow the original `ok`
///     s.spawn(move |_| {
///         println!("ok: {:?}", ok); // captures the shadowed version
///         println!("bad: {:?}", bad);
///     });
///
///     // Now we too can use the shadowed `ok`, since `&Vec<i32>` references
///     // can be shared freely. Note that we need a `move` closure here though,
///     // because otherwise we'd be trying to borrow the shadowed `ok`,
///     // and that doesn't outlive `scope`.
///     s.spawn(move |_| println!("ok: {:?}", ok));
/// });
/// ```
///
/// Another option is not to use the `move` keyword but instead to take ownership
/// of individual variables:
///
/// ```rust
/// let ok: Vec<i32> = vec![1, 2, 3];
/// rayon::scope(|s| {
///     let bad: Vec<i32> = vec![4, 5, 6];
///     s.spawn(|_| {
///         // Transfer ownership of `bad` into a local variable (also named `bad`).
///         // This will force the closure to take ownership of `bad` from the environment.
///         let bad = bad;
///         println!("ok: {:?}", ok); // `ok` is only borrowed.
///         println!("bad: {:?}", bad); // refers to our local variable, above.
///     });
///
///     s.spawn(|_| println!("ok: {:?}", ok)); // we too can borrow `ok`
/// });
/// ```
pub fn scope<'scope, OP, R>(op: OP) -> R
    where OP: for<'s> FnOnce(&'s Scope<'scope>) -> R
{
    let scope = Scope {
        counter: AtomicUsize::new(1),
        panic: AtomicPtr::new(ptr::null_mut()),
        mutex: Mutex::new(()),
        job_completed_cvar: Condvar::new(),
        marker: PhantomData,
    };
    let result = op(&scope);
    scope.job_completed_ok(); // `op` counts as a job
    scope.block_till_jobs_complete();
    result
}

impl<'scope> Scope<'scope> {
    /// Spawns a job into the fork-join scope `self`. This job will
    /// execute sometime before the fork-join scope completes.  The
    /// job is specified as a closure, and this closure receives its
    /// own reference to `self` as argument. This can be used to
    /// inject new jobs into `self`.
    pub fn spawn<BODY>(&self, body: BODY)
        where BODY: FnOnce(&Scope<'scope>) + 'scope
    {
        unsafe {
            let old_value = self.counter.fetch_add(1, Ordering::SeqCst);
            assert!(old_value > 0); // scope can't have completed yet
            let job_ref = Box::new(HeapJob::new(self, body)).as_job_ref();
            let worker_thread = WorkerThread::current();
            if !worker_thread.is_null() {
                let worker_thread = &*worker_thread;
                let spawn_count = worker_thread.spawn_count();
                spawn_count.set(spawn_count.get() + 1);
                worker_thread.push(job_ref);
            } else {
                thread_pool::get_registry().inject(&[job_ref]);
            }
        }
    }

    fn job_panicked(&self, err: Box<Any + Send + 'static>) {
        // capture the first error we see, free the rest
        let nil = ptr::null_mut();
        let mut err = Box::new(err); // box up the fat ptr
        if self.panic.compare_and_swap(nil, &mut *err, Ordering::SeqCst).is_null() {
            mem::forget(err); // ownership now transferred into self.panic
        }

        self.job_completed_ok()
    }

    fn job_completed_ok(&self) {
        let old_value = self.counter.fetch_sub(1, Ordering::Release);
        if old_value == 1 {
            // Important: grab the lock here to avoid a data race with
            // the `block_till_jobs_complete` code. Consider what could
            // otherwise happen:
            //
            // ```
            //    Us          Them
            //              Acquire lock
            //              Read counter: 1
            // Dec counter
            // Notify all
            //              Wait on job_completed_cvar
            // ```
            //
            // By holding the lock, we ensure that the "read counter"
            // and "wait on job_completed_cvar" occur atomically with respect to the
            // notify.
            let _guard = self.mutex.lock().unwrap();
            self.job_completed_cvar.notify_all();
        }
    }

    fn block_till_jobs_complete(&self) {
        // wait for job counter to reach 0:
        //
        // FIXME -- if on a worker thread, we should be helping here
        let mut guard = self.mutex.lock().unwrap();
        while self.counter.load(Ordering::Acquire) > 0 {
            guard = self.job_completed_cvar.wait(guard).unwrap();
        }

        // propagate panic, if any occurred; at this point, all
        // outstanding jobs have completed, so we can use a relaxed
        // ordering:
        let panic = self.panic.swap(ptr::null_mut(), Ordering::Relaxed);
        if !panic.is_null() {
            unsafe {
                let value: Box<Box<Any + Send + 'static>> = mem::transmute(panic);
                unwind::resume_unwinding(*value);
            }
        }
    }
}

struct HeapJob<'scope, BODY>
    where BODY: FnOnce(&Scope<'scope>) + 'scope,
{
    scope: *const Scope<'scope>,
    func: UnsafeCell<Option<BODY>>,
}

impl<'scope, BODY> HeapJob<'scope, BODY>
    where BODY: FnOnce(&Scope<'scope>) + 'scope
{
    fn new(scope: *const Scope<'scope>, func: BODY) -> Self {
        HeapJob {
            scope: scope,
            func: UnsafeCell::new(Some(func))
        }
    }

    unsafe fn as_job_ref(self: Box<Self>) -> JobRef {
        let this: *const Self = mem::transmute(self);
        JobRef::new(this)
    }

    /// We have to maintain an invariant that we pop off any work
    /// that we pushed onto the local thread deque. In other words,
    /// if no thieves are at play, then the height of the local
    /// deque must be the same when we enter and exit. Otherwise,
    /// we get into trouble composing with the main `join` API,
    /// which assumes that -- after it executes the first closure
    /// -- the top-most thing on the stack is the second closure.
    unsafe fn pop_jobs(worker_thread: &WorkerThread, start_count: usize) {
        let spawn_count = worker_thread.spawn_count();
        let current_count = spawn_count.get();
        for _ in start_count .. current_count {
            if let Some(job_ref) = worker_thread.pop() {
                job_ref.execute(JobMode::Execute);
            }
        }
        spawn_count.set(start_count);
    }
}

impl<'scope, BODY> Job for HeapJob<'scope, BODY>
    where BODY: FnOnce(&Scope<'scope>) + 'scope
{
    unsafe fn execute(this: *const Self, mode: JobMode) {
        let this: Box<Self> = mem::transmute(this);
        let scope = &*this.scope;

        match mode {
            JobMode::Execute => {
                let worker_thread = &*WorkerThread::current();
                let start_count = worker_thread.spawn_count().get();

                let func = (*this.func.get()).take().unwrap();
                match unwind::halt_unwinding(|| func(&*scope)) {
                    Ok(()) => { (*scope).job_completed_ok(); }
                    Err(err) => { (*scope).job_panicked(err); }
                }

                Self::pop_jobs(worker_thread, start_count);
            }

            JobMode::Abort => {
                (*this.scope).job_completed_ok();
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Factor out the setup from timetable ingestion.<commit_after><|endoftext|>


<commit_before>// pest. The Elegant Parser
// Copyright (c) 2018 Dragoș Tiselice
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

use std::fmt;
use std::hash::{Hash, Hasher};
use std::ptr;
use std::rc::Rc;
use std::str;

use super::flat_pairs::{self, FlatPairs};
use super::pair::{self, Pair};
use super::queueable_token::QueueableToken;
use super::tokens::{self, Tokens};
use RuleType;

/// An iterator over [`Pair`]s. It is created by [`pest::state`] and [`Pair::into_inner`].
///
/// [`Pair`]: struct.Pair.html
/// [`pest::state`]: ../fn.state.html
/// [`Pair::into_inner`]: struct.Pair.html#method.into_inner
#[derive(Clone)]
pub struct Pairs<'i, R> {
    queue: Rc<Vec<QueueableToken<R>>>,
    input: &'i [u8],
    start: usize,
    end: usize
}

pub fn new<R: RuleType>(
    queue: Rc<Vec<QueueableToken<R>>>,
    input: &[u8],
    start: usize,
    end: usize
) -> Pairs<R> {
    Pairs {
        queue,
        input,
        start,
        end
    }
}

impl<'i, R: RuleType> Pairs<'i, R> {
    /// Captures a slice from the `&str` defined by the starting position of the first token `Pair`
    /// and the ending position of the last token `Pair` of the `Pairs`. This also captures
    /// the input between those two token `Pair`s.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::rc::Rc;
    /// # use pest;
    /// # #[allow(non_camel_case_types)]
    /// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
    /// enum Rule {
    ///     a,
    ///     b
    /// }
    ///
    /// let input = "a b";
    /// let pairs = pest::state(input, |state| {
    ///     // generating Token pairs with Rule::a and Rule::b ...
    /// #     state.rule(Rule::a, |s| s.match_string("a")).and_then(|s| s.skip(1))
    /// #         .and_then(|s| s.rule(Rule::b, |s| s.match_string("b")))
    /// }).unwrap();
    ///
    /// assert_eq!(pairs.as_str(), "a b");
    /// ```
    #[inline]
    pub fn as_str(&self) -> &'i str {
        let start = self.pos(self.start);
        let end = self.pos(self.end - 1);

        // Generated positions always come from Positions and are UTF-8 borders.
        unsafe { str::from_utf8_unchecked(&self.input[start..end]) }
    }

    /// Captures inner token `Pair`s and concatenates resulting `&str`s. This does not capture
    /// the input between token `Pair`s.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::rc::Rc;
    /// # use pest;
    /// # #[allow(non_camel_case_types)]
    /// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
    /// enum Rule {
    ///     a,
    ///     b
    /// }
    ///
    /// let input = "a b";
    /// let pairs = pest::state(input, |state| {
    ///     // generating Token pairs with Rule::a and Rule::b ...
    /// #     state.rule(Rule::a, |s| s.match_string("a")).and_then(|s| s.skip(1))
    /// #         .and_then(|s| s.rule(Rule::b, |s| s.match_string("b")))
    /// }).unwrap();
    ///
    /// assert_eq!(pairs.concat(), "ab");
    /// ```
    #[inline]
    pub fn concat(&self) -> String {
        self.clone().fold(String::new(), |string, pair| string + pair.as_str())
    }

    /// Flattens the `Pairs`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::rc::Rc;
    /// # use pest;
    /// # #[allow(non_camel_case_types)]
    /// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
    /// enum Rule {
    ///     a,
    ///     b
    /// }
    ///
    /// let input = "";
    /// let pairs = pest::state(input, |state| {
    ///     // generating nested Token pair with Rule::b inside Rule::a
    /// #     state.rule(Rule::a, |state| {
    /// #         state.rule(Rule::b, |s| Ok(s))
    /// #     })
    /// }).unwrap();
    /// let tokens: Vec<_> = pairs.flatten().tokens().collect();
    ///
    /// assert_eq!(tokens.len(), 4);
    /// ```
    #[inline]
    pub fn flatten(self) -> FlatPairs<'i, R> {
        flat_pairs::new(self.queue, self.input, self.start, self.end)
    }

    /// Returns the `Tokens` for the `Pairs`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::rc::Rc;
    /// # use pest;
    /// # #[allow(non_camel_case_types)]
    /// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
    /// enum Rule {
    ///     a
    /// }
    ///
    /// let input = "";
    /// let pairs = pest::state(input, |state| {
    ///     // generating Token pair with Rule::a ...
    /// #     state.rule(Rule::a, |s| Ok(s))
    /// }).unwrap();
    /// let tokens: Vec<_> = pairs.tokens().collect();
    ///
    /// assert_eq!(tokens.len(), 2);
    /// ```
    #[inline]
    pub fn tokens(self) -> Tokens<'i, R> {
        tokens::new(self.queue, self.input, self.start, self.end)
    }

    #[inline]
    pub fn peek(&mut self) -> Option<Pair<'i, R>> {
        if self.start < self.end {
            Some(pair::new(Rc::clone(&self.queue), self.input, self.start))
        } else {
            None
        }
    }

    fn pair(&self) -> usize {
        match self.queue[self.start] {
            QueueableToken::Start {
                end_token_index, ..
            } => end_token_index,
            _ => unreachable!()
        }
    }

    fn pair_from_end(&self) -> usize {
        match self.queue[self.end - 1] {
            QueueableToken::End {
                start_token_index, ..
            } => start_token_index,
            _ => unreachable!()
        }
    }

    fn pos(&self, index: usize) -> usize {
        match self.queue[index] {
            QueueableToken::Start { input_pos, .. } | QueueableToken::End { input_pos, .. } => {
                input_pos
            }
        }
    }
}

impl<'i, R: RuleType> Iterator for Pairs<'i, R> {
    type Item = Pair<'i, R>;

    fn next(&mut self) -> Option<Self::Item> {
        let pair = self.peek()?;
        self.start = self.pair() + 1;
        Some(pair)
    }
}

impl<'i, R: RuleType> DoubleEndedIterator for Pairs<'i, R> {
    fn next_back(&mut self) -> Option<Self::Item> {
        if self.end <= self.start {
            return None;
        }

        self.end = self.pair_from_end();

        let pair = pair::new(Rc::clone(&self.queue), self.input, self.end);

        Some(pair)
    }
}

impl<'i, R: RuleType> fmt::Debug for Pairs<'i, R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_list().entries(self.clone()).finish()
    }
}

impl<'i, R: RuleType> fmt::Display for Pairs<'i, R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "[{}]",
            self.clone()
                .map(|pair| format!("{}", pair))
                .collect::<Vec<_>>()
                .join(", ")
        )
    }
}

impl<'i, R: PartialEq> PartialEq for Pairs<'i, R> {
    fn eq(&self, other: &Pairs<'i, R>) -> bool {
        Rc::ptr_eq(&self.queue, &other.queue) && ptr::eq(self.input, other.input)
            && self.start == other.start && self.end == other.end
    }
}

impl<'i, R: Eq> Eq for Pairs<'i, R> {}

impl<'i, R: Hash> Hash for Pairs<'i, R> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        (&*self.queue as *const Vec<QueueableToken<R>>).hash(state);
        (self.input as *const [u8]).hash(state);
        self.start.hash(state);
        self.end.hash(state);
    }
}

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

    #[test]
    fn as_str() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();

        assert_eq!(pairs.as_str(), "abcde");
    }

    #[test]
    fn concat() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();

        assert_eq!(pairs.concat(), "abce");
    }

    #[test]
    fn pairs_debug() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();

        assert_eq!(
            format!("{:?}", pairs),
            "[\
                Pair { rule: a, span: Span { str: \"abc\", start: 0, end: 3 }, inner: [\
                    Pair { rule: b, span: Span { str: \"b\", start: 1, end: 2 }, inner: [] }\
                ] }, \
                Pair { rule: c, span: Span { str: \"e\", start: 4, end: 5 }, inner: [] }\
            ]"
        .to_owned()
        );
    }

    #[test]
    fn pairs_display() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();

        assert_eq!(
            format!("{}", pairs),
            "[a(0, 3, [b(1, 2)]), c(4, 5)]".to_owned()
        );
    }

    #[test]
    fn iter_for_pairs() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();
        assert_eq!(
            pairs.map(|p| p.as_rule()).collect::<Vec<Rule>>(),
            vec![Rule::a, Rule::c]
        );
    }

    #[test]
    fn double_ended_iter_for_pairs() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();
        assert_eq!(
            pairs.rev().map(|p| p.as_rule()).collect::<Vec<Rule>>(),
            vec![Rule::c, Rule::a]
        );
    }
}
<commit_msg>Peek should take &self<commit_after>// pest. The Elegant Parser
// Copyright (c) 2018 Dragoș Tiselice
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

use std::fmt;
use std::hash::{Hash, Hasher};
use std::ptr;
use std::rc::Rc;
use std::str;

use super::flat_pairs::{self, FlatPairs};
use super::pair::{self, Pair};
use super::queueable_token::QueueableToken;
use super::tokens::{self, Tokens};
use RuleType;

/// An iterator over [`Pair`]s. It is created by [`pest::state`] and [`Pair::into_inner`].
///
/// [`Pair`]: struct.Pair.html
/// [`pest::state`]: ../fn.state.html
/// [`Pair::into_inner`]: struct.Pair.html#method.into_inner
#[derive(Clone)]
pub struct Pairs<'i, R> {
    queue: Rc<Vec<QueueableToken<R>>>,
    input: &'i [u8],
    start: usize,
    end: usize
}

pub fn new<R: RuleType>(
    queue: Rc<Vec<QueueableToken<R>>>,
    input: &[u8],
    start: usize,
    end: usize
) -> Pairs<R> {
    Pairs {
        queue,
        input,
        start,
        end
    }
}

impl<'i, R: RuleType> Pairs<'i, R> {
    /// Captures a slice from the `&str` defined by the starting position of the first token `Pair`
    /// and the ending position of the last token `Pair` of the `Pairs`. This also captures
    /// the input between those two token `Pair`s.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::rc::Rc;
    /// # use pest;
    /// # #[allow(non_camel_case_types)]
    /// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
    /// enum Rule {
    ///     a,
    ///     b
    /// }
    ///
    /// let input = "a b";
    /// let pairs = pest::state(input, |state| {
    ///     // generating Token pairs with Rule::a and Rule::b ...
    /// #     state.rule(Rule::a, |s| s.match_string("a")).and_then(|s| s.skip(1))
    /// #         .and_then(|s| s.rule(Rule::b, |s| s.match_string("b")))
    /// }).unwrap();
    ///
    /// assert_eq!(pairs.as_str(), "a b");
    /// ```
    #[inline]
    pub fn as_str(&self) -> &'i str {
        let start = self.pos(self.start);
        let end = self.pos(self.end - 1);

        // Generated positions always come from Positions and are UTF-8 borders.
        unsafe { str::from_utf8_unchecked(&self.input[start..end]) }
    }

    /// Captures inner token `Pair`s and concatenates resulting `&str`s. This does not capture
    /// the input between token `Pair`s.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::rc::Rc;
    /// # use pest;
    /// # #[allow(non_camel_case_types)]
    /// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
    /// enum Rule {
    ///     a,
    ///     b
    /// }
    ///
    /// let input = "a b";
    /// let pairs = pest::state(input, |state| {
    ///     // generating Token pairs with Rule::a and Rule::b ...
    /// #     state.rule(Rule::a, |s| s.match_string("a")).and_then(|s| s.skip(1))
    /// #         .and_then(|s| s.rule(Rule::b, |s| s.match_string("b")))
    /// }).unwrap();
    ///
    /// assert_eq!(pairs.concat(), "ab");
    /// ```
    #[inline]
    pub fn concat(&self) -> String {
        self.clone().fold(String::new(), |string, pair| string + pair.as_str())
    }

    /// Flattens the `Pairs`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::rc::Rc;
    /// # use pest;
    /// # #[allow(non_camel_case_types)]
    /// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
    /// enum Rule {
    ///     a,
    ///     b
    /// }
    ///
    /// let input = "";
    /// let pairs = pest::state(input, |state| {
    ///     // generating nested Token pair with Rule::b inside Rule::a
    /// #     state.rule(Rule::a, |state| {
    /// #         state.rule(Rule::b, |s| Ok(s))
    /// #     })
    /// }).unwrap();
    /// let tokens: Vec<_> = pairs.flatten().tokens().collect();
    ///
    /// assert_eq!(tokens.len(), 4);
    /// ```
    #[inline]
    pub fn flatten(self) -> FlatPairs<'i, R> {
        flat_pairs::new(self.queue, self.input, self.start, self.end)
    }

    /// Returns the `Tokens` for the `Pairs`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::rc::Rc;
    /// # use pest;
    /// # #[allow(non_camel_case_types)]
    /// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
    /// enum Rule {
    ///     a
    /// }
    ///
    /// let input = "";
    /// let pairs = pest::state(input, |state| {
    ///     // generating Token pair with Rule::a ...
    /// #     state.rule(Rule::a, |s| Ok(s))
    /// }).unwrap();
    /// let tokens: Vec<_> = pairs.tokens().collect();
    ///
    /// assert_eq!(tokens.len(), 2);
    /// ```
    #[inline]
    pub fn tokens(self) -> Tokens<'i, R> {
        tokens::new(self.queue, self.input, self.start, self.end)
    }

    #[inline]
    pub fn peek(&self) -> Option<Pair<'i, R>> {
        if self.start < self.end {
            Some(pair::new(Rc::clone(&self.queue), self.input, self.start))
        } else {
            None
        }
    }

    fn pair(&self) -> usize {
        match self.queue[self.start] {
            QueueableToken::Start {
                end_token_index, ..
            } => end_token_index,
            _ => unreachable!()
        }
    }

    fn pair_from_end(&self) -> usize {
        match self.queue[self.end - 1] {
            QueueableToken::End {
                start_token_index, ..
            } => start_token_index,
            _ => unreachable!()
        }
    }

    fn pos(&self, index: usize) -> usize {
        match self.queue[index] {
            QueueableToken::Start { input_pos, .. } | QueueableToken::End { input_pos, .. } => {
                input_pos
            }
        }
    }
}

impl<'i, R: RuleType> Iterator for Pairs<'i, R> {
    type Item = Pair<'i, R>;

    fn next(&mut self) -> Option<Self::Item> {
        let pair = self.peek()?;
        self.start = self.pair() + 1;
        Some(pair)
    }
}

impl<'i, R: RuleType> DoubleEndedIterator for Pairs<'i, R> {
    fn next_back(&mut self) -> Option<Self::Item> {
        if self.end <= self.start {
            return None;
        }

        self.end = self.pair_from_end();

        let pair = pair::new(Rc::clone(&self.queue), self.input, self.end);

        Some(pair)
    }
}

impl<'i, R: RuleType> fmt::Debug for Pairs<'i, R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_list().entries(self.clone()).finish()
    }
}

impl<'i, R: RuleType> fmt::Display for Pairs<'i, R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "[{}]",
            self.clone()
                .map(|pair| format!("{}", pair))
                .collect::<Vec<_>>()
                .join(", ")
        )
    }
}

impl<'i, R: PartialEq> PartialEq for Pairs<'i, R> {
    fn eq(&self, other: &Pairs<'i, R>) -> bool {
        Rc::ptr_eq(&self.queue, &other.queue) && ptr::eq(self.input, other.input)
            && self.start == other.start && self.end == other.end
    }
}

impl<'i, R: Eq> Eq for Pairs<'i, R> {}

impl<'i, R: Hash> Hash for Pairs<'i, R> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        (&*self.queue as *const Vec<QueueableToken<R>>).hash(state);
        (self.input as *const [u8]).hash(state);
        self.start.hash(state);
        self.end.hash(state);
    }
}

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

    #[test]
    fn as_str() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();

        assert_eq!(pairs.as_str(), "abcde");
    }

    #[test]
    fn concat() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();

        assert_eq!(pairs.concat(), "abce");
    }

    #[test]
    fn pairs_debug() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();

        assert_eq!(
            format!("{:?}", pairs),
            "[\
                Pair { rule: a, span: Span { str: \"abc\", start: 0, end: 3 }, inner: [\
                    Pair { rule: b, span: Span { str: \"b\", start: 1, end: 2 }, inner: [] }\
                ] }, \
                Pair { rule: c, span: Span { str: \"e\", start: 4, end: 5 }, inner: [] }\
            ]"
        .to_owned()
        );
    }

    #[test]
    fn pairs_display() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();

        assert_eq!(
            format!("{}", pairs),
            "[a(0, 3, [b(1, 2)]), c(4, 5)]".to_owned()
        );
    }

    #[test]
    fn iter_for_pairs() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();
        assert_eq!(
            pairs.map(|p| p.as_rule()).collect::<Vec<Rule>>(),
            vec![Rule::a, Rule::c]
        );
    }

    #[test]
    fn double_ended_iter_for_pairs() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();
        assert_eq!(
            pairs.rev().map(|p| p.as_rule()).collect::<Vec<Rule>>(),
            vec![Rule::c, Rule::a]
        );
    }
}
<|endoftext|>


<commit_before>use num::Num;

#[inline(always)]
pub fn new<T: Num>(
    m11: T, m12: T, m13: T, m14: T,
    m21: T, m22: T, m23: T, m24: T,
    m31: T, m32: T, m33: T, m34: T,
    m41: T, m42: T, m43: T, m44: T
) -> [T; 16] {[
    m11, m12, m13, m14,
    m21, m22, m23, m24,
    m31, m32, m33, m34,
    m41, m42, m43, m44
]}
#[inline(always)]
pub fn create<T: Num>(
    m11: T, m12: T, m13: T, m14: T,
    m21: T, m22: T, m23: T, m24: T,
    m31: T, m32: T, m33: T, m34: T,
    m41: T, m42: T, m43: T, m44: T
) -> [T; 16] {new(
    m11, m12, m13, m14,
    m21, m22, m23, m24,
    m31, m32, m33, m34,
    m41, m42, m43, m44
)}
#[test]
fn test_new() {
    let m = new(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
    assert_eq!(m, [
        1, 0, 0, 0,
        0, 1, 0, 0,
        0, 0, 1, 0,
        0, 0, 0, 1
    ]);
}

#[inline(always)]
pub fn new_identity<T: Num>() -> [T; 16] {
    new(
        T::one(), T::zero(), T::zero(), T::zero(),
        T::zero(), T::one(), T::zero(), T::zero(),
        T::zero(), T::zero(), T::one(), T::zero(),
        T::zero(), T::zero(), T::zero(), T::one()
    )
}
#[inline(always)]
pub fn new_zero<T: Num>() -> [T; 16] {
    new(
        T::zero(), T::zero(), T::zero(), T::zero(),
        T::zero(), T::zero(), T::zero(), T::zero(),
        T::zero(), T::zero(), T::zero(), T::zero(),
        T::zero(), T::zero(), T::zero(), T::zero()
    )
}

#[inline(always)]
pub fn clone<T: Num>(m: [T; 16]) -> [T; 16] {
    new(
        m[0], m[4], m[8], m[12],
        m[1], m[5], m[9], m[13],
        m[2], m[6], m[10], m[14],
        m[3], m[7], m[11], m[15]
    )
}

#[inline(always)]
pub fn copy<T: Num>(out: &mut [T; 16], a: [T; 16]) -> &mut [T; 16] {
    out[0] = a[0];
    out[1] = a[1];
    out[2] = a[2];
    out[3] = a[3];
    out[4] = a[4];
    out[5] = a[5];
    out[6] = a[6];
    out[7] = a[7];
    out[8] = a[8];
    out[9] = a[9];
    out[10] = a[10];
    out[11] = a[11];
    out[12] = a[12];
    out[13] = a[13];
    out[14] = a[14];
    out[15] = a[15];
    out
}
<commit_msg>added from mat2, mat32, and mat4<commit_after>use num::Num;

#[inline(always)]
pub fn new<T: Num>(
    m11: T, m12: T, m13: T, m14: T,
    m21: T, m22: T, m23: T, m24: T,
    m31: T, m32: T, m33: T, m34: T,
    m41: T, m42: T, m43: T, m44: T
) -> [T; 16] {[
    m11, m12, m13, m14,
    m21, m22, m23, m24,
    m31, m32, m33, m34,
    m41, m42, m43, m44
]}
#[inline(always)]
pub fn create<T: Num>(
    m11: T, m12: T, m13: T, m14: T,
    m21: T, m22: T, m23: T, m24: T,
    m31: T, m32: T, m33: T, m34: T,
    m41: T, m42: T, m43: T, m44: T
) -> [T; 16] {new(
    m11, m12, m13, m14,
    m21, m22, m23, m24,
    m31, m32, m33, m34,
    m41, m42, m43, m44
)}
#[test]
fn test_new() {
    let m = new(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
    assert_eq!(m, [
        1, 0, 0, 0,
        0, 1, 0, 0,
        0, 0, 1, 0,
        0, 0, 0, 1
    ]);
}

#[inline(always)]
pub fn new_identity<T: Num>() -> [T; 16] {
    new(
        T::one(), T::zero(), T::zero(), T::zero(),
        T::zero(), T::one(), T::zero(), T::zero(),
        T::zero(), T::zero(), T::one(), T::zero(),
        T::zero(), T::zero(), T::zero(), T::one()
    )
}
#[inline(always)]
pub fn new_zero<T: Num>() -> [T; 16] {
    new(
        T::zero(), T::zero(), T::zero(), T::zero(),
        T::zero(), T::zero(), T::zero(), T::zero(),
        T::zero(), T::zero(), T::zero(), T::zero(),
        T::zero(), T::zero(), T::zero(), T::zero()
    )
}

#[inline(always)]
pub fn clone<T: Num>(m: [T; 16]) -> [T; 16] {
    new(
        m[0], m[4], m[8], m[12],
        m[1], m[5], m[9], m[13],
        m[2], m[6], m[10], m[14],
        m[3], m[7], m[11], m[15]
    )
}

#[inline(always)]
pub fn copy<T: Num>(out: &mut [T; 16], a: [T; 16]) -> &mut [T; 16] {
    out[0] = a[0];
    out[1] = a[1];
    out[2] = a[2];
    out[3] = a[3];
    out[4] = a[4];
    out[5] = a[5];
    out[6] = a[6];
    out[7] = a[7];
    out[8] = a[8];
    out[9] = a[9];
    out[10] = a[10];
    out[11] = a[11];
    out[12] = a[12];
    out[13] = a[13];
    out[14] = a[14];
    out[15] = a[15];
    out
}

#[inline(always)]
pub fn from_mat2<T: Num>(m: [T; 4]) -> [T; 16] {
    new(
        m[0], m[2], T::zero(), T::zero(),
        m[1], m[3], T::zero(), T::zero(),
        T::zero(), T::zero(), T::one(), T::zero(),
        T::zero(), T::zero(), T::zero(), T::one()
    )
}
#[inline(always)]
pub fn from_mat32<T: Num>(m: [T; 6]) -> [T; 16] {
    new(
        m[0], m[2], T::zero(), m[4],
        m[1], m[3], T::zero(), m[5],
        T::zero(), T::zero(), T::one(), T::zero(),
        T::zero(), T::zero(), T::zero(), T::one()
    )
}
#[inline(always)]
pub fn from_mat3<T: Num>(m: [T; 9]) -> [T; 16] {
    new(
        m[0], m[3], m[6], T::zero(),
        m[1], m[4], m[7], T::zero(),
        m[2], m[5], m[8], T::zero(),
        T::zero(), T::zero(), T::zero(), T::one()
    )
}
<|endoftext|>