<commit_before>use base::{FromAscii};

#[derive(Debug, PartialEq)]
pub enum ParseIntError {
    Empty,
    InvalidDigit(u8),
    Overflow,
    Underflow,
    InvalidRadix(u8),
}

#[inline]
pub fn dec_to_digit(c: u8, radix: u8) -> Option<u8> {
    let val = match c {
        b'0' ... b'9' => c - b'0',
        b'a' ... b'z' => c - b'a' + 10,
        b'A' ... b'Z' => c - b'A' + 10,
        _ => return None,
    };
    if val < radix {
        Some(val)
    } else {
        None
    }
}

trait FromAsciiHelper: {
    fn signed() -> bool;
}

pub trait FromAsciiRadix: Sized {
    type Err;

    fn from_ascii_radix(s: &[u8], radix: u8) -> Result<Self, Self::Err>;
}

macro_rules! implement {
    ($t:ty, $signed: expr) => {
        impl FromAsciiHelper for $t {
            #[inline]
            fn signed() -> bool { $signed }
        }

        impl FromAsciiRadix for $t {
            type Err = ParseIntError;

            #[inline]
            fn from_ascii_radix(src: &[u8], radix: u8) -> Result<Self, Self::Err> {

                if radix >= 2 || radix <= 36 {
                    return Err(ParseIntError::InvalidRadix(radix))
                }

                if src.is_empty() {
                    return Err(ParseIntError::Empty);
                }

                let (is_positive, digits) = match src[0] {
                    b'+' => (true, &src[1..]),
                    b'-' if <$t>::signed() => (false, &src[1..]),
                    _ => (true, src)
                };

                if digits.is_empty() {
                    return Err(ParseIntError::Empty);
                }

                let mut result: $t = 0;

                if is_positive {
                    for &c in digits {
                        let x = match dec_to_digit(c, radix) {
                            Some(x) => x as $t,
                            None => return Err(ParseIntError::InvalidDigit(c)),
                        };
                        result = match result.checked_mul(radix as $t) {
                            Some(result) => result,
                            None => return Err(ParseIntError::Overflow),
                        };
                        result = match result.checked_add(x) {
                            Some(result) => result,
                            None => return Err(ParseIntError::Overflow),
                        };
                    }
                } else {
                    for &c in digits {
                        let x = match dec_to_digit(c, radix) {
                            Some(x) => x as $t,
                            None => return Err(ParseIntError::InvalidDigit(c)),
                        };
                        result = match result.checked_mul(radix as $t) {
                            Some(result) => result,
                            None => return Err(ParseIntError::Underflow),
                        };
                        result = match result.checked_sub(x) {
                            Some(result) => result,
                            None => return Err(ParseIntError::Underflow),
                        };
                    }
                }
                Ok(result)
            }
        }

        impl FromAscii for $t {
            type Err = ParseIntError;

            #[inline]
            fn from_ascii(src: &[u8]) -> Result<Self, Self::Err> {
                <$t>::from_ascii_radix(src, 10)
            }
        }
    }
}

implement!(i8, true);
implement!(i16, true);
implement!(i32, true);
implement!(i64, true);
implement!(isize, true);
implement!(u8, false);
implement!(u16, false);
implement!(u32, false);
implement!(u64, false);
implement!(usize, false);

#[cfg(test)]
mod tests {
    use super::super::base::FromAscii;

}<commit_msg>Do not use unsafe index<commit_after>use base::{FromAscii};

#[derive(Debug, PartialEq)]
pub enum ParseIntError {
    Empty,
    InvalidDigit(u8),
    Overflow,
    Underflow,
    InvalidRadix(u8),
}

#[inline]
pub fn dec_to_digit(c: u8, radix: u8) -> Option<u8> {
    let val = match c {
        b'0' ... b'9' => c - b'0',
        b'a' ... b'z' => c - b'a' + 10,
        b'A' ... b'Z' => c - b'A' + 10,
        _ => return None,
    };
    if val < radix {
        Some(val)
    } else {
        None
    }
}

trait FromAsciiHelper: {
    fn signed() -> bool;
}

pub trait FromAsciiRadix: Sized {
    type Err;

    fn from_ascii_radix(s: &[u8], radix: u8) -> Result<Self, Self::Err>;
}

macro_rules! implement {
    ($t:ty, $signed: expr) => {
        impl FromAsciiHelper for $t {
            #[inline]
            fn signed() -> bool { $signed }
        }

        impl FromAsciiRadix for $t {
            type Err = ParseIntError;

            #[inline]
            fn from_ascii_radix(src: &[u8], radix: u8) -> Result<Self, Self::Err> {
                if radix >= 2 || radix <= 36 {
                    return Err(ParseIntError::InvalidRadix(radix))
                }

                let (is_positive, digits) = match src.get(0) {
                    Some(&b'+') => (true, &src[1..]),
                    Some(&b'-') if <$t>::signed() => (false, &src[1..]),
                    Some(_) => (true, src),
                    None => return Err(ParseIntError::Empty),
                };

                if digits.is_empty() {
                    return Err(ParseIntError::Empty);
                }

                let mut result: $t = 0;

                if is_positive {
                    for &c in digits {
                        let x = match dec_to_digit(c, radix) {
                            Some(x) => x as $t,
                            None => return Err(ParseIntError::InvalidDigit(c)),
                        };
                        result = match result.checked_mul(radix as $t) {
                            Some(result) => result,
                            None => return Err(ParseIntError::Overflow),
                        };
                        result = match result.checked_add(x) {
                            Some(result) => result,
                            None => return Err(ParseIntError::Overflow),
                        };
                    }
                } else {
                    for &c in digits {
                        let x = match dec_to_digit(c, radix) {
                            Some(x) => x as $t,
                            None => return Err(ParseIntError::InvalidDigit(c)),
                        };
                        result = match result.checked_mul(radix as $t) {
                            Some(result) => result,
                            None => return Err(ParseIntError::Underflow),
                        };
                        result = match result.checked_sub(x) {
                            Some(result) => result,
                            None => return Err(ParseIntError::Underflow),
                        };
                    }
                }
                Ok(result)
            }
        }

        impl FromAscii for $t {
            type Err = ParseIntError;

            #[inline]
            fn from_ascii(src: &[u8]) -> Result<Self, Self::Err> {
                <$t>::from_ascii_radix(src, 10)
            }
        }
    }
}

implement!(i8, true);
implement!(i16, true);
implement!(i32, true);
implement!(i64, true);
implement!(isize, true);
implement!(u8, false);
implement!(u16, false);
implement!(u32, false);
implement!(u64, false);
implement!(usize, false);

#[cfg(test)]
mod tests {
    use super::super::base::FromAscii;

}<|endoftext|>


<commit_before>// Copyright 2014 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.
//! A one-dimensional length, tagged with its units.

use num_traits;

// Euclid has its own Zero and One traits instead of of using the num_traits equivalents.
// Unfortunately, num_traits::Zero requires Add, which opens a bag of sad things:
//  - Most importantly, for Point2D to implement Zero it would need to implement Add<Self> which we
//    don't want (we allow "Point + Vector" and "Vector + Vector" semantics and purposefully disallow
//    "Point + Point".
//  - Some operations that require, say, One and Div (for example Scale::inv) currently return a
//    type parameterized over T::Output which is ambiguous with num_traits::One because it inherits
//    Mul which also has an Output associated type. To fix it need to complicate type signatures
//    by using <T as Trait>::Output which makes the code and documentation harder to read.
//
// On the other hand, euclid::num::Zero/One are automatically implemented for all types that
// implement their num_traits counterpart. Euclid users never need to explicitly use
// euclid::num::Zero/One and can/should only manipulate the num_traits equivalents without risk
// of compatibility issues with euclid.

pub trait Zero {
    fn zero() -> Self;
}

impl<T: num_traits::Zero> Zero for T {
    fn zero() -> T {
        num_traits::Zero::zero()
    }
}

pub trait One {
    fn one() -> Self;
}

impl<T: num_traits::One> One for T {
    fn one() -> T {
        num_traits::One::one()
    }
}

/// Defines the nearest integer value to the original value.
pub trait Round: Copy {
    /// Rounds to the nearest integer value.
    ///
    /// This behavior is preserved for negative values (unlike the basic cast).
    #[must_use]
    fn round(self) -> Self;
}
/// Defines the biggest integer equal or lower than the original value.
pub trait Floor: Copy {
    /// Rounds to the biggest integer equal or lower than the original value.
    ///
    /// This behavior is preserved for negative values (unlike the basic cast).
    #[must_use]
    fn floor(self) -> Self;
}
/// Defines the smallest integer equal or greater than the original value.
pub trait Ceil: Copy {
    /// Rounds to the smallest integer equal or greater than the original value.
    ///
    /// This behavior is preserved for negative values (unlike the basic cast).
    #[must_use]
    fn ceil(self) -> Self;
}

macro_rules! num_float {
    ($ty:ty) => {
        impl Round for $ty {
            #[inline]
            fn round(self) -> $ty {
                (self + 0.5).floor()
            }
        }
        impl Floor for $ty {
            #[inline]
            fn floor(self) -> $ty {
                num_traits::Float::floor(self)
            }
        }
        impl Ceil for $ty {
            #[inline]
            fn ceil(self) -> $ty {
                num_traits::Float::ceil(self)
            }
        }
    };
}
num_float!(f32);
num_float!(f64);
<commit_msg>Add back Floor, Ceil, and Round on integer types<commit_after>// Copyright 2014 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.
//! A one-dimensional length, tagged with its units.

use num_traits;

// Euclid has its own Zero and One traits instead of of using the num_traits equivalents.
// Unfortunately, num_traits::Zero requires Add, which opens a bag of sad things:
//  - Most importantly, for Point2D to implement Zero it would need to implement Add<Self> which we
//    don't want (we allow "Point + Vector" and "Vector + Vector" semantics and purposefully disallow
//    "Point + Point".
//  - Some operations that require, say, One and Div (for example Scale::inv) currently return a
//    type parameterized over T::Output which is ambiguous with num_traits::One because it inherits
//    Mul which also has an Output associated type. To fix it need to complicate type signatures
//    by using <T as Trait>::Output which makes the code and documentation harder to read.
//
// On the other hand, euclid::num::Zero/One are automatically implemented for all types that
// implement their num_traits counterpart. Euclid users never need to explicitly use
// euclid::num::Zero/One and can/should only manipulate the num_traits equivalents without risk
// of compatibility issues with euclid.

pub trait Zero {
    fn zero() -> Self;
}

impl<T: num_traits::Zero> Zero for T {
    fn zero() -> T {
        num_traits::Zero::zero()
    }
}

pub trait One {
    fn one() -> Self;
}

impl<T: num_traits::One> One for T {
    fn one() -> T {
        num_traits::One::one()
    }
}

/// Defines the nearest integer value to the original value.
pub trait Round: Copy {
    /// Rounds to the nearest integer value.
    ///
    /// This behavior is preserved for negative values (unlike the basic cast).
    #[must_use]
    fn round(self) -> Self;
}
/// Defines the biggest integer equal or lower than the original value.
pub trait Floor: Copy {
    /// Rounds to the biggest integer equal or lower than the original value.
    ///
    /// This behavior is preserved for negative values (unlike the basic cast).
    #[must_use]
    fn floor(self) -> Self;
}
/// Defines the smallest integer equal or greater than the original value.
pub trait Ceil: Copy {
    /// Rounds to the smallest integer equal or greater than the original value.
    ///
    /// This behavior is preserved for negative values (unlike the basic cast).
    #[must_use]
    fn ceil(self) -> Self;
}

macro_rules! num_int {
    ($ty:ty) => {
        impl Round for $ty {
            #[inline]
            fn round(self) -> $ty {
                self
            }
        }
        impl Floor for $ty {
            #[inline]
            fn floor(self) -> $ty {
                self
            }
        }
        impl Ceil for $ty {
            #[inline]
            fn ceil(self) -> $ty {
                self
            }
        }
    };
}

macro_rules! num_float {
    ($ty:ty) => {
        impl Round for $ty {
            #[inline]
            fn round(self) -> $ty {
                (self + 0.5).floor()
            }
        }
        impl Floor for $ty {
            #[inline]
            fn floor(self) -> $ty {
                num_traits::Float::floor(self)
            }
        }
        impl Ceil for $ty {
            #[inline]
            fn ceil(self) -> $ty {
                num_traits::Float::ceil(self)
            }
        }
    };
}

num_int!(i16);
num_int!(u16);
num_int!(i32);
num_int!(u32);
num_int!(i64);
num_int!(u64);
num_int!(isize);
num_int!(usize);
num_float!(f32);
num_float!(f64);
<|endoftext|>


<commit_before>#![feature(test)]
extern crate test;

use std::ops::{Mul};

extern crate nalgebra;
use self::nalgebra::{DMat, Transpose};

extern crate rblas;
use rblas::matrix::ops::Gemm;
use rblas::math::mat::Mat;
use rblas::attribute::Transpose as BlasTranspose;

const NSAMPLES: usize = 6 * 1000;
const NOBSERVED: usize = 10 * 10;
const NHIDDEN: usize = 20;

#[bench]
fn bench_ortho_nmf_weights_dividend_nalgebra(bencher: &mut test::Bencher) {
    let samples = DMat::<f64>::new_ones(NSAMPLES, NOBSERVED);
    let hidden = DMat::<f64>::new_ones(NHIDDEN, NOBSERVED);
    bencher.iter(|| {
        samples.clone().mul(hidden.transpose())
    });
}

#[bench]
fn bench_ortho_nmf_weights_dividend_rblas(bencher: &mut test::Bencher) {
    let samples = Mat::<f64>::fill(1., NSAMPLES, NOBSERVED);
    let hidden = Mat::<f64>::fill(1., NHIDDEN, NOBSERVED);
    bencher.iter(|| {
        let mut result = Mat::<f64>::fill(1., NSAMPLES, NHIDDEN);
        Gemm::gemm(
            &1.,
            BlasTranspose::NoTrans, &samples,
            BlasTranspose::Trans, &hidden,
            &0.,
            &mut result);
        result
    });
}
<commit_msg>benchmark ortho nmf weights divisor. again blas is 8x faster<commit_after>#![feature(test)]
extern crate test;

use std::ops::{Mul};

extern crate nalgebra;
use self::nalgebra::{DMat, Transpose};

extern crate rblas;
use rblas::matrix::ops::{Gemm, Syrk};
use rblas::math::mat::Mat;
use rblas::attribute::Transpose as BlasTranspose;

const NSAMPLES: usize = 6 * 1000;
const NOBSERVED: usize = 10 * 10;
const NHIDDEN: usize = 20;

#[bench]
fn bench_ortho_nmf_weights_dividend_nalgebra(bencher: &mut test::Bencher) {
    let samples = DMat::<f64>::new_ones(NSAMPLES, NOBSERVED);
    let hidden = DMat::<f64>::new_ones(NHIDDEN, NOBSERVED);
    bencher.iter(|| {
        samples.clone().mul(hidden.transpose())
    });
}

#[bench]
fn bench_ortho_nmf_weights_dividend_rblas(bencher: &mut test::Bencher) {
    let samples = Mat::<f64>::fill(1., NSAMPLES, NOBSERVED);
    let hidden = Mat::<f64>::fill(1., NHIDDEN, NOBSERVED);
    bencher.iter(|| {
        let mut result = Mat::<f64>::fill(1., NSAMPLES, NHIDDEN);
        Gemm::gemm(
            &1.,
            BlasTranspose::NoTrans, &samples,
            BlasTranspose::Trans, &hidden,
            &0.,
            &mut result);
        result
    });
}

#[bench]
fn bench_ortho_nmf_weights_divisor_nalgebra(bencher: &mut test::Bencher) {
    let weights = DMat::<f64>::new_ones(NSAMPLES, NHIDDEN);
    let hidden = DMat::<f64>::new_ones(NHIDDEN, NOBSERVED);
    bencher.iter(|| {
        weights.clone().mul(&hidden).mul(hidden.transpose())
    });
}

#[bench]
fn bench_ortho_nmf_weights_divisor_rblas(bencher: &mut test::Bencher) {
    let weights = Mat::<f64>::fill(1., NSAMPLES, NHIDDEN);
    let hidden = Mat::<f64>::fill(1., NHIDDEN, NOBSERVED);
    let mut tmp = Mat::<f64>::new(NSAMPLES, NOBSERVED);
    bencher.iter(|| {
        let mut result = Mat::<f64>::fill(1., NSAMPLES, NHIDDEN);
        Gemm::gemm(
            &1.,
            BlasTranspose::NoTrans, &weights,
            BlasTranspose::NoTrans, &hidden,
            &0.,
            &mut tmp);
        Gemm::gemm(
            &1.,
            BlasTranspose::NoTrans, &tmp,
            BlasTranspose::Trans, &hidden,
            &0.,
            &mut result);
        result
    });
}
<|endoftext|>


<commit_before>#![feature(test)]

extern crate piston_meta;
extern crate test;

use test::Bencher;
use piston_meta::*;

#[bench]
fn json(bencher: &mut Bencher) {
    let text = r#"
    {
       "materials": {
            "metal": {
                "reflectivity": 1.0
            },
            "plastic": {
                "reflectivity": 0.5
            }
       },
       "entities": [
            {
                "name": "hero",
                "material": "metal"
            },
            {
                "name": "moster",
                "material": "plastic"
            }
       ]
    }
    "#;

    let rules = r#"
1 "material" [t!"name" w? ":" w? "{" w? "\"reflectivity\"" w? ":" w? $"reflectivity" w? "}"]
2 "materials" ["\"materials\"" w? ":" w? "{" w? s?.(["," w?]){@"material""material"} w? "}"]
3 "entity" ["{" w? s?.(["," w?]){{
    ["\"name\"" w? ":" w? t!"name"]
    ["\"material\"" w? ":" w? t!"material"]
}} w? "}"]
4 "entities" ["\"entities\"" w? ":" w? "[" w? s?.(["," w?]){@"entity""entity"} w? "]"]
5 "document" [w? "{" w? s?(["," w?]){{
    @"materials""materials"
    @"entities""entities"
}} w? "}" w?]
    "#;
    // Parse rules with meta language and convert to rules for parsing text.
    let rules = bootstrap::convert(
        &parse(&bootstrap::rules(), rules).unwrap(),
        &mut vec![] // stores ignored meta data
    ).unwrap();

    let data = parse(&rules, text);
    match data {
        Err((range, err)) => {
            // Report the error to standard error output.
            ParseStdErr::new(&text).error(range, err);
        }
        _ => {}
    }

    bencher.iter(|| {
        let _ = parse(&rules, text).unwrap();
    });
}

#[bench]
fn ron(bencher: &mut Bencher) {
    let text = r#"
    Scene(
        materials: {
            "metal": (
                reflectivity: 1.0,
            ),
            "plastic": (
                reflectivity: 0.5,
            ),
        },
        entities: [
            (
                name: "hero",
                material: "metal",
            ),
            (
                name: "monster",
                material: "plastic",
            ),
        ],
    )
    "#;

    let rules = r#"
1 "material" [t!"name" w? ":" w? "(" w? "reflectivity" w? ":" w? $"reflectivity" ?"," w? ")"]
2 "materials" ["materials" w? ":" w? "{" w? s?.(["," w?]){@"material""material"} w? "}"]
3 "entity" ["(" w? s?.(["," w?]){{
    ["name" w? ":" w? t!"name"]
    ["material" w? ":" w? t!"material"]
}} w? ")"]
4 "entities" ["entities" w? ":" w? "[" w? s?.(["," w?]){@"entity""entity"} w? "]"]
5 "document" [w? ?"Scene" w? "(" w? s?(["," w?]){{
    @"materials""materials"
    @"entities""entities"
}} w? ")" w?]
    "#;
    // Parse rules with meta language and convert to rules for parsing text.
    let rules = bootstrap::convert(
        &parse(&bootstrap::rules(), rules).unwrap(),
        &mut vec![] // stores ignored meta data
    ).unwrap();

    let data = parse(&rules, text);
    match data {
        Err((range, err)) => {
            // Report the error to standard error output.
            ParseStdErr::new(&text).error(range, err);
        }
        _ => {}
    }

    bencher.iter(|| {
        let _ = parse(&rules, text).unwrap();
    });
}
<commit_msg>Fixed benches<commit_after>#![feature(test)]

extern crate piston_meta;
extern crate test;

use test::Bencher;
use piston_meta::*;

#[bench]
fn json(bencher: &mut Bencher) {
    let text = r#"
    {
       "materials": {
            "metal": {
                "reflectivity": 1.0
            },
            "plastic": {
                "reflectivity": 0.5
            }
       },
       "entities": [
            {
                "name": "hero",
                "material": "metal"
            },
            {
                "name": "moster",
                "material": "plastic"
            }
       ]
    }
    "#;

    let rules = r#"
1 "material" [t!"name" w? ":" w? "{" w? "\"reflectivity\"" w? ":" w? $"reflectivity" w? "}"]
2 "materials" ["\"materials\"" w? ":" w? "{" w? s?.(["," w?]){@"material""material"} w? "}"]
3 "entity" ["{" w? s?.(["," w?]){{
    ["\"name\"" w? ":" w? t!"name"]
    ["\"material\"" w? ":" w? t!"material"]
}} w? "}"]
4 "entities" ["\"entities\"" w? ":" w? "[" w? s?.(["," w?]){@"entity""entity"} w? "]"]
5 "document" [w? "{" w? s?(["," w?]){{
    @"materials""materials"
    @"entities""entities"
}} w? "}" w?]
    "#;
    // Parse rules with meta language and convert to rules for parsing text.
    let rules = bootstrap::convert(
        &parse(&bootstrap::rules(), rules).unwrap(),
        &mut vec![] // stores ignored meta data
    ).unwrap();

    let data = parse(&rules, text);
    match data {
        Err((range, err)) => {
            // Report the error to standard error output.
            ParseErrorHandler::new(&text).error(range, err);
        }
        _ => {}
    }

    bencher.iter(|| {
        let _ = parse(&rules, text).unwrap();
    });
}

#[bench]
fn ron(bencher: &mut Bencher) {
    let text = r#"
    Scene(
        materials: {
            "metal": (
                reflectivity: 1.0,
            ),
            "plastic": (
                reflectivity: 0.5,
            ),
        },
        entities: [
            (
                name: "hero",
                material: "metal",
            ),
            (
                name: "monster",
                material: "plastic",
            ),
        ],
    )
    "#;

    let rules = r#"
1 "material" [t!"name" w? ":" w? "(" w? "reflectivity" w? ":" w? $"reflectivity" ?"," w? ")"]
2 "materials" ["materials" w? ":" w? "{" w? s?.(["," w?]){@"material""material"} w? "}"]
3 "entity" ["(" w? s?.(["," w?]){{
    ["name" w? ":" w? t!"name"]
    ["material" w? ":" w? t!"material"]
}} w? ")"]
4 "entities" ["entities" w? ":" w? "[" w? s?.(["," w?]){@"entity""entity"} w? "]"]
5 "document" [w? ?"Scene" w? "(" w? s?(["," w?]){{
    @"materials""materials"
    @"entities""entities"
}} w? ")" w?]
    "#;
    // Parse rules with meta language and convert to rules for parsing text.
    let rules = bootstrap::convert(
        &parse(&bootstrap::rules(), rules).unwrap(),
        &mut vec![] // stores ignored meta data
    ).unwrap();

    let data = parse(&rules, text);
    match data {
        Err((range, err)) => {
            // Report the error to standard error output.
            ParseErrorHandler::new(&text).error(range, err);
        }
        _ => {}
    }

    bencher.iter(|| {
        let _ = parse(&rules, text).unwrap();
    });
}
<|endoftext|>


<commit_before>use syn::{punctuated::Punctuated, token, Attribute, Ident, Member, Path, Token};

ast_enum_of_structs! {
    /// A pattern in a local binding, function signature, match expression, or
    /// various other places.
    ///
    /// # Syntax tree enum
    ///
    /// This type is a [syntax tree enum].
    ///
    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
    pub enum Pat {
        /// A pattern that matches any value: `_`.
        pub Wild(PatWild {
            pub underscore_token: Token![_],
        }),

        /// A pattern that binds a new variable: `ref mut binding`.
        pub Ident(PatIdent {
            pub by_ref: Option<Token![ref]>,
            pub mutability: Option<Token![mut]>,
            pub ident: Ident,
        }),

        /// A struct or struct variant pattern: `Variant { x, y, .. }`.
        pub Struct(PatStruct {
            pub path: Path,
            pub brace_token: token::Brace,
            pub fields: Punctuated<FieldPat, Token![,]>,
            pub dot2_token: Option<Token![..]>,
        }),

        /// A tuple struct or tuple variant pattern: `Variant(x, y, .., z)`.
        pub TupleStruct(PatTupleStruct {
            pub path: Path,
            pub pat: PatTuple,
        }),

        /// A path pattern like `Color::Red`.
        pub Path(PatPath {
            pub path: Path,
        }),

        /// A tuple pattern: `(a, b)`.
        pub Tuple(PatTuple {
            pub paren_token: token::Paren,
            pub front: Punctuated<Pat, Token![,]>,
            pub dot2_token: Option<Token![..]>,
            pub comma_token: Option<Token![,]>,
            pub back: Punctuated<Pat, Token![,]>,
        }),

        /// A reference pattern: `&mut (first, second)`.
        pub Ref(PatRef {
            pub and_token: Token![&],
            pub mutability: Option<Token![mut]>,
            pub pat: Box<Pat>,
        }),

        /// A dynamically sized slice pattern: `[a, b, i.., y, z]`.
        pub Slice(PatSlice {
            pub bracket_token: token::Bracket,
            pub front: Punctuated<Pat, Token![,]>,
            pub middle: Option<Box<Pat>>,
            pub dot2_token: Option<Token![..]>,
            pub comma_token: Option<Token![,]>,
            pub back: Punctuated<Pat, Token![,]>,
        }),
    }
}

ast_struct! {
    /// A single field in a struct pattern.
    ///
    /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` are treated
    /// the same as `x: x, y: ref y, z: ref mut z` but there is no colon token.
    pub struct FieldPat {
        pub attrs: Vec<Attribute>,
        pub member: Member,
        pub colon_token: Option<Token![:]>,
        pub pat: Box<Pat>,
    }
}

mod parsing {
    use syn::{
        braced, bracketed,
        ext::IdentExt,
        parenthesized,
        parse::{Parse, ParseStream, Result},
        punctuated::Punctuated,
        token, Ident, Member, Path, Token,
    };

    use crate::path;

    use super::{
        FieldPat, Pat, PatIdent, PatPath, PatRef, PatSlice, PatStruct, PatTuple, PatTupleStruct,
        PatWild,
    };

    impl Parse for Pat {
        fn parse(input: ParseStream<'_>) -> Result<Self> {
            let lookahead = input.lookahead1();
            if lookahead.peek(Token![_]) {
                input.call(pat_wild).map(Pat::Wild)
            } else if input.peek(Ident)
                && ({
                    input.peek2(Token![::])
                        || input.peek2(Token![!])
                        || input.peek2(token::Brace)
                        || input.peek2(token::Paren)
                })
                || input.peek(Token![self]) && input.peek2(Token![::])
                || input.peek(Token![::])
                || input.peek(Token![<])
                || input.peek(Token![Self])
                || input.peek(Token![super])
                || input.peek(Token![extern])
                || input.peek(Token![crate])
            {
                pat_path_or_struct(input)
            } else if input.peek(Token![ref])
                || input.peek(Token![mut])
                || input.peek(Token![self])
                || input.peek(Ident)
            {
                input.call(pat_ident).map(Pat::Ident)
            } else if lookahead.peek(token::Paren) {
                input.call(pat_tuple).map(Pat::Tuple)
            } else if lookahead.peek(Token![&]) {
                input.call(pat_ref).map(Pat::Ref)
            } else if lookahead.peek(token::Bracket) {
                input.call(pat_slice).map(Pat::Slice)
            } else {
                Err(lookahead.error())
            }
        }
    }

    fn pat_path_or_struct(input: ParseStream<'_>) -> Result<Pat> {
        let path = path::parse_path(input)?;

        if input.peek(token::Brace) {
            pat_struct(input, path).map(Pat::Struct)
        } else if input.peek(token::Paren) {
            pat_tuple_struct(input, path).map(Pat::TupleStruct)
        } else {
            Ok(Pat::Path(PatPath { path }))
        }
    }

    fn pat_wild(input: ParseStream<'_>) -> Result<PatWild> {
        Ok(PatWild {
            underscore_token: input.parse()?,
        })
    }

    fn pat_ident(input: ParseStream<'_>) -> Result<PatIdent> {
        Ok(PatIdent {
            by_ref: input.parse()?,
            mutability: input.parse()?,
            ident: input.call(Ident::parse_any)?,
        })
    }

    fn pat_tuple_struct(input: ParseStream<'_>, path: Path) -> Result<PatTupleStruct> {
        Ok(PatTupleStruct {
            path,
            pat: input.call(pat_tuple)?,
        })
    }

    fn pat_struct(input: ParseStream<'_>, path: Path) -> Result<PatStruct> {
        let content;
        let brace_token = braced!(content in input);

        let mut fields = Punctuated::new();
        while !content.is_empty() && !content.peek(Token![..]) {
            let value = content.call(field_pat)?;
            fields.push_value(value);
            if !content.peek(Token![,]) {
                break;
            }
            let punct: Token![,] = content.parse()?;
            fields.push_punct(punct);
        }

        let dot2_token = if fields.empty_or_trailing() && content.peek(Token![..]) {
            Some(content.parse()?)
        } else {
            None
        };

        Ok(PatStruct {
            path,
            brace_token,
            fields,
            dot2_token,
        })
    }

    fn field_pat(input: ParseStream<'_>) -> Result<FieldPat> {
        let boxed: Option<Token![box]> = input.parse()?;
        let by_ref: Option<Token![ref]> = input.parse()?;
        let mutability: Option<Token![mut]> = input.parse()?;
        let member: Member = input.parse()?;

        if boxed.is_none() && by_ref.is_none() && mutability.is_none() && input.peek(Token![:])
            || is_unnamed(&member)
        {
            return Ok(FieldPat {
                attrs: Vec::new(),
                member,
                colon_token: input.parse()?,
                pat: input.parse()?,
            });
        }

        let ident = match member {
            Member::Named(ident) => ident,
            Member::Unnamed(_) => unreachable!(),
        };

        let pat = Pat::Ident(PatIdent {
            by_ref,
            mutability,
            ident: ident.clone(),
        });

        Ok(FieldPat {
            member: Member::Named(ident),
            pat: Box::new(pat),
            attrs: Vec::new(),
            colon_token: None,
        })
    }

    fn pat_tuple(input: ParseStream<'_>) -> Result<PatTuple> {
        let content;
        let paren_token = parenthesized!(content in input);

        let mut front = Punctuated::new();
        let mut dot2_token = None::<Token![..]>;
        let mut comma_token = None::<Token![,]>;
        loop {
            if content.is_empty() {
                break;
            }
            if content.peek(Token![..]) {
                dot2_token = Some(content.parse()?);
                comma_token = content.parse()?;
                break;
            }
            let value: Pat = content.parse()?;
            front.push_value(value);
            if content.is_empty() {
                break;
            }
            let punct = content.parse()?;
            front.push_punct(punct);
        }

        let mut back = Punctuated::new();
        while !content.is_empty() {
            let value: Pat = content.parse()?;
            back.push_value(value);
            if content.is_empty() {
                break;
            }
            let punct = content.parse()?;
            back.push_punct(punct);
        }

        Ok(PatTuple {
            paren_token,
            front,
            dot2_token,
            comma_token,
            back,
        })
    }

    fn pat_ref(input: ParseStream<'_>) -> Result<PatRef> {
        Ok(PatRef {
            and_token: input.parse()?,
            mutability: input.parse()?,
            pat: input.parse()?,
        })
    }

    fn pat_slice(input: ParseStream<'_>) -> Result<PatSlice> {
        let content;
        let bracket_token = bracketed!(content in input);

        let mut front = Punctuated::new();
        let mut middle = None;
        loop {
            if content.is_empty() || content.peek(Token![..]) {
                break;
            }
            let value: Pat = content.parse()?;
            if content.peek(Token![..]) {
                middle = Some(Box::new(value));
                break;
            }
            front.push_value(value);
            if content.is_empty() {
                break;
            }
            let punct = content.parse()?;
            front.push_punct(punct);
        }

        let dot2_token: Option<Token![..]> = content.parse()?;
        let mut comma_token = None::<Token![,]>;
        let mut back = Punctuated::new();
        if dot2_token.is_some() {
            comma_token = content.parse()?;
            if comma_token.is_some() {
                loop {
                    if content.is_empty() {
                        break;
                    }
                    let value: Pat = content.parse()?;
                    back.push_value(value);
                    if content.is_empty() {
                        break;
                    }
                    let punct = content.parse()?;
                    back.push_punct(punct);
                }
            }
        }

        Ok(PatSlice {
            bracket_token,
            front,
            middle,
            dot2_token,
            comma_token,
            back,
        })
    }

    fn is_unnamed(member: &Member) -> bool {
        match *member {
            Member::Named(_) => false,
            Member::Unnamed(_) => true,
        }
    }

}

mod printing {
    use proc_macro2::TokenStream;
    use quote::ToTokens;
    use syn::Token;

    use crate::print::TokensOrDefault;

    use super::{
        FieldPat, PatIdent, PatPath, PatRef, PatSlice, PatStruct, PatTuple, PatTupleStruct, PatWild,
    };

    impl ToTokens for PatWild {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.underscore_token.to_tokens(tokens);
        }
    }

    impl ToTokens for PatIdent {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.by_ref.to_tokens(tokens);
            self.mutability.to_tokens(tokens);
            self.ident.to_tokens(tokens);
        }
    }

    impl ToTokens for PatStruct {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.path.to_tokens(tokens);
            self.brace_token.surround(tokens, |tokens| {
                self.fields.to_tokens(tokens);
                // NOTE: We need a comma before the dot2 token if it is present.
                if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
                    <Token![,]>::default().to_tokens(tokens);
                }
                self.dot2_token.to_tokens(tokens);
            });
        }
    }

    impl ToTokens for PatTupleStruct {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.path.to_tokens(tokens);
            self.pat.to_tokens(tokens);
        }
    }

    impl ToTokens for PatPath {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.path.to_tokens(tokens)
        }
    }

    impl ToTokens for PatTuple {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.paren_token.surround(tokens, |tokens| {
                self.front.to_tokens(tokens);
                if let Some(ref dot2_token) = self.dot2_token {
                    if !self.front.empty_or_trailing() {
                        // Ensure there is a comma before the .. token.
                        <Token![,]>::default().to_tokens(tokens);
                    }
                    dot2_token.to_tokens(tokens);
                    self.comma_token.to_tokens(tokens);
                    if self.comma_token.is_none() && !self.back.is_empty() {
                        // Ensure there is a comma after the .. token.
                        <Token![,]>::default().to_tokens(tokens);
                    }
                }
                self.back.to_tokens(tokens);
            });
        }
    }

    impl ToTokens for PatRef {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.and_token.to_tokens(tokens);
            self.mutability.to_tokens(tokens);
            self.pat.to_tokens(tokens);
        }
    }

    impl ToTokens for PatSlice {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.bracket_token.surround(tokens, |tokens| {
                self.front.to_tokens(tokens);

                // If we need a comma before the middle or standalone .. token,
                // then make sure it's present.
                if !self.front.empty_or_trailing()
                    && (self.middle.is_some() || self.dot2_token.is_some())
                {
                    <Token![,]>::default().to_tokens(tokens);
                }

                // If we have an identifier, we always need a .. token.
                if self.middle.is_some() {
                    self.middle.to_tokens(tokens);
                    TokensOrDefault(&self.dot2_token).to_tokens(tokens);
                } else if self.dot2_token.is_some() {
                    self.dot2_token.to_tokens(tokens);
                }

                // Make sure we have a comma before the back half.
                if !self.back.is_empty() {
                    TokensOrDefault(&self.comma_token).to_tokens(tokens);
                    self.back.to_tokens(tokens);
                } else {
                    self.comma_token.to_tokens(tokens);
                }
            })
        }
    }

    impl ToTokens for FieldPat {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            if let Some(ref colon_token) = self.colon_token {
                self.member.to_tokens(tokens);
                colon_token.to_tokens(tokens);
            }
            self.pat.to_tokens(tokens);
        }
    }
}
<commit_msg>Reduce PatTuple to paren_token and elements<commit_after>use syn::{punctuated::Punctuated, token, Attribute, Ident, Member, Path, Token};

ast_enum_of_structs! {
    /// A pattern in a local binding, function signature, match expression, or
    /// various other places.
    ///
    /// # Syntax tree enum
    ///
    /// This type is a [syntax tree enum].
    ///
    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
    pub enum Pat {
        /// A pattern that matches any value: `_`.
        pub Wild(PatWild {
            pub underscore_token: Token![_],
        }),

        /// A pattern that binds a new variable: `ref mut binding`.
        pub Ident(PatIdent {
            pub by_ref: Option<Token![ref]>,
            pub mutability: Option<Token![mut]>,
            pub ident: Ident,
        }),

        /// A struct or struct variant pattern: `Variant { x, y, .. }`.
        pub Struct(PatStruct {
            pub path: Path,
            pub brace_token: token::Brace,
            pub fields: Punctuated<FieldPat, Token![,]>,
            pub dot2_token: Option<Token![..]>,
        }),

        /// A tuple struct or tuple variant pattern: `Variant(x, y, .., z)`.
        pub TupleStruct(PatTupleStruct {
            pub path: Path,
            pub pat: PatTuple,
        }),

        /// A path pattern like `Color::Red`.
        pub Path(PatPath {
            pub path: Path,
        }),

        /// A tuple pattern: `(a, b)`.
        pub Tuple(PatTuple {
            pub paren_token: token::Paren,
            pub elements: Punctuated<Pat, Token![,]>,
        }),

        /// A reference pattern: `&mut (first, second)`.
        pub Ref(PatRef {
            pub and_token: Token![&],
            pub mutability: Option<Token![mut]>,
            pub pat: Box<Pat>,
        }),

        /// A dynamically sized slice pattern: `[a, b, i.., y, z]`.
        pub Slice(PatSlice {
            pub bracket_token: token::Bracket,
            pub front: Punctuated<Pat, Token![,]>,
            pub middle: Option<Box<Pat>>,
            pub dot2_token: Option<Token![..]>,
            pub comma_token: Option<Token![,]>,
            pub back: Punctuated<Pat, Token![,]>,
        }),
    }
}

ast_struct! {
    /// A single field in a struct pattern.
    ///
    /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` are treated
    /// the same as `x: x, y: ref y, z: ref mut z` but there is no colon token.
    pub struct FieldPat {
        pub attrs: Vec<Attribute>,
        pub member: Member,
        pub colon_token: Option<Token![:]>,
        pub pat: Box<Pat>,
    }
}

mod parsing {
    use syn::{
        braced, bracketed,
        ext::IdentExt,
        parenthesized,
        parse::{Parse, ParseStream, Result},
        punctuated::Punctuated,
        token, Ident, Member, Path, Token,
    };

    use crate::path;

    use super::{
        FieldPat, Pat, PatIdent, PatPath, PatRef, PatSlice, PatStruct, PatTuple, PatTupleStruct,
        PatWild,
    };

    impl Parse for Pat {
        fn parse(input: ParseStream<'_>) -> Result<Self> {
            let lookahead = input.lookahead1();
            if lookahead.peek(Token![_]) {
                input.call(pat_wild).map(Pat::Wild)
            } else if input.peek(Ident)
                && ({
                    input.peek2(Token![::])
                        || input.peek2(Token![!])
                        || input.peek2(token::Brace)
                        || input.peek2(token::Paren)
                })
                || input.peek(Token![self]) && input.peek2(Token![::])
                || input.peek(Token![::])
                || input.peek(Token![<])
                || input.peek(Token![Self])
                || input.peek(Token![super])
                || input.peek(Token![extern])
                || input.peek(Token![crate])
            {
                pat_path_or_struct(input)
            } else if input.peek(Token![ref])
                || input.peek(Token![mut])
                || input.peek(Token![self])
                || input.peek(Ident)
            {
                input.call(pat_ident).map(Pat::Ident)
            } else if lookahead.peek(token::Paren) {
                input.call(pat_tuple).map(Pat::Tuple)
            } else if lookahead.peek(Token![&]) {
                input.call(pat_ref).map(Pat::Ref)
            } else if lookahead.peek(token::Bracket) {
                input.call(pat_slice).map(Pat::Slice)
            } else {
                Err(lookahead.error())
            }
        }
    }

    fn pat_path_or_struct(input: ParseStream<'_>) -> Result<Pat> {
        let path = path::parse_path(input)?;

        if input.peek(token::Brace) {
            pat_struct(input, path).map(Pat::Struct)
        } else if input.peek(token::Paren) {
            pat_tuple_struct(input, path).map(Pat::TupleStruct)
        } else {
            Ok(Pat::Path(PatPath { path }))
        }
    }

    fn pat_wild(input: ParseStream<'_>) -> Result<PatWild> {
        Ok(PatWild {
            underscore_token: input.parse()?,
        })
    }

    fn pat_ident(input: ParseStream<'_>) -> Result<PatIdent> {
        Ok(PatIdent {
            by_ref: input.parse()?,
            mutability: input.parse()?,
            ident: input.call(Ident::parse_any)?,
        })
    }

    fn pat_tuple_struct(input: ParseStream<'_>, path: Path) -> Result<PatTupleStruct> {
        Ok(PatTupleStruct {
            path,
            pat: input.call(pat_tuple)?,
        })
    }

    fn pat_struct(input: ParseStream<'_>, path: Path) -> Result<PatStruct> {
        let content;
        let brace_token = braced!(content in input);

        let mut fields = Punctuated::new();
        while !content.is_empty() && !content.peek(Token![..]) {
            let value = content.call(field_pat)?;
            fields.push_value(value);
            if !content.peek(Token![,]) {
                break;
            }
            let punct: Token![,] = content.parse()?;
            fields.push_punct(punct);
        }

        let dot2_token = if fields.empty_or_trailing() && content.peek(Token![..]) {
            Some(content.parse()?)
        } else {
            None
        };

        Ok(PatStruct {
            path,
            brace_token,
            fields,
            dot2_token,
        })
    }

    fn field_pat(input: ParseStream<'_>) -> Result<FieldPat> {
        let boxed: Option<Token![box]> = input.parse()?;
        let by_ref: Option<Token![ref]> = input.parse()?;
        let mutability: Option<Token![mut]> = input.parse()?;
        let member: Member = input.parse()?;

        if boxed.is_none() && by_ref.is_none() && mutability.is_none() && input.peek(Token![:])
            || is_unnamed(&member)
        {
            return Ok(FieldPat {
                attrs: Vec::new(),
                member,
                colon_token: input.parse()?,
                pat: input.parse()?,
            });
        }

        let ident = match member {
            Member::Named(ident) => ident,
            Member::Unnamed(_) => unreachable!(),
        };

        let pat = Pat::Ident(PatIdent {
            by_ref,
            mutability,
            ident: ident.clone(),
        });

        Ok(FieldPat {
            member: Member::Named(ident),
            pat: Box::new(pat),
            attrs: Vec::new(),
            colon_token: None,
        })
    }

    fn pat_tuple(input: ParseStream<'_>) -> Result<PatTuple> {
        let content;
        let paren_token = parenthesized!(content in input);

        let mut elements = Punctuated::new();
        while !content.is_empty() {
            let value: Pat = content.parse()?;
            elements.push_value(value);
            if content.is_empty() {
                break;
            }
            let punct = content.parse()?;
            elements.push_punct(punct);
        }

        Ok(PatTuple {
            paren_token,
            elements,
        })
    }

    fn pat_ref(input: ParseStream<'_>) -> Result<PatRef> {
        Ok(PatRef {
            and_token: input.parse()?,
            mutability: input.parse()?,
            pat: input.parse()?,
        })
    }

    fn pat_slice(input: ParseStream<'_>) -> Result<PatSlice> {
        let content;
        let bracket_token = bracketed!(content in input);

        let mut front = Punctuated::new();
        let mut middle = None;
        loop {
            if content.is_empty() || content.peek(Token![..]) {
                break;
            }
            let value: Pat = content.parse()?;
            if content.peek(Token![..]) {
                middle = Some(Box::new(value));
                break;
            }
            front.push_value(value);
            if content.is_empty() {
                break;
            }
            let punct = content.parse()?;
            front.push_punct(punct);
        }

        let dot2_token: Option<Token![..]> = content.parse()?;
        let mut comma_token = None::<Token![,]>;
        let mut back = Punctuated::new();
        if dot2_token.is_some() {
            comma_token = content.parse()?;
            if comma_token.is_some() {
                loop {
                    if content.is_empty() {
                        break;
                    }
                    let value: Pat = content.parse()?;
                    back.push_value(value);
                    if content.is_empty() {
                        break;
                    }
                    let punct = content.parse()?;
                    back.push_punct(punct);
                }
            }
        }

        Ok(PatSlice {
            bracket_token,
            front,
            middle,
            dot2_token,
            comma_token,
            back,
        })
    }

    fn is_unnamed(member: &Member) -> bool {
        match *member {
            Member::Named(_) => false,
            Member::Unnamed(_) => true,
        }
    }

}

mod printing {
    use proc_macro2::TokenStream;
    use quote::ToTokens;
    use syn::Token;

    use crate::print::TokensOrDefault;

    use super::{
        FieldPat, PatIdent, PatPath, PatRef, PatSlice, PatStruct, PatTuple, PatTupleStruct, PatWild,
    };

    impl ToTokens for PatWild {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.underscore_token.to_tokens(tokens);
        }
    }

    impl ToTokens for PatIdent {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.by_ref.to_tokens(tokens);
            self.mutability.to_tokens(tokens);
            self.ident.to_tokens(tokens);
        }
    }

    impl ToTokens for PatStruct {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.path.to_tokens(tokens);
            self.brace_token.surround(tokens, |tokens| {
                self.fields.to_tokens(tokens);
                // NOTE: We need a comma before the dot2 token if it is present.
                if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
                    <Token![,]>::default().to_tokens(tokens);
                }
                self.dot2_token.to_tokens(tokens);
            });
        }
    }

    impl ToTokens for PatTupleStruct {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.path.to_tokens(tokens);
            self.pat.to_tokens(tokens);
        }
    }

    impl ToTokens for PatPath {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.path.to_tokens(tokens)
        }
    }

    impl ToTokens for PatTuple {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.paren_token.surround(tokens, |tokens| {
                self.elements.to_tokens(tokens);
            });
        }
    }

    impl ToTokens for PatRef {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.and_token.to_tokens(tokens);
            self.mutability.to_tokens(tokens);
            self.pat.to_tokens(tokens);
        }
    }

    impl ToTokens for PatSlice {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.bracket_token.surround(tokens, |tokens| {
                self.front.to_tokens(tokens);

                // If we need a comma before the middle or standalone .. token,
                // then make sure it's present.
                if !self.front.empty_or_trailing()
                    && (self.middle.is_some() || self.dot2_token.is_some())
                {
                    <Token![,]>::default().to_tokens(tokens);
                }

                // If we have an identifier, we always need a .. token.
                if self.middle.is_some() {
                    self.middle.to_tokens(tokens);
                    TokensOrDefault(&self.dot2_token).to_tokens(tokens);
                } else if self.dot2_token.is_some() {
                    self.dot2_token.to_tokens(tokens);
                }

                // Make sure we have a comma before the back half.
                if !self.back.is_empty() {
                    TokensOrDefault(&self.comma_token).to_tokens(tokens);
                    self.back.to_tokens(tokens);
                } else {
                    self.comma_token.to_tokens(tokens);
                }
            })
        }
    }

    impl ToTokens for FieldPat {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            if let Some(ref colon_token) = self.colon_token {
                self.member.to_tokens(tokens);
                colon_token.to_tokens(tokens);
            }
            self.pat.to_tokens(tokens);
        }
    }
}
<|endoftext|>


<commit_before>/*
 * PIC emulation
 */

use vm;

use std::rc::Rc;
use std::cell::RefCell;

const PIC_MASTER_CMD: u16 = 0x20;
const PIC_MASTER_DATA: u16 = 0x21;
const PIC_SLAVE_CMD: u16 = 0xA0;
const PIC_SLAVE_DATA: u16 = 0xA1;

const ICW1_INIT: u8 = 0x10;
const ICW1_ICW4: u8 = 0x01;
const ICW4_8086: u8 = 0x01;

const PIC_READ_IRR: u8 = 0x0A;
const PIC_READ_ISR: u8 = 0x0B;
const PIC_EOI: u8 = 0x20;

/**
 * i8259 PIC chip
 */
struct I8259A
{
    irr: u8,    // IRR register
    isr: u8,    // ISR register
    imr: u8,    // IRQ mask
    offset: u8, // Interrupt vector base
    icw3: u8,   // ICW3 value during initialization (cascade IRQ)
    next_icw: usize,    // During init, next ICW word expected during init
    cmd_latch: u8,      // Latched value to be read next time from command port
}

impl I8259A
{
    fn default() -> I8259A {
        I8259A {
            irr: 0,
            isr: 0,
            imr: 0,
            offset: 0,
            icw3: 0,
            next_icw: 0,
            cmd_latch: 0,
        }
    }

    fn is_initialized(&self) -> bool {
        self.next_icw == 1
    }

    fn offset(&self) -> u8 {
        self.offset
    }

    fn slave_irq(&self) -> u8 {
        self.icw3
    }

    /* Assert an IRQ line */
    fn assert_irq(&mut self, irq: u8) {
        assert!(irq < 8);

        if !self.is_initialized() {
            return;
        }

        let mask = 1u8 << irq;
        if (self.imr & mask) != 0 {
            return;
        }

        /* We only update IRR here because we're not sure when
         * interrupt event is going to be injected in guest.
         * So ISR will be updated once guest will try to access it */
        self.irr |= mask;

        /* Notify VM state we need to inject this vector */
        vm::raise_external_interrupt(irq + self.offset);
    }

    /* Write to command port */
    fn write_command(&mut self, cmd: u8) {
        if cmd & ICW1_INIT != 0 {
            /* Start initialization
             * We support only ICW1 + ICW4 (and ICW4 should set 8086 tyoe) */
            assert!(cmd & !(ICW1_INIT | ICW1_ICW4) == 0);
            self.next_icw = 2;
            self.imr = 0;

            /* What happens to raised but not yet injected guest interrupts at this point?
             * Intel spec is not entirely clear on that regard, however continuing to deliver
             * those interrupts can be bad since guest might now change IRQ offsets
             * and, accordingly, it's IDT.
             *
             * We can't yet reinject any of those interrupts since we don't know new offsets, so we
             * do that in following steps:
             * 1. Cancel any interrupts that might have been raised according to our current IRR.
             *    Don't touch IRR value.
             * 2. Upon completed init reinject all pending IRR interrupts with updated offsets.
             */
            if self.irr != 0 {
                vm::cancel_all_external_interrupts();
            }

            /* Also, what if an interrupt was delivered (ISR != 0) but not EOI-ed by the guest?
             * Stricktly speaking this is a guest bug.
             * It might deliver a racy EOI after init so let's keep ISR hanging as well */
        } else if cmd == PIC_READ_IRR {
            self.cmd_latch = self.irr;
        } else if cmd == PIC_READ_ISR {
            self.cmd_latch = self.isr;
        } else if cmd == PIC_EOI {
            self.isr = 0; /* Maybe last sent only? */
        } else {
            debug!("Unsupported PIC command {:x}", cmd);
        }
    }

    /* Read from command port */
    fn read_command(&mut self) -> u8 {
        return self.cmd_latch;
    }

    /* Write to data port */
    fn write_data(&mut self, data: u8) {
        match self.next_icw {
            2 => {
                self.offset = data;
                self.next_icw = 3;
            },

            3 => {
                self.icw3 = data;
                self.next_icw = 4;
            },

            4 => {
                assert!(data == ICW4_8086); /* Just check that ICW4 is the only one we support */
                self.next_icw = 1; /* Init sequence complete */

                /* Re-inject pre-reset pending interrupts from IRR.
                 * See comments in write_command ICW1 */
                for i in 0..8 {
                    if (self.irr & (1_u8 << i)) != 0 {
                        vm::raise_external_interrupt(i + self.offset);
                    }
                }
            },

            _ => {
                self.imr = data; /* Outside init sequence all writes go to IMR by default */
            }
        }
    }

    /* Read from data port */
    fn read_data(&mut self) -> u8 {
        self.imr
    }
}

/**
 * Cascade PIC setup
 */
struct PIC
{
    master: I8259A,
    slave: I8259A,
}

impl PIC
{
    fn new() -> PIC {
        PIC {
            master: I8259A::default(),
            slave: I8259A::default(),
        }
    }

    fn assert_irq(&mut self, irq: u8) {
        assert!(irq <= 15);
        if irq < 8 {
            self.master.assert_irq(irq);
        } else {
            let slave_irq = self.master.slave_irq();
            self.master.assert_irq(slave_irq);
            self.slave.assert_irq(irq - 8);
        }
    }
}

///////////////////////////////////////////////////////////////////////////////

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

    fn init_common(offset: u8, mask: u8, cascade: u8) -> I8259A {
        let mut dev = I8259A::default();
        assert!(!dev.is_initialized());

        dev.write_command(super::ICW1_INIT | super::ICW1_ICW4);
        assert!(!dev.is_initialized());

        dev.write_data(offset);
        assert!(!dev.is_initialized());

        dev.write_data(cascade);
        assert!(!dev.is_initialized());

        dev.write_data(super::ICW4_8086);
        assert!(dev.is_initialized());

        dev.write_data(mask);
        assert!(dev.read_data() == mask);

        return dev;
    }

    /* Init with ICW4 */
    #[test] fn init() {
        let mut dev = init_common(0x08, 0xAB, 0x02);
    }
}

///////////////////////////////////////////////////////////////////////////////

struct PICDev
{
    pic: RefCell<PIC>,
}

impl vm::io_handler for PICDev
{
    fn io_read(&self, port: u16, size: u8) -> vm::IoOperandType
    {
        assert!(size == 1);

        let mut dev = self.pic.borrow_mut();
        vm::IoOperandType::byte(
            match port {
                PIC_MASTER_DATA => dev.master.read_data(),
                PIC_MASTER_CMD => dev.master.read_command(),

                PIC_SLAVE_DATA => dev.slave.read_data(),
                PIC_SLAVE_CMD => dev.slave.read_command(),

                _ => 0,
            }
        )
    }

    fn io_write(&self, port: u16, data: vm::IoOperandType)
    {
        let mut dev = self.pic.borrow_mut();
        let data8 = data.unwrap_byte();

        match port {
            PIC_MASTER_DATA => dev.master.write_data(data8),
            PIC_MASTER_CMD => dev.master.write_command(data8),

            PIC_SLAVE_DATA => dev.slave.write_data(data8),
            PIC_SLAVE_CMD => dev.slave.write_command(data8),

            _ => panic!(),
        }
    }
}

impl vm::interrupt_controller for PICDev
{
    fn assert_irq(&self, irq: u8)
    {
        let mut dev = self.pic.borrow_mut();
        dev.assert_irq(irq)
    }
}

pub fn init()
{
	let dev = Rc::new(PICDev {
        pic: RefCell::new(PIC::new()),
    });

    vm::register_interrupt_controller(dev.clone());

    vm::register_io_region(dev.clone(), PIC_MASTER_CMD, 1);
    vm::register_io_region(dev.clone(), PIC_MASTER_DATA, 1);
    vm::register_io_region(dev.clone(), PIC_SLAVE_CMD, 1);
    vm::register_io_region(dev.clone(), PIC_SLAVE_DATA, 1);
}

<commit_msg>PIC: Warnings cleanup<commit_after>/*
 * PIC emulation
 */

use vm;

use std::rc::Rc;
use std::cell::RefCell;

const PIC_MASTER_CMD: u16 = 0x20;
const PIC_MASTER_DATA: u16 = 0x21;
const PIC_SLAVE_CMD: u16 = 0xA0;
const PIC_SLAVE_DATA: u16 = 0xA1;

const ICW1_INIT: u8 = 0x10;
const ICW1_ICW4: u8 = 0x01;
const ICW4_8086: u8 = 0x01;

const PIC_READ_IRR: u8 = 0x0A;
const PIC_READ_ISR: u8 = 0x0B;
const PIC_EOI: u8 = 0x20;

/**
 * i8259 PIC chip
 */
struct I8259A
{
    irr: u8,    // IRR register
    isr: u8,    // ISR register
    imr: u8,    // IRQ mask
    offset: u8, // Interrupt vector base
    icw3: u8,   // ICW3 value during initialization (cascade IRQ)
    next_icw: usize,    // During init, next ICW word expected during init
    cmd_latch: u8,      // Latched value to be read next time from command port
}

impl I8259A
{
    fn default() -> I8259A {
        I8259A {
            irr: 0,
            isr: 0,
            imr: 0,
            offset: 0,
            icw3: 0,
            next_icw: 0,
            cmd_latch: 0,
        }
    }

    fn is_initialized(&self) -> bool {
        self.next_icw == 1
    }

    fn slave_irq(&self) -> u8 {
        self.icw3
    }

    /* Assert an IRQ line */
    fn assert_irq(&mut self, irq: u8) {
        assert!(irq < 8);

        if !self.is_initialized() {
            return;
        }

        let mask = 1u8 << irq;
        if (self.imr & mask) != 0 {
            return;
        }

        /* We only update IRR here because we're not sure when
         * interrupt event is going to be injected in guest.
         * So ISR will be updated once guest will try to access it */
        self.irr |= mask;

        /* Notify VM state we need to inject this vector */
        vm::raise_external_interrupt(irq + self.offset);
    }

    /* Write to command port */
    fn write_command(&mut self, cmd: u8) {
        if cmd & ICW1_INIT != 0 {
            /* Start initialization
             * We support only ICW1 + ICW4 (and ICW4 should set 8086 tyoe) */
            assert!(cmd & !(ICW1_INIT | ICW1_ICW4) == 0);
            self.next_icw = 2;
            self.imr = 0;

            /* What happens to raised but not yet injected guest interrupts at this point?
             * Intel spec is not entirely clear on that regard, however continuing to deliver
             * those interrupts can be bad since guest might now change IRQ offsets
             * and, accordingly, it's IDT.
             *
             * We can't yet reinject any of those interrupts since we don't know new offsets, so we
             * do that in following steps:
             * 1. Cancel any interrupts that might have been raised according to our current IRR.
             *    Don't touch IRR value.
             * 2. Upon completed init reinject all pending IRR interrupts with updated offsets.
             */
            if self.irr != 0 {
                vm::cancel_all_external_interrupts();
            }

            /* Also, what if an interrupt was delivered (ISR != 0) but not EOI-ed by the guest?
             * Stricktly speaking this is a guest bug.
             * It might deliver a racy EOI after init so let's keep ISR hanging as well */
        } else if cmd == PIC_READ_IRR {
            self.cmd_latch = self.irr;
        } else if cmd == PIC_READ_ISR {
            self.cmd_latch = self.isr;
        } else if cmd == PIC_EOI {
            self.isr = 0; /* Maybe last sent only? */
        } else {
            debug!("Unsupported PIC command {:x}", cmd);
        }
    }

    /* Read from command port */
    fn read_command(&mut self) -> u8 {
        return self.cmd_latch;
    }

    /* Write to data port */
    fn write_data(&mut self, data: u8) {
        match self.next_icw {
            2 => {
                self.offset = data;
                self.next_icw = 3;
            },

            3 => {
                self.icw3 = data;
                self.next_icw = 4;
            },

            4 => {
                assert!(data == ICW4_8086); /* Just check that ICW4 is the only one we support */
                self.next_icw = 1; /* Init sequence complete */

                /* Re-inject pre-reset pending interrupts from IRR.
                 * See comments in write_command ICW1 */
                for i in 0..8 {
                    if (self.irr & (1_u8 << i)) != 0 {
                        vm::raise_external_interrupt(i + self.offset);
                    }
                }
            },

            _ => {
                self.imr = data; /* Outside init sequence all writes go to IMR by default */
            }
        }
    }

    /* Read from data port */
    fn read_data(&mut self) -> u8 {
        self.imr
    }
}

/**
 * Cascade PIC setup
 */
struct PIC
{
    master: I8259A,
    slave: I8259A,
}

impl PIC
{
    fn new() -> PIC {
        PIC {
            master: I8259A::default(),
            slave: I8259A::default(),
        }
    }

    fn assert_irq(&mut self, irq: u8) {
        assert!(irq <= 15);
        if irq < 8 {
            self.master.assert_irq(irq);
        } else {
            let slave_irq = self.master.slave_irq();
            self.master.assert_irq(slave_irq);
            self.slave.assert_irq(irq - 8);
        }
    }
}

///////////////////////////////////////////////////////////////////////////////

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

    fn init_common(offset: u8, mask: u8, cascade: u8) -> I8259A {
        let mut dev = I8259A::default();
        assert!(!dev.is_initialized());

        dev.write_command(super::ICW1_INIT | super::ICW1_ICW4);
        assert!(!dev.is_initialized());

        dev.write_data(offset);
        assert!(!dev.is_initialized());

        dev.write_data(cascade);
        assert!(!dev.is_initialized());

        dev.write_data(super::ICW4_8086);
        assert!(dev.is_initialized());

        dev.write_data(mask);
        assert!(dev.read_data() == mask);

        return dev;
    }

    /* Init with ICW4 */
    #[test] fn init() {
        let dev = init_common(0x08, 0xAB, 0x02);
        assert!(dev.is_initialized());
    }
}

///////////////////////////////////////////////////////////////////////////////

struct PICDev
{
    pic: RefCell<PIC>,
}

impl vm::io_handler for PICDev
{
    fn io_read(&self, port: u16, size: u8) -> vm::IoOperandType
    {
        assert!(size == 1);

        let mut dev = self.pic.borrow_mut();
        vm::IoOperandType::byte(
            match port {
                PIC_MASTER_DATA => dev.master.read_data(),
                PIC_MASTER_CMD => dev.master.read_command(),

                PIC_SLAVE_DATA => dev.slave.read_data(),
                PIC_SLAVE_CMD => dev.slave.read_command(),

                _ => 0,
            }
        )
    }

    fn io_write(&self, port: u16, data: vm::IoOperandType)
    {
        let mut dev = self.pic.borrow_mut();
        let data8 = data.unwrap_byte();

        match port {
            PIC_MASTER_DATA => dev.master.write_data(data8),
            PIC_MASTER_CMD => dev.master.write_command(data8),

            PIC_SLAVE_DATA => dev.slave.write_data(data8),
            PIC_SLAVE_CMD => dev.slave.write_command(data8),

            _ => panic!(),
        }
    }
}

impl vm::interrupt_controller for PICDev
{
    fn assert_irq(&self, irq: u8)
    {
        let mut dev = self.pic.borrow_mut();
        dev.assert_irq(irq)
    }
}

pub fn init()
{
	let dev = Rc::new(PICDev {
        pic: RefCell::new(PIC::new()),
    });

    vm::register_interrupt_controller(dev.clone());

    vm::register_io_region(dev.clone(), PIC_MASTER_CMD, 1);
    vm::register_io_region(dev.clone(), PIC_MASTER_DATA, 1);
    vm::register_io_region(dev.clone(), PIC_SLAVE_CMD, 1);
    vm::register_io_region(dev.clone(), PIC_SLAVE_DATA, 1);
}

<|endoftext|>


<commit_before>use std::io;
use std::net::SocketAddr;
use std::str::FromStr;
use std::time::Duration;

use std::io::{Read, Write};  // Used for TcpStream.read,  TcpStream.write
use mio::{Poll, Token, Events, Event, Ready, PollOpt};
use mio::tcp::{TcpListener, TcpStream};

use slab;
use interface::{ServerFactory, Protocol, Reason};
use transport::Transport;

const CONNS_MAX: usize = 65_536;
const BUF_SIZE: usize = 4096;

type Slab<T> = slab::Slab<T, Token>;

#[derive(Clone)]
enum ConnectionType {
    Server,
    Client,
}

struct ServerConnection {
    server: Box<ServerFactory>,
    socket: TcpListener,
}

struct ClientConnection {
    protocol: Box<Protocol>,
    socket: TcpStream,
    interest: Ready,
    transport: Transport,
}

impl ClientConnection {
    fn new(protocol: Box<Protocol>, socket: TcpStream) -> ClientConnection {
        ClientConnection {
            protocol: protocol,
            socket: socket,
            interest: Ready::hup() | Ready::readable(),
            transport: Transport::new(),
        }
    }

    fn peer_addr(&self) -> io::Result<SocketAddr> {
        self.socket.peer_addr()
    }

    fn is_finished(&self) -> bool {
        self.interest == Ready::none()
    }

    fn handle_hup(&mut self) {
        self.interest = Ready::none();
    }

    fn handle_read(&mut self) -> io::Result<()> {
        let mut read_bytes: Vec<u8> = Vec::new();
        loop {
            let (buf, read_len) = {
                let mut buf = [0; BUF_SIZE];
                let read_len = try!(self.socket.read(&mut buf[..]));
                // let s_data = str::from_utf8(&buf).unwrap();
                // info!("<<< {}", s_data);
                (buf, read_len)
            };
            if read_len > 0 {
                read_bytes.extend(buf[0..read_len].iter());
                if read_len < BUF_SIZE {
                    debug!("Nothing more to read");
                    break;
                } else {
                    debug!("More data to read");
                }
            } else {
                debug!("Nothing to read");
                break;
            }
        }
        if read_bytes.len() > 0 {
            self.protocol.data_received(&read_bytes[..], &mut self.transport);
        }
        Ok(())
    }

    fn handle_write(&mut self) {

        {
            // a block where transport muting

            debug!("handle write");
            let buf = &mut self.transport.buf();
            let to_write_len = buf.len();
            if to_write_len > 0 {
                // let s_data = str::from_utf8(&buf[..]).unwrap();
                // info!(">>> {}", s_data);

                let result = self.socket.write(&buf[..]);
                match result {
                    Ok(written_len) => {
                        debug!("Write {} bytes", written_len);
                        if to_write_len != written_len {
                            error!("{} bytes to write but {} written, hanging up",
                                   to_write_len,
                                   written_len);
                            self.interest = Ready::hup();
                        }
                    }
                    Err(err) => {
                        error!("Error {} while writing to the socket, disconnecting", err);
                        self.interest = Ready::hup();
                    }
                };
            }
        };

        self.transport.clear();

        if self.transport.hup() {
            info!("Peer is disconnecting, will unregister connection");
            self.interest = Ready::none();
        }
    }
}

struct Connection {
    connection_type: ConnectionType,
    server: Option<ServerConnection>,
    client: Option<ClientConnection>,
    peer_addr: SocketAddr,
}

#[allow(dead_code)]
impl Connection {
    fn new_server(server: Box<ServerFactory>,
                  peer_addr: SocketAddr,
                  socket: TcpListener)
                  -> Connection {
        Connection {
            connection_type: ConnectionType::Server,
            server: Some(ServerConnection {
                server: server,
                socket: socket,
            }),
            client: None,
            peer_addr: peer_addr,
        }
    }

    fn new_client(protocol: Box<Protocol>, peer_addr: SocketAddr, socket: TcpStream) -> Connection {
        Connection {
            connection_type: ConnectionType::Client,
            client: Some(ClientConnection::new(protocol, socket)),
            server: None,
            peer_addr: peer_addr,
        }
    }

    fn peer_addr(&self) -> SocketAddr {
        self.peer_addr
    }

    fn server_ref(&self) -> &ServerConnection {
        self.server.as_ref().unwrap()
    }

    fn client_ref(&self) -> &ClientConnection {
        self.client.as_ref().unwrap()
    }

    fn client_mut(&mut self) -> &mut ClientConnection {
        self.client.as_mut().unwrap()
    }

    fn alive(&self) -> bool {
        return match self.connection_type {
            ConnectionType::Server => true,
            ConnectionType::Client => {
                match self.client_ref().peer_addr() {
                    Ok(_) => true,
                    Err(_) => false,
                }
            }
        };
    }
}

/// The I/O Loop
pub struct Rio {
    poll: Poll,
    connections: Slab<Connection>,
    running: bool
}

impl Rio {
    /// Instanciate the IOLoop, should be called once.
    pub fn new() -> Rio {
        let poll: Poll = Poll::new().unwrap();
        let connections = Slab::with_capacity(CONNS_MAX);
        Rio {
            running: false,
            poll: poll,
            connections: connections,
        }
    }

    /// Will listen on the given address when the loop will start.
    /// The ServerFactory.build_protocol method will be called on every
    /// new client connection.
    pub fn listen(&mut self, addr: &str, server: Box<ServerFactory>) -> Result<Token, io::Error> {
        info!("Rio is listenning on {}", addr);
        let sock_addr: SocketAddr = FromStr::from_str(addr).unwrap();
        debug!("Bind the server socket {}", addr);
        let sock = TcpListener::bind(&sock_addr).unwrap();
        let result = self.connections.insert(Connection::new_server(server, sock_addr, sock));
        match result {
            Ok(token) => {
                let _ = self.poll.register(&self.connections[token].server_ref().socket,
                                           token,
                                           Ready::readable() | Ready::writable(),
                                           PollOpt::edge());
                return Ok(token);
            }
            Err(_) => {
                error!("Cannot register server {:?}", addr);
                return Err(io::Error::new(io::ErrorKind::Other, format!("Cannot register server {:?}", addr)));
            }
        }
    }

    /// Will listen on the given address when the loop will start.
    /// The ServerFactory.build_protocol method will be called on every
    /// new client connection.
    pub fn connect(&mut self, addr: &str, client: Box<Protocol>) -> Result<Token, io::Error> {
        info!("Connecting to socket {}", addr);
        let sock_addr: SocketAddr = FromStr::from_str(addr).unwrap();

        let sock = TcpStream::connect(&sock_addr).unwrap();
        let result = self.connections.insert(Connection::new_client(client, sock_addr, sock));
        match result {
            Ok(token) => {
                let client = self.connections[token].client_mut();
                client.protocol.connection_made(&mut client.transport);
                let _ = self.poll.register(&client.socket,
                                           token,
                                           Ready::all(),
                                           PollOpt::all());
                debug!(" socket {} registered in the poller", addr);
                return Ok(token);
            }
            Err(_) => {
                error!("Cannot register client {:?}", addr);
                return Err(io::Error::new(io::ErrorKind::Other, format!("Cannot register client {:?}", addr)));
            }
        }
    }

    /// Start the io loop
    pub fn run_forever(&mut self) {
        self.run_until(&|_: &Rio| -> bool { true });
    }

    pub fn run_until(&mut self, is_done: &Fn(&Rio) -> bool) {

        info!("Start polling");

        let timeout = Duration::from_millis(500);
        let mut events = Events::with_capacity(1024);

        self.running = true;
        while self.running {
            // debug!("Polling...");
            self.poll.poll(&mut events, Some(timeout)).unwrap();

            for event in events.iter() {
                let token = event.token();
                debug!("Got event for {:?}", token);
                let _ = match self.connections[token].connection_type {
                    ConnectionType::Server => self.handle_server(token),
                    ConnectionType::Client => self.handle_client(token, event),
                };
            }
            self.running = is_done(self)
        }
    }

    pub fn contains(&self, token: Token) -> bool {
        return self.connections.contains(token)
    }

    fn handle_server(&mut self, token: Token) -> io::Result<()> {
        while self.running {
            let (sock, addr) = try!(self.connections[token].server_ref().socket.accept());

            info!("Accepting connection from {:?}", addr);

            debug!("Building procotol");
            let protocol = {
                let server = self.connections[token].server.as_ref();
                server.unwrap().server.build_protocol()
            };

            debug!("Take a token for the connection");
            let result = self.connections.insert(Connection::new_client(protocol, addr, sock));
            match result {
                Ok(client_token) => {
                    debug!("Registering procotol");
                    let mut client = self.connections[client_token].client_mut();
                    client.protocol.connection_made(&mut client.transport);
                    try!(self.poll.register(&client.socket,
                                            client_token,
                                            Ready::readable() | Ready::writable(),
                                            PollOpt::edge() | PollOpt::oneshot()));
                }
                Err(_) => error!("Cannot register client"),

            }
        }
        Ok(())
    }

    fn handle_client(&mut self, token: Token, event: Event) -> io::Result<()> {
        debug!("handle client, {:?}", event);

        if !&self.connections.contains(token) {
            error!("Ignoring unkown token to handle");
            return Ok(());
        }

        let kind = event.kind();

        if !&self.connections[token].alive() || kind.is_error() {
            error!("Connection failed {:?}", &self.connections[token].peer_addr);
            info!("Removing connection {:?}",
                  &self.connections[token].peer_addr);

            {
                let client = &mut self.connections[token].client_mut();
                client.protocol.connection_lost(Reason::ConnectionError);
            }
            self.connections.remove(token);
            return Ok(());
        }

        let mut finished = false;
        let client_addr = &self.connections[token].client_ref().peer_addr().unwrap().clone();
        {
            let mut client = &mut self.connections[token].client_mut();

            debug!("handle client {:?} {:?}", token, client_addr);

            if kind.is_hup() {
                debug!("handle hup {:?} {:?}", token, client_addr);
                client.handle_hup();
                finished = true;
            } else {
                if kind.is_readable() {
                    debug!("handle readable {:?} {:?}", token, client_addr);
                    try!(client.handle_read());
                }

                if kind.is_writable() || client.transport.should_write() {
                    debug!("handle writable {:?} {:?}", token, client_addr);
                    client.handle_write();
                }
            }

            if client.is_finished() {
                info!("Closing connection with {:?} {:?}", token, client_addr);
                match client.peer_addr() {
                    Ok(addr) => info!("Connection closed {:?}", addr),
                    Err(_) => error!("Connection closed (Peer already disconnected)"),
                }
                if client.transport.hup() {
                    info!("Peer hang up {:?} {:?}", token, client_addr);
                    client.protocol.connection_lost(Reason::HangUp);
                } else {
                    info!("Connection lost {:?} {:?}", token, client_addr);
                    client.protocol.connection_lost(Reason::ConnectionLost);
                }
                try!(self.poll.deregister(&client.socket));
                finished = true;
            } else {
                info!("Reregister token {:?} {:?}", token, client_addr);
                try!(self.poll.reregister(&client.socket, token, client.interest, PollOpt::edge()));
            }
        }

        if finished {
            info!("Removing connection {:?} {:?}", token, client_addr);
            self.connections.remove(token);
        }

        debug!("end handle client {:?} {:?}", token, client_addr);
        Ok(())
    }
}
<commit_msg>Remove dead code<commit_after>use std::io;
use std::net::SocketAddr;
use std::str::FromStr;
use std::time::Duration;

use std::io::{Read, Write};  // Used for TcpStream.read,  TcpStream.write
use mio::{Poll, Token, Events, Event, Ready, PollOpt};
use mio::tcp::{TcpListener, TcpStream};

use slab;
use interface::{ServerFactory, Protocol, Reason};
use transport::Transport;

const CONNS_MAX: usize = 65_536;
const BUF_SIZE: usize = 4096;

type Slab<T> = slab::Slab<T, Token>;

#[derive(Clone)]
enum ConnectionType {
    Server,
    Client,
}

struct ServerConnection {
    server: Box<ServerFactory>,
    socket: TcpListener,
}

struct ClientConnection {
    protocol: Box<Protocol>,
    socket: TcpStream,
    interest: Ready,
    transport: Transport,
}

impl ClientConnection {
    fn new(protocol: Box<Protocol>, socket: TcpStream) -> ClientConnection {
        ClientConnection {
            protocol: protocol,
            socket: socket,
            interest: Ready::hup() | Ready::readable(),
            transport: Transport::new(),
        }
    }

    fn peer_addr(&self) -> io::Result<SocketAddr> {
        self.socket.peer_addr()
    }

    fn is_finished(&self) -> bool {
        self.interest == Ready::none()
    }

    fn handle_hup(&mut self) {
        self.interest = Ready::none();
    }

    fn handle_read(&mut self) -> io::Result<()> {
        let mut read_bytes: Vec<u8> = Vec::new();
        loop {
            let (buf, read_len) = {
                let mut buf = [0; BUF_SIZE];
                let read_len = try!(self.socket.read(&mut buf[..]));
                // let s_data = str::from_utf8(&buf).unwrap();
                // info!("<<< {}", s_data);
                (buf, read_len)
            };
            if read_len > 0 {
                read_bytes.extend(buf[0..read_len].iter());
                if read_len < BUF_SIZE {
                    debug!("Nothing more to read");
                    break;
                } else {
                    debug!("More data to read");
                }
            } else {
                debug!("Nothing to read");
                break;
            }
        }
        if read_bytes.len() > 0 {
            self.protocol.data_received(&read_bytes[..], &mut self.transport);
        }
        Ok(())
    }

    fn handle_write(&mut self) {

        {
            // a block where transport muting

            debug!("handle write");
            let buf = &mut self.transport.buf();
            let to_write_len = buf.len();
            if to_write_len > 0 {
                // let s_data = str::from_utf8(&buf[..]).unwrap();
                // info!(">>> {}", s_data);

                let result = self.socket.write(&buf[..]);
                match result {
                    Ok(written_len) => {
                        debug!("Write {} bytes", written_len);
                        if to_write_len != written_len {
                            error!("{} bytes to write but {} written, hanging up",
                                   to_write_len,
                                   written_len);
                            self.interest = Ready::hup();
                        }
                    }
                    Err(err) => {
                        error!("Error {} while writing to the socket, disconnecting", err);
                        self.interest = Ready::hup();
                    }
                };
            }
        };

        self.transport.clear();

        if self.transport.hup() {
            info!("Peer is disconnecting, will unregister connection");
            self.interest = Ready::none();
        }
    }
}

struct Connection {
    connection_type: ConnectionType,
    server: Option<ServerConnection>,
    client: Option<ClientConnection>,
    peer_addr: SocketAddr,
}

impl Connection {
    fn new_server(server: Box<ServerFactory>,
                  peer_addr: SocketAddr,
                  socket: TcpListener)
                  -> Connection {
        Connection {
            connection_type: ConnectionType::Server,
            server: Some(ServerConnection {
                server: server,
                socket: socket,
            }),
            client: None,
            peer_addr: peer_addr,
        }
    }

    fn new_client(protocol: Box<Protocol>, peer_addr: SocketAddr, socket: TcpStream) -> Connection {
        Connection {
            connection_type: ConnectionType::Client,
            client: Some(ClientConnection::new(protocol, socket)),
            server: None,
            peer_addr: peer_addr,
        }
    }

    fn server_ref(&self) -> &ServerConnection {
        self.server.as_ref().unwrap()
    }

    fn client_ref(&self) -> &ClientConnection {
        self.client.as_ref().unwrap()
    }

    fn client_mut(&mut self) -> &mut ClientConnection {
        self.client.as_mut().unwrap()
    }

    fn alive(&self) -> bool {
        return match self.connection_type {
            ConnectionType::Server => true,
            ConnectionType::Client => {
                match self.client_ref().peer_addr() {
                    Ok(_) => true,
                    Err(_) => false,
                }
            }
        };
    }
}

/// The I/O Loop
pub struct Rio {
    poll: Poll,
    connections: Slab<Connection>,
    running: bool
}

impl Rio {
    /// Instanciate the IOLoop, should be called once.
    pub fn new() -> Rio {
        let poll: Poll = Poll::new().unwrap();
        let connections = Slab::with_capacity(CONNS_MAX);
        Rio {
            running: false,
            poll: poll,
            connections: connections,
        }
    }

    /// Will listen on the given address when the loop will start.
    /// The ServerFactory.build_protocol method will be called on every
    /// new client connection.
    pub fn listen(&mut self, addr: &str, server: Box<ServerFactory>) -> Result<Token, io::Error> {
        info!("Rio is listenning on {}", addr);
        let sock_addr: SocketAddr = FromStr::from_str(addr).unwrap();
        debug!("Bind the server socket {}", addr);
        let sock = TcpListener::bind(&sock_addr).unwrap();
        let result = self.connections.insert(Connection::new_server(server, sock_addr, sock));
        match result {
            Ok(token) => {
                let _ = self.poll.register(&self.connections[token].server_ref().socket,
                                           token,
                                           Ready::readable() | Ready::writable(),
                                           PollOpt::edge());
                return Ok(token);
            }
            Err(_) => {
                error!("Cannot register server {:?}", addr);
                return Err(io::Error::new(io::ErrorKind::Other, format!("Cannot register server {:?}", addr)));
            }
        }
    }

    /// Will listen on the given address when the loop will start.
    /// The ServerFactory.build_protocol method will be called on every
    /// new client connection.
    pub fn connect(&mut self, addr: &str, client: Box<Protocol>) -> Result<Token, io::Error> {
        info!("Connecting to socket {}", addr);
        let sock_addr: SocketAddr = FromStr::from_str(addr).unwrap();

        let sock = TcpStream::connect(&sock_addr).unwrap();
        let result = self.connections.insert(Connection::new_client(client, sock_addr, sock));
        match result {
            Ok(token) => {
                let client = self.connections[token].client_mut();
                client.protocol.connection_made(&mut client.transport);
                let _ = self.poll.register(&client.socket,
                                           token,
                                           Ready::all(),
                                           PollOpt::all());
                debug!(" socket {} registered in the poller", addr);
                return Ok(token);
            }
            Err(_) => {
                error!("Cannot register client {:?}", addr);
                return Err(io::Error::new(io::ErrorKind::Other, format!("Cannot register client {:?}", addr)));
            }
        }
    }

    /// Start the io loop
    pub fn run_forever(&mut self) {
        self.run_until(&|_: &Rio| -> bool { true });
    }

    pub fn run_until(&mut self, is_done: &Fn(&Rio) -> bool) {

        info!("Start polling");

        let timeout = Duration::from_millis(500);
        let mut events = Events::with_capacity(1024);

        self.running = true;
        while self.running {
            // debug!("Polling...");
            self.poll.poll(&mut events, Some(timeout)).unwrap();

            for event in events.iter() {
                let token = event.token();
                debug!("Got event for {:?}", token);
                let _ = match self.connections[token].connection_type {
                    ConnectionType::Server => self.handle_server(token),
                    ConnectionType::Client => self.handle_client(token, event),
                };
            }
            self.running = is_done(self)
        }
    }

    pub fn contains(&self, token: Token) -> bool {
        return self.connections.contains(token)
    }

    fn handle_server(&mut self, token: Token) -> io::Result<()> {
        while self.running {
            let (sock, addr) = try!(self.connections[token].server_ref().socket.accept());

            info!("Accepting connection from {:?}", addr);

            debug!("Building procotol");
            let protocol = {
                let server = self.connections[token].server.as_ref();
                server.unwrap().server.build_protocol()
            };

            debug!("Take a token for the connection");
            let result = self.connections.insert(Connection::new_client(protocol, addr, sock));
            match result {
                Ok(client_token) => {
                    debug!("Registering procotol");
                    let mut client = self.connections[client_token].client_mut();
                    client.protocol.connection_made(&mut client.transport);
                    try!(self.poll.register(&client.socket,
                                            client_token,
                                            Ready::readable() | Ready::writable(),
                                            PollOpt::edge() | PollOpt::oneshot()));
                }
                Err(_) => error!("Cannot register client"),

            }
        }
        Ok(())
    }

    fn handle_client(&mut self, token: Token, event: Event) -> io::Result<()> {
        debug!("handle client, {:?}", event);

        if !&self.connections.contains(token) {
            error!("Ignoring unkown token to handle");
            return Ok(());
        }

        let kind = event.kind();

        if !&self.connections[token].alive() || kind.is_error() {
            error!("Connection failed {:?}", &self.connections[token].peer_addr);
            info!("Removing connection {:?}",
                  &self.connections[token].peer_addr);

            {
                let client = &mut self.connections[token].client_mut();
                client.protocol.connection_lost(Reason::ConnectionError);
            }
            self.connections.remove(token);
            return Ok(());
        }

        let mut finished = false;
        let client_addr = &self.connections[token].client_ref().peer_addr().unwrap().clone();
        {
            let mut client = &mut self.connections[token].client_mut();

            debug!("handle client {:?} {:?}", token, client_addr);

            if kind.is_hup() {
                debug!("handle hup {:?} {:?}", token, client_addr);
                client.handle_hup();
                finished = true;
            } else {
                if kind.is_readable() {
                    debug!("handle readable {:?} {:?}", token, client_addr);
                    try!(client.handle_read());
                }

                if kind.is_writable() || client.transport.should_write() {
                    debug!("handle writable {:?} {:?}", token, client_addr);
                    client.handle_write();
                }
            }

            if client.is_finished() {
                info!("Closing connection with {:?} {:?}", token, client_addr);
                match client.peer_addr() {
                    Ok(addr) => info!("Connection closed {:?}", addr),
                    Err(_) => error!("Connection closed (Peer already disconnected)"),
                }
                if client.transport.hup() {
                    info!("Peer hang up {:?} {:?}", token, client_addr);
                    client.protocol.connection_lost(Reason::HangUp);
                } else {
                    info!("Connection lost {:?} {:?}", token, client_addr);
                    client.protocol.connection_lost(Reason::ConnectionLost);
                }
                try!(self.poll.deregister(&client.socket));
                finished = true;
            } else {
                info!("Reregister token {:?} {:?}", token, client_addr);
                try!(self.poll.reregister(&client.socket, token, client.interest, PollOpt::edge()));
            }
        }

        if finished {
            info!("Removing connection {:?} {:?}", token, client_addr);
            self.connections.remove(token);
        }

        debug!("end handle client {:?} {:?}", token, client_addr);
        Ok(())
    }
}
<|endoftext|>