<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.

//! A type representing either success or failure

#[allow(missing_doc)];

use clone::Clone;
use cmp::Eq;
use either;
use either::Either;
use iterator::IteratorUtil;
use option::{None, Option, Some};
use vec;
use vec::{OwnedVector, ImmutableVector};
use container::Container;

/// The result type
#[deriving(Clone, Eq)]
pub enum Result<T, U> {
    /// Contains the successful result value
    Ok(T),
    /// Contains the error value
    Err(U)
}

/**
 * Get the value out of a successful result
 *
 * # Failure
 *
 * If the result is an error
 */
#[inline]
pub fn get<T:Clone,U>(res: &Result<T, U>) -> T {
    match *res {
      Ok(ref t) => (*t).clone(),
      Err(ref the_err) =>
        fail!("get called on error result: %?", *the_err)
    }
}

/**
 * Get a reference to the value out of a successful result
 *
 * # Failure
 *
 * If the result is an error
 */
#[inline]
pub fn get_ref<'a, T, U>(res: &'a Result<T, U>) -> &'a T {
    match *res {
        Ok(ref t) => t,
        Err(ref the_err) =>
            fail!("get_ref called on error result: %?", *the_err)
    }
}

/**
 * Get the value out of an error result
 *
 * # Failure
 *
 * If the result is not an error
 */
#[inline]
pub fn get_err<T, U: Clone>(res: &Result<T, U>) -> U {
    match *res {
      Err(ref u) => (*u).clone(),
      Ok(_) => fail!("get_err called on ok result")
    }
}

/// Returns true if the result is `ok`
#[inline]
pub fn is_ok<T, U>(res: &Result<T, U>) -> bool {
    match *res {
      Ok(_) => true,
      Err(_) => false
    }
}

/// Returns true if the result is `err`
#[inline]
pub fn is_err<T, U>(res: &Result<T, U>) -> bool {
    !is_ok(res)
}

/**
 * Convert to the `either` type
 *
 * `ok` result variants are converted to `either::right` variants, `err`
 * result variants are converted to `either::left`.
 */
#[inline]
pub fn to_either<T:Clone,U:Clone>(res: &Result<U, T>)
    -> Either<T, U> {
    match *res {
      Ok(ref res) => either::Right((*res).clone()),
      Err(ref fail_) => either::Left((*fail_).clone())
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `ok` then the value is extracted and passed to `op` whereupon
 * `op`s result is returned. if `res` is `err` then it is immediately
 * returned. This function can be used to compose the results of two
 * functions.
 *
 * Example:
 *
 *     let res = chain(read_file(file)) { |buf|
 *         ok(parse_bytes(buf))
 *     }
 */
#[inline]
pub fn chain<T, U, V>(res: Result<T, V>, op: &fn(T)
    -> Result<U, V>) -> Result<U, V> {
    match res {
        Ok(t) => op(t),
        Err(e) => Err(e)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `err` then the value is extracted and passed to `op`
 * whereupon `op`s result is returned. if `res` is `ok` then it is
 * immediately returned.  This function can be used to pass through a
 * successful result while handling an error.
 */
#[inline]
pub fn chain_err<T, U, V>(
    res: Result<T, V>,
    op: &fn(t: V) -> Result<T, U>)
    -> Result<T, U> {
    match res {
      Ok(t) => Ok(t),
      Err(v) => op(v)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `ok` then the value is extracted and passed to `op` whereupon
 * `op`s result is returned. if `res` is `err` then it is immediately
 * returned. This function can be used to compose the results of two
 * functions.
 *
 * Example:
 *
 *     iter(read_file(file)) { |buf|
 *         print_buf(buf)
 *     }
 */
#[inline]
pub fn iter<T, E>(res: &Result<T, E>, f: &fn(&T)) {
    match *res {
      Ok(ref t) => f(t),
      Err(_) => ()
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `err` then the value is extracted and passed to `op` whereupon
 * `op`s result is returned. if `res` is `ok` then it is immediately returned.
 * This function can be used to pass through a successful result while
 * handling an error.
 */
#[inline]
pub fn iter_err<T, E>(res: &Result<T, E>, f: &fn(&E)) {
    match *res {
      Ok(_) => (),
      Err(ref e) => f(e)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `ok` then the value is extracted and passed to `op` whereupon
 * `op`s result is wrapped in `ok` and returned. if `res` is `err` then it is
 * immediately returned.  This function can be used to compose the results of
 * two functions.
 *
 * Example:
 *
 *     let res = map(read_file(file)) { |buf|
 *         parse_bytes(buf)
 *     }
 */
#[inline]
pub fn map<T, E: Clone, U: Clone>(res: &Result<T, E>, op: &fn(&T) -> U)
  -> Result<U, E> {
    match *res {
      Ok(ref t) => Ok(op(t)),
      Err(ref e) => Err((*e).clone())
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `err` then the value is extracted and passed to `op` whereupon
 * `op`s result is wrapped in an `err` and returned. if `res` is `ok` then it
 * is immediately returned.  This function can be used to pass through a
 * successful result while handling an error.
 */
#[inline]
pub fn map_err<T:Clone,E,F:Clone>(res: &Result<T, E>, op: &fn(&E) -> F)
  -> Result<T, F> {
    match *res {
      Ok(ref t) => Ok((*t).clone()),
      Err(ref e) => Err(op(e))
    }
}

impl<T, E> Result<T, E> {
    #[inline]
    pub fn get_ref<'a>(&'a self) -> &'a T { get_ref(self) }

    #[inline]
    pub fn is_ok(&self) -> bool { is_ok(self) }

    #[inline]
    pub fn is_err(&self) -> bool { is_err(self) }

    #[inline]
    pub fn iter(&self, f: &fn(&T)) { iter(self, f) }

    #[inline]
    pub fn iter_err(&self, f: &fn(&E)) { iter_err(self, f) }

    #[inline]
    pub fn unwrap(self) -> T { unwrap(self) }

    #[inline]
    pub fn unwrap_err(self) -> E { unwrap_err(self) }

    #[inline]
    pub fn chain<U>(self, op: &fn(T) -> Result<U,E>) -> Result<U,E> {
        chain(self, op)
    }

    #[inline]
    pub fn chain_err<F>(self, op: &fn(E) -> Result<T,F>) -> Result<T,F> {
        chain_err(self, op)
    }
}

impl<T:Clone,E> Result<T, E> {
    #[inline]
    pub fn get(&self) -> T { get(self) }

    #[inline]
    pub fn map_err<F:Clone>(&self, op: &fn(&E) -> F) -> Result<T,F> {
        map_err(self, op)
    }
}

impl<T, E:Clone> Result<T, E> {
    #[inline]
    pub fn get_err(&self) -> E { get_err(self) }

    #[inline]
    pub fn map<U:Clone>(&self, op: &fn(&T) -> U) -> Result<U,E> {
        map(self, op)
    }
}

/**
 * Maps each element in the vector `ts` using the operation `op`.  Should an
 * error occur, no further mappings are performed and the error is returned.
 * Should no error occur, a vector containing the result of each map is
 * returned.
 *
 * Here is an example which increments every integer in a vector,
 * checking for overflow:
 *
 *     fn inc_conditionally(x: uint) -> result<uint,str> {
 *         if x == uint::max_value { return err("overflow"); }
 *         else { return ok(x+1u); }
 *     }
 *     map(~[1u, 2u, 3u], inc_conditionally).chain {|incd|
 *         assert!(incd == ~[2u, 3u, 4u]);
 *     }
 */
#[inline]
pub fn map_vec<T,U,V>(ts: &[T], op: &fn(&T) -> Result<V,U>)
                      -> Result<~[V],U> {
    let mut vs: ~[V] = vec::with_capacity(ts.len());
    for ts.iter().advance |t| {
        match op(t) {
          Ok(v) => vs.push(v),
          Err(u) => return Err(u)
        }
    }
    return Ok(vs);
}

#[inline]
#[allow(missing_doc)]
pub fn map_opt<T,
               U,
               V>(
               o_t: &Option<T>,
               op: &fn(&T) -> Result<V,U>)
               -> Result<Option<V>,U> {
    match *o_t {
        None => Ok(None),
        Some(ref t) => match op(t) {
            Ok(v) => Ok(Some(v)),
            Err(e) => Err(e)
        }
    }
}

/**
 * Same as map, but it operates over two parallel vectors.
 *
 * A precondition is used here to ensure that the vectors are the same
 * length.  While we do not often use preconditions in the standard
 * library, a precondition is used here because result::t is generally
 * used in 'careful' code contexts where it is both appropriate and easy
 * to accommodate an error like the vectors being of different lengths.
 */
#[inline]
pub fn map_vec2<S,T,U,V>(ss: &[S], ts: &[T],
                op: &fn(&S,&T) -> Result<V,U>) -> Result<~[V],U> {

    assert!(vec::same_length(ss, ts));
    let n = ts.len();
    let mut vs = vec::with_capacity(n);
    let mut i = 0u;
    while i < n {
        match op(&ss[i],&ts[i]) {
          Ok(v) => vs.push(v),
          Err(u) => return Err(u)
        }
        i += 1u;
    }
    return Ok(vs);
}

/**
 * Applies op to the pairwise elements from `ss` and `ts`, aborting on
 * error.  This could be implemented using `map_zip()` but it is more efficient
 * on its own as no result vector is built.
 */
#[inline]
pub fn iter_vec2<S,T,U>(ss: &[S], ts: &[T],
                         op: &fn(&S,&T) -> Result<(),U>) -> Result<(),U> {

    assert!(vec::same_length(ss, ts));
    let n = ts.len();
    let mut i = 0u;
    while i < n {
        match op(&ss[i],&ts[i]) {
          Ok(()) => (),
          Err(u) => return Err(u)
        }
        i += 1u;
    }
    return Ok(());
}

/// Unwraps a result, assuming it is an `ok(T)`
#[inline]
pub fn unwrap<T, U>(res: Result<T, U>) -> T {
    match res {
      Ok(t) => t,
      Err(_) => fail!("unwrap called on an err result")
    }
}

/// Unwraps a result, assuming it is an `err(U)`
#[inline]
pub fn unwrap_err<T, U>(res: Result<T, U>) -> U {
    match res {
      Err(u) => u,
      Ok(_) => fail!("unwrap called on an ok result")
    }
}

#[cfg(test)]
mod tests {
    use result::{Err, Ok, Result, chain, get, get_err};
    use result;

    pub fn op1() -> result::Result<int, ~str> { result::Ok(666) }

    pub fn op2(i: int) -> result::Result<uint, ~str> {
        result::Ok(i as uint + 1u)
    }

    pub fn op3() -> result::Result<int, ~str> { result::Err(~"sadface") }

    #[test]
    pub fn chain_success() {
        assert_eq!(get(&chain(op1(), op2)), 667u);
    }

    #[test]
    pub fn chain_failure() {
        assert_eq!(get_err(&chain(op3(), op2)), ~"sadface");
    }

    #[test]
    pub fn test_impl_iter() {
        let mut valid = false;
        Ok::<~str, ~str>(~"a").iter(|_x| valid = true);
        assert!(valid);

        Err::<~str, ~str>(~"b").iter(|_x| valid = false);
        assert!(valid);
    }

    #[test]
    pub fn test_impl_iter_err() {
        let mut valid = true;
        Ok::<~str, ~str>(~"a").iter_err(|_x| valid = false);
        assert!(valid);

        valid = false;
        Err::<~str, ~str>(~"b").iter_err(|_x| valid = true);
        assert!(valid);
    }

    #[test]
    pub fn test_impl_map() {
        assert_eq!(Ok::<~str, ~str>(~"a").map(|_x| ~"b"), Ok(~"b"));
        assert_eq!(Err::<~str, ~str>(~"a").map(|_x| ~"b"), Err(~"a"));
    }

    #[test]
    pub fn test_impl_map_err() {
        assert_eq!(Ok::<~str, ~str>(~"a").map_err(|_x| ~"b"), Ok(~"a"));
        assert_eq!(Err::<~str, ~str>(~"a").map_err(|_x| ~"b"), Err(~"b"));
    }

    #[test]
    pub fn test_get_ref_method() {
        let foo: Result<int, ()> = Ok(100);
        assert_eq!(*foo.get_ref(), 100);
    }
}
<commit_msg>cleanup get_ref<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.

//! A type representing either success or failure

#[allow(missing_doc)];

use clone::Clone;
use cmp::Eq;
use either;
use either::Either;
use iterator::IteratorUtil;
use option::{None, Option, Some};
use vec;
use vec::{OwnedVector, ImmutableVector};
use container::Container;

/// The result type
#[deriving(Clone, Eq)]
pub enum Result<T, U> {
    /// Contains the successful result value
    Ok(T),
    /// Contains the error value
    Err(U)
}

/**
 * Get the value out of a successful result
 *
 * # Failure
 *
 * If the result is an error
 */
#[inline]
pub fn get<T:Clone,U>(res: &Result<T, U>) -> T {
    match *res {
      Ok(ref t) => (*t).clone(),
      Err(ref the_err) =>
        fail!("get called on error result: %?", *the_err)
    }
}

/**
 * Get the value out of an error result
 *
 * # Failure
 *
 * If the result is not an error
 */
#[inline]
pub fn get_err<T, U: Clone>(res: &Result<T, U>) -> U {
    match *res {
      Err(ref u) => (*u).clone(),
      Ok(_) => fail!("get_err called on ok result")
    }
}

/// Returns true if the result is `ok`
#[inline]
pub fn is_ok<T, U>(res: &Result<T, U>) -> bool {
    match *res {
      Ok(_) => true,
      Err(_) => false
    }
}

/// Returns true if the result is `err`
#[inline]
pub fn is_err<T, U>(res: &Result<T, U>) -> bool {
    !is_ok(res)
}

/**
 * Convert to the `either` type
 *
 * `ok` result variants are converted to `either::right` variants, `err`
 * result variants are converted to `either::left`.
 */
#[inline]
pub fn to_either<T:Clone,U:Clone>(res: &Result<U, T>)
    -> Either<T, U> {
    match *res {
      Ok(ref res) => either::Right((*res).clone()),
      Err(ref fail_) => either::Left((*fail_).clone())
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `ok` then the value is extracted and passed to `op` whereupon
 * `op`s result is returned. if `res` is `err` then it is immediately
 * returned. This function can be used to compose the results of two
 * functions.
 *
 * Example:
 *
 *     let res = chain(read_file(file)) { |buf|
 *         ok(parse_bytes(buf))
 *     }
 */
#[inline]
pub fn chain<T, U, V>(res: Result<T, V>, op: &fn(T)
    -> Result<U, V>) -> Result<U, V> {
    match res {
        Ok(t) => op(t),
        Err(e) => Err(e)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `err` then the value is extracted and passed to `op`
 * whereupon `op`s result is returned. if `res` is `ok` then it is
 * immediately returned.  This function can be used to pass through a
 * successful result while handling an error.
 */
#[inline]
pub fn chain_err<T, U, V>(
    res: Result<T, V>,
    op: &fn(t: V) -> Result<T, U>)
    -> Result<T, U> {
    match res {
      Ok(t) => Ok(t),
      Err(v) => op(v)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `ok` then the value is extracted and passed to `op` whereupon
 * `op`s result is returned. if `res` is `err` then it is immediately
 * returned. This function can be used to compose the results of two
 * functions.
 *
 * Example:
 *
 *     iter(read_file(file)) { |buf|
 *         print_buf(buf)
 *     }
 */
#[inline]
pub fn iter<T, E>(res: &Result<T, E>, f: &fn(&T)) {
    match *res {
      Ok(ref t) => f(t),
      Err(_) => ()
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `err` then the value is extracted and passed to `op` whereupon
 * `op`s result is returned. if `res` is `ok` then it is immediately returned.
 * This function can be used to pass through a successful result while
 * handling an error.
 */
#[inline]
pub fn iter_err<T, E>(res: &Result<T, E>, f: &fn(&E)) {
    match *res {
      Ok(_) => (),
      Err(ref e) => f(e)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `ok` then the value is extracted and passed to `op` whereupon
 * `op`s result is wrapped in `ok` and returned. if `res` is `err` then it is
 * immediately returned.  This function can be used to compose the results of
 * two functions.
 *
 * Example:
 *
 *     let res = map(read_file(file)) { |buf|
 *         parse_bytes(buf)
 *     }
 */
#[inline]
pub fn map<T, E: Clone, U: Clone>(res: &Result<T, E>, op: &fn(&T) -> U)
  -> Result<U, E> {
    match *res {
      Ok(ref t) => Ok(op(t)),
      Err(ref e) => Err((*e).clone())
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `err` then the value is extracted and passed to `op` whereupon
 * `op`s result is wrapped in an `err` and returned. if `res` is `ok` then it
 * is immediately returned.  This function can be used to pass through a
 * successful result while handling an error.
 */
#[inline]
pub fn map_err<T:Clone,E,F:Clone>(res: &Result<T, E>, op: &fn(&E) -> F)
  -> Result<T, F> {
    match *res {
      Ok(ref t) => Ok((*t).clone()),
      Err(ref e) => Err(op(e))
    }
}

impl<T, E> Result<T, E> {
    /**
     * Get a reference to the value out of a successful result
     *
     * # Failure
     *
     * If the result is an error
     */
    #[inline]
    pub fn get_ref<'a>(&'a self) -> &'a T {
        match *self {
        Ok(ref t) => t,
        Err(ref the_err) =>
            fail!("get_ref called on error result: %?", *the_err)
        }
    }

    #[inline]
    pub fn is_ok(&self) -> bool { is_ok(self) }

    #[inline]
    pub fn is_err(&self) -> bool { is_err(self) }

    #[inline]
    pub fn iter(&self, f: &fn(&T)) { iter(self, f) }

    #[inline]
    pub fn iter_err(&self, f: &fn(&E)) { iter_err(self, f) }

    #[inline]
    pub fn unwrap(self) -> T { unwrap(self) }

    #[inline]
    pub fn unwrap_err(self) -> E { unwrap_err(self) }

    #[inline]
    pub fn chain<U>(self, op: &fn(T) -> Result<U,E>) -> Result<U,E> {
        chain(self, op)
    }

    #[inline]
    pub fn chain_err<F>(self, op: &fn(E) -> Result<T,F>) -> Result<T,F> {
        chain_err(self, op)
    }
}

impl<T:Clone,E> Result<T, E> {
    #[inline]
    pub fn get(&self) -> T { get(self) }

    #[inline]
    pub fn map_err<F:Clone>(&self, op: &fn(&E) -> F) -> Result<T,F> {
        map_err(self, op)
    }
}

impl<T, E:Clone> Result<T, E> {
    #[inline]
    pub fn get_err(&self) -> E { get_err(self) }

    #[inline]
    pub fn map<U:Clone>(&self, op: &fn(&T) -> U) -> Result<U,E> {
        map(self, op)
    }
}

/**
 * Maps each element in the vector `ts` using the operation `op`.  Should an
 * error occur, no further mappings are performed and the error is returned.
 * Should no error occur, a vector containing the result of each map is
 * returned.
 *
 * Here is an example which increments every integer in a vector,
 * checking for overflow:
 *
 *     fn inc_conditionally(x: uint) -> result<uint,str> {
 *         if x == uint::max_value { return err("overflow"); }
 *         else { return ok(x+1u); }
 *     }
 *     map(~[1u, 2u, 3u], inc_conditionally).chain {|incd|
 *         assert!(incd == ~[2u, 3u, 4u]);
 *     }
 */
#[inline]
pub fn map_vec<T,U,V>(ts: &[T], op: &fn(&T) -> Result<V,U>)
                      -> Result<~[V],U> {
    let mut vs: ~[V] = vec::with_capacity(ts.len());
    for ts.iter().advance |t| {
        match op(t) {
          Ok(v) => vs.push(v),
          Err(u) => return Err(u)
        }
    }
    return Ok(vs);
}

#[inline]
#[allow(missing_doc)]
pub fn map_opt<T,
               U,
               V>(
               o_t: &Option<T>,
               op: &fn(&T) -> Result<V,U>)
               -> Result<Option<V>,U> {
    match *o_t {
        None => Ok(None),
        Some(ref t) => match op(t) {
            Ok(v) => Ok(Some(v)),
            Err(e) => Err(e)
        }
    }
}

/**
 * Same as map, but it operates over two parallel vectors.
 *
 * A precondition is used here to ensure that the vectors are the same
 * length.  While we do not often use preconditions in the standard
 * library, a precondition is used here because result::t is generally
 * used in 'careful' code contexts where it is both appropriate and easy
 * to accommodate an error like the vectors being of different lengths.
 */
#[inline]
pub fn map_vec2<S,T,U,V>(ss: &[S], ts: &[T],
                op: &fn(&S,&T) -> Result<V,U>) -> Result<~[V],U> {

    assert!(vec::same_length(ss, ts));
    let n = ts.len();
    let mut vs = vec::with_capacity(n);
    let mut i = 0u;
    while i < n {
        match op(&ss[i],&ts[i]) {
          Ok(v) => vs.push(v),
          Err(u) => return Err(u)
        }
        i += 1u;
    }
    return Ok(vs);
}

/**
 * Applies op to the pairwise elements from `ss` and `ts`, aborting on
 * error.  This could be implemented using `map_zip()` but it is more efficient
 * on its own as no result vector is built.
 */
#[inline]
pub fn iter_vec2<S,T,U>(ss: &[S], ts: &[T],
                         op: &fn(&S,&T) -> Result<(),U>) -> Result<(),U> {

    assert!(vec::same_length(ss, ts));
    let n = ts.len();
    let mut i = 0u;
    while i < n {
        match op(&ss[i],&ts[i]) {
          Ok(()) => (),
          Err(u) => return Err(u)
        }
        i += 1u;
    }
    return Ok(());
}

/// Unwraps a result, assuming it is an `ok(T)`
#[inline]
pub fn unwrap<T, U>(res: Result<T, U>) -> T {
    match res {
      Ok(t) => t,
      Err(_) => fail!("unwrap called on an err result")
    }
}

/// Unwraps a result, assuming it is an `err(U)`
#[inline]
pub fn unwrap_err<T, U>(res: Result<T, U>) -> U {
    match res {
      Err(u) => u,
      Ok(_) => fail!("unwrap called on an ok result")
    }
}

#[cfg(test)]
mod tests {
    use result::{Err, Ok, Result, chain, get, get_err};
    use result;

    pub fn op1() -> result::Result<int, ~str> { result::Ok(666) }

    pub fn op2(i: int) -> result::Result<uint, ~str> {
        result::Ok(i as uint + 1u)
    }

    pub fn op3() -> result::Result<int, ~str> { result::Err(~"sadface") }

    #[test]
    pub fn chain_success() {
        assert_eq!(get(&chain(op1(), op2)), 667u);
    }

    #[test]
    pub fn chain_failure() {
        assert_eq!(get_err(&chain(op3(), op2)), ~"sadface");
    }

    #[test]
    pub fn test_impl_iter() {
        let mut valid = false;
        Ok::<~str, ~str>(~"a").iter(|_x| valid = true);
        assert!(valid);

        Err::<~str, ~str>(~"b").iter(|_x| valid = false);
        assert!(valid);
    }

    #[test]
    pub fn test_impl_iter_err() {
        let mut valid = true;
        Ok::<~str, ~str>(~"a").iter_err(|_x| valid = false);
        assert!(valid);

        valid = false;
        Err::<~str, ~str>(~"b").iter_err(|_x| valid = true);
        assert!(valid);
    }

    #[test]
    pub fn test_impl_map() {
        assert_eq!(Ok::<~str, ~str>(~"a").map(|_x| ~"b"), Ok(~"b"));
        assert_eq!(Err::<~str, ~str>(~"a").map(|_x| ~"b"), Err(~"a"));
    }

    #[test]
    pub fn test_impl_map_err() {
        assert_eq!(Ok::<~str, ~str>(~"a").map_err(|_x| ~"b"), Ok(~"a"));
        assert_eq!(Err::<~str, ~str>(~"a").map_err(|_x| ~"b"), Err(~"b"));
    }

    #[test]
    pub fn test_get_ref_method() {
        let foo: Result<int, ()> = Ok(100);
        assert_eq!(*foo.get_ref(), 100);
    }
}
<|endoftext|>


<commit_before><commit_msg>Update for latest serenity<commit_after><|endoftext|>


<commit_before><commit_msg>Initialize counter<commit_after><|endoftext|>


<commit_before><commit_msg>Update main.rs<commit_after><|endoftext|>


<commit_before><commit_msg>:ambulance: Fix type of value.content<commit_after><|endoftext|>


<commit_before><commit_msg>Use range iterator to be a bit more terse<commit_after><|endoftext|>


<commit_before><commit_msg>Remove rendering of demo product.<commit_after><|endoftext|>


<commit_before><commit_msg>Added IntoIter and Iterator for Record<commit_after><|endoftext|>


<commit_before><commit_msg>Auto merge of #24817 - servo:jdm-patch-31, r=Manishearth<commit_after><|endoftext|>


<commit_before><commit_msg>test: more tests<commit_after>extern crate memcache;

#[test]
fn set_string() {
    let mut conn = memcache::connection::connect("127.0.0.1:12345").unwrap();
    conn.set("this_is_a_string", String::from("a string"), 0).unwrap();
    conn.set("this_is_another_string", "another string", 0).unwrap();
}

#[test]
fn set_bytes() {
    let mut conn = memcache::connection::connect("127.0.0.1:12345").unwrap();
    conn.set("this_is_a_bytes", "some bytes".as_bytes(), 0).unwrap();
}
<|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.

//! Check license of third-party deps by inspecting src/vendor

use std::fs::File;
use std::io::Read;
use std::path::Path;

static LICENSES: &'static [&'static str] = &[
    "MIT/Apache-2.0",
    "MIT / Apache-2.0",
    "Apache-2.0/MIT",
    "Apache-2.0 / MIT",
    "MIT OR Apache-2.0",
    "MIT",
    "Unlicense/MIT",
];

// These are exceptions to Rust's permissive licensing policy, and
// should be considered bugs. Exceptions are only allowed in Rust
// tooling. It is _crucial_ that no exception crates be dependencies
// of the Rust runtime (std / test).
static EXCEPTIONS: &'static [&'static str] = &[
    "mdbook", // MPL2, mdbook
    "openssl", // BSD+advertising clause, cargo, mdbook
    "pest", // MPL2, mdbook via handlebars
    "thread-id", // Apache-2.0, mdbook
    "toml-query", // MPL-2.0, mdbook
    "is-match", // MPL-2.0, mdbook
    "cssparser", // MPL-2.0, rustdoc
    "smallvec", // MPL-2.0, rustdoc
    "fuchsia-zircon-sys", // BSD-3-Clause, rustdoc, rustc, cargo
    "fuchsia-zircon", // BSD-3-Clause, rustdoc, rustc, cargo (jobserver & tempdir)
    "cssparser-macros", // MPL-2.0, rustdoc
    "selectors", // MPL-2.0, rustdoc
];

pub fn check(path: &Path, bad: &mut bool) {
    let path = path.join("vendor");
    assert!(path.exists(), "vendor directory missing");
    let mut saw_dir = false;
    'next_path: for dir in t!(path.read_dir()) {
        saw_dir = true;
        let dir = t!(dir);

        // skip our exceptions
        for exception in EXCEPTIONS {
            if dir.path()
                .to_str()
                .unwrap()
                .contains(&format!("src/vendor/{}", exception)) {
                continue 'next_path;
            }
        }

        let toml = dir.path().join("Cargo.toml");
        if !check_license(&toml) {
            *bad = true;
        }
    }
    assert!(saw_dir, "no vendored source");
}

fn check_license(path: &Path) -> bool {
    if !path.exists() {
        panic!("{} does not exist", path.display());
    }
    let mut contents = String::new();
    t!(t!(File::open(path)).read_to_string(&mut contents));

    let mut found_license = false;
    for line in contents.lines() {
        if !line.starts_with("license") {
            continue;
        }
        let license = extract_license(line);
        if !LICENSES.contains(&&*license) {
            println!("invalid license {} in {}", license, path.display());
            return false;
        }
        found_license = true;
        break;
    }
    if !found_license {
        println!("no license in {}", path.display());
        return false;
    }

    true
}

fn extract_license(line: &str) -> String {
    let first_quote = line.find('"');
    let last_quote = line.rfind('"');
    if let (Some(f), Some(l)) = (first_quote, last_quote) {
        let license = &line[f + 1 .. l];
        license.into()
    } else {
        "bad-license-parse".into()
    }
}
<commit_msg>Exclude clippy lints from tidy license check<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.

//! Check license of third-party deps by inspecting src/vendor

use std::fs::File;
use std::io::Read;
use std::path::Path;

static LICENSES: &'static [&'static str] = &[
    "MIT/Apache-2.0",
    "MIT / Apache-2.0",
    "Apache-2.0/MIT",
    "Apache-2.0 / MIT",
    "MIT OR Apache-2.0",
    "MIT",
    "Unlicense/MIT",
];

// These are exceptions to Rust's permissive licensing policy, and
// should be considered bugs. Exceptions are only allowed in Rust
// tooling. It is _crucial_ that no exception crates be dependencies
// of the Rust runtime (std / test).
static EXCEPTIONS: &'static [&'static str] = &[
    "mdbook", // MPL2, mdbook
    "openssl", // BSD+advertising clause, cargo, mdbook
    "pest", // MPL2, mdbook via handlebars
    "thread-id", // Apache-2.0, mdbook
    "toml-query", // MPL-2.0, mdbook
    "is-match", // MPL-2.0, mdbook
    "cssparser", // MPL-2.0, rustdoc
    "smallvec", // MPL-2.0, rustdoc
    "fuchsia-zircon-sys", // BSD-3-Clause, rustdoc, rustc, cargo
    "fuchsia-zircon", // BSD-3-Clause, rustdoc, rustc, cargo (jobserver & tempdir)
    "cssparser-macros", // MPL-2.0, rustdoc
    "selectors", // MPL-2.0, rustdoc
    "clippy_lints", // MPL-2.0 rls
];

pub fn check(path: &Path, bad: &mut bool) {
    let path = path.join("vendor");
    assert!(path.exists(), "vendor directory missing");
    let mut saw_dir = false;
    'next_path: for dir in t!(path.read_dir()) {
        saw_dir = true;
        let dir = t!(dir);

        // skip our exceptions
        for exception in EXCEPTIONS {
            if dir.path()
                .to_str()
                .unwrap()
                .contains(&format!("src/vendor/{}", exception)) {
                continue 'next_path;
            }
        }

        let toml = dir.path().join("Cargo.toml");
        if !check_license(&toml) {
            *bad = true;
        }
    }
    assert!(saw_dir, "no vendored source");
}

fn check_license(path: &Path) -> bool {
    if !path.exists() {
        panic!("{} does not exist", path.display());
    }
    let mut contents = String::new();
    t!(t!(File::open(path)).read_to_string(&mut contents));

    let mut found_license = false;
    for line in contents.lines() {
        if !line.starts_with("license") {
            continue;
        }
        let license = extract_license(line);
        if !LICENSES.contains(&&*license) {
            println!("invalid license {} in {}", license, path.display());
            return false;
        }
        found_license = true;
        break;
    }
    if !found_license {
        println!("no license in {}", path.display());
        return false;
    }

    true
}

fn extract_license(line: &str) -> String {
    let first_quote = line.find('"');
    let last_quote = line.rfind('"');
    if let (Some(f), Some(l)) = (first_quote, last_quote) {
        let license = &line[f + 1 .. l];
        license.into()
    } else {
        "bad-license-parse".into()
    }
}
<|endoftext|>


<commit_before><commit_msg>Oops, forgot to commit util.rs<commit_after><|endoftext|>


<commit_before><commit_msg>Add a test for new borrow capability<commit_after><|endoftext|>


<commit_before><commit_msg>add response type for `GetEntryList`<commit_after>use super::SI;
use super::Kat;
use super::Medium;
use super::State;
use super::Season;

#[derive(Debug, Clone, Deserialize)]
pub struct EntryList {
	pub id: SI,
	pub name: String,
	pub genre: String,
	pub medium: Medium,
	pub count: i64,
	pub state: State,
	pub rate_sum: i64,
	pub rate_count: SI,
	pub language: String,
	pub year: SI,
	pub season: Season,
	#[serde(rename = "type")]
	pub type_: Option<String>,
}
<|endoftext|>


<commit_before>use std::path::PathBuf;
use std::ffi::OsString;
use hyper;

declare_errors! {
    types {
        Error, ErrorKind, ChainError, Result;
    }

    links { }

    foreign_links { }

    errors {
        LocatingHome {
            description("could not locate home directory")
        }
        LocatingWorkingDir {
            description("could not locate working directory")
        }
        ReadingFile {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not read file")
            display("could not read {} file: '{}'", name, path.display())
        }
        ReadingDirectory {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not read directory")
            display("could not read {} directory: '{}'", name, path.display())
        }
        WritingFile {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not write file")
            display("could not write {} file: '{}'", name, path.display())
        }
        CreatingDirectory {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not create directory")
            display("could not crate {} directory: '{}'", name, path.display())
        }
        FilteringFile {
            name: &'static str,
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not copy  file")
            display("could not copy {} file from '{}' to '{}'", name, src.display(), dest.display())
        }
        RenamingFile {
            name: &'static str,
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not rename file")
            display("could not rename {} file from '{}' to '{}'", name, src.display(), dest.display())
        }
        RenamingDirectory {
            name: &'static str,
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not rename directory")
            display("could not rename {} directory from '{}' to '{}'", name, src.display(), dest.display())
        }
        DownloadingFile {
            url: hyper::Url,
            path: PathBuf,
        } {
            description("could not download file")
            display("could not download file from '{}' to '{}", url, path.display())
        }
        Download404 {
            url: hyper::Url,
            path: PathBuf,
        } {
            description("could not download file")
            display("could not download file from '{}' to '{}", url, path.display())
        }
        InvalidUrl {
            url: String,
        } {
            description("invalid url")
            display("invalid url: {}", url)
        }
        RunningCommand {
            name: OsString,
        } {
            description("command failed")
            display("command failed: '{}'", PathBuf::from(name).display())
        }
        NotAFile {
            path: PathBuf,
        } {
            description("not a file")
            display("not a file: '{}'", path.display())
        }
        NotADirectory {
            path: PathBuf,
        } {
            description("not a directory")
            display("not a directory: '{}'", path.display())
        }
        LinkingFile {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not link file")
            display("could not create link from '{}' to '{}'", src.display(), dest.display())
        }
        LinkingDirectory {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not symlink directory")
            display("could not create link from '{}' to '{}'", src.display(), dest.display())
        }
        CopyingDirectory {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not copy directory")
            display("could not copy directory from '{}' to '{}'", src.display(), dest.display())
        }
        CopyingFile {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not copy file")
            display("could not copy file from '{}' to '{}'", src.display(), dest.display())
        }
        RemovingFile {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not remove file")
            display("could not remove '{}' file: '{}'", name, path.display())
        }
        RemovingDirectory {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not remove directory")
            display("could not remove '{}' directory: '{}'", name, path.display())
        }
        OpeningBrowser {
            description("could not open browser")
        }
        NoBrowser {
            description("could not open browser: no browser installed")
        }
        SettingPermissions {
            path: PathBuf,
        } {
            description("failed to set permissions")
            display("failed to set permissions for '{}'", path.display())
        }
        CargoHome {
            description("couldn't find value of CARGO_HOME")
        }
        MultirustHome {
            description("couldn't find value of RUSTUP_HOME")
        }
    }
}
<commit_msg>Remove unused variant<commit_after>use std::path::PathBuf;
use std::ffi::OsString;
use hyper;

declare_errors! {
    types {
        Error, ErrorKind, ChainError, Result;
    }

    links { }

    foreign_links { }

    errors {
        LocatingWorkingDir {
            description("could not locate working directory")
        }
        ReadingFile {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not read file")
            display("could not read {} file: '{}'", name, path.display())
        }
        ReadingDirectory {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not read directory")
            display("could not read {} directory: '{}'", name, path.display())
        }
        WritingFile {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not write file")
            display("could not write {} file: '{}'", name, path.display())
        }
        CreatingDirectory {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not create directory")
            display("could not crate {} directory: '{}'", name, path.display())
        }
        FilteringFile {
            name: &'static str,
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not copy  file")
            display("could not copy {} file from '{}' to '{}'", name, src.display(), dest.display())
        }
        RenamingFile {
            name: &'static str,
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not rename file")
            display("could not rename {} file from '{}' to '{}'", name, src.display(), dest.display())
        }
        RenamingDirectory {
            name: &'static str,
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not rename directory")
            display("could not rename {} directory from '{}' to '{}'", name, src.display(), dest.display())
        }
        DownloadingFile {
            url: hyper::Url,
            path: PathBuf,
        } {
            description("could not download file")
            display("could not download file from '{}' to '{}", url, path.display())
        }
        Download404 {
            url: hyper::Url,
            path: PathBuf,
        } {
            description("could not download file")
            display("could not download file from '{}' to '{}", url, path.display())
        }
        InvalidUrl {
            url: String,
        } {
            description("invalid url")
            display("invalid url: {}", url)
        }
        RunningCommand {
            name: OsString,
        } {
            description("command failed")
            display("command failed: '{}'", PathBuf::from(name).display())
        }
        NotAFile {
            path: PathBuf,
        } {
            description("not a file")
            display("not a file: '{}'", path.display())
        }
        NotADirectory {
            path: PathBuf,
        } {
            description("not a directory")
            display("not a directory: '{}'", path.display())
        }
        LinkingFile {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not link file")
            display("could not create link from '{}' to '{}'", src.display(), dest.display())
        }
        LinkingDirectory {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not symlink directory")
            display("could not create link from '{}' to '{}'", src.display(), dest.display())
        }
        CopyingDirectory {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not copy directory")
            display("could not copy directory from '{}' to '{}'", src.display(), dest.display())
        }
        CopyingFile {
            src: PathBuf,
            dest: PathBuf,
        } {
            description("could not copy file")
            display("could not copy file from '{}' to '{}'", src.display(), dest.display())
        }
        RemovingFile {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not remove file")
            display("could not remove '{}' file: '{}'", name, path.display())
        }
        RemovingDirectory {
            name: &'static str,
            path: PathBuf,
        } {
            description("could not remove directory")
            display("could not remove '{}' directory: '{}'", name, path.display())
        }
        OpeningBrowser {
            description("could not open browser")
        }
        NoBrowser {
            description("could not open browser: no browser installed")
        }
        SettingPermissions {
            path: PathBuf,
        } {
            description("failed to set permissions")
            display("failed to set permissions for '{}'", path.display())
        }
        CargoHome {
            description("couldn't find value of CARGO_HOME")
        }
        MultirustHome {
            description("couldn't find value of RUSTUP_HOME")
        }
    }
}
<|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.

// no-prefer-dynamic
// compile-flags: --test

#![crate_type = "proc-macro"]

extern crate proc_macro;

use proc_macro::TokenStream;

#[proc_macro_derive(Foo)]
pub fn derive_foo(_input: TokenStream) -> TokenStream {
    "".parse().unwrap()
}

#[test]
pub fn test_derive() {
    assert!(true);
}
<commit_msg>Add doctest to the proc-macro derive-test<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.

// no-prefer-dynamic
// compile-flags: --test

#![crate_type = "proc-macro"]

extern crate proc_macro;

use proc_macro::TokenStream;

// ```
// assert!(true);
// ```
#[proc_macro_derive(Foo)]
pub fn derive_foo(_input: TokenStream) -> TokenStream {
    "".parse().unwrap()
}

#[test]
pub fn test_derive() {
    assert!(true);
}
<|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.

//! This module provides two passes:
//!
//!   - [CleanAscribeUserType], that replaces all
//!     [StatementKind::AscribeUserType] statements with [StatementKind::Nop].
//!   - [CleanFakeReadsAndBorrows], that replaces all [FakeRead] statements and
//!     borrows that are read by [FakeReadCause::ForMatchGuard] fake reads with
//!     [StatementKind::Nop].
//!
//! The [CleanFakeReadsAndBorrows] "pass" is actually implemented as two
//! traversals (aka visits) of the input MIR. The first traversal,
//! [DeleteAndRecordFakeReads], deletes the fake reads and finds the temporaries
//! read by [ForMatchGuard] reads, and [DeleteFakeBorrows] deletes the
//! initialization of those temporaries.

use rustc_data_structures::fx::FxHashSet;

use rustc::mir::{BasicBlock, FakeReadCause, Local, Location, Mir, Place};
use rustc::mir::{Statement, StatementKind};
use rustc::mir::visit::MutVisitor;
use rustc::ty::TyCtxt;
use transform::{MirPass, MirSource};

pub struct CleanAscribeUserType;

pub struct DeleteAscribeUserType;

impl MirPass for CleanAscribeUserType {
    fn run_pass<'a, 'tcx>(&self,
                          _tcx: TyCtxt<'a, 'tcx, 'tcx>,
                          _source: MirSource,
                          mir: &mut Mir<'tcx>) {
        let mut delete = DeleteAscribeUserType;
        delete.visit_mir(mir);
    }
}

impl<'tcx> MutVisitor<'tcx> for DeleteAscribeUserType {
    fn visit_statement(&mut self,
                       block: BasicBlock,
                       statement: &mut Statement<'tcx>,
                       location: Location) {
        if let StatementKind::AscribeUserType(..) = statement.kind {
            statement.make_nop();
        }
        self.super_statement(block, statement, location);
    }
}

pub struct CleanFakeReadsAndBorrows;

#[derive(Default)]
pub struct DeleteAndRecordFakeReads {
    fake_borrow_temporaries: FxHashSet<Local>,
}

pub struct DeleteFakeBorrows {
    fake_borrow_temporaries: FxHashSet<Local>,
}

// Removes any FakeReads from the MIR
impl MirPass for CleanFakeReadsAndBorrows {
    fn run_pass<'a, 'tcx>(&self,
                          _tcx: TyCtxt<'a, 'tcx, 'tcx>,
                          _source: MirSource,
                          mir: &mut Mir<'tcx>) {
        let mut delete_reads = DeleteAndRecordFakeReads::default();
        delete_reads.visit_mir(mir);
        let mut delete_borrows = DeleteFakeBorrows {
            fake_borrow_temporaries: delete_reads.fake_borrow_temporaries,
        };
        delete_borrows.visit_mir(mir);
    }
}

impl<'tcx> MutVisitor<'tcx> for DeleteAndRecordFakeReads {
    fn visit_statement(&mut self,
                       block: BasicBlock,
                       statement: &mut Statement<'tcx>,
                       location: Location) {
        if let StatementKind::FakeRead(cause, ref place) = statement.kind {
            if let FakeReadCause::ForMatchGuard = cause {
                match *place {
                    Place::Local(local) => self.fake_borrow_temporaries.insert(local),
                    _ => bug!("Fake match guard read of non-local: {:?}", place),
                };
            }
            statement.make_nop();
        }
        self.super_statement(block, statement, location);
    }
}

impl<'tcx> MutVisitor<'tcx> for DeleteFakeBorrows {
    fn visit_statement(&mut self,
                       block: BasicBlock,
                       statement: &mut Statement<'tcx>,
                       location: Location) {
        if let StatementKind::Assign(Place::Local(local), _) = statement.kind {
            if self.fake_borrow_temporaries.contains(&local) {
                statement.make_nop();
            }
        }
        self.super_statement(block, statement, location);
    }
}
<commit_msg>Fix some rustc doc links<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.

//! This module provides two passes:
//!
//!   - [`CleanAscribeUserType`], that replaces all [`AscribeUserType`]
//!     statements with [`Nop`].
//!   - [`CleanFakeReadsAndBorrows`], that replaces all [`FakeRead`] statements
//!     and borrows that are read by [`ForMatchGuard`] fake reads with [`Nop`].
//!
//! The `CleanFakeReadsAndBorrows` "pass" is actually implemented as two
//! traversals (aka visits) of the input MIR. The first traversal,
//! [`DeleteAndRecordFakeReads`], deletes the fake reads and finds the
//! temporaries read by [`ForMatchGuard`] reads, and [`DeleteFakeBorrows`]
//! deletes the initialization of those temporaries.
//!
//! [`CleanAscribeUserType`]: cleanup_post_borrowck::CleanAscribeUserType
//! [`CleanFakeReadsAndBorrows`]: cleanup_post_borrowck::CleanFakeReadsAndBorrows
//! [`DeleteAndRecordFakeReads`]: cleanup_post_borrowck::DeleteAndRecordFakeReads
//! [`DeleteFakeBorrows`]: cleanup_post_borrowck::DeleteFakeBorrows
//! [`AscribeUserType`]: rustc::mir::StatementKind::AscribeUserType
//! [`Nop`]: rustc::mir::StatementKind::Nop
//! [`FakeRead`]: rustc::mir::StatementKind::FakeRead
//! [`ForMatchGuard`]: rustc::mir::FakeReadCause::ForMatchGuard

use rustc_data_structures::fx::FxHashSet;

use rustc::mir::{BasicBlock, FakeReadCause, Local, Location, Mir, Place};
use rustc::mir::{Statement, StatementKind};
use rustc::mir::visit::MutVisitor;
use rustc::ty::TyCtxt;
use transform::{MirPass, MirSource};

pub struct CleanAscribeUserType;

pub struct DeleteAscribeUserType;

impl MirPass for CleanAscribeUserType {
    fn run_pass<'a, 'tcx>(&self,
                          _tcx: TyCtxt<'a, 'tcx, 'tcx>,
                          _source: MirSource,
                          mir: &mut Mir<'tcx>) {
        let mut delete = DeleteAscribeUserType;
        delete.visit_mir(mir);
    }
}

impl<'tcx> MutVisitor<'tcx> for DeleteAscribeUserType {
    fn visit_statement(&mut self,
                       block: BasicBlock,
                       statement: &mut Statement<'tcx>,
                       location: Location) {
        if let StatementKind::AscribeUserType(..) = statement.kind {
            statement.make_nop();
        }
        self.super_statement(block, statement, location);
    }
}

pub struct CleanFakeReadsAndBorrows;

#[derive(Default)]
pub struct DeleteAndRecordFakeReads {
    fake_borrow_temporaries: FxHashSet<Local>,
}

pub struct DeleteFakeBorrows {
    fake_borrow_temporaries: FxHashSet<Local>,
}

// Removes any FakeReads from the MIR
impl MirPass for CleanFakeReadsAndBorrows {
    fn run_pass<'a, 'tcx>(&self,
                          _tcx: TyCtxt<'a, 'tcx, 'tcx>,
                          _source: MirSource,
                          mir: &mut Mir<'tcx>) {
        let mut delete_reads = DeleteAndRecordFakeReads::default();
        delete_reads.visit_mir(mir);
        let mut delete_borrows = DeleteFakeBorrows {
            fake_borrow_temporaries: delete_reads.fake_borrow_temporaries,
        };
        delete_borrows.visit_mir(mir);
    }
}

impl<'tcx> MutVisitor<'tcx> for DeleteAndRecordFakeReads {
    fn visit_statement(&mut self,
                       block: BasicBlock,
                       statement: &mut Statement<'tcx>,
                       location: Location) {
        if let StatementKind::FakeRead(cause, ref place) = statement.kind {
            if let FakeReadCause::ForMatchGuard = cause {
                match *place {
                    Place::Local(local) => self.fake_borrow_temporaries.insert(local),
                    _ => bug!("Fake match guard read of non-local: {:?}", place),
                };
            }
            statement.make_nop();
        }
        self.super_statement(block, statement, location);
    }
}

impl<'tcx> MutVisitor<'tcx> for DeleteFakeBorrows {
    fn visit_statement(&mut self,
                       block: BasicBlock,
                       statement: &mut Statement<'tcx>,
                       location: Location) {
        if let StatementKind::Assign(Place::Local(local), _) = statement.kind {
            if self.fake_borrow_temporaries.contains(&local) {
                statement.make_nop();
            }
        }
        self.super_statement(block, statement, location);
    }
}
<|endoftext|>


<commit_before>/**
   A parallel word-frequency counting program.

   This is meant primarily to demonstrate Rust's MapReduce framework.

   It takes a list of files on the command line and outputs a list of
   words along with how many times each word is used.

*/

use std;

import option = option;
import option::{some, none};
import std::{map, time};
import std::map::hashmap;
import io::reader_util;

import comm::chan;
import comm::port;
import comm::recv;
import comm::send;

fn map(input: ~str, emit: map_reduce::putter) {
    let f = io::str_reader(input);

    loop {
        alt read_word(f) { some(w) { emit(w, 1); } none { break; } }
    }
}

fn reduce(_word: ~str, get: map_reduce::getter) {
    let mut count = 0;

    loop { alt get() { some(_) { count += 1; } none { break; } } }
}

mod map_reduce {
    export putter;
    export getter;
    export mapper;
    export reducer;
    export map_reduce;

    type putter = fn@(~str, int);

    type mapper = fn@(~str, putter);

    type getter = fn@() -> option<int>;

    type reducer = fn@(~str, getter);

    enum ctrl_proto {
        find_reducer(~str, chan<chan<reduce_proto>>),
        mapper_done,
    }

    enum reduce_proto { emit_val(int), done, addref, release, }

    fn start_mappers(ctrl: chan<ctrl_proto>, -inputs: ~[~str]) ->
       ~[future::future<task::task_result>] {
        let mut results = ~[];
        for inputs.each |i| {
            do task::task().future_result(|-r| {
                results += ~[r]; // Add result for this task to the list
            }).spawn {
                map_task(ctrl, i); // Task body
            }
        }
        return results;
    }

    fn map_task(ctrl: chan<ctrl_proto>, input: ~str) {
        // log(error, "map_task " + input);
        let intermediates = map::str_hash();

        fn emit(im: map::hashmap<~str, chan<reduce_proto>>,
                ctrl: chan<ctrl_proto>, key: ~str, val: int) {
            let mut c;
            alt im.find(key) {
              some(_c) {
                c = _c;
              }
              none {
                let p = port();
                send(ctrl, find_reducer(key, chan(p)));
                c = recv(p);
                im.insert(key, c);
                send(c, addref);
              }
            }
            send(c, emit_val(val));
        }

        map(input, |a,b| emit(intermediates, ctrl, a, b) );

        for intermediates.each_value |v| { send(v, release); }

        send(ctrl, mapper_done);
    }

    fn reduce_task(key: ~str, out: chan<chan<reduce_proto>>) {
        let p = port();

        send(out, chan(p));

        let state = @{mut ref_count: 0, mut is_done: false};

        fn get(p: port<reduce_proto>, state: @{mut ref_count: int,
                                               mut is_done: bool})
            -> option<int> {
            while !state.is_done || state.ref_count > 0 {
                alt recv(p) {
                  emit_val(v) {
                    // error!{"received %d", v};
                    return some(v);
                  }
                  done {
                    // error!{"all done"};
                    state.is_done = true;
                  }
                  addref { state.ref_count += 1; }
                  release { state.ref_count -= 1; }
                }
            }
            return none;
        }

        reduce(key, || get(p, state) );
    }

    fn map_reduce(-inputs: ~[~str]) {
        let ctrl = port::<ctrl_proto>();

        // This task becomes the master control task. It task::_spawns
        // to do the rest.

        let mut reducers: map::hashmap<~str, chan<reduce_proto>>;

        reducers = map::str_hash();

        let mut num_mappers = vec::len(inputs) as int;
        let mut results = start_mappers(chan(ctrl), inputs);

        while num_mappers > 0 {
            alt recv(ctrl) {
              mapper_done {
                // error!{"received mapper terminated."};
                num_mappers -= 1;
              }
              find_reducer(k, cc) {
                let mut c;
                // log(error, "finding reducer for " + k);
                alt reducers.find(k) {
                  some(_c) {
                    // log(error,
                    // "reusing existing reducer for " + k);
                    c = _c;
                  }
                  none {
                    // log(error, "creating new reducer for " + k);
                    let p = port();
                    let ch = chan(p);
                    do task::task().future_result(|-r| {
                        results += ~[r]; // Add result for this task
                    }).spawn {
                        reduce_task(k, ch); // Task body
                    }
                    c = recv(p);
                    reducers.insert(k, c);
                  }
                }
                send(cc, c);
              }
            }
        }

        for reducers.each_value |v| { send(v, done); }

        for results.each |r| { future::get(r); }
    }
}

fn main(argv: ~[~str]) {
    let inputs = if vec::len(argv) < 2u {
        ~[input1(), input2(), input3()]
    } else {
        vec::map(vec::slice(argv, 1u, vec::len(argv)),
                 {|f| result::get(io::read_whole_file_str(f)) })
    };

    let start = time::precise_time_ns();

    map_reduce::map_reduce(inputs);
    let stop = time::precise_time_ns();

    let mut elapsed = stop - start;
    elapsed /= 1000000u64;

    log(error, ~"MapReduce completed in "
             + u64::str(elapsed) + ~"ms");
}

fn read_word(r: io::reader) -> option<~str> {
    let mut w = ~"";

    while !r.eof() {
        let c = r.read_char();

        if is_word_char(c) {
            w += str::from_char(c);
        } else { if w != ~"" { return some(w); } }
    }
    return none;
}

fn is_digit(c: char) -> bool {
    alt c {
      '0' { true }
      '1' { true }
      '2' { true }
      '3' { true }
      '4' { true }
      '5' { true }
      '6' { true }
      '7' { true }
      '8' { true }
      '9' { true }
      _ { false }
    }
}

fn is_alpha_lower(c: char) -> bool {
    alt c {
      'a' { true }
      'b' { true }
      'c' { true }
      'd' { true }
      'e' { true }
      'f' { true }
      'g' { true }
      'h' { true }
      'i' { true }
      'j' { true }
      'k' { true }
      'l' { true }
      'm' { true }
      'n' { true }
      'o' { true }
      'p' { true }
      'q' { true }
      'r' { true }
      's' { true }
      't' { true }
      'u' { true }
      'v' { true }
      'w' { true }
      'x' { true }
      'y' { true }
      'z' { true }
      _ { false }
    }
}

fn is_alpha_upper(c: char) -> bool {
    alt c {
      'A' { true }
      'B' { true }
      'C' { true }
      'D' { true }
      'E' { true }
      'F' { true }
      'G' { true }
      'H' { true }
      'I' { true }
      'J' { true }
      'K' { true }
      'L' { true }
      'M' { true }
      'N' { true }
      'O' { true }
      'P' { true }
      'Q' { true }
      'R' { true }
      'S' { true }
      'T' { true }
      'U' { true }
      'V' { true }
      'W' { true }
      'X' { true }
      'Y' { true }
      'Z' { true }
      _ { false }
    }
}

fn is_alpha(c: char) -> bool { is_alpha_upper(c) || is_alpha_lower(c) }

fn is_word_char(c: char) -> bool { is_alpha(c) || is_digit(c) || c == '_' }

fn input1() -> ~str { ~" Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Vestibulum tempor erat a dui commodo congue. Proin ac
imperdiet est. Nunc volutpat placerat justo, ac euismod nisl elementum
et. Nam a eros eleifend dolor porttitor auctor a a felis. Maecenas dui
odio, malesuada eget bibendum at, ultrices suscipit enim. Sed libero
dolor, sagittis eget mattis quis, imperdiet quis diam. Praesent eu
tristique nunc. Integer blandit commodo elementum. In eros lacus,
pretium vel fermentum vitae, euismod ut nulla.

Cras eget magna tempor mauris gravida laoreet. Suspendisse venenatis
volutpat molestie. Pellentesque suscipit nisl feugiat sem blandit
venenatis. Mauris id odio nec est elementum congue sed id
diam. Maecenas viverra, mi id aliquam commodo, ipsum dolor iaculis
odio, sed fringilla neque ipsum quis orci. Pellentesque dui dolor,
faucibus a rutrum sed, faucibus a mi. In eget sodales
ipsum. Pellentesque sollicitudin dapibus diam, ac interdum tellus
porta ac.

Donec ligula mi, sodales vel cursus a, dapibus ut sapien. In convallis
tempor libero, id dapibus mi sodales quis. Suspendisse
potenti. Vestibulum feugiat bibendum bibendum. Maecenas metus magna,
consequat in mollis at, malesuada id sem. Donec interdum viverra enim
nec ornare. Donec pellentesque neque magna.

Donec euismod, ante quis tempor pretium, leo lectus ornare arcu, sed
porttitor nisl ipsum elementum lectus. Nam rhoncus dictum sapien sed
tincidunt. Integer sit amet dui orci. Quisque lectus elit, dignissim
eget mattis nec, cursus nec erat. Fusce vitae metus nulla, et mattis
quam. Nullam sit amet diam augue. Nunc non ante eu enim lacinia
condimentum ac eget lectus.

Aliquam ut pulvinar tellus. Vestibulum ante ipsum primis in faucibus
orci luctus et ultrices posuere cubilia Curae; Pellentesque non urna
urna. Nulla facilisi. Aenean in felis quis massa aliquam eleifend non
sed libero. Proin sit amet iaculis urna. In hac habitasse platea
dictumst. Aenean scelerisque aliquet dolor, sit amet viverra est
laoreet nec. Curabitur non urna a augue rhoncus pulvinar. Integer
placerat vehicula nisl sed egestas. Morbi iaculis diam at erat
sollicitudin nec interdum libero tristique.  " }

fn input2() -> ~str { ~" Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Proin enim nibh, scelerisque faucibus accumsan id,
feugiat id ipsum. In luctus mauris a massa consequat dignissim. Donec
sit amet sem urna. Nullam pellentesque accumsan mi, at convallis arcu
pharetra in. Quisque euismod gravida nibh in rutrum. Phasellus laoreet
elit porta augue molestie nec imperdiet quam venenatis. Maecenas et
egestas arcu. Donec vulputate mauris enim. Aenean malesuada urna sed
dui eleifend quis posuere massa malesuada. Proin varius fringilla
feugiat. Donec mollis lorem sit amet ligula blandit quis fermentum dui
eleifend. Fusce molestie sodales magna in mattis. Aenean imperdiet,
elit sit amet accumsan vehicula, velit massa semper nibh, et varius
justo sem ut orci. Sed et magna lectus. Vestibulum vehicula, tellus
non dapibus mattis, libero ligula ullamcorper odio, in interdum odio
sem at mi.

Donec ut rhoncus mi. Donec ullamcorper, sem nec laoreet ullamcorper,
metus metus accumsan orci, ac luctus est velit a dolor. Donec eros
lectus, facilisis ut volutpat sit amet, pellentesque eu
velit. Praesent eget nibh et arcu vestibulum consequat. Pellentesque
habitant morbi tristique senectus et netus et malesuada fames ac
turpis egestas. Pellentesque lectus est, rhoncus ut cursus sit amet,
hendrerit quis dui. Maecenas vel purus in tellus luctus semper vel non
orci. Proin viverra, erat eget pretium ultrices, quam quam vulputate
tortor, eu dapibus risus nunc ac ipsum. Vestibulum ante ipsum primis
in faucibus orci luctus et ultrices posuere cubilia Curae; Ut aliquet
augue volutpat arcu mattis ullamcorper. Quisque vulputate consectetur
massa, quis cursus mauris lacinia vitae. Morbi id mi eu leo accumsan
aliquet ac et arcu. Quisque risus nisi, rhoncus vulputate egestas sed,
rhoncus quis risus. Sed semper odio sed nulla accumsan vitae auctor
tortor mattis.

Vivamus vitae mauris turpis. Praesent consectetur mi non sem lacinia a
cursus sapien gravida. Aenean viverra turpis sit amet ligula
vestibulum a ornare nunc feugiat. Mauris et risus arcu. Cras dictum
porta cursus. Donec tempus laoreet eros. Nam nec turpis non dui
hendrerit laoreet eu ut ipsum. Nam in sem eget turpis lacinia euismod
eu eget nulla.

Suspendisse at varius elit. Donec consectetur pharetra massa nec
viverra. Cras vehicula lorem id sapien hendrerit tristique. Mauris
vitae mi ipsum. Suspendisse feugiat commodo iaculis. Maecenas vitae
dignissim nunc. Sed hendrerit, arcu et aliquet suscipit, urna quam
fermentum eros, vel accumsan metus quam quis risus. Praesent id eros
pulvinar tellus fringilla cursus. Sed nec vulputate ipsum. Suspendisse
sagittis, magna vitae faucibus semper, nibh felis vehicula tortor, et
molestie velit lorem ac massa.

Duis aliquam accumsan lobortis. Morbi interdum cursus risus, vel
dapibus nisl fermentum sit amet. Etiam in mauris at lectus lacinia
mollis. Proin pretium sem nibh, id scelerisque arcu. Mauris pretium
adipiscing metus. Suspendisse quis convallis augue. Aliquam sed dui
augue, vel tempor ligula. Suspendisse luctus velit quis urna suscipit
sit amet ullamcorper nunc mollis. Praesent vitae velit justo. Donec
quis risus felis. Nullam rutrum, odio non varius ornare, tortor odio
posuere felis, eget accumsan sem sapien et nunc. Fusce mi neque,
elementum non convallis eu, hendrerit id arcu. Morbi tempus tincidunt
ullamcorper. Nullam blandit, diam quis sollicitudin tincidunt, elit
justo varius lacus, aliquet luctus neque nibh quis turpis. Etiam massa
sapien, tristique ut consectetur eu, elementum vel orci.  " }

fn input3() -> ~str { ~" Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Pellentesque bibendum sapien ut magna fringilla
mollis. Vivamus in neque non metus faucibus accumsan eu pretium
nunc. Ut erat augue, pulvinar eget blandit nec, cursus quis
ipsum. Aliquam eu ornare risus. Mauris ipsum tortor, posuere vel
gravida ut, tincidunt eu nunc. Aenean pellentesque, justo eu aliquam
condimentum, neque eros feugiat nibh, in dictum nisi augue euismod
lectus. Nam fringilla placerat metus aliquam rutrum. Nullam dapibus
vehicula ligula ut tempor. Aliquam vehicula, diam vitae fermentum
aliquam, justo augue venenatis enim, porta euismod dolor libero in
arcu. Sed sollicitudin dictum eros non ornare. Donec nec purus
orci. Mauris euismod fringilla consequat. Praesent non erat quis risus
dapibus semper ac adipiscing lorem. Aliquam pulvinar dapibus
mollis. Donec fermentum sollicitudin metus, sit amet condimentum leo
adipiscing a.

Vestibulum mi felis, commodo placerat rhoncus sed, feugiat tincidunt
orci. Integer faucibus ornare placerat. Nam et odio massa. Suspendisse
porttitor nunc quis mi mollis imperdiet. Ut ut neque ipsum, sit amet
facilisis erat. Nam ac lacinia turpis. Vivamus ullamcorper iaculis
odio, et euismod sem imperdiet non. Duis porta felis sit amet nunc
venenatis eu vestibulum nisi scelerisque. Nullam luctus mollis nunc
vel pulvinar. Nam lorem tellus, imperdiet sed sodales eu, auctor ut
nunc.

Nulla at mauris at leo sagittis varius eu a elit. Etiam consequat,
tellus ut sagittis porttitor, est justo convallis eros, quis suscipit
justo tortor vitae sem. In in odio augue. Pellentesque habitant morbi
tristique senectus et netus et malesuada fames ac turpis
egestas. Nulla varius ornare ligula quis euismod. Maecenas lobortis
sodales sapien a mattis. Nulla blandit lobortis lacus, ut lobortis
neque dictum ut. Praesent semper laoreet nisl. Etiam arcu eros,
pretium eget eleifend eu, condimentum quis leo. Donec imperdiet porta
erat. Aenean tempor sapien ut arcu porta mollis. Duis ultrices commodo
quam venenatis commodo.

Aliquam odio tellus, tincidunt nec condimentum pellentesque, semper
eget magna. Nam et lacus urna. Pellentesque urna nisi, pharetra vitae
dignissim non, scelerisque eu massa. Sed sapien neque, cursus a
malesuada ut, porta et quam. Donec odio sapien, blandit non aliquam
vel, lobortis quis ligula. Nullam fermentum velit nec quam ultrices et
venenatis sapien congue. Pellentesque vitae nunc arcu. Nullam eget
laoreet nulla. Curabitur dignissim convallis nunc sed blandit. Sed ac
ipsum mi. Ut euismod tellus hendrerit arcu egestas sollicitudin. Nam
eget laoreet ipsum. Morbi sed nulla odio, at volutpat ante. Vivamus
elementum dictum gravida.

Phasellus diam nisi, ullamcorper et placerat non, ultrices ut
lectus. Etiam tincidunt scelerisque imperdiet. Quisque pretium pretium
urna quis cursus. Sed sit amet velit sem. Maecenas eu orci et leo
ultricies dictum. Mauris pellentesque ante a purus gravida
convallis. Integer non tellus ante. Nulla hendrerit lobortis augue sit
amet vulputate. Donec cursus hendrerit diam convallis
luctus. Curabitur ipsum mauris, fermentum quis tincidunt ac, laoreet
sollicitudin sapien. Fusce velit urna, gravida non pulvinar eu, tempor
id nunc.  " }
<commit_msg>Removing an obsolete benchmark<commit_after><|endoftext|>


<commit_before><commit_msg>new test showing off the improved inference<commit_after>fn foo(i: int) -> int { i + 1 }

fn apply<A>(f: fn(A) -> A, v: A) -> A { f(v) }

fn main() {
    let f = {|i| foo(i)};
    assert apply(f, 2) == 3;
}
<|endoftext|>


<commit_before><commit_msg>parsing the binaries<commit_after>#![feature(macro_rules)]
#![allow(unused_variable)]
use std::io::{File};

macro_rules! unwrap(
    ($inp: expr) => (
        match $inp {
            Ok(r) => r,
            Err(e) => fail!("{}",e)
        }
    );
)

fn main() {
    let path = Path::new("/home/alex/.bitcoin/blocks/blk00000.dat");
    let mut file = unwrap!(File::open(&path));

    verify_block(&mut file);
    parse_block(&mut file);
}

fn parse_block(file: &mut File) {
    let header = unwrap!(file.read_le_u32());
    //println!("header={}",header);

    let version = unwrap!(file.read_le_u32());
    println!("version={}",version);

    let sha = unwrap!(file.read_exact(32));
    //println!("sha={}",sha);

    let merkle = unwrap!(file.read_exact(32));
    //println!("merkle={}",merkle);

    let timestamp = unwrap!(file.read_le_u32());
    println!("timestamp={}",timestamp);

    let difficulty = unwrap!(file.read_le_u32());
    //println!("difficulty={}",difficulty);

    let nonce = unwrap!(file.read_le_u32());
    println!("nonce={}",nonce);

    let transaction_count = read_vli(file);
    println!("transaction_count={}",transaction_count);

    for _ in range(0, transaction_count) {
        let transaction_version = unwrap!(file.read_le_u32());

        let input_count = read_vli(file);
        println!("{} inputs", input_count);
        for _ in range(0, input_count) {
            let transaction_hash = unwrap!(file.read_exact(32));
            println!("tx hash={}",transaction_hash);
            let transaction_index = unwrap!(file.read_le_u32());
            let script_length = read_vli(file) as uint; // is this okay?
            let script = unwrap!(file.read_exact(script_length));
            let sequence_number = unwrap!(file.read_le_u32());
            assert!(sequence_number == 0xFFFFFFFFu32);
        }

        let output_count = read_vli(file);
        println!("{} outputs", output_count);
        for _ in range(0, output_count) {
            let value = unwrap!(file.read_le_u64());
            println!("value={}", value);
            let script_length = read_vli(file) as uint;
            let script = unwrap!(file.read_exact(script_length));
        }

        let lock_time = unwrap!(file.read_le_u32());
        assert!(lock_time == 0u32);
    }

    // Now, we should be done with the block.
    assert!(file.eof());
}

fn read_vli(file: &mut File) -> u64 {
    let flag = unwrap!(file.read_u8());
    if flag < 0xfd {
        flag as u64
    } else if flag == 0xfd {
        (unwrap!(file.read_le_u16())) as u64
    } else if flag == 0xfe {
        (unwrap!(file.read_le_u32())) as u64
    } else {
        unwrap!(file.read_le_u64())
    }
}

fn verify_block(file: &mut File) {
    print!("verifying block...");

    let magic_uint : u32 = 0xD9B4BEF9;
    let file_uint = unwrap!(file.read_le_u32());
    assert!(magic_uint == file_uint);

    println!("verify passed...");
}
<|endoftext|>


<commit_before><commit_msg>Add prelude.rs for ios tests<commit_after><|endoftext|>


<commit_before><commit_msg>Add roundtrip benchmark<commit_after>#![feature(test)]

extern crate las;
extern crate test;

use las::{Point, Reader, Writer};
use test::Bencher;

fn roundtrip(npoints: usize) {
    let mut writer = Writer::default();
    for _ in 0..npoints {
        writer.write(Point::default()).unwrap();
    }
    let mut reader = Reader::new(writer.into_inner().unwrap()).unwrap();
    for point in reader.points() {
        let _ = point.unwrap();
    }
}

#[bench]
fn roundtrip_0(bencher: &mut Bencher) {
    bencher.iter(|| roundtrip(0));
}

#[bench]
fn roundtrip_1(bencher: &mut Bencher) {
    bencher.iter(|| roundtrip(1));
}

#[bench]
fn roundtrip_100(bencher: &mut Bencher) {
    bencher.iter(|| roundtrip(100));
}

#[bench]
fn roundtrip_10000(bencher: &mut Bencher) {
    bencher.iter(|| roundtrip(10000));
}
<|endoftext|>


<commit_before>extern mod std;

use libc::c_char;
use libc::c_int;
use libc::size_t;
use libc::c_ulong;
use libc::c_void;
use ptr::null;
use ptr::addr_of;
use str::as_c_str;
use str::to_str;

struct mpz_struct {
  _mp_alloc: c_int,
  _mp_size: c_int,
  _mp_d: *c_void
}

type mpz_t = *mpz_struct;

extern mod gmp {
  fn __gmpz_init(x: mpz_t);
  fn __gmpz_clear(x: mpz_t);
  fn __gmpz_set_str(rop: mpz_t, str: *c_char, base: c_int) -> c_int;
  fn __gmpz_get_str(str: *c_char, base: c_int, op: mpz_t) -> *c_char;
  fn __gmpz_sizeinbase(op: mpz_t, base: c_int) -> size_t;
  fn __gmpz_cmp(op: mpz_t, op2: mpz_t) -> c_int;
  fn __gmpz_cmp_ui(op1: mpz_t, op2: c_ulong) -> c_int;
  fn __gmpz_add(rop: mpz_t, op1: mpz_t, op2: mpz_t);
  fn __gmpz_sub(rop: mpz_t, op1: mpz_t, op2: mpz_t);
  fn __gmpz_mul(rop: mpz_t, op1: mpz_t, op2: mpz_t);
  fn __gmpz_neg(rop: mpz_t, op: mpz_t);
  fn __gmpz_tdiv_q(r: mpz_t, n: mpz_t, d: mpz_t);
  fn __gmpz_mod(r: mpz_t, n: mpz_t, d: mpz_t);
}

use gmp::*;

pub struct Mpz {
  priv mpz: mpz_struct,

  drop {
    __gmpz_clear(addr_of(&self.mpz));
  }
}

impl Mpz {
  fn set_str(&self, s: &str, base: int) -> bool {
    let mpz = addr_of(&self.mpz);
    let r = as_c_str(s, { |s| __gmpz_set_str(mpz, s, base as c_int) });
    r == 0
  }

  fn size_in_base(&self, base: int) -> uint {
    __gmpz_sizeinbase(addr_of(&self.mpz), base as c_int) as uint
  }
}

impl Mpz: cmp::Eq {
  pure fn eq(other: &Mpz) -> bool unsafe {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) == 0
  }
  pure fn ne(other: &Mpz) -> bool unsafe {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) != 0
  }
}

impl Mpz: cmp::Ord {
  pure fn lt(other: &Mpz) -> bool unsafe {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) < 0
  }
  pure fn le(other: &Mpz) -> bool unsafe {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) <= 0
  }
  pure fn gt(other: &Mpz) -> bool unsafe {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) > 0
  }
  pure fn ge(other: &Mpz) -> bool unsafe {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) >= 0
  }
}

impl Mpz: num::Num {
  pure fn add(other: &Mpz) -> Mpz unsafe {
    let res = init();
    __gmpz_add(addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn sub(other: &Mpz) -> Mpz unsafe {
    let res = init();
    __gmpz_sub(addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn mul(other: &Mpz) -> Mpz unsafe {
    let res = init();
    __gmpz_mul(addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn div(other: &Mpz) -> Mpz unsafe {
    if __gmpz_cmp_ui(addr_of(&self.mpz), 0) == 0 {
      fail ~"divide by zero";
    }

    let res = init();
    __gmpz_tdiv_q(addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn modulo(other: &Mpz) -> Mpz unsafe {
    if __gmpz_cmp_ui(addr_of(&self.mpz), 0) == 0 {
      fail ~"divide by zero";
    }

    let res = init();
    __gmpz_mod(addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn neg() -> Mpz unsafe {
    let res = init();
    __gmpz_neg(addr_of(&res.mpz), addr_of(&self.mpz));
    res
  }
  pure fn to_int() -> int {
    fail ~"not implemented";
  }
  static pure fn from_int(other: int) -> Mpz unsafe {
    fail ~"not implemented";
  }
}

fn init() -> Mpz {
  let mpz = mpz_struct { _mp_alloc: 0, _mp_size: 0, _mp_d: null() };
  __gmpz_init(addr_of(&mpz));
  Mpz { mpz: mpz }
}

#[cfg(test)]
mod tests {
  #[test]
  fn size_in_base() {
    let x = init();
    x.set_str("150000", 10);
    assert(x.size_in_base(10) == 6);
  }

  #[test]
  fn eq() {
    let x = init();
    x.set_str("4242142195", 10);
    let y = init();
    y.set_str("4242142195", 10);
    let z = init();
    z.set_str("4242142196", 10);

    assert(x == y);
    assert(x != z);
    assert(y != z);
  }

  #[test]
  fn ord() {
    let x = init();
    x.set_str("40000000000000000000000", 10);
    let y = init();
    y.set_str("45000000000000000000000", 10);
    let z = init();
    z.set_str("50000000000000000000000", 10);

    assert(x < y && x < z && y < z);
    assert(x <= x && x <= y && x <= z && y <= z);
    assert(z > y && z > x && y > x);
    assert(z >= z && z >= y && z >= x && y >= x);
  }

  #[test]
  #[should_fail]
  fn div_zero() {
    let x = init();
    x / x;
  }

  #[test]
  #[should_fail]
  fn modulo_zero() {
    let x = init();
    x % x;
  }

  #[test]
  fn test_div_round() {
    let x = init();
    let y = init();
    let mut z: Mpz;

    x.set_str("2", 10);
    y.set_str("3", 10);
    z = x / y;
    assert(__gmpz_cmp_ui(addr_of(&z.mpz), 2 / 3) == 0);

    x.set_str("2", 10);
    y.set_str("-3", 10);
    z = x / y;
    assert(__gmpz_cmp_ui(addr_of(&z.mpz), 2 / -3) == 0);
  }
}
<commit_msg>make init public<commit_after>extern mod std;

use libc::c_char;
use libc::c_int;
use libc::size_t;
use libc::c_ulong;
use libc::c_void;
use ptr::null;
use ptr::addr_of;
use str::as_c_str;
use str::to_str;

struct mpz_struct {
  _mp_alloc: c_int,
  _mp_size: c_int,
  _mp_d: *c_void
}

type mpz_t = *mpz_struct;

extern mod gmp {
  fn __gmpz_init(x: mpz_t);
  fn __gmpz_clear(x: mpz_t);
  fn __gmpz_set_str(rop: mpz_t, str: *c_char, base: c_int) -> c_int;
  fn __gmpz_get_str(str: *c_char, base: c_int, op: mpz_t) -> *c_char;
  fn __gmpz_sizeinbase(op: mpz_t, base: c_int) -> size_t;
  fn __gmpz_cmp(op: mpz_t, op2: mpz_t) -> c_int;
  fn __gmpz_cmp_ui(op1: mpz_t, op2: c_ulong) -> c_int;
  fn __gmpz_add(rop: mpz_t, op1: mpz_t, op2: mpz_t);
  fn __gmpz_sub(rop: mpz_t, op1: mpz_t, op2: mpz_t);
  fn __gmpz_mul(rop: mpz_t, op1: mpz_t, op2: mpz_t);
  fn __gmpz_neg(rop: mpz_t, op: mpz_t);
  fn __gmpz_tdiv_q(r: mpz_t, n: mpz_t, d: mpz_t);
  fn __gmpz_mod(r: mpz_t, n: mpz_t, d: mpz_t);
}

use gmp::*;

pub struct Mpz {
  priv mpz: mpz_struct,

  drop {
    __gmpz_clear(addr_of(&self.mpz));
  }
}

impl Mpz {
  fn set_str(&self, s: &str, base: int) -> bool {
    let mpz = addr_of(&self.mpz);
    let r = as_c_str(s, { |s| __gmpz_set_str(mpz, s, base as c_int) });
    r == 0
  }

  fn size_in_base(&self, base: int) -> uint {
    __gmpz_sizeinbase(addr_of(&self.mpz), base as c_int) as uint
  }
}

impl Mpz: cmp::Eq {
  pure fn eq(other: &Mpz) -> bool unsafe {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) == 0
  }
  pure fn ne(other: &Mpz) -> bool unsafe {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) != 0
  }
}

impl Mpz: cmp::Ord {
  pure fn lt(other: &Mpz) -> bool unsafe {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) < 0
  }
  pure fn le(other: &Mpz) -> bool unsafe {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) <= 0
  }
  pure fn gt(other: &Mpz) -> bool unsafe {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) > 0
  }
  pure fn ge(other: &Mpz) -> bool unsafe {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) >= 0
  }
}

impl Mpz: num::Num {
  pure fn add(other: &Mpz) -> Mpz unsafe {
    let res = init();
    __gmpz_add(addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn sub(other: &Mpz) -> Mpz unsafe {
    let res = init();
    __gmpz_sub(addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn mul(other: &Mpz) -> Mpz unsafe {
    let res = init();
    __gmpz_mul(addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn div(other: &Mpz) -> Mpz unsafe {
    if __gmpz_cmp_ui(addr_of(&self.mpz), 0) == 0 {
      fail ~"divide by zero";
    }

    let res = init();
    __gmpz_tdiv_q(addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn modulo(other: &Mpz) -> Mpz unsafe {
    if __gmpz_cmp_ui(addr_of(&self.mpz), 0) == 0 {
      fail ~"divide by zero";
    }

    let res = init();
    __gmpz_mod(addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn neg() -> Mpz unsafe {
    let res = init();
    __gmpz_neg(addr_of(&res.mpz), addr_of(&self.mpz));
    res
  }
  pure fn to_int() -> int {
    fail ~"not implemented";
  }
  static pure fn from_int(other: int) -> Mpz unsafe {
    fail ~"not implemented";
  }
}

pub fn init() -> Mpz {
  let mpz = mpz_struct { _mp_alloc: 0, _mp_size: 0, _mp_d: null() };
  __gmpz_init(addr_of(&mpz));
  Mpz { mpz: mpz }
}

#[cfg(test)]
mod tests {
  #[test]
  fn size_in_base() {
    let x = init();
    x.set_str("150000", 10);
    assert(x.size_in_base(10) == 6);
  }

  #[test]
  fn eq() {
    let x = init();
    x.set_str("4242142195", 10);
    let y = init();
    y.set_str("4242142195", 10);
    let z = init();
    z.set_str("4242142196", 10);

    assert(x == y);
    assert(x != z);
    assert(y != z);
  }

  #[test]
  fn ord() {
    let x = init();
    x.set_str("40000000000000000000000", 10);
    let y = init();
    y.set_str("45000000000000000000000", 10);
    let z = init();
    z.set_str("50000000000000000000000", 10);

    assert(x < y && x < z && y < z);
    assert(x <= x && x <= y && x <= z && y <= z);
    assert(z > y && z > x && y > x);
    assert(z >= z && z >= y && z >= x && y >= x);
  }

  #[test]
  #[should_fail]
  fn div_zero() {
    let x = init();
    x / x;
  }

  #[test]
  #[should_fail]
  fn modulo_zero() {
    let x = init();
    x % x;
  }

  #[test]
  fn test_div_round() {
    let x = init();
    let y = init();
    let mut z: Mpz;

    x.set_str("2", 10);
    y.set_str("3", 10);
    z = x / y;
    assert(__gmpz_cmp_ui(addr_of(&z.mpz), 2 / 3) == 0);

    x.set_str("2", 10);
    y.set_str("-3", 10);
    z = x / y;
    assert(__gmpz_cmp_ui(addr_of(&z.mpz), 2 / -3) == 0);
  }
}
<|endoftext|>


<commit_before><commit_msg>Add basic transfer test<commit_after>use actix::prelude::*;
use godcoin::prelude::*;

mod common;
pub use common::*;

#[test]
fn basic_transfer() {
    System::run(|| {
        let minter = TestMinter::new();
        let to_addr = KeyPair::gen();

        let create_tx = |fee: &str, amount: Asset| {
            let mut tx = TransferTx {
                base: create_tx_header(TxType::TRANSFER, fee),
                from: (&minter.genesis_info().script).into(),
                to: (&to_addr.0).into(),
                amount,
                memo: vec![],
                script: minter.genesis_info().script.clone(),
            };
            tx.append_sign(&minter.genesis_info().wallet_keys[3]);
            tx.append_sign(&minter.genesis_info().wallet_keys[0]);
            TxVariant::TransferTx(tx)
        };

        let bal = get_asset("1.0000 GRAEL");
        let tx = create_tx("1.0000 GRAEL", bal);
        let fut = minter.request(MsgRequest::Broadcast(tx));
        System::current().arbiter().send(
            fut.and_then(move |res| {
                assert_eq!(res, MsgResponse::Broadcast());
                minter.produce_block().map(|_| minter)
            })
            .and_then(move |minter| {
                let chain = minter.chain();
                let cur_bal = chain.get_balance(&to_addr.0.into(), &[]);
                assert_eq!(cur_bal, Some(bal));

                System::current().stop();
                Ok(())
            }),
        );
    })
    .unwrap();
}
<|endoftext|>


<commit_before><commit_msg>Document response functions<commit_after><|endoftext|>


<commit_before><commit_msg>New demo showing how to use the values in envelopes at the playhead position.<commit_after>#[macro_use]
extern crate conrod_core;
extern crate nannou;
extern crate nannou_timeline as timeline;
extern crate pitch_calc;
extern crate time_calc;

use nannou::prelude::*;
use nannou::ui::prelude::*;
use pitch_calc as pitch;
use std::iter::once;
use time_calc as time;
use timeline::track::automation::{BangValue as Bang, Envelope, Point, ToggleValue as Toggle};
use timeline::track::piano_roll;
use timeline::{bars, track};

const BPM: time::calc::Bpm = 140.0;
const ONE_SECOND_MS: time::calc::Ms = 1_000.0;
const PPQN: time::Ppqn = 9600;
const WIDTH: u32 = 800;
const HEIGHT: u32 = 600;

fn main() {
    nannou::app(model).update(update).run();
}

struct Model {
    _window: window::Id,
    ui: Ui,
    ids: Ids,
    timeline_data: TimelineData,
    playing: bool,
}

struct TimelineData {
    playhead_ticks: time::Ticks,
    bars: Vec<time::TimeSig>,
    notes: Vec<piano_roll::Note>,
    tempo_envelope: track::automation::numeric::Envelope<f32>,
    octave_envelope: track::automation::numeric::Envelope<i32>,
    toggle_envelope: track::automation::toggle::Envelope,
    bang_envelope: track::automation::bang::Envelope,
}

// Create all of our unique `WidgetId`s with the `widget_ids!` macro.
conrod_core::widget_ids! {
    struct Ids {
        window,
        ruler,
        timeline,
    }
}

fn model(app: &App) -> Model {
    let physical_device = best_gpu(app).expect("no available GPU detected on system");
    println!("Physical device: {}", physical_device.name());
    let _window = app
        .new_window()
        .key_pressed(key_pressed)
        .with_dimensions(WIDTH, HEIGHT)
        .with_title("Timeline Demo")
        .vk_physical_device(physical_device)
        .view(view)
        .build()
        .unwrap();

    // Create the UI.
    let mut ui = app.new_ui().build().unwrap();
    let ids = Ids::new(ui.widget_id_generator());

    // Start the playhead at the beginning.
    let playhead_ticks = time::Ticks::from(0);

    // A sequence of bars with varying time signatures.
    let bars = vec![
        time::TimeSig { top: 4, bottom: 4 },
        time::TimeSig { top: 4, bottom: 4 },
        time::TimeSig { top: 6, bottom: 8 },
        time::TimeSig { top: 6, bottom: 8 },
        time::TimeSig { top: 4, bottom: 4 },
        time::TimeSig { top: 4, bottom: 4 },
        time::TimeSig { top: 7, bottom: 8 },
        time::TimeSig { top: 7, bottom: 8 },
    ];

    let notes = bars::WithStarts::new(bars.iter().cloned(), PPQN)
        .enumerate()
        .map(|(i, (time_sig, start))| {
            let end = start + time_sig.ticks_per_bar(PPQN);
            let period = timeline::Period { start, end };
            let pitch = pitch::Step((24 + (i * 5) % 12) as f32).to_letter_octave();
            piano_roll::Note { period, pitch }
        })
        .collect();

    let tempo_envelope = {
        let start = Point {
            ticks: time::Ticks(0),
            value: 20.0,
        };
        let points = bars::Periods::new(bars.iter().cloned(), PPQN)
            .enumerate()
            .map(|(i, period)| Point {
                ticks: period.end,
                value: 20.0 + (i + 1) as f32 * 60.0 % 220.0,
            });
        Envelope::from_points(once(start).chain(points), 20.0, 240.0)
    };

    let octave_envelope = {
        let start = Point {
            ticks: time::Ticks(0),
            value: 0,
        };
        let points = bars::WithStarts::new(bars.iter().cloned(), PPQN)
            .enumerate()
            .flat_map(|(i, (ts, mut start))| {
                let bar_end = start + ts.ticks_per_bar(PPQN);
                let mut j = 0;
                std::iter::from_fn(move || {
                    if start >= bar_end {
                        return None;
                    }

                    let end = start + time::Ticks(PPQN as _);
                    let end = if end > bar_end { bar_end } else { end };
                    let point = Point {
                        ticks: end,
                        value: 1 + ((i as i32 + j as i32) * 3) % 12,
                    };
                    start = end;
                    j += 1;
                    Some(point)
                })
            });
        Envelope::from_points(once(start).chain(points), 0, 12)
    };

    let toggle_envelope = {
        let start = Point {
            ticks: time::Ticks(0),
            value: Toggle(random()),
        };
        let points = bars::Periods::new(bars.iter().cloned(), PPQN).map(|period| Point {
            ticks: period.end,
            value: Toggle(random()),
        });
        Envelope::from_points(once(start).chain(points), Toggle(false), Toggle(true))
    };

    let bang_envelope = {
        let points = bars::Periods::new(bars.iter().cloned(), PPQN).map(|period| Point {
            ticks: period.start,
            value: Bang,
        });
        Envelope::from_points(points, Bang, Bang)
    };

    let timeline_data = TimelineData {
        playhead_ticks,
        bars,
        notes,
        tempo_envelope,
        octave_envelope,
        toggle_envelope,
        bang_envelope,
    };

    Model {
        _window,
        ui,
        ids,
        timeline_data,
        playing: false,
    }
}

fn update(_app: &App, model: &mut Model, update: Update) {
    let Model {
        ids,
        ui,
        timeline_data,
        playing,
        ..
    } = model;

    // Update the user interface.
    set_widgets(&mut ui.set_widgets(), ids, timeline_data);

    // Get the current bpm from the tempo_envelope automation track.
    use timeline::track::automation::EnvelopeTrait; // needed to use the .y(Ticks) method on the envelope
    let tempo_value = timeline_data.tempo_envelope.y(timeline_data.playhead_ticks);
    let current_bpm = tempo_value.unwrap_or(BPM as f32) as f64;

    // Update the playhead.
    let delta_secs = if *playing {
        update.since_last.secs()
        } else {
            0.0
        };
    let delta_ticks = time::Ms(delta_secs * ONE_SECOND_MS).to_ticks(current_bpm, PPQN);
    let total_duration_ticks =
        timeline::bars_duration_ticks(timeline_data.bars.iter().cloned(), PPQN);
    let previous_playhead_ticks = timeline_data.playhead_ticks.clone();
    timeline_data.playhead_ticks = (timeline_data.playhead_ticks + delta_ticks) % total_duration_ticks;

    // Check if a bang in the bang_envelope has banged.
    for bang_point in timeline_data.bang_envelope.points() {
        if bang_point.ticks > previous_playhead_ticks
            && bang_point.ticks <= timeline_data.playhead_ticks
        {
            println!("BANG!");
        }
    }

    // Check if a note is playing
    for note in &timeline_data.notes {
        if timeline_data.playhead_ticks >= note.period.start
            && timeline_data.playhead_ticks < note.period.end
        {
            println!("Note playing: {:?}", note.pitch);
        }
    }

}

fn view(app: &App, model: &Model, frame: &Frame) {
    model.ui.draw_to_frame(app, frame).unwrap();
}

// Update / draw the Ui.
fn set_widgets(ui: &mut UiCell, ids: &Ids, data: &mut TimelineData) {
    use timeline::Timeline;

    // Main window canvas.
    widget::Canvas::new()
        .border(0.0)
        .color(ui::color::DARK_CHARCOAL.alpha(0.5))
        .set(ids.window, ui);

    let TimelineData {
        playhead_ticks,
        bars,
        notes,
        tempo_envelope,
        octave_envelope,
        toggle_envelope,
        bang_envelope,
    } = data;

    let ticks = playhead_ticks.clone();
    let color = ui::color::LIGHT_BLUE;

    ////////////////////
    ///// TIMELINE /////
    ////////////////////
    //
    // Set the `Timeline` widget.
    //
    // This returns a context on which we can begin setting our tracks, playhead and scrollbar.
    //
    // The context is used in three stages:
    //
    // 1. `PinnedTracks` for setting tracks that should be pinned to the top of the timeline.
    // 2. `Tracks` for setting regular tracks.
    // 3. `Final` for setting the `Playhead` and `Scrollbar` widgets after all tracks are set.

    let context = Timeline::new(bars.iter().cloned(), PPQN)
        .playhead(ticks)
        .color(color)
        .wh_of(ids.window)
        .middle_of(ids.window)
        .border(1.0)
        .border_color(ui::color::CHARCOAL)
        .set(ids.timeline, ui);

    /////////////////////////
    ///// PINNED TRACKS /////
    /////////////////////////
    //
    // Pin the ruler track to the top of the timeline.
    //
    // All pinned tracks must be `set` prior to non-pinned tracks.
    {
        let ruler = track::Ruler::new(context.ruler, &context.bars, PPQN).color(color);
        let track = context.set_next_pinned_track(ruler, ui);
        for triggered in track.event {
            *playhead_ticks = triggered.ticks;
        }
    }

    //////////////////
    ///// TRACKS /////
    //////////////////

    // Now that we've finished setting the pinned tracks, move on to the `Tracks` context.
    let context = context.start_tracks(ui);

    {
        // Piano roll.
        let piano_roll = track::PianoRoll::new(&context.bars, PPQN, &notes[..]).color(color);
        let track = context.set_next_track(piano_roll, ui);
        for event in track.event {
            use timeline::track::piano_roll::Event;
            match event {
                Event::NoteOn(_note_idx) => (),
                Event::NoteOff(_note_idx) => (),
                Event::NotePlayed(_note_idx) => (),
            }
        }

        // A macro for common logic between tempo and octave "numeric" envelopes.
        macro_rules! numeric_automation {
            ($envelope:expr) => {
                let track = {
                    let automation =
                        track::automation::Numeric::new(&context.bars, PPQN, $envelope)
                            .color(color);
                    context.set_next_track(automation, ui)
                };
                for event in track.event {
                    use timeline::track::automation::numeric::Event;
                    match event {
                        Event::Interpolate(number) => println!("{}",number),
                        Event::Mutate(mutate) => mutate.apply($envelope),
                    }
                }
            };
        }

        // Tempo automation.
        numeric_automation!(tempo_envelope);
        // Octave automation.
        numeric_automation!(octave_envelope);

        // Toggle automation.
        let track = {
            let automation =
                track::automation::Toggle::new(&context.bars, PPQN, toggle_envelope).color(color);
            context.set_next_track(automation, ui)
        };
        for event in track.event {
            use timeline::track::automation::toggle::Event;
            match event {
                Event::Interpolate(_toggle) => (),
                Event::SwitchTo(_toggle) => (),
                Event::Mutate(mutate) => mutate.apply(toggle_envelope),
            }
        }

        // Bang automation.
        let track = {
            let automation =
                track::automation::Bang::new(&context.bars, PPQN, bang_envelope).color(color);
            context.set_next_track(automation, ui)
        };
        for event in track.event {
            use timeline::track::automation::bang::Event;
            match event {
                Event::Mutate(mutate) => mutate.apply(bang_envelope),
                _ => ()
            }
        }
    }

    ////////////////////////////////
    ///// PLAYHEAD & SCROLLBAR /////
    ////////////////////////////////

    // Now that all tracks have been set, finish up and set the `Playhead` and `Scrollbar`.
    let context = context.end_tracks();

    // Set the playhead after all tracks have been set.
    for event in context.set_playhead(ui) {
        use timeline::playhead::Event;
        match event {
            Event::Pressed => println!("Playhead pressed!"),
            Event::DraggedTo(ticks) => *playhead_ticks = ticks,
            Event::Released => println!("Playhead released!"),
        }
    }

    // Set the scrollbar if it is visible.
    context.set_scrollbar(ui);
}

fn key_pressed(_app: &App, model: &mut Model, key: Key) {
    match key {

        // Toggle play when space is pressed
        Key::Space => {
            model.playing = !model.playing;
        }
        Key::R => {
            let bars = model.timeline_data.bars.clone();
            model.timeline_data.notes = bars::WithStarts::new(bars.iter().cloned(), PPQN)
                .enumerate()
                .map(|(i, (time_sig, start))| {
                    let end = start + time_sig.ticks_per_bar(PPQN);
                    let period = timeline::Period { start, end };
                    let pitch = pitch::Step((24 + (i * (random::<usize>() % 11)) % 12) as f32).to_letter_octave();
                    piano_roll::Note { period, pitch }
                })
                .collect();
        }
        _ => {}
    }
}

// Return a dedicated GPU device if there is one.
fn find_discrete_gpu<'a, I>(devices: I) -> Option<vk::PhysicalDevice<'a>>
where
    I: IntoIterator<Item = vk::PhysicalDevice<'a>>,
{
    devices
        .into_iter()
        .find(|d| d.ty() == vk::PhysicalDeviceType::DiscreteGpu)
}

/// Select the best GPU from those available.
pub fn best_gpu(app: &App) -> Option<vk::PhysicalDevice> {
    find_discrete_gpu(app.vk_physical_devices()).or_else(|| app.default_vk_physical_device())
}<|endoftext|>


<commit_before><commit_msg>Associated types note<commit_after>use std::fmt::Debug;

// Associated types are perfect for cases where each implementation has one
// specific related type: each type of Task produces a particular type of Output;
// each type of Pattern looks for a particular type of Match.
// However, as we’ll see, some relationships among types are not like this.

// Cool way to tell Rust, that some component implement some trait
fn dump<I>(iter: I)
  where I: Iterator, I::Item: Debug
{
    // ...
}

// Or, we could write, “I must be an iterator over String values”:
fn dump<I>(iter: I)
  where I: Iterator<Item=String>
{
    // ...
}

// It works with trait objects too, which is really great
fn dump(iter: &mut Iterator<Item=String>) {
    for (index, s) in iter.enumerate() {
        println!("{}: {:?}", index, s);
    }
}

pub trait Mul<RHS=Self> {
    // ...
}

fn main() {
    // ...
}
<|endoftext|>