<commit_before>extern crate png;

use predicates::prelude::*;
use predicates::reflection::{Case, Child, PredicateReflection, Product};
use std::fmt;
use std::io::BufReader;
use std::path::{Path, PathBuf};

use librsvg::surface_utils::shared_surface::{SharedImageSurface, SurfaceType};

use crate::compare_surfaces::BufferDiff;
use crate::reference_utils::{surface_from_png, Compare, Deviation, Reference};

/// Checks that the variable of type [u8] can be parsed as a PNG file.
#[derive(Debug)]
pub struct PngPredicate {}

impl PngPredicate {
    pub fn with_size(self: Self, w: u32, h: u32) -> SizePredicate<Self> {
        SizePredicate::<Self> { p: self, w, h }
    }

    pub fn with_contents<P: AsRef<Path>>(self: Self, reference: P) -> ReferencePredicate<Self> {
        let mut path = PathBuf::new();
        path.push(reference);
        ReferencePredicate::<Self> { p: self, path }
    }
}

impl Predicate<[u8]> for PngPredicate {
    fn eval(&self, data: &[u8]) -> bool {
        let decoder = png::Decoder::new(data);
        decoder.read_info().is_ok()
    }

    fn find_case<'a>(&'a self, _expected: bool, data: &[u8]) -> Option<Case<'a>> {
        let decoder = png::Decoder::new(data);
        match decoder.read_info() {
            Ok(_) => None,
            Err(e) => Some(Case::new(Some(self), false).add_product(Product::new("Error", e))),
        }
    }
}

impl PredicateReflection for PngPredicate {}

impl fmt::Display for PngPredicate {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "is a PNG")
    }
}

/// Extends a PngPredicate by a check for a given size of the PNG file.
#[derive(Debug)]
pub struct SizePredicate<PngPredicate> {
    p: PngPredicate,
    w: u32,
    h: u32,
}

impl SizePredicate<PngPredicate> {
    fn eval_info(&self, info: &png::OutputInfo) -> bool {
        info.width == self.w && info.height == self.h
    }

    fn find_case_for_info<'a>(
        &'a self,
        expected: bool,
        info: &png::OutputInfo,
    ) -> Option<Case<'a>> {
        if self.eval_info(info) == expected {
            let product = self.product_for_info(info);
            Some(Case::new(Some(self), false).add_product(product))
        } else {
            None
        }
    }

    fn product_for_info(&self, info: &png::OutputInfo) -> Product {
        let actual_size = format!("{} x {}", info.width, info.height);
        Product::new("actual size", actual_size)
    }
}

impl Predicate<[u8]> for SizePredicate<PngPredicate> {
    fn eval(&self, data: &[u8]) -> bool {
        let decoder = png::Decoder::new(data);
        match decoder.read_info() {
            Ok((info, _)) => self.eval_info(&info),
            _ => false,
        }
    }

    fn find_case<'a>(&'a self, expected: bool, data: &[u8]) -> Option<Case<'a>> {
        let decoder = png::Decoder::new(data);
        match decoder.read_info() {
            Ok((info, _)) => self.find_case_for_info(expected, &info),
            Err(e) => Some(Case::new(Some(self), false).add_product(Product::new("Error", e))),
        }
    }
}

impl PredicateReflection for SizePredicate<PngPredicate> {
    fn children<'a>(&'a self) -> Box<dyn Iterator<Item = Child<'a>> + 'a> {
        let params = vec![Child::new("predicate", &self.p)];
        Box::new(params.into_iter())
    }
}

impl fmt::Display for SizePredicate<PngPredicate> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "is a PNG with size {} x {}", self.w, self.h)
    }
}

/// Extends a PngPredicate by a comparison to the contents of a reference file
#[derive(Debug)]
pub struct ReferencePredicate<PngPredicate> {
    p: PngPredicate,
    path: PathBuf,
}

impl ReferencePredicate<PngPredicate> {
    fn diff_acceptable(diff: &BufferDiff) -> bool {
        match diff {
            BufferDiff::DifferentSizes => false,
            BufferDiff::Diff(diff) => !diff.inacceptable(),
        }
    }

    fn diff_surface(&self, surface: &SharedImageSurface) -> Option<BufferDiff> {
        let reference = Reference::from_png(&self.path).unwrap();
        if let Ok(diff) = reference.compare(&surface) {
            if !Self::diff_acceptable(&diff) {
                return Some(diff);
            }
        }
        None
    }

    fn find_case_for_surface<'a>(
        &'a self,
        expected: bool,
        surface: &SharedImageSurface,
    ) -> Option<Case<'a>> {
        let diff = self.diff_surface(&surface);
        if diff.is_some() != expected {
            let product = self.product_for_diff(&diff.unwrap());
            Some(Case::new(Some(self), false).add_product(product))
        } else {
            None
        }
    }

    fn product_for_diff(&self, diff: &BufferDiff) -> Product {
        let difference = format!("{}", diff);
        Product::new("images differ", difference)
    }
}

impl Predicate<[u8]> for ReferencePredicate<PngPredicate> {
    fn eval(&self, data: &[u8]) -> bool {
        if let Ok(surface) = surface_from_png(&mut BufReader::new(data)) {
            let surface = SharedImageSurface::wrap(surface, SurfaceType::SRgb).unwrap();
            self.diff_surface(&surface).is_some()
        } else {
            false
        }
    }

    fn find_case<'a>(&'a self, expected: bool, data: &[u8]) -> Option<Case<'a>> {
        match surface_from_png(&mut BufReader::new(data)) {
            Ok(surface) => {
                let surface = SharedImageSurface::wrap(surface, SurfaceType::SRgb).unwrap();
                self.find_case_for_surface(expected, &surface)
            }
            Err(e) => Some(Case::new(Some(self), false).add_product(Product::new("Error", e))),
        }
    }
}

impl PredicateReflection for ReferencePredicate<PngPredicate> {
    fn children<'a>(&'a self) -> Box<dyn Iterator<Item = Child<'a>> + 'a> {
        let params = vec![Child::new("predicate", &self.p)];
        Box::new(params.into_iter())
    }
}

impl fmt::Display for ReferencePredicate<PngPredicate> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "is a PNG that matches the reference {}",
            self.path.display()
        )
    }
}
<commit_msg>When a test reference file doesn't exist, panic with a better message<commit_after>extern crate png;

use predicates::prelude::*;
use predicates::reflection::{Case, Child, PredicateReflection, Product};
use std::fmt;
use std::io::BufReader;
use std::path::{Path, PathBuf};

use librsvg::surface_utils::shared_surface::{SharedImageSurface, SurfaceType};

use crate::compare_surfaces::BufferDiff;
use crate::reference_utils::{surface_from_png, Compare, Deviation, Reference};

/// Checks that the variable of type [u8] can be parsed as a PNG file.
#[derive(Debug)]
pub struct PngPredicate {}

impl PngPredicate {
    pub fn with_size(self: Self, w: u32, h: u32) -> SizePredicate<Self> {
        SizePredicate::<Self> { p: self, w, h }
    }

    pub fn with_contents<P: AsRef<Path>>(self: Self, reference: P) -> ReferencePredicate<Self> {
        let mut path = PathBuf::new();
        path.push(reference);
        ReferencePredicate::<Self> { p: self, path }
    }
}

impl Predicate<[u8]> for PngPredicate {
    fn eval(&self, data: &[u8]) -> bool {
        let decoder = png::Decoder::new(data);
        decoder.read_info().is_ok()
    }

    fn find_case<'a>(&'a self, _expected: bool, data: &[u8]) -> Option<Case<'a>> {
        let decoder = png::Decoder::new(data);
        match decoder.read_info() {
            Ok(_) => None,
            Err(e) => Some(Case::new(Some(self), false).add_product(Product::new("Error", e))),
        }
    }
}

impl PredicateReflection for PngPredicate {}

impl fmt::Display for PngPredicate {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "is a PNG")
    }
}

/// Extends a PngPredicate by a check for a given size of the PNG file.
#[derive(Debug)]
pub struct SizePredicate<PngPredicate> {
    p: PngPredicate,
    w: u32,
    h: u32,
}

impl SizePredicate<PngPredicate> {
    fn eval_info(&self, info: &png::OutputInfo) -> bool {
        info.width == self.w && info.height == self.h
    }

    fn find_case_for_info<'a>(
        &'a self,
        expected: bool,
        info: &png::OutputInfo,
    ) -> Option<Case<'a>> {
        if self.eval_info(info) == expected {
            let product = self.product_for_info(info);
            Some(Case::new(Some(self), false).add_product(product))
        } else {
            None
        }
    }

    fn product_for_info(&self, info: &png::OutputInfo) -> Product {
        let actual_size = format!("{} x {}", info.width, info.height);
        Product::new("actual size", actual_size)
    }
}

impl Predicate<[u8]> for SizePredicate<PngPredicate> {
    fn eval(&self, data: &[u8]) -> bool {
        let decoder = png::Decoder::new(data);
        match decoder.read_info() {
            Ok((info, _)) => self.eval_info(&info),
            _ => false,
        }
    }

    fn find_case<'a>(&'a self, expected: bool, data: &[u8]) -> Option<Case<'a>> {
        let decoder = png::Decoder::new(data);
        match decoder.read_info() {
            Ok((info, _)) => self.find_case_for_info(expected, &info),
            Err(e) => Some(Case::new(Some(self), false).add_product(Product::new("Error", e))),
        }
    }
}

impl PredicateReflection for SizePredicate<PngPredicate> {
    fn children<'a>(&'a self) -> Box<dyn Iterator<Item = Child<'a>> + 'a> {
        let params = vec![Child::new("predicate", &self.p)];
        Box::new(params.into_iter())
    }
}

impl fmt::Display for SizePredicate<PngPredicate> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "is a PNG with size {} x {}", self.w, self.h)
    }
}

/// Extends a PngPredicate by a comparison to the contents of a reference file
#[derive(Debug)]
pub struct ReferencePredicate<PngPredicate> {
    p: PngPredicate,
    path: PathBuf,
}

impl ReferencePredicate<PngPredicate> {
    fn diff_acceptable(diff: &BufferDiff) -> bool {
        match diff {
            BufferDiff::DifferentSizes => false,
            BufferDiff::Diff(diff) => !diff.inacceptable(),
        }
    }

    fn diff_surface(&self, surface: &SharedImageSurface) -> Option<BufferDiff> {
        let reference = Reference::from_png(&self.path)
            .unwrap_or_else(|_| panic!("could not open {:?}", self.path));
        if let Ok(diff) = reference.compare(&surface) {
            if !Self::diff_acceptable(&diff) {
                return Some(diff);
            }
        }
        None
    }

    fn find_case_for_surface<'a>(
        &'a self,
        expected: bool,
        surface: &SharedImageSurface,
    ) -> Option<Case<'a>> {
        let diff = self.diff_surface(&surface);
        if diff.is_some() != expected {
            let product = self.product_for_diff(&diff.unwrap());
            Some(Case::new(Some(self), false).add_product(product))
        } else {
            None
        }
    }

    fn product_for_diff(&self, diff: &BufferDiff) -> Product {
        let difference = format!("{}", diff);
        Product::new("images differ", difference)
    }
}

impl Predicate<[u8]> for ReferencePredicate<PngPredicate> {
    fn eval(&self, data: &[u8]) -> bool {
        if let Ok(surface) = surface_from_png(&mut BufReader::new(data)) {
            let surface = SharedImageSurface::wrap(surface, SurfaceType::SRgb).unwrap();
            self.diff_surface(&surface).is_some()
        } else {
            false
        }
    }

    fn find_case<'a>(&'a self, expected: bool, data: &[u8]) -> Option<Case<'a>> {
        match surface_from_png(&mut BufReader::new(data)) {
            Ok(surface) => {
                let surface = SharedImageSurface::wrap(surface, SurfaceType::SRgb).unwrap();
                self.find_case_for_surface(expected, &surface)
            }
            Err(e) => Some(Case::new(Some(self), false).add_product(Product::new("Error", e))),
        }
    }
}

impl PredicateReflection for ReferencePredicate<PngPredicate> {
    fn children<'a>(&'a self) -> Box<dyn Iterator<Item = Child<'a>> + 'a> {
        let params = vec![Child::new("predicate", &self.p)];
        Box::new(params.into_iter())
    }
}

impl fmt::Display for ReferencePredicate<PngPredicate> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "is a PNG that matches the reference {}",
            self.path.display()
        )
    }
}
<|endoftext|>


<commit_before>use ast::{Expr, ConstExpr, BlockExpr, TypeOfExpr, LocalExpr, GetConstFieldExpr, GetFieldExpr, CallExpr, WhileLoopExpr, IfExpr, SwitchExpr, ObjectDeclExpr, ArrayDeclExpr, FunctionDeclExpr, ArrowFunctionDeclExpr, NumOpExpr, BitOpExpr, LogOpExpr, CompOpExpr, ConstructExpr, ReturnExpr, ThrowExpr, AssignExpr};
use ast::{CNum, CInt, CString, CBool, CRegExp, CNull, CUndefined};
use ast::{OpSub, OpAdd, OpMul, OpDiv, OpMod};
use ast::{BitAnd, BitOr, BitXor, BitShl, BitShr};
use ast::{LogAnd, LogOr};
use ast::{CompEqual, CompNotEqual, CompStrictEqual, CompStrictNotEqual, CompGreaterThan, CompGreaterThanOrEqual, CompLessThan, CompLessThanOrEqual};
use js::value::{Value, ValueData, VNull, VUndefined, VString, VNumber, VInteger, VObject, VBoolean, VFunction, ResultValue, to_value, from_value};
use js::object::{INSTANCE_PROTOTYPE, PROTOTYPE, ObjectData};
use js::function::{RegularFunc, RegularFunction};
use js::{console, math, object, array, function, json, number, error, uri, string};
use collections::treemap::TreeMap;
use std::vec::Vec;
use std::gc::Gc;
use std::cell::RefCell;
use std::str::MaybeOwned;
/// An execution engine
pub trait Executor {
	/// Makes a new execution engine
	fn new() -> ~Self;
	/// Sets a global variable
	fn set_global(&mut self, name:MaybeOwned, val:Value) -> Value;
	/// Gets a global variable
	fn get_global(&self, name:MaybeOwned) -> Value;
	/// Make a new scope
	fn make_scope(&mut self) -> Gc<RefCell<ObjectData>>;
	/// Destroy the current scope
	fn destroy_scope(&mut self) -> ();
	/// Runs the expression
	fn run(&mut self, expr:&Expr) -> ResultValue;
}
#[deriving(Clone)]
/// An intepreter
pub struct Interpreter {
	/// An object representing the global variables
	global: Value,
	/// The scopes
	scopes: Vec<Gc<RefCell<ObjectData>>>,
}
impl Executor for Interpreter {
	fn new() -> ~Interpreter {
		let global = ValueData::new_obj(None);
		object::init(global);
		console::init(global);
		math::init(global);
		array::init(global);
		function::init(global);
		json::init(global);
		number::init(global);
		error::init(global);
		number::init(global);
		string::init(global);
		uri::init(global);
		return ~Interpreter {global: global, scopes: Vec::new()};
	}
	fn set_global(&mut self, name:MaybeOwned, val:Value) -> Value {
		self.global.borrow().set_field(name, val)
	}
	fn get_global(&self, name:MaybeOwned) -> Value {
		self.global.borrow().get_field(name)
	}
	fn make_scope(&mut self) -> Gc<RefCell<ObjectData>> {
		let value = Gc::new(RefCell::new(TreeMap::new()));
		self.scopes.push(value.clone());
		value
	}
	fn destroy_scope(&mut self) -> () {
		self.scopes.pop();
	}
	fn run(&mut self, expr:&Expr) -> ResultValue {
		match expr.def {
			ConstExpr(CNull) => Ok(Gc::new(VNull)),
			ConstExpr(CUndefined) => Ok(Gc::new(VUndefined)),
			ConstExpr(CNum(num)) => Ok(to_value(num)),
			ConstExpr(CInt(num)) => Ok(to_value(num)),
			ConstExpr(CString(ref str)) => Ok(Gc::new(VString(str.to_owned()))),
			ConstExpr(CBool(val)) => Ok(Gc::new(VBoolean(val))),
			ConstExpr(CRegExp(_, _, _)) => Ok(Gc::new(VNull)),
			BlockExpr(ref es) => {
				let mut obj = Gc::new(VNull);
				for e in es.iter() {
					let val = try!(self.run(*e));
					if e == es.last().unwrap() {
						obj = val;
					}
				}
				Ok(obj)
			},
			LocalExpr(ref name) => {
				let mut value = Gc::new(VUndefined);
				for scope in self.scopes.iter().rev() {
					match scope.borrow().borrow().find(name) {
						Some(v) => {
							value = v.value.clone();
							break;
						}
						None => ()
					}
				}
				Ok(if value.borrow().is_undefined() {
					self.global.borrow().get_field(name.clone().into_maybe_owned())
				} else {
					value
				})
			},
			GetConstFieldExpr(ref obj, ref field) => {
				let val_obj = try!(self.run(*obj));
				Ok(val_obj.borrow().get_field(field.clone().into_maybe_owned()))
			},
			GetFieldExpr(ref obj, ref field) => {
				let val_obj = try!(self.run(*obj));
				let val_field = try!(self.run(*field));
				Ok(val_obj.borrow().get_field(val_field.borrow().to_str().into_maybe_owned()))
			},
			CallExpr(ref callee, ref args) => {
				let (this, func) = match callee.def {
					GetConstFieldExpr(ref obj, ref field) => {
						let obj = try!(self.run(*obj));
						(obj, obj.borrow().get_field(field.clone().into_maybe_owned()))
					},
					GetFieldExpr(ref obj, ref field) => {
						let obj = try!(self.run(*obj));
						let field = try!(self.run(*field));
						(obj, obj.borrow().get_field(field.borrow().to_str().into_maybe_owned()))
					},
					_ => (self.global.clone(), try!(self.run(callee.clone())))
				};
				let mut v_args = Vec::with_capacity(args.len());
				for arg in args.iter() {
					v_args.push(try!(self.run(*arg)));
				}
				match *func.borrow() {
					VFunction(ref func) => {
						func.borrow().call(self, this, Gc::new(VNull), v_args)
					},
					_ => Err(Gc::new(VUndefined))
				}
			},
			WhileLoopExpr(ref cond, ref expr) => {
				let mut result = Gc::new(VUndefined);
				while try!(self.run(*cond)).borrow().is_true() {
					result = try!(self.run(*expr));
				}
				Ok(result)
			},
			IfExpr(ref cond, ref expr, None) => {
				Ok(if try!(self.run(*cond)).borrow().is_true() {
					try!(self.run(*expr))
				} else {
					Gc::new(VUndefined)
				})
			},
			IfExpr(ref cond, ref expr, Some(ref else_e)) => {
				Ok(if try!(self.run(*cond)).borrow().is_true() {
					try!(self.run(*expr))
				} else {
					try!(self.run(*else_e))
				})
			},
			SwitchExpr(ref val_e, ref vals, ref default) => {
				let val = try!(self.run(*val_e)).borrow().clone();
				let mut result = Gc::new(VNull);
				let mut matched = false;
				for tup in vals.iter() {
					let tup:&(~Expr, Vec<~Expr>) = tup;
					match *tup {
						(ref cond, ref block) if(val == *try!(self.run(*cond)).borrow()) => {
							matched = true;
							let last_expr = block.last().unwrap();
							for expr in block.iter() {
								let e_result = try!(self.run(*expr));
								if expr == last_expr {
									result = e_result;
								}
							}
						},
						_ => ()
					}
				}
				if !matched && default.is_some() {
					result = try!(self.run(*default.as_ref().unwrap()));
				}
				Ok(result)
			},
			ObjectDeclExpr(ref map) => {
				let obj = ValueData::new_obj(Some(self.global));
				for (key, val) in map.iter() {
					obj.borrow().set_field(key.clone().into_maybe_owned(), try!(self.run(val.clone())));
				}
				Ok(obj)
			},
			ArrayDeclExpr(ref arr) => {
				let arr_map = ValueData::new_obj(Some(self.global));
				let mut index : i32 = 0;
				for val in arr.iter() {
					let val = try!(self.run(val.clone()));
					arr_map.borrow().set_field(index.to_str().into_maybe_owned(), val);
					index += 1;
				}
				arr_map.borrow().set_field(INSTANCE_PROTOTYPE.into_maybe_owned(), self.get_global("Array".into_maybe_owned()).borrow().get_field(PROTOTYPE.into_maybe_owned()));
				arr_map.borrow().set_field("length".into_maybe_owned(), to_value(index));
				Ok(arr_map)
			},
			FunctionDeclExpr(ref name, ref args, ref expr) => {
				let function = RegularFunc(RegularFunction::new(*expr.clone(), args.clone()));
				let val = Gc::new(VFunction(RefCell::new(function)));
				if name.is_some() {
					self.global.borrow().set_field(name.clone().unwrap().into_maybe_owned(), val);
				}
				Ok(val)
			},
			ArrowFunctionDeclExpr(ref args, ref expr) => {
				let function = RegularFunc(RegularFunction::new(*expr.clone(), args.clone()));
				Ok(Gc::new(VFunction(RefCell::new(function))))
			},
			NumOpExpr(ref op, ref a, ref b) => {
				let v_a = try!(self.run(*a)).borrow().clone();
				let v_b = try!(self.run(*b)).borrow().clone();
				Ok(Gc::new(match *op {
					OpAdd => v_a + v_b,
					OpSub => v_a - v_b,
					OpMul => v_a * v_b,
					OpDiv => v_a / v_b,
					OpMod => v_a % v_b
				}))
			},
			BitOpExpr(ref op, ref a, ref b) => {
				let v_a = try!(self.run(*a)).borrow().clone();
				let v_b = try!(self.run(*b)).borrow().clone();
				Ok(Gc::new(match *op {
					BitAnd => v_a & v_b,
					BitOr => v_a | v_b,
					BitXor => v_a ^ v_b,
					BitShl => v_a << v_b,
					BitShr => v_a >> v_b
				}))
			},
			CompOpExpr(ref op, ref a, ref b) => {
				let v_r_a = try!(self.run(*a));
				let v_r_b = try!(self.run(*b));
				let v_a = v_r_a.borrow();
				let v_b = v_r_b.borrow();
				Ok(to_value(match *op {
					CompEqual => v_r_a.ptr_eq(&v_r_b) || v_a == v_b,
					CompNotEqual => !v_r_a.ptr_eq(&v_r_b) || v_a != v_b,
					CompStrictEqual => v_r_a.ptr_eq(&v_r_b) || v_a == v_b,
					CompStrictNotEqual => !v_r_a.ptr_eq(&v_r_b) || v_a != v_b,
					CompGreaterThan => v_a.to_num() > v_b.to_num(),
					CompGreaterThanOrEqual => v_a.to_num() >= v_b.to_num(),
					CompLessThan => v_a.to_num() < v_b.to_num(),
					CompLessThanOrEqual => v_a.to_num() <= v_b.to_num()
				}))
			},
			LogOpExpr(ref op, ref a, ref b) => {
				let v_a = from_value::<bool>(try!(self.run(*a))).unwrap();
				let v_b = from_value::<bool>(try!(self.run(*b))).unwrap();
				Ok(match *op {
					LogAnd => to_value(v_a && v_b),
					LogOr => to_value(v_a || v_b)
				})
			},
			ConstructExpr(ref callee, ref args) => {
				let func = try!(self.run(*callee));
				let mut v_args = Vec::with_capacity(args.len());
				for arg in args.iter() {
					v_args.push(try!(self.run(*arg)));
				}
				let this = Gc::new(VObject(RefCell::new(TreeMap::new())));
				this.borrow().set_field(INSTANCE_PROTOTYPE.into_maybe_owned(), func.borrow().get_field(PROTOTYPE.into_maybe_owned()));
				Ok(match *func.borrow() {
					VFunction(ref func) => {
						try!(func.borrow().call(self, this, Gc::new(VNull), v_args));
						this
					},
					_ => Gc::new(VUndefined)
				})
			},
			ReturnExpr(ref ret) => {
				match *ret {
					Some(ref v) =>
						self.run(v.clone()),
					None => Ok(Gc::new(VUndefined))
				}
			},
			ThrowExpr(ref ex) => Err(try!(self.run(*ex))),
			AssignExpr(ref ref_e, ref val_e) => {
				let val = try!(self.run(*val_e));
				match ref_e.def {
					LocalExpr(ref name) => {
						self.global.borrow().set_field(name.clone().into_maybe_owned(), val);
					},
					GetConstFieldExpr(ref obj, ref field) => {
						let val_obj = try!(self.run(*obj));
						val_obj.borrow().set_field(field.clone().into_maybe_owned(), val);
					},
					_ => ()
				}
				Ok(val)
			},
			TypeOfExpr(ref val_e) => {
				let val = try!(self.run(*val_e));
				Ok(to_value(match *val.borrow() {
					VUndefined => "undefined",
					VNull | VObject(_) => "object",
					VBoolean(_) => "boolean",
					VNumber(_) | VInteger(_) => "number",
					VString(_) => "string",
					VFunction(_) => "function"
				}.into_maybe_owned()))
			}
		}
	}
}<commit_msg>Avoid cloning values, use references instead<commit_after>use ast::{Expr, ConstExpr, BlockExpr, TypeOfExpr, LocalExpr, GetConstFieldExpr, GetFieldExpr, CallExpr, WhileLoopExpr, IfExpr, SwitchExpr, ObjectDeclExpr, ArrayDeclExpr, FunctionDeclExpr, ArrowFunctionDeclExpr, NumOpExpr, BitOpExpr, LogOpExpr, CompOpExpr, ConstructExpr, ReturnExpr, ThrowExpr, AssignExpr};
use ast::{CNum, CInt, CString, CBool, CRegExp, CNull, CUndefined};
use ast::{OpSub, OpAdd, OpMul, OpDiv, OpMod};
use ast::{BitAnd, BitOr, BitXor, BitShl, BitShr};
use ast::{LogAnd, LogOr};
use ast::{CompEqual, CompNotEqual, CompStrictEqual, CompStrictNotEqual, CompGreaterThan, CompGreaterThanOrEqual, CompLessThan, CompLessThanOrEqual};
use js::value::{Value, ValueData, VNull, VUndefined, VString, VNumber, VInteger, VObject, VBoolean, VFunction, ResultValue, to_value, from_value};
use js::object::{INSTANCE_PROTOTYPE, PROTOTYPE, ObjectData};
use js::function::{RegularFunc, RegularFunction};
use js::{console, math, object, array, function, json, number, error, uri, string};
use collections::treemap::TreeMap;
use std::vec::Vec;
use std::gc::Gc;
use std::cell::RefCell;
use std::str::MaybeOwned;
/// An execution engine
pub trait Executor {
	/// Makes a new execution engine
	fn new() -> ~Self;
	/// Sets a global variable
	fn set_global(&mut self, name:MaybeOwned, val:Value) -> Value;
	/// Gets a global variable
	fn get_global(&self, name:MaybeOwned) -> Value;
	/// Make a new scope
	fn make_scope(&mut self) -> Gc<RefCell<ObjectData>>;
	/// Destroy the current scope
	fn destroy_scope(&mut self) -> ();
	/// Runs the expression
	fn run(&mut self, expr:&Expr) -> ResultValue;
}
#[deriving(Clone)]
/// An intepreter
pub struct Interpreter {
	/// An object representing the global variables
	global: Value,
	/// The scopes
	scopes: Vec<Gc<RefCell<ObjectData>>>,
}
impl Executor for Interpreter {
	fn new() -> ~Interpreter {
		let global = ValueData::new_obj(None);
		object::init(global);
		console::init(global);
		math::init(global);
		array::init(global);
		function::init(global);
		json::init(global);
		number::init(global);
		error::init(global);
		number::init(global);
		string::init(global);
		uri::init(global);
		return ~Interpreter {global: global, scopes: Vec::new()};
	}
	fn set_global(&mut self, name:MaybeOwned, val:Value) -> Value {
		self.global.borrow().set_field(name, val)
	}
	fn get_global(&self, name:MaybeOwned) -> Value {
		self.global.borrow().get_field(name)
	}
	fn make_scope(&mut self) -> Gc<RefCell<ObjectData>> {
		let value = Gc::new(RefCell::new(TreeMap::new()));
		self.scopes.push(value.clone());
		value
	}
	fn destroy_scope(&mut self) -> () {
		self.scopes.pop();
	}
	fn run(&mut self, expr:&Expr) -> ResultValue {
		match expr.def {
			ConstExpr(CNull) => Ok(Gc::new(VNull)),
			ConstExpr(CUndefined) => Ok(Gc::new(VUndefined)),
			ConstExpr(CNum(num)) => Ok(to_value(num)),
			ConstExpr(CInt(num)) => Ok(to_value(num)),
			ConstExpr(CString(ref str)) => Ok(Gc::new(VString(str.to_owned()))),
			ConstExpr(CBool(val)) => Ok(Gc::new(VBoolean(val))),
			ConstExpr(CRegExp(_, _, _)) => Ok(Gc::new(VNull)),
			BlockExpr(ref es) => {
				let mut obj = Gc::new(VNull);
				for e in es.iter() {
					let val = try!(self.run(*e));
					if e == es.last().unwrap() {
						obj = val;
					}
				}
				Ok(obj)
			},
			LocalExpr(ref name) => {
				let mut value = Gc::new(VUndefined);
				for scope in self.scopes.iter().rev() {
					match scope.borrow().borrow().find(name) {
						Some(v) => {
							value = v.value.clone();
							break;
						}
						None => ()
					}
				}
				Ok(if value.borrow().is_undefined() {
					self.global.borrow().get_field(name.clone().into_maybe_owned())
				} else {
					value
				})
			},
			GetConstFieldExpr(ref obj, ref field) => {
				let val_obj = try!(self.run(*obj));
				Ok(val_obj.borrow().get_field(field.clone().into_maybe_owned()))
			},
			GetFieldExpr(ref obj, ref field) => {
				let val_obj = try!(self.run(*obj));
				let val_field = try!(self.run(*field));
				Ok(val_obj.borrow().get_field(val_field.borrow().to_str().into_maybe_owned()))
			},
			CallExpr(ref callee, ref args) => {
				let (this, func) = match callee.def {
					GetConstFieldExpr(ref obj, ref field) => {
						let obj = try!(self.run(*obj));
						(obj, obj.borrow().get_field(field.clone().into_maybe_owned()))
					},
					GetFieldExpr(ref obj, ref field) => {
						let obj = try!(self.run(*obj));
						let field = try!(self.run(*field));
						(obj, obj.borrow().get_field(field.borrow().to_str().into_maybe_owned()))
					},
					_ => (self.global.clone(), try!(self.run(callee.clone())))
				};
				let mut v_args = Vec::with_capacity(args.len());
				for arg in args.iter() {
					v_args.push(try!(self.run(*arg)));
				}
				match *func.borrow() {
					VFunction(ref func) => {
						func.borrow().call(self, this, Gc::new(VNull), v_args)
					},
					_ => Err(Gc::new(VUndefined))
				}
			},
			WhileLoopExpr(ref cond, ref expr) => {
				let mut result = Gc::new(VUndefined);
				while try!(self.run(*cond)).borrow().is_true() {
					result = try!(self.run(*expr));
				}
				Ok(result)
			},
			IfExpr(ref cond, ref expr, None) => {
				Ok(if try!(self.run(*cond)).borrow().is_true() {
					try!(self.run(*expr))
				} else {
					Gc::new(VUndefined)
				})
			},
			IfExpr(ref cond, ref expr, Some(ref else_e)) => {
				Ok(if try!(self.run(*cond)).borrow().is_true() {
					try!(self.run(*expr))
				} else {
					try!(self.run(*else_e))
				})
			},
			SwitchExpr(ref val_e, ref vals, ref default) => {
				let val = try!(self.run(*val_e)).borrow().clone();
				let mut result = Gc::new(VNull);
				let mut matched = false;
				for tup in vals.iter() {
					let tup:&(~Expr, Vec<~Expr>) = tup;
					match *tup {
						(ref cond, ref block) if(val == *try!(self.run(*cond)).borrow()) => {
							matched = true;
							let last_expr = block.last().unwrap();
							for expr in block.iter() {
								let e_result = try!(self.run(*expr));
								if expr == last_expr {
									result = e_result;
								}
							}
						},
						_ => ()
					}
				}
				if !matched && default.is_some() {
					result = try!(self.run(*default.as_ref().unwrap()));
				}
				Ok(result)
			},
			ObjectDeclExpr(ref map) => {
				let obj = ValueData::new_obj(Some(self.global));
				for (key, val) in map.iter() {
					obj.borrow().set_field(key.clone().into_maybe_owned(), try!(self.run(val.clone())));
				}
				Ok(obj)
			},
			ArrayDeclExpr(ref arr) => {
				let arr_map = ValueData::new_obj(Some(self.global));
				let mut index : i32 = 0;
				for val in arr.iter() {
					let val = try!(self.run(val.clone()));
					arr_map.borrow().set_field(index.to_str().into_maybe_owned(), val);
					index += 1;
				}
				arr_map.borrow().set_field(INSTANCE_PROTOTYPE.into_maybe_owned(), self.get_global("Array".into_maybe_owned()).borrow().get_field(PROTOTYPE.into_maybe_owned()));
				arr_map.borrow().set_field("length".into_maybe_owned(), to_value(index));
				Ok(arr_map)
			},
			FunctionDeclExpr(ref name, ref args, ref expr) => {
				let function = RegularFunc(RegularFunction::new(*expr.clone(), args.clone()));
				let val = Gc::new(VFunction(RefCell::new(function)));
				if name.is_some() {
					self.global.borrow().set_field(name.clone().unwrap().into_maybe_owned(), val);
				}
				Ok(val)
			},
			ArrowFunctionDeclExpr(ref args, ref expr) => {
				let function = RegularFunc(RegularFunction::new(*expr.clone(), args.clone()));
				Ok(Gc::new(VFunction(RefCell::new(function))))
			},
			NumOpExpr(ref op, ref a, ref b) => {
				let v_r_a = try!(self.run(*a));
				let v_r_b = try!(self.run(*b));
				let v_a = v_r_a.borrow();
				let v_b = v_r_b.borrow();
				Ok(Gc::new(match *op {
					OpAdd => *v_a + *v_b,
					OpSub => *v_a - *v_b,
					OpMul => *v_a * *v_b,
					OpDiv => *v_a / *v_b,
					OpMod => *v_a % *v_b
				}))
			},
			BitOpExpr(ref op, ref a, ref b) => {
				let v_r_a = try!(self.run(*a));
				let v_r_b = try!(self.run(*b));
				let v_a = v_r_a.borrow();
				let v_b = v_r_b.borrow();
				Ok(Gc::new(match *op {
					BitAnd => *v_a & *v_b,
					BitOr => *v_a | *v_b,
					BitXor => *v_a ^ *v_b,
					BitShl => *v_a << *v_b,
					BitShr => *v_a >> *v_b
				}))
			},
			CompOpExpr(ref op, ref a, ref b) => {
				let v_r_a = try!(self.run(*a));
				let v_r_b = try!(self.run(*b));
				let v_a = v_r_a.borrow();
				let v_b = v_r_b.borrow();
				Ok(to_value(match *op {
					CompEqual => v_r_a.ptr_eq(&v_r_b) || v_a == v_b,
					CompNotEqual => !v_r_a.ptr_eq(&v_r_b) || v_a != v_b,
					CompStrictEqual => v_r_a.ptr_eq(&v_r_b) || v_a == v_b,
					CompStrictNotEqual => !v_r_a.ptr_eq(&v_r_b) || v_a != v_b,
					CompGreaterThan => v_a.to_num() > v_b.to_num(),
					CompGreaterThanOrEqual => v_a.to_num() >= v_b.to_num(),
					CompLessThan => v_a.to_num() < v_b.to_num(),
					CompLessThanOrEqual => v_a.to_num() <= v_b.to_num()
				}))
			},
			LogOpExpr(ref op, ref a, ref b) => {
				let v_a = from_value::<bool>(try!(self.run(*a))).unwrap();
				let v_b = from_value::<bool>(try!(self.run(*b))).unwrap();
				Ok(match *op {
					LogAnd => to_value(v_a && v_b),
					LogOr => to_value(v_a || v_b)
				})
			},
			ConstructExpr(ref callee, ref args) => {
				let func = try!(self.run(*callee));
				let mut v_args = Vec::with_capacity(args.len());
				for arg in args.iter() {
					v_args.push(try!(self.run(*arg)));
				}
				let this = Gc::new(VObject(RefCell::new(TreeMap::new())));
				this.borrow().set_field(INSTANCE_PROTOTYPE.into_maybe_owned(), func.borrow().get_field(PROTOTYPE.into_maybe_owned()));
				Ok(match *func.borrow() {
					VFunction(ref func) => {
						try!(func.borrow().call(self, this, Gc::new(VNull), v_args));
						this
					},
					_ => Gc::new(VUndefined)
				})
			},
			ReturnExpr(ref ret) => {
				match *ret {
					Some(ref v) =>
						self.run(v.clone()),
					None => Ok(Gc::new(VUndefined))
				}
			},
			ThrowExpr(ref ex) => Err(try!(self.run(*ex))),
			AssignExpr(ref ref_e, ref val_e) => {
				let val = try!(self.run(*val_e));
				match ref_e.def {
					LocalExpr(ref name) => {
						self.global.borrow().set_field(name.clone().into_maybe_owned(), val);
					},
					GetConstFieldExpr(ref obj, ref field) => {
						let val_obj = try!(self.run(*obj));
						val_obj.borrow().set_field(field.clone().into_maybe_owned(), val);
					},
					_ => ()
				}
				Ok(val)
			},
			TypeOfExpr(ref val_e) => {
				let val = try!(self.run(*val_e));
				Ok(to_value(match *val.borrow() {
					VUndefined => "undefined",
					VNull | VObject(_) => "object",
					VBoolean(_) => "boolean",
					VNumber(_) | VInteger(_) => "number",
					VString(_) => "string",
					VFunction(_) => "function"
				}.into_maybe_owned()))
			}
		}
	}
}<|endoftext|>


<commit_before>pub type Font4x5 = [u8; 5 * 16];

pub const FONT_CHIP8_4X5: Font4x5 = [// 0
                                     0b_1111_0000,
                                     0b_1001_0000,
                                     0b_1001_0000,
                                     0b_1001_0000,
                                     0b_1111_0000,
                                     // 1
                                     0b_0010_0000,
                                     0b_0110_0000,
                                     0b_0010_0000,
                                     0b_0010_0000,
                                     0b_0111_0000,
                                     // 2
                                     0b_1111_0000,
                                     0b_0001_0000,
                                     0b_1111_0000,
                                     0b_1000_0000,
                                     0b_1111_0000,
                                     // 3
                                     0b_1111_0000,
                                     0b_0001_0000,
                                     0b_1111_0000,
                                     0b_0001_0000,
                                     0b_1111_0000,
                                     // 4
                                     0b_1001_0000,
                                     0b_1001_0000,
                                     0b_1111_0000,
                                     0b_0001_0000,
                                     0b_0001_0000,
                                     // 5
                                     0b_1111_0000,
                                     0b_1000_0000,
                                     0b_1111_0000,
                                     0b_0001_0000,
                                     0b_1111_0000,
                                     // 6
                                     0b_1111_0000,
                                     0b_1000_0000,
                                     0b_1111_0000,
                                     0b_1001_0000,
                                     0b_1111_0000,
                                     // 7
                                     0b_1111_0000,
                                     0b_0001_0000,
                                     0b_0010_0000,
                                     0b_0100_0000,
                                     0b_1000_0000,
                                     // 8
                                     0b_1111_0000,
                                     0b_1001_0000,
                                     0b_1111_0000,
                                     0b_1001_0000,
                                     0b_1111_0000,
                                     // 9
                                     0b_1111_0000,
                                     0b_1001_0000,
                                     0b_1111_0000,
                                     0b_0001_0000,
                                     0b_0001_0000,
                                     // A
                                     0b_1111_0000,
                                     0b_1001_0000,
                                     0b_1001_0000,
                                     0b_1001_0000,
                                     0b_1001_0000,
                                     // B
                                     0b_1110_0000,
                                     0b_1001_0000,
                                     0b_1110_0000,
                                     0b_1001_0000,
                                     0b_1110_0000,
                                     // C
                                     0b_1111_0000,
                                     0b_1000_0000,
                                     0b_1000_0000,
                                     0b_1000_0000,
                                     0b_1111_0000,
                                     // D
                                     0b_1110_0000,
                                     0b_1001_0000,
                                     0b_1001_0000,
                                     0b_1001_0000,
                                     0b_1110_0000,
                                     // E
                                     0b_1111_0000,
                                     0b_1000_0000,
                                     0b_1111_0000,
                                     0b_1000_0000,
                                     0b_1111_0000,
                                     // F
                                     0b_1111_0000,
                                     0b_1000_0000,
                                     0b_1111_0000,
                                     0b_1000_0000,
                                     0b_1000_0000];

#[test]
fn test_font4x5() {
    const CHIP8_REFERENCE_FONT: [u8] =
        [0xF0, 0x90, 0x90, 0x90, 0xF0 /* 0 */, 0x20, 0x60, 0x20, 0x20, 0x70 /* 1 */,
         0xF0, 0x10, 0xF0, 0x80, 0xF0 /* 2 */, 0xF0, 0x10, 0xF0, 0x10, 0xF0 /* 3 */,
         0x90, 0x90, 0xF0, 0x10, 0x10 /* 4 */, 0xF0, 0x80, 0xF0, 0x10, 0xF0 /* 5 */,
         0xF0, 0x80, 0xF0, 0x90, 0xF0 /* 6 */, 0xF0, 0x10, 0x20, 0x40, 0x40 /* 7 */,
         0xF0, 0x90, 0xF0, 0x90, 0xF0 /* 8 */, 0xF0, 0x90, 0xF0, 0x10, 0xF0 /* 9 */,
         0xF0, 0x90, 0xF0, 0x90, 0x90 /* A */, 0xE0, 0x90, 0xE0, 0x90, 0xE0 /* B */,
         0xF0, 0x80, 0x80, 0x80, 0xF0 /* C */, 0xE0, 0x90, 0x90, 0x90, 0xE0 /* D */,
         0xF0, 0x80, 0xF0, 0x80, 0xF0 /* E */, 0xF0, 0x80, 0xF0, 0x80, 0x80 /* F */];
    assert!(FONT_CHIP8_4X5 == CHIP8_REFERENCE_FONT);
}
<commit_msg>Fixed font so it matches the standard font<commit_after>pub type Font4x5 = [u8; 5 * 16];

pub const FONT_CHIP8_4X5: Font4x5 = [// 0
                                     0b_1111_0000,
                                     0b_1001_0000,
                                     0b_1001_0000,
                                     0b_1001_0000,
                                     0b_1111_0000,
                                     // 1
                                     0b_0010_0000,
                                     0b_0110_0000,
                                     0b_0010_0000,
                                     0b_0010_0000,
                                     0b_0111_0000,
                                     // 2
                                     0b_1111_0000,
                                     0b_0001_0000,
                                     0b_1111_0000,
                                     0b_1000_0000,
                                     0b_1111_0000,
                                     // 3
                                     0b_1111_0000,
                                     0b_0001_0000,
                                     0b_1111_0000,
                                     0b_0001_0000,
                                     0b_1111_0000,
                                     // 4
                                     0b_1001_0000,
                                     0b_1001_0000,
                                     0b_1111_0000,
                                     0b_0001_0000,
                                     0b_0001_0000,
                                     // 5
                                     0b_1111_0000,
                                     0b_1000_0000,
                                     0b_1111_0000,
                                     0b_0001_0000,
                                     0b_1111_0000,
                                     // 6
                                     0b_1111_0000,
                                     0b_1000_0000,
                                     0b_1111_0000,
                                     0b_1001_0000,
                                     0b_1111_0000,
                                     // 7
                                     0b_1111_0000,
                                     0b_0001_0000,
                                     0b_0010_0000,
                                     0b_0100_0000,
                                     0b_0100_0000,
                                     // 8
                                     0b_1111_0000,
                                     0b_1001_0000,
                                     0b_1111_0000,
                                     0b_1001_0000,
                                     0b_1111_0000,
                                     // 9
                                     0b_1111_0000,
                                     0b_1001_0000,
                                     0b_1111_0000,
                                     0b_0001_0000,
                                     0b_1111_0000,
                                     // A
                                     0b_1111_0000,
                                     0b_1001_0000,
                                     0b_1111_0000,
                                     0b_1001_0000,
                                     0b_1001_0000,
                                     // B
                                     0b_1110_0000,
                                     0b_1001_0000,
                                     0b_1110_0000,
                                     0b_1001_0000,
                                     0b_1110_0000,
                                     // C
                                     0b_1111_0000,
                                     0b_1000_0000,
                                     0b_1000_0000,
                                     0b_1000_0000,
                                     0b_1111_0000,
                                     // D
                                     0b_1110_0000,
                                     0b_1001_0000,
                                     0b_1001_0000,
                                     0b_1001_0000,
                                     0b_1110_0000,
                                     // E
                                     0b_1111_0000,
                                     0b_1000_0000,
                                     0b_1111_0000,
                                     0b_1000_0000,
                                     0b_1111_0000,
                                     // F
                                     0b_1111_0000,
                                     0b_1000_0000,
                                     0b_1111_0000,
                                     0b_1000_0000,
                                     0b_1000_0000];

#[test]
fn test_font4x5() {
    const CHIP8_REFERENCE_FONT: Font4x5 =
        [0xF0, 0x90, 0x90, 0x90, 0xF0 /* 0 */, 0x20, 0x60, 0x20, 0x20, 0x70 /* 1 */,
         0xF0, 0x10, 0xF0, 0x80, 0xF0 /* 2 */, 0xF0, 0x10, 0xF0, 0x10, 0xF0 /* 3 */,
         0x90, 0x90, 0xF0, 0x10, 0x10 /* 4 */, 0xF0, 0x80, 0xF0, 0x10, 0xF0 /* 5 */,
         0xF0, 0x80, 0xF0, 0x90, 0xF0 /* 6 */, 0xF0, 0x10, 0x20, 0x40, 0x40 /* 7 */,
         0xF0, 0x90, 0xF0, 0x90, 0xF0 /* 8 */, 0xF0, 0x90, 0xF0, 0x10, 0xF0 /* 9 */,
         0xF0, 0x90, 0xF0, 0x90, 0x90 /* A */, 0xE0, 0x90, 0xE0, 0x90, 0xE0 /* B */,
         0xF0, 0x80, 0x80, 0x80, 0xF0 /* C */, 0xE0, 0x90, 0x90, 0x90, 0xE0 /* D */,
         0xF0, 0x80, 0xF0, 0x80, 0xF0 /* E */, 0xF0, 0x80, 0xF0, 0x80, 0x80 /* F */];

    for (i, glyph) in FONT_CHIP8_4X5.iter().enumerate() {
        let ref_glyph = CHIP8_REFERENCE_FONT[i];
        println!("Glyph {:X}.{}: {:08b} ?= {:08b}", i / 5, i % 5, glyph, ref_glyph);
        assert_eq!(*glyph, ref_glyph);
    }
}
<|endoftext|>


<commit_before>use curl;
use oauth2::*;
use app::App;
use util::{CargoResult, internal, ChainError, human};
use rustc_serialize::{json, Decodable};
use std::str;

/// Does all the nonsense for sending a GET to Github. Doesn't handle parsing
/// because custom error-code handling may be desirable. Use
/// parse_github_response to handle the "common" processing of responses.
pub fn github(app: &App, url: &str, auth: &Token)
              -> Result<curl::http::Response, curl::ErrCode>
{
    let url = format!("{}://api.github.com{}", app.config.api_protocol(), url);
    info!("GITHUB HTTP: {}", url);

    app.handle()
       .get(url)
       .header("Accept", "application/vnd.github.v3+json")
       .header("User-Agent", "hello!")
       .auth_with(auth)
       .exec()
}

/// Checks for normal responses
pub fn parse_github_response<T: Decodable>(resp: curl::http::Response)
                                            -> CargoResult<T> {
    match resp.get_code() {
        200 => {} // Ok!
        403 => {
            return Err(human("It looks like you don't have permission \
                              to query a necessary property from Github \
                              to complete this request. \
                              You may need to re-authenticate on \
                              crates.io to grant permission to read \
                              github org memberships. Just go to \
                              https://crates.io/login"));
        }
        _ => {
            return Err(internal(format!("didn't get a 200 result from
                                        github: {}", resp)));
        }
    }

    let json = try!(str::from_utf8(resp.get_body()).ok().chain_error(||{
        internal("github didn't send a utf8-response")
    }));

    json::decode(json).chain_error(|| {
        internal("github didn't send a valid json response")
    })
}

/// Gets a token with the given string as the access token, but all
/// other info null'd out. Generally, just to be fed to the `github` fn.
pub fn token(token: String) -> Token {
    Token {
        access_token: token,
        scopes: Vec::new(),
        token_type: String::new(),
    }
}
<commit_msg>Fix a stray newline<commit_after>use curl;
use oauth2::*;
use app::App;
use util::{CargoResult, internal, ChainError, human};
use rustc_serialize::{json, Decodable};
use std::str;

/// Does all the nonsense for sending a GET to Github. Doesn't handle parsing
/// because custom error-code handling may be desirable. Use
/// parse_github_response to handle the "common" processing of responses.
pub fn github(app: &App, url: &str, auth: &Token)
              -> Result<curl::http::Response, curl::ErrCode>
{
    let url = format!("{}://api.github.com{}", app.config.api_protocol(), url);
    info!("GITHUB HTTP: {}", url);

    app.handle()
       .get(url)
       .header("Accept", "application/vnd.github.v3+json")
       .header("User-Agent", "hello!")
       .auth_with(auth)
       .exec()
}

/// Checks for normal responses
pub fn parse_github_response<T: Decodable>(resp: curl::http::Response)
                                            -> CargoResult<T> {
    match resp.get_code() {
        200 => {} // Ok!
        403 => {
            return Err(human("It looks like you don't have permission \
                              to query a necessary property from Github \
                              to complete this request. \
                              You may need to re-authenticate on \
                              crates.io to grant permission to read \
                              github org memberships. Just go to \
                              https://crates.io/login"));
        }
        _ => {
            return Err(internal(format!("didn't get a 200 result from \
                                        github: {}", resp)));
        }
    }

    let json = try!(str::from_utf8(resp.get_body()).ok().chain_error(||{
        internal("github didn't send a utf8-response")
    }));

    json::decode(json).chain_error(|| {
        internal("github didn't send a valid json response")
    })
}

/// Gets a token with the given string as the access token, but all
/// other info null'd out. Generally, just to be fed to the `github` fn.
pub fn token(token: String) -> Token {
    Token {
        access_token: token,
        scopes: Vec::new(),
        token_type: String::new(),
    }
}
<|endoftext|>


<commit_before>use conduit::{Request, Response};
use conduit_middleware::Middleware;
use curl;
use curl::easy::{Easy, List};
use oauth2::*;
use app::App;
use util::{CargoResult, internal, ChainError, human};
use serde_json;
use serde::Deserialize;
use std::str;
use std::error::Error;

/// Does all the nonsense for sending a GET to Github. Doesn't handle parsing
/// because custom error-code handling may be desirable. Use
/// `parse_github_response` to handle the "common" processing of responses.
pub fn github(app: &App, url: &str, auth: &Token) -> Result<(Easy, Vec<u8>), curl::Error> {
    let url = format!("{}://api.github.com{}", app.config.api_protocol, url);
    info!("GITHUB HTTP: {}", url);

    let mut headers = List::new();
    headers
        .append("Accept: application/vnd.github.v3+json")
        .unwrap();
    headers.append("User-Agent: hello!").unwrap();
    headers
        .append(&format!("Authorization: token {}", auth.access_token))
        .unwrap();

    let mut handle = app.handle();
    handle.url(&url).unwrap();
    handle.get(true).unwrap();
    handle.http_headers(headers).unwrap();

    let mut data = Vec::new();
    {
        let mut transfer = handle.transfer();
        transfer
            .write_function(|buf| {
                data.extend_from_slice(buf);
                Ok(buf.len())
            })
            .unwrap();
        transfer.perform()?;
    }
    Ok((handle, data))
}

/// Checks for normal responses
pub fn parse_github_response<'de, 'a: 'de, T: Deserialize<'de>>(
    mut resp: Easy,
    data: &'a [u8],
) -> CargoResult<T> {
    match resp.response_code().unwrap() {
        200 => {} // Ok!
        403 => {
            return Err(human(
                "It looks like you don't have permission \
                 to query a necessary property from Github \
                 to complete this request. \
                 You may need to re-authenticate on \
                 crates.io to grant permission to read \
                 github org memberships. Just go to \
                 https://crates.io/login",
            ));
        }
        n => {
            let resp = String::from_utf8_lossy(data);
            return Err(internal(&format_args!(
                "didn't get a 200 result from \
                 github, got {} with: {}",
                n,
                resp
            )));
        }
    }

    let json = str::from_utf8(data).ok().chain_error(|| {
        internal("github didn't send a utf8-response")
    })?;

    serde_json::from_str(json).chain_error(|| internal("github didn't send a valid json response"))
}

/// Gets a token with the given string as the access token, but all
/// other info null'd out. Generally, just to be fed to the `github` fn.
pub fn token(token: String) -> Token {
    Token {
        access_token: token,
        scopes: Vec::new(),
        token_type: String::new(),
    }
}

pub struct SecurityHeadersMiddleware;

impl Middleware for SecurityHeadersMiddleware {
    fn after(&self, _: &mut Request, mut res: Result<Response, Box<Error+Send>>)
        -> Result<Response, Box<Error+Send>> {
        if let Ok(ref mut response) = res {
            response.headers.insert(
                "Content-Security-Policy".into(),
                vec!["default-src 'self'; \
                      script-src 'self' https://www.google-analytics.com https://www.google.com; \
                      style-src 'self' https://www.google.com; \
                      img-src *; \
                      object-src 'none'".into()],
            );
            response.headers.insert(
                "X-Content-Type-Options".into(),
                vec!["nosniff".into()],
            );
            response.headers.insert(
                "X-Frame-Options".into(),
                vec!["SAMEORIGIN".into()],
            );
            response.headers.insert(
                "X-XSS-Protection".into(),
                vec!["1; mode=block".into()],
            );
            response.headers.insert(
                "Strict-Transport-Security".into(),
                vec!["max-age=31536000; includeSubDomains".into()],
            );
        }
        res
    }
}
<commit_msg>Remove STS header setting from middleware; it's set in nginx config<commit_after>use conduit::{Request, Response};
use conduit_middleware::Middleware;
use curl;
use curl::easy::{Easy, List};
use oauth2::*;
use app::App;
use util::{CargoResult, internal, ChainError, human};
use serde_json;
use serde::Deserialize;
use std::str;
use std::error::Error;

/// Does all the nonsense for sending a GET to Github. Doesn't handle parsing
/// because custom error-code handling may be desirable. Use
/// `parse_github_response` to handle the "common" processing of responses.
pub fn github(app: &App, url: &str, auth: &Token) -> Result<(Easy, Vec<u8>), curl::Error> {
    let url = format!("{}://api.github.com{}", app.config.api_protocol, url);
    info!("GITHUB HTTP: {}", url);

    let mut headers = List::new();
    headers
        .append("Accept: application/vnd.github.v3+json")
        .unwrap();
    headers.append("User-Agent: hello!").unwrap();
    headers
        .append(&format!("Authorization: token {}", auth.access_token))
        .unwrap();

    let mut handle = app.handle();
    handle.url(&url).unwrap();
    handle.get(true).unwrap();
    handle.http_headers(headers).unwrap();

    let mut data = Vec::new();
    {
        let mut transfer = handle.transfer();
        transfer
            .write_function(|buf| {
                data.extend_from_slice(buf);
                Ok(buf.len())
            })
            .unwrap();
        transfer.perform()?;
    }
    Ok((handle, data))
}

/// Checks for normal responses
pub fn parse_github_response<'de, 'a: 'de, T: Deserialize<'de>>(
    mut resp: Easy,
    data: &'a [u8],
) -> CargoResult<T> {
    match resp.response_code().unwrap() {
        200 => {} // Ok!
        403 => {
            return Err(human(
                "It looks like you don't have permission \
                 to query a necessary property from Github \
                 to complete this request. \
                 You may need to re-authenticate on \
                 crates.io to grant permission to read \
                 github org memberships. Just go to \
                 https://crates.io/login",
            ));
        }
        n => {
            let resp = String::from_utf8_lossy(data);
            return Err(internal(&format_args!(
                "didn't get a 200 result from \
                 github, got {} with: {}",
                n,
                resp
            )));
        }
    }

    let json = str::from_utf8(data).ok().chain_error(|| {
        internal("github didn't send a utf8-response")
    })?;

    serde_json::from_str(json).chain_error(|| internal("github didn't send a valid json response"))
}

/// Gets a token with the given string as the access token, but all
/// other info null'd out. Generally, just to be fed to the `github` fn.
pub fn token(token: String) -> Token {
    Token {
        access_token: token,
        scopes: Vec::new(),
        token_type: String::new(),
    }
}

pub struct SecurityHeadersMiddleware;

impl Middleware for SecurityHeadersMiddleware {
    fn after(&self, _: &mut Request, mut res: Result<Response, Box<Error+Send>>)
        -> Result<Response, Box<Error+Send>> {
        if let Ok(ref mut response) = res {
            response.headers.insert(
                "Content-Security-Policy".into(),
                vec!["default-src 'self'; \
                      script-src 'self' https://www.google-analytics.com https://www.google.com; \
                      style-src 'self' https://www.google.com; \
                      img-src *; \
                      object-src 'none'".into()],
            );
            response.headers.insert(
                "X-Content-Type-Options".into(),
                vec!["nosniff".into()],
            );
            response.headers.insert(
                "X-Frame-Options".into(),
                vec!["SAMEORIGIN".into()],
            );
            response.headers.insert(
                "X-XSS-Protection".into(),
                vec!["1; mode=block".into()],
            );
        }
        res
    }
}
<|endoftext|>


<commit_before>use giftr::refs::*;
use giftr::refs::functional::Ref as Ref;
//use giftr::refs::imperative::Ref as Ref;
use std::mem::replace;
use std::iter::Iterator;

#[derive(Clone, Debug)]
pub struct Node<T: Clone> {
    next: Option<Ref<Node<T>>>,
    elt: Option<T>,
}

impl <T: Clone> Node<T> {
    fn new(x: T) -> Node<T> {
        Node { next: None, elt: Some(x) }
    }

    fn len(&self) -> i32 {
        if let Some(ref node) = self.next {
            1 + node.len()
        } else {
            1
        }
    }

    fn append(&mut self, x: T) {
        if let Some(ref mut next) = self.next {
            next.append(x)
        } else {
            self.next = Some(Ref::new(Node::new(x)))
        }
    }

    fn is_last(&self) -> bool {
        self.next.is_none()
    }

    fn pop_back(&mut self) -> Option<T> {
        assert!(self.next.is_some());
        let mut ret = None;
        let mut took_here = false;
        if let Some(ref mut next) = self.next {
            println!("have next");

            if next.is_last() {
                ret = _move_opt(&mut next.elt);
                took_here = true;
            } else {
                ret = next.pop_back();
            }
        }
        if took_here {
            self.next = None
        }
        ret
    }
}

#[derive(Clone, Debug)]
pub struct List<T: Clone> {
    first : Option<Ref<Node<T>>>,
}

impl <T: Clone> List<T> {
    pub fn new() -> List<T> {
        List { first: None }
    }

    pub fn prepend(&mut self, x: T) {
        let new_next = replace(&mut self.first, None);
        let new_first = Node { elt: Some(x), next: new_next };
        self.first = Some(Ref::new(new_first));
    }

    pub fn append(&mut self, x:T) {
        if let Some(ref mut node) = self.first {
            node.append(x)
        }
    }

    pub fn pop_front(&mut self) -> Option<T> {
        let mut ret = None;
        let optfirst = _move_opt(&mut self.first);
        if let Some(first) = optfirst {
            let Node { elt, next } = first.into_inner();
            self.first = next;
            ret = elt;
        }
        ret
    }

    pub fn pop_back(&mut self) -> Option<T> {
        let mut ret = None;
        let mut first_is_last = false;
        if let Some(ref mut first) = self.first {
            if first.is_last() {
                println!("first is last");
                first_is_last = true;
                ret = _move_opt(&mut first.elt);
            } else {
                println!("first is not last");
                ret = first.pop_back();
            }
        }
        if first_is_last {
            self.first = None;
        }
        ret

//        if let Some(ref mut first) = self.first {
//            if first.is_last() {
//                let mut first = _move_opt(first).expect("");
//
//                _move_opt(&mut first.elt)
//            } else {
//                first.pop_back()
//            }
//        } else {
//            None
//        }
    }

    pub fn len(&self) -> i32 {
        if let Some(ref first) = self.first {
            first.len()
        } else {
            0
        }
    }

    pub fn iter(&self) -> Iter<T> {
        Iter { cur: self.first.clone() }
    }

    pub fn to_iter(mut self) -> Iter<T> {
        Iter { cur: _move_opt(&mut self.first) }
    }

}

pub fn to_iter<T: Clone>(s: Ref<List<T>>) -> Iter<T> {
    let mut s = s;
    Iter { cur: _move_opt(&mut s.first) }
}

pub struct Iter<T: Clone> {
    cur: Option<Ref<Node<T>>>,
}

impl <T: Clone> Iterator for Iter<T> {
    type Item = T;
    fn next(&mut self) -> Option<Self::Item> {
        let mut new_cur = None;
        let mut ret = None;
        if let Some(ref mut cur) = self.cur {
            //FIXME get rid of clone!
            ret = cur.elt.clone();
            new_cur = replace(&mut cur.next, None);
        }
        self.cur = new_cur;
        ret
    }
}

#[test]
fn lst_len() {
    println!("=== LST_LEN ==============");
    let mut lst = Ref::new(List::new());
    assert_eq!(0, lst.len());

    lst.prepend(1);
    assert_eq!(1, lst.len());

    lst.prepend(2);
    assert_eq!(2, lst.len());

    lst.prepend(3);
    assert_eq!(3, lst.len());

    lst.pop_front();
    assert_eq!(2, lst.len());
}

#[test]
fn lst_pop_front() {
    println!("=== LST_LEN ==============");
    let mut lst = Ref::new(List::new());
    lst.prepend(3);
    lst.prepend(2);
    lst.prepend(1);

    assert_eq!(Some(1), lst.pop_front());
    assert_eq!(Some(2), lst.pop_front());
    assert_eq!(Some(3), lst.pop_front());
    assert_eq!(None, lst.pop_front());
    assert_eq!(None, lst.pop_front());
}

#[test]
fn lst_pop_back() {
    println!("=== LST_LEN ==============");
    let mut lst = Ref::new(List::new());
    lst.prepend(3);
    lst.prepend(2);
    lst.prepend(1);

    assert_eq!(Some(3), lst.pop_back());
    assert_eq!(Some(2), lst.pop_back());
    assert_eq!(Some(1), lst.pop_back());
    assert_eq!(None, lst.pop_front());
    assert_eq!(None, lst.pop_front());
}

#[test]
fn lst_copy() {
    println!("=== LST_COPY ==============");
    let mut lst1 = Ref::new(List::new());
    lst1.prepend(1);
    let lst2 : Ref<List<i32>>;
    lst1.prepend(2);

    lst2 = lst1.clone();

    lst1.prepend(3);

    assert!(3 == lst1.len());
    assert!(2 == lst2.len());
}

#[test]
fn lst_iter() {
    let mut lst1 = Ref::new(List::new());
    lst1.prepend(3);
    lst1.prepend(2);
    lst1.prepend(1);

    let mut cnt = 1;
    for v in lst1.iter() {
        println!("v={}, cnt={}", v, cnt);
        assert_eq!(v, cnt);
        cnt = cnt+1;
    }

    let mut cnt = 1;
    for v in to_iter(lst1) {
        println!("v={}, cnt={}", v, cnt);
        assert_eq!(v, cnt);
        cnt = cnt+1;
    }
}
<commit_msg>implement custom drop trait as blueprint for generated code<commit_after>use giftr::refs::*;
pub use giftr::refs::functional::Ref as Ref;
//pub use giftr::refs::imperative::Ref as Ref;
use std::mem::replace;
use std::iter::Iterator;
use std::rc::Rc;

#[derive(Clone, Debug)]
pub struct Node<T: Clone> {
    next: Option<Ref<Node<T>>>,
    elt: Option<T>,
}

impl <T: Clone> Node<T> {
    fn new(x: T) -> Node<T> {
        Node { next: None, elt: Some(x) }
    }

//    fn at_last_node_mut<F>(&mut self, f: F)
//        where F: Fn(&mut Node<T>)
//    {
////        let mut cur = self;
////        loop {
////            if cur.next.is_none() {
////                f(cur);
////                //break;
////            } else {
////                let &mut Node {next: ref mut nxt, elt: _} = {cur};
////                if let &mut Some(ref mut r) = {nxt} {
////                    cur = {r};
////                }
////            }
//        //        }
//        let mut nxt : Option<&mut Node<T>>;
//        match {self.next} {
//            None => nxt = None,
//            Some(ref mut r) => nxt = Some(&mut **r)
//        }
//
//
//        loop {
//            match {nxt} {
//                None => break,
//                Some(ref mut r) => {
//                    nxt = Some(&mut *r)
//                }
//            }
//        }
//
//        match self.next {
//            None => f(self),
//            Some(ref mut last) => f(&mut **last)
//        }
//    }

    fn len(&self) -> i32 {
        let mut n = 1;
        let mut cur : &Node<T> = &self;
        while let Some(ref nxt) = cur.next {
            n += 1;
            cur = nxt;
        };
        n
    }

    fn append(&mut self, x: T) {
        if let Some(ref mut next) = self.next {
            next.append(x)
        } else {
            self.next = Some(Ref::new(Node::new(x)))
        }
    }

    fn is_last(&self) -> bool {
        self.next.is_none()
    }

    fn pop_back(&mut self) -> Option<T> {
        assert!(self.next.is_some());
        let mut ret = None;
        let mut took_here = false;
        if let Some(ref mut next) = self.next {
            println!("have next");

            if next.is_last() {
                ret = next.elt.take();
                took_here = true;
            } else {
                ret = next.pop_back();
            }
        }
        if took_here {
            self.next = None
        }
        ret
    }
}

impl <T: Clone> Drop for Node<T> {
    fn drop(&mut self) {
        let mut optcur : Option<_> = self.next.take();
        while let Some(cur) = optcur {
            match Rc::try_unwrap(cur._ptr) {
                Ok(ref mut cur) => optcur = cur.next.take(), //nxt,
                Err(_)          => break
            }
        }
    }
}

#[derive(Clone, Debug)]
pub struct List<T: Clone> {
    first : Option<Ref<Node<T>>>,
}

impl <T: Clone> List<T> {
    pub fn new() -> List<T> {
        List { first: None }
    }

    pub fn prepend(&mut self, x: T) {
        let new_next = replace(&mut self.first, None);
        let new_first = Node { elt: Some(x), next: new_next };
        self.first = Some(Ref::new(new_first));
    }

    pub fn append(&mut self, x:T) {
        if let Some(ref mut node) = self.first {
            node.append(x)
        } else {
            self.first = Some(Ref::new(Node::new(x)))
        }
    }

    pub fn pop_front(&mut self) -> Option<T> {
        let mut ret = None;
        let optfirst = self.first.take();
        if let Some(first) = optfirst {
            let mut n = first.into_inner();
            self.first = n.next.take();
            ret = n.elt.take();
        }
        ret
    }

    pub fn pop_back(&mut self) -> Option<T> {
        let mut ret = None;
        let mut first_is_last = false;
        if let Some(ref mut first) = self.first {
            if first.is_last() {
                println!("first is last");
                first_is_last = true;
                ret = first.elt.take();
            } else {
                println!("first is not last");
                ret = first.pop_back();
            }
        }
        if first_is_last {
            self.first = None;
        }
        ret
    }

    pub fn len(&self) -> i32 {
        if let Some(ref first) = self.first {
            first.len()
        } else {
            0
        }
    }

    pub fn iter(&self) -> Iter<T> {
        Iter { cur: self.first.clone() }
    }

    pub fn to_iter(mut self) -> Iter<T> {
        Iter { cur: self.first.take() }
    }

}

pub struct Iter<T: Clone> {
    cur: Option<Ref<Node<T>>>,
}

impl <T: Clone> Iterator for Iter<T> {
    type Item = T;
    fn next(&mut self) -> Option<Self::Item> {
        let mut new_cur = None;
        let mut ret = None;
        if let Some(ref mut cur) = self.cur {
            //FIXME get rid of clone!
            ret = cur.elt.clone();
            new_cur = replace(&mut cur.next, None);
        }
        self.cur = new_cur;
        ret
    }
}

mod test {
    use giftr::refs::*;
    use super::{Ref, List};
    #[test]
    fn lst_len() {
        println!("=== LST_LEN ==============");
        let mut lst = Ref::new(List::new());
        assert_eq!(0, lst.len());

        lst.prepend(1);
        assert_eq!(1, lst.len());

        lst.prepend(2);
        assert_eq!(2, lst.len());

        lst.prepend(3);
        assert_eq!(3, lst.len());

        lst.pop_front();
        assert_eq!(2, lst.len());
    }

    #[test]
    fn lst_pop_front() {
        println!("=== LST_LEN ==============");
        let mut lst = Ref::new(List::new());
        lst.prepend(3);
        lst.prepend(2);
        lst.prepend(1);

        assert_eq!(Some(1), lst.pop_front());
        assert_eq!(Some(2), lst.pop_front());
        assert_eq!(Some(3), lst.pop_front());
        assert_eq!(None, lst.pop_front());
        assert_eq!(None, lst.pop_front());
    }

    #[test]
    fn lst_pop_back() {
        println!("=== LST_LEN ==============");
        let mut lst = Ref::new(List::new());
        lst.prepend(3);
        lst.prepend(2);
        lst.prepend(1);

        assert_eq!(Some(3), lst.pop_back());
        assert_eq!(Some(2), lst.pop_back());
        assert_eq!(Some(1), lst.pop_back());
        assert_eq!(None, lst.pop_front());
        assert_eq!(None, lst.pop_front());
    }

    #[test]
    fn lst_copy() {
        println!("=== LST_COPY ==============");
        let mut lst1 = Ref::new(List::new());
        lst1.prepend(1);
        let lst2 : Ref<List<i32>>;
        lst1.prepend(2);

        lst2 = lst1.clone();

        lst1.prepend(3);

        assert!(3 == lst1.len());
        assert!(2 == lst2.len());
    }

    #[test]
    fn lst_iter() {
        let mut lst1 = Ref::new(List::new());
        lst1.prepend(3);
        lst1.prepend(2);
        lst1.prepend(1);

        let mut cnt = 1;
        for v in lst1.iter() {
            println!("v={}, cnt={}", v, cnt);
            assert_eq!(v, cnt);
            cnt = cnt+1;
        }
    }

}

#[cfg(test)]
mod bench {
    use test;
    use test::Bencher;
    use giftr::refs::*;
    use super::{Ref, List};

    #[bench]
    fn lst_append(b: &mut Bencher) {
        let mut lst1 : Ref<List<i32>> = Ref::new(List::new());
        let size = 100;
        for i in 0..size {
            lst1.append(i);
        }
        b.iter(
            || {
                test::black_box(lst1.append(1));
            }
        );
    }

    #[bench]
    fn lst_prepend(b: &mut Bencher) {
        let mut lst1 : List<i32> = List::new();
        let size = 100;
        for i in 0..size {
            lst1.append(i);
        }
        b.iter(
            || {
                test::black_box(lst1.prepend(1));
            }
        );
    }

}

<|endoftext|>


<commit_before>use super::command::{Command, Query};
use super::command::Command::Load;
use std::iter::IntoIterator;
use std::collections::HashMap;
use std::fmt;
use std::str::FromStr;
use std::convert::AsRef;
use self::InputType::{JSON, ExtInputType};

pub type LoadValues = String;

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct LoadCommand {
    command: Command,
    arguments: HashMap<String, String>,
    table: String,
    values: LoadValues,
}

#[derive (Debug)]
pub enum InputTypeError { Empty }

#[derive (Clone, PartialEq, Eq, Debug)]
pub enum InputType {
    JSON,
    /// For future extensibility.
    ExtInputType(String),
}

impl AsRef<str> for InputType {
    fn as_ref(&self) -> &str {
        match *self {
            JSON => "json",
            ExtInputType(ref s) => s.as_ref()
        }
    }
}

impl fmt::Display for InputType {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.write_str(match *self {
            JSON => "json",
            ExtInputType(ref s) => s.as_ref()
        })
    }
}

impl FromStr for InputType {
    type Err = InputTypeError;
    fn from_str(s: &str) -> Result<InputType, InputTypeError> {
        if s == "" {
            Err(InputTypeError::Empty)
        } else {
            Ok(match s {
                "json" => JSON,
                _ => ExtInputType(s.to_owned())
            })
        }
    }
}

impl Default for LoadCommand {
    fn default() -> LoadCommand {
        LoadCommand {
            command: Load,
            table: "".to_string(),
            arguments: HashMap::new(),
            values: "".to_string(),
        }
    }
}

impl LoadCommand {
    pub fn new(table: String, data: String) -> LoadCommand {
        let default: LoadCommand = Default::default();
        LoadCommand {
            command: default.command,
            table: table,
            arguments: default.arguments,
            values: data,
        }
    }

    #[inline]
    fn split_columns_vec(&mut self, columns: Vec<String>) -> String {
        let string = columns.into_iter().collect::<Vec<String>>()
            .join(",").to_owned();
        string.clone()
    }

    pub fn columns(mut self, columns: Vec<String>) -> LoadCommand {
        let string = self.split_columns_vec(columns);
        self.arguments.insert("columns".to_string(), string.clone());
        self
    }

    pub fn input_type(mut self, input_type: InputType) -> LoadCommand {
        let input_type_str = format!("{}", input_type);
        self.arguments.insert("input_type".to_string(),
                              input_type_str.clone());
        self
    }

    pub fn build(self) -> (Command, Query, LoadValues) {
        let mut query: Query = vec![("table".to_string(), self.table)];
        for (key, value) in self.arguments.iter() {
            query.push((key.to_owned(), value.to_owned()));
        }
        let values = self.values.clone();
        (Load, query, values)
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use command::Query;
    use command::Command::Load;
    use std::collections::HashMap;

    const DATA: &'static str = r#"[
{"_key":"http://example.org/","title":"This is test record 1!"},
]"#;

    #[test]
    fn test_new() {
        let vanilla_load = LoadCommand::new("test".to_string(),
                                            DATA.to_string());
        let expected = LoadCommand {
            command: Load,
            table: "test".to_string(),
            arguments: HashMap::new(),
            values: DATA.to_string(),
        };
        assert_eq!(expected, vanilla_load);
    }

    #[test]
    fn test_columns() {
        let load = LoadCommand::new("test".to_string(), DATA.to_string())
            .columns(vec!["_key".to_string(), "title".to_string()]);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("columns".to_string(), "_key,title".to_string());
        let expected = LoadCommand {
            command: Load,
            table: "test".to_string(),
            arguments: arg,
            values: DATA.to_string(),
        };
        assert_eq!(expected, load);
    }

    #[test]
    fn test_input_type() {
        let load = LoadCommand::new("test".to_string(), DATA.to_string())
            .input_type(InputType::JSON);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("input_type".to_string(), "json".to_string());
        let expected = LoadCommand {
            command: Load,
            table: "test".to_string(),
            arguments: arg,
            values: DATA.to_string(),
        };
        assert_eq!(expected, load);
    }

    #[test]
    fn test_build() {
        let load = LoadCommand::new("test".to_string(), DATA.to_string())
            .columns(vec!["_key".to_string(), "title".to_string()]).build();
        let expected_query: Query =
            vec![("table".to_string(), "test".to_string()),
                 ("columns".to_string(), "_key,title".to_string())];
        let expected = (Load, expected_query, DATA.to_string());
        assert_eq!(expected, load);
    }
}
<commit_msg>load: Add test cases for InputType enum constants<commit_after>use super::command::{Command, Query};
use super::command::Command::Load;
use std::iter::IntoIterator;
use std::collections::HashMap;
use std::fmt;
use std::str::FromStr;
use std::convert::AsRef;
use self::InputType::{JSON, ExtInputType};

pub type LoadValues = String;

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct LoadCommand {
    command: Command,
    arguments: HashMap<String, String>,
    table: String,
    values: LoadValues,
}

#[derive (Debug)]
pub enum InputTypeError { Empty }

#[derive (Clone, PartialEq, Eq, Debug)]
pub enum InputType {
    JSON,
    /// For future extensibility.
    ExtInputType(String),
}

impl AsRef<str> for InputType {
    fn as_ref(&self) -> &str {
        match *self {
            JSON => "json",
            ExtInputType(ref s) => s.as_ref()
        }
    }
}

impl fmt::Display for InputType {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.write_str(match *self {
            JSON => "json",
            ExtInputType(ref s) => s.as_ref()
        })
    }
}

impl FromStr for InputType {
    type Err = InputTypeError;
    fn from_str(s: &str) -> Result<InputType, InputTypeError> {
        if s == "" {
            Err(InputTypeError::Empty)
        } else {
            Ok(match s {
                "json" => JSON,
                _ => ExtInputType(s.to_owned())
            })
        }
    }
}

impl Default for LoadCommand {
    fn default() -> LoadCommand {
        LoadCommand {
            command: Load,
            table: "".to_string(),
            arguments: HashMap::new(),
            values: "".to_string(),
        }
    }
}

impl LoadCommand {
    pub fn new(table: String, data: String) -> LoadCommand {
        let default: LoadCommand = Default::default();
        LoadCommand {
            command: default.command,
            table: table,
            arguments: default.arguments,
            values: data,
        }
    }

    #[inline]
    fn split_columns_vec(&mut self, columns: Vec<String>) -> String {
        let string = columns.into_iter().collect::<Vec<String>>()
            .join(",").to_owned();
        string.clone()
    }

    pub fn columns(mut self, columns: Vec<String>) -> LoadCommand {
        let string = self.split_columns_vec(columns);
        self.arguments.insert("columns".to_string(), string.clone());
        self
    }

    pub fn input_type(mut self, input_type: InputType) -> LoadCommand {
        let input_type_str = format!("{}", input_type);
        self.arguments.insert("input_type".to_string(),
                              input_type_str.clone());
        self
    }

    pub fn build(self) -> (Command, Query, LoadValues) {
        let mut query: Query = vec![("table".to_string(), self.table)];
        for (key, value) in self.arguments.iter() {
            query.push((key.to_owned(), value.to_owned()));
        }
        let values = self.values.clone();
        (Load, query, values)
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use command::Query;
    use command::Command::Load;
    use std::collections::HashMap;
    use std::str::FromStr;

    #[test]
    fn test_from_str() {
        assert_eq!(InputType::JSON, FromStr::from_str("json").unwrap());
        assert_eq!(InputType::ExtInputType("added-type".to_owned()),
                   FromStr::from_str("added-type").unwrap());
        let x: Result<InputType, _> = FromStr::from_str("");
        if let Err(InputTypeError::Empty) = x {
        } else {
            panic!("An empty input type is invalid!")
        }
    }

    #[test]
    fn test_fmt() {
        assert_eq!("json".to_owned(), format!("{}", InputType::JSON));
        assert_eq!("added-type".to_owned(),
                   format!("{}", InputType::ExtInputType("added-type".to_owned())));
    }

    #[test]
    fn test_as_str() {
        assert_eq!(InputType::JSON.as_ref(), "json");
        assert_eq!(InputType::ExtInputType("added-type".to_owned()).as_ref(),
                   "added-type");
    }

    const DATA: &'static str = r#"[
{"_key":"http://example.org/","title":"This is test record 1!"},
]"#;

    #[test]
    fn test_new() {
        let vanilla_load = LoadCommand::new("test".to_string(),
                                            DATA.to_string());
        let expected = LoadCommand {
            command: Load,
            table: "test".to_string(),
            arguments: HashMap::new(),
            values: DATA.to_string(),
        };
        assert_eq!(expected, vanilla_load);
    }

    #[test]
    fn test_columns() {
        let load = LoadCommand::new("test".to_string(), DATA.to_string())
            .columns(vec!["_key".to_string(), "title".to_string()]);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("columns".to_string(), "_key,title".to_string());
        let expected = LoadCommand {
            command: Load,
            table: "test".to_string(),
            arguments: arg,
            values: DATA.to_string(),
        };
        assert_eq!(expected, load);
    }

    #[test]
    fn test_input_type() {
        let load = LoadCommand::new("test".to_string(), DATA.to_string())
            .input_type(InputType::JSON);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("input_type".to_string(), "json".to_string());
        let expected = LoadCommand {
            command: Load,
            table: "test".to_string(),
            arguments: arg,
            values: DATA.to_string(),
        };
        assert_eq!(expected, load);
    }

    #[test]
    fn test_build() {
        let load = LoadCommand::new("test".to_string(), DATA.to_string())
            .columns(vec!["_key".to_string(), "title".to_string()]).build();
        let expected_query: Query =
            vec![("table".to_string(), "test".to_string()),
                 ("columns".to_string(), "_key,title".to_string())];
        let expected = (Load, expected_query, DATA.to_string());
        assert_eq!(expected, load);
    }
}
<|endoftext|>


<commit_before>#![feature(box_patterns,box_syntax)]
#![feature(scheme)]
#![feature(compile)]
#![feature(collections)]
extern crate rustc_serialize;
extern crate docopt;

extern crate seax_svm as svm;
extern crate seax_scheme as scheme;

#[macro_use]
extern crate log;

use docopt::Docopt;
use std::io;
use std::io::{Write, Read, BufRead,BufReader};
use svm::slist::{List,Stack};
use svm::cell::{SVMCell,Inst};
use svm::State;
use std::iter::FromIterator;
use std::error::Error;

static USAGE: &'static str = "
Usage:
    seax repl [-vd]
    seax [-vd] <bin>

Options:
    -v, --verbose   Enable verbose mode
    -d, --debug     Enable debug mode
";

#[derive(RustcDecodable)]
struct Args {
    cmd_repl: bool,
    arg_bin: String,
    flag_verbose: bool,
    flag_debug: bool,
}

mod loggers;

fn main() {
    let args: Args = Docopt::new(USAGE)
                .and_then(|d| d.decode())
                .unwrap_or_else(|e| e.exit());

    if args.flag_verbose {
        log::set_logger(|max_log_level| {
            max_log_level.set(log::LogLevelFilter::Debug);
            Box::new(loggers::DebugLogger)
        });
    } else {
        log::set_logger(|max_log_level| {
            max_log_level.set(log::LogLevelFilter::Info);
            Box::new(loggers::DefaultLogger)
        });
    };

    if args.cmd_repl {
        let mut stdin = BufReader::new(io::stdin());
        let mut stdout = io::stdout();

        print!("scheme> ");
        stdout.flush();

        for line in stdin.lines() {
            line.map_err(   |error   | String::from_str(error.description()) )
                .and_then(  |ref code| scheme::compile(code) )
                .map(       |program | svm::eval_program(program, true) )
                .map(       |result  | println!(">> {:?}", result) )
                .map_err(   |err     | error!("{}", err));
            print!("scheme> ");
            stdout.flush();
        }
    }
}
<commit_msg>Remove a great deal of compiler warnings<commit_after>#![feature(box_patterns,box_syntax)]
#![feature(scheme)]
#![feature(compile)]
#![feature(collections)]
extern crate rustc_serialize;
extern crate docopt;

extern crate seax_svm as svm;
extern crate seax_scheme as scheme;

#[macro_use]
extern crate log;

use docopt::Docopt;
use std::io;
use std::io::{Write, BufRead,BufReader};
use std::error::Error;

static USAGE: &'static str = "
Usage:
    seax repl [-vd]
    seax [-vd] <bin>

Options:
    -v, --verbose   Enable verbose mode
    -d, --debug     Enable debug mode
";

#[derive(RustcDecodable)]
struct Args {
    cmd_repl: bool,
    arg_bin: String,
    flag_verbose: bool,
    flag_debug: bool,
}

mod loggers;

fn main() {
    let args: Args = Docopt::new(USAGE)
                .and_then(|d| d.decode())
                .unwrap_or_else(|e| e.exit());

    if args.flag_verbose {
        let _ = log::set_logger(|max_log_level| {
            max_log_level.set(log::LogLevelFilter::Debug);
            Box::new(loggers::DebugLogger)
        });
    } else {
        let _ = log::set_logger(|max_log_level| {
            max_log_level.set(log::LogLevelFilter::Info);
            Box::new(loggers::DefaultLogger)
        });
    };

    if args.cmd_repl {
        let stdin = BufReader::new(io::stdin());
        let mut stdout = io::stdout();

        print!("scheme> ");
        let _ = stdout.flush();

        for line in stdin.lines() {
            match line.map_err(|error| String::from_str(error.description()) )
                .and_then(  |ref code| scheme::compile(code) )
                .map(       |program | svm::eval_program(program, true) ) {
                    Ok(result)  => println!(">> {:?}",result),
                    Err(why)    => error!("{:?}", why)
                };
            print!("scheme> ");
            let _ = stdout.flush();
        }
    }
}
<|endoftext|>


<commit_before>extern crate chrono;
extern crate clap;
extern crate hyper;
extern crate libc;
extern crate multirust;
extern crate rust_install;

extern crate rust_bisect;

use std::process;

use chrono::NaiveDate;
use clap::{App, AppSettings, Arg};
use hyper::client::Client;
use rust_install::dist::ToolchainDesc;

use rust_bisect::{Result, least_satisfying};

const NIGHTLY: &'static str = "nightly";

fn nightly(date: NaiveDate) -> String {
    format!("{}-{}", NIGHTLY, date)
}

fn list_available_nightlies(dist_root: &str,
                            from: NaiveDate,
                            to: NaiveDate)
                            -> Result<Vec<NaiveDate>> {
    assert!(from < to, "`from` must be less than `to`");
    println!("finding available nightlies between {} and {}", from, to);
    let client = Client::new();
    let mut nightlies = Vec::with_capacity((to - from).num_days() as usize);
    let mut date = from;
    while date < to {
        let desc = ToolchainDesc::from_str(&nightly(date)).expect("should always parse");
        let resp = try!(client.head(&desc.manifest_url(dist_root)).send());
        // TODO: ensure failures are 404
        if resp.status.is_success() {
            nightlies.push(date);
        }
        date = date.succ();
    }
    println!("found {} nightlies", nightlies.len());
    Ok(nightlies)
}

fn run_rust_bisect() -> Result<i32> {
    fn validate_version(s: String) -> std::result::Result<(), String> {
        let ret = ToolchainDesc::from_str(&s);
        match ret {
            Some(ref desc) if desc.channel == NIGHTLY && desc.date.is_some() => Ok(()),
            Some(_) => Err(String::from("can only bisect on dated nightlies")),
            None => Err(String::from(format!("invalid version: {}", s))),
        }
    }
    let matches = App::new("rust-bisect")
                      .author("Kamal Marhubi <kamal@marhubi.com>")
                      .about("Find the Rust nightly that that changed some behavior")
                      .setting(AppSettings::TrailingVarArg)
                      .usage("rust-bisect [FLAGS] --bad <VERSION> --good <VERSION> <COMMAND> \
                              [ARGS...]")
                      .arg(Arg::with_name("good")
                               .long("good")
                               .takes_value(true)
                               .value_name("VERSION")
                               .help("A known good nightly release")
                               .validator(validate_version)
                               .required(true))
                      .arg(Arg::with_name("bad")
                               .long("bad")
                               .takes_value(true)
                               .value_name("VERSION")
                               .help("A known bad nightly release")
                               .validator(validate_version)
                               .required(true))
                      .arg(Arg::with_name("COMMAND")
                               .index(1)
                               .help("The command to run")
                               .required(true))
                      .arg(Arg::with_name("ARGS")
                               .index(2)
                               .multiple(true)
                               .help("Arguments for COMMAND"))
                      .get_matches();

    let cfg = try!(multirust::Cfg::from_env(rust_install::notify::SharedNotifyHandler::none()));

    let good = matches.value_of("good").expect("clap didn't respect required arg `good`");
    let good = ToolchainDesc::from_str(good).expect("clap validator misbehaved for `good`");

    let bad = matches.value_of("bad").expect("clap didn't respect required arg `bad`");
    let bad = ToolchainDesc::from_str(bad).expect("clap validator misbehaved for `bad`");

    let good_date: NaiveDate = try!(good.date
                                        .expect("clap validator misbehaved for `good`")
                                        .parse());
    let bad_date: NaiveDate = try!(bad.date
                                      .expect("clap validator misbehaved for `bad`")
                                      .parse());

    let cmd = matches.value_of_os("COMMAND")
                     .expect("clap didn't respect required arg `COMMAND`");
    let args: Vec<_> = matches.values_of_os("ARGS")
                              .map(|args| args.collect())
                              .unwrap_or(Vec::new());

    let nightlies = try!(list_available_nightlies(&*cfg.dist_root_url, good_date, bad_date));
    println!("bisecting across {} nightlies (about {} steps)",
             nightlies.len(),
             nightlies.len().next_power_of_two().trailing_zeros());

    let idx = least_satisfying(&nightlies[..], |date| {
        let version = nightly(*date);
        println!("testing with {}", version);

        let toolchain = cfg.get_toolchain(&version, false).expect("could not get toolchain");
        toolchain.install_from_dist_if_not_installed().expect("could not install toolchain");

        let mut cmd = toolchain.create_command(cmd).expect("could not create command");
        cmd.args(&args);
        let res = cmd.status().expect("could not run command").success();

        println!("command {} with {}",
                 if res {
                     "succeeded"
                 } else {
                     "failed"
                 },
                 version);
        !res
    });

    println!("{} is the first failing nightly", nightly(nightlies[idx]));
    Ok(libc::EXIT_SUCCESS)
}

fn main() {
    process::exit(run_rust_bisect().expect("something went wrong"));
}
<commit_msg>style: Fix whitespace issue<commit_after>extern crate chrono;
extern crate clap;
extern crate hyper;
extern crate libc;
extern crate multirust;
extern crate rust_install;

extern crate rust_bisect;

use std::process;

use chrono::NaiveDate;
use clap::{App, AppSettings, Arg};
use hyper::client::Client;
use rust_install::dist::ToolchainDesc;

use rust_bisect::{Result, least_satisfying};

const NIGHTLY: &'static str = "nightly";

fn nightly(date: NaiveDate) -> String {
    format!("{}-{}", NIGHTLY, date)
}

fn list_available_nightlies(dist_root: &str,
                            from: NaiveDate,
                            to: NaiveDate)
                            -> Result<Vec<NaiveDate>> {
    assert!(from < to, "`from` must be less than `to`");
    println!("finding available nightlies between {} and {}", from, to);
    let client = Client::new();
    let mut nightlies = Vec::with_capacity((to - from).num_days() as usize);
    let mut date = from;
    while date < to {
        let desc = ToolchainDesc::from_str(&nightly(date)).expect("should always parse");
        let resp = try!(client.head(&desc.manifest_url(dist_root)).send());
        // TODO: ensure failures are 404
        if resp.status.is_success() {
            nightlies.push(date);
        }
        date = date.succ();
    }
    println!("found {} nightlies", nightlies.len());
    Ok(nightlies)
}

fn run_rust_bisect() -> Result<i32> {
    fn validate_version(s: String) -> std::result::Result<(), String> {
        let ret = ToolchainDesc::from_str(&s);
        match ret {
            Some(ref desc) if desc.channel == NIGHTLY && desc.date.is_some() => Ok(()),
            Some(_) => Err(String::from("can only bisect on dated nightlies")),
            None => Err(String::from(format!("invalid version: {}", s))),
        }
    }
    let matches = App::new("rust-bisect")
                      .author("Kamal Marhubi <kamal@marhubi.com>")
                      .about("Find the Rust nightly that that changed some behavior")
                      .setting(AppSettings::TrailingVarArg)
                      .usage("rust-bisect [FLAGS] --bad <VERSION> --good <VERSION> <COMMAND> \
                              [ARGS...]")
                      .arg(Arg::with_name("good")
                               .long("good")
                               .takes_value(true)
                               .value_name("VERSION")
                               .help("A known good nightly release")
                               .validator(validate_version)
                               .required(true))
                      .arg(Arg::with_name("bad")
                               .long("bad")
                               .takes_value(true)
                               .value_name("VERSION")
                               .help("A known bad nightly release")
                               .validator(validate_version)
                               .required(true))
                      .arg(Arg::with_name("COMMAND")
                               .index(1)
                               .help("The command to run")
                               .required(true))
                      .arg(Arg::with_name("ARGS")
                               .index(2)
                               .multiple(true)
                               .help("Arguments for COMMAND"))
                      .get_matches();

    let cfg = try!(multirust::Cfg::from_env(rust_install::notify::SharedNotifyHandler::none()));

    let good = matches.value_of("good").expect("clap didn't respect required arg `good`");
    let good = ToolchainDesc::from_str(good).expect("clap validator misbehaved for `good`");

    let bad = matches.value_of("bad").expect("clap didn't respect required arg `bad`");
    let bad = ToolchainDesc::from_str(bad).expect("clap validator misbehaved for `bad`");

    let good_date: NaiveDate = try!(good.date
                                        .expect("clap validator misbehaved for `good`")
                                        .parse());
    let bad_date: NaiveDate = try!(bad.date
                                      .expect("clap validator misbehaved for `bad`")
                                      .parse());

    let cmd = matches.value_of_os("COMMAND")
                     .expect("clap didn't respect required arg `COMMAND`");
    let args: Vec<_> = matches.values_of_os("ARGS")
                              .map(|args| args.collect())
                              .unwrap_or(Vec::new());

    let nightlies = try!(list_available_nightlies(&*cfg.dist_root_url, good_date, bad_date));
    println!("bisecting across {} nightlies (about {} steps)",
             nightlies.len(),
             nightlies.len().next_power_of_two().trailing_zeros());

    let idx = least_satisfying(&nightlies[..], |date| {
        let version = nightly(*date);
        println!("testing with {}", version);

        let toolchain = cfg.get_toolchain(&version, false).expect("could not get toolchain");
        toolchain.install_from_dist_if_not_installed().expect("could not install toolchain");

        let mut cmd = toolchain.create_command(cmd).expect("could not create command");
        cmd.args(&args);
        let res = cmd.status().expect("could not run command").success();

        println!("command {} with {}",
                 if res {
                     "succeeded"
                 } else {
                     "failed"
                 },
                 version);
        !res
    });

    println!("{} is the first failing nightly", nightly(nightlies[idx]));
    Ok(libc::EXIT_SUCCESS)
}

fn main() {
    process::exit(run_rust_bisect().expect("something went wrong"));
}
<|endoftext|>