<commit_before>//! `gel` is an extension of sebcrozet's `nalgebra` crate, designed to facilitate OpenGL
//! mathematics.

extern crate num;
extern crate nalgebra;
extern crate glium;
extern crate rustc_serialize;

use glium::uniforms::{
    AsUniformValue,
    UniformValue,
};

pub use num::{
    One,
    Zero,
};

pub use nalgebra::*;
/// A trait for objects able to be extended.
pub trait Extend<N> {
    type Output;

    fn extend(&self, N) -> Self::Output;
}

/// A trait for objects able to be truncated.
pub trait Truncate {
    type Output;

    fn truncate(&self) -> Self::Output;
}

/// A trait for objects able to construct view matrices.
pub trait LookAt<N> {
    fn look_at(camera: &Vec3<N>, target: &Vec3<N>, up: &Vec3<N>) -> Self;
}

impl<N> Extend<N> for Vec0<N>
    where N: Copy
{
    type Output = Vec1<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Vec1::new(elem)
    }
}

impl<N> Extend<N> for Vec1<N>
    where N: Copy
{
    type Output = Vec2<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Vec2::new(self.x, elem)
    }
}

impl<N> Extend<N> for Vec2<N>
    where N: Copy
{
    type Output = Vec3<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Vec3::new(self.x, self.y, elem)
    }
}

impl<N> Extend<N> for Vec3<N>
    where N: Copy
{
    type Output = Vec4<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Vec4::new(self.x, self.y, self.z, elem)
    }
}

impl<N> Extend<N> for Vec4<N>
    where N: Copy
{
    type Output = Vec5<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Vec5::new(self.x, self.y, self.z, self.w, elem)
    }
}

impl<N> Extend<N> for Vec5<N>
    where N: Copy
{
    type Output = Vec6<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Vec6::new(self.x, self.y, self.z, self.w, self.a, elem)
    }
}

impl<N> Truncate for Vec1<N>
    where N: Copy
{
    type Output = Vec0<N>;

    fn truncate(&self) -> Self::Output {
        Vec0::new()
    }
}

impl<N> Truncate for Vec2<N>
    where N: Copy
{
    type Output = Vec1<N>;

    fn truncate(&self) -> Self::Output {
        Vec1::new(self.x)
    }
}

impl<N> Truncate for Vec3<N>
    where N: Copy
{
    type Output = Vec2<N>;

    fn truncate(&self) -> Self::Output {
        Vec2::new(self.x, self.y)
    }
}

impl<N> Truncate for Vec4<N>
    where N: Copy
{
    type Output = Vec3<N>;

    fn truncate(&self) -> Self::Output {
        Vec3::new(self.x, self.y, self.z)
    }
}

impl<N> Truncate for Vec5<N>
    where N: Copy
{
    type Output = Vec4<N>;

    fn truncate(&self) -> Self::Output {
        Vec4::new(self.x, self.y, self.z, self.w)
    }
}

impl<N> Truncate for Vec6<N>
    where N: Copy
{
    type Output = Vec5<N>;

    fn truncate(&self) -> Self::Output {
        Vec5::new(self.x, self.y, self.z, self.w, self.a)
    }
}

impl<N> Extend<N> for Pnt0<N>
    where N: Copy
{
    type Output = Pnt1<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Pnt1::new(elem)
    }
}

impl<N> Extend<N> for Pnt1<N>
    where N: Copy
{
    type Output = Pnt2<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Pnt2::new(self.x, elem)
    }
}

impl<N> Extend<N> for Pnt2<N>
    where N: Copy
{
    type Output = Pnt3<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Pnt3::new(self.x, self.y, elem)
    }
}

impl<N> Extend<N> for Pnt3<N>
    where N: Copy
{
    type Output = Pnt4<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Pnt4::new(self.x, self.y, self.z, elem)
    }
}

impl<N> Extend<N> for Pnt4<N>
    where N: Copy
{
    type Output = Pnt5<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Pnt5::new(self.x, self.y, self.z, self.w, elem)
    }
}

impl<N> Extend<N> for Pnt5<N>
    where N: Copy
{
    type Output = Pnt6<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Pnt6::new(self.x, self.y, self.z, self.w, self.a, elem)
    }
}

impl<N> Truncate for Pnt1<N>
    where N: Copy
{
    type Output = Pnt0<N>;

    fn truncate(&self) -> Self::Output {
        Pnt0::new()
    }
}

impl<N> Truncate for Pnt2<N>
    where N: Copy
{
    type Output = Pnt1<N>;

    fn truncate(&self) -> Self::Output {
        Pnt1::new(self.x)
    }
}

impl<N> Truncate for Pnt3<N>
    where N: Copy
{
    type Output = Pnt2<N>;

    fn truncate(&self) -> Self::Output {
        Pnt2::new(self.x, self.y)
    }
}

impl<N> Truncate for Pnt4<N>
    where N: Copy
{
    type Output = Pnt3<N>;

    fn truncate(&self) -> Self::Output {
        Pnt3::new(self.x, self.y, self.z)
    }
}

impl<N> Truncate for Pnt5<N>
    where N: Copy
{
    type Output = Pnt4<N>;

    fn truncate(&self) -> Self::Output {
        Pnt4::new(self.x, self.y, self.z, self.w)
    }
}

impl<N> Truncate for Pnt6<N>
    where N: Copy
{
    type Output = Pnt5<N>;

    fn truncate(&self) -> Self::Output {
        Pnt5::new(self.x, self.y, self.z, self.w, self.a)
    }
}

impl<N> LookAt<N> for Mat4<N>
    where N: BaseFloat
{
    fn look_at(camera: &Vec3<N>, target: &Vec3<N>, up: &Vec3<N>) -> Self {
        let f = (*target - *camera).normalize();
        let s = f.cross(up).normalize();
        let u = s.cross(&f);

        let mut result = Self::one();

        unsafe {
            result.set_fast((0, 0), s.x);
            result.set_fast((1, 0), s.y);
            result.set_fast((2, 0), s.z);
            result.set_fast((0, 1), u.x);
            result.set_fast((1, 1), u.y);
            result.set_fast((2, 1), u.z);
            result.set_fast((0, 2), -f.x);
            result.set_fast((1, 2), -f.y);
            result.set_fast((2, 2), -f.z);
            result.set_fast((3, 0), -(s.dot(camera)));
            result.set_fast((3, 1), -(u.dot(camera)));
            result.set_fast((3, 2), f.dot(camera));
        }

        result
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, RustcDecodable, RustcEncodable)]
pub struct Perspective<N> {
    mat: Mat4<N>,
}

impl<N> Perspective<N>
    where N: BaseFloat
{
    pub fn new(fov: N, aspect: N, znear: N, zfar: N) -> Perspective<N> {
        let one = N::one();
        let two = N::one() + N::one();

        let tan_half_fov = (fov / two).tan();

        let mut mat = Mat4::zero();
        unsafe {
            mat.set_fast((0, 0), one / (aspect * tan_half_fov));
            mat.set_fast((1, 1), one / (tan_half_fov));
            mat.set_fast((2, 2), -(zfar + znear) / (zfar - znear));
            mat.set_fast((2, 3), -one);
            mat.set_fast((3, 2), -(two * zfar * znear) / (zfar - znear));
        }

        Perspective {
            mat: mat,
        }
    }

    pub fn as_mat<'a>(&'a self) -> &'a Mat4<N> {
        &self.mat
    }

}

impl<N> Perspective<N>
    where N: BaseFloat + Clone
{
    pub fn to_mat(&self) -> Mat4<N> {
        self.mat.clone()
    }
}

impl AsUniformValue for Perspective<f32> {
    fn as_uniform_value(&self) -> UniformValue {
        let val = self.to_mat();
        UniformValue::Mat4(*val.as_array())
    }
}

pub fn radians<N>(n: N) -> N
    where N: BaseFloat
{
    n * (N::pi() / <N as Cast<f64>>::from(180.0))
}

pub fn degrees<N>(n: N) -> N
    where N: BaseFloat
{
    n * (<N as Cast<f64>>::from(180.0) / N::pi())
}

pub fn extend<T, N>(base: T, elem: N) -> T::Output
    where T: Extend<N>
{
    base.extend(elem)
}

pub fn truncate<T>(base: T) -> T::Output
    where T: Truncate
{
    base.truncate()
}
<commit_msg>impl uniformblock<commit_after>//! `gel` is an extension of sebcrozet's `nalgebra` crate, designed to facilitate OpenGL
//! mathematics.

extern crate num;
extern crate nalgebra;
extern crate glium;
extern crate rustc_serialize;

use glium::uniforms::{
    AsUniformValue,
    UniformValue,
    UniformBlock,
};

pub use num::{
    One,
    Zero,
};

pub use nalgebra::*;
/// A trait for objects able to be extended.
pub trait Extend<N> {
    type Output;

    fn extend(&self, N) -> Self::Output;
}

/// A trait for objects able to be truncated.
pub trait Truncate {
    type Output;

    fn truncate(&self) -> Self::Output;
}

/// A trait for objects able to construct view matrices.
pub trait LookAt<N> {
    fn look_at(camera: &Vec3<N>, target: &Vec3<N>, up: &Vec3<N>) -> Self;
}

impl<N> Extend<N> for Vec0<N>
    where N: Copy
{
    type Output = Vec1<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Vec1::new(elem)
    }
}

impl<N> Extend<N> for Vec1<N>
    where N: Copy
{
    type Output = Vec2<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Vec2::new(self.x, elem)
    }
}

impl<N> Extend<N> for Vec2<N>
    where N: Copy
{
    type Output = Vec3<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Vec3::new(self.x, self.y, elem)
    }
}

impl<N> Extend<N> for Vec3<N>
    where N: Copy
{
    type Output = Vec4<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Vec4::new(self.x, self.y, self.z, elem)
    }
}

impl<N> Extend<N> for Vec4<N>
    where N: Copy
{
    type Output = Vec5<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Vec5::new(self.x, self.y, self.z, self.w, elem)
    }
}

impl<N> Extend<N> for Vec5<N>
    where N: Copy
{
    type Output = Vec6<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Vec6::new(self.x, self.y, self.z, self.w, self.a, elem)
    }
}

impl<N> Truncate for Vec1<N>
    where N: Copy
{
    type Output = Vec0<N>;

    fn truncate(&self) -> Self::Output {
        Vec0::new()
    }
}

impl<N> Truncate for Vec2<N>
    where N: Copy
{
    type Output = Vec1<N>;

    fn truncate(&self) -> Self::Output {
        Vec1::new(self.x)
    }
}

impl<N> Truncate for Vec3<N>
    where N: Copy
{
    type Output = Vec2<N>;

    fn truncate(&self) -> Self::Output {
        Vec2::new(self.x, self.y)
    }
}

impl<N> Truncate for Vec4<N>
    where N: Copy
{
    type Output = Vec3<N>;

    fn truncate(&self) -> Self::Output {
        Vec3::new(self.x, self.y, self.z)
    }
}

impl<N> Truncate for Vec5<N>
    where N: Copy
{
    type Output = Vec4<N>;

    fn truncate(&self) -> Self::Output {
        Vec4::new(self.x, self.y, self.z, self.w)
    }
}

impl<N> Truncate for Vec6<N>
    where N: Copy
{
    type Output = Vec5<N>;

    fn truncate(&self) -> Self::Output {
        Vec5::new(self.x, self.y, self.z, self.w, self.a)
    }
}

impl<N> Extend<N> for Pnt0<N>
    where N: Copy
{
    type Output = Pnt1<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Pnt1::new(elem)
    }
}

impl<N> Extend<N> for Pnt1<N>
    where N: Copy
{
    type Output = Pnt2<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Pnt2::new(self.x, elem)
    }
}

impl<N> Extend<N> for Pnt2<N>
    where N: Copy
{
    type Output = Pnt3<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Pnt3::new(self.x, self.y, elem)
    }
}

impl<N> Extend<N> for Pnt3<N>
    where N: Copy
{
    type Output = Pnt4<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Pnt4::new(self.x, self.y, self.z, elem)
    }
}

impl<N> Extend<N> for Pnt4<N>
    where N: Copy
{
    type Output = Pnt5<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Pnt5::new(self.x, self.y, self.z, self.w, elem)
    }
}

impl<N> Extend<N> for Pnt5<N>
    where N: Copy
{
    type Output = Pnt6<N>;

    fn extend(&self, elem: N) -> Self::Output {
        Pnt6::new(self.x, self.y, self.z, self.w, self.a, elem)
    }
}

impl<N> Truncate for Pnt1<N>
    where N: Copy
{
    type Output = Pnt0<N>;

    fn truncate(&self) -> Self::Output {
        Pnt0::new()
    }
}

impl<N> Truncate for Pnt2<N>
    where N: Copy
{
    type Output = Pnt1<N>;

    fn truncate(&self) -> Self::Output {
        Pnt1::new(self.x)
    }
}

impl<N> Truncate for Pnt3<N>
    where N: Copy
{
    type Output = Pnt2<N>;

    fn truncate(&self) -> Self::Output {
        Pnt2::new(self.x, self.y)
    }
}

impl<N> Truncate for Pnt4<N>
    where N: Copy
{
    type Output = Pnt3<N>;

    fn truncate(&self) -> Self::Output {
        Pnt3::new(self.x, self.y, self.z)
    }
}

impl<N> Truncate for Pnt5<N>
    where N: Copy
{
    type Output = Pnt4<N>;

    fn truncate(&self) -> Self::Output {
        Pnt4::new(self.x, self.y, self.z, self.w)
    }
}

impl<N> Truncate for Pnt6<N>
    where N: Copy
{
    type Output = Pnt5<N>;

    fn truncate(&self) -> Self::Output {
        Pnt5::new(self.x, self.y, self.z, self.w, self.a)
    }
}

impl<N> LookAt<N> for Mat4<N>
    where N: BaseFloat
{
    fn look_at(camera: &Vec3<N>, target: &Vec3<N>, up: &Vec3<N>) -> Self {
        let f = (*target - *camera).normalize();
        let s = f.cross(up).normalize();
        let u = s.cross(&f);

        let mut result = Self::one();

        unsafe {
            result.set_fast((0, 0), s.x);
            result.set_fast((1, 0), s.y);
            result.set_fast((2, 0), s.z);
            result.set_fast((0, 1), u.x);
            result.set_fast((1, 1), u.y);
            result.set_fast((2, 1), u.z);
            result.set_fast((0, 2), -f.x);
            result.set_fast((1, 2), -f.y);
            result.set_fast((2, 2), -f.z);
            result.set_fast((3, 0), -(s.dot(camera)));
            result.set_fast((3, 1), -(u.dot(camera)));
            result.set_fast((3, 2), f.dot(camera));
        }

        result
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, RustcDecodable, RustcEncodable)]
pub struct Perspective<N> {
    mat: Mat4<N>,
}

impl<N> Perspective<N>
    where N: BaseFloat
{
    pub fn new(fov: N, aspect: N, znear: N, zfar: N) -> Perspective<N> {
        let one = N::one();
        let two = N::one() + N::one();

        let tan_half_fov = (fov / two).tan();

        let mut mat = Mat4::zero();
        unsafe {
            mat.set_fast((0, 0), one / (aspect * tan_half_fov));
            mat.set_fast((1, 1), one / (tan_half_fov));
            mat.set_fast((2, 2), -(zfar + znear) / (zfar - znear));
            mat.set_fast((2, 3), -one);
            mat.set_fast((3, 2), -(two * zfar * znear) / (zfar - znear));
        }

        Perspective {
            mat: mat,
        }
    }

    pub fn as_mat<'a>(&'a self) -> &'a Mat4<N> {
        &self.mat
    }

}

impl<N> Perspective<N>
    where N: BaseFloat + Clone
{
    pub fn to_mat(&self) -> Mat4<N> {
        self.mat.clone()
    }
}

impl AsUniformValue for Perspective<f32> {
    fn as_uniform_value(&self) -> UniformValue {
        let val = self.to_mat();
        UniformValue::Mat4(*val.as_array())
    }
}

impl UniformBlock for Perspective<f32> {
    fn matches(layout: &glium::program::BlockLayout, base_offset: usize)
        -> Result<(), glium::uniforms::LayoutMismatchError>
    {
        use glium::program::BlockLayout;
        use glium::uniforms::LayoutMismatchError;
        use glium::uniforms::UniformType;

        if let &BlockLayout::BasicType { ty, offset_in_buffer } = layout {
            if ty != UniformType::FloatMat4 {
                return Err(LayoutMismatchError::TypeMismatch {
                    expected: ty,
                    obtained: UniformType::FloatMat4,
                });
            }

            if offset_in_buffer != base_offset {
                return Err(LayoutMismatchError::OffsetMismatch {
                    expected: offset_in_buffer,
                    obtained: base_offset,
                });
            }

            Ok(())
        } else {
            Err(LayoutMismatchError::LayoutMismatch {
                expected: layout.clone(),
                obtained: BlockLayout::BasicType {
                    ty: UniformType::FloatMat4,
                    offset_in_buffer: base_offset,
                }
            })
        }
    }

    #[inline]
    fn build_layout(base_offset: usize) -> glium::program::BlockLayout {
        use glium::program::BlockLayout;
        use glium::uniforms::UniformType;

        BlockLayout::BasicType {
            ty: UniformType::FloatMat4,
            offset_in_buffer: base_offset,
        }
    }
}
pub fn radians<N>(n: N) -> N
    where N: BaseFloat
{
    n * (N::pi() / <N as Cast<f64>>::from(180.0))
}

pub fn degrees<N>(n: N) -> N
    where N: BaseFloat
{
    n * (<N as Cast<f64>>::from(180.0) / N::pi())
}

pub fn extend<T, N>(base: T, elem: N) -> T::Output
    where T: Extend<N>
{
    base.extend(elem)
}

pub fn truncate<T>(base: T) -> T::Output
    where T: Truncate
{
    base.truncate()
}

<|endoftext|>


<commit_before>
/*!
This crate provides a library for parsing and manipulating network data, packet captures.

# Usage

Add `ether` to the dependencies in your `Cargo.toml` and the following to *root* of your crate:

```rust
extern crate ether;
```

Here's a simple example that prints all packets received on interface `en0`:

```rust,no_run
extern crate futures;
extern crate ether;

use futures::stream::Stream;
use ether::tap;

fn main() {
    let mut tap = tap::Tap::new("en0").unwrap();
    for packet in tap.stream().wait().filter_map(|p| p.ok()) {
        println!("{:?}", packet);
    }
}
```
*/

extern crate num;
extern crate libc;
extern crate glob;
extern crate futures;

#[macro_use]
extern crate nom;

mod utility;

pub mod packet;
pub mod pcap;
pub mod tap;
<commit_msg>Update documentation.<commit_after>
/*!
This crate provides a library for parsing and manipulating network data, packet captures.

# Usage

Add `ether` to the dependencies in your `Cargo.toml` and the following to *root* of your crate:

```rust
extern crate ether;
```

Here's a simple example that prints all packets received on interface `en0`:

```rust,no_run
extern crate ether;

use ether::tap;
use ether::tap::Stream;

fn main() {
    let mut tap = tap::Tap::new("en0").unwrap();
    for packet in tap.stream().wait().filter_map(|p| p.ok()) {
        println!("{:?}", packet);
    }
}
```
*/

extern crate num;
extern crate libc;
extern crate glob;
extern crate futures;

#[macro_use]
extern crate nom;

mod utility;

pub mod packet;
pub mod pcap;
pub mod tap;
<|endoftext|>


<commit_before>// Distributed under the OSI-approved BSD 3-Clause License.
// See accompanying LICENSE file for details.

use std::fmt;

use lazy_static::lazy_static;
use uuid::Uuid;

#[cfg(unix)]
mod imp {
    mod unix;
    pub use self::unix::get_machine_id;
}

#[cfg(not(any(unix)))]
mod imp {
    fn get_machine_id() -> Option<Uuid> {
        None
    }
}

/// A machine-specific ID.
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
pub struct MachineId {
    uuid: Uuid,
}

lazy_static! {
    static ref GENERATED_ID: Uuid = Uuid::new_v4();
    static ref GLOBAL_ID: Option<Uuid> = imp::get_machine_id();
}

impl MachineId {
    /// Retrieves or generates the machine-specific ID.
    pub fn get() -> MachineId {
        MachineId {
            uuid: GLOBAL_ID.unwrap_or(*GENERATED_ID),
        }
    }
}

impl fmt::Display for MachineId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.uuid)
    }
}

#[test]
fn test_idempotent() {
    let fst = MachineId::get();
    let snd = MachineId::get();

    assert_eq!(fst, snd);
}

#[test]
fn test_can_print() {
    let mid = MachineId::get();

    println!("{}", mid);
}
<commit_msg>MachineId: expose the inner uuid<commit_after>// Distributed under the OSI-approved BSD 3-Clause License.
// See accompanying LICENSE file for details.

use std::fmt;

use lazy_static::lazy_static;
use uuid::Uuid;

#[cfg(unix)]
mod imp {
    mod unix;
    pub use self::unix::get_machine_id;
}

#[cfg(not(any(unix)))]
mod imp {
    fn get_machine_id() -> Option<Uuid> {
        None
    }
}

/// A machine-specific ID.
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
pub struct MachineId {
    uuid: Uuid,
}

lazy_static! {
    static ref GENERATED_ID: Uuid = Uuid::new_v4();
    static ref GLOBAL_ID: Option<Uuid> = imp::get_machine_id();
}

impl MachineId {
    /// Retrieves or generates the machine-specific ID.
    pub fn get() -> MachineId {
        MachineId {
            uuid: GLOBAL_ID.unwrap_or(*GENERATED_ID),
        }
    }
}

impl fmt::Display for MachineId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.uuid)
    }
}

impl From<MachineId> for Uuid {
    fn from(mid: MachineId) -> Uuid {
        mid.uuid
    }
}

#[test]
fn test_idempotent() {
    let fst = MachineId::get();
    let snd = MachineId::get();

    assert_eq!(fst, snd);
}

#[test]
fn test_can_print() {
    let mid = MachineId::get();

    println!("{}", mid);
}
<|endoftext|>


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

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

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

use std::fmt;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

use std::fmt;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


<commit_before>// Copyright 2013-2018, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

#![allow(deprecated)]
#![cfg_attr(feature = "cargo-clippy", allow(cast_ptr_alignment))]
#![cfg_attr(feature = "cargo-clippy", allow(trivially_copy_pass_by_ref))]

extern crate gdk_pixbuf;
extern crate gdk_sys;
extern crate gio;
extern crate gio_sys;
extern crate glib_sys;
#[macro_use]
extern crate glib;
extern crate cairo;
extern crate cairo_sys;
extern crate gobject_sys;
extern crate libc;
extern crate pango;
#[macro_use]
extern crate bitflags;

#[macro_use]
mod rt;
#[macro_use]
mod event;

#[cfg_attr(feature = "cargo-clippy", allow(type_complexity))]
#[cfg_attr(feature = "cargo-clippy", allow(unreadable_literal))]
mod auto;

pub mod prelude;

pub use self::auto::functions::*;
pub use auto::*;

mod atom;
mod cairo_interaction;
mod change_data;
mod device;
mod device_manager;
mod drag_context;
mod event_button;
mod event_configure;
mod event_crossing;
mod event_dnd;
mod event_expose;
mod event_focus;
mod event_grab_broken;
mod event_key;
mod event_motion;
mod event_owner_change;
#[cfg(any(feature = "v3_22", feature = "dox"))]
mod event_pad_axis;
#[cfg(any(feature = "v3_22", feature = "dox"))]
mod event_pad_button;
#[cfg(any(feature = "v3_22", feature = "dox"))]
mod event_pad_group_mode;
mod event_property;
mod event_proximity;
mod event_scroll;
mod event_selection;
mod event_setting;
mod event_touch;
#[cfg(any(feature = "v3_18", feature = "dox"))]
mod event_touchpad_pinch;
#[cfg(any(feature = "v3_18", feature = "dox"))]
mod event_touchpad_swipe;
mod event_visibility;
mod event_window_state;
mod frame_clock;
mod frame_timings;
mod functions;
mod geometry;
mod keymap;
mod keymap_key;
pub mod keys;
mod rectangle;
mod rgba;
mod screen;
mod time_coord;
mod visual;
mod window;

pub use gdk_sys::GdkColor as Color;

pub use self::rt::{init, set_initialized};

pub use atom::Atom;
pub use atom::NONE as ATOM_NONE;
pub use atom::SELECTION_CLIPBOARD;
pub use atom::SELECTION_PRIMARY;
pub use atom::SELECTION_SECONDARY;
pub use atom::SELECTION_TYPE_ATOM;
pub use atom::SELECTION_TYPE_BITMAP;
pub use atom::SELECTION_TYPE_COLORMAP;
pub use atom::SELECTION_TYPE_DRAWABLE;
pub use atom::SELECTION_TYPE_INTEGER;
pub use atom::SELECTION_TYPE_PIXMAP;
pub use atom::SELECTION_TYPE_STRING;
pub use atom::SELECTION_TYPE_WINDOW;
pub use atom::TARGET_BITMAP;
pub use atom::TARGET_COLORMAP;
pub use atom::TARGET_DRAWABLE;
pub use atom::TARGET_PIXMAP;
pub use atom::TARGET_STRING;
pub use change_data::ChangeData;
pub use event::Event;
pub use event_button::EventButton;
pub use event_configure::EventConfigure;
pub use event_crossing::EventCrossing;
pub use event_dnd::EventDND;
pub use event_expose::EventExpose;
pub use event_focus::EventFocus;
pub use event_grab_broken::EventGrabBroken;
pub use event_key::EventKey;
pub use event_motion::EventMotion;
pub use event_owner_change::EventOwnerChange;
#[cfg(any(feature = "v3_22", feature = "dox"))]
pub use event_pad_axis::EventPadAxis;
#[cfg(any(feature = "v3_22", feature = "dox"))]
pub use event_pad_button::EventPadButton;
#[cfg(any(feature = "v3_22", feature = "dox"))]
pub use event_pad_group_mode::EventPadGroupMode;
pub use event_property::EventProperty;
pub use event_proximity::EventProximity;
pub use event_scroll::EventScroll;
pub use event_selection::EventSelection;
pub use event_setting::EventSetting;
pub use event_touch::EventTouch;
#[cfg(any(feature = "v3_18", feature = "dox"))]
pub use event_touchpad_pinch::EventTouchpadPinch;
#[cfg(any(feature = "v3_18", feature = "dox"))]
pub use event_touchpad_swipe::EventTouchpadSwipe;
pub use event_visibility::EventVisibility;
pub use event_window_state::EventWindowState;
pub use functions::*;
pub use geometry::Geometry;
pub use keymap_key::KeymapKey;
pub use rectangle::Rectangle;
pub use rgba::{RgbaParseError, RGBA};
pub use time_coord::TimeCoord;
pub use window::WindowAttr;

#[allow(non_camel_case_types)]
pub type key = i32;

pub use self::keys::{keyval_name, keyval_to_unicode};
<commit_msg>add GDK_BUTTON_* see https://github.com/gtk-rs/gtk/issues/1044<commit_after>// Copyright 2013-2018, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

#![allow(deprecated)]
#![cfg_attr(feature = "cargo-clippy", allow(cast_ptr_alignment))]
#![cfg_attr(feature = "cargo-clippy", allow(trivially_copy_pass_by_ref))]

extern crate gdk_pixbuf;
extern crate gdk_sys;
extern crate gio;
extern crate gio_sys;
extern crate glib_sys;
#[macro_use]
extern crate glib;
extern crate cairo;
extern crate cairo_sys;
extern crate gobject_sys;
extern crate libc;
extern crate pango;
#[macro_use]
extern crate bitflags;

#[macro_use]
mod rt;
#[macro_use]
mod event;

#[cfg_attr(feature = "cargo-clippy", allow(type_complexity))]
#[cfg_attr(feature = "cargo-clippy", allow(unreadable_literal))]
mod auto;

pub mod prelude;

pub use self::auto::functions::*;
pub use auto::*;

mod atom;
mod cairo_interaction;
mod change_data;
mod device;
mod device_manager;
mod drag_context;
mod event_button;
mod event_configure;
mod event_crossing;
mod event_dnd;
mod event_expose;
mod event_focus;
mod event_grab_broken;
mod event_key;
mod event_motion;
mod event_owner_change;
#[cfg(any(feature = "v3_22", feature = "dox"))]
mod event_pad_axis;
#[cfg(any(feature = "v3_22", feature = "dox"))]
mod event_pad_button;
#[cfg(any(feature = "v3_22", feature = "dox"))]
mod event_pad_group_mode;
mod event_property;
mod event_proximity;
mod event_scroll;
mod event_selection;
mod event_setting;
mod event_touch;
#[cfg(any(feature = "v3_18", feature = "dox"))]
mod event_touchpad_pinch;
#[cfg(any(feature = "v3_18", feature = "dox"))]
mod event_touchpad_swipe;
mod event_visibility;
mod event_window_state;
mod frame_clock;
mod frame_timings;
mod functions;
mod geometry;
mod keymap;
mod keymap_key;
pub mod keys;
mod rectangle;
mod rgba;
mod screen;
mod time_coord;
mod visual;
mod window;

pub use gdk_sys::GdkColor as Color;

pub use self::rt::{init, set_initialized};

pub use atom::Atom;
pub use atom::NONE as ATOM_NONE;
pub use atom::SELECTION_CLIPBOARD;
pub use atom::SELECTION_PRIMARY;
pub use atom::SELECTION_SECONDARY;
pub use atom::SELECTION_TYPE_ATOM;
pub use atom::SELECTION_TYPE_BITMAP;
pub use atom::SELECTION_TYPE_COLORMAP;
pub use atom::SELECTION_TYPE_DRAWABLE;
pub use atom::SELECTION_TYPE_INTEGER;
pub use atom::SELECTION_TYPE_PIXMAP;
pub use atom::SELECTION_TYPE_STRING;
pub use atom::SELECTION_TYPE_WINDOW;
pub use atom::TARGET_BITMAP;
pub use atom::TARGET_COLORMAP;
pub use atom::TARGET_DRAWABLE;
pub use atom::TARGET_PIXMAP;
pub use atom::TARGET_STRING;
pub use change_data::ChangeData;
pub use event::Event;
pub use event_button::EventButton;
pub use event_configure::EventConfigure;
pub use event_crossing::EventCrossing;
pub use event_dnd::EventDND;
pub use event_expose::EventExpose;
pub use event_focus::EventFocus;
pub use event_grab_broken::EventGrabBroken;
pub use event_key::EventKey;
pub use event_motion::EventMotion;
pub use event_owner_change::EventOwnerChange;
#[cfg(any(feature = "v3_22", feature = "dox"))]
pub use event_pad_axis::EventPadAxis;
#[cfg(any(feature = "v3_22", feature = "dox"))]
pub use event_pad_button::EventPadButton;
#[cfg(any(feature = "v3_22", feature = "dox"))]
pub use event_pad_group_mode::EventPadGroupMode;
pub use event_property::EventProperty;
pub use event_proximity::EventProximity;
pub use event_scroll::EventScroll;
pub use event_selection::EventSelection;
pub use event_setting::EventSetting;
pub use event_touch::EventTouch;
#[cfg(any(feature = "v3_18", feature = "dox"))]
pub use event_touchpad_pinch::EventTouchpadPinch;
#[cfg(any(feature = "v3_18", feature = "dox"))]
pub use event_touchpad_swipe::EventTouchpadSwipe;
pub use event_visibility::EventVisibility;
pub use event_window_state::EventWindowState;
pub use functions::*;
pub use geometry::Geometry;
pub use keymap_key::KeymapKey;
pub use rectangle::Rectangle;
pub use rgba::{RgbaParseError, RGBA};
pub use time_coord::TimeCoord;
pub use window::WindowAttr;

#[allow(non_camel_case_types)]
pub type key = i32;

pub use self::keys::{keyval_name, keyval_to_unicode};

/// The primary button. This is typically the left mouse button, or the right button in a left-handed setup.
pub const BUTTON_PRIMARY: u32 = gdk_sys::GDK_BUTTON_PRIMARY as u32;

/// The middle button.
pub const BUTTON_MIDDLE: u32 = gdk_sys::GDK_BUTTON_MIDDLE as u32;

/// The secondary button. This is typically the right mouse button, or the left button in a left-handed setup.
pub const BUTTON_SECONDARY: u32 = gdk_sys::GDK_BUTTON_SECONDARY as u32;
<|endoftext|>


<commit_before>#![crate_name = "binstat"]
#![deny(missing_doc)]

//! A library for modelling and reasoning about multidimensional
//! binary states.

#[cfg(test)]
extern crate debug;

use std::collections::Bitv;

/// Contains a binary state and the choices.
#[deriving(PartialEq, Eq, Show, Clone)]
pub struct BinStateChoices {
    /// The state composed of bits.
    pub state: Bitv,
    /// The choices represented as bits that can be flipped.
    pub choices: Bitv
}

impl BinStateChoices {
    /// Gets pairs from pair of booleans.
    pub fn from_pairs(pairs: &[(bool, bool)]) -> BinStateChoices {
        BinStateChoices {
            state: pairs.iter().map(|&(a, _)| a).collect(),
            choices: pairs.iter().map(|&(_, b)| b).collect()
        }
    }

    /// Iterate for each available choice.
    #[inline(always)]
    pub fn with_choices(&self, f: |i: uint|) {
        for i in range(0, self.choices.len())
            .zip(self.choices.iter())
            .filter(|&(_, v)| v == true)
            .map(|(i, _)| i
        ) {
            f(i)
        }
    }
}

/// Models a multidimensional binary state.
pub struct BinGraph<TAction> {
    /// The states and the bits that can be flipped.
    pub data: Vec<BinStateChoices>,
    /// A description the action that takes when flipping bits.
    pub actions: Vec<TAction>,
}

impl<TAction> BinGraph<TAction> {
    /// Creates a new BinGraph.
    pub fn new() -> BinGraph<TAction> {
        BinGraph {
            data: Vec::new(),
            actions: Vec::new()
        }
    }

    /// Adds new information about state and choices.
    ///
    /// The first bool indicate state, the second whether it can change.
    pub fn push_pairs(&mut self, pairs: &[(bool, bool)]) {
        self.data.push(BinStateChoices::from_pairs(pairs));
    }

    /// Returns the suggestion in default state that are open to all choices.
    pub fn default_suggestion(&self) -> BinStateChoices {
        let open_for_all_choices: Vec<(bool, bool)> =
            range(0, self.actions.len()).map(|_| (false, true)).collect();
        BinStateChoices::from_pairs(open_for_all_choices.as_slice())
    }

    /// Suggests a missing state with choices.
    pub fn suggestion(&self) -> Option<BinStateChoices> {
        if self.data.len() == 0 {
            Some(self.default_suggestion())
        } else {
            None
        }
    }
}

#[test]
fn test_exclusive() {
    let mut g: BinGraph<&'static str> = BinGraph::new();
    g.actions.push("Go swiming");
    g.actions.push("Read a book");

    let suggestion = g.suggestion().unwrap();
    assert_eq!(suggestion, BinStateChoices::from_pairs([
        (false, true),
        (false, true)
    ]));

    g.data.push(suggestion);

    g.push_pairs([
        (true, true), // is swimming, can stop.
        (false, false), // is not reading book, can't read book.
    ]);
}

<commit_msg>Added `BinGraph::contains_choice`<commit_after>#![crate_name = "binstat"]
#![deny(missing_doc)]

//! A library for modelling and reasoning about multidimensional
//! binary states.

#[cfg(test)]
extern crate debug;

use std::collections::Bitv;

/// Contains a binary state and the choices.
#[deriving(PartialEq, Eq, Show, Clone)]
pub struct BinStateChoices {
    /// The state composed of bits.
    pub state: Bitv,
    /// The choices represented as bits that can be flipped.
    pub choices: Bitv
}

impl BinStateChoices {
    /// Gets pairs from pair of booleans.
    pub fn from_pairs(pairs: &[(bool, bool)]) -> BinStateChoices {
        BinStateChoices {
            state: pairs.iter().map(|&(a, _)| a).collect(),
            choices: pairs.iter().map(|&(_, b)| b).collect()
        }
    }

    /// Call closure for each available choice.
    #[inline(always)]
    pub fn with_choices(&self, f: |i: uint|) {
        for i in range(0, self.choices.len())
            .zip(self.choices.iter())
            .filter(|&(_, v)| v == true)
            .map(|(i, _)| i
        ) {
            f(i)
        }
    }
}

/// Models a multidimensional binary state.
pub struct BinGraph<TAction> {
    /// The states and the bits that can be flipped.
    pub data: Vec<BinStateChoices>,
    /// A description the action that takes when flipping bits.
    pub actions: Vec<TAction>,
}

impl<TAction> BinGraph<TAction> {
    /// Creates a new BinGraph.
    pub fn new() -> BinGraph<TAction> {
        BinGraph {
            data: Vec::new(),
            actions: Vec::new()
        }
    }

    /// Adds new information about state and choices.
    ///
    /// The first bool indicate state, the second whether it can change.
    pub fn push_pairs(&mut self, pairs: &[(bool, bool)]) {
        self.data.push(BinStateChoices::from_pairs(pairs));
    }

    /// Returns true if the graph contains a choice.
    pub fn contains_choice(&self, state: &BinStateChoices, i: uint) -> bool {
        self.data.iter().any(|st|
            range(0, st.choices.len()).all(|j|
                state.choices.get(j) == if j == i {
                        !state.choices.get(j)
                    } else {
                        state.choices.get(j)
                    }
            )
        )
    }

    /// Returns the suggestion in default state that are open to all choices.
    pub fn default_suggestion(&self) -> BinStateChoices {
        let open_for_all_choices: Vec<(bool, bool)> =
            range(0, self.actions.len()).map(|_| (false, true)).collect();
        BinStateChoices::from_pairs(open_for_all_choices.as_slice())
    }

    /// Suggests a missing state with choices.
    pub fn suggestion(&self) -> Option<BinStateChoices> {
        if self.data.len() == 0 {
            Some(self.default_suggestion())
        } else {
            None
        }
    }
}

#[test]
fn test_exclusive() {
    let mut g: BinGraph<&'static str> = BinGraph::new();
    g.actions.push("Go swiming");
    g.actions.push("Read a book");

    let suggestion = g.suggestion().unwrap();
    assert_eq!(suggestion, BinStateChoices::from_pairs([
        (false, true),
        (false, true)
    ]));

    g.data.push(suggestion.clone());

    assert!(!g.contains_choice(&suggestion, 0));

    g.push_pairs([
        (true, true), // is swimming, can stop.
        (false, false), // is not reading book, can't read book.
    ]);
}

<|endoftext|>


<commit_before>//! A library for creating General Game Playing (GGP) players. This library is based off of
//! [GGP Base](https://github.com/ggp-org/ggp-base). While GGP Base allows the creation of
//! players backed by a propositional network or a logic prover, this library currently only
//! supports logic prover based players.
//!
//! # Example
//!
//! To create your own player, simply implement the `Player` trait for your struct and pass the
//! host/port you want the player to run at and the player itself to the `run` function.
//!
//! The following example implements a RandomPlayer, which plays random legal moves each turn.
//!
//! ```
//! extern crate rand;
//! extern crate ggp_rs;
//!
//! use ggp_rs::{Player, Game, Move};
//! use std::net::Ipv4Addr;
//!
//! struct RandomPlayer;
//!
//! impl Player for RandomPlayer {
//!     fn get_name(&self) -> String {
//!         "RandomPlayer".to_string()
//!     }
//!
//!     fn select_move(&self, game: &Game) -> Move {
//!         let state = game.get_current_state();
//!         let role = game.get_role();
//!         let mut moves = game.get_legal_moves(state, role);
//!         let r = rand::random::<usize>() % moves.len();
//!         moves.swap_remove(r)
//!     }
//! }
//!
//! fn main() {
//!     ggp_rs::run((Ipv4Addr::new(0,0,0,0), 9147), RandomPlayer);
//! }
//! ```

#![feature(std_misc, plugin, collections)]
#![plugin(regex_macros)]

extern crate gdl_parser;
extern crate hyper;
extern crate regex;

#[macro_use]
extern crate log;

mod game_manager;
mod gdl;
mod prover;

use hyper::Server;
use hyper::server::{Request, Response, Handler};
use hyper::header::ContentLength;
use hyper::net::Fresh;

use std::net::ToSocketAddrs;
use std::io::Read;
use std::io::Write;
use std::ascii::OwnedAsciiExt;
use std::sync::Mutex;

use game_manager::GameManager;

pub use game_manager::{Game, State};
pub use gdl::{Move, Role, Score};

/// A GGP player
pub trait Player {
    fn get_name(&self) -> String;

    fn meta_game(&self, _: &Game) {}

    fn select_move(&self, game: &Game) -> Move;

    fn stop(&self, _: &Game) {}
}

/// Starts a GGP player listening at `host`
pub fn run<T: ToSocketAddrs + 'static, P: Player + Sync + Send + 'static>(host: T, player: P) {
    let handler = GameHandler::new(player);
    Server::http(handler).listen(host).unwrap();
}

struct GameHandler<P: Player + Send> {
    pub gm: Mutex<GameManager<P>>
}

impl<P: Player + Send> GameHandler<P> {
    pub fn new(player: P) -> GameHandler<P> {
        GameHandler { gm: Mutex::new(GameManager::new(player)) }
    }
}

impl<P: Player + Sync + Send> Handler for GameHandler<P> {
    fn handle(&self, mut req: Request, mut res: Response<Fresh>) {
        let mut s = String::new();
        req.read_to_string(&mut s).unwrap();
        let s = s.into_ascii_lowercase();
        info!("Got request: {}", s);

        let mut gm = self.gm.lock().unwrap();
        let s = gm.handle(s);
        let s = s.into_bytes();
        res.headers_mut().set(ContentLength(s.len() as u64));
        let mut res = res.start().unwrap();
        res.write_all(&s).unwrap();
        res.end().unwrap();
    }
}
<commit_msg>Don't test documentation example<commit_after>//! A library for creating General Game Playing (GGP) players. This library is based off of
//! [GGP Base](https://github.com/ggp-org/ggp-base). While GGP Base allows the creation of
//! players backed by a propositional network or a logic prover, this library currently only
//! supports logic prover based players.
//!
//! # Example
//!
//! To create your own player, simply implement the `Player` trait for your struct and pass the
//! host/port you want the player to run at and the player itself to the `run` function.
//!
//! The following example implements a RandomPlayer, which plays random legal moves each turn.
//!
//! ```ignore
//! extern crate rand;
//! extern crate ggp_rs;
//!
//! use ggp_rs::{Player, Game, Move};
//! use std::net::Ipv4Addr;
//!
//! struct RandomPlayer;
//!
//! impl Player for RandomPlayer {
//!     fn get_name(&self) -> String {
//!         "RandomPlayer".to_string()
//!     }
//!
//!     fn select_move(&self, game: &Game) -> Move {
//!         let state = game.get_current_state();
//!         let role = game.get_role();
//!         let mut moves = game.get_legal_moves(state, role);
//!         let r = rand::random::<usize>() % moves.len();
//!         moves.swap_remove(r)
//!     }
//! }
//!
//! fn main() {
//!     ggp_rs::run((Ipv4Addr::new(0,0,0,0), 9147), RandomPlayer);
//! }
//! ```

#![feature(std_misc, plugin, collections)]
#![plugin(regex_macros)]

extern crate gdl_parser;
extern crate hyper;
extern crate regex;

#[macro_use]
extern crate log;

mod game_manager;
mod gdl;
mod prover;

use hyper::Server;
use hyper::server::{Request, Response, Handler};
use hyper::header::ContentLength;
use hyper::net::Fresh;

use std::net::ToSocketAddrs;
use std::io::Read;
use std::io::Write;
use std::ascii::OwnedAsciiExt;
use std::sync::Mutex;

use game_manager::GameManager;

pub use game_manager::{Game, State};
pub use gdl::{Move, Role, Score};

/// A GGP player
pub trait Player {
    fn get_name(&self) -> String;

    fn meta_game(&self, _: &Game) {}

    fn select_move(&self, game: &Game) -> Move;

    fn stop(&self, _: &Game) {}
}

/// Starts a GGP player listening at `host`
pub fn run<T: ToSocketAddrs + 'static, P: Player + Sync + Send + 'static>(host: T, player: P) {
    let handler = GameHandler::new(player);
    Server::http(handler).listen(host).unwrap();
}

struct GameHandler<P: Player + Send> {
    pub gm: Mutex<GameManager<P>>
}

impl<P: Player + Send> GameHandler<P> {
    pub fn new(player: P) -> GameHandler<P> {
        GameHandler { gm: Mutex::new(GameManager::new(player)) }
    }
}

impl<P: Player + Sync + Send> Handler for GameHandler<P> {
    fn handle(&self, mut req: Request, mut res: Response<Fresh>) {
        let mut s = String::new();
        req.read_to_string(&mut s).unwrap();
        let s = s.into_ascii_lowercase();
        info!("Got request: {}", s);

        let mut gm = self.gm.lock().unwrap();
        let s = gm.handle(s);
        let s = s.into_bytes();
        res.headers_mut().set(ContentLength(s.len() as u64));
        let mut res = res.start().unwrap();
        res.write_all(&s).unwrap();
        res.end().unwrap();
    }
}
<|endoftext|>


<commit_before>//! # Mime
//!
//! Mime is now Media Type, technically, but `Mime` is more immediately
//! understandable, so the main type here is `Mime`.
//!
//! ## What is Mime?
//!
//! Example mime string: `text/plain;charset=utf-8`
//!
//! ```rust
//! # use std::from_str::FromStr;
//! use mime::{Mime, Text, Plain, Charset, Utf8};
//! let mime: Mime = FromStr::from_str("text/plain;charset=utf-8").unwrap();
//! assert_eq!(mime, Mime(Text, Plain, vec![(Charset, Utf8)]));
//! ```

#![license = "MIT"]
#![doc(html_root_url = "http://seanmonstar.github.io/mime.rs")]
#![experimental]
#![feature(macro_rules, phase)]

#[phase(plugin, link)]
extern crate log;

#[cfg(test)]
extern crate test;

use std::ascii::AsciiExt;
use std::cmp::Equiv;
use std::fmt;
use std::from_str::FromStr;
use std::iter::Enumerate;
use std::str::Chars;

macro_rules! inspect(
    ($s:expr, $t:expr) => ({
        let t = $t;
        debug!("inspect {}: {}", $s, t);
        t
    })
)

/// Mime, or Media Type. Encapsulates common registers types.
///
/// Consider that a traditional mime type contains a "top level type",
/// a "sub level type", and 0-N "parameters". And they're all strings.
/// Strings everywhere. Strings mean typos. Rust has type safety. We should
/// use types!
///
/// So, Mime bundles together this data into types so the compiler can catch
/// your typos.
///
/// This improves things so you use match without Strings:
///
/// ```rust
/// use std::from_str::from_str;
/// use mime::{Mime, Application, Json};
///
/// let mime: mime::Mime = from_str("application/json").unwrap();
///
/// match mime {
///     Mime(Application, Json, _) => println!("matched json!"),
///     _ => ()
/// }
/// ```
#[deriving(Clone, PartialEq)]
pub struct Mime(pub TopLevel, pub SubLevel, pub Vec<Param>);

macro_rules! enoom (
    (pub enum $en:ident; $ext:ident; $($ty:ident, $text:expr;)*) => (

        #[deriving(Clone, PartialEq)]
        pub enum $en {
            $($ty),*,
            $ext(String)
        }

        impl fmt::Show for $en {
            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
                match *self {
                    $($ty => $text),*,
                    $ext(ref s) => return s.fmt(fmt)
                }.fmt(fmt)
            }
        }

        impl FromStr for $en {
            fn from_str(s: &str) -> Option<$en> {
                Some(match s {
                    $(_s if _s == $text => $ty),*,
                    s => $ext(inspect!(stringify!($ext), s).to_string())
                })
            }
        }
    )
)

enoom! {
    pub enum TopLevel;
    TopExt;
    TopStar, "*"; // remove Top prefix if enums gain namespaces
    Text, "text";
    Image, "image";
    Audio, "audio";
    Video, "video";
    Application, "application";
    Multipart, "multipart";
    Message, "message";
    Model, "model";
}

enoom! {
    pub enum SubLevel;
    SubExt;
    SubStar, "*"; // remove Sub prefix if enums gain namespaces

    // common text/*
    Plain, "plain";
    Html, "html";
    Xml, "xml";
    Javascript, "javascript";
    Css, "css";

    // common application/*
    Json, "json";

    // common image/*
    Png, "png";
    Gif, "gif";
    Bmp, "bmp";
    Jpeg, "jpeg";
}

enoom! {
    pub enum Attr;
    AttrExt;
    Charset, "charset";
    Q, "q";
}

enoom! {
    pub enum Value;
    ValueExt;
    Utf8, "utf-8";
}

pub type Param = (Attr, Value);

impl Equiv<Mime> for Mime {
    fn equiv(&self, other: &Mime) -> bool {
        //im so sorry
        //TODO: be less sorry. dont to_string()
        self.to_string() == other.to_string()
    }
}

impl fmt::Show for Mime {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let Mime(ref top, ref sub, ref params) = *self;
        try!(write!(fmt, "{}/{}", top, sub));
        fmt_params(params.as_slice(), fmt)
    }
}

impl FromStr for Mime {
    fn from_str(raw: &str) -> Option<Mime> {
        let ascii = raw.to_ascii_lower(); // lifetimes :(
        let raw = ascii.as_slice();
        let len = raw.len();
        let mut iter = raw.chars().enumerate();
        let mut params = vec![];
        // toplevel
        let mut start;
        let mut top;
        loop {
            match inspect!("top iter", iter.next()) {
                Some((0, c)) if is_restricted_name_first_char(c) => (),
                Some((i, c)) if i > 0 && is_restricted_name_char(c) => (),
                Some((i, '/')) if i > 0 => match FromStr::from_str(raw.slice_to(i)) {
                    Some(t) => {
                        top = t;
                        start = i + 1;
                        break;
                    }
                    None => return None
                },
                _ => return None // EOF and no toplevel is no Mime
            };

        }

        // sublevel
        let mut sub;
        loop {
            match inspect!("sub iter", iter.next()) {
                Some((i, c)) if i == start && is_restricted_name_first_char(c) => (),
                Some((i, c)) if i > start && is_restricted_name_char(c) => (),
                Some((i, ';')) if i > start => match FromStr::from_str(raw.slice(start, i)) {
                    Some(s) => {
                        sub = s;
                        start = i + 1;
                        break;
                    }
                    None => return None
                },
                None => match FromStr::from_str(raw.slice_from(start)) {
                    Some(s) => return Some(Mime(top, s, params)),
                    None => return None
                },
                _ => return None
            };
        }

        // params
        debug!("starting params, len={}", len);
        loop {
            match inspect!("param", param_from_str(raw, &mut iter, start)) {
                Some((p, end)) => {
                    params.push(p);
                    start = end;
                    if start >= len {
                        break;
                    }
                }
                None => break
            }
        }

        Some(Mime(top, sub, params))
    }
}

fn param_from_str(raw: &str, iter: &mut Enumerate<Chars>, mut start: uint) -> Option<(Param, uint)> {
    let mut attr;
    debug!("param_from_str, start={}", start);
    loop {
        match inspect!("attr iter", iter.next()) {
            Some((i, ' ')) if i == start => start = i + 1,
            Some((i, c)) if i == start && is_restricted_name_first_char(c) => (),
            Some((i, c)) if i > start && is_restricted_name_char(c) => (),
            Some((i, '=')) if i > start => match FromStr::from_str(raw.slice(start, i)) {
                Some(a) => {
                    attr = inspect!("attr", a);
                    start = i + 1;
                    break;
                },
                None => return None
            },
            _ => return None
        }
    }
    let mut value;
    // values must be restrict-name-char or "anything goes"
    let mut is_quoted = false;
    loop {
        match inspect!("value iter", iter.next()) {
            Some((i, '"')) if i == start => {
                debug!("quoted");
                is_quoted = true;
                start = i + 1;
            },
            Some((i, c)) if i == start && is_restricted_name_first_char(c) => (),
            Some((i, '"')) if i > start && is_quoted => match FromStr::from_str(raw.slice(start, i)) {
                Some(v) => {
                    value = v;
                    start = i + 1;
                    break;
                },
                None => return None
            },
            Some((i, c)) if i > start && is_quoted || is_restricted_name_char(c) => (),
            Some((i, ';')) if i > start => match FromStr::from_str(raw.slice(start, i)) {
                Some(v) => {
                    value = v;
                    start = i + 1;
                    break;
                },
                None => return None
            },
            None => match FromStr::from_str(raw.slice_from(start)) {
                Some(v) => {
                    value = v;
                    start = raw.len();
                    break;
                },
                None => return None
            },

            _ => return None
        }
    }

    Some(((attr, value), start))
}

// From [RFC6838](http://tools.ietf.org/html/rfc6838#section-4.2):
//
// > All registered media types MUST be assigned top-level type and
// > subtype names.  The combination of these names serves to uniquely
// > identify the media type, and the subtype name facet (or the absence
// > of one) identifies the registration tree.  Both top-level type and
// > subtype names are case-insensitive.
// >
// > Type and subtype names MUST conform to the following ABNF:
// >
// >     type-name = restricted-name
// >     subtype-name = restricted-name
// >
// >     restricted-name = restricted-name-first *126restricted-name-chars
// >     restricted-name-first  = ALPHA / DIGIT
// >     restricted-name-chars  = ALPHA / DIGIT / "!" / "#" /
// >                              "$" / "&" / "-" / "^" / "_"
// >     restricted-name-chars =/ "." ; Characters before first dot always
// >                                  ; specify a facet name
// >     restricted-name-chars =/ "+" ; Characters after last plus always
// >                                  ; specify a structured syntax suffix
//
fn is_restricted_name_first_char(c: char) -> bool {
    match c {
        'a'...'z' |
        '0'...'9' => true,
        _ => false
    }
}

fn is_restricted_name_char(c: char) -> bool {
    if is_restricted_name_first_char(c) {
        true
    } else {
        match c {
            '!' |
            '#' |
            '$' |
            '&' |
            '-' |
            '^' |
            '.' |
            '+' |
            '_' => true,
            _ => false
        }
    }
}

#[inline]
fn fmt_params<T: AsSlice<Param>>(params: T, fmt: &mut fmt::Formatter) -> fmt::Result {
    for param in params.as_slice().iter() {
        try!(fmt_param(param, fmt));
    }
    Ok(())
}

#[inline]
fn fmt_param(param: &Param, fmt: &mut fmt::Formatter) -> fmt::Result {
    let (ref attr, ref value) = *param;
    write!(fmt, "; {}={}", attr, value)
}

#[cfg(test)]
mod tests {
    use std::from_str::{FromStr, from_str};
    use test::Bencher;
    use super::{Mime, Text, Plain, Charset, Utf8, AttrExt, ValueExt};

    #[test]
    fn test_mime_show() {
        let mime = Mime(Text, Plain, vec![]);
        assert_eq!(mime.to_string(), "text/plain".to_string());
        let mime = Mime(Text, Plain, vec![(Charset, Utf8)]);
        assert_eq!(mime.to_string(), "text/plain; charset=utf-8".to_string());
    }

    #[test]
    fn test_mime_from_str() {
        assert_eq!(FromStr::from_str("text/plain"), Some(Mime(Text, Plain, vec![])));
        assert_eq!(FromStr::from_str("TEXT/PLAIN"), Some(Mime(Text, Plain, vec![])));
        assert_eq!(FromStr::from_str("text/plain; charset=utf-8"), Some(Mime(Text, Plain, vec![(Charset, Utf8)])));
        assert_eq!(FromStr::from_str("text/plain;charset=\"utf-8\""), Some(Mime(Text, Plain, vec![(Charset, Utf8)])));
        assert_eq!(FromStr::from_str("text/plain; charset=utf-8; foo=bar"),
            Some(Mime(Text, Plain, vec![(Charset, Utf8),
                                        (AttrExt("foo".to_string()), ValueExt("bar".to_string())) ])));
    }

    #[bench]
    fn bench_show(b: &mut Bencher) {
        let mime = Mime(Text, Plain, vec![(Charset, Utf8), (AttrExt("foo".to_string()), ValueExt("bar".to_string()))]);
        b.bytes = mime.to_string().as_bytes().len() as u64;
        b.iter(|| mime.to_string())
    }

    #[bench]
    fn bench_from_str(b: &mut Bencher) {
        let s = "text/plain; charset=utf-8; foo=bar";
        b.bytes = s.as_bytes().len() as u64;
        b.iter(|| from_str::<Mime>(s))
    }
}
<commit_msg>add WwwFormUrlEncoded subtype<commit_after>//! # Mime
//!
//! Mime is now Media Type, technically, but `Mime` is more immediately
//! understandable, so the main type here is `Mime`.
//!
//! ## What is Mime?
//!
//! Example mime string: `text/plain;charset=utf-8`
//!
//! ```rust
//! # use std::from_str::FromStr;
//! use mime::{Mime, Text, Plain, Charset, Utf8};
//! let mime: Mime = FromStr::from_str("text/plain;charset=utf-8").unwrap();
//! assert_eq!(mime, Mime(Text, Plain, vec![(Charset, Utf8)]));
//! ```

#![license = "MIT"]
#![doc(html_root_url = "http://seanmonstar.github.io/mime.rs")]
#![experimental]
#![feature(macro_rules, phase)]

#[phase(plugin, link)]
extern crate log;

#[cfg(test)]
extern crate test;

use std::ascii::AsciiExt;
use std::cmp::Equiv;
use std::fmt;
use std::from_str::FromStr;
use std::iter::Enumerate;
use std::str::Chars;

macro_rules! inspect(
    ($s:expr, $t:expr) => ({
        let t = $t;
        debug!("inspect {}: {}", $s, t);
        t
    })
)

/// Mime, or Media Type. Encapsulates common registers types.
///
/// Consider that a traditional mime type contains a "top level type",
/// a "sub level type", and 0-N "parameters". And they're all strings.
/// Strings everywhere. Strings mean typos. Rust has type safety. We should
/// use types!
///
/// So, Mime bundles together this data into types so the compiler can catch
/// your typos.
///
/// This improves things so you use match without Strings:
///
/// ```rust
/// use std::from_str::from_str;
/// use mime::{Mime, Application, Json};
///
/// let mime: mime::Mime = from_str("application/json").unwrap();
///
/// match mime {
///     Mime(Application, Json, _) => println!("matched json!"),
///     _ => ()
/// }
/// ```
#[deriving(Clone, PartialEq)]
pub struct Mime(pub TopLevel, pub SubLevel, pub Vec<Param>);

macro_rules! enoom (
    (pub enum $en:ident; $ext:ident; $($ty:ident, $text:expr;)*) => (

        #[deriving(Clone, PartialEq)]
        pub enum $en {
            $($ty),*,
            $ext(String)
        }

        impl fmt::Show for $en {
            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
                match *self {
                    $($ty => $text),*,
                    $ext(ref s) => return s.fmt(fmt)
                }.fmt(fmt)
            }
        }

        impl FromStr for $en {
            fn from_str(s: &str) -> Option<$en> {
                Some(match s {
                    $(_s if _s == $text => $ty),*,
                    s => $ext(inspect!(stringify!($ext), s).to_string())
                })
            }
        }
    )
)

enoom! {
    pub enum TopLevel;
    TopExt;
    TopStar, "*"; // remove Top prefix if enums gain namespaces
    Text, "text";
    Image, "image";
    Audio, "audio";
    Video, "video";
    Application, "application";
    Multipart, "multipart";
    Message, "message";
    Model, "model";
}

enoom! {
    pub enum SubLevel;
    SubExt;
    SubStar, "*"; // remove Sub prefix if enums gain namespaces

    // common text/*
    Plain, "plain";
    Html, "html";
    Xml, "xml";
    Javascript, "javascript";
    Css, "css";

    // common application/*
    Json, "json";
    WwwFormUrlEncoded, "x-www-form-urlencoded";

    // common image/*
    Png, "png";
    Gif, "gif";
    Bmp, "bmp";
    Jpeg, "jpeg";
}

enoom! {
    pub enum Attr;
    AttrExt;
    Charset, "charset";
    Q, "q";
}

enoom! {
    pub enum Value;
    ValueExt;
    Utf8, "utf-8";
}

pub type Param = (Attr, Value);

impl Equiv<Mime> for Mime {
    fn equiv(&self, other: &Mime) -> bool {
        //im so sorry
        //TODO: be less sorry. dont to_string()
        self.to_string() == other.to_string()
    }
}

impl fmt::Show for Mime {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let Mime(ref top, ref sub, ref params) = *self;
        try!(write!(fmt, "{}/{}", top, sub));
        fmt_params(params.as_slice(), fmt)
    }
}

impl FromStr for Mime {
    fn from_str(raw: &str) -> Option<Mime> {
        let ascii = raw.to_ascii_lower(); // lifetimes :(
        let raw = ascii.as_slice();
        let len = raw.len();
        let mut iter = raw.chars().enumerate();
        let mut params = vec![];
        // toplevel
        let mut start;
        let mut top;
        loop {
            match inspect!("top iter", iter.next()) {
                Some((0, c)) if is_restricted_name_first_char(c) => (),
                Some((i, c)) if i > 0 && is_restricted_name_char(c) => (),
                Some((i, '/')) if i > 0 => match FromStr::from_str(raw.slice_to(i)) {
                    Some(t) => {
                        top = t;
                        start = i + 1;
                        break;
                    }
                    None => return None
                },
                _ => return None // EOF and no toplevel is no Mime
            };

        }

        // sublevel
        let mut sub;
        loop {
            match inspect!("sub iter", iter.next()) {
                Some((i, c)) if i == start && is_restricted_name_first_char(c) => (),
                Some((i, c)) if i > start && is_restricted_name_char(c) => (),
                Some((i, ';')) if i > start => match FromStr::from_str(raw.slice(start, i)) {
                    Some(s) => {
                        sub = s;
                        start = i + 1;
                        break;
                    }
                    None => return None
                },
                None => match FromStr::from_str(raw.slice_from(start)) {
                    Some(s) => return Some(Mime(top, s, params)),
                    None => return None
                },
                _ => return None
            };
        }

        // params
        debug!("starting params, len={}", len);
        loop {
            match inspect!("param", param_from_str(raw, &mut iter, start)) {
                Some((p, end)) => {
                    params.push(p);
                    start = end;
                    if start >= len {
                        break;
                    }
                }
                None => break
            }
        }

        Some(Mime(top, sub, params))
    }
}

fn param_from_str(raw: &str, iter: &mut Enumerate<Chars>, mut start: uint) -> Option<(Param, uint)> {
    let mut attr;
    debug!("param_from_str, start={}", start);
    loop {
        match inspect!("attr iter", iter.next()) {
            Some((i, ' ')) if i == start => start = i + 1,
            Some((i, c)) if i == start && is_restricted_name_first_char(c) => (),
            Some((i, c)) if i > start && is_restricted_name_char(c) => (),
            Some((i, '=')) if i > start => match FromStr::from_str(raw.slice(start, i)) {
                Some(a) => {
                    attr = inspect!("attr", a);
                    start = i + 1;
                    break;
                },
                None => return None
            },
            _ => return None
        }
    }
    let mut value;
    // values must be restrict-name-char or "anything goes"
    let mut is_quoted = false;
    loop {
        match inspect!("value iter", iter.next()) {
            Some((i, '"')) if i == start => {
                debug!("quoted");
                is_quoted = true;
                start = i + 1;
            },
            Some((i, c)) if i == start && is_restricted_name_first_char(c) => (),
            Some((i, '"')) if i > start && is_quoted => match FromStr::from_str(raw.slice(start, i)) {
                Some(v) => {
                    value = v;
                    start = i + 1;
                    break;
                },
                None => return None
            },
            Some((i, c)) if i > start && is_quoted || is_restricted_name_char(c) => (),
            Some((i, ';')) if i > start => match FromStr::from_str(raw.slice(start, i)) {
                Some(v) => {
                    value = v;
                    start = i + 1;
                    break;
                },
                None => return None
            },
            None => match FromStr::from_str(raw.slice_from(start)) {
                Some(v) => {
                    value = v;
                    start = raw.len();
                    break;
                },
                None => return None
            },

            _ => return None
        }
    }

    Some(((attr, value), start))
}

// From [RFC6838](http://tools.ietf.org/html/rfc6838#section-4.2):
//
// > All registered media types MUST be assigned top-level type and
// > subtype names.  The combination of these names serves to uniquely
// > identify the media type, and the subtype name facet (or the absence
// > of one) identifies the registration tree.  Both top-level type and
// > subtype names are case-insensitive.
// >
// > Type and subtype names MUST conform to the following ABNF:
// >
// >     type-name = restricted-name
// >     subtype-name = restricted-name
// >
// >     restricted-name = restricted-name-first *126restricted-name-chars
// >     restricted-name-first  = ALPHA / DIGIT
// >     restricted-name-chars  = ALPHA / DIGIT / "!" / "#" /
// >                              "$" / "&" / "-" / "^" / "_"
// >     restricted-name-chars =/ "." ; Characters before first dot always
// >                                  ; specify a facet name
// >     restricted-name-chars =/ "+" ; Characters after last plus always
// >                                  ; specify a structured syntax suffix
//
fn is_restricted_name_first_char(c: char) -> bool {
    match c {
        'a'...'z' |
        '0'...'9' => true,
        _ => false
    }
}

fn is_restricted_name_char(c: char) -> bool {
    if is_restricted_name_first_char(c) {
        true
    } else {
        match c {
            '!' |
            '#' |
            '$' |
            '&' |
            '-' |
            '^' |
            '.' |
            '+' |
            '_' => true,
            _ => false
        }
    }
}

#[inline]
fn fmt_params<T: AsSlice<Param>>(params: T, fmt: &mut fmt::Formatter) -> fmt::Result {
    for param in params.as_slice().iter() {
        try!(fmt_param(param, fmt));
    }
    Ok(())
}

#[inline]
fn fmt_param(param: &Param, fmt: &mut fmt::Formatter) -> fmt::Result {
    let (ref attr, ref value) = *param;
    write!(fmt, "; {}={}", attr, value)
}

#[cfg(test)]
mod tests {
    use std::from_str::{FromStr, from_str};
    use test::Bencher;
    use super::{Mime, Text, Plain, Charset, Utf8, AttrExt, ValueExt};

    #[test]
    fn test_mime_show() {
        let mime = Mime(Text, Plain, vec![]);
        assert_eq!(mime.to_string(), "text/plain".to_string());
        let mime = Mime(Text, Plain, vec![(Charset, Utf8)]);
        assert_eq!(mime.to_string(), "text/plain; charset=utf-8".to_string());
    }

    #[test]
    fn test_mime_from_str() {
        assert_eq!(FromStr::from_str("text/plain"), Some(Mime(Text, Plain, vec![])));
        assert_eq!(FromStr::from_str("TEXT/PLAIN"), Some(Mime(Text, Plain, vec![])));
        assert_eq!(FromStr::from_str("text/plain; charset=utf-8"), Some(Mime(Text, Plain, vec![(Charset, Utf8)])));
        assert_eq!(FromStr::from_str("text/plain;charset=\"utf-8\""), Some(Mime(Text, Plain, vec![(Charset, Utf8)])));
        assert_eq!(FromStr::from_str("text/plain; charset=utf-8; foo=bar"),
            Some(Mime(Text, Plain, vec![(Charset, Utf8),
                                        (AttrExt("foo".to_string()), ValueExt("bar".to_string())) ])));
    }

    #[bench]
    fn bench_show(b: &mut Bencher) {
        let mime = Mime(Text, Plain, vec![(Charset, Utf8), (AttrExt("foo".to_string()), ValueExt("bar".to_string()))]);
        b.bytes = mime.to_string().as_bytes().len() as u64;
        b.iter(|| mime.to_string())
    }

    #[bench]
    fn bench_from_str(b: &mut Bencher) {
        let s = "text/plain; charset=utf-8; foo=bar";
        b.bytes = s.as_bytes().len() as u64;
        b.iter(|| from_str::<Mime>(s))
    }
}
<|endoftext|>


<commit_before>//! Example usage:
//!
//! ```
//! use perfcnt::{AbstractPerfCounter, PerfCounter};
//! use perfcnt::linux::{PerfCounterBuilderLinux, HardwareEventType};
//!
//! let mut pc: PerfCounter =
//!     PerfCounterBuilderLinux::from_hardware_event(HardwareEventType::CacheMisses)
//!         .finish().expect("Can not create the counter");
//! pc.start().expect("Can not start the counter");
//! pc.stop().expect("Can not start the counter");
//! let res = pc.read().expect("Can not read the counter");
//! println!("Measured {} cache misses.", res);
//! ```

pub mod linux;
pub use crate::linux::PerfCounter;

use std::io;

/// Abstract trait to control performance counters.
pub trait AbstractPerfCounter {
    /// Reset performance counter.
    fn reset(&self) -> Result<(), io::Error>;

    /// Start measuring.
    fn start(&self) -> Result<(), io::Error>;

    /// Stop measuring.
    fn stop(&self) -> Result<(), io::Error>;

    /// Read the counter value.
    fn read(&mut self) -> Result<u64, io::Error>;
}
<commit_msg>Update documentation code<commit_after>//! Example usage:
//!
//! ```
//! use perfcnt::{AbstractPerfCounter, PerfCounter};
//! use perfcnt::linux::{PerfCounterBuilderLinux, HardwareEventType};
//!
//! let mut pc: PerfCounter =
//!     PerfCounterBuilderLinux::from_hardware_event(HardwareEventType::CacheMisses)
//!         .finish()?;
//! pc.start().expect("Can not start the counter");
//! pc.stop().expect("Can not start the counter");
//! let res = pc.read().expect("Can not read the counter");
//! println!("Measured {} cache misses.", res);
//! ```

pub mod linux;
pub use crate::linux::PerfCounter;

use std::io;

/// Abstract trait to control performance counters.
pub trait AbstractPerfCounter {
    /// Reset performance counter.
    fn reset(&self) -> Result<(), io::Error>;

    /// Start measuring.
    fn start(&self) -> Result<(), io::Error>;

    /// Stop measuring.
    fn stop(&self) -> Result<(), io::Error>;

    /// Read the counter value.
    fn read(&mut self) -> Result<u64, io::Error>;
}
<|endoftext|>


<commit_before>extern crate libc;

#[cfg(feature = "dlopen")]
#[macro_export]
macro_rules! ffi_dispatch(
    ($handle: ident, $func: ident, $($arg: expr),*) => (
        ($handle.$func)($($arg),*)
    )
);

#[cfg(not(feature = "dlopen"))]
#[macro_export]
macro_rules! ffi_dispatch(
    ($handle: ident, $func: ident, $($arg: expr),*) => (
        $func($($arg),*)
    )
);

#[cfg(feature = "dlopen")]
#[macro_export]
macro_rules! ffi_dispatch_static(
    ($handle: ident, $name: ident) => (
        $handle.$name
    )
);

#[cfg(not(feature = "dlopen"))]
#[macro_export]
macro_rules! ffi_dispatch_static(
    ($handle: ident, $name: ident) => (
        &$name
    )
);

#[cfg(not(feature = "dlopen"))]
#[macro_export]
macro_rules! external_library(
    ($structname: ident, $link: expr,
        $(statics: $($sname: ident: $stype: ty),+)|*
        $(functions: $(fn $fname: ident($($farg: ty),*) -> $fret:ty),+)|*
        $(varargs: $(fn $vname: ident($($vargs: ty),+ ...) -> $vret: ty),+)|*
    ) => (
        #[link(name = $link)]
        extern {
            $($(
                pub static $sname: $stype;
            )+)*
            $($(
                pub fn $fname($(_: $farg),*) -> $fret;
            )+)*
            $($(
                pub fn $vname($(_: $vargs),+ , ...) -> $vret;
            )+)*
        }
    );
);

pub enum DlError {
    NotFound,
    MissingSymbol(&'static str)
}

#[cfg(feature = "dlopen")]
#[macro_export]
macro_rules! external_library(
    (__struct, $structname: ident, $link: expr,
        $(statics: $($sname: ident: $stype: ty),+)|*
        $(functions: $(fn $fname: ident($($farg: ty),*) -> $fret:ty),+)|*
        $(varargs: $(fn $vname: ident($($vargs: ty),+ ...) -> $vret: ty),+)|*
    ) => (
        pub struct $structname {
            $($(
                pub $sname: &'static $stype,
            )+)*
            $($(
                pub $fname: unsafe extern fn($($farg),*) -> $fret,
            )+)*
            $($(
                pub $vname: unsafe extern "C" fn($($vargs),+ , ...) -> $vret,
            )+)*
        }
    );
    (__impl, $structname: ident,
        $(statics: $($sname: ident: $stype: ty),+)|*
        $(functions: $(fn $fname: ident($($farg: ty),*) -> $fret:ty),+)|*
        $(varargs: $(fn $vname: ident($($vargs: ty),+ ...) -> $vret: ty),+)|*
    ) => (
    impl $structname {
        pub fn open(name: &str) -> Result<$structname, DlError> {
            let cname = match ::std::ffi::CString::new(name) {
                Ok(cs) => cs,
                Err(_) => Err(DlError::NotFound)
            };
            unsafe {
                let dl = $crate::ffi::dlopen(cname.as_bytes_with_nul().as_ptr() as *const _, 1);
                if dl.is_null() {
                    return Err(DlError::NotFound);
                }
                $crate::ffi::dlerror();
                let s = $structname {
                    $($($sname: {
                        let s_name = concat!(stringify!($sname), "\0");
                        let symbol = $crate::ffi::dlsym(dl, s_name.as_ptr() as *const _);
                        if !$crate::ffi::dlerror().is_null() {
                            return Err(DlError::MissingSymbol(s_name))
                        }
                        ::std::mem::transmute(symbol)
                    },
                    )+)*
                    $($($fname: {
                        let s_name = concat!(stringify!($fname), "\0");
                        let symbol = $crate::ffi::dlsym(dl, s_name.as_ptr() as *const _);
                        if !$crate::ffi::dlerror().is_null() {
                            return Err(DlError::MissingSymbol(s_name))
                        }
                        ::std::mem::transmute(symbol)
                    },
                    )+)*
                    $($($vname: {
                        let s_name = concat!(stringify!($vname), "\0");
                        let symbol = $crate::ffi::dlsym(dl, s_name.as_ptr() as *const _);
                        if !$crate::ffi::dlerror().is_null() {
                            return Err(DlError::MissingSymbol(s_name))
                        }
                        ::std::mem::transmute(symbol)
                    },
                    )+)*
                };
                Ok(s)
            }
        }
    }
    );
    ($structname: ident,
        $(statics: $($sname: ident: $stype: ty),+)|*
        $(functions: $(fn $fname: ident($($farg: ty),*) -> $fret:ty),+)|*
        $(varargs: $(fn $vname: ident($($vargs: ty),+ ...) -> $vret: ty),+)|*
    ) => (
        external_library!(__struct,
            $structname, $(statics: $($sname: $stype),+)|*
            $(functions: $(fn $fname($($farg),*) -> $fret),+)|*
           $(varargs: $(fn $vname($($vargs),+ ...) -> $vret),+)|*
        );
        external_library!(__impl,
            $structname, $(statics: $($sname: $stype),+)|*
            $(functions: $(fn $fname($($farg),*) -> $fret),+)|*
           $(varargs: $(fn $vname($($vargs),+ ...) -> $vret),+)|*
        );
        unsafe impl Sync for $structname { }
    );
);

pub mod ffi {
    use libc::{c_char, c_int, c_void};
    extern {
        pub fn dlopen(filename: *const c_char, flag: c_int) -> *mut c_void;
        pub fn dlerror() -> *mut c_char;
        pub fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void;
        pub fn dlclose(handle: *mut c_void) -> c_int;
    }
}<commit_msg>Bugfix.<commit_after>extern crate libc;

#[cfg(feature = "dlopen")]
#[macro_export]
macro_rules! ffi_dispatch(
    ($handle: ident, $func: ident, $($arg: expr),*) => (
        ($handle.$func)($($arg),*)
    )
);

#[cfg(not(feature = "dlopen"))]
#[macro_export]
macro_rules! ffi_dispatch(
    ($handle: ident, $func: ident, $($arg: expr),*) => (
        $func($($arg),*)
    )
);

#[cfg(feature = "dlopen")]
#[macro_export]
macro_rules! ffi_dispatch_static(
    ($handle: ident, $name: ident) => (
        $handle.$name
    )
);

#[cfg(not(feature = "dlopen"))]
#[macro_export]
macro_rules! ffi_dispatch_static(
    ($handle: ident, $name: ident) => (
        &$name
    )
);

#[cfg(not(feature = "dlopen"))]
#[macro_export]
macro_rules! external_library(
    ($structname: ident, $link: expr,
        $(statics: $($sname: ident: $stype: ty),+)|*
        $(functions: $(fn $fname: ident($($farg: ty),*) -> $fret:ty),+)|*
        $(varargs: $(fn $vname: ident($($vargs: ty),+ ...) -> $vret: ty),+)|*
    ) => (
        #[link(name = $link)]
        extern {
            $($(
                pub static $sname: $stype;
            )+)*
            $($(
                pub fn $fname($(_: $farg),*) -> $fret;
            )+)*
            $($(
                pub fn $vname($(_: $vargs),+ , ...) -> $vret;
            )+)*
        }
    );
);

pub enum DlError {
    NotFound,
    MissingSymbol(&'static str)
}

#[cfg(feature = "dlopen")]
#[macro_export]
macro_rules! external_library(
    (__struct, $structname: ident,
        $(statics: $($sname: ident: $stype: ty),+)|*
        $(functions: $(fn $fname: ident($($farg: ty),*) -> $fret:ty),+)|*
        $(varargs: $(fn $vname: ident($($vargs: ty),+ ...) -> $vret: ty),+)|*
    ) => (
        pub struct $structname {
            $($(
                pub $sname: &'static $stype,
            )+)*
            $($(
                pub $fname: unsafe extern fn($($farg),*) -> $fret,
            )+)*
            $($(
                pub $vname: unsafe extern "C" fn($($vargs),+ , ...) -> $vret,
            )+)*
        }
    );
    (__impl, $structname: ident,
        $(statics: $($sname: ident: $stype: ty),+)|*
        $(functions: $(fn $fname: ident($($farg: ty),*) -> $fret:ty),+)|*
        $(varargs: $(fn $vname: ident($($vargs: ty),+ ...) -> $vret: ty),+)|*
    ) => (
    impl $structname {
        pub fn open(name: &str) -> Result<$structname, DlError> {
            let cname = match ::std::ffi::CString::new(name) {
                Ok(cs) => cs,
                Err(_) => Err(DlError::NotFound)
            };
            unsafe {
                let dl = $crate::ffi::dlopen(cname.as_bytes_with_nul().as_ptr() as *const _, 1);
                if dl.is_null() {
                    return Err(DlError::NotFound);
                }
                $crate::ffi::dlerror();
                let s = $structname {
                    $($($sname: {
                        let s_name = concat!(stringify!($sname), "\0");
                        let symbol = $crate::ffi::dlsym(dl, s_name.as_ptr() as *const _);
                        if !$crate::ffi::dlerror().is_null() {
                            return Err(DlError::MissingSymbol(s_name))
                        }
                        ::std::mem::transmute(symbol)
                    },
                    )+)*
                    $($($fname: {
                        let s_name = concat!(stringify!($fname), "\0");
                        let symbol = $crate::ffi::dlsym(dl, s_name.as_ptr() as *const _);
                        if !$crate::ffi::dlerror().is_null() {
                            return Err(DlError::MissingSymbol(s_name))
                        }
                        ::std::mem::transmute(symbol)
                    },
                    )+)*
                    $($($vname: {
                        let s_name = concat!(stringify!($vname), "\0");
                        let symbol = $crate::ffi::dlsym(dl, s_name.as_ptr() as *const _);
                        if !$crate::ffi::dlerror().is_null() {
                            return Err(DlError::MissingSymbol(s_name))
                        }
                        ::std::mem::transmute(symbol)
                    },
                    )+)*
                };
                Ok(s)
            }
        }
    }
    );
    ($structname: ident, $link: expr,
        $(statics: $($sname: ident: $stype: ty),+)|*
        $(functions: $(fn $fname: ident($($farg: ty),*) -> $fret:ty),+)|*
        $(varargs: $(fn $vname: ident($($vargs: ty),+ ...) -> $vret: ty),+)|*
    ) => (
        external_library!(__struct,
            $structname, $(statics: $($sname: $stype),+)|*
            $(functions: $(fn $fname($($farg),*) -> $fret),+)|*
           $(varargs: $(fn $vname($($vargs),+ ...) -> $vret),+)|*
        );
        external_library!(__impl,
            $structname, $(statics: $($sname: $stype),+)|*
            $(functions: $(fn $fname($($farg),*) -> $fret),+)|*
           $(varargs: $(fn $vname($($vargs),+ ...) -> $vret),+)|*
        );
        unsafe impl Sync for $structname { }
    );
);

pub mod ffi {
    use libc::{c_char, c_int, c_void};
    extern {
        pub fn dlopen(filename: *const c_char, flag: c_int) -> *mut c_void;
        pub fn dlerror() -> *mut c_char;
        pub fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void;
        pub fn dlclose(handle: *mut c_void) -> c_int;
    }
}<|endoftext|>


<commit_before>#![crate_name = "amethyst"]
#![crate_type = "lib"]

//! Amethyst is a free and open source SDK (software development kit) written in
//! idiomatic [Rust](https://www.rust-lang.org/) for building video games and
//! interactive multimedia applications.
//!
//! This project is a work in progress and is very incomplete. Pardon the dust!
//!
//! # Example
//!
//! ```ignore
//! extern crate amethyst;
//!
//! use amethyst::*;
//!
//! struct GameState;
//!
//! impl State for GameState {
//!     fn handle_events(&mut self, events: &Vec<Event>) -> Trans {
//!         for e in events {
//!             match e {
//!                 Event::Closed => Trans::Quit,
//!                 Event::Resized(x, y) => println!("x: {}, y: {}", x, y),
//!                 Event::KeyPressed(k) => if k == Key::Esc { Trans::Quit },
//!             }
//!         }
//!         Trans::None
//!     }
//!
//!     fn update(&mut self, _delta: Duration) -> Trans {
//!         println!("Computing some more whoop-ass...");
//!         Trans::None
//!     }
//! }
//!
//! fn main() {
//!     let mut game = Application::new(GameState);
//!     game.run();
//! }
//! ```

mod engine;
pub mod renderer;

pub use self::engine::app::Application;
pub use self::engine::state::{State, StateMachine, Trans};
pub use self::engine::timing::{Duration, Stopwatch};
<commit_msg>clean up lib.rs doc comments<commit_after>#![crate_name = "amethyst"]
#![crate_type = "lib"]

//! Amethyst is a free and open source game engine written in idiomatic
//! [Rust][rs] for building video games and interactive multimedia applications.
//! The source code is available for free on [GitHub][gh].
//!
//! [rs]: https://www.rust-lang.org/
//! [gh]: https://github.com/ebkalderon/amethyst
//!
//! This project is a work in progress and is very incomplete. Pardon the dust!
//!
//! # Example
//!
//! ```ignore
//! extern crate amethyst;
//!
//! use amethyst::*;
//!
//! struct GameState;
//!
//! impl State for GameState {
//!     fn handle_events(&mut self, events: &Vec<Event>) -> Trans {
//!         for e in events {
//!             match e {
//!                 Event::Closed => Trans::Quit,
//!                 Event::Resized(x, y) => println!("x: {}, y: {}", x, y),
//!                 Event::KeyPressed(k) => if k == Key::Esc { Trans::Quit },
//!             }
//!         }
//!         Trans::None
//!     }
//!
//!     fn update(&mut self, _delta: Duration) -> Trans {
//!         println!("Computing some more whoop-ass...");
//!         Trans::None
//!     }
//! }
//!
//! fn main() {
//!     let mut game = Application::new(GameState);
//!     game.run();
//! }
//! ```

mod engine;
pub mod renderer;

pub use self::engine::app::Application;
pub use self::engine::state::{State, StateMachine, Trans};
pub use self::engine::timing::{Duration, Stopwatch};
<|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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. This file may not be copied, modified, or distributed
// except according to those terms.

/*!
Syntax extension to generate FourCCs.

Once loaded, fourcc!() is called with a single 4-character string,
and an optional ident that is either `big`, `little`, or `target`.
The ident represents endianness, and specifies in which direction
the characters should be read. If the ident is omitted, it is assumed
to be `big`, i.e. left-to-right order. It returns a u32.

# Examples

To load the extension and use it:

```rust,ignore
#[phase(plugin)]
extern crate fourcc;

fn main() {
    let val = fourcc!("\xC0\xFF\xEE!");
    assert_eq!(val, 0xC0FFEE21u32);
    let little_val = fourcc!("foo ", little);
    assert_eq!(little_val, 0x21EEFFC0u32);
}
```

# References

* [Wikipedia: FourCC](http://en.wikipedia.org/wiki/FourCC)

*/

#![crate_name = "fourcc"]
#![experimental]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico")]

#![feature(plugin_registrar, managed_boxes)]

extern crate syntax;
extern crate rustc;

use syntax::ast;
use syntax::attr::contains;
use syntax::codemap::{Span, mk_sp};
use syntax::ext::base;
use syntax::ext::base::{ExtCtxt, MacExpr};
use syntax::ext::build::AstBuilder;
use syntax::parse::token;
use syntax::parse::token::InternedString;
use syntax::ptr::P;
use rustc::plugin::Registry;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("fourcc", expand_syntax_ext);
}

pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                         -> Box<base::MacResult + 'static> {
    let (expr, endian) = parse_tts(cx, tts);

    let little = match endian {
        None => false,
        Some(Ident{ident, span}) => match token::get_ident(ident).get() {
            "little" => true,
            "big" => false,
            "target" => target_endian_little(cx, sp),
            _ => {
                cx.span_err(span, "invalid endian directive in fourcc!");
                target_endian_little(cx, sp)
            }
        }
    };

    let s = match expr.node {
        // expression is a literal
        ast::ExprLit(ref lit) => match lit.node {
            // string literal
            ast::LitStr(ref s, _) => {
                if s.get().char_len() != 4 {
                    cx.span_err(expr.span, "string literal with len != 4 in fourcc!");
                }
                s
            }
            _ => {
                cx.span_err(expr.span, "unsupported literal in fourcc!");
                return base::DummyResult::expr(sp)
            }
        },
        _ => {
            cx.span_err(expr.span, "non-literal in fourcc!");
            return base::DummyResult::expr(sp)
        }
    };

    let mut val = 0u32;
    for codepoint in s.get().chars().take(4) {
        let byte = if codepoint as u32 > 0xFF {
            cx.span_err(expr.span, "fourcc! literal character out of range 0-255");
            0u8
        } else {
            codepoint as u8
        };

        val = if little {
            (val >> 8) | ((byte as u32) << 24)
        } else {
            (val << 8) | (byte as u32)
        };
    }
    let e = cx.expr_lit(sp, ast::LitInt(val as u64, ast::UnsignedIntLit(ast::TyU32)));
    MacExpr::new(e)
}

struct Ident {
    ident: ast::Ident,
    span: Span
}

fn parse_tts(cx: &ExtCtxt,
             tts: &[ast::TokenTree]) -> (P<ast::Expr>, Option<Ident>) {
    let p = &mut cx.new_parser_from_tts(tts);
    let ex = p.parse_expr();
    let id = if p.token == token::EOF {
        None
    } else {
        p.expect(&token::COMMA);
        let lo = p.span.lo;
        let ident = p.parse_ident();
        let hi = p.last_span.hi;
        Some(Ident{ident: ident, span: mk_sp(lo, hi)})
    };
    if p.token != token::EOF {
        p.unexpected();
    }
    (ex, id)
}

fn target_endian_little(cx: &ExtCtxt, sp: Span) -> bool {
    let meta = cx.meta_name_value(sp, InternedString::new("target_endian"),
        ast::LitStr(InternedString::new("little"), ast::CookedStr));
    contains(cx.cfg().as_slice(), &*meta)
}

// FIXME (10872): This is required to prevent an LLVM assert on Windows
#[test]
fn dummy_test() { }
<commit_msg>Update to rust master<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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. This file may not be copied, modified, or distributed
// except according to those terms.

/*!
Syntax extension to generate FourCCs.

Once loaded, fourcc!() is called with a single 4-character string,
and an optional ident that is either `big`, `little`, or `target`.
The ident represents endianness, and specifies in which direction
the characters should be read. If the ident is omitted, it is assumed
to be `big`, i.e. left-to-right order. It returns a u32.

# Examples

To load the extension and use it:

```rust,ignore
#[phase(plugin)]
extern crate fourcc;

fn main() {
    let val = fourcc!("\xC0\xFF\xEE!");
    assert_eq!(val, 0xC0FFEE21u32);
    let little_val = fourcc!("foo ", little);
    assert_eq!(little_val, 0x21EEFFC0u32);
}
```

# References

* [Wikipedia: FourCC](http://en.wikipedia.org/wiki/FourCC)

*/

#![crate_name = "fourcc"]
#![experimental]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico")]

#![feature(plugin_registrar)]

extern crate syntax;
extern crate rustc;

use syntax::ast;
use syntax::attr::contains;
use syntax::codemap::{Span, mk_sp};
use syntax::ext::base;
use syntax::ext::base::{ExtCtxt, MacExpr};
use syntax::ext::build::AstBuilder;
use syntax::parse::token;
use syntax::parse::token::InternedString;
use syntax::ptr::P;
use rustc::plugin::Registry;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("fourcc", expand_syntax_ext);
}

pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                         -> Box<base::MacResult + 'static> {
    let (expr, endian) = parse_tts(cx, tts);

    let little = match endian {
        None => false,
        Some(Ident{ident, span}) => match token::get_ident(ident).get() {
            "little" => true,
            "big" => false,
            "target" => target_endian_little(cx, sp),
            _ => {
                cx.span_err(span, "invalid endian directive in fourcc!");
                target_endian_little(cx, sp)
            }
        }
    };

    let s = match expr.node {
        // expression is a literal
        ast::ExprLit(ref lit) => match lit.node {
            // string literal
            ast::LitStr(ref s, _) => {
                if s.get().char_len() != 4 {
                    cx.span_err(expr.span, "string literal with len != 4 in fourcc!");
                }
                s
            }
            _ => {
                cx.span_err(expr.span, "unsupported literal in fourcc!");
                return base::DummyResult::expr(sp)
            }
        },
        _ => {
            cx.span_err(expr.span, "non-literal in fourcc!");
            return base::DummyResult::expr(sp)
        }
    };

    let mut val = 0u32;
    for codepoint in s.get().chars().take(4) {
        let byte = if codepoint as u32 > 0xFF {
            cx.span_err(expr.span, "fourcc! literal character out of range 0-255");
            0u8
        } else {
            codepoint as u8
        };

        val = if little {
            (val >> 8) | ((byte as u32) << 24)
        } else {
            (val << 8) | (byte as u32)
        };
    }
    let e = cx.expr_lit(sp, ast::LitInt(val as u64, ast::UnsignedIntLit(ast::TyU32)));
    MacExpr::new(e)
}

struct Ident {
    ident: ast::Ident,
    span: Span
}

fn parse_tts(cx: &ExtCtxt,
             tts: &[ast::TokenTree]) -> (P<ast::Expr>, Option<Ident>) {
    let p = &mut cx.new_parser_from_tts(tts);
    let ex = p.parse_expr();
    let id = if p.token == token::EOF {
        None
    } else {
        p.expect(&token::COMMA);
        let lo = p.span.lo;
        let ident = p.parse_ident();
        let hi = p.last_span.hi;
        Some(Ident{ident: ident, span: mk_sp(lo, hi)})
    };
    if p.token != token::EOF {
        p.unexpected();
    }
    (ex, id)
}

fn target_endian_little(cx: &ExtCtxt, sp: Span) -> bool {
    let meta = cx.meta_name_value(sp, InternedString::new("target_endian"),
        ast::LitStr(InternedString::new("little"), ast::CookedStr));
    contains(cx.cfg().as_slice(), &*meta)
}

// FIXME (10872): This is required to prevent an LLVM assert on Windows
#[test]
fn dummy_test() { }
<|endoftext|>