<commit_before>use std::collections::HashMap;
use std::collections::HashSet;
use std::borrow::BorrowMut;
use std::fmt;
use std::fmt::Display;
use std::cmp;

type Id = String;

/// Returns an `Id` with prefix `x` that is not in the set `vars`
fn fresh_var_like(x: &Id, vars: HashSet<Id>) -> Id {
    let mut suffix = 0;
    let mut result = x.clone();
    let len = result.len();
    loop {
        result.push_str(&suffix.to_string());

        if !vars.contains(&result) {
            return result;
        }

        suffix += 1;
        result.truncate(len);
    }
}

#[derive(Debug)]
pub enum EvaluationError {
    UnboundVariable(String),
    IllformedExpression,
}

impl fmt::Display for EvaluationError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::EvaluationError::*;
        match *self {
            UnboundVariable(ref id) => write!(f, "Encountered unbound variable: {}", id),
            IllformedExpression => write!(f, "Illformed expression"),
        }
    }
}

#[derive(Clone, Debug)]
pub enum Type {
    Var(Id),
    Fun(Box<Type>, Box<Type>),
    Forall(Id, Box<Type>),
}

impl PartialEq for Type {
    /// Equality is defined as alpha-equivalence of types
    fn eq(&self, other: &Type) -> bool {
        use self::Type::*;

        match (self,other) {
            (&Var(ref x),&Var(ref y)) => {
                *x == *y
            },
            (&Fun(ref t1, ref t2),&Fun(ref t3, ref t4)) => {
                *t1 == *t3 && *t2 == *t4
            },
            (&Forall(ref A, ref t1),&Forall(ref B, ref t2)) => {
                t1.subst(&Var(B.clone()), &A) == **t2
            },
            _ => false,
        }
    }
}

impl Eq for Type { }

impl Display for Type {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Type::Var(ref x) => write!(f,"{}",x),
            Type::Fun(ref a, ref b) => write!(f,"({}) -> {}",a,b),
            Type::Forall(ref x, ref t) => write!(f,"(forall {}. {})", x, t),
        }
    }
}

impl Type {
    /// Returns the result of the capture avoiding substitution `self` {`t`/`X`}
    fn subst(&self, t: &Type, X: &str) -> Type {
        match *self {
            Type::Var(ref Y) => {
                if X == *Y {
                    t.clone()
                } else {
                    self.clone()
                }
            },
            Type::Fun(ref t1, ref t2) => {
                Type::Fun(Box::new(t1.subst(t,X)), Box::new(t2.subst(t,X)))
            },
            Type::Forall(ref Y, ref tau) => {
                if X == *Y {
                    self.clone()
                } else {
                    let mut fvs = t.free_vars();
                    if fvs.contains(Y) {
                        let mut vars = self.vars();
                        vars.extend(fvs.drain());
                        vars.insert(String::from(X));
                        let fresh_id = fresh_var_like(Y, vars);
                        let renamed = self.rename(Y, &fresh_id);
                        renamed.subst(t, X)
                    } else {
                        Type::Forall(Y.clone(), Box::new(tau.subst(t,X)))
                    }
                }
            },
        }
    }

    /// Returns an identical type with `var` renamed into `into`
    fn rename(&self, var: &str, into: &str) -> Type {
        match *self {
            Type::Var(ref X) => {
                if *X == var {
                    Type::Var(String::from(into))
                } else {
                    self.clone()
                }
            },
            Type::Fun(ref t1, ref t2) => {
                Type::Fun(Box::new(t1.rename(var, into)),
                        Box::new(t2.rename(var,into)))
            },
            Type::Forall(ref X, ref tau) => {
                let binder = {
                    if *X == var {
                        String::from(into)
                    } else {
                        X.clone()
                    }
                };
                Type::Forall(binder, Box::new(tau.rename(var, into)))
            },
        }
    }

    /// Returns a set the free variables contained in `self`
    fn free_vars(&self) -> HashSet<Id> {
        match *self {
            Type::Var(ref X) => {
                let mut fvs = HashSet::new();
                fvs.insert(X.clone());
                fvs
            },
            Type::Fun(ref t1, ref t2) => {
                let mut fvs = t1.free_vars();
                let mut t2_fvs = t2.free_vars();
                fvs.extend(t2_fvs.drain());
                fvs
            }
            Type::Forall(ref X, ref t) => {
                let mut fvs = t.free_vars();
                fvs.remove(X);
                fvs
            }
        }
    }

    /// Returns a set containing all of the variables contained in `self`
    fn vars(&self) -> HashSet<Id> {
        match *self {
            Type::Var(ref X) => {
                let mut vars = HashSet::new();
                vars.insert(X.clone());
                vars
            },
            Type::Fun(ref t1, ref t2) => {
                let mut vars = t1.vars();
                let mut t2_vars = t2.vars();
                vars.extend(t2_vars.drain());
                vars
            }
            Type::Forall(ref X, ref t) => {
                let mut vars = t.vars();
                vars.insert(X.clone());
                vars
            }
        }
    }
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Expr {
    Var(Id),
    Lam(Id, Box<Type>, Box<Expr>),
    App(Box<Expr>, Box<Expr>),
    TLam(Id, Box<Expr>),
    TApp(Box<Expr>, Box<Type>),
    Let(Id, Box<Type>, Box<Expr>, Box<Expr>),
    TLet(Id, Box<Type>, Box<Expr>),
}

impl Display for Expr {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Expr::Var(ref x) => write!(f,"{}",x),
            Expr::Lam(ref x, ref t, ref e) => write!(f,"(\\{}:{}.{})",x,t,e),
            Expr::App(ref e1, ref e2) => write!(f,"({} {})",e1,e2),
            Expr::TLam(ref X, ref e) => write!(f,"(/\\{}.{})",X,e),
            Expr::TApp(ref e, ref t) => write!(f,"({} [{}])",e,t),
            Expr::Let(ref x, ref t, ref e1, ref e2) => write!(f,"(let {}:{} = {} in {})",x,t,e1,e2),
            Expr::TLet(ref X, ref t, ref e) => write!(f,"(Let {} = {} in {})",X,t,e),
        }
    }
}

impl Expr {
    /// Returns the normal form of `self` under call-by-value semantics
    pub fn eval(&self) -> Result<Expr,EvaluationError> {
        match *self {
            Expr::Var(ref x) => {
                Err(EvaluationError::UnboundVariable(x.clone()))
            },
            Expr::Lam(_,_,_) | Expr::TLam(_,_) => Ok(self.clone()),
            Expr::App(ref e1, ref e2) => {
                let v1 = e1.eval()?;
                let v2 = e2.eval()?;
                if let Expr::Lam(x,t,e3) = v1 {
                    let new_expr = e3.subst(&v2, &x);
                    new_expr.eval()
                } else {
                    Err(EvaluationError::IllformedExpression)
                }
            },
            Expr::TApp(ref e, ref t) => {
                let v = e.eval()?;
                if let Expr::TLam(X,e) = v {
                    let new_expr = e.subst_type(t, &X);
                    new_expr.eval()
                } else {
                    Err(EvaluationError::IllformedExpression)
                }
            },
            Expr::Let(ref x, ref t, ref e1, ref e2) => {
                Expr::App(
                    Box::new(Expr::Lam(
                        x.clone(),
                        t.clone(),
                        e2.clone())),
                    e1.clone()).eval()
            },
            Expr::TLet(ref X, ref t, ref e) => {
                Expr::TApp(
                    Box::new(Expr::TLam(
                        X.clone(),
                        e.clone())),
                    t.clone()).eval()
            },
        }
    }

    /// Returns the result of the capture avoiding substitution `self` {`e`/`x`}
    fn subst(&self, e: &Expr, x: &str) -> Expr {
        match *self {
            Expr::Var(ref y) => {
                if x == *y {
                    e.clone()
                } else {
                    self.clone()
                }
            },
            Expr::Lam(ref y,ref t,ref e1) => {
                if x == *y {
                    self.clone()
                } else {
                    // TODO: check freshness
                    unimplemented!()
                }
            },
            Expr::App(ref e1,ref e2) => {
                Expr::App(Box::new(e1.subst(e,x)), Box::new(e2.subst(e,x)))
            },
            Expr::TLam(ref X,ref e1) => {
                Expr::TLam(X.clone(), Box::new(e1.subst(e,x)))
            },
            Expr::TApp(ref e1,ref t) => {
                Expr::TApp(Box::new(e1.subst(e,x)), t.clone())
            },
            Expr::Let(ref y,ref t,ref e1,ref e2) => {
                // Unclear
                unimplemented!()
            },
            Expr::TLet(ref X,ref t,ref e1) => {
                Expr::TLet(X.clone(), t.clone(), Box::new(e1.subst(e,x)))
            },
        }
    }

    fn subst_type(&self, to: &Type, from: &str) -> Expr {
        match *self {
            Expr::Var(ref y) => {
                self.clone()
            },
            Expr::Lam(ref y,ref t,ref e1) => {
                let new_t = t.subst(to, from);
                Expr::Lam(y.clone(), Box::new(new_t), Box::new(e1.subst_type(to,from)))
            },
            Expr::App(ref e1,ref e2) => {
                Expr::App(Box::new(e1.subst_type(to,from)), Box::new(e2.subst_type(to,from)))
            },
            Expr::TLam(ref X,ref e1) => {
                if *X == from {
                    self.clone()
                } else {
                    // FIXME: Do I need to worry about the fvs of `to` here?
                    Expr::TLam(X.clone(), Box::new(e1.subst_type(to,from)))
                }
            },
            Expr::TApp(ref e1,ref t) => {
                let new_t = t.subst(to, from);
                let new_e1 = e1.subst_type(to, from);
                Expr::TApp(Box::new(new_e1), Box::new(new_t))
            },
            Expr::Let(ref y,ref t,ref e1,ref e2) => {
                unimplemented!()
            },
            Expr::TLet(ref X,ref t,ref e1) => {
                unimplemented!()
            },
        }
    }
}<commit_msg>Add skeleton necessary for finishing eval<commit_after>use std::collections::HashMap;
use std::collections::HashSet;
use std::borrow::BorrowMut;
use std::fmt;
use std::fmt::Display;
use std::cmp;

type Id = String;

/// Returns an `Id` with prefix `x` that is not in the set `vars`
fn fresh_var_like(x: &Id, vars: HashSet<Id>) -> Id {
    let mut suffix = 0;
    let mut result = x.clone();
    let len = result.len();
    loop {
        result.push_str(&suffix.to_string());

        if !vars.contains(&result) {
            return result;
        }

        suffix += 1;
        result.truncate(len);
    }
}

#[derive(Debug)]
pub enum EvaluationError {
    UnboundVariable(String),
    IllformedExpression,
}

impl fmt::Display for EvaluationError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::EvaluationError::*;
        match *self {
            UnboundVariable(ref id) => write!(f, "Encountered unbound variable: {}", id),
            IllformedExpression => write!(f, "Illformed expression"),
        }
    }
}

#[derive(Clone, Debug)]
pub enum Type {
    Var(Id),
    Fun(Box<Type>, Box<Type>),
    Forall(Id, Box<Type>),
}

impl PartialEq for Type {
    /// Equality is defined as alpha-equivalence of types
    fn eq(&self, other: &Type) -> bool {
        use self::Type::*;

        match (self,other) {
            (&Var(ref x),&Var(ref y)) => {
                *x == *y
            },
            (&Fun(ref t1, ref t2),&Fun(ref t3, ref t4)) => {
                *t1 == *t3 && *t2 == *t4
            },
            (&Forall(ref A, ref t1),&Forall(ref B, ref t2)) => {
                t1.subst(&Var(B.clone()), &A) == **t2
            },
            _ => false,
        }
    }
}

impl Eq for Type { }

impl Display for Type {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Type::Var(ref x) => write!(f,"{}",x),
            Type::Fun(ref a, ref b) => write!(f,"({}) -> {}",a,b),
            Type::Forall(ref x, ref t) => write!(f,"(forall {}. {})", x, t),
        }
    }
}

impl Type {
    /// Returns the result of the capture avoiding substitution `self` {`t`/`X`}
    fn subst(&self, t: &Type, X: &str) -> Type {
        match *self {
            Type::Var(ref Y) => {
                if X == *Y {
                    t.clone()
                } else {
                    self.clone()
                }
            },
            Type::Fun(ref t1, ref t2) => {
                Type::Fun(Box::new(t1.subst(t,X)), Box::new(t2.subst(t,X)))
            },
            Type::Forall(ref Y, ref tau) => {
                if X == *Y {
                    self.clone()
                } else {
                    let mut fvs = t.free_vars();
                    if fvs.contains(Y) {
                        let mut vars = self.vars();
                        vars.extend(fvs.drain());
                        vars.insert(String::from(X));
                        let fresh_id = fresh_var_like(Y, vars);
                        let renamed = self.rename(Y, &fresh_id);
                        renamed.subst(t, X)
                    } else {
                        Type::Forall(Y.clone(), Box::new(tau.subst(t,X)))
                    }
                }
            },
        }
    }

    /// Returns an identical type with `var` renamed into `into`
    fn rename(&self, var: &str, into: &str) -> Type {
        match *self {
            Type::Var(ref X) => {
                if *X == var {
                    Type::Var(String::from(into))
                } else {
                    self.clone()
                }
            },
            Type::Fun(ref t1, ref t2) => {
                Type::Fun(Box::new(t1.rename(var, into)),
                        Box::new(t2.rename(var,into)))
            },
            Type::Forall(ref X, ref tau) => {
                let binder = {
                    if *X == var {
                        String::from(into)
                    } else {
                        X.clone()
                    }
                };
                Type::Forall(binder, Box::new(tau.rename(var, into)))
            },
        }
    }

    /// Returns a set the free variables contained in `self`
    fn free_vars(&self) -> HashSet<Id> {
        match *self {
            Type::Var(ref X) => {
                let mut fvs = HashSet::new();
                fvs.insert(X.clone());
                fvs
            },
            Type::Fun(ref t1, ref t2) => {
                let mut fvs = t1.free_vars();
                let mut t2_fvs = t2.free_vars();
                fvs.extend(t2_fvs.drain());
                fvs
            }
            Type::Forall(ref X, ref t) => {
                let mut fvs = t.free_vars();
                fvs.remove(X);
                fvs
            }
        }
    }

    /// Returns a set containing all of the variables contained in `self`
    fn vars(&self) -> HashSet<Id> {
        match *self {
            Type::Var(ref X) => {
                let mut vars = HashSet::new();
                vars.insert(X.clone());
                vars
            },
            Type::Fun(ref t1, ref t2) => {
                let mut vars = t1.vars();
                let mut t2_vars = t2.vars();
                vars.extend(t2_vars.drain());
                vars
            }
            Type::Forall(ref X, ref t) => {
                let mut vars = t.vars();
                vars.insert(X.clone());
                vars
            }
        }
    }
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Expr {
    Var(Id),
    Lam(Id, Box<Type>, Box<Expr>),
    App(Box<Expr>, Box<Expr>),
    TLam(Id, Box<Expr>),
    TApp(Box<Expr>, Box<Type>),
    Let(Id, Box<Type>, Box<Expr>, Box<Expr>),
    TLet(Id, Box<Type>, Box<Expr>),
}

impl Display for Expr {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Expr::Var(ref x) => write!(f,"{}",x),
            Expr::Lam(ref x, ref t, ref e) => write!(f,"(\\{}:{}.{})",x,t,e),
            Expr::App(ref e1, ref e2) => write!(f,"({} {})",e1,e2),
            Expr::TLam(ref X, ref e) => write!(f,"(/\\{}.{})",X,e),
            Expr::TApp(ref e, ref t) => write!(f,"({} [{}])",e,t),
            Expr::Let(ref x, ref t, ref e1, ref e2) => write!(f,"(let {}:{} = {} in {})",x,t,e1,e2),
            Expr::TLet(ref X, ref t, ref e) => write!(f,"(Let {} = {} in {})",X,t,e),
        }
    }
}

impl Expr {
    /// Returns the normal form of `self` under call-by-value semantics
    pub fn eval(&self) -> Result<Expr,EvaluationError> {
        match *self {
            Expr::Var(ref x) => {
                Err(EvaluationError::UnboundVariable(x.clone()))
            },
            Expr::Lam(_,_,_) | Expr::TLam(_,_) => Ok(self.clone()),
            Expr::App(ref e1, ref e2) => {
                let v1 = e1.eval()?;
                let v2 = e2.eval()?;
                if let Expr::Lam(x,t,e3) = v1 {
                    let new_expr = e3.subst(&v2, &x);
                    new_expr.eval()
                } else {
                    Err(EvaluationError::IllformedExpression)
                }
            },
            Expr::TApp(ref e, ref t) => {
                let v = e.eval()?;
                if let Expr::TLam(X,e) = v {
                    let new_expr = e.subst_type(t, &X);
                    new_expr.eval()
                } else {
                    Err(EvaluationError::IllformedExpression)
                }
            },
            Expr::Let(ref x, ref t, ref e1, ref e2) => {
                Expr::App(
                    Box::new(Expr::Lam(
                        x.clone(),
                        t.clone(),
                        e2.clone())),
                    e1.clone()).eval()
            },
            Expr::TLet(ref X, ref t, ref e) => {
                Expr::TApp(
                    Box::new(Expr::TLam(
                        X.clone(),
                        e.clone())),
                    t.clone()).eval()
            },
        }
    }

    /// Returns the result of the capture avoiding substitution `self` {`e`/`x`}
    fn subst(&self, e: &Expr, x: &str) -> Expr {
        match *self {
            Expr::Var(ref y) => {
                if x == *y {
                    e.clone()
                } else {
                    self.clone()
                }
            },
            Expr::Lam(ref y,ref t,ref e1) => {
                if x == *y {
                    self.clone()
                } else {
                    // TODO: check freshness
                    unimplemented!()
                }
            },
            Expr::App(ref e1,ref e2) => {
                Expr::App(Box::new(e1.subst(e,x)), Box::new(e2.subst(e,x)))
            },
            Expr::TLam(ref X,ref e1) => {
                Expr::TLam(X.clone(), Box::new(e1.subst(e,x)))
            },
            Expr::TApp(ref e1,ref t) => {
                Expr::TApp(Box::new(e1.subst(e,x)), t.clone())
            },
            Expr::Let(ref y,ref t,ref e1,ref e2) => {
                let new_e1 = e1.subst(e, x);
                // Unclear
                unimplemented!()
            },
            Expr::TLet(ref X,ref t,ref e1) => {
                Expr::TLet(X.clone(), t.clone(), Box::new(e1.subst(e,x)))
            },
        }
    }

    fn subst_type(&self, to: &Type, from: &str) -> Expr {
        match *self {
            Expr::Var(ref y) => {
                self.clone()
            },
            Expr::Lam(ref y,ref t,ref e1) => {
                let new_t = t.subst(to, from);
                Expr::Lam(y.clone(), Box::new(new_t), Box::new(e1.subst_type(to,from)))
            },
            Expr::App(ref e1,ref e2) => {
                Expr::App(Box::new(e1.subst_type(to,from)), Box::new(e2.subst_type(to,from)))
            },
            Expr::TLam(ref X,ref e1) => {
                if *X == from {
                    self.clone()
                } else {
                    unimplemented!()
                }
            },
            Expr::TApp(ref e1,ref t) => {
                let new_t = t.subst(to, from);
                let new_e1 = e1.subst_type(to, from);
                Expr::TApp(Box::new(new_e1), Box::new(new_t))
            },
            Expr::Let(ref y,ref t,ref e1,ref e2) => {
                let new_t = t.subst(to, from);
                let new_e1 = e1.subst_type(to, from);
                let new_e2 = e2.subst_type(to, from);
                Expr::Let(y.clone(), Box::new(new_t), Box::new(new_e1), Box::new(new_e2))
            },
            Expr::TLet(ref X,ref t,ref e1) => {
                let new_t = t.subst(to, from);
                if *X == from {
                    Expr::TLet(X.clone(), Box::new(new_t), e1.clone())
                }
                else {
                    unimplemented!()
                }
            },
        }
    }

    /// Returns an identical expression with expression variable `var` renamed into `into`
    fn rename(&self, var: &str, into: &str) -> Expr {
        unimplemented!()
    }

    /// Returns an identical expression with type variable `var` renamed into `into`
    fn rename_type(&self, var: &str, into: &str) -> Expr {
        unimplemented!()
    }

    /// Returns a set the free variables contained in `self`
    fn free_vars(&self) -> HashSet<Id> {
        unimplemented!()
    }

    /// Returns a set containing all of the variables contained in `self`
    fn vars(&self) -> HashSet<Id> {
        unimplemented!()
    }

    /// Returns a set the free type variables contained in `self`
    fn free_type_vars(&self) -> HashSet<Id> {
        unimplemented!()
    }

    /// Returns a set containing all of the type variables contained in `self`
    fn type_vars(&self) -> HashSet<Id> {
        unimplemented!()
    }
}<|endoftext|>


<commit_before>use color::Color3;
use id_allocator::IdAllocator;
use noise::Seed;
use state::EntityId;
use std::collections::hash_map::{HashMap, Entry};
use std::mem;
use stopwatch::TimerSet;
use terrain_block::{TerrainBlock, BlockPosition};
use terrain_heightmap::HeightMap;

pub const AMPLITUDE: f64 = 256.0;
pub const FREQUENCY: f64 = 1.0 / 64.0;
pub const PERSISTENCE: f64 = 1.0 / 16.0;
pub const LACUNARITY: f64 = 8.0;
pub const OCTAVES: usize = 3;

// Quality is the number of times the noise function is sampled along each axis.
pub const LOD_QUALITY: [u32; 5] = [32, 16, 4, 2, 1];

#[derive(Show, Copy, Clone, PartialEq, Eq, Hash)]
pub enum TerrainType {
  Grass,
  Dirt,
  Stone,
}

impl TerrainType {
  pub fn color(&self) -> Color3<f32> {
    match *self {
      TerrainType::Grass => Color3::of_rgb(0.0, 0.5, 0.0),
      TerrainType::Dirt => Color3::of_rgb(0.5, 0.4, 0.2),
      TerrainType::Stone => Color3::of_rgb(0.5, 0.5, 0.5),
    }
  }
}

pub struct TerrainMipMesh {
  pub lods: Vec<Option<TerrainBlock>>,
}

/// This struct contains and lazily generates the world's terrain.
pub struct Terrain {
  pub heightmap: HeightMap,
  // all the blocks that have ever been created.
  pub all_blocks: HashMap<BlockPosition, TerrainMipMesh>,
}

impl Terrain {
  pub fn new(terrain_seed: Seed) -> Terrain {
    Terrain {
      heightmap:
        HeightMap::new(terrain_seed, OCTAVES, FREQUENCY, PERSISTENCE, LACUNARITY, AMPLITUDE),
      all_blocks: HashMap::new(),
    }
  }

  pub unsafe fn load<'a>(
    &'a mut self,
    timers: &TimerSet,
    id_allocator: &mut IdAllocator<EntityId>,
    position: &'a BlockPosition,
    lod_index: u32,
  ) -> &'a TerrainBlock {
    let mip_mesh =
      match self.all_blocks.entry(*position) {
        Entry::Occupied(mut entry) => {
          // Fudge the lifetime bounds
          mem::transmute(entry.get_mut())
        },
        Entry::Vacant(entry) => {
          entry.insert(
            TerrainMipMesh {
              lods: range(0, LOD_QUALITY.len()).map(|_| None).collect(),
            }
          )
        },
      };

    let mesh = mip_mesh.lods.get_mut(lod_index as usize).unwrap();
    if mesh.is_none() {
      *mesh = Some(
        TerrainBlock::generate(
          timers,
          id_allocator,
          &self.heightmap,
          position,
          LOD_QUALITY[lod_index as usize],
        )
      );
    }

    mesh.as_ref().unwrap()
  }
}
<commit_msg>Friendlier terrain<commit_after>use color::Color3;
use id_allocator::IdAllocator;
use noise::Seed;
use state::EntityId;
use std::collections::hash_map::{HashMap, Entry};
use std::mem;
use stopwatch::TimerSet;
use terrain_block::{TerrainBlock, BlockPosition};
use terrain_heightmap::HeightMap;

pub const AMPLITUDE: f64 = 64.0;
pub const FREQUENCY: f64 = 1.0 / 64.0;
pub const PERSISTENCE: f64 = 1.0 / 16.0;
pub const LACUNARITY: f64 = 8.0;
pub const OCTAVES: usize = 2;

// Quality is the number of times the noise function is sampled along each axis.
pub const LOD_QUALITY: [u32; 5] = [32, 16, 4, 2, 1];

#[derive(Show, Copy, Clone, PartialEq, Eq, Hash)]
pub enum TerrainType {
  Grass,
  Dirt,
  Stone,
}

impl TerrainType {
  pub fn color(&self) -> Color3<f32> {
    match *self {
      TerrainType::Grass => Color3::of_rgb(0.0, 0.5, 0.0),
      TerrainType::Dirt => Color3::of_rgb(0.5, 0.4, 0.2),
      TerrainType::Stone => Color3::of_rgb(0.5, 0.5, 0.5),
    }
  }
}

pub struct TerrainMipMesh {
  pub lods: Vec<Option<TerrainBlock>>,
}

/// This struct contains and lazily generates the world's terrain.
pub struct Terrain {
  pub heightmap: HeightMap,
  // all the blocks that have ever been created.
  pub all_blocks: HashMap<BlockPosition, TerrainMipMesh>,
}

impl Terrain {
  pub fn new(terrain_seed: Seed) -> Terrain {
    Terrain {
      heightmap:
        HeightMap::new(terrain_seed, OCTAVES, FREQUENCY, PERSISTENCE, LACUNARITY, AMPLITUDE),
      all_blocks: HashMap::new(),
    }
  }

  pub unsafe fn load<'a>(
    &'a mut self,
    timers: &TimerSet,
    id_allocator: &mut IdAllocator<EntityId>,
    position: &'a BlockPosition,
    lod_index: u32,
  ) -> &'a TerrainBlock {
    let mip_mesh =
      match self.all_blocks.entry(*position) {
        Entry::Occupied(mut entry) => {
          // Fudge the lifetime bounds
          mem::transmute(entry.get_mut())
        },
        Entry::Vacant(entry) => {
          entry.insert(
            TerrainMipMesh {
              lods: range(0, LOD_QUALITY.len()).map(|_| None).collect(),
            }
          )
        },
      };

    let mesh = mip_mesh.lods.get_mut(lod_index as usize).unwrap();
    if mesh.is_none() {
      *mesh = Some(
        TerrainBlock::generate(
          timers,
          id_allocator,
          &self.heightmap,
          position,
          LOD_QUALITY[lod_index as usize],
        )
      );
    }

    mesh.as_ref().unwrap()
  }
}
<|endoftext|>


<commit_before>pub use luminance::pixel::{Depth32F, R32F, RGBA32F};
pub use luminance::texture::{Dim2, Flat, MagFilter, MinFilter, Sampler, Texture, Wrap};
use image;
use std::ops::Deref;
use std::path::{Path, PathBuf};

use resource::{CacheKey, Load, LoadError, LoadResult, Store};

// Common texture aliases.
pub type TextureRGBA32F = Texture<Flat, Dim2, RGBA32F>;
pub type TextureR32F = Texture<Flat, Dim2, R32F>;
pub type TextureDepth32F = Texture<Flat, Dim2, Depth32F>;

/// Load an RGBA texture from an image at a path.
///
/// The `linearizer` argument is an option that gives the factor to apply to linearize if needed. Pass
/// `None` if the texture is already linearized.
pub fn load_rgba_texture<P>(path: P) -> Result<TextureRGBA32F, LoadError> where P: AsRef<Path> {
  let img = image::open(path).map_err(|e| LoadError::ConversionFailed(format!("{:?}", e)))?.flipv().to_rgba();
  let (w, h) = img.dimensions();
  let raw: Vec<f32> = img.into_raw().into_iter().map(|x| {
    x as f32 / 255.
  }).collect();

  let tex = Texture::new([w, h], 0, &Sampler::default()).map_err(|e| LoadError::ConversionFailed(format!("{:?}", e)))?;
  tex.upload_raw(false, &raw);

  Ok(tex)
}

/// Save an RGBA image on disk.
pub fn save_rgba_texture<P>(texture: &TextureRGBA32F, path: P) where P: AsRef<Path> {
  info!("saving texture image to: \x1b[35m{:?}", path.as_ref());

  let texels = texture.get_raw_texels();
  let [w, h] = texture.size();
  let mut output = Vec::with_capacity((w * h) as usize);

  for texel in &texels {
    output.push((texel * 255.) as u8);
  }

  let _ = image::save_buffer(path, &output, w, h, image::ColorType::RGBA(8));
}

#[derive(Debug)]
pub struct TextureImage(pub TextureRGBA32F);

impl Deref for TextureImage {
  type Target = TextureRGBA32F;

  fn deref(&self) -> &Self::Target {
    &self.0
  }
}

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct TextureKey(pub String);

impl TextureKey {
  pub fn new(key: &str) -> Self {
    TextureKey(key.to_owned())
  }
}

impl<'a> From<&'a str> for TextureKey {
  fn from(key: &str) -> Self {
    TextureKey::new(key)
  }
}

impl CacheKey for TextureKey {
  type Target = TextureImage;
}

impl Load for TextureImage {
  type Key = TextureKey;

  fn key_to_path(key: &Self::Key) -> PathBuf {
    key.0.clone().into()
  }

  fn load<P>(path: P, _: &mut Store) -> Result<LoadResult<Self>, LoadError> where P: AsRef<Path> {
    let result = load_rgba_texture(path).map(TextureImage)?.into();
    Ok(result)
  }
}
<commit_msg>Re-export pixel formats.<commit_after>pub use luminance::pixel::{Depth32F, R32F, RGB32F, RGBA32F};
pub use luminance::texture::{Dim2, Flat, MagFilter, MinFilter, Sampler, Texture, Wrap};
use image;
use std::ops::Deref;
use std::path::{Path, PathBuf};

use resource::{CacheKey, Load, LoadError, LoadResult, Store};

// Common texture aliases.
pub type TextureRGB32F = Texture<Flat, Dim2, RGB32F>;
pub type TextureRGBA32F = Texture<Flat, Dim2, RGBA32F>;
pub type TextureR32F = Texture<Flat, Dim2, R32F>;
pub type TextureDepth32F = Texture<Flat, Dim2, Depth32F>;

/// Load an RGBA texture from an image at a path.
///
/// The `linearizer` argument is an option that gives the factor to apply to linearize if needed. Pass
/// `None` if the texture is already linearized.
pub fn load_rgba_texture<P>(path: P) -> Result<TextureRGBA32F, LoadError> where P: AsRef<Path> {
  let img = image::open(path).map_err(|e| LoadError::ConversionFailed(format!("{:?}", e)))?.flipv().to_rgba();
  let (w, h) = img.dimensions();
  let raw: Vec<f32> = img.into_raw().into_iter().map(|x| {
    x as f32 / 255.
  }).collect();

  let tex = Texture::new([w, h], 0, &Sampler::default()).map_err(|e| LoadError::ConversionFailed(format!("{:?}", e)))?;
  tex.upload_raw(false, &raw);

  Ok(tex)
}

/// Save an RGBA image on disk.
pub fn save_rgba_texture<P>(texture: &TextureRGBA32F, path: P) where P: AsRef<Path> {
  info!("saving texture image to: \x1b[35m{:?}", path.as_ref());

  let texels = texture.get_raw_texels();
  let [w, h] = texture.size();
  let mut output = Vec::with_capacity((w * h) as usize);

  for texel in &texels {
    output.push((texel * 255.) as u8);
  }

  let _ = image::save_buffer(path, &output, w, h, image::ColorType::RGBA(8));
}

#[derive(Debug)]
pub struct TextureImage(pub TextureRGBA32F);

impl Deref for TextureImage {
  type Target = TextureRGBA32F;

  fn deref(&self) -> &Self::Target {
    &self.0
  }
}

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct TextureKey(pub String);

impl TextureKey {
  pub fn new(key: &str) -> Self {
    TextureKey(key.to_owned())
  }
}

impl<'a> From<&'a str> for TextureKey {
  fn from(key: &str) -> Self {
    TextureKey::new(key)
  }
}

impl CacheKey for TextureKey {
  type Target = TextureImage;
}

impl Load for TextureImage {
  type Key = TextureKey;

  fn key_to_path(key: &Self::Key) -> PathBuf {
    key.0.clone().into()
  }

  fn load<P>(path: P, _: &mut Store) -> Result<LoadResult<Self>, LoadError> where P: AsRef<Path> {
    let result = load_rgba_texture(path).map(TextureImage)?.into();
    Ok(result)
  }
}
<|endoftext|>


<commit_before>/*
  This Source Code Form is subject to the terms of the Mozilla Public
  License, v. 2.0. If a copy of the MPL was not distributed with this
  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

use std::path::Path;
use chrono::{DateTime,Utc};
use exempi::Xmp;

use plutils::Plist;
use store;
use custominfo::CustomInfoProperties;
use exif::ExifProperties;
use iptc::IptcProperties;
use AplibObject;
use AplibType;
use audit::{
    audit_get_str_value,
    audit_get_int_value,
    audit_get_bool_value,
    audit_get_dict_value,
    audit_get_date_value,
    audit_get_array_value,
    SkipReason,
    Report
};
use xmp::ToXmp;

/// A rendered image. There is one for the orignal, and one per
/// actual version. `Version` are associated to a `Master`.
pub struct Version {
    uuid: Option<String>,
    model_id: Option<i64>,
    /// The associated `Master`.
    master_uuid: Option<String>,

    /// uuid of the `Folder` project this reside in.
    pub project_uuid: Option<String>,
    /// uuid of the raw `Master`.
    pub raw_master_uuid: Option<String>,
    /// uuid of the non raw `Master`.
    pub nonraw_master_uuid: Option<String>,
    pub timezone_name: Option<String>,
    pub create_date: Option<DateTime<Utc>>,
    pub image_date: Option<DateTime<Utc>>,
    pub export_image_change_date: Option<DateTime<Utc>>,
    pub export_metadata_change_date: Option<DateTime<Utc>>,
    pub version_number: Option<i64>,
    pub db_version: Option<i64>,
    pub db_minor_version: Option<i64>,
    pub is_flagged: Option<bool>,
    /// Indicate the version is the original.
    pub is_original: Option<bool>,
    pub is_editable: Option<bool>,
    pub is_hidden: Option<bool>,
    pub is_in_trash: Option<bool>,
    pub file_name: Option<String>,
    pub name: Option<String>,
    pub rating: Option<i64>,
    pub rotation: Option<i64>,
    pub colour_label_index: Option<i64>,

    pub iptc: Option<IptcProperties>,
    pub exif: Option<ExifProperties>,
    pub custom_info: Option<CustomInfoProperties>,
    pub keywords: Option<Vec<Plist>>,
}

impl AplibObject for Version {
    /// Load the version object from the plist at plist_path.
    fn from_path(plist_path: &Path,
                 mut auditor: Option<&mut Report>) -> Option<Version> {

        use plutils::*;

        let plist = parse_plist(plist_path);
        match plist {
            Plist::Dictionary(ref dict) => {
                let iptc = audit_get_dict_value(dict, "iptcProperties", &mut auditor);
                let exif = audit_get_dict_value(dict, "exifProperties", &mut auditor);
                let custom_info = audit_get_dict_value(dict, "customInfo", &mut auditor);
                let result = Some(Version {
                    uuid: audit_get_str_value(dict, "uuid", &mut auditor),
                    master_uuid: audit_get_str_value(
                        dict, "masterUuid", &mut auditor),
                    project_uuid: audit_get_str_value(
                        dict, "projectUuid", &mut auditor),
                    raw_master_uuid: audit_get_str_value(
                        dict, "rawMasterUuid", &mut auditor),
                    nonraw_master_uuid: audit_get_str_value(
                        dict, "nonRawMasterUuid", &mut auditor),
                    timezone_name: audit_get_str_value(
                        dict, "imageTimeZoneName", &mut auditor),
                    create_date: audit_get_date_value(
                        dict, "createDate", &mut auditor),
                    image_date: audit_get_date_value(
                        dict, "imageDate", &mut auditor),
                    export_image_change_date: audit_get_date_value(
                        dict, "exportImageChangeDate", &mut auditor),
                    export_metadata_change_date: audit_get_date_value(
                        dict, "exportMetadataChangeDate", &mut auditor),
                    version_number: audit_get_int_value(
                        dict, "versionNumber", &mut auditor),
                    db_version: audit_get_int_value(
                        dict, "version", &mut auditor),
                    db_minor_version: audit_get_int_value(
                        dict, "minorVersion", &mut auditor),
                    is_flagged: audit_get_bool_value(
                        dict, "isFlagged", &mut auditor),
                    is_original: audit_get_bool_value(
                        dict, "isOriginal", &mut auditor),
                    is_editable: audit_get_bool_value(
                        dict, "isEditable", &mut auditor),
                    is_hidden: audit_get_bool_value(
                        dict, "isHidden", &mut auditor),
                    is_in_trash: audit_get_bool_value(
                        dict, "isInTrash", &mut auditor),
                    file_name: audit_get_str_value(
                        dict, "fileName", &mut auditor),
                    name: audit_get_str_value(dict, "name", &mut auditor),
                    model_id: audit_get_int_value(
                        dict, "modelId", &mut auditor),
                    rating: audit_get_int_value(
                        dict, "mainRating", &mut auditor),
                    rotation: audit_get_int_value(
                        dict, "rotation", &mut auditor),
                    colour_label_index: audit_get_int_value(dict, "colorLabelIndex", &mut auditor),
                    iptc: IptcProperties::from(&iptc, &mut auditor),
                    exif: ExifProperties::from(&exif, &mut auditor),
                    custom_info: CustomInfoProperties::from(&custom_info, &mut auditor),
                    keywords: audit_get_array_value(
                        dict, "keywords", &mut auditor),
                });
                if auditor.is_some() {
                    let ref mut auditor = auditor.unwrap();
                    auditor.skip("statistics", SkipReason::Ignore);
                    auditor.skip("thumbnailGroup", SkipReason::Ignore);
                    auditor.skip("faceDetectionIsFromPreview", SkipReason::Ignore);
                    auditor.skip("processedHeight", SkipReason::Ignore);
                    auditor.skip("processedWidth", SkipReason::Ignore);
                    auditor.skip("masterHeight", SkipReason::Ignore);
                    auditor.skip("masterWidth", SkipReason::Ignore);
                    auditor.skip("supportedStatus", SkipReason::Ignore);
                    auditor.skip("showInLibrary", SkipReason::Ignore);

                    auditor.skip("adjustmentProperties", SkipReason::Ignore); // don't know what to do yet
                    auditor.skip("RKImageAdjustments", SkipReason::Ignore);
                    auditor.skip("hasAdjustments", SkipReason::Ignore);
                    auditor.skip("hasEnabledAdjustments", SkipReason::Ignore);
                    auditor.skip("renderVersion", SkipReason::Ignore);

                    auditor.skip("imageProxyState", SkipReason::Ignore);
                    auditor.skip("plistWriteTimestamp", SkipReason::Ignore);
                    auditor.audit_ignored(dict, None);
                }
                result
            },
            _ =>
                None
        }
    }
    fn obj_type(&self) -> AplibType {
        AplibType::Version
    }
    fn uuid(&self) -> &Option<String> {
        &self.uuid
    }
    fn parent(&self) -> &Option<String> {
        &self.master_uuid
    }
    fn model_id(&self) -> i64 {
        self.model_id.unwrap_or(0)
    }
    fn is_valid(&self) -> bool {
        self.uuid.is_some()
    }
    fn wrap(obj: Version) -> store::Wrapper {
        store::Wrapper::Version(Box::new(obj))
    }
}

impl ToXmp for Version {

    fn to_xmp(&self, xmp: &mut Xmp) -> bool {
        if let Some(ref iptc) = self.iptc {
            iptc.to_xmp(xmp);
        }
        true
    }
}

#[cfg(test)]
#[test]
fn test_version_parse() {
    use testutils;

    let version = Version::from_path(
        testutils::get_test_file_path("Version-0.apversion")
            .as_path(), None);
    assert!(version.is_some());
    let version = version.unwrap();

    assert_eq!(version.uuid.as_ref().unwrap(), "MHMIbw5CQaiMgQ3n7g2w2A");
    assert!(version.is_original.unwrap());
    assert_eq!(version.master_uuid.as_ref().unwrap(), "WZMCPPRHR%C3nffgeeS4IQ");
    assert_eq!(version.name.as_ref().unwrap(), "img_3136");
    assert!(version.iptc.is_some());
    let iptc = version.iptc.as_ref().unwrap();
    assert!(iptc.bag.contains_key("Byline"));
    assert!(iptc.bag.contains_key("CiAdrCity"));
    let exif = version.exif.as_ref().unwrap();
    assert!(exif.bag.contains_key("ApertureValue"));
    assert!(exif.bag.contains_key("Depth"))
    // XXX fix when have actual audit.
//    println!("report {:?}", report);
}
<commit_msg>version: reformat<commit_after>/*
  This Source Code Form is subject to the terms of the Mozilla Public
  License, v. 2.0. If a copy of the MPL was not distributed with this
  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

use std::path::Path;
use chrono::{DateTime,Utc};
use exempi::Xmp;

use plutils::Plist;
use store;
use custominfo::CustomInfoProperties;
use exif::ExifProperties;
use iptc::IptcProperties;
use AplibObject;
use AplibType;
use audit::{
    audit_get_str_value,
    audit_get_int_value,
    audit_get_bool_value,
    audit_get_dict_value,
    audit_get_date_value,
    audit_get_array_value,
    SkipReason,
    Report
};
use xmp::ToXmp;

/// A rendered image. There is one for the orignal, and one per
/// actual version. `Version` are associated to a `Master`.
pub struct Version {
    uuid: Option<String>,
    model_id: Option<i64>,
    /// The associated `Master`.
    master_uuid: Option<String>,

    /// uuid of the `Folder` project this reside in.
    pub project_uuid: Option<String>,
    /// uuid of the raw `Master`.
    pub raw_master_uuid: Option<String>,
    /// uuid of the non raw `Master`.
    pub nonraw_master_uuid: Option<String>,
    pub timezone_name: Option<String>,
    pub create_date: Option<DateTime<Utc>>,
    pub image_date: Option<DateTime<Utc>>,
    pub export_image_change_date: Option<DateTime<Utc>>,
    pub export_metadata_change_date: Option<DateTime<Utc>>,
    pub version_number: Option<i64>,
    pub db_version: Option<i64>,
    pub db_minor_version: Option<i64>,
    pub is_flagged: Option<bool>,
    /// Indicate the version is the original.
    pub is_original: Option<bool>,
    pub is_editable: Option<bool>,
    pub is_hidden: Option<bool>,
    pub is_in_trash: Option<bool>,
    pub file_name: Option<String>,
    pub name: Option<String>,
    pub rating: Option<i64>,
    pub rotation: Option<i64>,
    pub colour_label_index: Option<i64>,

    pub iptc: Option<IptcProperties>,
    pub exif: Option<ExifProperties>,
    pub custom_info: Option<CustomInfoProperties>,
    pub keywords: Option<Vec<Plist>>,
}

impl AplibObject for Version {
    /// Load the version object from the plist at plist_path.
    fn from_path(plist_path: &Path,
                 mut auditor: Option<&mut Report>) -> Option<Version> {

        use plutils::*;

        let plist = parse_plist(plist_path);
        match plist {
            Plist::Dictionary(ref dict) => {
                let iptc = audit_get_dict_value(dict, "iptcProperties",
                                                &mut auditor);
                let exif = audit_get_dict_value(dict, "exifProperties",
                                                &mut auditor);
                let custom_info = audit_get_dict_value(dict, "customInfo",
                                                       &mut auditor);
                let result = Some(Version {
                    uuid: audit_get_str_value(dict, "uuid", &mut auditor),
                    master_uuid: audit_get_str_value(
                        dict, "masterUuid", &mut auditor),
                    project_uuid: audit_get_str_value(
                        dict, "projectUuid", &mut auditor),
                    raw_master_uuid: audit_get_str_value(
                        dict, "rawMasterUuid", &mut auditor),
                    nonraw_master_uuid: audit_get_str_value(
                        dict, "nonRawMasterUuid", &mut auditor),
                    timezone_name: audit_get_str_value(
                        dict, "imageTimeZoneName", &mut auditor),
                    create_date: audit_get_date_value(
                        dict, "createDate", &mut auditor),
                    image_date: audit_get_date_value(
                        dict, "imageDate", &mut auditor),
                    export_image_change_date: audit_get_date_value(
                        dict, "exportImageChangeDate", &mut auditor),
                    export_metadata_change_date: audit_get_date_value(
                        dict, "exportMetadataChangeDate", &mut auditor),
                    version_number: audit_get_int_value(
                        dict, "versionNumber", &mut auditor),
                    db_version: audit_get_int_value(
                        dict, "version", &mut auditor),
                    db_minor_version: audit_get_int_value(
                        dict, "minorVersion", &mut auditor),
                    is_flagged: audit_get_bool_value(
                        dict, "isFlagged", &mut auditor),
                    is_original: audit_get_bool_value(
                        dict, "isOriginal", &mut auditor),
                    is_editable: audit_get_bool_value(
                        dict, "isEditable", &mut auditor),
                    is_hidden: audit_get_bool_value(
                        dict, "isHidden", &mut auditor),
                    is_in_trash: audit_get_bool_value(
                        dict, "isInTrash", &mut auditor),
                    file_name: audit_get_str_value(
                        dict, "fileName", &mut auditor),
                    name: audit_get_str_value(dict, "name", &mut auditor),
                    model_id: audit_get_int_value(
                        dict, "modelId", &mut auditor),
                    rating: audit_get_int_value(
                        dict, "mainRating", &mut auditor),
                    rotation: audit_get_int_value(
                        dict, "rotation", &mut auditor),
                    colour_label_index: audit_get_int_value(
                        dict, "colorLabelIndex", &mut auditor),
                    iptc: IptcProperties::from(&iptc, &mut auditor),
                    exif: ExifProperties::from(&exif, &mut auditor),
                    custom_info: CustomInfoProperties::from(
                        &custom_info, &mut auditor),
                    keywords: audit_get_array_value(
                        dict, "keywords", &mut auditor),
                });
                if auditor.is_some() {
                    let ref mut auditor = auditor.unwrap();
                    auditor.skip("statistics", SkipReason::Ignore);
                    auditor.skip("thumbnailGroup", SkipReason::Ignore);
                    auditor.skip("faceDetectionIsFromPreview",
                                 SkipReason::Ignore);
                    auditor.skip("processedHeight", SkipReason::Ignore);
                    auditor.skip("processedWidth", SkipReason::Ignore);
                    auditor.skip("masterHeight", SkipReason::Ignore);
                    auditor.skip("masterWidth", SkipReason::Ignore);
                    auditor.skip("supportedStatus", SkipReason::Ignore);
                    auditor.skip("showInLibrary", SkipReason::Ignore);

                    auditor.skip("adjustmentProperties", SkipReason::Ignore); // don't know what to do yet
                    auditor.skip("RKImageAdjustments", SkipReason::Ignore);
                    auditor.skip("hasAdjustments", SkipReason::Ignore);
                    auditor.skip("hasEnabledAdjustments", SkipReason::Ignore);
                    auditor.skip("renderVersion", SkipReason::Ignore);

                    auditor.skip("imageProxyState", SkipReason::Ignore);
                    auditor.skip("plistWriteTimestamp", SkipReason::Ignore);
                    auditor.audit_ignored(dict, None);
                }
                result
            },
            _ =>
                None
        }
    }
    fn obj_type(&self) -> AplibType {
        AplibType::Version
    }
    fn uuid(&self) -> &Option<String> {
        &self.uuid
    }
    fn parent(&self) -> &Option<String> {
        &self.master_uuid
    }
    fn model_id(&self) -> i64 {
        self.model_id.unwrap_or(0)
    }
    fn is_valid(&self) -> bool {
        self.uuid.is_some()
    }
    fn wrap(obj: Version) -> store::Wrapper {
        store::Wrapper::Version(Box::new(obj))
    }
}

impl ToXmp for Version {

    fn to_xmp(&self, xmp: &mut Xmp) -> bool {
        if let Some(ref iptc) = self.iptc {
            iptc.to_xmp(xmp);
        }
        true
    }
}

#[cfg(test)]
#[test]
fn test_version_parse() {
    use testutils;

    let version = Version::from_path(
        testutils::get_test_file_path("Version-0.apversion")
            .as_path(), None);
    assert!(version.is_some());
    let version = version.unwrap();

    assert_eq!(version.uuid.as_ref().unwrap(), "MHMIbw5CQaiMgQ3n7g2w2A");
    assert!(version.is_original.unwrap());
    assert_eq!(version.master_uuid.as_ref().unwrap(), "WZMCPPRHR%C3nffgeeS4IQ");
    assert_eq!(version.name.as_ref().unwrap(), "img_3136");
    assert!(version.iptc.is_some());
    let iptc = version.iptc.as_ref().unwrap();
    assert!(iptc.bag.contains_key("Byline"));
    assert!(iptc.bag.contains_key("CiAdrCity"));
    let exif = version.exif.as_ref().unwrap();
    assert!(exif.bag.contains_key("ApertureValue"));
    assert!(exif.bag.contains_key("Depth"))
    // XXX fix when have actual audit.
//    println!("report {:?}", report);
}
<|endoftext|>


<commit_before>extern crate translator;

extern crate piston;
extern crate piston_window;
#[macro_use]
extern crate conrod;
extern crate find_folder;

use piston_window::{PistonWindow, WindowSettings, Glyphs, UpdateEvent};
use piston::event_loop::EventLoop;
use conrod::{Theme, Ui, Canvas, TextBox, Widget, Sizeable};
use conrod::color::{self, Colorable};

fn main() {
    let window: PistonWindow = WindowSettings::new("Hello Conrod", [800, 600])
                                   .exit_on_esc(true)
                                   .vsync(true)
                                   .build()
                                   .unwrap();

    let mut ui = {
        let assets_path = find_folder::Search::KidsThenParents(3, 5).for_folder("assets").unwrap();
        let font_path = assets_path.join("NotoSans-Regular.ttf");
        let theme = Theme::default();
        let glyph_cache = Glyphs::new(&font_path, window.factory.borrow().clone());
        Ui::new(glyph_cache.unwrap(), theme)
    };

    for w in window.ups(60) {
        ui.handle_event(&w);

        w.update(|_| {
            ui.set_widgets(|ui| {
                let background_color = color::rgb(0.2, 0.35, 0.45);
                let mut text = "".to_owned();

                Canvas::new()
                    .pad(30.)
                    .color(background_color)
                    .scroll_kids()
                    .set(CANVAS, ui);

                TextBox::new(&mut text)
                    .font_size(20)
                    .w_h(420.0, 40.0)
                    .color(background_color.invert())
                    .react(|_string: &mut String| {})
                    .set(INPUT_TEXT, ui);

                TextBox::new(&mut text)
                    .font_size(20)
                    .w_h(320.0, 40.0)
                    .color(background_color.invert())
                    .react(|_string: &mut String| {})
                    .set(OUTPUT_TEXT, ui);
            })
        });

        w.draw_2d(|context, graphic| ui.draw_if_changed(context, graphic));
    }
}

widget_ids! {
    CANVAS,
    INPUT_TEXT,
    OUTPUT_TEXT,
}
<commit_msg>Text boxes position<commit_after>extern crate translator;

extern crate piston;
extern crate piston_window;
#[macro_use]
extern crate conrod;
extern crate find_folder;

use piston_window::{PistonWindow, WindowSettings, Glyphs, UpdateEvent};
use piston::event_loop::EventLoop;
use conrod::{Theme, Ui, Canvas, TextBox, Widget, Sizeable, Positionable};
use conrod::color::{self, Colorable};

fn main() {
    let window: PistonWindow = WindowSettings::new("Hello Conrod", [800, 600])
                                   .exit_on_esc(true)
                                   .vsync(true)
                                   .build()
                                   .unwrap();

    let mut ui = {
        let assets_path = find_folder::Search::KidsThenParents(3, 5).for_folder("assets").unwrap();
        let font_path = assets_path.join("NotoSans-Regular.ttf");
        let theme = Theme::default();
        let glyph_cache = Glyphs::new(&font_path, window.factory.borrow().clone());
        Ui::new(glyph_cache.unwrap(), theme)
    };

    for w in window.ups(60) {
        ui.handle_event(&w);

        w.update(|_| {
            ui.set_widgets(|ui| {
                let background_color = color::rgb(0.2, 0.35, 0.45);
                let mut text = "".to_owned();

                Canvas::new()
                    .pad(30.)
                    .color(background_color)
                    .scroll_kids()
                    .set(CANVAS, ui);

                TextBox::new(&mut text)
                    .font_size(20)
                    .w_h(420.0, 40.0)
                    .mid_left_of(CANVAS)
                    .color(background_color.invert())
                    .react(|_string: &mut String| {})
                    .set(INPUT_TEXT, ui);

                TextBox::new(&mut text)
                    .font_size(20)
                    .w_h(320.0, 40.0)
                    .down_from(INPUT_TEXT, 45.0)
                    .color(background_color.invert())
                    .react(|_string: &mut String| {})
                    .set(OUTPUT_TEXT, ui);
            })
        });

        w.draw_2d(|context, graphic| ui.draw_if_changed(context, graphic));
    }
}

widget_ids! {
    CANVAS,
    INPUT_TEXT,
    OUTPUT_TEXT,
}
<|endoftext|>


<commit_before>#![feature(std_misc)]
#![feature(core)]

extern crate para_bm;

use std::time::Duration;
use std::thread::Thread;
use std::num::Float;

use para_bm::{sleep_ns};

fn fast () {
    sleep_ns(1000);
}

fn slow () {
    sleep_ns(10000000);
}

fn my_bench<F> (f: F) -> f64 where F: Fn() {

    // first "throw away" run
    let mut d = Duration::span(|| {
        f();
    });
    let ns = d.num_nanoseconds().unwrap();
    //println!("num nano seconds first run {}", ns);

    let mut sum = 0;
    // iterate to get more cache hits, etc...
    let iters = 100.0;
    for _ in 0 .. iters as usize {
        d = Duration::span(|| {
            f();
        });
        let ns = d.num_nanoseconds().unwrap();
        sum = sum + ns;
    }

    let avg = (sum as f64) / iters;
    //println!("average after first run {}", avg);

    return avg;
}

fn main () {

    let mut max_ns = 10000000.0;
    let mut min_ns = 1.0;

    let num_steps = 500;
    let step_size = (max_ns - min_ns) / num_steps as f64;
    let mut num_ns = min_ns;

    for power in 0 .. num_steps {
        println!("Size.....: {}", num_ns as i64);
        num_ns += step_size;

        let t_avg = my_bench(||{
            let threads_holder = (0 .. 3).map(|_| {
                Thread::scoped(move || {
                    sleep_ns(num_ns as i64);
                })
            }).collect::<Vec<_>>();
        });
        println!("Runtime thread....: {}", t_avg);

        let s_avg = my_bench(||{
            let serial_holder = (0 .. 3).map(|_| {
                sleep_ns(num_ns as i64);
            }).collect::<Vec<_>>();
        });
        println!("Runtime serial....: {}", s_avg);

        if t_avg < s_avg {
            println!("Cutoff size {}", num_ns);
            break;
        }
    }
}
<commit_msg>remove uneeded overhead for serial<commit_after>#![feature(std_misc)]
#![feature(core)]

extern crate para_bm;

use std::time::Duration;
use std::thread::Thread;
use std::num::Float;

use para_bm::{sleep_ns};

fn fast () {
    sleep_ns(1000);
}

fn slow () {
    sleep_ns(10000000);
}

fn my_bench<F> (f: F) -> f64 where F: Fn() {

    // first "throw away" run
    let mut d = Duration::span(|| {
        f();
    });
    let ns = d.num_nanoseconds().unwrap();
    //println!("num nano seconds first run {}", ns);

    let mut sum = 0;
    // iterate to get more cache hits, etc...
    let iters = 100.0;
    for _ in 0 .. iters as usize {
        d = Duration::span(|| {
            f();
        });
        let ns = d.num_nanoseconds().unwrap();
        sum = sum + ns;
    }

    let avg = (sum as f64) / iters;
    //println!("average after first run {}", avg);

    return avg;
}

fn main () {

    let mut max_ns = 10000000.0;
    let mut min_ns = 1.0;

    let num_steps = 500;
    let step_size = (max_ns - min_ns) / num_steps as f64;
    let mut num_ns = min_ns;

    for power in 0 .. num_steps {
        println!("Size.....: {}", num_ns as i64);
        num_ns += step_size;

        let t_avg = my_bench(||{
            let threads_holder = (0 .. 3).map(|_| {
                Thread::scoped(move || {
                    sleep_ns(num_ns as i64);
                })
            }).collect::<Vec<_>>();
        });
        println!("Runtime thread....: {}", t_avg);

        let s_avg = my_bench(||{
            sleep_ns(num_ns as i64);
            sleep_ns(num_ns as i64);
            sleep_ns(num_ns as i64);
        });
        println!("Runtime serial....: {}", s_avg);

        if t_avg < s_avg {
            println!("Cutoff size {}", num_ns);
            break;
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 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 module for working with borrowed data.

#![stable(feature = "rust1", since = "1.0.0")]

use core::clone::Clone;
use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
use core::convert::AsRef;
use core::hash::{Hash, Hasher};
use core::marker::Sized;
use core::ops::Deref;
use core::option::Option;

use fmt;
use alloc::{rc, arc};

use self::Cow::*;

/// A trait for borrowing data.
///
/// In general, there may be several ways to "borrow" a piece of data.  The
/// typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T`
/// (a mutable borrow). But types like `Vec<T>` provide additional kinds of
/// borrows: the borrowed slices `&[T]` and `&mut [T]`.
///
/// When writing generic code, it is often desirable to abstract over all ways
/// of borrowing data from a given type. That is the role of the `Borrow`
/// trait: if `T: Borrow<U>`, then `&U` can be borrowed from `&T`.  A given
/// type can be borrowed as multiple different types. In particular, `Vec<T>:
/// Borrow<Vec<T>>` and `Vec<T>: Borrow<[T]>`.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Borrow<Borrowed: ?Sized> {
    /// Immutably borrow from an owned value.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::borrow::Borrow;
    ///
    /// fn check<T: Borrow<str>>(s: T) {
    ///     assert_eq!("Hello", s.borrow());
    /// }
    ///
    /// let s = "Hello".to_string();
    ///
    /// check(s);
    ///
    /// let s = "Hello";
    ///
    /// check(s);
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    fn borrow(&self) -> &Borrowed;
}

/// A trait for mutably borrowing data.
///
/// Similar to `Borrow`, but for mutable borrows.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait BorrowMut<Borrowed: ?Sized> : Borrow<Borrowed> {
    /// Mutably borrow from an owned value.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::borrow::BorrowMut;
    ///
    /// fn check<T: BorrowMut<[i32]>>(mut v: T) {
    ///     assert_eq!(&mut [1, 2, 3], v.borrow_mut());
    /// }
    ///
    /// let v = vec![1, 2, 3];
    ///
    /// check(v);
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    fn borrow_mut(&mut self) -> &mut Borrowed;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Borrow<T> for T {
    fn borrow(&self) -> &T { self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> BorrowMut<T> for T {
    fn borrow_mut(&mut self) -> &mut T { self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized> Borrow<T> for &'a T {
    fn borrow(&self) -> &T { &**self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized> Borrow<T> for &'a mut T {
    fn borrow(&self) -> &T { &**self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized> BorrowMut<T> for &'a mut T {
    fn borrow_mut(&mut self) -> &mut T { &mut **self }
}

impl<T> Borrow<T> for rc::Rc<T> {
    fn borrow(&self) -> &T { &**self }
}

impl<T> Borrow<T> for arc::Arc<T> {
    fn borrow(&self) -> &T { &**self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Borrow<B> for Cow<'a, B> where B: ToOwned, <B as ToOwned>::Owned: 'a {
    fn borrow(&self) -> &B {
        &**self
    }
}

/// A generalization of Clone to borrowed data.
///
/// Some types make it possible to go from borrowed to owned, usually by
/// implementing the `Clone` trait. But `Clone` works only for going from `&T`
/// to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data
/// from any borrow of a given type.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait ToOwned {
    #[stable(feature = "rust1", since = "1.0.0")]
    type Owned: Borrow<Self>;

    /// Create owned data from borrowed data, usually by copying.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn to_owned(&self) -> Self::Owned;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ToOwned for T where T: Clone {
    type Owned = T;
    fn to_owned(&self) -> T { self.clone() }
}

/// A clone-on-write smart pointer.
///
/// The type `Cow` is a smart pointer providing clone-on-write functionality: it
/// can enclose and provide immutable access to borrowed data, and clone the
/// data lazily when mutation or ownership is required. The type is designed to
/// work with general borrowed data via the `Borrow` trait.
///
/// `Cow` implements both `Deref`, which means that you can call
/// non-mutating methods directly on the data it encloses. If mutation
/// is desired, `to_mut` will obtain a mutable references to an owned
/// value, cloning if necessary.
///
/// # Examples
///
/// ```
/// use std::borrow::Cow;
///
/// fn abs_all(input: &mut Cow<[i32]>) {
///     for i in 0..input.len() {
///         let v = input[i];
///         if v < 0 {
///             // clones into a vector the first time (if not already owned)
///             input.to_mut()[i] = -v;
///         }
///     }
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub enum Cow<'a, B: ?Sized + 'a> where B: ToOwned {
    /// Borrowed data.
    #[stable(feature = "rust1", since = "1.0.0")]
    Borrowed(&'a B),

    /// Owned data.
    #[stable(feature = "rust1", since = "1.0.0")]
    Owned(<B as ToOwned>::Owned)
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Clone for Cow<'a, B> where B: ToOwned {
    fn clone(&self) -> Cow<'a, B> {
        match *self {
            Borrowed(b) => Borrowed(b),
            Owned(ref o) => {
                let b: &B = o.borrow();
                Owned(b.to_owned())
            },
        }
    }
}

impl<'a, B: ?Sized> Cow<'a, B> where B: ToOwned {
    /// Acquire a mutable reference to the owned form of the data.
    ///
    /// Copies the data if it is not already owned.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::borrow::Cow;
    ///
    /// let mut cow: Cow<[_]> = Cow::Owned(vec![1, 2, 3]);
    ///
    /// let hello = cow.to_mut();
    ///
    /// assert_eq!(hello, &[1, 2, 3]);
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn to_mut(&mut self) -> &mut <B as ToOwned>::Owned {
        match *self {
            Borrowed(borrowed) => {
                *self = Owned(borrowed.to_owned());
                self.to_mut()
            }
            Owned(ref mut owned) => owned
        }
    }

    /// Extract the owned data.
    ///
    /// Copies the data if it is not already owned.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::borrow::Cow;
    ///
    /// let cow: Cow<[_]> = Cow::Owned(vec![1, 2, 3]);
    ///
    /// let hello = cow.into_owned();
    ///
    /// assert_eq!(vec![1, 2, 3], hello);
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn into_owned(self) -> <B as ToOwned>::Owned {
        match self {
            Borrowed(borrowed) => borrowed.to_owned(),
            Owned(owned) => owned
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Deref for Cow<'a, B> where B: ToOwned {
    type Target = B;

    fn deref(&self) -> &B {
        match *self {
            Borrowed(borrowed) => borrowed,
            Owned(ref owned) => owned.borrow()
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Eq for Cow<'a, B> where B: Eq + ToOwned {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Ord for Cow<'a, B> where B: Ord + ToOwned {
    #[inline]
    fn cmp(&self, other: &Cow<'a, B>) -> Ordering {
        Ord::cmp(&**self, &**other)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b, B: ?Sized, C: ?Sized> PartialEq<Cow<'b, C>> for Cow<'a, B> where
    B: PartialEq<C> + ToOwned, C: ToOwned,
{
    #[inline]
    fn eq(&self, other: &Cow<'b, C>) -> bool {
        PartialEq::eq(&**self, &**other)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> PartialOrd for Cow<'a, B> where B: PartialOrd + ToOwned,
{
    #[inline]
    fn partial_cmp(&self, other: &Cow<'a, B>) -> Option<Ordering> {
        PartialOrd::partial_cmp(&**self, &**other)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> fmt::Debug for Cow<'a, B> where
    B: fmt::Debug + ToOwned,
    <B as ToOwned>::Owned: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Borrowed(ref b) => fmt::Debug::fmt(b, f),
            Owned(ref o) => fmt::Debug::fmt(o, f),
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> fmt::Display for Cow<'a, B> where
    B: fmt::Display + ToOwned,
    <B as ToOwned>::Owned: fmt::Display,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Borrowed(ref b) => fmt::Display::fmt(b, f),
            Owned(ref o) => fmt::Display::fmt(o, f),
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Hash for Cow<'a, B> where B: Hash + ToOwned
{
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        Hash::hash(&**self, state)
    }
}

/// Trait for moving into a `Cow`
#[unstable(feature = "into_cow", reason = "may be replaced by `convert::Into`")]
pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
    /// Moves `self` into `Cow`
    fn into_cow(self) -> Cow<'a, B>;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a,  B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned {
    fn into_cow(self) -> Cow<'a, B> {
        self
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized + ToOwned> AsRef<T> for Cow<'a, T> {
    fn as_ref(&self) -> &T {
        self
    }
}
<commit_msg>Fix `borrow` docs<commit_after>// Copyright 2014 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 module for working with borrowed data.

#![stable(feature = "rust1", since = "1.0.0")]

use core::clone::Clone;
use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
use core::convert::AsRef;
use core::hash::{Hash, Hasher};
use core::marker::Sized;
use core::ops::Deref;
use core::option::Option;

use fmt;
use alloc::{rc, arc};

use self::Cow::*;

/// A trait for borrowing data.
///
/// In general, there may be several ways to "borrow" a piece of data.  The
/// typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T`
/// (a mutable borrow). But types like `Vec<T>` provide additional kinds of
/// borrows: the borrowed slices `&[T]` and `&mut [T]`.
///
/// When writing generic code, it is often desirable to abstract over all ways
/// of borrowing data from a given type. That is the role of the `Borrow`
/// trait: if `T: Borrow<U>`, then `&U` can be borrowed from `&T`.  A given
/// type can be borrowed as multiple different types. In particular, `Vec<T>:
/// Borrow<Vec<T>>` and `Vec<T>: Borrow<[T]>`.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Borrow<Borrowed: ?Sized> {
    /// Immutably borrows from an owned value.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::borrow::Borrow;
    ///
    /// fn check<T: Borrow<str>>(s: T) {
    ///     assert_eq!("Hello", s.borrow());
    /// }
    ///
    /// let s = "Hello".to_string();
    ///
    /// check(s);
    ///
    /// let s = "Hello";
    ///
    /// check(s);
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    fn borrow(&self) -> &Borrowed;
}

/// A trait for mutably borrowing data.
///
/// Similar to `Borrow`, but for mutable borrows.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait BorrowMut<Borrowed: ?Sized> : Borrow<Borrowed> {
    /// Mutably borrows from an owned value.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::borrow::BorrowMut;
    ///
    /// fn check<T: BorrowMut<[i32]>>(mut v: T) {
    ///     assert_eq!(&mut [1, 2, 3], v.borrow_mut());
    /// }
    ///
    /// let v = vec![1, 2, 3];
    ///
    /// check(v);
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    fn borrow_mut(&mut self) -> &mut Borrowed;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Borrow<T> for T {
    fn borrow(&self) -> &T { self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> BorrowMut<T> for T {
    fn borrow_mut(&mut self) -> &mut T { self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized> Borrow<T> for &'a T {
    fn borrow(&self) -> &T { &**self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized> Borrow<T> for &'a mut T {
    fn borrow(&self) -> &T { &**self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized> BorrowMut<T> for &'a mut T {
    fn borrow_mut(&mut self) -> &mut T { &mut **self }
}

impl<T> Borrow<T> for rc::Rc<T> {
    fn borrow(&self) -> &T { &**self }
}

impl<T> Borrow<T> for arc::Arc<T> {
    fn borrow(&self) -> &T { &**self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Borrow<B> for Cow<'a, B> where B: ToOwned, <B as ToOwned>::Owned: 'a {
    fn borrow(&self) -> &B {
        &**self
    }
}

/// A generalization of `Clone` to borrowed data.
///
/// Some types make it possible to go from borrowed to owned, usually by
/// implementing the `Clone` trait. But `Clone` works only for going from `&T`
/// to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data
/// from any borrow of a given type.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait ToOwned {
    #[stable(feature = "rust1", since = "1.0.0")]
    type Owned: Borrow<Self>;

    /// Creates owned data from borrowed data, usually by cloning.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn to_owned(&self) -> Self::Owned;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ToOwned for T where T: Clone {
    type Owned = T;
    fn to_owned(&self) -> T { self.clone() }
}

/// A clone-on-write smart pointer.
///
/// The type `Cow` is a smart pointer providing clone-on-write functionality: it
/// can enclose and provide immutable access to borrowed data, and clone the
/// data lazily when mutation or ownership is required. The type is designed to
/// work with general borrowed data via the `Borrow` trait.
///
/// `Cow` implements `Deref`, which means that you can call
/// non-mutating methods directly on the data it encloses. If mutation
/// is desired, `to_mut` will obtain a mutable reference to an owned
/// value, cloning if necessary.
///
/// # Examples
///
/// ```
/// use std::borrow::Cow;
///
/// fn abs_all(input: &mut Cow<[i32]>) {
///     for i in 0..input.len() {
///         let v = input[i];
///         if v < 0 {
///             // clones into a vector the first time (if not already owned)
///             input.to_mut()[i] = -v;
///         }
///     }
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub enum Cow<'a, B: ?Sized + 'a> where B: ToOwned {
    /// Borrowed data.
    #[stable(feature = "rust1", since = "1.0.0")]
    Borrowed(&'a B),

    /// Owned data.
    #[stable(feature = "rust1", since = "1.0.0")]
    Owned(<B as ToOwned>::Owned)
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Clone for Cow<'a, B> where B: ToOwned {
    fn clone(&self) -> Cow<'a, B> {
        match *self {
            Borrowed(b) => Borrowed(b),
            Owned(ref o) => {
                let b: &B = o.borrow();
                Owned(b.to_owned())
            },
        }
    }
}

impl<'a, B: ?Sized> Cow<'a, B> where B: ToOwned {
    /// Acquires a mutable reference to the owned form of the data.
    ///
    /// Copies the data if it is not already owned.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::borrow::Cow;
    ///
    /// let mut cow: Cow<[_]> = Cow::Owned(vec![1, 2, 3]);
    ///
    /// let hello = cow.to_mut();
    ///
    /// assert_eq!(hello, &[1, 2, 3]);
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn to_mut(&mut self) -> &mut <B as ToOwned>::Owned {
        match *self {
            Borrowed(borrowed) => {
                *self = Owned(borrowed.to_owned());
                self.to_mut()
            }
            Owned(ref mut owned) => owned
        }
    }

    /// Extracts the owned data.
    ///
    /// Copies the data if it is not already owned.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::borrow::Cow;
    ///
    /// let cow: Cow<[_]> = Cow::Owned(vec![1, 2, 3]);
    ///
    /// let hello = cow.into_owned();
    ///
    /// assert_eq!(vec![1, 2, 3], hello);
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn into_owned(self) -> <B as ToOwned>::Owned {
        match self {
            Borrowed(borrowed) => borrowed.to_owned(),
            Owned(owned) => owned
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Deref for Cow<'a, B> where B: ToOwned {
    type Target = B;

    fn deref(&self) -> &B {
        match *self {
            Borrowed(borrowed) => borrowed,
            Owned(ref owned) => owned.borrow()
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Eq for Cow<'a, B> where B: Eq + ToOwned {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Ord for Cow<'a, B> where B: Ord + ToOwned {
    #[inline]
    fn cmp(&self, other: &Cow<'a, B>) -> Ordering {
        Ord::cmp(&**self, &**other)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b, B: ?Sized, C: ?Sized> PartialEq<Cow<'b, C>> for Cow<'a, B> where
    B: PartialEq<C> + ToOwned, C: ToOwned,
{
    #[inline]
    fn eq(&self, other: &Cow<'b, C>) -> bool {
        PartialEq::eq(&**self, &**other)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> PartialOrd for Cow<'a, B> where B: PartialOrd + ToOwned,
{
    #[inline]
    fn partial_cmp(&self, other: &Cow<'a, B>) -> Option<Ordering> {
        PartialOrd::partial_cmp(&**self, &**other)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> fmt::Debug for Cow<'a, B> where
    B: fmt::Debug + ToOwned,
    <B as ToOwned>::Owned: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Borrowed(ref b) => fmt::Debug::fmt(b, f),
            Owned(ref o) => fmt::Debug::fmt(o, f),
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> fmt::Display for Cow<'a, B> where
    B: fmt::Display + ToOwned,
    <B as ToOwned>::Owned: fmt::Display,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Borrowed(ref b) => fmt::Display::fmt(b, f),
            Owned(ref o) => fmt::Display::fmt(o, f),
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Hash for Cow<'a, B> where B: Hash + ToOwned
{
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        Hash::hash(&**self, state)
    }
}

/// Trait for moving into a `Cow`.
#[unstable(feature = "into_cow", reason = "may be replaced by `convert::Into`")]
pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
    /// Moves `self` into `Cow`
    fn into_cow(self) -> Cow<'a, B>;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a,  B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned {
    fn into_cow(self) -> Cow<'a, B> {
        self
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized + ToOwned> AsRef<T> for Cow<'a, T> {
    fn as_ref(&self) -> &T {
        self
    }
}
<|endoftext|>