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

//! Types dealing with dynamic mutability

use prelude::*;
use cast;
use util::NonCopyable;

/// A mutable memory location that admits only `Pod` data.
#[no_freeze]
#[deriving(Clone)]
pub struct Cell<T> {
    priv value: T,
}

impl<T: ::kinds::Pod> Cell<T> {
    /// Creates a new `Cell` containing the given value.
    pub fn new(value: T) -> Cell<T> {
        Cell {
            value: value,
        }
    }

    /// Returns a copy of the contained value.
    #[inline]
    pub fn get(&self) -> T {
        self.value
    }

    /// Sets the contained value.
    #[inline]
    pub fn set(&self, value: T) {
        unsafe {
            *cast::transmute_mut(&self.value) = value
        }
    }
}

/// A mutable memory location with dynamically checked borrow rules
#[no_freeze]
pub struct RefCell<T> {
    priv value: T,
    priv borrow: BorrowFlag,
    priv nc: NonCopyable
}

// Values [1, MAX-1] represent the number of `Ref` active
// (will not outgrow its range since `uint` is the size of the address space)
type BorrowFlag = uint;
static UNUSED: BorrowFlag = 0;
static WRITING: BorrowFlag = -1;

impl<T> RefCell<T> {
    /// Create a new `RefCell` containing `value`
    pub fn new(value: T) -> RefCell<T> {
        RefCell {
            value: value,
            borrow: UNUSED,
            nc: NonCopyable
        }
    }

    /// Consumes the `RefCell`, returning the wrapped value.
    pub fn unwrap(self) -> T {
        assert!(self.borrow == UNUSED);
        self.value
    }

    unsafe fn as_mut<'a>(&'a self) -> &'a mut RefCell<T> {
        cast::transmute_mut(self)
    }

    /// Attempts to immutably borrow the wrapped value.
    ///
    /// The borrow lasts until the returned `Ref` exits scope. Multiple
    /// immutable borrows can be taken out at the same time.
    ///
    /// Returns `None` if the value is currently mutably borrowed.
    pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
        match self.borrow {
            WRITING => None,
            _ => {
                unsafe { self.as_mut().borrow += 1; }
                Some(Ref { parent: self })
            }
        }
    }

    /// Immutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `Ref` exits scope. Multiple
    /// immutable borrows can be taken out at the same time.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently mutably borrowed.
    pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
        match self.try_borrow() {
            Some(ptr) => ptr,
            None => fail!("RefCell<T> already mutably borrowed")
        }
    }

    /// Mutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `RefMut` exits scope. The value
    /// cannot be borrowed while this borrow is active.
    ///
    /// Returns `None` if the value is currently borrowed.
    pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
        match self.borrow {
            UNUSED => unsafe {
                let mut_self = self.as_mut();
                mut_self.borrow = WRITING;
                Some(RefMut { parent: mut_self })
            },
            _ => None
        }
    }

    /// Mutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `RefMut` exits scope. The value
    /// cannot be borrowed while this borrow is active.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently borrowed.
    pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> {
        match self.try_borrow_mut() {
            Some(ptr) => ptr,
            None => fail!("RefCell<T> already borrowed")
        }
    }

    /// Immutably borrows the wrapped value and applies `blk` to it.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently mutably borrowed.
    #[inline]
    pub fn with<U>(&self, blk: |&T| -> U) -> U {
        let ptr = self.borrow();
        blk(ptr.get())
    }

    /// Mutably borrows the wrapped value and applies `blk` to it.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently borrowed.
    #[inline]
    pub fn with_mut<U>(&self, blk: |&mut T| -> U) -> U {
        let mut ptr = self.borrow_mut();
        blk(ptr.get())
    }

    /// Sets the value, replacing what was there.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently borrowed.
    #[inline]
    pub fn set(&self, value: T) {
        let mut reference = self.borrow_mut();
        *reference.get() = value
    }
}

impl<T:Clone> RefCell<T> {
    /// Returns a copy of the contained value.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently mutably borrowed.
    #[inline]
    pub fn get(&self) -> T {
        let reference = self.borrow();
        (*reference.get()).clone()
    }
}

impl<T: Clone> Clone for RefCell<T> {
    fn clone(&self) -> RefCell<T> {
        let x = self.borrow();
        RefCell::new(x.get().clone())
    }
}

impl<T: DeepClone> DeepClone for RefCell<T> {
    fn deep_clone(&self) -> RefCell<T> {
        let x = self.borrow();
        RefCell::new(x.get().deep_clone())
    }
}

impl<T: Eq> Eq for RefCell<T> {
    fn eq(&self, other: &RefCell<T>) -> bool {
        let a = self.borrow();
        let b = other.borrow();
        a.get() == b.get()
    }
}

/// Wraps a borrowed reference to a value in a `RefCell` box.
pub struct Ref<'b, T> {
    priv parent: &'b RefCell<T>
}

#[unsafe_destructor]
impl<'b, T> Drop for Ref<'b, T> {
    fn drop(&mut self) {
        assert!(self.parent.borrow != WRITING && self.parent.borrow != UNUSED);
        unsafe { self.parent.as_mut().borrow -= 1; }
    }
}

impl<'b, T> Ref<'b, T> {
    /// Retrieve an immutable reference to the stored value.
    #[inline]
    pub fn get<'a>(&'a self) -> &'a T {
        &self.parent.value
    }
}

/// Wraps a mutable borrowed reference to a value in a `RefCell` box.
pub struct RefMut<'b, T> {
    priv parent: &'b mut RefCell<T>
}

#[unsafe_destructor]
impl<'b, T> Drop for RefMut<'b, T> {
    fn drop(&mut self) {
        assert!(self.parent.borrow == WRITING);
        self.parent.borrow = UNUSED;
    }
}

impl<'b, T> RefMut<'b, T> {
    /// Retrieve a mutable reference to the stored value.
    #[inline]
    pub fn get<'a>(&'a mut self) -> &'a mut T {
        &mut self.parent.value
    }
}

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

    #[test]
    fn smoketest_cell() {
        let x = Cell::new(10);
        assert_eq!(x.get(), 10);
        x.set(20);
        assert_eq!(x.get(), 20);

        let y = Cell::new((30, 40));
        assert_eq!(y.get(), (30, 40));
    }

    #[test]
    fn double_imm_borrow() {
        let x = RefCell::new(0);
        let _b1 = x.borrow();
        x.borrow();
    }

    #[test]
    fn no_mut_then_imm_borrow() {
        let x = RefCell::new(0);
        let _b1 = x.borrow_mut();
        assert!(x.try_borrow().is_none());
    }

    #[test]
    fn no_imm_then_borrow_mut() {
        let x = RefCell::new(0);
        let _b1 = x.borrow();
        assert!(x.try_borrow_mut().is_none());
    }

    #[test]
    fn no_double_borrow_mut() {
        let x = RefCell::new(0);
        let _b1 = x.borrow_mut();
        assert!(x.try_borrow_mut().is_none());
    }

    #[test]
    fn imm_release_borrow_mut() {
        let x = RefCell::new(0);
        {
            let _b1 = x.borrow();
        }
        x.borrow_mut();
    }

    #[test]
    fn mut_release_borrow_mut() {
        let x = RefCell::new(0);
        {
            let _b1 = x.borrow_mut();
        }
        x.borrow();
    }

    #[test]
    fn double_borrow_single_release_no_borrow_mut() {
        let x = RefCell::new(0);
        let _b1 = x.borrow();
        {
            let _b2 = x.borrow();
        }
        assert!(x.try_borrow_mut().is_none());
    }

    #[test]
    fn with_ok() {
        let x = RefCell::new(0);
        assert_eq!(1, x.with(|x| *x+1));
    }

    #[test]
    #[should_fail]
    fn mut_borrow_with() {
        let x = RefCell::new(0);
        let _b1 = x.borrow_mut();
        x.with(|x| *x+1);
    }

    #[test]
    fn borrow_with() {
        let x = RefCell::new(0);
        let _b1 = x.borrow();
        assert_eq!(1, x.with(|x| *x+1));
    }

    #[test]
    fn with_mut_ok() {
        let x = RefCell::new(0);
        x.with_mut(|x| *x += 1);
        let b = x.borrow();
        assert_eq!(1, *b.get());
    }

    #[test]
    #[should_fail]
    fn borrow_with_mut() {
        let x = RefCell::new(0);
        let _b = x.borrow();
        x.with_mut(|x| *x += 1);
    }

    #[test]
    #[should_fail]
    fn discard_doesnt_unborrow() {
        let x = RefCell::new(0);
        let _b = x.borrow();
        let _ = _b;
        let _b = x.borrow_mut();
    }
}
<commit_msg>libstd: Make a temporary separate `stage0` implementation for `Cell` to avoid a crash in later stages<commit_after>// Copyright 2012-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.

//! Types dealing with dynamic mutability

use prelude::*;
use cast;
use util::NonCopyable;

/// A mutable memory location that admits only `Pod` data.
#[no_freeze]
#[deriving(Clone)]
pub struct Cell<T> {
    priv value: T,
}

#[cfg(stage0)]
impl<T> Cell<T> {
    /// Creates a new `Cell` containing the given value.
    pub fn new(value: T) -> Cell<T> {
        Cell {
            value: value,
        }
    }

    /// Returns a copy of the contained value.
    #[inline]
    pub fn get(&self) -> T {
        unsafe {
            ::cast::transmute_copy(&self.value)
        }
    }

    /// Sets the contained value.
    #[inline]
    pub fn set(&self, value: T) {
        unsafe {
            *cast::transmute_mut(&self.value) = value
        }
    }
}

#[cfg(not(stage0))]
impl<T: ::kinds::Pod> Cell<T> {
    /// Creates a new `Cell` containing the given value.
    pub fn new(value: T) -> Cell<T> {
        Cell {
            value: value,
        }
    }

    /// Returns a copy of the contained value.
    #[inline]
    pub fn get(&self) -> T {
        self.value
    }

    /// Sets the contained value.
    #[inline]
    pub fn set(&self, value: T) {
        unsafe {
            *cast::transmute_mut(&self.value) = value
        }
    }
}

/// A mutable memory location with dynamically checked borrow rules
#[no_freeze]
pub struct RefCell<T> {
    priv value: T,
    priv borrow: BorrowFlag,
    priv nc: NonCopyable
}

// Values [1, MAX-1] represent the number of `Ref` active
// (will not outgrow its range since `uint` is the size of the address space)
type BorrowFlag = uint;
static UNUSED: BorrowFlag = 0;
static WRITING: BorrowFlag = -1;

impl<T> RefCell<T> {
    /// Create a new `RefCell` containing `value`
    pub fn new(value: T) -> RefCell<T> {
        RefCell {
            value: value,
            borrow: UNUSED,
            nc: NonCopyable
        }
    }

    /// Consumes the `RefCell`, returning the wrapped value.
    pub fn unwrap(self) -> T {
        assert!(self.borrow == UNUSED);
        self.value
    }

    unsafe fn as_mut<'a>(&'a self) -> &'a mut RefCell<T> {
        cast::transmute_mut(self)
    }

    /// Attempts to immutably borrow the wrapped value.
    ///
    /// The borrow lasts until the returned `Ref` exits scope. Multiple
    /// immutable borrows can be taken out at the same time.
    ///
    /// Returns `None` if the value is currently mutably borrowed.
    pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
        match self.borrow {
            WRITING => None,
            _ => {
                unsafe { self.as_mut().borrow += 1; }
                Some(Ref { parent: self })
            }
        }
    }

    /// Immutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `Ref` exits scope. Multiple
    /// immutable borrows can be taken out at the same time.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently mutably borrowed.
    pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
        match self.try_borrow() {
            Some(ptr) => ptr,
            None => fail!("RefCell<T> already mutably borrowed")
        }
    }

    /// Mutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `RefMut` exits scope. The value
    /// cannot be borrowed while this borrow is active.
    ///
    /// Returns `None` if the value is currently borrowed.
    pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
        match self.borrow {
            UNUSED => unsafe {
                let mut_self = self.as_mut();
                mut_self.borrow = WRITING;
                Some(RefMut { parent: mut_self })
            },
            _ => None
        }
    }

    /// Mutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `RefMut` exits scope. The value
    /// cannot be borrowed while this borrow is active.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently borrowed.
    pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> {
        match self.try_borrow_mut() {
            Some(ptr) => ptr,
            None => fail!("RefCell<T> already borrowed")
        }
    }

    /// Immutably borrows the wrapped value and applies `blk` to it.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently mutably borrowed.
    #[inline]
    pub fn with<U>(&self, blk: |&T| -> U) -> U {
        let ptr = self.borrow();
        blk(ptr.get())
    }

    /// Mutably borrows the wrapped value and applies `blk` to it.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently borrowed.
    #[inline]
    pub fn with_mut<U>(&self, blk: |&mut T| -> U) -> U {
        let mut ptr = self.borrow_mut();
        blk(ptr.get())
    }

    /// Sets the value, replacing what was there.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently borrowed.
    #[inline]
    pub fn set(&self, value: T) {
        let mut reference = self.borrow_mut();
        *reference.get() = value
    }
}

impl<T:Clone> RefCell<T> {
    /// Returns a copy of the contained value.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently mutably borrowed.
    #[inline]
    pub fn get(&self) -> T {
        let reference = self.borrow();
        (*reference.get()).clone()
    }
}

impl<T: Clone> Clone for RefCell<T> {
    fn clone(&self) -> RefCell<T> {
        let x = self.borrow();
        RefCell::new(x.get().clone())
    }
}

impl<T: DeepClone> DeepClone for RefCell<T> {
    fn deep_clone(&self) -> RefCell<T> {
        let x = self.borrow();
        RefCell::new(x.get().deep_clone())
    }
}

impl<T: Eq> Eq for RefCell<T> {
    fn eq(&self, other: &RefCell<T>) -> bool {
        let a = self.borrow();
        let b = other.borrow();
        a.get() == b.get()
    }
}

/// Wraps a borrowed reference to a value in a `RefCell` box.
pub struct Ref<'b, T> {
    priv parent: &'b RefCell<T>
}

#[unsafe_destructor]
impl<'b, T> Drop for Ref<'b, T> {
    fn drop(&mut self) {
        assert!(self.parent.borrow != WRITING && self.parent.borrow != UNUSED);
        unsafe { self.parent.as_mut().borrow -= 1; }
    }
}

impl<'b, T> Ref<'b, T> {
    /// Retrieve an immutable reference to the stored value.
    #[inline]
    pub fn get<'a>(&'a self) -> &'a T {
        &self.parent.value
    }
}

/// Wraps a mutable borrowed reference to a value in a `RefCell` box.
pub struct RefMut<'b, T> {
    priv parent: &'b mut RefCell<T>
}

#[unsafe_destructor]
impl<'b, T> Drop for RefMut<'b, T> {
    fn drop(&mut self) {
        assert!(self.parent.borrow == WRITING);
        self.parent.borrow = UNUSED;
    }
}

impl<'b, T> RefMut<'b, T> {
    /// Retrieve a mutable reference to the stored value.
    #[inline]
    pub fn get<'a>(&'a mut self) -> &'a mut T {
        &mut self.parent.value
    }
}

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

    #[test]
    fn smoketest_cell() {
        let x = Cell::new(10);
        assert_eq!(x.get(), 10);
        x.set(20);
        assert_eq!(x.get(), 20);

        let y = Cell::new((30, 40));
        assert_eq!(y.get(), (30, 40));
    }

    #[test]
    fn double_imm_borrow() {
        let x = RefCell::new(0);
        let _b1 = x.borrow();
        x.borrow();
    }

    #[test]
    fn no_mut_then_imm_borrow() {
        let x = RefCell::new(0);
        let _b1 = x.borrow_mut();
        assert!(x.try_borrow().is_none());
    }

    #[test]
    fn no_imm_then_borrow_mut() {
        let x = RefCell::new(0);
        let _b1 = x.borrow();
        assert!(x.try_borrow_mut().is_none());
    }

    #[test]
    fn no_double_borrow_mut() {
        let x = RefCell::new(0);
        let _b1 = x.borrow_mut();
        assert!(x.try_borrow_mut().is_none());
    }

    #[test]
    fn imm_release_borrow_mut() {
        let x = RefCell::new(0);
        {
            let _b1 = x.borrow();
        }
        x.borrow_mut();
    }

    #[test]
    fn mut_release_borrow_mut() {
        let x = RefCell::new(0);
        {
            let _b1 = x.borrow_mut();
        }
        x.borrow();
    }

    #[test]
    fn double_borrow_single_release_no_borrow_mut() {
        let x = RefCell::new(0);
        let _b1 = x.borrow();
        {
            let _b2 = x.borrow();
        }
        assert!(x.try_borrow_mut().is_none());
    }

    #[test]
    fn with_ok() {
        let x = RefCell::new(0);
        assert_eq!(1, x.with(|x| *x+1));
    }

    #[test]
    #[should_fail]
    fn mut_borrow_with() {
        let x = RefCell::new(0);
        let _b1 = x.borrow_mut();
        x.with(|x| *x+1);
    }

    #[test]
    fn borrow_with() {
        let x = RefCell::new(0);
        let _b1 = x.borrow();
        assert_eq!(1, x.with(|x| *x+1));
    }

    #[test]
    fn with_mut_ok() {
        let x = RefCell::new(0);
        x.with_mut(|x| *x += 1);
        let b = x.borrow();
        assert_eq!(1, *b.get());
    }

    #[test]
    #[should_fail]
    fn borrow_with_mut() {
        let x = RefCell::new(0);
        let _b = x.borrow();
        x.with_mut(|x| *x += 1);
    }

    #[test]
    #[should_fail]
    fn discard_doesnt_unborrow() {
        let x = RefCell::new(0);
        let _b = x.borrow();
        let _ = _b;
        let _b = x.borrow_mut();
    }
}
<|endoftext|>


<commit_before><commit_msg>#1 - dangling operators no longer cause panics, but instead report unexpected end of input.<commit_after><|endoftext|>


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

#![crate_name = "foo"]

mod private {
    pub enum Enum{Variant}
}
pub use self::private::Enum::*;

// @!has foo/index.html '//a/@href' './private/index.html'
<commit_msg>Fix issue-46767 test<commit_after>// Copyright 2017 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.

#![crate_name = "foo"]

mod private {
    pub enum Enum{Variant}
}
pub use self::private::Enum::*;

// @!has-dir foo/private
// @!has foo/index.html '//a/@href' 'private/index.html'
<|endoftext|>


<commit_before><commit_msg>Move systems and stores into Engine as state<commit_after><|endoftext|>


<commit_before><commit_msg>Add Swap Unit Type<commit_after><|endoftext|>


<commit_before><commit_msg>Added files via upload<commit_after>//
//
use std::env;

#[cfg(unix)]
fn is_executable() {
   println!("is unix");
   }
#[cfg(windows)]
fn is_executable() {
   println!("is windows");
   }

pub fn pargs() {
    for (key,value) in env::vars_os() {
    println!("{:?}: {:?}", key, value);
    }
}

fn main() {
pargs();
is_executable();
println!("Hallo World");
}

#[test]
fn its_really_works() {
}
<|endoftext|>


<commit_before><commit_msg>Fix call parsing, was missing every other argument<commit_after><|endoftext|>


<commit_before>use Renderable;
use LiquidOptions;
use value::Value;
use variable::Variable;
use text::Text;
use std::slice::Iter;
use output::Output;
use output::FilterPrototype;
use output::VarOrVal;
use lexer::Token;
use lexer::Token::{Identifier, Colon, Pipe, StringLiteral};
use lexer::Element;
use lexer::Element::{Expression, Tag, Raw};

pub fn parse<'a> (elements: Vec<Element>, options: &'a LiquidOptions) -> Vec<Box<Renderable + 'a>> {
    let mut ret = vec![];
    let mut iter = elements.iter();
    let mut token = iter.next();
    while token.is_some() {
        match token.unwrap() {
            &Expression(ref tokens,_) => ret.push(parse_expression(tokens, options)),
            &Tag(ref tokens,_) => ret.push(parse_tag(&mut iter, tokens, options)),
            &Raw(ref x) => ret.push(box Text::new(&x[]) as Box<Renderable>)
        }
        token = iter.next();
    }
    ret
}

// creates an expression, which wraps everything that gets rendered
fn parse_expression<'a> (tokens: &Vec<Token>, options: &'a LiquidOptions) -> Box<Renderable + 'a> {
    match tokens[0] {
        Identifier(ref x) if options.tags.contains_key(&x.to_string()) => {
            options.tags.get(x).unwrap().initialize(&x[], tokens.tail(), options)
        },
        _ => parse_output(tokens, options),
    }
}

// creates an output, basically a wrapper around values, variables and filters
fn parse_output<'a> (tokens: &Vec<Token>, options: &'a LiquidOptions) -> Box<Renderable + 'a> {
    let entry = match tokens[0] {
        Identifier(ref x) => VarOrVal::Var(Variable::new(&x[])),
        StringLiteral(ref x) => VarOrVal::Val(Value::Str(x.to_string())),
        // TODO implement warnings/errors
        ref x => panic!("parse_output: {:?} not implemented", x)
    };

    println!("{:?}", tokens);
    let mut filters = vec![];
    let mut iter = tokens.iter().peekable();
    iter.next();

    while !iter.is_empty() {
        if iter.next().unwrap() != &Pipe{
            panic!("parse_output: expected a pipe");
        }
        let name = match iter.next(){
            Some(&Identifier(ref name)) => name,
            // TODO implement warnings/errors
            ref x => panic!("parse_output: expected an Identifier, got {:?}", x)
        };
        let mut args = vec![];

        match iter.peek()  {
            Some(&&Pipe) | None => {
                filters.push(FilterPrototype::new(&name[], args));
                continue;
            }
            _ => ()
        };

        if iter.peek().unwrap() != &&Colon{
            panic!("parse_output: expected a colon");
        }

        while !iter.is_empty() && iter.peek().unwrap() != &&Pipe{
            match iter.next().unwrap(){
                &StringLiteral(ref x) => args.push(Value::Str(x.to_string())),
                ref x => panic!("parse_output: {:?} not implemented", x)
            };
        }

        filters.push(FilterPrototype::new(&name[], args));
    }

    println!("{:?}", filters);

    box Output::new(entry, filters) as Box<Renderable>
}

// a tag can be either a single-element tag or a block, which can contain other elements
// and is delimited by a closing tag named {{end + the_name_of_the_tag}}
// tags do not get rendered, but blocks may contain renderable expressions
fn parse_tag<'a> (iter: &mut Iter<Element>, tokens: &Vec<Token>, options: &'a LiquidOptions) -> Box<Renderable + 'a> {
    match tokens[0] {

        // is a tag
        Identifier(ref x) if options.tags.contains_key(x) => {
            options.tags.get(x).unwrap().initialize(&x[], tokens.tail(), options)
        },

        // is a block
        Identifier(ref x) if options.blocks.contains_key(x) => {
            let end_tag = Identifier("end".to_string() + &x[]);
            let mut children = vec![];
            loop {
                children.push(match iter.next() {
                    Some(&Tag(ref tokens,_)) if tokens[0] == end_tag => break,
                    None => break,
                    Some(t) => t.clone(),
                })
            }
            options.blocks.get(x).unwrap().initialize(&x[], tokens.tail(), children, options)
        },

        // TODO implement warnings/errors
        ref x => panic!("parse_tag: {:?} not implemented", x)
    }
}

<commit_msg>Remove debug statements<commit_after>use Renderable;
use LiquidOptions;
use value::Value;
use variable::Variable;
use text::Text;
use std::slice::Iter;
use output::Output;
use output::FilterPrototype;
use output::VarOrVal;
use lexer::Token;
use lexer::Token::{Identifier, Colon, Pipe, StringLiteral};
use lexer::Element;
use lexer::Element::{Expression, Tag, Raw};

pub fn parse<'a> (elements: Vec<Element>, options: &'a LiquidOptions) -> Vec<Box<Renderable + 'a>> {
    let mut ret = vec![];
    let mut iter = elements.iter();
    let mut token = iter.next();
    while token.is_some() {
        match token.unwrap() {
            &Expression(ref tokens,_) => ret.push(parse_expression(tokens, options)),
            &Tag(ref tokens,_) => ret.push(parse_tag(&mut iter, tokens, options)),
            &Raw(ref x) => ret.push(box Text::new(&x[]) as Box<Renderable>)
        }
        token = iter.next();
    }
    ret
}

// creates an expression, which wraps everything that gets rendered
fn parse_expression<'a> (tokens: &Vec<Token>, options: &'a LiquidOptions) -> Box<Renderable + 'a> {
    match tokens[0] {
        Identifier(ref x) if options.tags.contains_key(&x.to_string()) => {
            options.tags.get(x).unwrap().initialize(&x[], tokens.tail(), options)
        },
        _ => parse_output(tokens, options),
    }
}

// creates an output, basically a wrapper around values, variables and filters
fn parse_output<'a> (tokens: &Vec<Token>, options: &'a LiquidOptions) -> Box<Renderable + 'a> {
    let entry = match tokens[0] {
        Identifier(ref x) => VarOrVal::Var(Variable::new(&x[])),
        StringLiteral(ref x) => VarOrVal::Val(Value::Str(x.to_string())),
        // TODO implement warnings/errors
        ref x => panic!("parse_output: {:?} not implemented", x)
    };

    let mut filters = vec![];
    let mut iter = tokens.iter().peekable();
    iter.next();

    while !iter.is_empty() {
        if iter.next().unwrap() != &Pipe{
            panic!("parse_output: expected a pipe");
        }
        let name = match iter.next(){
            Some(&Identifier(ref name)) => name,
            // TODO implement warnings/errors
            ref x => panic!("parse_output: expected an Identifier, got {:?}", x)
        };
        let mut args = vec![];

        match iter.peek()  {
            Some(&&Pipe) | None => {
                filters.push(FilterPrototype::new(&name[], args));
                continue;
            }
            _ => ()
        };

        if iter.peek().unwrap() != &&Colon{
            panic!("parse_output: expected a colon");
        }

        while !iter.is_empty() && iter.peek().unwrap() != &&Pipe{
            match iter.next().unwrap(){
                &StringLiteral(ref x) => args.push(Value::Str(x.to_string())),
                ref x => panic!("parse_output: {:?} not implemented", x)
            };
        }

        filters.push(FilterPrototype::new(&name[], args));
    }

    box Output::new(entry, filters) as Box<Renderable>
}

// a tag can be either a single-element tag or a block, which can contain other elements
// and is delimited by a closing tag named {{end + the_name_of_the_tag}}
// tags do not get rendered, but blocks may contain renderable expressions
fn parse_tag<'a> (iter: &mut Iter<Element>, tokens: &Vec<Token>, options: &'a LiquidOptions) -> Box<Renderable + 'a> {
    match tokens[0] {

        // is a tag
        Identifier(ref x) if options.tags.contains_key(x) => {
            options.tags.get(x).unwrap().initialize(&x[], tokens.tail(), options)
        },

        // is a block
        Identifier(ref x) if options.blocks.contains_key(x) => {
            let end_tag = Identifier("end".to_string() + &x[]);
            let mut children = vec![];
            loop {
                children.push(match iter.next() {
                    Some(&Tag(ref tokens,_)) if tokens[0] == end_tag => break,
                    None => break,
                    Some(t) => t.clone(),
                })
            }
            options.blocks.get(x).unwrap().initialize(&x[], tokens.tail(), children, options)
        },

        // TODO implement warnings/errors
        ref x => panic!("parse_tag: {:?} not implemented", x)
    }
}

<|endoftext|>


<commit_before><commit_msg>[field] use TAB as default delimiter<commit_after><|endoftext|>


<commit_before><commit_msg>Added fn-unused example<commit_after>fn used_function() {}

// `#[allow(dead_code)]` is an attribute that disables the `dead_code` lint
#[allow(dead_code)]
fn unused_function() {}

#[allow(dead_code)]
fn noisy_unused_function() {}
// FIXME ^ Add an attribute to suppress the warning

fn main() {
    used_function();
}
<|endoftext|>


<commit_before><commit_msg>Added gray codes<commit_after>fn gray_encode(integer: uint) -> uint {
	(integer >> 1) ^ integer
}

fn gray_decode(integer: uint) -> uint {
	match integer {
		0 => 0,
		_ => integer ^ gray_decode(integer >> 1)
	}
}

fn main() {
	for i in range(0u,32u) {
		println!("{:2} {:0>5t} {:0>5t} {:2}", i, i, gray_encode(i),
			gray_decode(i));
	}

}<|endoftext|>


<commit_before><commit_msg>time_conversion<commit_after>//https://www.hackerrank.com/challenges/time-conversion

use std::io;
use std::io::prelude::*;

fn main() {
    let stdin = io::stdin();

    let mut time_str = stdin.lock().lines() //iterator over lines in stdin
        .next().unwrap().unwrap().trim().to_string(); //finally it's a string;
    time_str.pop();
    let is_pm = if time_str.pop().unwrap() == 'P' {
        true
    } else {
        false
    };
    let mut time: Vec<_> = time_str.split(':').map(|x| x.parse::<i32>().unwrap()).collect();
    if is_pm {
        if time[0] != 12 {
            time[0] += 12;
        }
    } else if time[0] == 12 {
        time[0] = 0;
    }

    println!("{0:02}:{1:02}:{2:02}", time[0], time[1], time[2]);
}<|endoftext|>


<commit_before><commit_msg>Remove async's dependence on Blocking<commit_after><|endoftext|>


<commit_before>// Copyright 2014 The Gfx-rs Developers.
//
// 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.

//! Command Buffer device interface

use draw_state::target;

use super::{attrib, shade, tex, Resources};

type Offset = u32;
type Size = u32;

/// The place of some data in the data buffer.
#[derive(Clone, Copy, PartialEq, Debug)]
pub struct DataPointer(Offset, Size);

/// A buffer of data accompanying the commands. It can be vertex data, texture
/// updates, uniform blocks, or even some draw states.
pub struct DataBuffer {
    buf: Vec<u8>,
}

impl DataBuffer {
    /// Create a fresh new data buffer.
    pub fn new() -> DataBuffer {
        DataBuffer {
            buf: Vec::new(),
        }
    }

    /// Clear all the data but retain the allocated storage.
    pub fn clear(&mut self) {
        unsafe { self.buf.set_len(0); }
    }

    /// Copy a given structure into the buffer, return the offset and the size.
    #[cfg(unstable)]
    #[inline(always)]
    pub fn add_struct<T: Copy>(&mut self, v: &T) -> DataPointer {
        use std::slice::ref_slice;
        self.add_vec(ref_slice(v))
    }

    /// Copy a given structure into the buffer, return the offset and the size.
    #[cfg(not(unstable))]
    pub fn add_struct<T: Copy>(&mut self, v: &T) -> DataPointer {
        use std::{intrinsics, mem};
        let offset = self.buf.len();
        let size = mem::size_of::<T>();
        self.buf.reserve(size);
        unsafe {
            self.buf.set_len(offset + size);
            intrinsics::copy((v as *const T) as *const u8,
                             &mut self.buf[offset] as *mut u8,
                             size);
        };
        DataPointer(offset as Offset, size as Size)
    }

    /// Copy a given vector slice into the buffer
    pub fn add_vec<T: Copy>(&mut self, v: &[T]) -> DataPointer {
        use std::{intrinsics, mem};
        let offset = self.buf.len();
        let size = mem::size_of::<T>() * v.len();
        self.buf.reserve(size);
        unsafe {
            self.buf.set_len(offset + size);
            intrinsics::copy(v.as_ptr() as *const u8,
                             &mut self.buf[offset] as *mut u8,
                             size);
        }
        DataPointer(offset as Offset, size as Size)
    }

    /// Return a reference to a stored data object.
    pub fn get_ref(&self, data: DataPointer) -> &[u8] {
        let DataPointer(offset, size) = data;
        &self.buf[offset as usize ..offset as usize + size as usize]
    }
}

/// Optional instance parameters
pub type InstanceOption = Option<(super::InstanceCount, super::VertexCount)>;

/// An interface of the abstract command buffer. It collects commands in an
/// efficient API-specific manner, to be ready for execution on the device.
#[allow(missing_docs)]
pub trait CommandBuffer<R: Resources> {
    /// An empty constructor
    fn new() -> Self;
    /// Clear the command buffer contents, retain the allocated storage
    fn clear(&mut self);
    /// Bind a shader program
    fn bind_program(&mut self, R::Program);
    /// Bind an array buffer object
    fn bind_array_buffer(&mut self, R::ArrayBuffer);
    /// Bind a vertex attribute
    fn bind_attribute(&mut self, super::AttributeSlot, R::Buffer, attrib::Format);
    /// Bind an index buffer
    fn bind_index(&mut self, R::Buffer);
    /// Bind a frame buffer object
    fn bind_frame_buffer(&mut self, Access, R::FrameBuffer, Gamma);
    /// Unbind any surface from the specified target slot
    fn unbind_target(&mut self, Access, Target);
    /// Bind a surface to the specified target slot
    fn bind_target_surface(&mut self, Access, Target, R::Surface);
    /// Bind a level of the texture to the specified target slot
    fn bind_target_texture(&mut self, Access, Target, R::Texture,
                           target::Level, Option<target::Layer>);
    /// Bind a uniform block
    fn bind_uniform_block(&mut self, R::Program,
                          super::UniformBufferSlot, super::UniformBlockIndex,
                          R::Buffer);
    /// Bind a single uniform in the default block
    fn bind_uniform(&mut self, shade::Location, shade::UniformValue);
    /// Bind a texture
    fn bind_texture(&mut self, super::TextureSlot, tex::Kind,
                    R::Texture, Option<(R::Sampler, tex::SamplerInfo)>);
    /// Select, which color buffers are going to be targetted by the shader
    fn set_draw_color_buffers(&mut self, usize);
    /// Set primitive topology
    fn set_primitive(&mut self, ::state::Primitive);
    /// Set viewport rectangle
    fn set_viewport(&mut self, target::Rect);
    /// Set multi-sampling state
    fn set_multi_sample(&mut self, Option<::state::MultiSample>);
    /// Set scissor test
    fn set_scissor(&mut self, Option<target::Rect>);
    /// Set depth and stencil states
    fn set_depth_stencil(&mut self, Option<::state::Depth>,
                         Option<::state::Stencil>, ::state::CullFace);
    /// Set blend state
    fn set_blend(&mut self, Option<::state::Blend>);
    /// Set output color mask for all targets
    fn set_color_mask(&mut self, ::state::ColorMask);
    /// Update a vertex/index/uniform buffer
    fn update_buffer(&mut self, R::Buffer, DataPointer, usize);
    /// Update a texture region
    fn update_texture(&mut self, tex::Kind, R::Texture,
                      tex::ImageInfo, DataPointer);
    /// Clear target surfaces
    fn call_clear(&mut self, target::ClearData, target::Mask);
    /// Draw a primitive
    fn call_draw(&mut self, super::PrimitiveType, super::VertexCount,
                 super::VertexCount, InstanceOption);
    /// Draw a primitive with index buffer
    fn call_draw_indexed(&mut self, super::PrimitiveType, super::IndexType,
                         super::VertexCount, super::VertexCount,
                         super::VertexCount, InstanceOption);
    /// Blit from one target to another
    fn call_blit(&mut self, target::Rect, target::Rect, target::Mirror, target::Mask);
}

/// Type of the frame buffer access.
#[repr(u8)]
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum Access {
    /// Draw access
    Draw,
    /// Read access
    Read,
}

/// Type of the gamma transformation for framebuffer writes.
#[repr(u8)]
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum Gamma {
    /// Process in linear color space.
    Original,
    /// Convert to sRGB color space.
    Convert,
}

/// When rendering, each "output" of the fragment shader goes to a specific target. A `Plane` can
/// be bound to a target, causing writes to that target to affect the `Plane`.
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum Target {
    /// Color data.
    ///
    /// # Portability Note
    ///
    /// The device is only required to expose one color target.
    Color(u8),
    /// Depth data.
    Depth,
    /// Stencil data.
    Stencil,
    /// A target for both depth and stencil data at once.
    DepthStencil,
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_data_buffer() {
        let mut buf = super::DataBuffer::new();
        assert_eq!(buf.add_struct(&(0u8, false)), super::DataPointer(0, 2));
        assert_eq!(buf.add_vec(&[5i32, 6i32]), super::DataPointer(2, 8));
    }
}
<commit_msg>Auto merge of #803 - alexcrichton:no-intrinsics, r=kvark<commit_after>// Copyright 2014 The Gfx-rs Developers.
//
// 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.

//! Command Buffer device interface

use draw_state::target;

use super::{attrib, shade, tex, Resources};

type Offset = u32;
type Size = u32;

/// The place of some data in the data buffer.
#[derive(Clone, Copy, PartialEq, Debug)]
pub struct DataPointer(Offset, Size);

/// A buffer of data accompanying the commands. It can be vertex data, texture
/// updates, uniform blocks, or even some draw states.
pub struct DataBuffer {
    buf: Vec<u8>,
}

impl DataBuffer {
    /// Create a fresh new data buffer.
    pub fn new() -> DataBuffer {
        DataBuffer {
            buf: Vec::new(),
        }
    }

    /// Clear all the data but retain the allocated storage.
    pub fn clear(&mut self) {
        unsafe { self.buf.set_len(0); }
    }

    /// Copy a given structure into the buffer, return the offset and the size.
    #[cfg(unstable)]
    #[inline(always)]
    pub fn add_struct<T: Copy>(&mut self, v: &T) -> DataPointer {
        use std::slice::ref_slice;
        self.add_vec(ref_slice(v))
    }

    /// Copy a given structure into the buffer, return the offset and the size.
    #[cfg(not(unstable))]
    pub fn add_struct<T: Copy>(&mut self, v: &T) -> DataPointer {
        use std::{ptr, mem};
        let offset = self.buf.len();
        let size = mem::size_of::<T>();
        self.buf.reserve(size);
        unsafe {
            self.buf.set_len(offset + size);
            ptr::copy((v as *const T) as *const u8,
                             &mut self.buf[offset] as *mut u8,
                             size);
        };
        DataPointer(offset as Offset, size as Size)
    }

    /// Copy a given vector slice into the buffer
    pub fn add_vec<T: Copy>(&mut self, v: &[T]) -> DataPointer {
        use std::{ptr, mem};
        let offset = self.buf.len();
        let size = mem::size_of::<T>() * v.len();
        self.buf.reserve(size);
        unsafe {
            self.buf.set_len(offset + size);
            ptr::copy(v.as_ptr() as *const u8,
                             &mut self.buf[offset] as *mut u8,
                             size);
        }
        DataPointer(offset as Offset, size as Size)
    }

    /// Return a reference to a stored data object.
    pub fn get_ref(&self, data: DataPointer) -> &[u8] {
        let DataPointer(offset, size) = data;
        &self.buf[offset as usize ..offset as usize + size as usize]
    }
}

/// Optional instance parameters
pub type InstanceOption = Option<(super::InstanceCount, super::VertexCount)>;

/// An interface of the abstract command buffer. It collects commands in an
/// efficient API-specific manner, to be ready for execution on the device.
#[allow(missing_docs)]
pub trait CommandBuffer<R: Resources> {
    /// An empty constructor
    fn new() -> Self;
    /// Clear the command buffer contents, retain the allocated storage
    fn clear(&mut self);
    /// Bind a shader program
    fn bind_program(&mut self, R::Program);
    /// Bind an array buffer object
    fn bind_array_buffer(&mut self, R::ArrayBuffer);
    /// Bind a vertex attribute
    fn bind_attribute(&mut self, super::AttributeSlot, R::Buffer, attrib::Format);
    /// Bind an index buffer
    fn bind_index(&mut self, R::Buffer);
    /// Bind a frame buffer object
    fn bind_frame_buffer(&mut self, Access, R::FrameBuffer, Gamma);
    /// Unbind any surface from the specified target slot
    fn unbind_target(&mut self, Access, Target);
    /// Bind a surface to the specified target slot
    fn bind_target_surface(&mut self, Access, Target, R::Surface);
    /// Bind a level of the texture to the specified target slot
    fn bind_target_texture(&mut self, Access, Target, R::Texture,
                           target::Level, Option<target::Layer>);
    /// Bind a uniform block
    fn bind_uniform_block(&mut self, R::Program,
                          super::UniformBufferSlot, super::UniformBlockIndex,
                          R::Buffer);
    /// Bind a single uniform in the default block
    fn bind_uniform(&mut self, shade::Location, shade::UniformValue);
    /// Bind a texture
    fn bind_texture(&mut self, super::TextureSlot, tex::Kind,
                    R::Texture, Option<(R::Sampler, tex::SamplerInfo)>);
    /// Select, which color buffers are going to be targetted by the shader
    fn set_draw_color_buffers(&mut self, usize);
    /// Set primitive topology
    fn set_primitive(&mut self, ::state::Primitive);
    /// Set viewport rectangle
    fn set_viewport(&mut self, target::Rect);
    /// Set multi-sampling state
    fn set_multi_sample(&mut self, Option<::state::MultiSample>);
    /// Set scissor test
    fn set_scissor(&mut self, Option<target::Rect>);
    /// Set depth and stencil states
    fn set_depth_stencil(&mut self, Option<::state::Depth>,
                         Option<::state::Stencil>, ::state::CullFace);
    /// Set blend state
    fn set_blend(&mut self, Option<::state::Blend>);
    /// Set output color mask for all targets
    fn set_color_mask(&mut self, ::state::ColorMask);
    /// Update a vertex/index/uniform buffer
    fn update_buffer(&mut self, R::Buffer, DataPointer, usize);
    /// Update a texture region
    fn update_texture(&mut self, tex::Kind, R::Texture,
                      tex::ImageInfo, DataPointer);
    /// Clear target surfaces
    fn call_clear(&mut self, target::ClearData, target::Mask);
    /// Draw a primitive
    fn call_draw(&mut self, super::PrimitiveType, super::VertexCount,
                 super::VertexCount, InstanceOption);
    /// Draw a primitive with index buffer
    fn call_draw_indexed(&mut self, super::PrimitiveType, super::IndexType,
                         super::VertexCount, super::VertexCount,
                         super::VertexCount, InstanceOption);
    /// Blit from one target to another
    fn call_blit(&mut self, target::Rect, target::Rect, target::Mirror, target::Mask);
}

/// Type of the frame buffer access.
#[repr(u8)]
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum Access {
    /// Draw access
    Draw,
    /// Read access
    Read,
}

/// Type of the gamma transformation for framebuffer writes.
#[repr(u8)]
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum Gamma {
    /// Process in linear color space.
    Original,
    /// Convert to sRGB color space.
    Convert,
}

/// When rendering, each "output" of the fragment shader goes to a specific target. A `Plane` can
/// be bound to a target, causing writes to that target to affect the `Plane`.
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum Target {
    /// Color data.
    ///
    /// # Portability Note
    ///
    /// The device is only required to expose one color target.
    Color(u8),
    /// Depth data.
    Depth,
    /// Stencil data.
    Stencil,
    /// A target for both depth and stencil data at once.
    DepthStencil,
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_data_buffer() {
        let mut buf = super::DataBuffer::new();
        assert_eq!(buf.add_struct(&(0u8, false)), super::DataPointer(0, 2));
        assert_eq!(buf.add_vec(&[5i32, 6i32]), super::DataPointer(2, 8));
    }
}
<|endoftext|>


<commit_before><commit_msg>Factor out lexer error methods<commit_after><|endoftext|>


<commit_before>use std::fmt;
use std::from_str::FromStr;
use std::io;
use std::iter;
use std::slice;

use serialize::{Decodable, Decoder};

use csv;
use csv::index::Indexed;
use docopt;

use util;

pub enum CliError {
    ErrFlag(docopt::Error),
    ErrCsv(csv::Error),
    ErrIo(io::IoError),
    ErrOther(String),
}

impl CliError {
    pub fn from_flags(v: docopt::Error) -> CliError {
        ErrFlag(v)
    }
    pub fn from_csv(v: csv::Error) -> CliError {
        match v {
            csv::ErrIo(v) => CliError::from_io(v),
            v => ErrCsv(v),
        }
    }
    pub fn from_io(v: io::IoError) -> CliError {
        ErrIo(v)
    }
    pub fn from_str<T: ToString>(v: T) -> CliError {
        ErrOther(v.to_string())
    }
}

#[deriving(Clone, Show)]
pub struct Delimiter(pub u8);

/// Delimiter represents values that can be passed from the command line that
/// can be used as a field delimiter in CSV data.
///
/// Its purpose is to ensure that the Unicode character given decodes to a
/// valid ASCII character as required by the CSV parser.
impl Delimiter {
    pub fn to_byte(self) -> u8 {
        let Delimiter(b) = self;
        b
    }

    pub fn as_byte(self) -> u8 {
        let Delimiter(b) = self;
        b
    }
}

impl<E, D: Decoder<E>> Decodable<D, E> for Delimiter {
    fn decode(d: &mut D) -> Result<Delimiter, E> {
        let c = try!(d.read_char());
        match c.to_ascii_opt() {
            Some(ascii) => Ok(Delimiter(ascii.to_byte())),
            None => {
                let msg = format!("Could not convert '{}' \
                                   to ASCII delimiter.", c);
                Err(d.error(msg.as_slice()))
            }
        }
    }
}

pub struct CsvConfig {
    path: Option<Path>, // None implies <stdin>
    idx_path: Option<Path>,
    delimiter: u8,
    no_headers: bool,
    flexible: bool,
    crlf: bool,
}

impl CsvConfig {
    pub fn new(mut path: Option<String>) -> CsvConfig {
        if path.as_ref().map(|p| p.equiv(&"-")) == Some(true) {
            // If the path explicitly wants stdin/stdout, then give it to them.
            path = None;
        }
        CsvConfig {
            path: path.map(|p| Path::new(p)),
            idx_path: None,
            delimiter: b',',
            no_headers: false,
            flexible: false,
            crlf: false,
        }
    }

    pub fn delimiter(mut self, d: Delimiter) -> CsvConfig {
        self.delimiter = d.as_byte();
        self
    }

    pub fn no_headers(mut self, yes: bool) -> CsvConfig {
        self.no_headers = yes;
        self
    }

    pub fn flexible(mut self, yes: bool) -> CsvConfig {
        self.flexible = yes;
        self
    }

    pub fn crlf(mut self, yes: bool) -> CsvConfig {
        self.crlf = yes;
        self
    }

    pub fn is_std(&self) -> bool {
        self.path.is_none()
    }

    pub fn idx_path(mut self, idx_path: Option<String>) -> CsvConfig {
        self.idx_path = idx_path.map(|p| Path::new(p));
        self
    }

    pub fn write_headers<R: io::Reader, W: io::Writer>
                        (&self, r: &mut csv::Reader<R>, w: &mut csv::Writer<W>)
                        -> csv::CsvResult<()> {
        if !self.no_headers {
            try!(w.write_bytes(try!(r.byte_headers()).into_iter()));
        }
        Ok(())
    }

    pub fn writer(&self) -> io::IoResult<csv::Writer<Box<io::Writer+'static>>> {
        Ok(self.from_writer(try!(self.io_writer())))
    }

    pub fn reader(&self) -> io::IoResult<csv::Reader<Box<io::Reader+'static>>> {
        Ok(self.from_reader(try!(self.io_reader())))
    }

    pub fn index_files(&self)
           -> io::IoResult<Option<(csv::Reader<io::File>, io::File)>> {
        let (mut csv_file, mut idx_file) = match (&self.path, &self.idx_path) {
            (&None, &None) => return Ok(None),
            (&None, &Some(ref p)) => return Err(io::IoError {
                kind: io::OtherIoError,
                desc: "Cannot use <stdin> with indexes",
                detail: Some(format!("index file: {}", p.display())),
            }),
            (&Some(ref p), &None) => {
                // We generally don't want to report an error here, since we're
                // passively trying to find an index.
                let idx_file = match io::File::open(&util::idx_path(p)) {
                    // TODO: Maybe we should report an error if the file exists
                    // but is not readable.
                    Err(_) => return Ok(None),
                    Ok(f) => f,
                };
                (try!(io::File::open(p)), idx_file)
            }
            (&Some(ref p), &Some(ref ip)) => {
                (try!(io::File::open(p)), try!(io::File::open(ip)))
            }
        };
        // If the CSV data was last modified after the index file was last
        // modified, then return an error and demand the user regenerate the
        // index.
        let data_modified = try!(csv_file.stat()).modified;
        let idx_modified = try!(idx_file.stat()).modified;
        if data_modified > idx_modified {
            return Err(io::IoError {
                kind: io::OtherIoError,
                desc: "The CSV file was modified after the index file. \
                       Please re-create the index.",
                detail: Some(format!("CSV file: {}, index file: {}",
                                     csv_file.path().display(),
                                     idx_file.path().display())),
            });
        }
        let csv_rdr = self.from_reader(csv_file);
        Ok(Some((csv_rdr, idx_file)))
    }

    pub fn indexed(&self) -> io::IoResult<Option<Indexed<io::File, io::File>>> {
        Ok({ try!(self.index_files()) }.map(|(r, i)| Indexed::new(r, i)))
    }

    pub fn io_reader(&self) -> io::IoResult<Box<io::Reader+'static>> {
        Ok(match self.path {
            None => box io::stdin() as Box<io::Reader+'static>,
            Some(ref p) =>
                box try!(io::File::open(p)) as Box<io::Reader+'static>,
        })
    }

    pub fn from_reader<R: Reader>(&self, rdr: R) -> csv::Reader<R> {
        csv::Reader::from_reader(rdr)
                    .flexible(self.flexible)
                    .delimiter(self.delimiter)
                    .has_headers(!self.no_headers)
    }

    pub fn io_writer(&self) -> io::IoResult<Box<io::Writer+'static>> {
        Ok(match self.path {
            None => box io::stdout() as Box<io::Writer+'static>,
            Some(ref p) =>
                box try!(io::File::create(p)) as Box<io::Writer+'static>,
        })
    }

    pub fn from_writer<W: Writer>(&self, wtr: W) -> csv::Writer<W> {
        csv::Writer::from_writer(wtr)
                    .flexible(self.flexible)
                    .delimiter(self.delimiter)
                    .crlf(self.crlf)
    }
}

pub struct SelectColumns(Vec<Selector>);

// This parser is super basic at the moment. Field names cannot contain [-,].
impl SelectColumns {
    pub fn selection(&self, conf: &CsvConfig, headers: &[csv::ByteString])
                    -> Result<Selection, String> {
        let mut map = vec![];
        for sel in self.selectors().iter() {
            let idxs = sel.indices(conf, headers);
            map.extend(try!(idxs).into_iter());
        }
        Ok(Selection(map))
    }

    fn selectors<'a>(&'a self) -> &'a [Selector] {
        let &SelectColumns(ref sels) = self;
        sels.as_slice()
    }

    fn parse(s: &str) -> Result<SelectColumns, String> {
        let mut sels = vec!();
        if s.is_empty() {
            return Ok(SelectColumns(sels));
        }
        for sel in s.split(',') {
            sels.push(try!(SelectColumns::parse_selector(sel)));
        }
        Ok(SelectColumns(sels))
    }

    fn parse_selector(sel: &str) -> Result<Selector, String> {
        if sel.contains_char('-') {
            let pieces: Vec<&str> = sel.splitn(1, '-').collect();
            let start =
                if pieces[0].is_empty() {
                    SelStart
                } else {
                    try!(SelectColumns::parse_one_selector(pieces[0]))
                };
            let end =
                if pieces[1].is_empty() {
                    SelEnd
                } else {
                    try!(SelectColumns::parse_one_selector(pieces[1]))
                };
            Ok(SelRange(box start, box end))
        } else {
            SelectColumns::parse_one_selector(sel)
        }
    }

    fn parse_one_selector(sel: &str) -> Result<Selector, String> {
        if sel.contains_char('-') {
            return Err(format!("Illegal '-' in selector '{}'.", sel))
        }
        let idx: Option<uint> = FromStr::from_str(sel);
        Ok(match idx {
            None => SelName(sel.to_string()),
            Some(idx) => SelIndex(idx),
        })
    }
}

impl fmt::Show for SelectColumns {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.selectors().is_empty() {
            return write!(f, "<All>");
        }
        let strs: Vec<String> = self.selectors().iter()
                                .map(|sel| sel.to_string())
                                .collect();
        write!(f, "{}", strs.connect(", "))
    }
}

impl <E, D: Decoder<E>> Decodable<D, E> for SelectColumns {
    fn decode(d: &mut D) -> Result<SelectColumns, E> {
        SelectColumns::parse(try!(d.read_str()).as_slice())
                      .map_err(|e| d.error(e.as_slice()))
    }
}

enum Selector {
    SelStart,
    SelEnd,
    SelIndex(uint),
    SelName(String),
    // invariant: selectors MUST NOT be ranges
    SelRange(Box<Selector>, Box<Selector>),
}

impl Selector {
    fn is_range(&self) -> bool {
        match self {
            &SelRange(_, _) => true,
            _ => false,
        }
    }

    fn indices(&self, conf: &CsvConfig, headers: &[csv::ByteString])
              -> Result<Vec<uint>, String> {
        match self {
            &SelStart => Ok(vec!(0)),
            &SelEnd => Ok(vec!(headers.len())),
            &SelIndex(i) => {
                if i < 1 || i > headers.len() {
                    Err(format!("Selector index {} is out of \
                                 bounds. Index must be >= 1 \
                                 and <= {}.", i, headers.len()))
                } else {
                    // Indices given by user are 1-offset. Convert them here!
                    Ok(vec!(i-1))
                }
            }
            &SelName(ref s) => {
                if conf.no_headers {
                    return Err(format!("Cannot use names ('{}') in selection \
                                        with --no-headers set.", s));
                }
                match headers.iter().position(|h| h.equiv(s)) {
                    None => Err(format!("Selector name '{}' does not exist \
                                         as a named header in the given CSV \
                                         data.", s)),
                    Some(i) => Ok(vec!(i)),
                }
            }
            &SelRange(box ref sel1, box ref sel2) => {
                assert!(!sel1.is_range());
                assert!(!sel2.is_range());
                let is1 = try!(sel1.indices(conf, headers));
                let is2 = try!(sel2.indices(conf, headers));
                let i1 = { assert!(is1.len() == 1); is1[0] };
                let i2 = { assert!(is2.len() == 1); is2[0] };
                Ok(match i1.cmp(&i2) {
                    Equal => vec!(i1),
                    Less => iter::range_inclusive(i1, i2).collect(),
                    Greater =>
                        iter::range_step_inclusive(i1 as int, i2 as int, -1)
                             .map(|i| i as uint).collect(),
                })
            }
        }
    }
}

impl fmt::Show for Selector {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &SelStart => write!(f, "Start"),
            &SelEnd => write!(f, "End"),
            &SelName(ref s) => write!(f, "Name({})", s),
            &SelIndex(idx) => write!(f, "Index({:u})", idx),
            &SelRange(ref s, ref e) => write!(f, "Range({}, {})", s, e),
        }
    }
}

#[deriving(Show)]
pub struct Selection(Vec<uint>);

impl Selection {
    pub fn select<'a, 'b>(&'a self, row: &'b [csv::ByteString])
                 -> iter::Scan<&'a uint,
                               &'b [u8],
                               slice::Items<'a, uint>,
                               &'b [csv::ByteString]> {
        // This is horrifying.
        // Help me closure reform, you're my only hope.
        self.as_slice().iter().scan(row, |row, &idx| Some(row[idx].as_slice()))
    }

    pub fn as_slice<'a>(&'a self) -> &'a [uint] {
        let &Selection(ref inds) = self;
        inds.as_slice()
    }
}
<commit_msg>Add a "normalized" selection, which is sorted and contains no duplicates. (This makes it amenable for use with one-pass iterators.)<commit_after>use std::fmt;
use std::from_str::FromStr;
use std::io;
use std::iter;
use std::slice;

use serialize::{Decodable, Decoder};

use csv;
use csv::index::Indexed;
use docopt;

use util;

pub enum CliError {
    ErrFlag(docopt::Error),
    ErrCsv(csv::Error),
    ErrIo(io::IoError),
    ErrOther(String),
}

impl CliError {
    pub fn from_flags(v: docopt::Error) -> CliError {
        ErrFlag(v)
    }
    pub fn from_csv(v: csv::Error) -> CliError {
        match v {
            csv::ErrIo(v) => CliError::from_io(v),
            v => ErrCsv(v),
        }
    }
    pub fn from_io(v: io::IoError) -> CliError {
        ErrIo(v)
    }
    pub fn from_str<T: ToString>(v: T) -> CliError {
        ErrOther(v.to_string())
    }
}

#[deriving(Clone, Show)]
pub struct Delimiter(pub u8);

/// Delimiter represents values that can be passed from the command line that
/// can be used as a field delimiter in CSV data.
///
/// Its purpose is to ensure that the Unicode character given decodes to a
/// valid ASCII character as required by the CSV parser.
impl Delimiter {
    pub fn to_byte(self) -> u8 {
        let Delimiter(b) = self;
        b
    }

    pub fn as_byte(self) -> u8 {
        let Delimiter(b) = self;
        b
    }
}

impl<E, D: Decoder<E>> Decodable<D, E> for Delimiter {
    fn decode(d: &mut D) -> Result<Delimiter, E> {
        let c = try!(d.read_char());
        match c.to_ascii_opt() {
            Some(ascii) => Ok(Delimiter(ascii.to_byte())),
            None => {
                let msg = format!("Could not convert '{}' \
                                   to ASCII delimiter.", c);
                Err(d.error(msg.as_slice()))
            }
        }
    }
}

pub struct CsvConfig {
    path: Option<Path>, // None implies <stdin>
    idx_path: Option<Path>,
    delimiter: u8,
    no_headers: bool,
    flexible: bool,
    crlf: bool,
}

impl CsvConfig {
    pub fn new(mut path: Option<String>) -> CsvConfig {
        if path.as_ref().map(|p| p.equiv(&"-")) == Some(true) {
            // If the path explicitly wants stdin/stdout, then give it to them.
            path = None;
        }
        CsvConfig {
            path: path.map(|p| Path::new(p)),
            idx_path: None,
            delimiter: b',',
            no_headers: false,
            flexible: false,
            crlf: false,
        }
    }

    pub fn delimiter(mut self, d: Delimiter) -> CsvConfig {
        self.delimiter = d.as_byte();
        self
    }

    pub fn no_headers(mut self, yes: bool) -> CsvConfig {
        self.no_headers = yes;
        self
    }

    pub fn flexible(mut self, yes: bool) -> CsvConfig {
        self.flexible = yes;
        self
    }

    pub fn crlf(mut self, yes: bool) -> CsvConfig {
        self.crlf = yes;
        self
    }

    pub fn is_std(&self) -> bool {
        self.path.is_none()
    }

    pub fn idx_path(mut self, idx_path: Option<String>) -> CsvConfig {
        self.idx_path = idx_path.map(|p| Path::new(p));
        self
    }

    pub fn write_headers<R: io::Reader, W: io::Writer>
                        (&self, r: &mut csv::Reader<R>, w: &mut csv::Writer<W>)
                        -> csv::CsvResult<()> {
        if !self.no_headers {
            try!(w.write_bytes(try!(r.byte_headers()).into_iter()));
        }
        Ok(())
    }

    pub fn writer(&self) -> io::IoResult<csv::Writer<Box<io::Writer+'static>>> {
        Ok(self.from_writer(try!(self.io_writer())))
    }

    pub fn reader(&self) -> io::IoResult<csv::Reader<Box<io::Reader+'static>>> {
        Ok(self.from_reader(try!(self.io_reader())))
    }

    pub fn index_files(&self)
           -> io::IoResult<Option<(csv::Reader<io::File>, io::File)>> {
        let (mut csv_file, mut idx_file) = match (&self.path, &self.idx_path) {
            (&None, &None) => return Ok(None),
            (&None, &Some(ref p)) => return Err(io::IoError {
                kind: io::OtherIoError,
                desc: "Cannot use <stdin> with indexes",
                detail: Some(format!("index file: {}", p.display())),
            }),
            (&Some(ref p), &None) => {
                // We generally don't want to report an error here, since we're
                // passively trying to find an index.
                let idx_file = match io::File::open(&util::idx_path(p)) {
                    // TODO: Maybe we should report an error if the file exists
                    // but is not readable.
                    Err(_) => return Ok(None),
                    Ok(f) => f,
                };
                (try!(io::File::open(p)), idx_file)
            }
            (&Some(ref p), &Some(ref ip)) => {
                (try!(io::File::open(p)), try!(io::File::open(ip)))
            }
        };
        // If the CSV data was last modified after the index file was last
        // modified, then return an error and demand the user regenerate the
        // index.
        let data_modified = try!(csv_file.stat()).modified;
        let idx_modified = try!(idx_file.stat()).modified;
        if data_modified > idx_modified {
            return Err(io::IoError {
                kind: io::OtherIoError,
                desc: "The CSV file was modified after the index file. \
                       Please re-create the index.",
                detail: Some(format!("CSV file: {}, index file: {}",
                                     csv_file.path().display(),
                                     idx_file.path().display())),
            });
        }
        let csv_rdr = self.from_reader(csv_file);
        Ok(Some((csv_rdr, idx_file)))
    }

    pub fn indexed(&self) -> io::IoResult<Option<Indexed<io::File, io::File>>> {
        Ok({ try!(self.index_files()) }.map(|(r, i)| Indexed::new(r, i)))
    }

    pub fn io_reader(&self) -> io::IoResult<Box<io::Reader+'static>> {
        Ok(match self.path {
            None => box io::stdin() as Box<io::Reader+'static>,
            Some(ref p) =>
                box try!(io::File::open(p)) as Box<io::Reader+'static>,
        })
    }

    pub fn from_reader<R: Reader>(&self, rdr: R) -> csv::Reader<R> {
        csv::Reader::from_reader(rdr)
                    .flexible(self.flexible)
                    .delimiter(self.delimiter)
                    .has_headers(!self.no_headers)
    }

    pub fn io_writer(&self) -> io::IoResult<Box<io::Writer+'static>> {
        Ok(match self.path {
            None => box io::stdout() as Box<io::Writer+'static>,
            Some(ref p) =>
                box try!(io::File::create(p)) as Box<io::Writer+'static>,
        })
    }

    pub fn from_writer<W: Writer>(&self, wtr: W) -> csv::Writer<W> {
        csv::Writer::from_writer(wtr)
                    .flexible(self.flexible)
                    .delimiter(self.delimiter)
                    .crlf(self.crlf)
    }
}

pub struct SelectColumns(Vec<Selector>);

// This parser is super basic at the moment. Field names cannot contain [-,].
impl SelectColumns {
    pub fn selection(&self, conf: &CsvConfig, headers: &[csv::ByteString])
                    -> Result<Selection, String> {
        let mut map = vec![];
        for sel in self.selectors().iter() {
            let idxs = sel.indices(conf, headers);
            map.extend(try!(idxs).into_iter());
        }
        Ok(Selection(map))
    }

    pub fn merge(&mut self, scols: SelectColumns) {
        let &SelectColumns(ref mut sels1) = self;
        let SelectColumns(sels2) = scols;
        sels1.extend(sels2.into_iter());
    }

    fn selectors<'a>(&'a self) -> &'a [Selector] {
        let &SelectColumns(ref sels) = self;
        sels.as_slice()
    }

    fn parse(s: &str) -> Result<SelectColumns, String> {
        let mut sels = vec!();
        if s.is_empty() {
            return Ok(SelectColumns(sels));
        }
        for sel in s.split(',') {
            sels.push(try!(SelectColumns::parse_selector(sel)));
        }
        Ok(SelectColumns(sels))
    }

    fn parse_selector(sel: &str) -> Result<Selector, String> {
        if sel.contains_char('-') {
            let pieces: Vec<&str> = sel.splitn(1, '-').collect();
            let start =
                if pieces[0].is_empty() {
                    SelStart
                } else {
                    try!(SelectColumns::parse_one_selector(pieces[0]))
                };
            let end =
                if pieces[1].is_empty() {
                    SelEnd
                } else {
                    try!(SelectColumns::parse_one_selector(pieces[1]))
                };
            Ok(SelRange(box start, box end))
        } else {
            SelectColumns::parse_one_selector(sel)
        }
    }

    fn parse_one_selector(sel: &str) -> Result<Selector, String> {
        if sel.contains_char('-') {
            return Err(format!("Illegal '-' in selector '{}'.", sel))
        }
        let idx: Option<uint> = FromStr::from_str(sel);
        Ok(match idx {
            None => SelName(sel.to_string()),
            Some(idx) => SelIndex(idx),
        })
    }
}

impl fmt::Show for SelectColumns {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.selectors().is_empty() {
            return write!(f, "<All>");
        }
        let strs: Vec<String> = self.selectors().iter()
                                .map(|sel| sel.to_string())
                                .collect();
        write!(f, "{}", strs.connect(", "))
    }
}

impl <E, D: Decoder<E>> Decodable<D, E> for SelectColumns {
    fn decode(d: &mut D) -> Result<SelectColumns, E> {
        SelectColumns::parse(try!(d.read_str()).as_slice())
                      .map_err(|e| d.error(e.as_slice()))
    }
}

enum Selector {
    SelStart,
    SelEnd,
    SelIndex(uint),
    SelName(String),
    // invariant: selectors MUST NOT be ranges
    SelRange(Box<Selector>, Box<Selector>),
}

impl Selector {
    fn is_range(&self) -> bool {
        match self {
            &SelRange(_, _) => true,
            _ => false,
        }
    }

    fn indices(&self, conf: &CsvConfig, headers: &[csv::ByteString])
              -> Result<Vec<uint>, String> {
        match self {
            &SelStart => Ok(vec!(0)),
            &SelEnd => Ok(vec!(headers.len())),
            &SelIndex(i) => {
                if i < 1 || i > headers.len() {
                    Err(format!("Selector index {} is out of \
                                 bounds. Index must be >= 1 \
                                 and <= {}.", i, headers.len()))
                } else {
                    // Indices given by user are 1-offset. Convert them here!
                    Ok(vec!(i-1))
                }
            }
            &SelName(ref s) => {
                if conf.no_headers {
                    return Err(format!("Cannot use names ('{}') in selection \
                                        with --no-headers set.", s));
                }
                match headers.iter().position(|h| h.equiv(s)) {
                    None => Err(format!("Selector name '{}' does not exist \
                                         as a named header in the given CSV \
                                         data.", s)),
                    Some(i) => Ok(vec!(i)),
                }
            }
            &SelRange(box ref sel1, box ref sel2) => {
                assert!(!sel1.is_range());
                assert!(!sel2.is_range());
                let is1 = try!(sel1.indices(conf, headers));
                let is2 = try!(sel2.indices(conf, headers));
                let i1 = { assert!(is1.len() == 1); is1[0] };
                let i2 = { assert!(is2.len() == 1); is2[0] };
                Ok(match i1.cmp(&i2) {
                    Equal => vec!(i1),
                    Less => iter::range_inclusive(i1, i2).collect(),
                    Greater =>
                        iter::range_step_inclusive(i1 as int, i2 as int, -1)
                             .map(|i| i as uint).collect(),
                })
            }
        }
    }
}

impl fmt::Show for Selector {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &SelStart => write!(f, "Start"),
            &SelEnd => write!(f, "End"),
            &SelName(ref s) => write!(f, "Name({})", s),
            &SelIndex(idx) => write!(f, "Index({:u})", idx),
            &SelRange(ref s, ref e) => write!(f, "Range({}, {})", s, e),
        }
    }
}

#[deriving(Show)]
pub struct Selection(Vec<uint>);

impl Selection {
    pub fn select<'a, 'b>(&'a self, row: &'b [csv::ByteString])
                 -> iter::Scan<&'a uint,
                               &'b [u8],
                               slice::Items<'a, uint>,
                               &'b [csv::ByteString]> {
        // This is horrifying.
        // Help me closure reform, you're my only hope.
        self.as_slice().iter().scan(row, |row, &idx| Some(row[idx].as_slice()))
    }

    pub fn normalized(&self) -> NormalSelection {
        let &Selection(ref inds) = self;
        let mut normal = inds.clone();
        normal.sort();
        normal.dedup();
        let mut set = Vec::from_elem(normal[normal.len()-1] + 1, false);
        for i in normal.into_iter() {
            *set.get_mut(i) = true;
        }
        NormalSelection(set)
    }

    pub fn as_slice<'a>(&'a self) -> &'a [uint] {
        let &Selection(ref inds) = self;
        inds.as_slice()
    }
}

impl Collection for Selection {
    fn len(&self) -> uint {
        let &Selection(ref inds) = self;
        inds.len()
    }
}

#[deriving(Show)]
pub struct NormalSelection(Vec<bool>);

impl NormalSelection {
    pub fn select<'a, 'b, T, I: Iterator<T>>(&'a self, row: I)
                 -> iter::FilterMap<Option<T>, T,
                                    iter::Scan<(uint, T),
                                               Option<T>,
                                               iter::Enumerate<I>,
                                               &'a [bool]>> {
        let set = self.as_slice();
        row.enumerate().scan(set, |set, (i, v)| {
            if i < set.len() && set[i] { Some(Some(v)) } else { Some(None) }
        }).filter_map(|v| v)
    }

    pub fn selected(&self, i: uint) -> bool {
        self.as_slice()[i]
    }

    pub fn as_slice<'a>(&'a self) -> &'a [bool] {
        let &NormalSelection(ref inds) = self;
        inds.as_slice()
    }
}
<|endoftext|>


<commit_before><commit_msg>chore: dijkstra<commit_after><|endoftext|>


<commit_before><commit_msg>Implement lex_comment.<commit_after><|endoftext|>


<commit_before><commit_msg>Create main.rs<commit_after>use std::env;

#[derive(Debug)]
pub enum ATree {
    ABranch(Vec<ATree>),
    ALeaf(String),
}

fn parse_ast<'a>(tokens: &'a [&'a str]) -> (ATree, &'a [&'a str]) {
    let head = tokens[0];
    if head == "(" {
        let mut state = Vec::new();
        let mut current = tokens[0];
        let mut rest = &tokens[1..];
        while current != ")" {
            let (node, tmp) = parse_ast(rest);
            rest = tmp;
            current = rest[0];
            state.push(node);
        }
        return (ATree::ABranch(state), &rest[1..]);
    } else if head == ")" {
        panic!("expected expression, but found ')'.")
    } else {
        return (ATree::ALeaf(head.to_string()), &tokens[1..]);
    }
}

fn eval_ast(tree: &ATree) -> f64 {
    match tree {
        ATree::ABranch(stuff) => {
            match &stuff[0] {
                ATree::ABranch(_) => {
                    panic!("lambda functions aren't supported");
                }
                ATree::ALeaf(x) => {
                    match &x[..] {
                        "+" => {
                            return stuff[1..].iter()
                                .map(|x| eval_ast(x))
                                .sum();
                        }
                        "-" => {
                            return eval_ast(&stuff[1]) - eval_ast(&stuff[2]);
                        }
                        _ => panic!("unknown operation {:?}", x)
                    }
                }
            }
            213.11
        }
        ATree::ALeaf(x) => {
            let four: f64 = x.parse().unwrap();
            return four;
        }
    }
}

fn main() {
    let input = "(+ 1 2(- 3 4))";

    let tokens0 = input
        .replace("(", " ( ")
        .replace(")", " ) ");

    let tokens1 = tokens0
        .split_ascii_whitespace()
        .collect::<Vec<_>>();

    let (result, rest) = parse_ast(&tokens1.as_slice());

    println!("result = {:?}", result);
    println!("rest = {:?}", rest);
    println!("eval = {:?}", eval_ast(&result));
}
<|endoftext|>


<commit_before>// Copyright 2012 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 core::prelude::*;

use codemap::{Pos, span};
use codemap;

use core::cmp;
use core::io::WriterUtil;
use core::io;
use core::option;
use core::str;
use core::vec;
use core::dvec::DVec;

use std::term;

pub type Emitter = fn@(cmsp: Option<(@codemap::CodeMap, span)>,
                   msg: &str, lvl: level);

pub trait span_handler {
    fn span_fatal(@mut self, sp: span, msg: &str) -> !;
    fn span_err(@mut self, sp: span, msg: &str);
    fn span_warn(@mut self, sp: span, msg: &str);
    fn span_note(@mut self, sp: span, msg: &str);
    fn span_bug(@mut self, sp: span, msg: &str) -> !;
    fn span_unimpl(@mut self, sp: span, msg: &str) -> !;
    fn handler(@mut self) -> handler;
}

pub trait handler {
    fn fatal(@mut self, msg: &str) -> !;
    fn err(@mut self, msg: &str);
    fn bump_err_count(@mut self);
    fn has_errors(@mut self) -> bool;
    fn abort_if_errors(@mut self);
    fn warn(@mut self, msg: &str);
    fn note(@mut self, msg: &str);
    fn bug(@mut self, msg: &str) -> !;
    fn unimpl(@mut self, msg: &str) -> !;
    fn emit(@mut self,
            cmsp: Option<(@codemap::CodeMap, span)>,
            msg: &str,
            lvl: level);
}

struct HandlerT {
    err_count: uint,
    emit: Emitter,
}

struct CodemapT {
    handler: handler,
    cm: @codemap::CodeMap,
}

impl CodemapT: span_handler {
    fn span_fatal(@mut self, sp: span, msg: &str) -> ! {
        self.handler.emit(Some((self.cm, sp)), msg, fatal);
        die!();
    }
    fn span_err(@mut self, sp: span, msg: &str) {
        self.handler.emit(Some((self.cm, sp)), msg, error);
        self.handler.bump_err_count();
    }
    fn span_warn(@mut self, sp: span, msg: &str) {
        self.handler.emit(Some((self.cm, sp)), msg, warning);
    }
    fn span_note(@mut self, sp: span, msg: &str) {
        self.handler.emit(Some((self.cm, sp)), msg, note);
    }
    fn span_bug(@mut self, sp: span, msg: &str) -> ! {
        self.span_fatal(sp, ice_msg(msg));
    }
    fn span_unimpl(@mut self, sp: span, msg: &str) -> ! {
        self.span_bug(sp, ~"unimplemented " + msg);
    }
    fn handler(@mut self) -> handler {
        self.handler
    }
}

impl HandlerT: handler {
    fn fatal(@mut self, msg: &str) -> ! {
        (self.emit)(None, msg, fatal);
        die!();
    }
    fn err(@mut self, msg: &str) {
        (self.emit)(None, msg, error);
        self.bump_err_count();
    }
    fn bump_err_count(@mut self) {
        self.err_count += 1u;
    }
    fn has_errors(@mut self) -> bool { self.err_count > 0u }
    fn abort_if_errors(@mut self) {
        let s;
        match self.err_count {
          0u => return,
          1u => s = ~"aborting due to previous error",
          _  => {
            s = fmt!("aborting due to %u previous errors",
                     self.err_count);
          }
        }
        self.fatal(s);
    }
    fn warn(@mut self, msg: &str) {
        (self.emit)(None, msg, warning);
    }
    fn note(@mut self, msg: &str) {
        (self.emit)(None, msg, note);
    }
    fn bug(@mut self, msg: &str) -> ! {
        self.fatal(ice_msg(msg));
    }
    fn unimpl(@mut self, msg: &str) -> ! {
        self.bug(~"unimplemented " + msg);
    }
    fn emit(@mut self,
            cmsp: Option<(@codemap::CodeMap, span)>,
            msg: &str,
            lvl: level) {
        (self.emit)(cmsp, msg, lvl);
    }
}

pub fn ice_msg(msg: &str) -> ~str {
    fmt!("internal compiler error: %s", msg)
}

pub fn mk_span_handler(handler: handler, cm: @codemap::CodeMap)
                    -> span_handler {
    @mut CodemapT { handler: handler, cm: cm } as @span_handler
}

pub fn mk_handler(emitter: Option<Emitter>) -> @handler {
    let emit: Emitter = match emitter {
        Some(e) => e,
        None => {
            let emit: Emitter = |cmsp, msg, t| emit(cmsp, msg, t);
            emit
        }
    };

    @mut HandlerT { mut err_count: 0, emit: emit } as @handler
}

#[deriving_eq]
pub enum level {
    fatal,
    error,
    warning,
    note,
}

fn diagnosticstr(lvl: level) -> ~str {
    match lvl {
        fatal => ~"error",
        error => ~"error",
        warning => ~"warning",
        note => ~"note"
    }
}

fn diagnosticcolor(lvl: level) -> u8 {
    match lvl {
        fatal => term::color_bright_red,
        error => term::color_bright_red,
        warning => term::color_bright_yellow,
        note => term::color_bright_green
    }
}

fn print_diagnostic(topic: ~str, lvl: level, msg: &str) {
    let use_color = term::color_supported() &&
        io::stderr().get_type() == io::Screen;
    if !topic.is_empty() {
        io::stderr().write_str(fmt!("%s ", topic));
    }
    if use_color {
        term::fg(io::stderr(), diagnosticcolor(lvl));
    }
    io::stderr().write_str(fmt!("%s:", diagnosticstr(lvl)));
    if use_color {
        term::reset(io::stderr());
    }
    io::stderr().write_str(fmt!(" %s\n", msg));
}

pub fn collect(messages: @DVec<~str>)
    -> fn@(Option<(@codemap::CodeMap, span)>, &str, level)
{
    let f: @fn(Option<(@codemap::CodeMap, span)>, &str, level) =
        |_o, msg: &str, _l| { messages.push(msg.to_str()); };
    f
}

pub fn emit(cmsp: Option<(@codemap::CodeMap, span)>, msg: &str, lvl: level) {
    match cmsp {
      Some((cm, sp)) => {
        let sp = cm.adjust_span(sp);
        let ss = cm.span_to_str(sp);
        let lines = cm.span_to_lines(sp);
        print_diagnostic(ss, lvl, msg);
        highlight_lines(cm, sp, lines);
        print_macro_backtrace(cm, sp);
      }
      None => {
        print_diagnostic(~"", lvl, msg);
      }
    }
}

fn highlight_lines(cm: @codemap::CodeMap,
                   sp: span,
                   lines: @codemap::FileLines) {
    let fm = lines.file;

    // arbitrarily only print up to six lines of the error
    let max_lines = 6u;
    let mut elided = false;
    let mut display_lines = /* FIXME (#2543) */ copy lines.lines;
    if vec::len(display_lines) > max_lines {
        display_lines = vec::slice(display_lines, 0u, max_lines);
        elided = true;
    }
    // Print the offending lines
    for display_lines.each |line| {
        io::stderr().write_str(fmt!("%s:%u ", fm.name, *line + 1u));
        let s = fm.get_line(*line as int) + ~"\n";
        io::stderr().write_str(s);
    }
    if elided {
        let last_line = display_lines[vec::len(display_lines) - 1u];
        let s = fmt!("%s:%u ", fm.name, last_line + 1u);
        let mut indent = str::len(s);
        let mut out = ~"";
        while indent > 0u { out += ~" "; indent -= 1u; }
        out += ~"...\n";
        io::stderr().write_str(out);
    }

    // If there's one line at fault we can easily point to the problem
    if vec::len(lines.lines) == 1u {
        let lo = cm.lookup_char_pos(sp.lo);
        let mut digits = 0u;
        let mut num = (lines.lines[0] + 1u) / 10u;

        // how many digits must be indent past?
        while num > 0u { num /= 10u; digits += 1u; }

        // indent past |name:## | and the 0-offset column location
        let mut left = str::len(fm.name) + digits + lo.col.to_uint() + 3u;
        let mut s = ~"";
        while left > 0u { str::push_char(&mut s, ' '); left -= 1u; }

        s += ~"^";
        let hi = cm.lookup_char_pos(sp.hi);
        if hi.col != lo.col {
            // the ^ already takes up one space
            let mut width = hi.col.to_uint() - lo.col.to_uint() - 1u;
            while width > 0u { str::push_char(&mut s, '~'); width -= 1u; }
        }
        io::stderr().write_str(s + ~"\n");
    }
}

fn print_macro_backtrace(cm: @codemap::CodeMap, sp: span) {
    do option::iter(&sp.expn_info) |ei| {
        let ss = option::map_default(&ei.callie.span, @~"",
                                     |span| @cm.span_to_str(*span));
        print_diagnostic(*ss, note,
                         fmt!("in expansion of %s!", ei.callie.name));
        let ss = cm.span_to_str(ei.call_site);
        print_diagnostic(ss, note, ~"expansion site");
        print_macro_backtrace(cm, ei.call_site);
    }
}

pub fn expect<T: Copy>(diag: span_handler,
                       opt: Option<T>,
                       msg: fn() -> ~str) -> T {
    match opt {
       Some(ref t) => (*t),
       None => diag.handler().bug(msg())
    }
}
<commit_msg>Fix for issue 2174<commit_after>// Copyright 2012 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 core::prelude::*;

use codemap::{Pos, span};
use codemap;

use core::cmp;
use core::io::WriterUtil;
use core::io;
use core::option;
use core::str;
use core::vec;
use core::dvec::DVec;

use std::term;

pub type Emitter = fn@(cmsp: Option<(@codemap::CodeMap, span)>,
                   msg: &str, lvl: level);

pub trait span_handler {
    fn span_fatal(@mut self, sp: span, msg: &str) -> !;
    fn span_err(@mut self, sp: span, msg: &str);
    fn span_warn(@mut self, sp: span, msg: &str);
    fn span_note(@mut self, sp: span, msg: &str);
    fn span_bug(@mut self, sp: span, msg: &str) -> !;
    fn span_unimpl(@mut self, sp: span, msg: &str) -> !;
    fn handler(@mut self) -> handler;
}

pub trait handler {
    fn fatal(@mut self, msg: &str) -> !;
    fn err(@mut self, msg: &str);
    fn bump_err_count(@mut self);
    fn has_errors(@mut self) -> bool;
    fn abort_if_errors(@mut self);
    fn warn(@mut self, msg: &str);
    fn note(@mut self, msg: &str);
    fn bug(@mut self, msg: &str) -> !;
    fn unimpl(@mut self, msg: &str) -> !;
    fn emit(@mut self,
            cmsp: Option<(@codemap::CodeMap, span)>,
            msg: &str,
            lvl: level);
}

struct HandlerT {
    err_count: uint,
    emit: Emitter,
}

struct CodemapT {
    handler: handler,
    cm: @codemap::CodeMap,
}

impl CodemapT: span_handler {
    fn span_fatal(@mut self, sp: span, msg: &str) -> ! {
        self.handler.emit(Some((self.cm, sp)), msg, fatal);
        die!();
    }
    fn span_err(@mut self, sp: span, msg: &str) {
        self.handler.emit(Some((self.cm, sp)), msg, error);
        self.handler.bump_err_count();
    }
    fn span_warn(@mut self, sp: span, msg: &str) {
        self.handler.emit(Some((self.cm, sp)), msg, warning);
    }
    fn span_note(@mut self, sp: span, msg: &str) {
        self.handler.emit(Some((self.cm, sp)), msg, note);
    }
    fn span_bug(@mut self, sp: span, msg: &str) -> ! {
        self.span_fatal(sp, ice_msg(msg));
    }
    fn span_unimpl(@mut self, sp: span, msg: &str) -> ! {
        self.span_bug(sp, ~"unimplemented " + msg);
    }
    fn handler(@mut self) -> handler {
        self.handler
    }
}

impl HandlerT: handler {
    fn fatal(@mut self, msg: &str) -> ! {
        (self.emit)(None, msg, fatal);
        die!();
    }
    fn err(@mut self, msg: &str) {
        (self.emit)(None, msg, error);
        self.bump_err_count();
    }
    fn bump_err_count(@mut self) {
        self.err_count += 1u;
    }
    fn has_errors(@mut self) -> bool { self.err_count > 0u }
    fn abort_if_errors(@mut self) {
        let s;
        match self.err_count {
          0u => return,
          1u => s = ~"aborting due to previous error",
          _  => {
            s = fmt!("aborting due to %u previous errors",
                     self.err_count);
          }
        }
        self.fatal(s);
    }
    fn warn(@mut self, msg: &str) {
        (self.emit)(None, msg, warning);
    }
    fn note(@mut self, msg: &str) {
        (self.emit)(None, msg, note);
    }
    fn bug(@mut self, msg: &str) -> ! {
        self.fatal(ice_msg(msg));
    }
    fn unimpl(@mut self, msg: &str) -> ! {
        self.bug(~"unimplemented " + msg);
    }
    fn emit(@mut self,
            cmsp: Option<(@codemap::CodeMap, span)>,
            msg: &str,
            lvl: level) {
        (self.emit)(cmsp, msg, lvl);
    }
}

pub fn ice_msg(msg: &str) -> ~str {
    fmt!("internal compiler error: %s", msg)
}

pub fn mk_span_handler(handler: handler, cm: @codemap::CodeMap)
                    -> span_handler {
    @mut CodemapT { handler: handler, cm: cm } as @span_handler
}

pub fn mk_handler(emitter: Option<Emitter>) -> @handler {
    let emit: Emitter = match emitter {
        Some(e) => e,
        None => {
            let emit: Emitter = |cmsp, msg, t| emit(cmsp, msg, t);
            emit
        }
    };

    @mut HandlerT { mut err_count: 0, emit: emit } as @handler
}

#[deriving_eq]
pub enum level {
    fatal,
    error,
    warning,
    note,
}

fn diagnosticstr(lvl: level) -> ~str {
    match lvl {
        fatal => ~"error",
        error => ~"error",
        warning => ~"warning",
        note => ~"note"
    }
}

fn diagnosticcolor(lvl: level) -> u8 {
    match lvl {
        fatal => term::color_bright_red,
        error => term::color_bright_red,
        warning => term::color_bright_yellow,
        note => term::color_bright_green
    }
}

fn print_diagnostic(topic: ~str, lvl: level, msg: &str) {
    let use_color = term::color_supported() &&
        io::stderr().get_type() == io::Screen;
    if !topic.is_empty() {
        io::stderr().write_str(fmt!("%s ", topic));
    }
    if use_color {
        term::fg(io::stderr(), diagnosticcolor(lvl));
    }
    io::stderr().write_str(fmt!("%s:", diagnosticstr(lvl)));
    if use_color {
        term::reset(io::stderr());
    }
    io::stderr().write_str(fmt!(" %s\n", msg));
}

pub fn collect(messages: @DVec<~str>)
    -> fn@(Option<(@codemap::CodeMap, span)>, &str, level)
{
    let f: @fn(Option<(@codemap::CodeMap, span)>, &str, level) =
        |_o, msg: &str, _l| { messages.push(msg.to_str()); };
    f
}

pub fn emit(cmsp: Option<(@codemap::CodeMap, span)>, msg: &str, lvl: level) {
    match cmsp {
      Some((cm, sp)) => {
        let sp = cm.adjust_span(sp);
        let ss = cm.span_to_str(sp);
        let lines = cm.span_to_lines(sp);
        print_diagnostic(ss, lvl, msg);
        highlight_lines(cm, sp, lines);
        print_macro_backtrace(cm, sp);
      }
      None => {
        print_diagnostic(~"", lvl, msg);
      }
    }
}

fn highlight_lines(cm: @codemap::CodeMap,
                   sp: span,
                   lines: @codemap::FileLines) {
    let fm = lines.file;

    // arbitrarily only print up to six lines of the error
    let max_lines = 6u;
    let mut elided = false;
    let mut display_lines = /* FIXME (#2543) */ copy lines.lines;
    if vec::len(display_lines) > max_lines {
        display_lines = vec::slice(display_lines, 0u, max_lines);
        elided = true;
    }
    // Print the offending lines
    for display_lines.each |line| {
        io::stderr().write_str(fmt!("%s:%u ", fm.name, *line + 1u));
        let s = fm.get_line(*line as int) + ~"\n";
        io::stderr().write_str(s);
    }
    if elided {
        let last_line = display_lines[vec::len(display_lines) - 1u];
        let s = fmt!("%s:%u ", fm.name, last_line + 1u);
        let mut indent = str::len(s);
        let mut out = ~"";
        while indent > 0u { out += ~" "; indent -= 1u; }
        out += ~"...\n";
        io::stderr().write_str(out);
    }

    // If there's one line at fault we can easily point to the problem
    if vec::len(lines.lines) == 1u {
        let lo = cm.lookup_char_pos(sp.lo);
        let mut digits = 0u;
        let mut num = (lines.lines[0] + 1u) / 10u;

        // how many digits must be indent past?
        while num > 0u { num /= 10u; digits += 1u; }

        // indent past |name:## | and the 0-offset column location
        let mut left = str::len(fm.name) + digits + lo.col.to_uint() + 3u;
        let mut s = ~"";
        // Skip is the number of characters we need to skip because they are
        // part of the 'filename:line ' part of the previous line.
        let skip = str::len(fm.name) + digits + 3u;
        for skip.times() {
            s += ~" ";
        }
        let orig = fm.get_line(lines.lines[0] as int);
        for uint::range(0u,left-skip) |pos| {
            let curChar = (orig[pos] as char);
            s += match curChar { // Whenever a tab occurs on the previous
                '\t' => "\t",    // line, we insert one on the error-point-
                _ => " "         // -squigly-line as well (instead of a
            };                   // space). This way the squigly-line will
        }                        // usually appear in the correct position.
        s += ~"^";
        let hi = cm.lookup_char_pos(sp.hi);
        if hi.col != lo.col {
            // the ^ already takes up one space
            let num_squiglies = hi.col.to_uint()-lo.col.to_uint()-1u;
            for num_squiglies.times() { s += ~"~"; }
        }
        io::stderr().write_str(s + ~"\n");
    }
}

fn print_macro_backtrace(cm: @codemap::CodeMap, sp: span) {
    do option::iter(&sp.expn_info) |ei| {
        let ss = option::map_default(&ei.callie.span, @~"",
                                     |span| @cm.span_to_str(*span));
        print_diagnostic(*ss, note,
                         fmt!("in expansion of %s!", ei.callie.name));
        let ss = cm.span_to_str(ei.call_site);
        print_diagnostic(ss, note, ~"expansion site");
        print_macro_backtrace(cm, ei.call_site);
    }
}

pub fn expect<T: Copy>(diag: span_handler,
                       opt: Option<T>,
                       msg: fn() -> ~str) -> T {
    match opt {
       Some(ref t) => (*t),
       None => diag.handler().bug(msg())
    }
}
<|endoftext|>


<commit_before><commit_msg>test(tmux/pane): Add some specs for pane<commit_after><|endoftext|>


<commit_before><commit_msg>Some refactoring in attempt to reduce complexity of tokenizer.<commit_after><|endoftext|>


<commit_before><commit_msg>Re-placed entities in the quadtree after they move because they can shift<commit_after><|endoftext|>


<commit_before><commit_msg>Use AppendReverse for Unzip to avoid 2nd traversal<commit_after><|endoftext|>


<commit_before><commit_msg>Problem 17<commit_after>fn split<'a, T>(list: &'a [T], n: uint) -> (&'a [T], &'a [T]) {
    (list.slice(0, n), list.slice(n, list.len()))
}

fn main() {
    let list = ~['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
    println!("{:?}", split(list, 3));
}

<|endoftext|>


<commit_before><commit_msg>Problem 62<commit_after>enum BinaryTree<T> {
    Node(T, ~BinaryTree<T>, ~BinaryTree<T>),
    Empty
}

fn leaves<T>(tree: BinaryTree<T>) -> ~[T] {
    match tree {
        Empty                   => ~[],
        Node(x, ~Empty, ~Empty) => ~[x],
        Node(_, ~left, ~right)  =>  leaves(left).move_iter()
                                    .chain(leaves(right).move_iter())
                                    .to_owned_vec()
    }
}

fn main() {
    let t1: BinaryTree<uint> = Empty;
    let t2 = Node('x', ~Node('y', ~Empty, ~Empty), ~Node('z', ~Node('t', ~Empty, ~Empty), ~Empty));
    assert_eq!(leaves(t1), ~[]);
    assert_eq!(leaves(t2), ~['y', 't']);
}

<|endoftext|>


<commit_before>// Copyright 2016 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 std::cell::RefCell;
use std::rc::Rc;
use rustc::ty::TyCtxt;
use trans_item::TransItem;
use util::nodemap::FxHashMap;

// In the SymbolCache we collect the symbol names of translation items
// and cache them for later reference. This is just a performance
// optimization and the cache is populated lazilly; symbol names of
// translation items are deterministic and fully defined by the item.
// Thus they can always be recomputed if needed.

pub struct SymbolCache<'a, 'tcx: 'a> {
    tcx: TyCtxt<'a, 'tcx, 'tcx>,
    index: RefCell<FxHashMap<TransItem<'tcx>, Rc<String>>>,
}

impl<'a, 'tcx> SymbolCache<'a, 'tcx> {
    pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
        SymbolCache {
            tcx: tcx,
            index: RefCell::new(FxHashMap())
        }
    }

    pub fn get(&self, trans_item: TransItem<'tcx>) -> Rc<String> {
        let mut index = self.index.borrow_mut();
        index.entry(trans_item)
             .or_insert_with(|| Rc::new(trans_item.compute_symbol_name(self.tcx)))
             .clone()
    }
}
<commit_msg>use Symbol/InternedString in the cache<commit_after>// Copyright 2016 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 rustc::ty::TyCtxt;
use std::cell::RefCell;
use syntax_pos::symbol::{InternedString, Symbol};
use trans_item::TransItem;
use util::nodemap::FxHashMap;

// In the SymbolCache we collect the symbol names of translation items
// and cache them for later reference. This is just a performance
// optimization and the cache is populated lazilly; symbol names of
// translation items are deterministic and fully defined by the item.
// Thus they can always be recomputed if needed.

pub struct SymbolCache<'a, 'tcx: 'a> {
    tcx: TyCtxt<'a, 'tcx, 'tcx>,
    index: RefCell<FxHashMap<TransItem<'tcx>, Symbol>>,
}

impl<'a, 'tcx> SymbolCache<'a, 'tcx> {
    pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
        SymbolCache {
            tcx: tcx,
            index: RefCell::new(FxHashMap())
        }
    }

    pub fn get(&self, trans_item: TransItem<'tcx>) -> InternedString {
        let mut index = self.index.borrow_mut();
        index.entry(trans_item)
             .or_insert_with(|| Symbol::intern(&trans_item.compute_symbol_name(self.tcx)))
             .as_str()
    }
}
<|endoftext|>


<commit_before><commit_msg>Move test from src/lib.rs to test/lib.rs<commit_after><|endoftext|>