<commit_before>// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];

//! A type that represents one of two alternatives

import result::result;

/// The either type
enum Either<T, U> {
    Left(T),
    Right(U)
}

fn either<T, U, V>(f_left: fn((&T)) -> V,
                   f_right: fn((&U)) -> V, value: &Either<T, U>) -> V {
    /*!
     * Applies a function based on the given either value
     *
     * If `value` is left(T) then `f_left` is applied to its contents, if
     * `value` is right(U) then `f_right` is applied to its contents, and the
     * result is returned.
     */

    match *value {
      Left(ref l) => f_left(l),
      Right(ref r) => f_right(r)
    }
}

fn lefts<T: copy, U>(eithers: &[Either<T, U>]) -> ~[T] {
    //! Extracts from a vector of either all the left values

    let mut result: ~[T] = ~[];
    for vec::each(eithers) |elt| {
        match elt {
          Left(l) => vec::push(result, l),
          _ => { /* fallthrough */ }
        }
    }
    return result;
}

fn rights<T, U: copy>(eithers: &[Either<T, U>]) -> ~[U] {
    //! Extracts from a vector of either all the right values

    let mut result: ~[U] = ~[];
    for vec::each(eithers) |elt| {
        match elt {
          Right(r) => vec::push(result, r),
          _ => { /* fallthrough */ }
        }
    }
    return result;
}

fn partition<T: copy, U: copy>(eithers: &[Either<T, U>])
    -> {lefts: ~[T], rights: ~[U]} {
    /*!
     * Extracts from a vector of either all the left values and right values
     *
     * Returns a structure containing a vector of left values and a vector of
     * right values.
     */

    let mut lefts: ~[T] = ~[];
    let mut rights: ~[U] = ~[];
    for vec::each(eithers) |elt| {
        match elt {
          Left(l) => vec::push(lefts, l),
          Right(r) => vec::push(rights, r)
        }
    }
    return {lefts: lefts, rights: rights};
}

pure fn flip<T: copy, U: copy>(eith: &Either<T, U>) -> Either<U, T> {
    //! Flips between left and right of a given either

    match *eith {
      Right(r) => Left(r),
      Left(l) => Right(l)
    }
}

pure fn to_result<T: copy, U: copy>(eith: &Either<T, U>) -> result<U, T> {
    /*!
     * Converts either::t to a result::t
     *
     * Converts an `either` type to a `result` type, making the "right" choice
     * an ok result, and the "left" choice a fail
     */

    match *eith {
      Right(r) => result::ok(r),
      Left(l) => result::err(l)
    }
}

pure fn is_left<T, U>(eith: &Either<T, U>) -> bool {
    //! Checks whether the given value is a left

    match *eith { Left(_) => true, _ => false }
}

pure fn is_right<T, U>(eith: &Either<T, U>) -> bool {
    //! Checks whether the given value is a right

    match *eith { Right(_) => true, _ => false }
}

#[test]
fn test_either_left() {
    let val = Left(10);
    fn f_left(x: &int) -> bool { *x == 10 }
    fn f_right(_x: &uint) -> bool { false }
    assert (either(f_left, f_right, &val));
}

#[test]
fn test_either_right() {
    let val = Right(10u);
    fn f_left(_x: &int) -> bool { false }
    fn f_right(x: &uint) -> bool { *x == 10u }
    assert (either(f_left, f_right, &val));
}

#[test]
fn test_lefts() {
    let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
    let result = lefts(input);
    assert (result == ~[10, 12, 14]);
}

#[test]
fn test_lefts_none() {
    let input: ~[Either<int, int>] = ~[Right(10), Right(10)];
    let result = lefts(input);
    assert (vec::len(result) == 0u);
}

#[test]
fn test_lefts_empty() {
    let input: ~[Either<int, int>] = ~[];
    let result = lefts(input);
    assert (vec::len(result) == 0u);
}

#[test]
fn test_rights() {
    let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
    let result = rights(input);
    assert (result == ~[11, 13]);
}

#[test]
fn test_rights_none() {
    let input: ~[Either<int, int>] = ~[Left(10), Left(10)];
    let result = rights(input);
    assert (vec::len(result) == 0u);
}

#[test]
fn test_rights_empty() {
    let input: ~[Either<int, int>] = ~[];
    let result = rights(input);
    assert (vec::len(result) == 0u);
}

#[test]
fn test_partition() {
    let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
    let result = partition(input);
    assert (result.lefts[0] == 10);
    assert (result.lefts[1] == 12);
    assert (result.lefts[2] == 14);
    assert (result.rights[0] == 11);
    assert (result.rights[1] == 13);
}

#[test]
fn test_partition_no_lefts() {
    let input: ~[Either<int, int>] = ~[Right(10), Right(11)];
    let result = partition(input);
    assert (vec::len(result.lefts) == 0u);
    assert (vec::len(result.rights) == 2u);
}

#[test]
fn test_partition_no_rights() {
    let input: ~[Either<int, int>] = ~[Left(10), Left(11)];
    let result = partition(input);
    assert (vec::len(result.lefts) == 2u);
    assert (vec::len(result.rights) == 0u);
}

#[test]
fn test_partition_empty() {
    let input: ~[Either<int, int>] = ~[];
    let result = partition(input);
    assert (vec::len(result.lefts) == 0u);
    assert (vec::len(result.rights) == 0u);
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
//
<commit_msg>Add either::unwrap_{left,right}<commit_after>// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];

//! A type that represents one of two alternatives

import result::result;

/// The either type
enum Either<T, U> {
    Left(T),
    Right(U)
}

fn either<T, U, V>(f_left: fn((&T)) -> V,
                   f_right: fn((&U)) -> V, value: &Either<T, U>) -> V {
    /*!
     * Applies a function based on the given either value
     *
     * If `value` is left(T) then `f_left` is applied to its contents, if
     * `value` is right(U) then `f_right` is applied to its contents, and the
     * result is returned.
     */

    match *value {
      Left(ref l) => f_left(l),
      Right(ref r) => f_right(r)
    }
}

fn lefts<T: copy, U>(eithers: &[Either<T, U>]) -> ~[T] {
    //! Extracts from a vector of either all the left values

    let mut result: ~[T] = ~[];
    for vec::each(eithers) |elt| {
        match elt {
          Left(l) => vec::push(result, l),
          _ => { /* fallthrough */ }
        }
    }
    return result;
}

fn rights<T, U: copy>(eithers: &[Either<T, U>]) -> ~[U] {
    //! Extracts from a vector of either all the right values

    let mut result: ~[U] = ~[];
    for vec::each(eithers) |elt| {
        match elt {
          Right(r) => vec::push(result, r),
          _ => { /* fallthrough */ }
        }
    }
    return result;
}

fn partition<T: copy, U: copy>(eithers: &[Either<T, U>])
    -> {lefts: ~[T], rights: ~[U]} {
    /*!
     * Extracts from a vector of either all the left values and right values
     *
     * Returns a structure containing a vector of left values and a vector of
     * right values.
     */

    let mut lefts: ~[T] = ~[];
    let mut rights: ~[U] = ~[];
    for vec::each(eithers) |elt| {
        match elt {
          Left(l) => vec::push(lefts, l),
          Right(r) => vec::push(rights, r)
        }
    }
    return {lefts: lefts, rights: rights};
}

pure fn flip<T: copy, U: copy>(eith: &Either<T, U>) -> Either<U, T> {
    //! Flips between left and right of a given either

    match *eith {
      Right(r) => Left(r),
      Left(l) => Right(l)
    }
}

pure fn to_result<T: copy, U: copy>(eith: &Either<T, U>) -> result<U, T> {
    /*!
     * Converts either::t to a result::t
     *
     * Converts an `either` type to a `result` type, making the "right" choice
     * an ok result, and the "left" choice a fail
     */

    match *eith {
      Right(r) => result::ok(r),
      Left(l) => result::err(l)
    }
}

pure fn is_left<T, U>(eith: &Either<T, U>) -> bool {
    //! Checks whether the given value is a left

    match *eith { Left(_) => true, _ => false }
}

pure fn is_right<T, U>(eith: &Either<T, U>) -> bool {
    //! Checks whether the given value is a right

    match *eith { Right(_) => true, _ => false }
}

pure fn unwrap_left<T,U>(+eith: Either<T,U>) -> T {
    //! Retrieves the value in the left branch. Fails if the either is Right.

    match move eith {
        Left(move x) => x, Right(_) => fail ~"either::unwrap_left Right"
    }
}

pure fn unwrap_right<T,U>(+eith: Either<T,U>) -> U {
    //! Retrieves the value in the right branch. Fails if the either is Left.

    match move eith {
        Right(move x) => x, Left(_) => fail ~"either::unwrap_right Left"
    }
}

#[test]
fn test_either_left() {
    let val = Left(10);
    fn f_left(x: &int) -> bool { *x == 10 }
    fn f_right(_x: &uint) -> bool { false }
    assert (either(f_left, f_right, &val));
}

#[test]
fn test_either_right() {
    let val = Right(10u);
    fn f_left(_x: &int) -> bool { false }
    fn f_right(x: &uint) -> bool { *x == 10u }
    assert (either(f_left, f_right, &val));
}

#[test]
fn test_lefts() {
    let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
    let result = lefts(input);
    assert (result == ~[10, 12, 14]);
}

#[test]
fn test_lefts_none() {
    let input: ~[Either<int, int>] = ~[Right(10), Right(10)];
    let result = lefts(input);
    assert (vec::len(result) == 0u);
}

#[test]
fn test_lefts_empty() {
    let input: ~[Either<int, int>] = ~[];
    let result = lefts(input);
    assert (vec::len(result) == 0u);
}

#[test]
fn test_rights() {
    let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
    let result = rights(input);
    assert (result == ~[11, 13]);
}

#[test]
fn test_rights_none() {
    let input: ~[Either<int, int>] = ~[Left(10), Left(10)];
    let result = rights(input);
    assert (vec::len(result) == 0u);
}

#[test]
fn test_rights_empty() {
    let input: ~[Either<int, int>] = ~[];
    let result = rights(input);
    assert (vec::len(result) == 0u);
}

#[test]
fn test_partition() {
    let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
    let result = partition(input);
    assert (result.lefts[0] == 10);
    assert (result.lefts[1] == 12);
    assert (result.lefts[2] == 14);
    assert (result.rights[0] == 11);
    assert (result.rights[1] == 13);
}

#[test]
fn test_partition_no_lefts() {
    let input: ~[Either<int, int>] = ~[Right(10), Right(11)];
    let result = partition(input);
    assert (vec::len(result.lefts) == 0u);
    assert (vec::len(result.rights) == 2u);
}

#[test]
fn test_partition_no_rights() {
    let input: ~[Either<int, int>] = ~[Left(10), Left(11)];
    let result = partition(input);
    assert (vec::len(result.lefts) == 2u);
    assert (vec::len(result.rights) == 0u);
}

#[test]
fn test_partition_empty() {
    let input: ~[Either<int, int>] = ~[];
    let result = partition(input);
    assert (vec::len(result.lefts) == 0u);
    assert (vec::len(result.rights) == 0u);
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
//
<|endoftext|>


<commit_before><commit_msg>Fix TODOs. Modify some AST types.<commit_after><|endoftext|>


<commit_before>use column::{Alignment, Column, Cell};
use xattr::Attribute;
use dir::Dir;
use file::{File, GREY};
use options::{Columns, FileFilter, RecurseOptions};
use users::OSUsers;

use locale;
use ansi_term::Style::Plain;

#[derive(PartialEq, Debug, Copy)]
pub struct Details {
    pub columns: Columns,
    pub header: bool,
    pub recurse: Option<(RecurseOptions, FileFilter)>,
    pub xattr: bool,
}

impl Details {
    pub fn view(&self, dir: Option<&Dir>, files: &[File]) {
        // The output gets formatted into columns, which looks nicer. To
        // do this, we have to write the results into a table, instead of
        // displaying each file immediately, then calculating the maximum
        // width of each column based on the length of the results and
        // padding the fields during output.

        // Almost all the heavy lifting is done in a Table object, which
        // automatically calculates the width of each column and the
        // appropriate padding.
        let mut table = Table::with_columns(self.columns.for_dir(dir));
        if self.header { table.add_header() }

        self.add_files_to_table(&mut table, files, 0);
        table.print_table(self.xattr, self.recurse.is_some());
    }

    /// Adds files to the table - recursively, if the `recurse` option
    /// is present.
    fn add_files_to_table(&self, table: &mut Table, src: &[File], depth: usize) {
        for (index, file) in src.iter().enumerate() {
            table.add_row(file, depth, index == src.len() - 1);

            if let Some((r, filter)) = self.recurse {
                if r.tree == false || r.is_too_deep(depth) {
                    continue;
                }

                if let Some(ref dir) = file.this {
                    let mut files = dir.files(true);
                    filter.transform_files(&mut files);
                    self.add_files_to_table(table, &files, depth + 1);
                }
            }
        }
    }
}

struct Row {
    depth: usize,
    cells: Vec<Cell>,
    name: String,
    last: bool,
    attrs: Vec<Attribute>,
    children: bool,
}

type ColumnInfo = (usize, Alignment);

struct Table {
    columns: Vec<Column>,
    users: OSUsers,
    locale: UserLocale,
    rows: Vec<Row>,
}

impl Table {
    fn with_columns(columns: Vec<Column>) -> Table {
        Table {
            columns: columns,
            users: OSUsers::empty_cache(),
            locale: UserLocale::new(),
            rows: Vec::new(),
        }
    }

    fn add_header(&mut self) {
        let row = Row {
            depth: 0,
            cells: self.columns.iter().map(|c| Cell::paint(Plain.underline(), c.header())).collect(),
            name: Plain.underline().paint("Name").to_string(),
            last: false,
            attrs: Vec::new(),
            children: false,
        };

        self.rows.push(row);
    }

    fn cells_for_file(&mut self, file: &File) -> Vec<Cell> {
        self.columns.clone().iter()
                    .map(|c| file.display(c, &mut self.users, &self.locale))
                    .collect()
    }

    fn add_row(&mut self, file: &File, depth: usize, last: bool) {
        let row = Row {
            depth: depth,
            cells: self.cells_for_file(file),
            name: file.file_name_view(),
            last: last,
            attrs: file.xattrs.clone(),
            children: file.this.is_some(),
        };

        self.rows.push(row)
    }

    fn print_table(self, xattr: bool, show_children: bool) {
        let mut stack = Vec::new();

        let column_widths: Vec<usize> = range(0, self.columns.len())
            .map(|n| self.rows.iter().map(|row| row.cells[n].length).max().unwrap_or(0))
            .collect();

        for row in self.rows.iter() {
            for (n, width) in column_widths.iter().enumerate() {
                let padding = width - row.cells[n].length;
                print!("{} ", self.columns[n].alignment().pad_string(&row.cells[n].text, padding));
            }

            if show_children {
                stack.resize(row.depth + 1, TreePart::Edge);
                stack[row.depth] = if row.last { TreePart::Corner } else { TreePart::Edge };

                for i in 1 .. row.depth + 1 {
                    print!("{}", GREY.paint(stack[i].ascii_art()));
                }

                if row.children {
                    stack[row.depth] = if row.last { TreePart::Blank } else { TreePart::Line };
                }

                if row.depth != 0 {
                    print!(" ");
                }
            }

            print!("{}\n", row.name);

            if xattr {
                let width = row.attrs.iter().map(|a| a.name().len()).max().unwrap_or(0);
                for attr in row.attrs.iter() {
                    let name = attr.name();
                    println!("{}\t{}",
                        Alignment::Left.pad_string(name, width - name.len()),
                        attr.size()
                    )
                }
            }
        }
    }
}

#[derive(PartialEq, Debug, Clone)]
enum TreePart {
    Edge,
    Corner,
    Blank,
    Line,
}

impl TreePart {
    fn ascii_art(&self) -> &'static str {
        match *self {
            TreePart::Edge   => "├──",
            TreePart::Line   => "│  ",
            TreePart::Corner => "└──",
            TreePart::Blank  => "   ",
        }
    }
}

pub struct UserLocale {
    pub time: locale::Time,
    pub numeric: locale::Numeric,
}

impl UserLocale {
    pub fn new() -> UserLocale {
        UserLocale {
            time: locale::Time::load_user_locale().unwrap_or_else(|_| locale::Time::english()),
            numeric: locale::Numeric::load_user_locale().unwrap_or_else(|_| locale::Numeric::english()),
        }
    }

    pub fn default() -> UserLocale {
        UserLocale {
            time: locale::Time::english(),
            numeric: locale::Numeric::english(),
        }
    }
}
<commit_msg>Spew comments everywhere<commit_after>use column::{Alignment, Column, Cell};
use xattr::Attribute;
use dir::Dir;
use file::{File, GREY};
use options::{Columns, FileFilter, RecurseOptions};
use users::OSUsers;

use locale;
use ansi_term::Style::Plain;

/// With the **Details** view, the output gets formatted into columns, with
/// each `Column` object showing some piece of information about the file,
/// such as its size, or its permissions.
///
/// To do this, the results have to be written to a table, instead of
/// displaying each file immediately. Then, the width of each column can be
/// calculated based on the individual results, and the fields are padded
/// during output.
///
/// Almost all the heavy lifting is done in a Table object, which handles the
/// columns for each row.
#[derive(PartialEq, Debug, Copy)]
pub struct Details {

    /// A Columns object that says which columns should be included in the
    /// output in the general case. Directories themselves can pick which
    /// columns are *added* to this list, such as the Git column.
    pub columns: Columns,

    /// Whether to recurse through directories with a tree view, and if so,
    /// which options to use. This field is only relevant here if the `tree`
    /// field of the RecurseOptions is `true`.
    pub recurse: Option<(RecurseOptions, FileFilter)>,

    /// Whether to show a header line or not.
    pub header: bool,

    /// Whether to show each file's extended attributes.
    pub xattr: bool,
}

impl Details {
    pub fn view(&self, dir: Option<&Dir>, files: &[File]) {
        // First, transform the Columns object into a vector of columns for
        // the current directory.
        let mut table = Table::with_columns(self.columns.for_dir(dir));
        if self.header { table.add_header() }

        // Then add files to the table and print it out.
        self.add_files_to_table(&mut table, files, 0);
        table.print_table(self.xattr, self.recurse.is_some());
    }

    /// Adds files to the table - recursively, if the `recurse` option
    /// is present.
    fn add_files_to_table(&self, table: &mut Table, src: &[File], depth: usize) {
        for (index, file) in src.iter().enumerate() {
            table.add_file(file, depth, index == src.len() - 1);

            // There are two types of recursion that exa supports: a tree
            // view, which is dealt with here, and multiple listings, which is
            // dealt with in the main module. So only actually recurse if we
            // are in tree mode - the other case will be dealt with elsewhere.
            if let Some((r, filter)) = self.recurse {
                if r.tree == false || r.is_too_deep(depth) {
                    continue;
                }

                // Use the filter to remove unwanted files *before* expanding
                // them, so we don't examine any directories that wouldn't
                // have their contents listed anyway.
                if let Some(ref dir) = file.this {
                    let mut files = dir.files(true);
                    filter.transform_files(&mut files);
                    self.add_files_to_table(table, &files, depth + 1);
                }
            }
        }
    }
}

struct Row {

    /// Vector of cells to display.
    cells:    Vec<Cell>,

    /// This file's name, in coloured output. The name is treated separately
    /// from the other cells, as it never requires padding.
    name:     String,

    /// How many directories deep into the tree structure this is. Directories
    /// on top have depth 0.
    depth:    usize,

    /// Vector of this file's extended attributes, if that feature is active.
    attrs:    Vec<Attribute>,

    /// Whether this is the last entry in the directory. This flag is used
    /// when calculating the tree view.
    last:     bool,

    /// Whether this file is a directory and has any children. Also used when
    /// calculating the tree view.
    children: bool,
}

/// A **Table** object gets built up by the view as it lists files and
/// directories.
struct Table {
    columns: Vec<Column>,
    users:   OSUsers,
    locale:  UserLocale,
    rows:    Vec<Row>,
}

impl Table {
    /// Create a new, empty Table object, setting the caching fields to their
    /// empty states.
    fn with_columns(columns: Vec<Column>) -> Table {
        Table {
            columns: columns,
            users: OSUsers::empty_cache(),
            locale: UserLocale::new(),
            rows: Vec::new(),
        }
    }

    /// Add a dummy "header" row to the table, which contains the names of all
    /// the columns, underlined. This has dummy data for the cases that aren't
    /// actually used, such as the depth or list of attributes.
    fn add_header(&mut self) {
        let row = Row {
            depth:    0,
            cells:    self.columns.iter().map(|c| Cell::paint(Plain.underline(), c.header())).collect(),
            name:     Plain.underline().paint("Name").to_string(),
            last:     false,
            attrs:    Vec::new(),
            children: false,
        };

        self.rows.push(row);
    }

    /// Use the list of columns to find which cells should be produced for
    /// this file, per-column.
    fn cells_for_file(&mut self, file: &File) -> Vec<Cell> {
        self.columns.clone().iter()
                    .map(|c| file.display(c, &mut self.users, &self.locale))
                    .collect()
    }

    /// Get the cells for the given file, and add the result to the table.
    fn add_file(&mut self, file: &File, depth: usize, last: bool) {
        let row = Row {
            depth:    depth,
            cells:    self.cells_for_file(file),
            name:     file.file_name_view(),
            last:     last,
            attrs:    file.xattrs.clone(),
            children: file.this.is_some(),
        };

        self.rows.push(row)
    }

    /// Print the table to standard output, consuming it in the process.
    fn print_table(self, xattr: bool, show_children: bool) {
        let mut stack = Vec::new();

        // Work out the list of column widths by finding the longest cell for
        // each column, then formatting each cell in that column to be the
        // width of that one.
        let column_widths: Vec<usize> = range(0, self.columns.len())
            .map(|n| self.rows.iter().map(|row| row.cells[n].length).max().unwrap_or(0))
            .collect();

        for row in self.rows.into_iter() {
            for (n, width) in column_widths.iter().enumerate() {
                let padding = width - row.cells[n].length;
                print!("{} ", self.columns[n].alignment().pad_string(&row.cells[n].text, padding));
            }

            // A stack tracks which tree characters should be printed. It's
            // necessary to maintain information about the previously-printed
            // lines, as the output will change based on whether the
            // *previous* entry was the last in its directory.
            if show_children {
                stack.resize(row.depth + 1, TreePart::Edge);
                stack[row.depth] = if row.last { TreePart::Corner } else { TreePart::Edge };

                for i in 1 .. row.depth + 1 {
                    print!("{}", GREY.paint(stack[i].ascii_art()));
                }

                if row.children {
                    stack[row.depth] = if row.last { TreePart::Blank } else { TreePart::Line };
                }

                // If any tree characters have been printed, then add an extra
                // space, which makes the output look much better.
                if row.depth != 0 {
                    print!(" ");
                }
            }

            // Print the name without worrying about padding.
            print!("{}\n", row.name);

            if xattr {
                let width = row.attrs.iter().map(|a| a.name().len()).max().unwrap_or(0);
                for attr in row.attrs.iter() {
                    let name = attr.name();
                    println!("{}\t{}",
                        Alignment::Left.pad_string(name, width - name.len()),
                        attr.size()
                    )
                }
            }
        }
    }
}

#[derive(PartialEq, Debug, Clone)]
enum TreePart {

    /// Rightmost column, *not* the last in the directory.
    Edge,

    /// Not the rightmost column, and the directory has not finished yet.
    Line,

    /// Rightmost column, and the last in the directory.
    Corner,

    /// Not the rightmost column, and the directory *has* finished.
    Blank,
}

impl TreePart {
    fn ascii_art(&self) -> &'static str {
        match *self {
            TreePart::Edge   => "├──",
            TreePart::Line   => "│  ",
            TreePart::Corner => "└──",
            TreePart::Blank  => "   ",
        }
    }
}

pub struct UserLocale {
    pub time:    locale::Time,
    pub numeric: locale::Numeric,
}

impl UserLocale {
    pub fn new() -> UserLocale {
        UserLocale {
            time:    locale::Time::load_user_locale().unwrap_or_else(|_| locale::Time::english()),
            numeric: locale::Numeric::load_user_locale().unwrap_or_else(|_| locale::Numeric::english()),
        }
    }

    pub fn default() -> UserLocale {
        UserLocale {
            time:    locale::Time::english(),
            numeric: locale::Numeric::english(),
        }
    }
}
<|endoftext|>


<commit_before>use alloc::boxed::Box;

use core::cmp;

use common::event::{KeyEvent, MouseEvent};

use drivers::pio::*;

use schemes::KScheme;

/// PS2
pub struct Ps2 {
    /// The data
    data: Pio8,
    /// The command
    cmd: Pio8,
    /// Left shift?
    lshift: bool,
    /// Right shift?
    rshift: bool,
    /// Caps lock?
    caps_lock: bool,
    /// Caps lock toggle
    caps_lock_toggle: bool,
    /// The mouse packet
    mouse_packet: [u8; 4],
    /// Mouse packet index
    mouse_i: usize,
    /// Mouse point x
    mouse_x: isize,
    /// Mouse point y
    mouse_y: isize,
    /// Layout for keyboard
    /// Currently : 0 = EN / 1 = FR
    layout: usize,
}

impl Ps2 {
    /// Create new PS2 data
    pub fn new() -> Box<Self> {
        let mut module = box Ps2 {
            data: Pio8::new(0x60),
            cmd: Pio8::new(0x64),
            lshift: false,
            rshift: false,
            caps_lock: false,
            caps_lock_toggle: false,
            mouse_packet: [0; 4],
            mouse_i: 0,
            mouse_x: 0,
            mouse_y: 0,
            layout: 0,
        };

        unsafe {
            module.keyboard_init();
            module.mouse_init();
        }

        module
    }

    unsafe fn wait0(&self) {
        while (self.cmd.read() & 1) == 0 {}
    }

    unsafe fn wait1(&self) {
        while (self.cmd.read() & 2) == 2 {}
    }

    unsafe fn keyboard_init(&mut self) {
        while (self.cmd.read() & 0x1) == 1 {
            self.data.read();
        }

        self.wait1();
        self.cmd.write(0x20);
        self.wait0();
        let flags = (self.data.read() & 0b00110111) | 1 | 0b10000;
        self.wait1();
        self.cmd.write(0x60);
        self.wait1();
        self.data.write(flags);

        // Set Defaults
        self.wait1();
        self.data.write(0xF6);
        self.wait0();
        self.data.read();

        // Set LEDS
        self.wait1();
        self.data.write(0xED);
        self.wait0();
        self.data.read();

        self.wait1();
        self.data.write(0);
        self.wait0();
        self.data.read();

        // Set Scancode Map:
        self.wait1();
        self.data.write(0xF0);
        self.wait0();
        self.data.read();

        self.wait1();
        self.data.write(1);
        self.wait0();
        self.data.read();
    }

    /// Keyboard interrupt
    pub fn keyboard_interrupt(&mut self) -> Option<KeyEvent> {
        let scancode = unsafe { self.data.read() };

        if scancode == 0 {
            return None;
        } else if scancode == 0x2A {
            self.lshift = true;
        } else if scancode == 0xAA {
            self.lshift = false;
        } else if scancode == 0x36 {
            self.rshift = true;
        } else if scancode == 0xB6 {
            self.rshift = false;
        } else if scancode == 0x3A {
            if !self.caps_lock {
                self.caps_lock = true;
                self.caps_lock_toggle = true;
            } else {
                self.caps_lock_toggle = false;
            }
        } else if scancode == 0xBA {
            if self.caps_lock && !self.caps_lock_toggle {
                self.caps_lock = false;
            }
        }

        let shift;
        if self.caps_lock {
            shift = !(self.lshift || self.rshift);
        } else {
            shift = self.lshift || self.rshift;
        }

        return Some(KeyEvent {
            character: char_for_scancode(scancode & 0x7F, shift, self.layout),
            scancode: scancode & 0x7F,
            pressed: scancode < 0x80,
        });
    }

    unsafe fn mouse_cmd(&mut self, byte: u8) -> u8 {
        self.wait1();
        self.cmd.write(0xD4);
        self.wait1();
        self.data.write(byte);

        self.wait0();
        self.data.read()
    }

    /// Initialize mouse
    pub unsafe fn mouse_init(&mut self) {
        // The Init Dance
        self.wait1();
        self.cmd.write(0xA8);

        self.wait1();
        self.cmd.write(0x20);
        self.wait0();
        let status = self.data.read() | 2;
        self.wait1();
        self.cmd.write(0x60);
        self.wait1();
        self.data.write(status);

        // Set defaults
        self.mouse_cmd(0xF6);

        // Enable Streaming
        self.mouse_cmd(0xF4);
    }

    /// Mouse interrupt
    pub fn mouse_interrupt(&mut self) -> Option<MouseEvent> {
        let byte = unsafe { self.data.read() };
        if self.mouse_i == 0 {
            if byte & 0x8 == 0x8 {
                self.mouse_packet[0] = byte;
                self.mouse_i += 1;
            }
        } else if self.mouse_i == 1 {
            self.mouse_packet[1] = byte;

            self.mouse_i += 1;
        } else {
            self.mouse_packet[2] = byte;

            let left_button = (self.mouse_packet[0] & 1) == 1;
            let right_button = (self.mouse_packet[0] & 2) == 2;
            let middle_button = (self.mouse_packet[0] & 4) == 4;

            let x;
            if (self.mouse_packet[0] & 0x40) != 0x40 && self.mouse_packet[1] != 0 {
                x = self.mouse_packet[1] as isize -
                    (((self.mouse_packet[0] as isize) << 4) & 0x100);
            } else {
                x = 0;
            }

            let y;
            if (self.mouse_packet[0] & 0x80) != 0x80 && self.mouse_packet[2] != 0 {
                y = (((self.mouse_packet[0] as isize) << 3) & 0x100) -
                    self.mouse_packet[2] as isize;
            } else {
                y = 0;
            }

            unsafe {
                self.mouse_x = cmp::max(0,
                                        cmp::min((*::console).display.width as isize,
                                                 self.mouse_x + x));
                self.mouse_y = cmp::max(0,
                                        cmp::min((*::console).display.height as isize,
                                                 self.mouse_y + y));
            }

            self.mouse_i = 0;

            return Some(MouseEvent {
                x: self.mouse_x,
                y: self.mouse_y,
                left_button: left_button,
                right_button: right_button,
                middle_button: middle_button,
            });
        }

        return None;
    }

    /// Function to change the layout of the keyboard
    pub fn change_layout(&mut self, layout: usize) {
        self.layout = layout;
    }

}

impl KScheme for Ps2 {
    fn on_irq(&mut self, irq: u8) {
        if irq == 0x1 || irq == 0xC {
            self.on_poll();
        }
    }

    fn on_poll(&mut self) {
        loop {
            let status = unsafe { self.cmd.read() };
            if status & 0x21 == 1 {
                if let Some(key_event) = self.keyboard_interrupt() {
                    key_event.trigger();
                }
            } else if status & 0x21 == 0x21 {
                if let Some(mouse_event) = self.mouse_interrupt() {
                    mouse_event.trigger();
                }
            } else {
                break;
            }
        }
    }
}

/// Function to return the character associated with the scancode, and the layout
fn char_for_scancode(scancode: u8, shift: bool, layout: usize) -> char {
    let mut character = '\x00';
    if scancode < 58 {
        let characters: [char; 2] =
            match layout {
                0 => SCANCODES_EN[scancode as usize],
                1 => SCANCODES_FR[scancode as usize],
                _ => SCANCODES_EN[scancode as usize],
            };
        if shift {
            character = characters[1]
        }
        //Else...
        character = characters[0]
    }
    character
}

static SCANCODES_EN: [[char; 2]; 58] = [['\0', '\0'],
                                     ['\x1B', '\x1B'],
                                     ['1', '!'],
                                     ['2', '@'],
                                     ['3', '#'],
                                     ['4', '$'],
                                     ['5', '%'],
                                     ['6', '^'],
                                     ['7', '&'],
                                     ['8', '*'],
                                     ['9', '('],
                                     ['0', ')'],
                                     ['-', '_'],
                                     ['=', '+'],
                                     ['\0', '\0'],
                                     ['\t', '\t'],
                                     ['q', 'Q'],
                                     ['w', 'W'],
                                     ['e', 'E'],
                                     ['r', 'R'],
                                     ['t', 'T'],
                                     ['y', 'Y'],
                                     ['u', 'U'],
                                     ['i', 'I'],
                                     ['o', 'O'],
                                     ['p', 'P'],
                                     ['[', '{'],
                                     [']', '}'],
                                     ['\n', '\n'],
                                     ['\0', '\0'],
                                     ['a', 'A'],
                                     ['s', 'S'],
                                     ['d', 'D'],
                                     ['f', 'F'],
                                     ['g', 'G'],
                                     ['h', 'H'],
                                     ['j', 'J'],
                                     ['k', 'K'],
                                     ['l', 'L'],
                                     [';', ':'],
                                     ['\'', '"'],
                                     ['`', '~'],
                                     ['\0', '\0'],
                                     ['\\', '|'],
                                     ['z', 'Z'],
                                     ['x', 'X'],
                                     ['c', 'C'],
                                     ['v', 'V'],
                                     ['b', 'B'],
                                     ['n', 'N'],
                                     ['m', 'M'],
                                     [',', '<'],
                                     ['.', '>'],
                                     ['/', '?'],
                                     ['\0', '\0'],
                                     ['\0', '\0'],
                                     ['\0', '\0'],
                                     [' ', ' ']];

 static SCANCODES_FR: [[char; 2]; 58] = [['\0', '\0'],
                                      ['\x1B', '\x1B'],
                                      ['1', '&'],
                                      ['2', 'é'],
                                      ['3', '"'],
                                      ['4', '\''],
                                      ['5', '('],
                                      ['6', '-'],
                                      ['7', 'è'],
                                      ['8', '_'],
                                      ['9', 'ç'],
                                      ['0', 'à'],
                                      ['-', ')'],
                                      ['=', '='],
                                      ['\0', '\0'],
                                      ['\t', '\t'],
                                      ['a', 'A'],
                                      ['z', 'Z'],
                                      ['e', 'E'],
                                      ['r', 'R'],
                                      ['t', 'T'],
                                      ['y', 'Y'],
                                      ['u', 'U'],
                                      ['i', 'I'],
                                      ['o', 'O'],
                                      ['p', 'P'],
                                      ['^', '¨'],
                                      ['$', '£'],
                                      ['\n', '\n'],
                                      ['\0', '\0'],
                                      ['q', 'Q'],
                                      ['s', 'S'],
                                      ['d', 'D'],
                                      ['f', 'F'],
                                      ['g', 'G'],
                                      ['h', 'H'],
                                      ['j', 'J'],
                                      ['k', 'K'],
                                      ['l', 'L'],
                                      ['m', 'M'],
                                      ['ù', '%'],
                                      ['*', 'µ'],
                                      ['\0', '\0'],
                                      ['<', '>'],
                                      ['w', 'W'],
                                      ['x', 'X'],
                                      ['c', 'C'],
                                      ['v', 'V'],
                                      ['b', 'B'],
                                      ['n', 'N'],
                                      [',', '?'],
                                      [';', '.'],
                                      [':', '/'],
                                      ['!', '§'],
                                      ['\0', '\0'],
                                      ['\0', '\0'],
                                      ['\0', '\0'],
                                      [' ', ' ']];
<commit_msg>layout module added as field of ps2<commit_after>use alloc::boxed::Box;

use core::cmp;

use common::event::{KeyEvent, MouseEvent};

use drivers::pio::*;

use schemes::KScheme;

use drivers::kb_layouts::layouts;

/// PS2
pub struct Ps2 {
    /// The data
    data: Pio8,
    /// The command
    cmd: Pio8,
    /// Left shift?
    lshift: bool,
    /// Right shift?
    rshift: bool,
    /// Caps lock?
    caps_lock: bool,
    /// Caps lock toggle
    caps_lock_toggle: bool,
    /// The mouse packet
    mouse_packet: [u8; 4],
    /// Mouse packet index
    mouse_i: usize,
    /// Mouse point x
    mouse_x: isize,
    /// Mouse point y
    mouse_y: isize,
    /// Layout for keyboard
    /// Currently : 0 = EN / 1 = FR
    layout: usize,
}

impl Ps2 {
    /// Create new PS2 data
    pub fn new() -> Box<Self> {
        let mut module = box Ps2 {
            data: Pio8::new(0x60),
            cmd: Pio8::new(0x64),
            lshift: false,
            rshift: false,
            caps_lock: false,
            caps_lock_toggle: false,
            mouse_packet: [0; 4],
            mouse_i: 0,
            mouse_x: 0,
            mouse_y: 0,
            layout: 0,
        };

        unsafe {
            module.keyboard_init();
            module.mouse_init();
        }

        module
    }

    unsafe fn wait0(&self) {
        while (self.cmd.read() & 1) == 0 {}
    }

    unsafe fn wait1(&self) {
        while (self.cmd.read() & 2) == 2 {}
    }

    unsafe fn keyboard_init(&mut self) {
        while (self.cmd.read() & 0x1) == 1 {
            self.data.read();
        }

        self.wait1();
        self.cmd.write(0x20);
        self.wait0();
        let flags = (self.data.read() & 0b00110111) | 1 | 0b10000;
        self.wait1();
        self.cmd.write(0x60);
        self.wait1();
        self.data.write(flags);

        // Set Defaults
        self.wait1();
        self.data.write(0xF6);
        self.wait0();
        self.data.read();

        // Set LEDS
        self.wait1();
        self.data.write(0xED);
        self.wait0();
        self.data.read();

        self.wait1();
        self.data.write(0);
        self.wait0();
        self.data.read();

        // Set Scancode Map:
        self.wait1();
        self.data.write(0xF0);
        self.wait0();
        self.data.read();

        self.wait1();
        self.data.write(1);
        self.wait0();
        self.data.read();
    }

    /// Keyboard interrupt
    pub fn keyboard_interrupt(&mut self) -> Option<KeyEvent> {
        let scancode = unsafe { self.data.read() };

        if scancode == 0 {
            return None;
        } else if scancode == 0x2A {
            self.lshift = true;
        } else if scancode == 0xAA {
            self.lshift = false;
        } else if scancode == 0x36 {
            self.rshift = true;
        } else if scancode == 0xB6 {
            self.rshift = false;
        } else if scancode == 0x3A {
            if !self.caps_lock {
                self.caps_lock = true;
                self.caps_lock_toggle = true;
            } else {
                self.caps_lock_toggle = false;
            }
        } else if scancode == 0xBA {
            if self.caps_lock && !self.caps_lock_toggle {
                self.caps_lock = false;
            }
        }

        let shift;
        if self.caps_lock {
            shift = !(self.lshift || self.rshift);
        } else {
            shift = self.lshift || self.rshift;
        }

        return Some(KeyEvent {
            character: char_for_scancode(scancode & 0x7F, shift, self.layout),
            scancode: scancode & 0x7F,
            pressed: scancode < 0x80,
        });
    }

    unsafe fn mouse_cmd(&mut self, byte: u8) -> u8 {
        self.wait1();
        self.cmd.write(0xD4);
        self.wait1();
        self.data.write(byte);

        self.wait0();
        self.data.read()
    }

    /// Initialize mouse
    pub unsafe fn mouse_init(&mut self) {
        // The Init Dance
        self.wait1();
        self.cmd.write(0xA8);

        self.wait1();
        self.cmd.write(0x20);
        self.wait0();
        let status = self.data.read() | 2;
        self.wait1();
        self.cmd.write(0x60);
        self.wait1();
        self.data.write(status);

        // Set defaults
        self.mouse_cmd(0xF6);

        // Enable Streaming
        self.mouse_cmd(0xF4);
    }

    /// Mouse interrupt
    pub fn mouse_interrupt(&mut self) -> Option<MouseEvent> {
        let byte = unsafe { self.data.read() };
        if self.mouse_i == 0 {
            if byte & 0x8 == 0x8 {
                self.mouse_packet[0] = byte;
                self.mouse_i += 1;
            }
        } else if self.mouse_i == 1 {
            self.mouse_packet[1] = byte;

            self.mouse_i += 1;
        } else {
            self.mouse_packet[2] = byte;

            let left_button = (self.mouse_packet[0] & 1) == 1;
            let right_button = (self.mouse_packet[0] & 2) == 2;
            let middle_button = (self.mouse_packet[0] & 4) == 4;

            let x;
            if (self.mouse_packet[0] & 0x40) != 0x40 && self.mouse_packet[1] != 0 {
                x = self.mouse_packet[1] as isize -
                    (((self.mouse_packet[0] as isize) << 4) & 0x100);
            } else {
                x = 0;
            }

            let y;
            if (self.mouse_packet[0] & 0x80) != 0x80 && self.mouse_packet[2] != 0 {
                y = (((self.mouse_packet[0] as isize) << 3) & 0x100) -
                    self.mouse_packet[2] as isize;
            } else {
                y = 0;
            }

            unsafe {
                self.mouse_x = cmp::max(0,
                                        cmp::min((*::console).display.width as isize,
                                                 self.mouse_x + x));
                self.mouse_y = cmp::max(0,
                                        cmp::min((*::console).display.height as isize,
                                                 self.mouse_y + y));
            }

            self.mouse_i = 0;

            return Some(MouseEvent {
                x: self.mouse_x,
                y: self.mouse_y,
                left_button: left_button,
                right_button: right_button,
                middle_button: middle_button,
            });
        }

        return None;
    }

    /// Function to change the layout of the keyboard
    pub fn change_layout(&mut self, layout: usize) {
        self.layout = layout;
    }

}

impl KScheme for Ps2 {
    fn on_irq(&mut self, irq: u8) {
        if irq == 0x1 || irq == 0xC {
            self.on_poll();
        }
    }

    fn on_poll(&mut self) {
        loop {
            let status = unsafe { self.cmd.read() };
            if status & 0x21 == 1 {
                if let Some(key_event) = self.keyboard_interrupt() {
                    key_event.trigger();
                }
            } else if status & 0x21 == 0x21 {
                if let Some(mouse_event) = self.mouse_interrupt() {
                    mouse_event.trigger();
                }
            } else {
                break;
            }
        }
    }
}

/// Function to return the character associated with the scancode, and the layout
fn char_for_scancode(scancode: u8, shift: bool, layout: usize) -> char {
    let mut character = '\x00';
    if scancode < 58 {
        let characters: [char; 2] =
            match layout {
                0 => SCANCODES_EN[scancode as usize],
                1 => SCANCODES_FR[scancode as usize],
                _ => SCANCODES_EN[scancode as usize],
            };
        if shift {
            character = characters[1]
        }
        //Else...
        character = characters[0]
    }
    character
}

static SCANCODES_EN: [[char; 2]; 58] = [['\0', '\0'],
                                     ['\x1B', '\x1B'],
                                     ['1', '!'],
                                     ['2', '@'],
                                     ['3', '#'],
                                     ['4', '$'],
                                     ['5', '%'],
                                     ['6', '^'],
                                     ['7', '&'],
                                     ['8', '*'],
                                     ['9', '('],
                                     ['0', ')'],
                                     ['-', '_'],
                                     ['=', '+'],
                                     ['\0', '\0'],
                                     ['\t', '\t'],
                                     ['q', 'Q'],
                                     ['w', 'W'],
                                     ['e', 'E'],
                                     ['r', 'R'],
                                     ['t', 'T'],
                                     ['y', 'Y'],
                                     ['u', 'U'],
                                     ['i', 'I'],
                                     ['o', 'O'],
                                     ['p', 'P'],
                                     ['[', '{'],
                                     [']', '}'],
                                     ['\n', '\n'],
                                     ['\0', '\0'],
                                     ['a', 'A'],
                                     ['s', 'S'],
                                     ['d', 'D'],
                                     ['f', 'F'],
                                     ['g', 'G'],
                                     ['h', 'H'],
                                     ['j', 'J'],
                                     ['k', 'K'],
                                     ['l', 'L'],
                                     [';', ':'],
                                     ['\'', '"'],
                                     ['`', '~'],
                                     ['\0', '\0'],
                                     ['\\', '|'],
                                     ['z', 'Z'],
                                     ['x', 'X'],
                                     ['c', 'C'],
                                     ['v', 'V'],
                                     ['b', 'B'],
                                     ['n', 'N'],
                                     ['m', 'M'],
                                     [',', '<'],
                                     ['.', '>'],
                                     ['/', '?'],
                                     ['\0', '\0'],
                                     ['\0', '\0'],
                                     ['\0', '\0'],
                                     [' ', ' ']];

 static SCANCODES_FR: [[char; 2]; 58] = [['\0', '\0'],
                                      ['\x1B', '\x1B'],
                                      ['1', '&'],
                                      ['2', 'é'],
                                      ['3', '"'],
                                      ['4', '\''],
                                      ['5', '('],
                                      ['6', '-'],
                                      ['7', 'è'],
                                      ['8', '_'],
                                      ['9', 'ç'],
                                      ['0', 'à'],
                                      ['-', ')'],
                                      ['=', '='],
                                      ['\0', '\0'],
                                      ['\t', '\t'],
                                      ['a', 'A'],
                                      ['z', 'Z'],
                                      ['e', 'E'],
                                      ['r', 'R'],
                                      ['t', 'T'],
                                      ['y', 'Y'],
                                      ['u', 'U'],
                                      ['i', 'I'],
                                      ['o', 'O'],
                                      ['p', 'P'],
                                      ['^', '¨'],
                                      ['$', '£'],
                                      ['\n', '\n'],
                                      ['\0', '\0'],
                                      ['q', 'Q'],
                                      ['s', 'S'],
                                      ['d', 'D'],
                                      ['f', 'F'],
                                      ['g', 'G'],
                                      ['h', 'H'],
                                      ['j', 'J'],
                                      ['k', 'K'],
                                      ['l', 'L'],
                                      ['m', 'M'],
                                      ['ù', '%'],
                                      ['*', 'µ'],
                                      ['\0', '\0'],
                                      ['<', '>'],
                                      ['w', 'W'],
                                      ['x', 'X'],
                                      ['c', 'C'],
                                      ['v', 'V'],
                                      ['b', 'B'],
                                      ['n', 'N'],
                                      [',', '?'],
                                      [';', '.'],
                                      [':', '/'],
                                      ['!', '§'],
                                      ['\0', '\0'],
                                      ['\0', '\0'],
                                      ['\0', '\0'],
                                      [' ', ' ']];
<|endoftext|>


<commit_before><commit_msg>Do String borrow better<commit_after><|endoftext|>


<commit_before><commit_msg>even better with the code<commit_after>/// MPI-based method for summing many arrays

// Argument parsing
#[macro_use] extern crate clap;
// logging
#[macro_use] extern crate log;
extern crate ndarray;
extern crate env_logger;
// lastly, this library
extern crate cabarrus;
use cabarrus::errors::*;
use std::cmp::min;
use ndarray as nd;
use ndarray::prelude::*;

pub fn main() {
    // Main can't return a Result, and the ? operator needs the enclosing function to return Result
    inner_main().expect("Could not recover. Exiting.");
}
pub fn inner_main() -> Result<()> {
    env_logger::init().unwrap();
    let args = app_from_crate!()
        .arg_from_usage("<size> 'how many workers there are' ")
        .arg_from_usage("<rank> 'which worker am I, starting from 0' ")
        .arg_from_usage("<addends>.. 'files contains matrices to add'")
        .arg_from_usage("<output> 'file in which to store the resulting matrix'")
        .get_matches();

    let mats = args.values_of("addends").unwrap();
    let size = value_t!(args, "size", usize).unwrap_or_else(|e| e.exit());
    let rank = value_t!(args, "rank", usize).unwrap_or_else(|e| e.exit());
    let chunksize = (mats.len() + size - 1) / size;

    let mut accum = None;
    for matname in mats.skip(rank*chunksize).take(chunksize) {
        let ref matfile = cabarrus::numpy::open_matrix_mmap(matname)?;
        let ref mat = cabarrus::numpy::read_matrix_mmap(matfile)?;
        accum = Some(match accum {
            Some(mut acc) => {acc += mat; acc}
            None => mat * 1.0
        });
    }
    if let Some(ref acc) = accum {
        cabarrus::numpy::write_matrix(args.value_of("output").unwrap(), acc)?;
    }
    Ok(())
}
<|endoftext|>


<commit_before><commit_msg>Fix for broken pipe panics<commit_after><|endoftext|>


<commit_before><commit_msg>style: Remove SpecialColorKeyword enum and merge into SystemColor.<commit_after><|endoftext|>


<commit_before><commit_msg>added chap6 exercise<commit_after>#[derive(Clone)]
#[derive(Debug)]
struct MagicNumber {
	num:f64,
}

#[derive(Debug)]
struct Alien {
	name:String,
	tentacles:u32,
}

// exercise chap6
impl Alien {
	fn grow_tentacles(&mut self) {
		self.tentacles+=2;
	}
}

#[derive(Debug)]
struct  Magician {
    name:&'static str,
    power:u32,
}

#[allow(unused_variables)]
fn main() {

	let n = 42;
	match n {
		ref n => println!("Got a reference {:p}",n),
	}

	let mut m = 89;
	match m {
		ref mut mr => {println!("\nGot a mutable reference {:?}",mr);*mr= 231;},
	}
	println!("\nm is now changed to {:?}",m);

	//getting reference via destructuring using ref keyword on LHS
	let mag = Magician {name:"Turok",power:298};
	let name_of_magician = {let Magician {name:ref ref_to_name,power:_}=mag;*ref_to_name};
	println!("{:?}",name_of_magician );

	// Ownership in action
	// al has the ownership of the Alien struct instance
	let al = Alien {name:"Predator".to_string(),tentacles:4};
	// ownership transferred to big_al
	let mut big_al = al;

	// #[1]error: al2 cannot get a immutable reference to al because the resource has been moved
	// where al currently was pointing to, the new owner is big_al
	//let al2 = &al;
	// same error as #[1]
	//al.name = "Omnivore".to_string();
	big_al.name = "Krieger".to_string();

	// exercise part of chapter 6
	println!("{:?}",big_al);
	big_al.grow_tentacles();
	println!("The tentacles upgraded to {:?}",big_al.tentacles);

}<|endoftext|>


<commit_before>use std::fs::File;
use std::path::Path;
use std::io::prelude::*;
use std::vec::Vec;
use std::io;
use std::env;
use std::collections::HashMap;

struct Tape {
  pos: usize,
  tape: Vec<isize>
}

impl Tape {
  fn new() -> Tape { Tape { pos: 0, tape: vec![0] } }
  fn get(&self) -> isize { self.tape[self.pos] }
  fn getc(&self) -> char { self.get() as u8 as char }
  fn inc(&mut self) { self.tape[self.pos] += 1; }
  fn dec(&mut self) { self.tape[self.pos] -= 1; }
  fn advance(&mut self) { self.pos += 1; if self.tape.len() <= self.pos { self.tape.push(0) } }
  fn devance(&mut self) { if self.pos > 0 { self.pos -= 1; } }
}

struct Program {
  code: Vec<char>,
  bracket_map: HashMap<usize, usize>
}

impl Program {
  fn new(content: String) -> Program {
    let mut code: Vec<char> = Vec::new();
    let mut bracket_map = HashMap::new();
    let mut leftstack = Vec::new();
    let mut pc = 0;

    for c in content.chars() {
      match c {
        '+' | '-' | '.' | ',' | '<' | '>' => (),
        '[' => { leftstack.push(pc); },
        ']' => match leftstack.pop() {
          Some(left) => { bracket_map.insert(left, pc); bracket_map.insert(pc, left); }
          None => ()
        },
        _ => { continue; }
      }
      code.push(c);
      pc += 1;
    }
    Program{ code: code, bracket_map: bracket_map }
  }

  fn run(&self) {
    let mut pc: usize = 0;
    let len = self.code.len();
    let mut tape = Tape::new();

    while pc < len {
      match self.code[pc] {
        '+' => tape.inc(),
        '-' => tape.dec(),
        '>' => tape.advance(),
        '<' => tape.devance(),
        '[' => { if tape.get() == 0 { pc = self.bracket_map[&pc]; } },
        ']' => { if tape.get() != 0 { pc = self.bracket_map[&pc]; } },
        '.' => { print!("{}", tape.getc()); io::stdout().flush().unwrap() },
        _ => ()
      }
      pc += 1;
    }
  }
}

fn main() {
  let arg1 = env::args().nth(1).unwrap();
  let path = Path::new(&arg1);
  let mut s = String::new();
  let mut file = File::open(&path).unwrap();
  file.read_to_string(&mut s).unwrap();
  Program::new(s).run()
}
<commit_msg>Use BTreeMap instead of HashMap in brainfuck.rs<commit_after>use std::fs::File;
use std::path::Path;
use std::io::prelude::*;
use std::vec::Vec;
use std::io;
use std::env;
use std::collections::BTreeMap;

struct Tape {
  pos: usize,
  tape: Vec<isize>
}

impl Tape {
  fn new() -> Tape { Tape { pos: 0, tape: vec![0] } }
  fn get(&self) -> isize { self.tape[self.pos] }
  fn getc(&self) -> char { self.get() as u8 as char }
  fn inc(&mut self) { self.tape[self.pos] += 1; }
  fn dec(&mut self) { self.tape[self.pos] -= 1; }
  fn advance(&mut self) { self.pos += 1; if self.tape.len() <= self.pos { self.tape.push(0) } }
  fn devance(&mut self) { if self.pos > 0 { self.pos -= 1; } }
}

struct Program {
  code: Vec<char>,
  bracket_map: BTreeMap<usize, usize>
}

impl Program {
  fn new(content: String) -> Program {
    let mut code: Vec<char> = Vec::new();
    let mut bracket_map = BTreeMap::new();
    let mut leftstack = Vec::new();
    let mut pc = 0;

    for c in content.chars() {
      match c {
        '+' | '-' | '.' | ',' | '<' | '>' => (),
        '[' => { leftstack.push(pc); },
        ']' => match leftstack.pop() {
          Some(left) => { bracket_map.insert(left, pc); bracket_map.insert(pc, left); }
          None => ()
        },
        _ => { continue; }
      }
      code.push(c);
      pc += 1;
    }
    Program{ code: code, bracket_map: bracket_map }
  }

  fn run(&self) {
    let mut pc: usize = 0;
    let len = self.code.len();
    let mut tape = Tape::new();

    while pc < len {
      match self.code[pc] {
        '+' => tape.inc(),
        '-' => tape.dec(),
        '>' => tape.advance(),
        '<' => tape.devance(),
        '[' => { if tape.get() == 0 { pc = self.bracket_map[&pc]; } },
        ']' => { if tape.get() != 0 { pc = self.bracket_map[&pc]; } },
        '.' => { print!("{}", tape.getc()); io::stdout().flush().unwrap() },
        _ => ()
      }
      pc += 1;
    }
  }
}

fn main() {
  let arg1 = env::args().nth(1).unwrap();
  let path = Path::new(&arg1);
  let mut s = String::new();
  let mut file = File::open(&path).unwrap();
  file.read_to_string(&mut s).unwrap();
  Program::new(s).run()
}
<|endoftext|>


<commit_before><commit_msg>Moved NumericLiteral structure into separate file.<commit_after>use std::fmt::{self, Debug, Display};
use std::ops::{Add, Mul};

#[derive(Debug, PartialEq)]
pub enum NumericLiteral {
    Integer(i32),
    Float(f64)
}

impl fmt::Display for NumericLiteral {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            NumericLiteral::Integer(i) => write!(f, "{}", i),
            NumericLiteral::Float(i) => write!(f, "{}", i),
        }
    }
}

impl Add for NumericLiteral {
    type Output = NumericLiteral;

    fn add(self, other: NumericLiteral) -> NumericLiteral {
        match self {
            NumericLiteral::Integer(i) => {
                match other {
                    NumericLiteral::Integer(j) => NumericLiteral::Integer(i + j),
                    NumericLiteral::Float(j) => NumericLiteral::Float(i as f64 + j),
                }
            },
            NumericLiteral::Float(i) => {
                match other {
                    NumericLiteral::Integer(j) => NumericLiteral::Float(i + j as f64),
                    NumericLiteral::Float(j) => NumericLiteral::Float(i + j),
                }
            }
        }
    }
}

impl Mul for NumericLiteral {
    type Output = NumericLiteral;

    fn mul(self, other: NumericLiteral) -> NumericLiteral {
        match self {
            NumericLiteral::Integer(i) => {
                match other {
                    NumericLiteral::Integer(j) => NumericLiteral::Integer(i * j),
                    NumericLiteral::Float(j) => NumericLiteral::Float(i as f64 * j),
                }
            },
            NumericLiteral::Float(i) => {
                match other {
                    NumericLiteral::Integer(j) => NumericLiteral::Float(i * j as f64),
                    NumericLiteral::Float(j) => NumericLiteral::Float(i * j),
                }
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add test for Asset struct with interpolated path<commit_after>#[macro_use]
extern crate rust_embed;

/// Test doc comment
#[derive(RustEmbed)]
#[folder = "$CARGO_MANFEST_ROOT/examples/public/"]
struct Asset;

#[test]
fn get_works() {
  match Asset::get("index.html") {
    None => assert!(false, "index.html should exist"),
    _ => assert!(true),
  }
  match Asset::get("gg.html") {
    Some(_) => assert!(false, "gg.html should not exist"),
    _ => assert!(true),
  }
  match Asset::get("images/llama.png") {
    None => assert!(false, "llama.png should exist"),
    _ => assert!(true),
  }
}

#[test]
fn iter_works() {
  let mut num_files = 0;
  for file in Asset::iter() {
    assert!(Asset::get(file.as_ref()).is_some());
    num_files += 1;
  }
  assert_eq!(num_files, 6);
}

#[test]
fn trait_works_generic() {
  trait_works_generic_helper::<Asset>();
}
fn trait_works_generic_helper<E: rust_embed::RustEmbed>() {
  let mut num_files = 0;
  for file in E::iter() {
    assert!(E::get(file.as_ref()).is_some());
    num_files += 1;
  }
  assert_eq!(num_files, 6);
  assert!(E::get("gg.html").is_none(), "gg.html should not exist");
}
<|endoftext|>


<commit_before><commit_msg>Auto merge of #288 - christophebiocca:patch-1, r=Manishearth<commit_after><|endoftext|>


<commit_before><commit_msg>macro repeat<commit_after>macro_rules! find_min {
    ($x:expr) => {$x};
    ($x:expr, $($y:expr),+ ) => {
        std::cmp::min($x, find_min!($($y),+))
    }
}

fn main() {
    println!("Min of 1: {}", find_min!(1u32));
    println!("Min of 1, 25: {}", find_min!(1u32, 25u32));
    println!("Min of 1, 3,5,0,2,4: {}", find_min!(1, 3,5,0,2,4));
}<|endoftext|>


<commit_before><commit_msg>Implement plugin read and write attribute commands.<commit_after><|endoftext|>


<commit_before><commit_msg>Add a test for block expressions of generic types. XFAILed<commit_after>// xfail-boot
// xfail-stage0
// -*- rust -*-

// Tests for standalone blocks as expressions with dynamic type sizes

type compare[T] = fn(&T t1, &T t2) -> bool;

fn test_generic[T](&T expected, &compare[T] eq) {
  let T actual = { expected };
  check (eq(expected, actual));
}

fn test_bool() {
  fn compare_bool(&bool b1, &bool b2) -> bool {
    ret b1 == b2;
  }
  auto eq = bind compare_bool(_, _);
  test_generic[bool](true, eq);
}

fn test_tup() {
  type t = tup(int, int);
  fn compare_tup(&t t1, &t t2) -> bool {
    ret t1 == t2;
  }
  auto eq = bind compare_tup(_, _);
  test_generic[t](tup(1, 2), eq);
}

fn test_vec() {
  fn compare_vec(&vec[int] v1, &vec[int] v2) -> bool {
    ret v1 == v2;
  }
  auto eq = bind compare_vec(_, _);
  test_generic[vec[int]](vec(1, 2), eq);
}

fn test_box() {
  fn compare_box(&@bool b1, &@bool b2) -> bool {
    ret *b1 == *b2;
  }
  auto eq = bind compare_box(_, _);
  test_generic[@bool](@true, eq);
}

fn main() {
  test_bool();
  test_tup();
  // FIXME: These two don't pass yet
  test_vec();
  test_box();
}

<|endoftext|>


<commit_before>// Copyright 2015 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.

//! This pass adds validation calls (AcquireValid, ReleaseValid) where appropriate.
//! It has to be run really early, before transformations like inlining, because
//! introducing these calls *adds* UB -- so, conceptually, this pass is actually part
//! of MIR building, and only after this pass we think of the program has having the
//! normal MIR semantics.

use rustc::ty::{TyCtxt, RegionKind};
use rustc::mir::*;
use rustc::mir::transform::{MirPass, MirSource};

pub struct AddValidation;

impl MirPass for AddValidation {
    fn run_pass<'a, 'tcx>(&self,
                          tcx: TyCtxt<'a, 'tcx, 'tcx>,
                          _: MirSource,
                          mir: &mut Mir<'tcx>) {
        // PART 1
        // Add an AcquireValid at the beginning of the start block.
        if mir.arg_count > 0 {
            let acquire_stmt = Statement {
                source_info: SourceInfo {
                    scope: ARGUMENT_VISIBILITY_SCOPE,
                    span: mir.span, // TODO: Consider using just the span covering the function argument declaration
                },
                kind: StatementKind::Validate(ValidationOp::Acquire,
                    // Skip return value, go over all the arguments
                    mir.local_decls.iter_enumerated().skip(1).take(mir.arg_count)
                    .map(|(local, local_decl)| (local_decl.ty, Lvalue::Local(local))).collect()
                )
            };
            mir.basic_blocks_mut()[START_BLOCK].statements.insert(0, acquire_stmt);
        }

        // PART 2
        // Add ReleaseValid/AcquireValid around function call terminators.  We don't use a visitor because
        // we need to access the block that a Call jumps to.
        let mut returns : Vec<(SourceInfo, Lvalue<'tcx>, BasicBlock)> = Vec::new(); // Here we collect the destinations.
        let local_decls = mir.local_decls.clone(); // TODO: Find a way to get rid of this clone.
        for block_data in mir.basic_blocks_mut() {
            match block_data.terminator {
                Some(Terminator { kind: TerminatorKind::Call { ref args, ref destination, .. }, source_info }) => {
                    // Before the call: Release all arguments
                    let release_stmt = Statement {
                        source_info,
                        kind: StatementKind::Validate(ValidationOp::Release,
                            args.iter().filter_map(|op| {
                                match op {
                                    &Operand::Consume(ref lval) => {
                                        let ty = lval.ty(&local_decls, tcx).to_ty(tcx);
                                        Some((ty, lval.clone()))
                                    },
                                    &Operand::Constant(..) => { None },
                                }
                            }).collect())
                    };
                    block_data.statements.push(release_stmt);
                    // Remember the return destination for later
                    if let &Some(ref destination) = destination {
                        returns.push((source_info, destination.0.clone(), destination.1));
                    }
                }
                Some(Terminator { kind: TerminatorKind::Drop { location: ref lval, .. }, source_info }) |
                Some(Terminator { kind: TerminatorKind::DropAndReplace { location: ref lval, .. }, source_info }) => {
                    // Before the call: Release all arguments
                    let ty = lval.ty(&local_decls, tcx).to_ty(tcx);
                    let release_stmt = Statement {
                        source_info,
                        kind: StatementKind::Validate(ValidationOp::Release, vec![(ty, lval.clone())])
                    };
                    block_data.statements.push(release_stmt);
                    // drop doesn't return anything, so we need no acquire.
                }
                _ => {
                    // Not a block ending in a Call -> ignore.
                }
            }
        }
        // Now we go over the returns we collected to acquire the return values.
        for (source_info, dest_lval, dest_block) in returns {
            let ty = dest_lval.ty(&local_decls, tcx).to_ty(tcx);
            let acquire_stmt = Statement {
                source_info,
                kind: StatementKind::Validate(ValidationOp::Acquire, vec![(ty, dest_lval)])
            };
            mir.basic_blocks_mut()[dest_block].statements.insert(0, acquire_stmt);
        }

        // PART 3
        // Add ReleaseValid/AcquireValid around Ref.  Again an iterator does not seem very suited as
        // we need to add new statements before and after each Ref.
        for block_data in mir.basic_blocks_mut() {
            // We want to insert statements around Ref commands as we iterate.  To this end, we iterate backwards
            // using indices.
            for i in (0..block_data.statements.len()).rev() {
                let (dest_lval, re, src_lval) = match block_data.statements[i].kind {
                    StatementKind::Assign(ref dest_lval, Rvalue::Ref(re, _, ref src_lval)) => {
                        (dest_lval.clone(), re, src_lval.clone())
                    },
                    _ => continue,
                };
                // So this is a ref, and we got all the data we wanted.
                let dest_ty = dest_lval.ty(&local_decls, tcx).to_ty(tcx);
                let acquire_stmt = Statement {
                    source_info: block_data.statements[i].source_info,
                    kind: StatementKind::Validate(ValidationOp::Acquire, vec![(dest_ty, dest_lval)]),
                };
                block_data.statements.insert(i+1, acquire_stmt);

                // The source is released until the region of the borrow ends.
                let src_ty = src_lval.ty(&local_decls, tcx).to_ty(tcx);
                let op = match re {
                    &RegionKind::ReScope(ce) => ValidationOp::Suspend(ce),
                    &RegionKind::ReErased => bug!("AddValidation pass must be run before erasing lifetimes"),
                    _ => ValidationOp::Release,
                };
                let release_stmt = Statement {
                    source_info: block_data.statements[i].source_info,
                    kind: StatementKind::Validate(op, vec![(src_ty, src_lval)]),
                };
                block_data.statements.insert(i, release_stmt);
            }
        }
    }
}
<commit_msg>only emit Suspend validation for mutable paths<commit_after>// Copyright 2015 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.

//! This pass adds validation calls (AcquireValid, ReleaseValid) where appropriate.
//! It has to be run really early, before transformations like inlining, because
//! introducing these calls *adds* UB -- so, conceptually, this pass is actually part
//! of MIR building, and only after this pass we think of the program has having the
//! normal MIR semantics.

use rustc::ty::{TyCtxt, RegionKind};
use rustc::mir::*;
use rustc::mir::transform::{MirPass, MirSource};

pub struct AddValidation;

fn is_lvalue_shared<'a, 'tcx, D>(lval: &Lvalue<'tcx>, local_decls: &D, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool
    where D: HasLocalDecls<'tcx>
{
    use rustc::mir::Lvalue::*;

    match *lval {
        Local { .. } => false,
        Static(_) => true,
        Projection(ref proj) => {
            // If the base is shared, things stay shared
            if is_lvalue_shared(&proj.base, local_decls, tcx) {
                return true;
            }
            // A Deref projection may make things shared
            match proj.elem {
                ProjectionElem::Deref => {
                    // Computing the inside the recursion makes this quadratic.  We don't expect deep paths though.
                    let ty = proj.base.ty(local_decls, tcx).to_ty(tcx);
                    !ty.is_mutable_pointer()
                }
                _ => false,
            }
        }
    }
}

impl MirPass for AddValidation {
    fn run_pass<'a, 'tcx>(&self,
                          tcx: TyCtxt<'a, 'tcx, 'tcx>,
                          _: MirSource,
                          mir: &mut Mir<'tcx>) {
        // PART 1
        // Add an AcquireValid at the beginning of the start block.
        if mir.arg_count > 0 {
            let acquire_stmt = Statement {
                source_info: SourceInfo {
                    scope: ARGUMENT_VISIBILITY_SCOPE,
                    span: mir.span, // TODO: Consider using just the span covering the function argument declaration
                },
                kind: StatementKind::Validate(ValidationOp::Acquire,
                    // Skip return value, go over all the arguments
                    mir.local_decls.iter_enumerated().skip(1).take(mir.arg_count)
                    .map(|(local, local_decl)| (local_decl.ty, Lvalue::Local(local))).collect()
                )
            };
            mir.basic_blocks_mut()[START_BLOCK].statements.insert(0, acquire_stmt);
        }

        // PART 2
        // Add ReleaseValid/AcquireValid around function call terminators.  We don't use a visitor because
        // we need to access the block that a Call jumps to.
        let mut returns : Vec<(SourceInfo, Lvalue<'tcx>, BasicBlock)> = Vec::new(); // Here we collect the destinations.
        let local_decls = mir.local_decls.clone(); // TODO: Find a way to get rid of this clone.
        for block_data in mir.basic_blocks_mut() {
            match block_data.terminator {
                Some(Terminator { kind: TerminatorKind::Call { ref args, ref destination, .. }, source_info }) => {
                    // Before the call: Release all arguments
                    let release_stmt = Statement {
                        source_info,
                        kind: StatementKind::Validate(ValidationOp::Release,
                            args.iter().filter_map(|op| {
                                match op {
                                    &Operand::Consume(ref lval) => {
                                        let ty = lval.ty(&local_decls, tcx).to_ty(tcx);
                                        Some((ty, lval.clone()))
                                    },
                                    &Operand::Constant(..) => { None },
                                }
                            }).collect())
                    };
                    block_data.statements.push(release_stmt);
                    // Remember the return destination for later
                    if let &Some(ref destination) = destination {
                        returns.push((source_info, destination.0.clone(), destination.1));
                    }
                }
                Some(Terminator { kind: TerminatorKind::Drop { location: ref lval, .. }, source_info }) |
                Some(Terminator { kind: TerminatorKind::DropAndReplace { location: ref lval, .. }, source_info }) => {
                    // Before the call: Release all arguments
                    let ty = lval.ty(&local_decls, tcx).to_ty(tcx);
                    let release_stmt = Statement {
                        source_info,
                        kind: StatementKind::Validate(ValidationOp::Release, vec![(ty, lval.clone())])
                    };
                    block_data.statements.push(release_stmt);
                    // drop doesn't return anything, so we need no acquire.
                }
                _ => {
                    // Not a block ending in a Call -> ignore.
                }
            }
        }
        // Now we go over the returns we collected to acquire the return values.
        for (source_info, dest_lval, dest_block) in returns {
            let ty = dest_lval.ty(&local_decls, tcx).to_ty(tcx);
            let acquire_stmt = Statement {
                source_info,
                kind: StatementKind::Validate(ValidationOp::Acquire, vec![(ty, dest_lval)])
            };
            mir.basic_blocks_mut()[dest_block].statements.insert(0, acquire_stmt);
        }

        // PART 3
        // Add ReleaseValid/AcquireValid around Ref.  Again an iterator does not seem very suited as
        // we need to add new statements before and after each Ref.
        for block_data in mir.basic_blocks_mut() {
            // We want to insert statements around Ref commands as we iterate.  To this end, we iterate backwards
            // using indices.
            for i in (0..block_data.statements.len()).rev() {
                let (dest_lval, re, src_lval) = match block_data.statements[i].kind {
                    StatementKind::Assign(ref dest_lval, Rvalue::Ref(re, _, ref src_lval)) => {
                        (dest_lval.clone(), re, src_lval.clone())
                    },
                    _ => continue,
                };
                // So this is a ref, and we got all the data we wanted.
                let dest_ty = dest_lval.ty(&local_decls, tcx).to_ty(tcx);
                let acquire_stmt = Statement {
                    source_info: block_data.statements[i].source_info,
                    kind: StatementKind::Validate(ValidationOp::Acquire, vec![(dest_ty, dest_lval)]),
                };
                block_data.statements.insert(i+1, acquire_stmt);

                // The source is released until the region of the borrow ends -- but not if it is shared.
                if !is_lvalue_shared(&src_lval, &local_decls, tcx) {
                    let src_ty = src_lval.ty(&local_decls, tcx).to_ty(tcx);
                    let op = match re {
                        &RegionKind::ReScope(ce) => ValidationOp::Suspend(ce),
                        &RegionKind::ReErased => bug!("AddValidation pass must be run before erasing lifetimes"),
                        _ => ValidationOp::Release,
                    };
                    let release_stmt = Statement {
                        source_info: block_data.statements[i].source_info,
                        kind: StatementKind::Validate(op, vec![(src_ty, src_lval)]),
                    };
                    block_data.statements.insert(i, release_stmt);
                }
            }
        }
    }
}
<|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.

use deriving::generic::*;
use deriving::generic::ty::*;

use syntax::ast::{MetaItem, Expr, BinOpKind};
use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt, Annotatable};
use syntax::ext::build::AstBuilder;
use syntax::parse::token::InternedString;
use syntax::ptr::P;

pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt,
                                  span: Span,
                                  mitem: &MetaItem,
                                  item: &Annotatable,
                                  push: &mut FnMut(Annotatable))
{
    // structures are equal if all fields are equal, and non equal, if
    // any fields are not equal or if the enum variants are different
    fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
        cs_fold(
            true,  // use foldl
            |cx, span, subexpr, self_f, other_fs| {
                let other_f = match (other_fs.len(), other_fs.get(0)) {
                    (1, Some(o_f)) => o_f,
                    _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialEq)`")
                };

                let eq = cx.expr_binary(span, BinOpKind::Eq, self_f, other_f.clone());

                cx.expr_binary(span, BinOpKind::And, subexpr, eq)
            },
            cx.expr_bool(span, true),
            Box::new(|cx, span, _, _| cx.expr_bool(span, false)),
            cx, span, substr)
    }
    fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
        cs_fold(
            true,  // use foldl
            |cx, span, subexpr, self_f, other_fs| {
                let other_f = match (other_fs.len(), other_fs.get(0)) {
                    (1, Some(o_f)) => o_f,
                    _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialEq)`")
                };

                let eq = cx.expr_binary(span, BinOpKind::Ne, self_f, other_f.clone());

                cx.expr_binary(span, BinOpKind::Or, subexpr, eq)
            },
            cx.expr_bool(span, false),
            Box::new(|cx, span, _, _| cx.expr_bool(span, true)),
            cx, span, substr)
    }

    macro_rules! md {
        ($name:expr, $f:ident) => { {
            let inline = cx.meta_word(span, InternedString::new("inline"));
            let attrs = vec!(cx.attribute(span, inline));
            MethodDef {
                name: $name,
                generics: LifetimeBounds::empty(),
                explicit_self: borrowed_explicit_self(),
                args: vec!(borrowed_self()),
                ret_ty: Literal(path_local!(bool)),
                attributes: attrs,
                is_unsafe: false,
                combine_substructure: combine_substructure(Box::new(|a, b, c| {
                    $f(a, b, c)
                }))
            }
        } }
    }

    let trait_def = TraitDef {
        span: span,
        attributes: Vec::new(),
        path: path_std!(cx, core::cmp::PartialEq),
        additional_bounds: Vec::new(),
        generics: LifetimeBounds::empty(),
        is_unsafe: false,
        methods: vec!(
            md!("eq", cs_eq),
            md!("ne", cs_ne)
        ),
        associated_types: Vec::new(),
    };
    trait_def.expand(cx, mitem, item, push)
}
<commit_msg>derive: Avoid emitting PartialEq::ne for c-like enums<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.

use deriving::generic::*;
use deriving::generic::ty::*;

use syntax::ast::{MetaItem, Expr, BinOpKind, ItemKind, VariantData};
use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt, Annotatable};
use syntax::ext::build::AstBuilder;
use syntax::parse::token::InternedString;
use syntax::ptr::P;

fn is_clike_enum(item: &Annotatable) -> bool {
    match *item {
        Annotatable::Item(ref item) => {
            match item.node {
                ItemKind::Enum(ref enum_def, _) => {
                    enum_def.variants.iter().all(|v|
                        if let VariantData::Unit(..) = v.node.data {
                            true
                        } else {
                            false
                        }
                    )
                }
                _ => false,
            }
        }
        _ => false,
    }
}

pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt,
                                  span: Span,
                                  mitem: &MetaItem,
                                  item: &Annotatable,
                                  push: &mut FnMut(Annotatable))
{
    // structures are equal if all fields are equal, and non equal, if
    // any fields are not equal or if the enum variants are different
    fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
        cs_fold(
            true,  // use foldl
            |cx, span, subexpr, self_f, other_fs| {
                let other_f = match (other_fs.len(), other_fs.get(0)) {
                    (1, Some(o_f)) => o_f,
                    _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialEq)`")
                };

                let eq = cx.expr_binary(span, BinOpKind::Eq, self_f, other_f.clone());

                cx.expr_binary(span, BinOpKind::And, subexpr, eq)
            },
            cx.expr_bool(span, true),
            Box::new(|cx, span, _, _| cx.expr_bool(span, false)),
            cx, span, substr)
    }
    fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
        cs_fold(
            true,  // use foldl
            |cx, span, subexpr, self_f, other_fs| {
                let other_f = match (other_fs.len(), other_fs.get(0)) {
                    (1, Some(o_f)) => o_f,
                    _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialEq)`")
                };

                let eq = cx.expr_binary(span, BinOpKind::Ne, self_f, other_f.clone());

                cx.expr_binary(span, BinOpKind::Or, subexpr, eq)
            },
            cx.expr_bool(span, false),
            Box::new(|cx, span, _, _| cx.expr_bool(span, true)),
            cx, span, substr)
    }

    macro_rules! md {
        ($name:expr, $f:ident) => { {
            let inline = cx.meta_word(span, InternedString::new("inline"));
            let attrs = vec!(cx.attribute(span, inline));
            MethodDef {
                name: $name,
                generics: LifetimeBounds::empty(),
                explicit_self: borrowed_explicit_self(),
                args: vec!(borrowed_self()),
                ret_ty: Literal(path_local!(bool)),
                attributes: attrs,
                is_unsafe: false,
                combine_substructure: combine_substructure(Box::new(|a, b, c| {
                    $f(a, b, c)
                }))
            }
        } }
    }

    // avoid defining `ne` if we can
    let mut methods = vec![md!("eq", cs_eq)];
    if !is_clike_enum(item) {
        methods.push(md!("ne", cs_ne));
    }

    let trait_def = TraitDef {
        span: span,
        attributes: Vec::new(),
        path: path_std!(cx, core::cmp::PartialEq),
        additional_bounds: Vec::new(),
        generics: LifetimeBounds::empty(),
        is_unsafe: false,
        methods: methods,
        associated_types: Vec::new(),
    };
    trait_def.expand(cx, mitem, item, push)
}
<|endoftext|>


<commit_before><commit_msg>Add a test<commit_after>// Copyright 2015 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.

// This code produces a CFG with critical edges that, if we don't
// handle properly, will cause invalid codegen.

#![feature(rustc_attrs)]

enum State {
    Both,
    Front,
    Back
}

pub struct Foo<A: Iterator, B: Iterator> {
    state: State,
    a: A,
    b: B
}

impl<A, B> Foo<A, B>
where A: Iterator, B: Iterator<Item=A::Item>
{
    // This is the function we care about
    #[rustc_mir]
    fn next(&mut self) -> Option<A::Item> {
        match self.state {
            State::Both => match self.a.next() {
                elt @ Some(..) => elt,
                None => {
                    self.state = State::Back;
                    self.b.next()
                }
            },
            State::Front => self.a.next(),
            State::Back => self.b.next(),
        }
    }
}

// Make sure we actually translate a version of the function
pub fn do_stuff(mut f: Foo<Box<Iterator<Item=u32>>, Box<Iterator<Item=u32>>>) {
    let _x = f.next();
}

fn main() {}
<|endoftext|>


<commit_before><commit_msg>added long_chain example<commit_after>extern crate fibe;

fn test(wait: fibe::Wait) {
    let mut front = fibe::Frontend::new();
    let mut last = front.add(move || {}, vec![]);
    for i in 1..300000 {
    	last = front.add(move || {}, vec![last]);
	}
    front.die(wait);
}

fn main() {
    test(fibe::Wait::Pending);
}
<|endoftext|>


<commit_before><commit_msg>create an example for pull request files<commit_after>extern crate env_logger;
extern crate futures;
extern crate hubcaps;
extern crate tokio_core;

use std::env;

use futures::Stream;
use tokio_core::reactor::Core;

use hubcaps::{Credentials, Github, Result};

fn main() -> Result<()> {
  drop(env_logger::init());
  match env::var("GITHUB_TOKEN").ok() {
    Some(token) => {
      let mut core = Core::new()?;
      let github = Github::new(
        concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")),
        Credentials::Token(token),
        &core.handle(),
      );
      for diff in core.run(github.repo("rust-lang", "rust").pulls().get(49536).files())? {
        println!("{:#?}", diff);
      }
      Ok(())
    }
    _ => Err("example missing GITHUB_TOKEN".into()),
  }
}
<|endoftext|>


<commit_before><commit_msg>fix build<commit_after><|endoftext|>


<commit_before><commit_msg>Part 2: define a type to encapsulate query inputs.<commit_after>// Copyright 2016 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

use std::collections::BTreeMap;

use mentat_core::{
    TypedValue,
    ValueType,
};

use mentat_query::{
    Variable,
};

pub use errors::{
    Error,
    ErrorKind,
    Result,
};

/// Define the inputs to a query. This is in two parts: a set of values known now, and a set of
/// types known now.
/// The separate map of types is to allow queries to be algebrized without full knowledge of
/// the bindings that will be used at execution time.
/// When built correctly, `types` is guaranteed to contain the types of `values` -- use
/// `QueryInputs::new` or `QueryInputs::with_values` to construct an instance.
pub struct QueryInputs {
    pub types: BTreeMap<Variable, ValueType>,
    pub values: BTreeMap<Variable, TypedValue>,
}

impl Default for QueryInputs {
    fn default() -> Self {
        QueryInputs { types: BTreeMap::default(), values: BTreeMap::default() }
    }
}

impl QueryInputs {
    pub fn with_value_sequence(vals: Vec<(Variable, TypedValue)>) -> QueryInputs {
        let values: BTreeMap<Variable, TypedValue> = vals.into_iter().collect();
        QueryInputs::with_values(values)
    }

    pub fn with_values(values: BTreeMap<Variable, TypedValue>) -> QueryInputs {
        QueryInputs {
            types: values.iter().map(|(var, val)| (var.clone(), val.value_type())).collect(),
            values: values,
        }
    }

    pub fn new(mut types: BTreeMap<Variable, ValueType>,
               values: BTreeMap<Variable, TypedValue>) -> Result<QueryInputs> {
        // Make sure that the types of the values agree with those in types, and collect.
        for (var, v) in values.iter() {
            let t = v.value_type();
            let old = types.insert(var.clone(), t);
            if let Some(old) = old {
                if old != t {
                    bail!(ErrorKind::InputTypeDisagreement(var.name(), old, t));
                }
            }
        }
        Ok(QueryInputs { types: types, values: values })
    }
}
<|endoftext|>


<commit_before><commit_msg> removed filter for testing<commit_after><|endoftext|>


<commit_before><commit_msg>an empy message<commit_after><|endoftext|>


<commit_before><commit_msg>refactor(backend/xcb): refactor window_name method<commit_after><|endoftext|>


<commit_before><commit_msg>Add a test for multiple main functions<commit_after><|endoftext|>