<commit_before>// Copyright 2016 Pavel Kiselev

// My implementation of Eller's Algorithm, following instructions at http://www.neocomputer.org/projects/eller.html

#![allow(dead_code)]

use rand::{Rng,thread_rng,ThreadRng};
use std::collections::HashMap;
use std::fmt;

#[derive(Debug,Clone,Copy)]
struct Cell {
    set: usize,
    rw: bool,
    bw: bool,
}

pub struct EllerMaze {
    maze: Vec<Vec<Cell>>,
}

// Somewhat changes look of generated mazes
pub enum MazeOrient {
    Normal,
    Vertical,
    Horizontal,
}

impl EllerMaze {
    pub fn generate(width: usize, height: usize, orient: MazeOrient) -> EllerMaze {

        let mut rng = thread_rng();

        //Closure for changing the maze generated (as proposed on neocomputer.org in "Example
        //mazes" section
        let verticality = |orient: &MazeOrient, rng: &mut ThreadRng, is_right: bool| -> bool {
            if is_right {
                match *orient {
                    MazeOrient::Normal => rng.gen(),
                    MazeOrient::Vertical => rng.gen() || rng.gen(),
                    MazeOrient::Horizontal => rng.gen() && rng.gen(),
                }
            } else {
                match *orient {
                    MazeOrient::Normal => rng.gen(),
                    MazeOrient::Vertical => rng.gen() && rng.gen(),
                    MazeOrient::Horizontal => rng.gen() || rng.gen(),
                }
            }
        };

        let mut maze: Vec<Vec<Cell>> = Vec::with_capacity(height);

        // 1. Create the first row. No cells will be members of any set
        let mut row = vec![Cell { set: 0, rw: false, bw: false }; width];

        row[width-1].rw = true; // The last one always has a wall.

        let mut sets: HashMap<usize, Vec<usize>> = HashMap::with_capacity(width);

        for count_iterations in 0..height {

            sets.drain(); // Empty the db

            // Create a database of indexes for all set members
            for (i,cell) in row.iter().enumerate() {
                if sets.contains_key(&cell.set) {
                    let mut vec = sets.get_mut(&cell.set).expect("Cannot get sets to compete the HashMap");
                    (*vec).push(i);
                } else {
                    sets.insert(cell.set, vec![i]);
                }
            }

            // 2. Join any cells not members of a set to their own unique set
            let no_set = sets.remove(&0).unwrap_or(vec![]); //Get indexes of cells without set, or init with empty vec
            for i in no_set {
                let mut j = 1;
                while row[i].set == 0 {
                    if sets.contains_key(&j) {
                        j += 1;
                    } else {
                        row[i].set = j;
                        sets.insert(j, vec![i]);
                    }
                }
            }

            // 3. Create right-walls, moving from left to right:
            for i in 0..row.len()-1 {
                // - If the current cell and the cell to the right are members of the same set, always create a wall between them. (This prevents loops)
                if row[i].set == row[i+1].set {
                    row[i].rw = true;
                    continue;
                }
                // - Randomly decide to add a wall or not:
                if verticality(&orient, &mut rng, true) {
                    row[i].rw = true;
                } else {
                    // - If you decide not to add a wall, union the sets to which the current cell and the cell to the right are members.
                    let mut set2 = sets.remove(&row[i+1].set).expect("Can't get set for union");
                    let mut set1 = sets.get_mut(&row[i].set).expect("Can't get set to union with");
                    for j in set2.iter() {
                        row[*j].set = row[i].set;
                    }
                    set1.append(&mut set2);
                }
            }

            // 4. Create bottom-walls, moving from left to right:
            // 4.1. Randomly decide to add a wall or not. Make sure that each set has at least one cell without a bottom-wall (This prevents isolations)
            // - If a cell is the only member of its set, do not create a bottom-wall
            // - If a cell is the only member of its set without a bottom-wall, do not create a bottom-wall
            let mut wall_sets = sets.clone();
            for (i, cell) in row.iter_mut().enumerate() {
                if verticality(&orient, &mut rng, false) {
                    let mut set = wall_sets.get_mut(&cell.set).expect("Cannot get set to ensure correct bottom walls creation");
                    if set.len() > 1 {
                        cell.bw = true;
                        set.retain(|&x| x != i); // Maybe not optimal. Remove the element
                    }
                }
            }

            // 5. Decide to keep adding rows, or stop and complete the maze
            // 5.1. If you decide to add another row:
            if !(count_iterations == height-1) {
                // 5.1.1. Output the current row
                maze.push(row.clone());
                for cell in row.iter_mut() {
                    // 5.1.2. Remove all right walls
                    if cell.rw {
                        cell.rw = false;
                    }
                    if cell.bw {
                        // 5.1.3. Remove cells with a bottom-wall from their set
                        cell.set = 0;
                        // 5.1.4. Remove all bottom walls
                        cell.bw = false;
                    }
                }
                row[width-1].rw = true; // return the right-most wall

            // 5.1.5. Continue from Step 2
            }
        }

        // 5.2. If you decide to complete the maze
        // 5.2.2. Moving from left to right:
        for i in 0..row.len()-1 {
            // 5.2.1. Add a bottom wall to every cell
            row[i].bw = true;
            // If the current cell and the cell to the right are members of a different set:
            if row[i].set != row[i+1].set {
                // - Remove the right wall
                row[i].rw = false;
                // - Union the sets to which the current cell and cell to the right are members.
                let mut set2 = sets.remove(&row[i+1].set).expect("Can't get set for union");
                let mut set1 = sets.get_mut(&row[i].set).expect("Can't get set to union with");
                for j in set2.iter() {
                    row[*j].set = row[i].set;
                }
                set1.append(&mut set2);
            }
        }
        row[width-1].bw = true;

        // - Output the final row
        maze.push(row);

        EllerMaze {
            maze: maze,
        }
    }
}

// Using the style of http://www.neocomputer.org/projects/eller.html
// Doubled the line count, I think it look better in terminal that way
impl fmt::Display for EllerMaze {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

        let mut result = String::new();

        for _ in 0..self.maze[0].len() {
            result.push_str(" ___");
        }
        result.push('\n');

        for row in &self.maze {
            let mut string1 = String::new();
            let mut string2 = String::new();
            string1.push('|');
            string2.push('|');
            for cell in row {
                if cell.bw {
                    string1.push_str("   ");
                    string2.push_str("___");
                } else {
                    string1.push_str("   ");
                    string2.push_str("   ");
                }
                if cell.rw {
                    string1.push_str("|");
                    string2.push_str("|");
                } else {
                    string1.push_str(" ");
                    string2.push_str(" ");
                }
            }
            result.push_str(&*string1);
            result.push('\n');
            result.push_str(&*string2);
            result.push('\n');
        }

        write!(f, "{}", result)
    }
}

<commit_msg>Update eller.rs<commit_after>// Copyright 2016 Pavel Kiselev

// My implementation of Eller's Algorithm, following instructions at http://www.neocomputer.org/projects/eller.html
// Comments detailing algorithm steps are mostly copypasted from there

#![allow(dead_code)]

use rand::{Rng,thread_rng,ThreadRng};
use std::collections::HashMap;
use std::fmt;

#[derive(Debug,Clone,Copy)]
struct Cell {
    set: usize,
    rw: bool,
    bw: bool,
}

pub struct EllerMaze {
    maze: Vec<Vec<Cell>>,
}

// Somewhat changes look of generated mazes
pub enum MazeOrient {
    Normal,
    Vertical,
    Horizontal,
}

impl EllerMaze {
    pub fn generate(width: usize, height: usize, orient: MazeOrient) -> EllerMaze {

        let mut rng = thread_rng();

        //Closure for changing the maze generated (as proposed on neocomputer.org in "Example
        //mazes" section
        let verticality = |orient: &MazeOrient, rng: &mut ThreadRng, is_right: bool| -> bool {
            if is_right {
                match *orient {
                    MazeOrient::Normal => rng.gen(),
                    MazeOrient::Vertical => rng.gen() || rng.gen(),
                    MazeOrient::Horizontal => rng.gen() && rng.gen(),
                }
            } else {
                match *orient {
                    MazeOrient::Normal => rng.gen(),
                    MazeOrient::Vertical => rng.gen() && rng.gen(),
                    MazeOrient::Horizontal => rng.gen() || rng.gen(),
                }
            }
        };

        let mut maze: Vec<Vec<Cell>> = Vec::with_capacity(height);

        // 1. Create the first row. No cells will be members of any set
        let mut row = vec![Cell { set: 0, rw: false, bw: false }; width];

        row[width-1].rw = true; // The last one always has a wall.

        let mut sets: HashMap<usize, Vec<usize>> = HashMap::with_capacity(width);

        for count_iterations in 0..height {

            sets.drain(); // Empty the db

            // Create a database of indexes for all set members
            for (i,cell) in row.iter().enumerate() {
                if sets.contains_key(&cell.set) {
                    let mut vec = sets.get_mut(&cell.set).expect("Cannot get sets to compete the HashMap");
                    (*vec).push(i);
                } else {
                    sets.insert(cell.set, vec![i]);
                }
            }

            // 2. Join any cells not members of a set to their own unique set
            let no_set = sets.remove(&0).unwrap_or(vec![]); //Get indexes of cells without set, or init with empty vec
            for i in no_set {
                let mut j = 1;
                while row[i].set == 0 {
                    if sets.contains_key(&j) {
                        j += 1;
                    } else {
                        row[i].set = j;
                        sets.insert(j, vec![i]);
                    }
                }
            }

            // 3. Create right-walls, moving from left to right:
            for i in 0..row.len()-1 {
                // - If the current cell and the cell to the right are members of the same set, always create a wall between them. (This prevents loops)
                if row[i].set == row[i+1].set {
                    row[i].rw = true;
                    continue;
                }
                // - Randomly decide to add a wall or not:
                if verticality(&orient, &mut rng, true) {
                    row[i].rw = true;
                } else {
                    // - If you decide not to add a wall, union the sets to which the current cell and the cell to the right are members.
                    let mut set2 = sets.remove(&row[i+1].set).expect("Can't get set for union");
                    let mut set1 = sets.get_mut(&row[i].set).expect("Can't get set to union with");
                    for j in set2.iter() {
                        row[*j].set = row[i].set;
                    }
                    set1.append(&mut set2);
                }
            }

            // 4. Create bottom-walls, moving from left to right:
            // 4.1. Randomly decide to add a wall or not. Make sure that each set has at least one cell without a bottom-wall (This prevents isolations)
            // - If a cell is the only member of its set, do not create a bottom-wall
            // - If a cell is the only member of its set without a bottom-wall, do not create a bottom-wall
            let mut wall_sets = sets.clone();
            for (i, cell) in row.iter_mut().enumerate() {
                if verticality(&orient, &mut rng, false) {
                    let mut set = wall_sets.get_mut(&cell.set).expect("Cannot get set to ensure correct bottom walls creation");
                    if set.len() > 1 {
                        cell.bw = true;
                        set.retain(|&x| x != i); // Maybe not optimal. Remove the element
                    }
                }
            }

            // 5. Decide to keep adding rows, or stop and complete the maze
            // 5.1. If you decide to add another row:
            if !(count_iterations == height-1) {
                // 5.1.1. Output the current row
                maze.push(row.clone());
                for cell in row.iter_mut() {
                    // 5.1.2. Remove all right walls
                    if cell.rw {
                        cell.rw = false;
                    }
                    if cell.bw {
                        // 5.1.3. Remove cells with a bottom-wall from their set
                        cell.set = 0;
                        // 5.1.4. Remove all bottom walls
                        cell.bw = false;
                    }
                }
                row[width-1].rw = true; // return the right-most wall

            // 5.1.5. Continue from Step 2
            }
        }

        // 5.2. If you decide to complete the maze
        // 5.2.2. Moving from left to right:
        for i in 0..row.len()-1 {
            // 5.2.1. Add a bottom wall to every cell
            row[i].bw = true;
            // If the current cell and the cell to the right are members of a different set:
            if row[i].set != row[i+1].set {
                // - Remove the right wall
                row[i].rw = false;
                // - Union the sets to which the current cell and cell to the right are members.
                let mut set2 = sets.remove(&row[i+1].set).expect("Can't get set for union");
                let mut set1 = sets.get_mut(&row[i].set).expect("Can't get set to union with");
                for j in set2.iter() {
                    row[*j].set = row[i].set;
                }
                set1.append(&mut set2);
            }
        }
        row[width-1].bw = true;

        // - Output the final row
        maze.push(row);

        EllerMaze {
            maze: maze,
        }
    }
}

// Using the style of http://www.neocomputer.org/projects/eller.html
// Doubled the line count, I think it look better in terminal that way
impl fmt::Display for EllerMaze {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

        let mut result = String::new();

        for _ in 0..self.maze[0].len() {
            result.push_str(" ___");
        }
        result.push('\n');

        for row in &self.maze {
            let mut string1 = String::new();
            let mut string2 = String::new();
            string1.push('|');
            string2.push('|');
            for cell in row {
                if cell.bw {
                    string1.push_str("   ");
                    string2.push_str("___");
                } else {
                    string1.push_str("   ");
                    string2.push_str("   ");
                }
                if cell.rw {
                    string1.push_str("|");
                    string2.push_str("|");
                } else {
                    string1.push_str(" ");
                    string2.push_str(" ");
                }
            }
            result.push_str(&*string1);
            result.push('\n');
            result.push_str(&*string2);
            result.push('\n');
        }

        write!(f, "{}", result)
    }
}

<|endoftext|>


<commit_before>// Copyright 2017-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Error types

use core::fmt;

#[cfg(feature="std")]
use std::error::Error as stdError;

/// Error kind which can be matched over.
#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub enum ErrorKind {
    /// Permanent failure: likely not recoverable without user action.
    Unavailable,
    /// Temporary failure: recommended to retry a few times, but may also be
    /// irrecoverable.
    Transient,
    /// Not ready yet: recommended to try again a little later.
    NotReady,
    /// Uncategorised error
    Other,
    #[doc(hidden)]
    __Nonexhaustive,
}

impl ErrorKind {
    /// True if this kind of error may resolve itself on retry.
    ///
    /// See also `should_wait()`.
    pub fn should_retry(self) -> bool {
        match self {
            ErrorKind::Transient | ErrorKind::NotReady => true,
            _ => false,
        }
    }

    /// True if we should retry but wait before retrying
    ///
    /// This implies `should_retry()` is true.
    pub fn should_wait(self) -> bool {
        self == ErrorKind::NotReady
    }

    /// A description of this error kind
    pub fn description(self) -> &'static str {
        match self {
            ErrorKind::Unavailable => "permanent failure or unavailable",
            ErrorKind::Transient => "transient failure",
            ErrorKind::NotReady => "not ready yet",
            ErrorKind::Other => "uncategorised",
            ErrorKind::__Nonexhaustive => unreachable!(),
        }
    }
}

/// Error type of random number generators
///
/// This is a relatively simple error type, designed for compatibility with and
/// without the Rust `std` library. It embeds a "kind" code, a message (static
/// string only), and an optional chained cause (`std` only).
#[derive(Debug)]
pub struct Error {
    kind: ErrorKind,
    msg: &'static str,
    #[cfg(feature="std")]
    cause: Option<Box<stdError + Send + Sync>>,
}

impl Error {
    /// Create a new instance, with specified kind and a message.
    pub fn new(kind: ErrorKind, msg: &'static str) -> Self {
        #[cfg(feature="std")] {
            Self { kind, msg, cause: None }
        }
        #[cfg(not(feature="std"))] {
            Self { kind, msg }
        }
    }

    /// Create a new instance, with specified kind, message, and a
    /// chained cause.
    ///
    /// Note: `stdError` is an alias for `std::error::Error`.
    ///
    /// If not targetting `std` (i.e. `no_std`), this function is replaced by
    /// another with the same prototype, except that there are no bounds on the
    /// type `E` (because both `Box` and `stdError` are unavailable), and the
    /// `cause` is ignored.
    #[cfg(feature="std")]
    pub fn with_cause<E>(kind: ErrorKind, msg: &'static str, cause: E) -> Self
        where E: Into<Box<stdError + Send + Sync>>
    {
        Self { kind, msg, cause: Some(cause.into()) }
    }

    /// Create a new instance, with specified kind, message, and a
    /// chained cause.
    ///
    /// In `no_std` mode the *cause* is ignored.
    #[cfg(not(feature="std"))]
    pub fn with_cause<E>(kind: ErrorKind, msg: &'static str, _cause: E) -> Self {
        Self { kind, msg }
    }

    /// Get the error kind
    pub fn kind(&self) -> ErrorKind {
        self.kind
    }

    /// Get the error message
    pub fn msg(&self) -> &'static str {
        self.msg
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "RNG error [{}]: {}", self.kind.description(), self.msg())
    }
}

#[cfg(feature="std")]
impl stdError for Error {
    fn description(&self) -> &str {
        self.msg
    }

    fn cause(&self) -> Option<&stdError> {
        self.cause.as_ref().map(|e| e.as_ref() as &stdError)
    }
}
<commit_msg>Fix for Rust 1.15<commit_after>// Copyright 2017-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Error types

use core::fmt;

#[cfg(feature="std")]
use std::error::Error as stdError;

/// Error kind which can be matched over.
#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub enum ErrorKind {
    /// Permanent failure: likely not recoverable without user action.
    Unavailable,
    /// Temporary failure: recommended to retry a few times, but may also be
    /// irrecoverable.
    Transient,
    /// Not ready yet: recommended to try again a little later.
    NotReady,
    /// Uncategorised error
    Other,
    #[doc(hidden)]
    __Nonexhaustive,
}

impl ErrorKind {
    /// True if this kind of error may resolve itself on retry.
    ///
    /// See also `should_wait()`.
    pub fn should_retry(self) -> bool {
        match self {
            ErrorKind::Transient | ErrorKind::NotReady => true,
            _ => false,
        }
    }

    /// True if we should retry but wait before retrying
    ///
    /// This implies `should_retry()` is true.
    pub fn should_wait(self) -> bool {
        self == ErrorKind::NotReady
    }

    /// A description of this error kind
    pub fn description(self) -> &'static str {
        match self {
            ErrorKind::Unavailable => "permanent failure or unavailable",
            ErrorKind::Transient => "transient failure",
            ErrorKind::NotReady => "not ready yet",
            ErrorKind::Other => "uncategorised",
            ErrorKind::__Nonexhaustive => unreachable!(),
        }
    }
}

/// Error type of random number generators
///
/// This is a relatively simple error type, designed for compatibility with and
/// without the Rust `std` library. It embeds a "kind" code, a message (static
/// string only), and an optional chained cause (`std` only).
#[derive(Debug)]
pub struct Error {
    kind: ErrorKind,
    msg: &'static str,
    #[cfg(feature="std")]
    cause: Option<Box<stdError + Send + Sync>>,
}

impl Error {
    /// Create a new instance, with specified kind and a message.
    pub fn new(kind: ErrorKind, msg: &'static str) -> Self {
        #[cfg(feature="std")] {
            Error { kind: kind, msg: msg, cause: None }
        }
        #[cfg(not(feature="std"))] {
            Error { kind: kind, msg: msg }
        }
    }

    /// Create a new instance, with specified kind, message, and a
    /// chained cause.
    ///
    /// Note: `stdError` is an alias for `std::error::Error`.
    ///
    /// If not targetting `std` (i.e. `no_std`), this function is replaced by
    /// another with the same prototype, except that there are no bounds on the
    /// type `E` (because both `Box` and `stdError` are unavailable), and the
    /// `cause` is ignored.
    #[cfg(feature="std")]
    pub fn with_cause<E>(kind: ErrorKind, msg: &'static str, cause: E) -> Self
        where E: Into<Box<stdError + Send + Sync>>
    {
        Error { kind: kind, msg: msg, cause: Some(cause.into()) }
    }

    /// Create a new instance, with specified kind, message, and a
    /// chained cause.
    ///
    /// In `no_std` mode the *cause* is ignored.
    #[cfg(not(feature="std"))]
    pub fn with_cause<E>(kind: ErrorKind, msg: &'static str, _cause: E) -> Self {
        Error { kind: kind, msg: msg }
    }

    /// Get the error kind
    pub fn kind(&self) -> ErrorKind {
        self.kind
    }

    /// Get the error message
    pub fn msg(&self) -> &'static str {
        self.msg
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "RNG error [{}]: {}", self.kind.description(), self.msg())
    }
}

#[cfg(feature="std")]
impl stdError for Error {
    fn description(&self) -> &str {
        self.msg
    }

    fn cause(&self) -> Option<&stdError> {
        self.cause.as_ref().map(|e| e.as_ref() as &stdError)
    }
}
<|endoftext|>


<commit_before>//! Error and result types.

use std::fmt;
use std::error::Error;
use std::io::Error as IoError;
use std::str::ParseBoolError;
use std::num::ParseIntError;

use chrono::format::ParseError as ChronoParseError;
use serde_json::{Value, from_str};

use xmlutil::XmlParseError;

/// An error produced when AWS API calls are unsuccessful.
#[derive(Debug, PartialEq)]
pub struct AwsError {
    pub message: String
}

pub fn parse_json_protocol_error(body: &str) -> AwsError {
    match from_str::<Value>(body) {
        Ok(json) => {
            let error_type: &str = match json.find("__type") {
                Some(error_type) => error_type.as_string().unwrap_or("Unknown error"),
                None => "Unknown error",
            };

            let error_message: &str = match json.find("message") {
                Some(error_message) => error_message.as_string().unwrap_or(body),
                None => body,
            };

            AwsError::new(format!("{}: {}", error_type, error_message))
        }
        Err(err) => AwsError::new(
            format!("Failed to parse error as JSON: {}.\nRaw error:\n{}", err, body)
        ),
    }
}

impl AwsError {
    /// Create a new error with the given message.
    pub fn new<S>(message: S) -> AwsError where S: Into<String> {
        AwsError {
            message: message.into(),
        }
    }
}

impl Error for AwsError {
    fn description(&self) -> &str {
        &self.message
    }
}

impl From<ParseBoolError> for AwsError {
    fn from(err: ParseBoolError) -> AwsError {
        AwsError::new(format!("{}", err))
    }
}

impl From<ParseIntError> for AwsError {
    fn from(err: ParseIntError) -> AwsError {
        AwsError::new(format!("{}", err))
    }
}

impl From<ChronoParseError> for AwsError {
    fn from(err: ChronoParseError) -> AwsError {
        AwsError::new(format!("{}", err))
    }
}

impl From<IoError> for AwsError {
    fn from(err: IoError) -> AwsError {
        AwsError::new(format!("{}", err))
    }
}

impl From<XmlParseError> for AwsError {
    fn from(err: XmlParseError) -> AwsError {
        AwsError::new(format!("{:?}", err))
    }
}

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

/// The result type produced by AWS API calls.
pub type AwsResult<T> = Result<T, AwsError>;
<commit_msg>remove error.rs<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2016 Linus Färnstrand <faern@faern.net>
//
// 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.

//! Support for sending and receiving data link layer packets on a fake network managed
//! by in memory FIFO queues. Useful for writing tests.

use std::io;
use std::sync::mpsc::{self, Receiver, Sender};
use std::thread;
use std::time;

use datalink::{self, EthernetDataLinkChannelIterator, EthernetDataLinkReceiver,
               EthernetDataLinkSender, NetworkInterface};
use packet::ethernet::{EthernetPacket, MutableEthernetPacket};
use util::MacAddr;

/// Configuration for the dummy datalink backend
#[derive(Debug)]
pub struct Config {
    /// The fake network will pull packets (or errors) form this `Receiver`
    pub in_packets_rx: Receiver<io::Result<Box<[u8]>>>,

    in_packets_tx: Option<Sender<io::Result<Box<[u8]>>>>,

    /// All packets sent to this fake network will end up on this `Sender`
    pub out_packets_tx: Sender<Vec<u8>>,

    out_packets_rx: Option<Receiver<Vec<u8>>>,
}

impl Config {
    /// Get the `Sender` handle that can inject packets in the fake network
    pub fn inject_handle(&mut self) -> Option<Sender<io::Result<Box<[u8]>>>> {
        self.in_packets_tx.take()
    }

    /// Get the `Receiver` handle where packets sent to the fake network can be read
    pub fn read_handle(&mut self) -> Option<Receiver<Vec<u8>>> {
        self.out_packets_rx.take()
    }
}

impl<'a> From<&'a datalink::Config> for Config {
    /// This conversion will not allow injecting and reading packets from the dummy network.
    /// To do that please create your own `dummy::Config`
    fn from(_config: &datalink::Config) -> Config {
        Config::default()
    }
}

impl Default for Config {
    /// This conversion will not allow injecting and reading packets from the dummy network.
    /// To do that please create your own `dummy::Config`
    fn default() -> Config {
        let (in_tx, in_rx) = mpsc::channel();
        let (out_tx, out_rx) = mpsc::channel();
        Config {
            in_packets_rx: in_rx,
            in_packets_tx: Some(in_tx),
            out_packets_tx: out_tx,
            out_packets_rx: Some(out_rx),
        }
    }
}

/// Create a data link channel backed by FIFO queues. Useful for debugging and testing.
pub fn channel(_: &NetworkInterface, config: Config) -> io::Result<datalink::Channel> {
    let sender = Box::new(MockEthernetDataLinkSender { out_packets: config.out_packets_tx });
    let receiver =
        Box::new(MockEthernetDataLinkReceiver { in_packets: Some(config.in_packets_rx) });

    Ok(datalink::Channel::Ethernet(sender, receiver))
}

struct MockEthernetDataLinkSender {
    out_packets: Sender<Vec<u8>>,
}

impl EthernetDataLinkSender for MockEthernetDataLinkSender {
    fn build_and_send(&mut self,
                      _num_packets: usize,
                      packet_size: usize,
                      func: &mut FnMut(MutableEthernetPacket))
        -> Option<io::Result<()>> {
        let mut buffer = vec![0; packet_size];
        {
            let pkg = MutableEthernetPacket::new(&mut buffer[..]).unwrap();
            func(pkg);
        }
        // Send the data to the queue. Don't care if it's closed
        self.out_packets.send(buffer).unwrap_or(());
        Some(Ok(()))
    }

    fn send_to(&mut self,
               _packet: &EthernetPacket,
               _dst: Option<NetworkInterface>)
        -> Option<io::Result<()>> {
        panic!("Not implemented in mock");
    }
}

struct MockEthernetDataLinkReceiver {
    in_packets: Option<Receiver<io::Result<Box<[u8]>>>>,
}

impl EthernetDataLinkReceiver for MockEthernetDataLinkReceiver {
    fn iter<'a>(&'a mut self) -> Box<EthernetDataLinkChannelIterator + 'a> {
        Box::new(MockEthernetDataLinkChannelIterator {
            in_packets: self.in_packets.take().expect("Only one receiver allowed"),
            used_packets: vec![],
        })
    }
}

struct MockEthernetDataLinkChannelIterator {
    in_packets: Receiver<io::Result<Box<[u8]>>>,
    used_packets: Vec<Box<[u8]>>,
}

impl<'a> EthernetDataLinkChannelIterator<'a> for MockEthernetDataLinkChannelIterator {
    fn next(&mut self) -> io::Result<EthernetPacket> {
        match self.in_packets.recv() {
            Ok(result) => {
                // A network event happened. Might be a packet or a simulated error
                match result {
                    Ok(buffer) => {
                        self.used_packets.push(buffer);
                        let buffer_ref = &*self.used_packets[self.used_packets.len() - 1];
                        let packet = EthernetPacket::new(buffer_ref).unwrap();
                        Ok(packet)
                    }
                    Err(e) => Err(e),
                }
            }
            Err(_) => {
                // The channel supplying fake packets is broken. The user lost/destroyed their
                // inject_handle. This means there will never be any more packets sent to this
                // dummy network. To simulate an idle network we block and sleep forever here.
                loop {
                    thread::sleep(time::Duration::new(::std::u64::MAX, 0));
                }
            }
        }
    }
}

/// Get three fake interfaces generated with `dummy_interface`
pub fn interfaces() -> Vec<NetworkInterface> {
    (0..3).map(|i| dummy_interface(i)).collect()
}

/// Generates a fake `NetworkInterface`.
/// The name of the interface will be `ethX` where X is the integer `i`.
/// The index will be `i`.
/// The MAC will be `01:02:03:04:05:i`.
pub fn dummy_interface(i: u8) -> NetworkInterface {
    NetworkInterface {
        name: format!("eth{}", i),
        index: i as u32,
        mac: Some(MacAddr::new(1, 2, 3, 4, 5, i)),
        ips: None,
        flags: 0,
    }
}
<commit_msg>Implement send_to in dummy<commit_after>// Copyright (c) 2016 Linus Färnstrand <faern@faern.net>
//
// 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.

//! Support for sending and receiving data link layer packets on a fake network managed
//! by in memory FIFO queues. Useful for writing tests.

use std::io;
use std::sync::mpsc::{self, Receiver, Sender};
use std::thread;
use std::time;

use datalink::{self, EthernetDataLinkChannelIterator, EthernetDataLinkReceiver,
               EthernetDataLinkSender, NetworkInterface};
use packet::ethernet::{EthernetPacket, MutableEthernetPacket};
use packet::Packet;
use util::MacAddr;

/// Configuration for the dummy datalink backend
#[derive(Debug)]
pub struct Config {
    /// The fake network will pull packets (or errors) form this `Receiver`
    pub in_packets_rx: Receiver<io::Result<Box<[u8]>>>,

    in_packets_tx: Option<Sender<io::Result<Box<[u8]>>>>,

    /// All packets sent to this fake network will end up on this `Sender`
    pub out_packets_tx: Sender<Vec<u8>>,

    out_packets_rx: Option<Receiver<Vec<u8>>>,
}

impl Config {
    /// Get the `Sender` handle that can inject packets in the fake network
    pub fn inject_handle(&mut self) -> Option<Sender<io::Result<Box<[u8]>>>> {
        self.in_packets_tx.take()
    }

    /// Get the `Receiver` handle where packets sent to the fake network can be read
    pub fn read_handle(&mut self) -> Option<Receiver<Vec<u8>>> {
        self.out_packets_rx.take()
    }
}

impl<'a> From<&'a datalink::Config> for Config {
    /// This conversion will not allow injecting and reading packets from the dummy network.
    /// To do that please create your own `dummy::Config`
    fn from(_config: &datalink::Config) -> Config {
        Config::default()
    }
}

impl Default for Config {
    /// This conversion will not allow injecting and reading packets from the dummy network.
    /// To do that please create your own `dummy::Config`
    fn default() -> Config {
        let (in_tx, in_rx) = mpsc::channel();
        let (out_tx, out_rx) = mpsc::channel();
        Config {
            in_packets_rx: in_rx,
            in_packets_tx: Some(in_tx),
            out_packets_tx: out_tx,
            out_packets_rx: Some(out_rx),
        }
    }
}

/// Create a data link channel backed by FIFO queues. Useful for debugging and testing.
pub fn channel(_: &NetworkInterface, config: Config) -> io::Result<datalink::Channel> {
    let sender = Box::new(MockEthernetDataLinkSender { out_packets: config.out_packets_tx });
    let receiver =
        Box::new(MockEthernetDataLinkReceiver { in_packets: Some(config.in_packets_rx) });

    Ok(datalink::Channel::Ethernet(sender, receiver))
}

struct MockEthernetDataLinkSender {
    out_packets: Sender<Vec<u8>>,
}

impl EthernetDataLinkSender for MockEthernetDataLinkSender {
    fn build_and_send(&mut self,
                      _num_packets: usize,
                      packet_size: usize,
                      func: &mut FnMut(MutableEthernetPacket))
        -> Option<io::Result<()>> {
        let mut buffer = vec![0; packet_size];
        {
            let pkg = MutableEthernetPacket::new(&mut buffer[..]).unwrap();
            func(pkg);
        }
        // Send the data to the queue. Don't care if it's closed
        self.out_packets.send(buffer).unwrap_or(());
        Some(Ok(()))
    }

    fn send_to(&mut self,
               packet: &EthernetPacket,
               _dst: Option<NetworkInterface>)
        -> Option<io::Result<()>> {
        let buffer = packet.packet().to_vec();
        self.out_packets.send(buffer).unwrap_or(());
        Some(Ok(()))
    }
}

struct MockEthernetDataLinkReceiver {
    in_packets: Option<Receiver<io::Result<Box<[u8]>>>>,
}

impl EthernetDataLinkReceiver for MockEthernetDataLinkReceiver {
    fn iter<'a>(&'a mut self) -> Box<EthernetDataLinkChannelIterator + 'a> {
        Box::new(MockEthernetDataLinkChannelIterator {
            in_packets: self.in_packets.take().expect("Only one receiver allowed"),
            used_packets: vec![],
        })
    }
}

struct MockEthernetDataLinkChannelIterator {
    in_packets: Receiver<io::Result<Box<[u8]>>>,
    used_packets: Vec<Box<[u8]>>,
}

impl<'a> EthernetDataLinkChannelIterator<'a> for MockEthernetDataLinkChannelIterator {
    fn next(&mut self) -> io::Result<EthernetPacket> {
        match self.in_packets.recv() {
            Ok(result) => {
                // A network event happened. Might be a packet or a simulated error
                match result {
                    Ok(buffer) => {
                        self.used_packets.push(buffer);
                        let buffer_ref = &*self.used_packets[self.used_packets.len() - 1];
                        let packet = EthernetPacket::new(buffer_ref).unwrap();
                        Ok(packet)
                    }
                    Err(e) => Err(e),
                }
            }
            Err(_) => {
                // The channel supplying fake packets is broken. The user lost/destroyed their
                // inject_handle. This means there will never be any more packets sent to this
                // dummy network. To simulate an idle network we block and sleep forever here.
                loop {
                    thread::sleep(time::Duration::new(::std::u64::MAX, 0));
                }
            }
        }
    }
}

/// Get three fake interfaces generated with `dummy_interface`
pub fn interfaces() -> Vec<NetworkInterface> {
    (0..3).map(|i| dummy_interface(i)).collect()
}

/// Generates a fake `NetworkInterface`.
/// The name of the interface will be `ethX` where X is the integer `i`.
/// The index will be `i`.
/// The MAC will be `01:02:03:04:05:i`.
pub fn dummy_interface(i: u8) -> NetworkInterface {
    NetworkInterface {
        name: format!("eth{}", i),
        index: i as u32,
        mac: Some(MacAddr::new(1, 2, 3, 4, 5, i)),
        ips: None,
        flags: 0,
    }
}
<|endoftext|>


<commit_before>extern crate scrabble_score;

use scrabble_score::*;

#[test]
fn a_is_worth_one_point() {
    assert_eq!(score("a"), 1);
}

#[test]
#[ignore]
fn scoring_is_case_insensitive() {
    assert_eq!(score("A"), 1);
}

#[test]
#[ignore]
fn f_is_worth_four() {
    assert_eq!(score("f"), 4);
}

#[test]
#[ignore]
fn two_one_point_letters_make_a_two_point_word() {
    assert_eq!(score("at"), 2);
}

#[test]
#[ignore]
fn three_letter_word() {
    assert_eq!(score("zoo"), 12);
}

#[test]
#[ignore]
fn medium_word() {
    assert_eq!(score("street"), 6);
}

#[test]
#[ignore]
fn longer_words_with_valuable_letters() {
    assert_eq!(score("quirky"), 22);
}

#[test]
#[ignore]
fn long_mixed_case_word() {
    assert_eq!(score("OxyphenButazone"), 41);
}

#[test]
#[ignore]
fn non_english_scrabble_letters_do_not_score() {
    assert_eq!(score("pinata"), 8);
    assert_eq!(score("piñata"), 7);
}

#[test]
#[ignore]
fn empty_words_are_worth_zero() {
    assert_eq!(score(""), 0);
}
<commit_msg>scrabble-score: add a test for the entire alphabet (#250)<commit_after>extern crate scrabble_score;

use scrabble_score::*;

#[test]
fn a_is_worth_one_point() {
    assert_eq!(score("a"), 1);
}

#[test]
#[ignore]
fn scoring_is_case_insensitive() {
    assert_eq!(score("A"), 1);
}

#[test]
#[ignore]
fn f_is_worth_four() {
    assert_eq!(score("f"), 4);
}

#[test]
#[ignore]
fn two_one_point_letters_make_a_two_point_word() {
    assert_eq!(score("at"), 2);
}

#[test]
#[ignore]
fn three_letter_word() {
    assert_eq!(score("zoo"), 12);
}

#[test]
#[ignore]
fn medium_word() {
    assert_eq!(score("street"), 6);
}

#[test]
#[ignore]
fn longer_words_with_valuable_letters() {
    assert_eq!(score("quirky"), 22);
}

#[test]
#[ignore]
fn long_mixed_case_word() {
    assert_eq!(score("OxyphenButazone"), 41);
}

#[test]
#[ignore]
fn non_english_scrabble_letters_do_not_score() {
    assert_eq!(score("pinata"), 8);
    assert_eq!(score("piñata"), 7);
}

#[test]
#[ignore]
fn empty_words_are_worth_zero() {
    assert_eq!(score(""), 0);
}

#[test]
#[ignore]
fn all_letters_work() {
    assert_eq!(score("abcdefghijklmnopqrstuvwxyz"), 87);
}
<|endoftext|>


<commit_before>/// `Builder!` macro
///
/// Only useful in combination with [custom_derive][custom_derive].
///
/// [custom_derive]: https://crates.io/crates/custom_derive
#[macro_export]
#[doc(hidden)]
macro_rules! Builder {
    // Strip empty argument list if given (Passed by custom_derive macro)
    (() $($body:tt)*) => {
        Builder! { $($body)* }
    };

    // Strip meta items, pub (if present) and struct from definition
    (
        $(#[$ignore:meta])*
        $(pub)* struct $($body:tt)*
    ) => {
        Builder! { $($body)* }
    };

    // Struct with + without generics.
    //
    // Receive parsed fields of normal struct from `__parse_struct_body`
    // and add implementation.
    //
    // These patterns must appear above those which start with an ident to
    // compile.
    (
        (
            struct_name = $struct_name:ident,
            generics = ($($generics:ident),*),
        ),
        fields = [$({
            field_name: $field_name:ident,
            field_ty: $field_ty:ty,
            field_attr: [$($attr:tt)*],
        })*],
    ) => {
        #[allow(dead_code)]
        impl<$($generics),*> $struct_name<$($generics),*> {
            $(
                $($attr)*
                pub fn $field_name<VALUE: Into<$field_ty>>(mut self, value: VALUE) -> Self {
                    self.$field_name = value.into();
                    self
                }
            )*
        }
    };

    // Handle struct with generics
    (
        $struct_name:ident <$($generics:ident),*>
        $body:tt $(;)*
    ) => {
        __parse_struct_body! {
            (
                struct_name = $struct_name,
                generics = ($($generics),*),
            ),
            callback = Builder,
            body = $body,
        }
    };

    // Handle struct with no generics
    (
        $struct_name:ident
        $body:tt $(;)*
    ) => {
        __parse_struct_body! {
            (
                struct_name = $struct_name,
                generics = (),
            ),
            callback = Builder,
            body = $body,
        }
    };
}
<commit_msg>fix compatibility with rust 1.10 + 1.11<commit_after>/// `Builder!` macro
///
/// Only useful in combination with [custom_derive][custom_derive].
///
/// [custom_derive]: https://crates.io/crates/custom_derive
#[macro_export]
#[doc(hidden)]
macro_rules! Builder {
    // Strip empty argument list if given (Passed by custom_derive macro)
    (() $($body:tt)*) => {
        Builder! { $($body)* }
    };

    // Strip meta items, pub (if present) and struct from definition
    (
        $(#[$ignore:meta])*
        $(pub)* struct $($body:tt)*
    ) => {
        Builder! { $($body)* }
    };

    // Struct with + without generics.
    //
    // Receive parsed fields of normal struct from `__parse_struct_body`
    // and add implementation.
    //
    // These patterns must appear above those which start with an ident to
    // compile.
    (
        (
            struct_name = $struct_name:ident,
            generics = ($($generics:ident),*),
        ),
        fields = [$({
            field_name: $field_name:ident,
            field_ty: $field_ty:ty,
            field_attr: [$(#[$meta:meta])*],
        })*],
    ) => {
        #[allow(dead_code)]
        impl<$($generics),*> $struct_name<$($generics),*> {
            $(
                $(#[$meta])*
                pub fn $field_name<VALUE: Into<$field_ty>>(mut self, value: VALUE) -> Self {
                    self.$field_name = value.into();
                    self
                }
            )*
        }
    };

    // Handle struct with generics
    (
        $struct_name:ident <$($generics:ident),*>
        $body:tt $(;)*
    ) => {
        __parse_struct_body! {
            (
                struct_name = $struct_name,
                generics = ($($generics),*),
            ),
            callback = Builder,
            body = $body,
        }
    };

    // Handle struct with no generics
    (
        $struct_name:ident
        $body:tt $(;)*
    ) => {
        __parse_struct_body! {
            (
                struct_name = $struct_name,
                generics = (),
            ),
            callback = Builder,
            body = $body,
        }
    };
}
<|endoftext|>


<commit_before>use geom::point::Point;
use renderer::Renderer;
use frame::Frame;
use draw::RGB;

use super::Scene;

pub struct DevelRenderer {
   scene: Scene,
   aliased: Vec<RGB>,
//   rendered: Vec<RGB>,
}

pub const SUBDIVISIONS: usize = 3;

impl DevelRenderer {
   #[inline]
   pub fn new(scene: Scene) -> Self {
      DevelRenderer {
         scene: scene,

         aliased: vec!(),
//         rendered: vec!(),
      }
   }

   fn check_resize(&mut self, width: u32, height: u32) {
      if self.aliased.len() == (width * height) as usize * SUBDIVISIONS * SUBDIVISIONS {
         return;
      }

      self.aliased.resize((width * height) as usize * SUBDIVISIONS * SUBDIVISIONS, RGB::new(0, 0, 0));
//      self.rendered.resize((width * height) as usize, RGB::new(0, 0, 0));
   }

   #[inline]
   fn clear(&mut self) {
      let mut aliased: &mut Vec<RGB> = self.aliased.as_mut();

      for i in 0..aliased.len() {
         aliased[i] = RGB::default();
      }
   }

   #[inline]
   fn render_aliased(&mut self, frame: &mut Frame) {
      let mut aliased: &mut Vec<RGB> = self.aliased.as_mut();

      for poly in &self.scene.polys {
         let points = &poly.points;

         let (left, right) = get_left_right_edges(points);

         let mut left_i = 0;
         let mut right_i = 0;

         let mut left_edge = left[left_i];
         let mut right_edge = right[right_i];

         let mut left_x = left_edge.p1.x;
         let mut right_x = right_edge.p1.x;

         let left_last_i = left.len() - 1;
         let right_last_i = right.len() - 1;

         let mut left_advancer = YAxisAdvancer::new(&left_edge);
         let mut right_advancer = YAxisAdvancer::new(&right_edge);

         let min_y = left_edge.p1.y;
         let max_y = left[left_last_i].p2.y;

         for y in min_y..max_y + 1 {
            if left_edge.p2.y == y && left_i != left_last_i {
               left_i += 1;
               left_edge = left[left_i];
               left_advancer = YAxisAdvancer::new(&left_edge);
            }

            if right_edge.p2.y == y && right_i != right_last_i  {
               right_i += 1;
               right_edge = right[right_i];
               right_advancer = YAxisAdvancer::new(&right_edge);
            }

            for x in left_x..right_x {
               aliased[y as usize * frame.width as usize * SUBDIVISIONS + x as usize] = poly.color;
            }

            left_x = left_advancer.advance();
            right_x = right_advancer.advance();
         }
      }
   }

   #[inline]
   fn downsample(&mut self, frame: &mut Frame) {
      let aliased: &mut Vec<RGB> = self.aliased.as_mut();

//      let rendered: &mut Vec<RGB> = self.rendered.as_mut();

      let (width, height) = (frame.width as usize, frame.height as usize);

      for y in 0..height {
         for x in 0..width {
            let color = calc_pixel_color(aliased, width, x, y);

            frame.put_pixel(x as i32, y as i32, &color);

//            rendered[y * width + x] = color;
         }
      }
   }
}

impl Renderer for DevelRenderer {
   #[inline]
   fn init(&mut self, width: u32, height: u32) {
      self.check_resize(width, height);
   }

   #[inline]
   fn render(&mut self, frame: &mut Frame) {
      self.check_resize(frame.width, frame.height);

      self.clear();

      self.render_aliased(frame);

      self.downsample(frame);
   }
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct Edge {
   p1: Point,
   p2: Point,
}

impl Edge {
   #[inline]
   fn new(p1: Point, p2: Point) -> Self {
      Edge {
         p1: p1,
         p2: p2,
      }
   }
}

struct YAxisAdvancer {
   delta: f64,
   f64x: f64,
}

impl YAxisAdvancer {
   #[inline]
   fn new(edge: &Edge) -> Self {
      let dx = edge.p2.x - edge.p1.x;
      let dy = edge.p2.y - edge.p1.y;

      let delta = dx as f64 / dy as f64;
      let f64x = edge.p1.x as f64;

      YAxisAdvancer {
         delta: delta,
         f64x: f64x,
      }
   }

   #[inline]
   fn advance(&mut self) -> i64 {
      self.f64x += self.delta;
      self.f64x.round() as i64
   }
}

#[inline]
fn get_left_right_edges(points: &Vec<Point>) -> (Vec<Edge>, Vec<Edge>){
   let (min_i, max_i) = find_min_max_y_index(points);

   let left = get_left_edges(points, min_i, max_i);
   let right = get_right_edges(points, min_i, max_i);

   (left, right)
}

#[inline]
fn get_left_edges(points: &Vec<Point>, min_i: usize, max_i: usize) -> Vec<Edge> {
   let mut edges = Vec::new();

   let mut curr_i = min_i;
   let mut prev_i = curr_i;

   loop {
      curr_i += 1;

      if curr_i == points.len() {
         curr_i = 0;
      }

      edges.push(Edge::new(points[prev_i], points[curr_i]));

      prev_i = curr_i;

      if curr_i == max_i {
         break;
      }
   }

   edges
}

#[inline]
fn get_right_edges(points: &Vec<Point>, min_i: usize, max_i: usize) -> Vec<Edge> {
   let mut edges = Vec::new();

   let mut curr_i = min_i;
   let mut prev_i = curr_i;

   loop {
      if curr_i == 0 {
         curr_i = points.len() - 1;
      } else {
         curr_i -= 1;
      }

      edges.push(Edge::new(points[prev_i], points[curr_i]));

      prev_i = curr_i;

      if curr_i == max_i {
         break;
      }
   }

   edges
}

#[inline]
fn find_min_max_y_index(points: &Vec<Point>) -> (usize, usize) {
   let (first, rest) = points.split_first().unwrap();

   let mut min_y = first.y;
   let mut max_y = min_y;
   let mut min_i = 0;
   let mut max_i = 0;

   for (i, point) in rest.iter().enumerate() {
      if point.y < min_y {
         min_i = i + 1;
         min_y = point.y;
      } else if point.y > max_y {
         max_i = i + 1;
         max_y = point.y;
      }
   }

   (min_i, max_i)
}

#[inline]
fn calc_pixel_color(aliased: &mut Vec<RGB>, width: usize, x: usize, y: usize) -> RGB {
   let mut r: u16 = 0;
   let mut g: u16 = 0;
   let mut b: u16 = 0;
   for box_y in 0..SUBDIVISIONS {
      for box_x in 0..SUBDIVISIONS {
         let pos = (box_y + y * SUBDIVISIONS) * width * SUBDIVISIONS + box_x + x * SUBDIVISIONS;
         let color = &aliased[pos];
         r += color.r as u16;
         g += color.g as u16;
         b += color.b as u16;
      }
   }

   let divisor = (SUBDIVISIONS * SUBDIVISIONS) as u16;

   r /= divisor;
   g /= divisor;
   b /= divisor;

   RGB::new(r as u8, g as u8, b as u8)
}
<commit_msg>Cleanup commented out vector<commit_after>use geom::point::Point;
use renderer::Renderer;
use frame::Frame;
use draw::RGB;

use super::Scene;

pub struct DevelRenderer {
   scene: Scene,
   aliased: Vec<RGB>,
}

pub const SUBDIVISIONS: usize = 3;

impl DevelRenderer {
   #[inline]
   pub fn new(scene: Scene) -> Self {
      DevelRenderer {
         scene: scene,

         aliased: vec!(),
      }
   }

   fn check_resize(&mut self, width: u32, height: u32) {
      if self.aliased.len() == (width * height) as usize * SUBDIVISIONS * SUBDIVISIONS {
         return;
      }

      self.aliased.resize((width * height) as usize * SUBDIVISIONS * SUBDIVISIONS, RGB::new(0, 0, 0));
   }

   #[inline]
   fn clear(&mut self) {
      let mut aliased: &mut Vec<RGB> = self.aliased.as_mut();

      for i in 0..aliased.len() {
         aliased[i] = RGB::default();
      }
   }

   #[inline]
   fn render_aliased(&mut self, frame: &mut Frame) {
      let mut aliased: &mut Vec<RGB> = self.aliased.as_mut();

      for poly in &self.scene.polys {
         let points = &poly.points;

         let (left, right) = get_left_right_edges(points);

         let mut left_i = 0;
         let mut right_i = 0;

         let mut left_edge = left[left_i];
         let mut right_edge = right[right_i];

         let mut left_x = left_edge.p1.x;
         let mut right_x = right_edge.p1.x;

         let left_last_i = left.len() - 1;
         let right_last_i = right.len() - 1;

         let mut left_advancer = YAxisAdvancer::new(&left_edge);
         let mut right_advancer = YAxisAdvancer::new(&right_edge);

         let min_y = left_edge.p1.y;
         let max_y = left[left_last_i].p2.y;

         for y in min_y..max_y + 1 {
            if left_edge.p2.y == y && left_i != left_last_i {
               left_i += 1;
               left_edge = left[left_i];
               left_advancer = YAxisAdvancer::new(&left_edge);
            }

            if right_edge.p2.y == y && right_i != right_last_i  {
               right_i += 1;
               right_edge = right[right_i];
               right_advancer = YAxisAdvancer::new(&right_edge);
            }

            for x in left_x..right_x {
               aliased[y as usize * frame.width as usize * SUBDIVISIONS + x as usize] = poly.color;
            }

            left_x = left_advancer.advance();
            right_x = right_advancer.advance();
         }
      }
   }

   #[inline]
   fn downsample(&mut self, frame: &mut Frame) {
      let aliased: &mut Vec<RGB> = self.aliased.as_mut();

      let (width, height) = (frame.width as usize, frame.height as usize);

      for y in 0..height {
         for x in 0..width {
            let color = calc_pixel_color(aliased, width, x, y);

            frame.put_pixel(x as i32, y as i32, &color);
         }
      }
   }
}

impl Renderer for DevelRenderer {
   #[inline]
   fn init(&mut self, width: u32, height: u32) {
      self.check_resize(width, height);
   }

   #[inline]
   fn render(&mut self, frame: &mut Frame) {
      self.check_resize(frame.width, frame.height);

      self.clear();

      self.render_aliased(frame);

      self.downsample(frame);
   }
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct Edge {
   p1: Point,
   p2: Point,
}

impl Edge {
   #[inline]
   fn new(p1: Point, p2: Point) -> Self {
      Edge {
         p1: p1,
         p2: p2,
      }
   }
}

struct YAxisAdvancer {
   delta: f64,
   f64x: f64,
}

impl YAxisAdvancer {
   #[inline]
   fn new(edge: &Edge) -> Self {
      let dx = edge.p2.x - edge.p1.x;
      let dy = edge.p2.y - edge.p1.y;

      let delta = dx as f64 / dy as f64;
      let f64x = edge.p1.x as f64;

      YAxisAdvancer {
         delta: delta,
         f64x: f64x,
      }
   }

   #[inline]
   fn advance(&mut self) -> i64 {
      self.f64x += self.delta;
      self.f64x.round() as i64
   }
}

#[inline]
fn get_left_right_edges(points: &Vec<Point>) -> (Vec<Edge>, Vec<Edge>){
   let (min_i, max_i) = find_min_max_y_index(points);

   let left = get_left_edges(points, min_i, max_i);
   let right = get_right_edges(points, min_i, max_i);

   (left, right)
}

#[inline]
fn get_left_edges(points: &Vec<Point>, min_i: usize, max_i: usize) -> Vec<Edge> {
   let mut edges = Vec::new();

   let mut curr_i = min_i;
   let mut prev_i = curr_i;

   loop {
      curr_i += 1;

      if curr_i == points.len() {
         curr_i = 0;
      }

      edges.push(Edge::new(points[prev_i], points[curr_i]));

      prev_i = curr_i;

      if curr_i == max_i {
         break;
      }
   }

   edges
}

#[inline]
fn get_right_edges(points: &Vec<Point>, min_i: usize, max_i: usize) -> Vec<Edge> {
   let mut edges = Vec::new();

   let mut curr_i = min_i;
   let mut prev_i = curr_i;

   loop {
      if curr_i == 0 {
         curr_i = points.len() - 1;
      } else {
         curr_i -= 1;
      }

      edges.push(Edge::new(points[prev_i], points[curr_i]));

      prev_i = curr_i;

      if curr_i == max_i {
         break;
      }
   }

   edges
}

#[inline]
fn find_min_max_y_index(points: &Vec<Point>) -> (usize, usize) {
   let (first, rest) = points.split_first().unwrap();

   let mut min_y = first.y;
   let mut max_y = min_y;
   let mut min_i = 0;
   let mut max_i = 0;

   for (i, point) in rest.iter().enumerate() {
      if point.y < min_y {
         min_i = i + 1;
         min_y = point.y;
      } else if point.y > max_y {
         max_i = i + 1;
         max_y = point.y;
      }
   }

   (min_i, max_i)
}

#[inline]
fn calc_pixel_color(aliased: &mut Vec<RGB>, width: usize, x: usize, y: usize) -> RGB {
   let mut r: u16 = 0;
   let mut g: u16 = 0;
   let mut b: u16 = 0;
   for box_y in 0..SUBDIVISIONS {
      for box_x in 0..SUBDIVISIONS {
         let pos = (box_y + y * SUBDIVISIONS) * width * SUBDIVISIONS + box_x + x * SUBDIVISIONS;
         let color = &aliased[pos];
         r += color.r as u16;
         g += color.g as u16;
         b += color.b as u16;
      }
   }

   let divisor = (SUBDIVISIONS * SUBDIVISIONS) as u16;

   r /= divisor;
   g /= divisor;
   b /= divisor;

   RGB::new(r as u8, g as u8, b as u8)
}
<|endoftext|>


<commit_before>use std::rc::Rc;

use gtk::prelude::*;
use gtk::{Window, FileChooser, Button, Entry, ComboBoxText};

use cargo::util::config::Config;
use cargo::ops::{self, VersionControl, NewOptions};

use util::PreContext;
use pages::Page;

/// An interface for creating packages.
#[derive(Clone)]
pub struct NewPackagePage {
    pub window: Window,
    pub config: Rc<Config>,
    pub file: FileChooser,
    pub new: Button,
    pub name: Entry,
    pub ty: ComboBoxText,
    pub vcs: ComboBoxText,
}
impl Page for NewPackagePage {
    fn new(c: &PreContext) -> NewPackagePage {
        let b = &c.builder;
        NewPackagePage {
            window: c.window.clone(),
            config: c.config.clone(),
            file: b.get_object("package-file").unwrap(),
            name: b.get_object("package-name").unwrap(),
            vcs: b.get_object("package-vcs").unwrap(),
            ty: b.get_object("package-type").unwrap(),
            new: b.get_object("package-new").unwrap()
        }
    }
    fn bind_listeners(&self) {
        let name = self.name.clone();
        let ty = self.ty.clone();
        let vcs = self.vcs.clone();
        let window = self.window.clone();
        let config = self.config.clone();
        ::bind_file_button(&self.file, &self.new, move |file| {
            let text = name.get_text();
            let opts = NewOptions {
                path: file.to_str().unwrap(),
                name: text.as_ref().map(String::as_str),
                bin: ty.get_active_id().as_ref().map(String::as_str) == Some("bin"),
                version_control: vcs.get_active_id().as_ref().map(String::as_str).map(|v| match v {
                    "git" => VersionControl::Git,
                    "mercurial" => VersionControl::Hg,
                    _ => VersionControl::NoVcs
                })
            };
            if ops::init(opts, &config).is_ok() {
                ::info(Some(&window), "Created crate successfully");
            } else {
                ::error(Some(&window), "Failed to create crate");
            }
        });
    }
}
<commit_msg>Use `ops::new` instead of `ops::init`<commit_after>use std::rc::Rc;

use gtk::prelude::*;
use gtk::{Window, FileChooser, Button, Entry, ComboBoxText};

use cargo::util::config::Config;
use cargo::ops::{self, VersionControl, NewOptions};

use util::PreContext;
use pages::Page;

/// An interface for creating packages.
#[derive(Clone)]
pub struct NewPackagePage {
    pub window: Window,
    pub config: Rc<Config>,
    pub file: FileChooser,
    pub new: Button,
    pub name: Entry,
    pub ty: ComboBoxText,
    pub vcs: ComboBoxText,
}
impl Page for NewPackagePage {
    fn new(c: &PreContext) -> NewPackagePage {
        let b = &c.builder;
        NewPackagePage {
            window: c.window.clone(),
            config: c.config.clone(),
            file: b.get_object("package-file").unwrap(),
            name: b.get_object("package-name").unwrap(),
            vcs: b.get_object("package-vcs").unwrap(),
            ty: b.get_object("package-type").unwrap(),
            new: b.get_object("package-new").unwrap()
        }
    }
    fn bind_listeners(&self) {
        let name = self.name.clone();
        let ty = self.ty.clone();
        let vcs = self.vcs.clone();
        let window = self.window.clone();
        let config = self.config.clone();
        ::bind_file_button(&self.file, &self.new, move |file| {
            let text = name.get_text();
            let opts = NewOptions {
                path: file.to_str().unwrap(),
                name: text.as_ref().map(String::as_str),
                bin: ty.get_active_id().as_ref().map(String::as_str) == Some("bin"),
                version_control: vcs.get_active_id().as_ref().map(String::as_str).map(|v| match v {
                    "git" => VersionControl::Git,
                    "mercurial" => VersionControl::Hg,
                    _ => VersionControl::NoVcs
                })
            };
            if ops::new(opts, &config).is_ok() {
                ::info(Some(&window), "Created crate successfully");
            } else {
                ::error(Some(&window), "Failed to create crate");
            }
        });
    }
}
<|endoftext|>


<commit_before>use std::ops::{Index, IndexMut};
use std::usize;

struct MemoMatrix<T> {
    rows: usize,
    cols: usize,
    v: Vec<Option<T>>,
}

impl<T> MemoMatrix<T> {
    fn new(rows: usize, cols: usize) -> Self {
        let mut v = Vec::with_capacity(rows*cols);
        for _ in 0..(rows*cols) {
            v.push(None);
        }
        MemoMatrix { rows: rows, cols: cols, v: v }
    }
}

impl<T> Index<(usize, usize)> for MemoMatrix<T> {
    type Output = Option<T>;
    fn index<'a>(&'a self, index: &(usize, usize)) -> &'a Option<T> {
        let (r, c) = *index;
        assert!(r < self.rows, "row index '{}' is out of bounds", r);
        assert!(c < self.cols, "column index '{}' is out of bounds", c);
        &self.v[r * self.cols + c]
    }
}

impl<T> IndexMut<(usize, usize)> for MemoMatrix<T> {
    fn index_mut<'a>(&'a mut self, index: &(usize, usize)) -> &'a mut Option<T> {
        let (r, c) = *index;
        assert!(r < self.rows, "row index '{}' is out of bounds", r);
        assert!(c < self.cols, "column index '{}' is out of bounds", c);
        &mut self.v[r * self.cols + c]
    }
}

pub fn fuzzy_contains<'a, 'b>(p: &'a str, t: &'b str) -> bool {
    fuzzy_contains_err(p, t, 1)
}

fn fuzzy_contains_err<'a, 'b>(p: &'a str, t: &'b str, k: usize) -> bool {
    lev_substring(p, t) <= k
}

// returns the minimum edit distance between `p` and all substrings of `t`
fn lev_substring<'a, 'b>(p: &'a str, t: &'b str) -> usize {
    let p_chars: Vec<char> = p.chars().collect();
    let t_chars: Vec<char> = t.chars().collect();

    // M(i, j) is the minimal cost of an edit sequence that turns p[..i] into t[..j]
    let n = t.chars().count();
    let mut rect = MemoMatrix::new(p.chars().count() + 1, n + 1);

    let mut min = usize::MAX;
    for k in 0..(n+1) {
        let dist = ed(&mut rect, &p_chars[], &t_chars[..k]);
        if dist < min {
            min = dist;
        }
    }

    min
}

fn ed<'a, 'b>(rect: &mut MemoMatrix<usize>, p: &'a [char], t: &'b [char]) -> usize {
    let (i, j) = (p.len(), t.len());

    // check if this has already been computed and use it if so
    match rect[(i, j)] {
        Some(dist) => return dist,
        None => {},
    }

    let dist = if i == 0 {
        0
    } else if j == 0 {
        i
    } else {
        let (a, b) = (i-1, j-1);
        if p[a] == t[b] {
            ed(rect, &p[..a], &t[..b])
        } else {
            let v = vec![
                ed(rect, &p[..a], &t[..b]),
                ed(rect, &p[..a], t),
                ed(rect, p, &t[..b])
            ];
            v.into_iter().min().unwrap() + 1
        }
    };

    rect[(i, j)] = Some(dist);
    dist
}
<commit_msg>Change names of some functions in fuzzy for aesthetic reasons<commit_after>use std::ops::{Index, IndexMut};
use std::usize;

struct MemoMatrix<T> {
    rows: usize,
    cols: usize,
    v: Vec<Option<T>>,
}

impl<T> MemoMatrix<T> {
    fn new(rows: usize, cols: usize) -> Self {
        let mut v = Vec::with_capacity(rows*cols);
        for _ in 0..(rows*cols) {
            v.push(None);
        }
        MemoMatrix { rows: rows, cols: cols, v: v }
    }
}

impl<T> Index<(usize, usize)> for MemoMatrix<T> {
    type Output = Option<T>;
    fn index<'a>(&'a self, index: &(usize, usize)) -> &'a Option<T> {
        let (r, c) = *index;
        assert!(r < self.rows, "row index '{}' is out of bounds", r);
        assert!(c < self.cols, "column index '{}' is out of bounds", c);
        &self.v[r * self.cols + c]
    }
}

impl<T> IndexMut<(usize, usize)> for MemoMatrix<T> {
    fn index_mut<'a>(&'a mut self, index: &(usize, usize)) -> &'a mut Option<T> {
        let (r, c) = *index;
        assert!(r < self.rows, "row index '{}' is out of bounds", r);
        assert!(c < self.cols, "column index '{}' is out of bounds", c);
        &mut self.v[r * self.cols + c]
    }
}

pub fn fuzzy_contains<'a, 'b>(p: &'a str, t: &'b str) -> bool {
    fuzzy_contains_err(p, t, 1)
}

fn fuzzy_contains_err<'a, 'b>(p: &'a str, t: &'b str, k: usize) -> bool {
    fuzzy_sub_dist(p, t) <= k
}

// returns the minimum edit distance between `p` and all substrings of `t`
fn fuzzy_sub_dist<'a, 'b>(p: &'a str, t: &'b str) -> usize {
    let p_chars: Vec<char> = p.chars().collect();
    let t_chars: Vec<char> = t.chars().collect();

    // M(i, j) is the minimal cost of an edit sequence that turns p[..i] into t[..j]
    let n = t.chars().count();
    let mut rect = MemoMatrix::new(p.chars().count() + 1, n + 1);

    let mut min = usize::MAX;
    for k in 0..(n+1) {
        let dist = ed_sub(&mut rect, &p_chars[..], &t_chars[..k]);
        if dist < min {
            min = dist;
        }
    }

    min
}

fn ed_sub<'a, 'b>(rect: &mut MemoMatrix<usize>, p: &'a [char], t: &'b [char]) -> usize {
    let (i, j) = (p.len(), t.len());

    // check if this has already been computed and use it if so
    match rect[(i, j)] {
        Some(dist) => return dist,
        None => {},
    }

    let dist = if i == 0 {
        0
    } else if j == 0 {
        i
    } else {
        let (a, b) = (i-1, j-1);
        if p[a] == t[b] {
            ed_sub(rect, &p[..a], &t[..b])
        } else {
            let v = vec![
                ed_sub(rect, &p[..a], &t[..b]),
                ed_sub(rect, &p[..a], t),
                ed_sub(rect, p, &t[..b])
            ];
            v.into_iter().min().unwrap() + 1
        }
    };

    rect[(i, j)] = Some(dist);
    dist
}
<|endoftext|>


<commit_before>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!

Bindings to libuv, along with the default implementation of `core::rt::rtio`.

UV types consist of the event loop (Loop), Watchers, Requests and
Callbacks.

Watchers and Requests encapsulate pointers to uv *handles*, which have
subtyping relationships with each other.  This subtyping is reflected
in the bindings with explicit or implicit coercions. For example, an
upcast from TcpWatcher to StreamWatcher is done with
`tcp_watcher.as_stream()`. In other cases a callback on a specific
type of watcher will be passed a watcher of a supertype.

Currently all use of Request types (connect/write requests) are
encapsulated in the bindings and don't need to be dealt with by the
caller.

# Safety note

Due to the complex lifecycle of uv handles, as well as compiler bugs,
this module is not memory safe and requires explicit memory management,
via `close` and `delete` methods.

*/

use container::Container;
use option::*;
use str::raw::from_c_str;
use to_str::ToStr;
use ptr::Ptr;
use libc;
use vec;
use ptr;
use cast;
use str;
use option::*;
use str::raw::from_c_str;
use to_str::ToStr;
use libc::{c_void, c_int, size_t, malloc, free};
use cast::transmute;
use ptr::null;
use unstable::finally::Finally;

use rt::io::IoError;

#[cfg(test)] use unstable::run_in_bare_thread;

pub use self::file::FsRequest;
pub use self::net::{StreamWatcher, TcpWatcher};
pub use self::idle::IdleWatcher;

/// The implementation of `rtio` for libuv
pub mod uvio;

/// C bindings to libuv
pub mod uvll;

pub mod file;
pub mod net;
pub mod idle;

/// XXX: Loop(*handle) is buggy with destructors. Normal structs
/// with dtors may not be destructured, but tuple structs can,
/// but the results are not correct.
pub struct Loop {
    handle: *uvll::uv_loop_t
}

/// The trait implemented by uv 'watchers' (handles). Watchers are
/// non-owning wrappers around the uv handles and are not completely
/// safe - there may be multiple instances for a single underlying
/// handle.  Watchers are generally created, then `start`ed, `stop`ed
/// and `close`ed, but due to their complex life cycle may not be
/// entirely memory safe if used in unanticipated patterns.
pub trait Watcher { }

pub trait Request { }

/// A type that wraps a native handle
pub trait NativeHandle<T> {
    pub fn from_native_handle(T) -> Self;
    pub fn native_handle(&self) -> T;
}

pub impl Loop {
    fn new() -> Loop {
        let handle = unsafe { uvll::loop_new() };
        assert!(handle.is_not_null());
        NativeHandle::from_native_handle(handle)
    }

    fn run(&mut self) {
        unsafe { uvll::run(self.native_handle()) };
    }

    fn close(&mut self) {
        unsafe { uvll::loop_delete(self.native_handle()) };
    }
}

impl NativeHandle<*uvll::uv_loop_t> for Loop {
    fn from_native_handle(handle: *uvll::uv_loop_t) -> Loop {
        Loop { handle: handle }
    }
    fn native_handle(&self) -> *uvll::uv_loop_t {
        self.handle
    }
}

// XXX: The uv alloc callback also has a *uv_handle_t arg
pub type AllocCallback = ~fn(uint) -> Buf;
pub type ReadCallback = ~fn(StreamWatcher, int, Buf, Option<UvError>);
pub type NullCallback = ~fn();
pub type IdleCallback = ~fn(IdleWatcher, Option<UvError>);
pub type ConnectionCallback = ~fn(StreamWatcher, Option<UvError>);
pub type FsCallback = ~fn(FsRequest, Option<UvError>);

/// Callbacks used by StreamWatchers, set as custom data on the foreign handle
struct WatcherData {
    read_cb: Option<ReadCallback>,
    write_cb: Option<ConnectionCallback>,
    connect_cb: Option<ConnectionCallback>,
    close_cb: Option<NullCallback>,
    alloc_cb: Option<AllocCallback>,
    idle_cb: Option<IdleCallback>
}

pub trait WatcherInterop {
    fn event_loop(&self) -> Loop;
    fn install_watcher_data(&mut self);
    fn get_watcher_data<'r>(&'r mut self) -> &'r mut WatcherData;
    fn drop_watcher_data(&mut self);
}

impl<H, W: Watcher + NativeHandle<*H>> WatcherInterop for W {
    /// Get the uv event loop from a Watcher
    pub fn event_loop(&self) -> Loop {
        unsafe {
            let handle = self.native_handle();
            let loop_ = uvll::get_loop_for_uv_handle(handle);
            NativeHandle::from_native_handle(loop_)
        }
    }

    pub fn install_watcher_data(&mut self) {
        unsafe {
            let data = ~WatcherData {
                read_cb: None,
                write_cb: None,
                connect_cb: None,
                close_cb: None,
                alloc_cb: None,
                idle_cb: None
            };
            let data = transmute::<~WatcherData, *c_void>(data);
            uvll::set_data_for_uv_handle(self.native_handle(), data);
        }
    }

    pub fn get_watcher_data<'r>(&'r mut self) -> &'r mut WatcherData {
        unsafe {
            let data = uvll::get_data_for_uv_handle(self.native_handle());
            let data = transmute::<&*c_void, &mut ~WatcherData>(&data);
            return &mut **data;
        }
    }

    pub fn drop_watcher_data(&mut self) {
        unsafe {
            let data = uvll::get_data_for_uv_handle(self.native_handle());
            let _data = transmute::<*c_void, ~WatcherData>(data);
            uvll::set_data_for_uv_handle(self.native_handle(), null::<()>());
        }
    }
}

// XXX: Need to define the error constants like EOF so they can be
// compared to the UvError type

pub struct UvError(uvll::uv_err_t);

pub impl UvError {

    fn name(&self) -> ~str {
        unsafe {
            let inner = match self { &UvError(ref a) => a };
            let name_str = uvll::err_name(inner);
            assert!(name_str.is_not_null());
            from_c_str(name_str)
        }
    }

    fn desc(&self) -> ~str {
        unsafe {
            let inner = match self { &UvError(ref a) => a };
            let desc_str = uvll::strerror(inner);
            assert!(desc_str.is_not_null());
            from_c_str(desc_str)
        }
    }

    fn is_eof(&self) -> bool {
        self.code == uvll::EOF
    }
}

impl ToStr for UvError {
    fn to_str(&self) -> ~str {
        fmt!("%s: %s", self.name(), self.desc())
    }
}

#[test]
fn error_smoke_test() {
    let err = uvll::uv_err_t { code: 1, sys_errno_: 1 };
    let err: UvError = UvError(err);
    assert!(err.to_str() == ~"EOF: end of file");
}

pub fn last_uv_error<H, W: Watcher + NativeHandle<*H>>(watcher: &W) -> UvError {
    unsafe {
        let loop_ = watcher.event_loop();
        UvError(uvll::last_error(loop_.native_handle()))
    }
}

pub fn uv_error_to_io_error(uverr: UvError) -> IoError {

    // XXX: Could go in str::raw
    unsafe fn c_str_to_static_slice(s: *libc::c_char) -> &'static str {
        let s = s as *u8;
        let mut curr = s, len = 0u;
        while *curr != 0u8 {
            len += 1u;
            curr = ptr::offset(s, len);
        }

        str::raw::buf_as_slice(s, len, |d| cast::transmute(d))
    }

    unsafe {
        // Importing error constants
        use rt::uv::uvll::*;
        use rt::io::*;

        // uv error descriptions are static
        let c_desc = uvll::strerror(&*uverr);
        let desc = c_str_to_static_slice(c_desc);

        let kind = match uverr.code {
            UNKNOWN => OtherIoError,
            OK => OtherIoError,
            EOF => EndOfFile,
            EACCES => PermissionDenied,
            ECONNREFUSED => ConnectionRefused,
            ECONNRESET => ConnectionReset,
            e => {
                abort!("unknown uv error code: %u", e as uint);
            }
        };

        IoError {
            kind: kind,
            desc: desc,
            detail: None
        }
    }
}

/// Given a uv handle, convert a callback status to a UvError
// XXX: Follow the pattern below by parameterizing over T: Watcher, not T
pub fn status_to_maybe_uv_error<T>(handle: *T, status: c_int) -> Option<UvError> {
    if status != -1 {
        None
    } else {
        unsafe {
            rtdebug!("handle: %x", handle as uint);
            let loop_ = uvll::get_loop_for_uv_handle(handle);
            rtdebug!("loop: %x", loop_ as uint);
            let err = uvll::last_error(loop_);
            Some(UvError(err))
        }
    }
}

/// The uv buffer type
pub type Buf = uvll::uv_buf_t;

/// Borrow a slice to a Buf
pub fn slice_to_uv_buf(v: &[u8]) -> Buf {
    let data = unsafe { vec::raw::to_ptr(v) };
    unsafe { uvll::buf_init(data, v.len()) }
}

// XXX: Do these conversions without copying

/// Transmute an owned vector to a Buf
pub fn vec_to_uv_buf(v: ~[u8]) -> Buf {
    unsafe {
        let data = malloc(v.len() as size_t) as *u8;
        assert!(data.is_not_null());
        do vec::as_imm_buf(v) |b, l| {
            let data = data as *mut u8;
            ptr::copy_memory(data, b, l)
        }
        uvll::buf_init(data, v.len())
    }
}

/// Transmute a Buf that was once a ~[u8] back to ~[u8]
pub fn vec_from_uv_buf(buf: Buf) -> Option<~[u8]> {
    if !(buf.len == 0 && buf.base.is_null()) {
        let v = unsafe { vec::from_buf(buf.base, buf.len as uint) };
        unsafe { free(buf.base as *c_void) };
        return Some(v);
    } else {
        // No buffer
        rtdebug!("No buffer!");
        return None;
    }
}

#[test]
fn test_slice_to_uv_buf() {
    let slice = [0, .. 20];
    let buf = slice_to_uv_buf(slice);

    assert!(buf.len == 20);

    unsafe {
        let base = transmute::<*u8, *mut u8>(buf.base);
        (*base) = 1;
        (*ptr::mut_offset(base, 1)) = 2;
    }

    assert!(slice[0] == 1);
    assert!(slice[1] == 2);
}

#[test]
fn loop_smoke_test() {
    do run_in_bare_thread {
        let mut loop_ = Loop::new();
        loop_.run();
        loop_.close();
    }
}

#[test]
#[ignore(reason = "valgrind - loop destroyed before watcher?")]
fn idle_new_then_close() {
    do run_in_bare_thread {
        let mut loop_ = Loop::new();
        let idle_watcher = { IdleWatcher::new(&mut loop_) };
        idle_watcher.close(||());
    }
}

#[test]
fn idle_smoke_test() {
    do run_in_bare_thread {
        let mut loop_ = Loop::new();
        let mut idle_watcher = { IdleWatcher::new(&mut loop_) };
        let mut count = 10;
        let count_ptr: *mut int = &mut count;
        do idle_watcher.start |idle_watcher, status| {
            let mut idle_watcher = idle_watcher;
            assert!(status.is_none());
            if unsafe { *count_ptr == 10 } {
                idle_watcher.stop();
                idle_watcher.close(||());
            } else {
                unsafe { *count_ptr = *count_ptr + 1; }
            }
        }
        loop_.run();
        loop_.close();
        assert!(count == 10);
    }
}

#[test]
fn idle_start_stop_start() {
    do run_in_bare_thread {
        let mut loop_ = Loop::new();
        let mut idle_watcher = { IdleWatcher::new(&mut loop_) };
        do idle_watcher.start |idle_watcher, status| {
            let mut idle_watcher = idle_watcher;
            assert!(status.is_none());
            idle_watcher.stop();
            do idle_watcher.start |idle_watcher, status| {
                assert!(status.is_none());
                let mut idle_watcher = idle_watcher;
                idle_watcher.stop();
                idle_watcher.close(||());
            }
        }
        loop_.run();
        loop_.close();
    }
}
<commit_msg>core::rt: Don't abort when reporting an unknown uv error<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!

Bindings to libuv, along with the default implementation of `core::rt::rtio`.

UV types consist of the event loop (Loop), Watchers, Requests and
Callbacks.

Watchers and Requests encapsulate pointers to uv *handles*, which have
subtyping relationships with each other.  This subtyping is reflected
in the bindings with explicit or implicit coercions. For example, an
upcast from TcpWatcher to StreamWatcher is done with
`tcp_watcher.as_stream()`. In other cases a callback on a specific
type of watcher will be passed a watcher of a supertype.

Currently all use of Request types (connect/write requests) are
encapsulated in the bindings and don't need to be dealt with by the
caller.

# Safety note

Due to the complex lifecycle of uv handles, as well as compiler bugs,
this module is not memory safe and requires explicit memory management,
via `close` and `delete` methods.

*/

use container::Container;
use option::*;
use str::raw::from_c_str;
use to_str::ToStr;
use ptr::Ptr;
use libc;
use vec;
use ptr;
use cast;
use str;
use option::*;
use str::raw::from_c_str;
use to_str::ToStr;
use libc::{c_void, c_int, size_t, malloc, free};
use cast::transmute;
use ptr::null;
use unstable::finally::Finally;

use rt::io::IoError;

#[cfg(test)] use unstable::run_in_bare_thread;

pub use self::file::FsRequest;
pub use self::net::{StreamWatcher, TcpWatcher};
pub use self::idle::IdleWatcher;

/// The implementation of `rtio` for libuv
pub mod uvio;

/// C bindings to libuv
pub mod uvll;

pub mod file;
pub mod net;
pub mod idle;

/// XXX: Loop(*handle) is buggy with destructors. Normal structs
/// with dtors may not be destructured, but tuple structs can,
/// but the results are not correct.
pub struct Loop {
    handle: *uvll::uv_loop_t
}

/// The trait implemented by uv 'watchers' (handles). Watchers are
/// non-owning wrappers around the uv handles and are not completely
/// safe - there may be multiple instances for a single underlying
/// handle.  Watchers are generally created, then `start`ed, `stop`ed
/// and `close`ed, but due to their complex life cycle may not be
/// entirely memory safe if used in unanticipated patterns.
pub trait Watcher { }

pub trait Request { }

/// A type that wraps a native handle
pub trait NativeHandle<T> {
    pub fn from_native_handle(T) -> Self;
    pub fn native_handle(&self) -> T;
}

pub impl Loop {
    fn new() -> Loop {
        let handle = unsafe { uvll::loop_new() };
        assert!(handle.is_not_null());
        NativeHandle::from_native_handle(handle)
    }

    fn run(&mut self) {
        unsafe { uvll::run(self.native_handle()) };
    }

    fn close(&mut self) {
        unsafe { uvll::loop_delete(self.native_handle()) };
    }
}

impl NativeHandle<*uvll::uv_loop_t> for Loop {
    fn from_native_handle(handle: *uvll::uv_loop_t) -> Loop {
        Loop { handle: handle }
    }
    fn native_handle(&self) -> *uvll::uv_loop_t {
        self.handle
    }
}

// XXX: The uv alloc callback also has a *uv_handle_t arg
pub type AllocCallback = ~fn(uint) -> Buf;
pub type ReadCallback = ~fn(StreamWatcher, int, Buf, Option<UvError>);
pub type NullCallback = ~fn();
pub type IdleCallback = ~fn(IdleWatcher, Option<UvError>);
pub type ConnectionCallback = ~fn(StreamWatcher, Option<UvError>);
pub type FsCallback = ~fn(FsRequest, Option<UvError>);

/// Callbacks used by StreamWatchers, set as custom data on the foreign handle
struct WatcherData {
    read_cb: Option<ReadCallback>,
    write_cb: Option<ConnectionCallback>,
    connect_cb: Option<ConnectionCallback>,
    close_cb: Option<NullCallback>,
    alloc_cb: Option<AllocCallback>,
    idle_cb: Option<IdleCallback>
}

pub trait WatcherInterop {
    fn event_loop(&self) -> Loop;
    fn install_watcher_data(&mut self);
    fn get_watcher_data<'r>(&'r mut self) -> &'r mut WatcherData;
    fn drop_watcher_data(&mut self);
}

impl<H, W: Watcher + NativeHandle<*H>> WatcherInterop for W {
    /// Get the uv event loop from a Watcher
    pub fn event_loop(&self) -> Loop {
        unsafe {
            let handle = self.native_handle();
            let loop_ = uvll::get_loop_for_uv_handle(handle);
            NativeHandle::from_native_handle(loop_)
        }
    }

    pub fn install_watcher_data(&mut self) {
        unsafe {
            let data = ~WatcherData {
                read_cb: None,
                write_cb: None,
                connect_cb: None,
                close_cb: None,
                alloc_cb: None,
                idle_cb: None
            };
            let data = transmute::<~WatcherData, *c_void>(data);
            uvll::set_data_for_uv_handle(self.native_handle(), data);
        }
    }

    pub fn get_watcher_data<'r>(&'r mut self) -> &'r mut WatcherData {
        unsafe {
            let data = uvll::get_data_for_uv_handle(self.native_handle());
            let data = transmute::<&*c_void, &mut ~WatcherData>(&data);
            return &mut **data;
        }
    }

    pub fn drop_watcher_data(&mut self) {
        unsafe {
            let data = uvll::get_data_for_uv_handle(self.native_handle());
            let _data = transmute::<*c_void, ~WatcherData>(data);
            uvll::set_data_for_uv_handle(self.native_handle(), null::<()>());
        }
    }
}

// XXX: Need to define the error constants like EOF so they can be
// compared to the UvError type

pub struct UvError(uvll::uv_err_t);

pub impl UvError {

    fn name(&self) -> ~str {
        unsafe {
            let inner = match self { &UvError(ref a) => a };
            let name_str = uvll::err_name(inner);
            assert!(name_str.is_not_null());
            from_c_str(name_str)
        }
    }

    fn desc(&self) -> ~str {
        unsafe {
            let inner = match self { &UvError(ref a) => a };
            let desc_str = uvll::strerror(inner);
            assert!(desc_str.is_not_null());
            from_c_str(desc_str)
        }
    }

    fn is_eof(&self) -> bool {
        self.code == uvll::EOF
    }
}

impl ToStr for UvError {
    fn to_str(&self) -> ~str {
        fmt!("%s: %s", self.name(), self.desc())
    }
}

#[test]
fn error_smoke_test() {
    let err = uvll::uv_err_t { code: 1, sys_errno_: 1 };
    let err: UvError = UvError(err);
    assert!(err.to_str() == ~"EOF: end of file");
}

pub fn last_uv_error<H, W: Watcher + NativeHandle<*H>>(watcher: &W) -> UvError {
    unsafe {
        let loop_ = watcher.event_loop();
        UvError(uvll::last_error(loop_.native_handle()))
    }
}

pub fn uv_error_to_io_error(uverr: UvError) -> IoError {

    // XXX: Could go in str::raw
    unsafe fn c_str_to_static_slice(s: *libc::c_char) -> &'static str {
        let s = s as *u8;
        let mut curr = s, len = 0u;
        while *curr != 0u8 {
            len += 1u;
            curr = ptr::offset(s, len);
        }

        str::raw::buf_as_slice(s, len, |d| cast::transmute(d))
    }

    unsafe {
        // Importing error constants
        use rt::uv::uvll::*;
        use rt::io::*;

        // uv error descriptions are static
        let c_desc = uvll::strerror(&*uverr);
        let desc = c_str_to_static_slice(c_desc);

        let kind = match uverr.code {
            UNKNOWN => OtherIoError,
            OK => OtherIoError,
            EOF => EndOfFile,
            EACCES => PermissionDenied,
            ECONNREFUSED => ConnectionRefused,
            ECONNRESET => ConnectionReset,
            _ => {
                // XXX: Need to map remaining uv error types
                OtherIoError
            }
        };

        IoError {
            kind: kind,
            desc: desc,
            detail: None
        }
    }
}

/// Given a uv handle, convert a callback status to a UvError
// XXX: Follow the pattern below by parameterizing over T: Watcher, not T
pub fn status_to_maybe_uv_error<T>(handle: *T, status: c_int) -> Option<UvError> {
    if status != -1 {
        None
    } else {
        unsafe {
            rtdebug!("handle: %x", handle as uint);
            let loop_ = uvll::get_loop_for_uv_handle(handle);
            rtdebug!("loop: %x", loop_ as uint);
            let err = uvll::last_error(loop_);
            Some(UvError(err))
        }
    }
}

/// The uv buffer type
pub type Buf = uvll::uv_buf_t;

/// Borrow a slice to a Buf
pub fn slice_to_uv_buf(v: &[u8]) -> Buf {
    let data = unsafe { vec::raw::to_ptr(v) };
    unsafe { uvll::buf_init(data, v.len()) }
}

// XXX: Do these conversions without copying

/// Transmute an owned vector to a Buf
pub fn vec_to_uv_buf(v: ~[u8]) -> Buf {
    unsafe {
        let data = malloc(v.len() as size_t) as *u8;
        assert!(data.is_not_null());
        do vec::as_imm_buf(v) |b, l| {
            let data = data as *mut u8;
            ptr::copy_memory(data, b, l)
        }
        uvll::buf_init(data, v.len())
    }
}

/// Transmute a Buf that was once a ~[u8] back to ~[u8]
pub fn vec_from_uv_buf(buf: Buf) -> Option<~[u8]> {
    if !(buf.len == 0 && buf.base.is_null()) {
        let v = unsafe { vec::from_buf(buf.base, buf.len as uint) };
        unsafe { free(buf.base as *c_void) };
        return Some(v);
    } else {
        // No buffer
        rtdebug!("No buffer!");
        return None;
    }
}

#[test]
fn test_slice_to_uv_buf() {
    let slice = [0, .. 20];
    let buf = slice_to_uv_buf(slice);

    assert!(buf.len == 20);

    unsafe {
        let base = transmute::<*u8, *mut u8>(buf.base);
        (*base) = 1;
        (*ptr::mut_offset(base, 1)) = 2;
    }

    assert!(slice[0] == 1);
    assert!(slice[1] == 2);
}

#[test]
fn loop_smoke_test() {
    do run_in_bare_thread {
        let mut loop_ = Loop::new();
        loop_.run();
        loop_.close();
    }
}

#[test]
#[ignore(reason = "valgrind - loop destroyed before watcher?")]
fn idle_new_then_close() {
    do run_in_bare_thread {
        let mut loop_ = Loop::new();
        let idle_watcher = { IdleWatcher::new(&mut loop_) };
        idle_watcher.close(||());
    }
}

#[test]
fn idle_smoke_test() {
    do run_in_bare_thread {
        let mut loop_ = Loop::new();
        let mut idle_watcher = { IdleWatcher::new(&mut loop_) };
        let mut count = 10;
        let count_ptr: *mut int = &mut count;
        do idle_watcher.start |idle_watcher, status| {
            let mut idle_watcher = idle_watcher;
            assert!(status.is_none());
            if unsafe { *count_ptr == 10 } {
                idle_watcher.stop();
                idle_watcher.close(||());
            } else {
                unsafe { *count_ptr = *count_ptr + 1; }
            }
        }
        loop_.run();
        loop_.close();
        assert!(count == 10);
    }
}

#[test]
fn idle_start_stop_start() {
    do run_in_bare_thread {
        let mut loop_ = Loop::new();
        let mut idle_watcher = { IdleWatcher::new(&mut loop_) };
        do idle_watcher.start |idle_watcher, status| {
            let mut idle_watcher = idle_watcher;
            assert!(status.is_none());
            idle_watcher.stop();
            do idle_watcher.start |idle_watcher, status| {
                assert!(status.is_none());
                let mut idle_watcher = idle_watcher;
                idle_watcher.stop();
                idle_watcher.close(||());
            }
        }
        loop_.run();
        loop_.close();
    }
}
<|endoftext|>