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

use resource_task::{ProgressMsg, Payload, Done, LoaderTask};

use std::cell::Cell;
use std::vec;
use extra::url::Url;
use http::client::RequestWriter;
use http::method::Get;
use http::headers::HeaderEnum;
use std::rt::io::Reader;
use std::rt::io::net::ip::SocketAddr;

pub fn factory() -> LoaderTask {
	let f: LoaderTask = |url, progress_chan| {
        let url = Cell::new(url);
        let progress_chan = Cell::new(progress_chan);
        spawn(|| load(url.take(), progress_chan.take()))
	};
	f
}

fn load(url: Url, progress_chan: Chan<ProgressMsg>) {
	assert!(url.scheme == ~"http");

    info!("requesting %s", url.to_str());

    let mut request = ~RequestWriter::new(Get, url.clone());
    request.remote_addr = Some(url_to_socket_addr(&url));
    let mut response = match request.read_response() {
        Ok(r) => r,
        Err(_) => {
            progress_chan.send(Done(Err(())));
            return;
        }
    };

    for header in response.headers.iter() {
        info!(" - %s: %s", header.header_name(), header.header_value());
    }

    loop {
        let mut buf = vec::with_capacity(1024);

        unsafe { vec::raw::set_len(&mut buf, 1024) };
        match response.read(buf) {
            Some(len) => {
                unsafe { vec::raw::set_len(&mut buf, len) };
            }
            None => {
                progress_chan.send(Done(Ok(())));
                return;
            }
        }
        progress_chan.send(Payload(buf));
    }
    progress_chan.send(Done(Ok(())));
}

// FIXME: Quick hack to convert ip addresses to SocketAddr
fn url_to_socket_addr(url: &Url) -> SocketAddr {
    let host_and_port = fmt!("%s:%s", url.host, url.port.clone().unwrap_or_default(~"80"));
    FromStr::from_str(host_and_port).expect("couldn't parse host as IP address")
}
<commit_msg>auto merge of #872 : brson/servo/http, r=metajack<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use resource_task::{ProgressMsg, Payload, Done, LoaderTask};

use std::cell::Cell;
use std::vec;
use extra::url::Url;
use http::client::RequestWriter;
use http::method::Get;
use http::headers::HeaderEnum;
use std::rt::io::Reader;
use std::rt::io::net::ip::SocketAddr;

pub fn factory() -> LoaderTask {
	let f: LoaderTask = |url, progress_chan| {
        let url = Cell::new(url);
        let progress_chan = Cell::new(progress_chan);
        spawn(|| load(url.take(), progress_chan.take()))
	};
	f
}

fn load(url: Url, progress_chan: Chan<ProgressMsg>) {
	assert!(url.scheme == ~"http");

    info!("requesting %s", url.to_str());

    let mut request = ~RequestWriter::new(Get, url.clone());
    request.remote_addr = Some(url_to_socket_addr(&url));
    let mut response = match request.read_response() {
        Ok(r) => r,
        Err(_) => {
            progress_chan.send(Done(Err(())));
            return;
        }
    };

    for header in response.headers.iter() {
        info!(" - %s: %s", header.header_name(), header.header_value());
    }

    loop {
        let mut buf = vec::with_capacity(1024);

        unsafe { vec::raw::set_len(&mut buf, 1024) };
        match response.read(buf) {
            Some(len) => {
                unsafe { vec::raw::set_len(&mut buf, len) };
            }
            None => {
                progress_chan.send(Done(Ok(())));
                return;
            }
        }
        progress_chan.send(Payload(buf));
    }
}

// FIXME: Quick hack to convert ip addresses to SocketAddr
fn url_to_socket_addr(url: &Url) -> SocketAddr {
    let host_and_port = fmt!("%s:%s", url.host, url.port.clone().unwrap_or_default(~"80"));
    FromStr::from_str(host_and_port).expect("couldn't parse host as IP address")
}
<|endoftext|>


<commit_before>use std::io::{BufferedReader, File};

fn read_tar(chan: Sender<Vec<u8>>) {
    static BLOCK_SIZE: uint = 512;
    let file = File::open(&Path::new("tar_test.tar"));
    let mut reader = BufferedReader::new(file);

    loop {
        let mut buf = vec!();
        match reader.push(BLOCK_SIZE, &mut buf) {
            Ok(_) => chan.send(buf),
            Err(e) => return,
        }

    }
}

fn main() {
    let (chan, port) = channel();
    read_tar(chan);
    println!("{:s}", port.recv().to_string());
}
<commit_msg>getting rid of warning<commit_after>use std::io::{BufferedReader, File};

fn read_tar(chan: Sender<Vec<u8>>) {
    static BLOCK_SIZE: uint = 512;
    let file = File::open(&Path::new("tar_test.tar"));
    let mut reader = BufferedReader::new(file);

    loop {
        let mut buf = vec!();
        match reader.push(BLOCK_SIZE, &mut buf) {
            Ok(_) => chan.send(buf),
            Err(_) => return,
        }

    }
}

fn main() {
    let (chan, port) = channel();
    read_tar(chan);
    println!("{:s}", port.recv().to_string());
}
<|endoftext|>


<commit_before>use super::*;
use super::super::lexer;
use codemap::CodeMap;
use codemap::Spanned;

fn get_tokens(source: &str) -> Vec<Spanned<Token>> {
  let mut map = CodeMap::new();
  let file = map.add_file(String::from("_test"), String::from(source));
  lexer::lex(&file)
}

#[test]
fn test_quark() {
  let source = "null true false 1.3 0.3 2 3 name table";
  let tokens = get_tokens(source);
  let mut it = tokens.iter().peekable();

  assert_eq!(parse_quark(&mut it), Ok(Node::Null));
  assert_eq!(parse_quark(&mut it), Ok(Node::Bool(true)));
  assert_eq!(parse_quark(&mut it), Ok(Node::Bool(false)));
  assert_eq!(parse_quark(&mut it), Ok(Node::Float(1.3)));
  assert_eq!(parse_quark(&mut it), Ok(Node::Float(0.3)));
  assert_eq!(parse_quark(&mut it), Ok(Node::Int(2)));
  assert_eq!(parse_quark(&mut it), Ok(Node::Int(3)));
  assert_eq!(parse_quark(&mut it), Ok(Node::Name(String::from("name"))));
  assert_eq!(parse_quark(&mut it), Ok(Node::Table));
  assert_eq!(
    parse_quark(&mut it),
    Err(UnexpectedToken(lexer::Token::End))
  );
  it.next();
  assert_eq!(
    parse_quark(&mut it),
    Err(UnexpectedToken(lexer::Token::EOF))
  );
  it.next();
  assert_eq!(parse_quark(&mut it), Err(UnexpectedEOF));
}

#[test]
fn test_atom() {
  let source = "null (null)";
  let tokens = get_tokens(source);
  let mut it = tokens.iter().peekable();

  assert_eq!(parse_atom(&mut it), Ok(Node::Null));
  assert_eq!(parse_atom(&mut it), Ok(Node::Null));
  assert_eq!(parse_atom(&mut it), Err(UnexpectedToken(lexer::Token::End)));
  it.next();
  assert_eq!(parse_atom(&mut it), Err(UnexpectedToken(lexer::Token::EOF)));
  it.next();
  assert_eq!(parse_atom(&mut it), Err(UnexpectedEOF));
}

#[test]
fn test_simple() {
  let source = "foo foo.bar foo[bar] foo() foo:bar() foo.bar() foo.bar[baz]:qux()";
  let tokens = get_tokens(source);
  let mut it = tokens.iter().peekable();

  assert_eq!(parse_simple(&mut it), Ok(Node::Name(String::from("foo"))));
  assert_eq!(
    parse_simple(&mut it),
    Ok(Node::Index {
      lhs: Box::new(Node::Name(String::from("foo"))),
      rhs: Box::new(Node::Str(String::from("bar"))),
    })
  );
  assert_eq!(
    parse_simple(&mut it),
    Ok(Node::Index {
      lhs: Box::new(Node::Name(String::from("foo"))),
      rhs: Box::new(Node::Name(String::from("bar"))),
    })
  );
  assert_eq!(
    parse_simple(&mut it),
    Ok(Node::Func {
      func: Box::new(Node::Name(String::from("foo"))),
      args: Vec::new(),
    })
  );
  assert_eq!(
    parse_simple(&mut it),
    Ok(Node::Method {
      owner: Box::new(Node::Name(String::from("foo"))),
      method: Box::new(Node::Str(String::from("bar"))),
      args: Vec::new(),
    })
  );
  assert_eq!(
    parse_simple(&mut it),
    Ok(Node::Func {
      func: Box::new(Node::Index {
        lhs: Box::new(Node::Name(String::from("foo"))),
        rhs: Box::new(Node::Str(String::from("bar"))),
      }),
      args: Vec::new(),
    })
  );
  assert_eq!(
    parse_simple(&mut it),
    Ok(Node::Method {
      owner: Box::new(Node::Index {
        lhs: Box::new(Node::Index {
          lhs: Box::new(Node::Name(String::from("foo"))),
          rhs: Box::new(Node::Str(String::from("bar"))),
        }),
        rhs: Box::new(Node::Name(String::from("baz"))),
      }),
      method: Box::new(Node::Str(String::from("qux"))),
      args: Vec::new(),
    })
  );
  assert_eq!(
    parse_simple(&mut it),
    Err(UnexpectedToken(lexer::Token::End))
  );
  it.next();
  assert_eq!(
    parse_simple(&mut it),
    Err(UnexpectedToken(lexer::Token::EOF))
  );
  it.next();
  assert_eq!(parse_simple(&mut it), Err(UnexpectedEOF));
}

#[test]
fn test_fn_args() {
  let source = "()";
  let tokens = get_tokens(source);
  let mut it = tokens.iter().peekable();

  assert_eq!(parse_fn_args(&mut it), Ok(Vec::new()));
  assert_eq!(
    parse_fn_args(&mut it),
    Err(UnexpectedToken(lexer::Token::End))
  );
  it.next();
  assert_eq!(
    parse_fn_args(&mut it),
    Err(UnexpectedToken(lexer::Token::EOF))
  );
  it.next();
  assert_eq!(parse_fn_args(&mut it), Err(UnexpectedEOF));
}

#[test]
fn test_un_expr() {
  let source = "5 foo() -5 -foo.bar !-5";
  let tokens = get_tokens(source);
  let mut it = tokens.iter().peekable();

  assert_eq!(parse_un_expr(&mut it), Ok(Node::Int(5)));
  assert_eq!(
    parse_un_expr(&mut it),
    Ok(Node::Func {
      func: Box::new(Node::Name(String::from("foo"))),
      args: Vec::new(),
    })
  );
  assert_eq!(
    parse_un_expr(&mut it),
    Ok(Node::UnExpr {
      op: lexer::Token::Sub,
      val: Box::new(Node::Int(5)),
    })
  );
  assert_eq!(
    parse_un_expr(&mut it),
    Ok(Node::UnExpr {
      op: lexer::Token::Sub,
      val: Box::new(Node::Index {
        lhs: Box::new(Node::Name(String::from("foo"))),
        rhs: Box::new(Node::Str(String::from("bar"))),
      }),
    })
  );
  assert_eq!(
    parse_un_expr(&mut it),
    Ok(Node::UnExpr {
      op: lexer::Token::Not,
      val: Box::new(Node::UnExpr {
        op: lexer::Token::Sub,
        val: Box::new(Node::Int(5)),
      }),
    })
  );
  assert_eq!(
    parse_un_expr(&mut it),
    Err(UnexpectedToken(lexer::Token::End))
  );
  it.next();
  assert_eq!(
    parse_un_expr(&mut it),
    Err(UnexpectedToken(lexer::Token::EOF))
  );
  it.next();
  assert_eq!(parse_un_expr(&mut it), Err(UnexpectedEOF));
}

#[test]
fn test_bin_expr() {
  let source = "1 + 2 1 + 2 1 + 2 * 3";
  let tokens = get_tokens(source);
  let mut it = tokens.iter().peekable();

  assert_eq!(
    parse_bin_expr(&mut it),
    Ok(Node::BinExpr {
      lhs: Box::new(Node::Int(1)),
      op: lexer::Token::Add,
      rhs: Box::new(Node::Int(2)),
    })
  );
  assert_eq!(
    parse_bin_expr(&mut it),
    Ok(Node::BinExpr {
      lhs: Box::new(Node::Int(1)),
      op: lexer::Token::Add,
      rhs: Box::new(Node::Int(2)),
    })
  );
  assert_eq!(
    parse_bin_expr(&mut it),
    Ok(Node::BinExpr {
      lhs: Box::new(Node::Int(1)),
      op: lexer::Token::Add,
      rhs: Box::new(Node::BinExpr {
        lhs: Box::new(Node::Int(2)),
        op: lexer::Token::Mul,
        rhs: Box::new(Node::Int(3)),
      }),
    })
  );
  assert_eq!(
    parse_un_expr(&mut it),
    Err(UnexpectedToken(lexer::Token::End))
  );
  it.next();
  assert_eq!(
    parse_un_expr(&mut it),
    Err(UnexpectedToken(lexer::Token::EOF))
  );
  it.next();
  assert_eq!(parse_un_expr(&mut it), Err(UnexpectedEOF));
}

#[test]
fn test_fn_expr() {
  let source = "|| 5 |x| 5 |x,| 5 |x, y| 5";
  let tokens = get_tokens(source);
  let mut it = tokens.iter().peekable();

  assert_eq!(
    parse_il_expr(&mut it),
    Ok(Node::Lambda {
      params: Vec::new(),
      expr: Box::new(Node::Int(5)),
    })
  );
  assert_eq!(
    parse_il_expr(&mut it),
    Ok(Node::Lambda {
      params: vec![String::from("x")],
      expr: Box::new(Node::Int(5)),
    })
  );
  assert_eq!(
    parse_il_expr(&mut it),
    Ok(Node::Lambda {
      params: vec![String::from("x")],
      expr: Box::new(Node::Int(5)),
    })
  );
  assert_eq!(
    parse_il_expr(&mut it),
    Ok(Node::Lambda {
      params: vec![String::from("x"), String::from("y")],
      expr: Box::new(Node::Int(5)),
    })
  );
  assert_eq!(
    parse_un_expr(&mut it),
    Err(UnexpectedToken(lexer::Token::End))
  );
  it.next();
  assert_eq!(
    parse_un_expr(&mut it),
    Err(UnexpectedToken(lexer::Token::EOF))
  );
  it.next();
  assert_eq!(parse_un_expr(&mut it), Err(UnexpectedEOF));
}
<commit_msg>tests.parser: Add test_parse() helper<commit_after>use super::*;
use super::super::lexer;
use codemap::CodeMap;
use codemap::Spanned;

fn get_tokens(source: &str) -> Vec<Spanned<Token>> {
  let mut map = CodeMap::new();
  let file = map.add_file(String::from("_test"), String::from(source));
  lexer::lex(&file)
}

fn test_parse(source: &str, func: &Fn(&mut ParseIter) -> Parse, expect: Parse) {
  let tokens = get_tokens(source);
  let mut it = tokens.iter().peekable();

  assert_eq!(
    func(&mut it),
    expect
  );

  assert_eq!(
    parse_un_expr(&mut it),
    Err(UnexpectedToken(lexer::Token::End))
  );
  it.next();

  assert_eq!(
    parse_un_expr(&mut it),
    Err(UnexpectedToken(lexer::Token::EOF))
  );
  it.next();

  assert_eq!(parse_un_expr(&mut it), Err(UnexpectedEOF));
}

#[test]
fn test_quark() {
  let source = "null true false 1.3 0.3 2 3 name table";
  let tokens = get_tokens(source);
  let mut it = tokens.iter().peekable();

  assert_eq!(parse_quark(&mut it), Ok(Node::Null));
  assert_eq!(parse_quark(&mut it), Ok(Node::Bool(true)));
  assert_eq!(parse_quark(&mut it), Ok(Node::Bool(false)));
  assert_eq!(parse_quark(&mut it), Ok(Node::Float(1.3)));
  assert_eq!(parse_quark(&mut it), Ok(Node::Float(0.3)));
  assert_eq!(parse_quark(&mut it), Ok(Node::Int(2)));
  assert_eq!(parse_quark(&mut it), Ok(Node::Int(3)));
  assert_eq!(parse_quark(&mut it), Ok(Node::Name(String::from("name"))));
  assert_eq!(parse_quark(&mut it), Ok(Node::Table));
  assert_eq!(
    parse_quark(&mut it),
    Err(UnexpectedToken(lexer::Token::End))
  );
  it.next();
  assert_eq!(
    parse_quark(&mut it),
    Err(UnexpectedToken(lexer::Token::EOF))
  );
  it.next();
  assert_eq!(parse_quark(&mut it), Err(UnexpectedEOF));
}

#[test]
fn test_atom() {
  let source = "null (null)";
  let tokens = get_tokens(source);
  let mut it = tokens.iter().peekable();

  assert_eq!(parse_atom(&mut it), Ok(Node::Null));
  assert_eq!(parse_atom(&mut it), Ok(Node::Null));
  assert_eq!(parse_atom(&mut it), Err(UnexpectedToken(lexer::Token::End)));
  it.next();
  assert_eq!(parse_atom(&mut it), Err(UnexpectedToken(lexer::Token::EOF)));
  it.next();
  assert_eq!(parse_atom(&mut it), Err(UnexpectedEOF));
}

#[test]
fn test_simple() {
  let source = "foo foo.bar foo[bar] foo() foo:bar() foo.bar() foo.bar[baz]:qux()";
  let tokens = get_tokens(source);
  let mut it = tokens.iter().peekable();

  assert_eq!(parse_simple(&mut it), Ok(Node::Name(String::from("foo"))));
  assert_eq!(
    parse_simple(&mut it),
    Ok(Node::Index {
      lhs: Box::new(Node::Name(String::from("foo"))),
      rhs: Box::new(Node::Str(String::from("bar"))),
    })
  );
  assert_eq!(
    parse_simple(&mut it),
    Ok(Node::Index {
      lhs: Box::new(Node::Name(String::from("foo"))),
      rhs: Box::new(Node::Name(String::from("bar"))),
    })
  );
  assert_eq!(
    parse_simple(&mut it),
    Ok(Node::Func {
      func: Box::new(Node::Name(String::from("foo"))),
      args: Vec::new(),
    })
  );
  assert_eq!(
    parse_simple(&mut it),
    Ok(Node::Method {
      owner: Box::new(Node::Name(String::from("foo"))),
      method: Box::new(Node::Str(String::from("bar"))),
      args: Vec::new(),
    })
  );
  assert_eq!(
    parse_simple(&mut it),
    Ok(Node::Func {
      func: Box::new(Node::Index {
        lhs: Box::new(Node::Name(String::from("foo"))),
        rhs: Box::new(Node::Str(String::from("bar"))),
      }),
      args: Vec::new(),
    })
  );
  assert_eq!(
    parse_simple(&mut it),
    Ok(Node::Method {
      owner: Box::new(Node::Index {
        lhs: Box::new(Node::Index {
          lhs: Box::new(Node::Name(String::from("foo"))),
          rhs: Box::new(Node::Str(String::from("bar"))),
        }),
        rhs: Box::new(Node::Name(String::from("baz"))),
      }),
      method: Box::new(Node::Str(String::from("qux"))),
      args: Vec::new(),
    })
  );
  assert_eq!(
    parse_simple(&mut it),
    Err(UnexpectedToken(lexer::Token::End))
  );
  it.next();
  assert_eq!(
    parse_simple(&mut it),
    Err(UnexpectedToken(lexer::Token::EOF))
  );
  it.next();
  assert_eq!(parse_simple(&mut it), Err(UnexpectedEOF));
}

#[test]
fn test_fn_args() {
  let source = "()";
  let tokens = get_tokens(source);
  let mut it = tokens.iter().peekable();

  assert_eq!(parse_fn_args(&mut it), Ok(Vec::new()));
  assert_eq!(
    parse_fn_args(&mut it),
    Err(UnexpectedToken(lexer::Token::End))
  );
  it.next();
  assert_eq!(
    parse_fn_args(&mut it),
    Err(UnexpectedToken(lexer::Token::EOF))
  );
  it.next();
  assert_eq!(parse_fn_args(&mut it), Err(UnexpectedEOF));
}

#[test]
fn test_un_expr() {
  let source = "5 foo() -5 -foo.bar !-5";
  let tokens = get_tokens(source);
  let mut it = tokens.iter().peekable();

  assert_eq!(parse_un_expr(&mut it), Ok(Node::Int(5)));
  assert_eq!(
    parse_un_expr(&mut it),
    Ok(Node::Func {
      func: Box::new(Node::Name(String::from("foo"))),
      args: Vec::new(),
    })
  );
  assert_eq!(
    parse_un_expr(&mut it),
    Ok(Node::UnExpr {
      op: lexer::Token::Sub,
      val: Box::new(Node::Int(5)),
    })
  );
  assert_eq!(
    parse_un_expr(&mut it),
    Ok(Node::UnExpr {
      op: lexer::Token::Sub,
      val: Box::new(Node::Index {
        lhs: Box::new(Node::Name(String::from("foo"))),
        rhs: Box::new(Node::Str(String::from("bar"))),
      }),
    })
  );
  assert_eq!(
    parse_un_expr(&mut it),
    Ok(Node::UnExpr {
      op: lexer::Token::Not,
      val: Box::new(Node::UnExpr {
        op: lexer::Token::Sub,
        val: Box::new(Node::Int(5)),
      }),
    })
  );
  assert_eq!(
    parse_un_expr(&mut it),
    Err(UnexpectedToken(lexer::Token::End))
  );
  it.next();
  assert_eq!(
    parse_un_expr(&mut it),
    Err(UnexpectedToken(lexer::Token::EOF))
  );
  it.next();
  assert_eq!(parse_un_expr(&mut it), Err(UnexpectedEOF));
}

#[test]
fn test_bin_expr() {
  test_parse(
    "1 + 2",
    &parse_bin_expr,
    Ok(Node::BinExpr {
      lhs: Box::new(Node::Int(1)),
      op: lexer::Token::Add,
      rhs: Box::new(Node::Int(2)),
    })
  );

  test_parse(
    "(1 + 2)",
    &parse_bin_expr,
    Ok(Node::BinExpr {
      lhs: Box::new(Node::Int(1)),
      op: lexer::Token::Add,
      rhs: Box::new(Node::Int(2)),
    })
  );

  test_parse(
    "1 + 2 * 3",
    &parse_bin_expr,
    Ok(Node::BinExpr {
      lhs: Box::new(Node::Int(1)),
      op: lexer::Token::Add,
      rhs: Box::new(Node::BinExpr {
        lhs: Box::new(Node::Int(2)),
        op: lexer::Token::Mul,
        rhs: Box::new(Node::Int(3)),
      }),
    })
  );
}

#[test]
fn test_fn_expr() {
  let source = "|| 5 |x| 5 |x,| 5 |x, y| 5";
  let tokens = get_tokens(source);
  let mut it = tokens.iter().peekable();

  assert_eq!(
    parse_il_expr(&mut it),
    Ok(Node::Lambda {
      params: Vec::new(),
      expr: Box::new(Node::Int(5)),
    })
  );
  assert_eq!(
    parse_il_expr(&mut it),
    Ok(Node::Lambda {
      params: vec![String::from("x")],
      expr: Box::new(Node::Int(5)),
    })
  );
  assert_eq!(
    parse_il_expr(&mut it),
    Ok(Node::Lambda {
      params: vec![String::from("x")],
      expr: Box::new(Node::Int(5)),
    })
  );
  assert_eq!(
    parse_il_expr(&mut it),
    Ok(Node::Lambda {
      params: vec![String::from("x"), String::from("y")],
      expr: Box::new(Node::Int(5)),
    })
  );
  assert_eq!(
    parse_un_expr(&mut it),
    Err(UnexpectedToken(lexer::Token::End))
  );
  it.next();
  assert_eq!(
    parse_un_expr(&mut it),
    Err(UnexpectedToken(lexer::Token::EOF))
  );
  it.next();
  assert_eq!(parse_un_expr(&mut it), Err(UnexpectedEOF));
}
<|endoftext|>


<commit_before>use crate::core::{Directed, Graph, Constrainer, ImplGraph, ImplGraphMut, GraphMut, RemoveVertex, AddEdge, EdgeWeighted, RemoveEdge};
use crate::core::constraint::{proxy_remove_edge_where, proxy_remove_vertex};
use crate::algo::DFS;

///
/// A marker trait for graphs that are unilaterally connected.
///
/// A graph is unilaterally connected if, for each pair of vertices, there exists at least 1 path
/// from one of them to the other. This is contrasted with strongly
/// connected graphs, where there must exist a path from either to the other (i.e. a path in each
/// direction).
///
/// The distinction between unilaterally and strongly connected only exists for directed graphs,
/// for undirected ones, they are equal. For this reason, the companion constrainer graph
/// `UnilateralGraph` only allows directed graphs. For undirected graph, simply use
/// `ConnectedGraph`.
///
/// For type safety reasons, the trait itself does not restrict directedness.
///
pub trait Unilateral: Graph
{}

#[derive(Clone, Debug)]
pub struct UnilateralGraph<C: Constrainer>(C)
	where C::Graph: Graph<Directedness=Directed>
;

impl<C: Constrainer> UnilateralGraph<C>
	where C::Graph: Graph<Directedness=Directed>
{
	///
	/// Creates a new unilaterally connected graph.
	/// The given graph *must* be unilaterally connected.
	/// This method does not check for this!!
	///
	pub fn new(c: C) -> Self
	{
		Self(c)
	}
}

impl<C: Constrainer> ImplGraph for UnilateralGraph<C>
	where C::Graph: Graph<Directedness=Directed>
{
	type Graph = Self;

	fn graph(&self) -> &Self::Graph {
		self
	}
}
impl<C: Constrainer> ImplGraphMut for UnilateralGraph<C>
	where C::Graph: Graph<Directedness=Directed>
{
	fn graph_mut(&mut self) -> &mut Self::Graph {
		self
	}
}
impl<C: Constrainer> Constrainer for UnilateralGraph<C>
	where C::Graph: Graph<Directedness=Directed>
{
	type Base = C::Base;
	type Constrained = C;

	fn constrain_single(c: Self::Constrained) -> Result<Self, ()>{
		// TODO: An efficient algorithm: https://stackoverflow.com/questions/30642383/determine-if-a-graph-is-semi-connected-or-not

		let graph = c.graph();

		let verts = graph.all_vertices().collect::<Vec<_>>();
		let mut iter = verts.iter();

		while let Some(&v1) = iter.next() {
			let iter_rest = iter.clone();
			for &v2 in iter_rest {
				if !DFS::new(graph, v1).any(|v| v == v2) && !DFS::new(graph, v2).any(|v| v == v1) {
					return Err(())
				}
			}
		}

		Ok(Self::new(c))
	}

	fn unconstrain_single(self) -> Self::Constrained{
		self.0
	}
}

impl<C: Constrainer> Graph for UnilateralGraph<C>
	where C::Graph: Graph<Directedness=Directed>
{
	type Vertex = <C::Graph as Graph>::Vertex;
	type VertexWeight = <C::Graph as Graph>::VertexWeight;
	type EdgeWeight = <C::Graph as Graph>::EdgeWeight;
	type Directedness = <C::Graph as Graph>::Directedness;

	fn all_vertices_weighted<'a>(&'a self) -> Box<dyn 'a + Iterator<Item=
	(Self::Vertex, &'a Self::VertexWeight)>>
	{
		self.0.graph().all_vertices_weighted()
	}

	fn all_edges<'a>(&'a self) -> Box<dyn 'a + Iterator<Item=
	(Self::Vertex, Self::Vertex, &'a Self::EdgeWeight)>>
	{
		self.0.graph().all_edges()
	}
}

impl<C: Constrainer + ImplGraphMut> GraphMut for UnilateralGraph<C>
	where C::Graph: GraphMut<Directedness=Directed>
{
	fn all_vertices_weighted_mut<'a>(&'a mut self) -> Box<dyn 'a + Iterator<Item=
	(Self::Vertex, &'a mut Self::VertexWeight)>>
	{
		self.0.graph_mut().all_vertices_weighted_mut()
	}

	fn all_edges_mut<'a>(&'a mut self) -> Box<dyn 'a + Iterator<Item=
	(Self::Vertex, Self::Vertex, &'a mut Self::EdgeWeight)>>
	{
		self.0.graph_mut().all_edges_mut()
	}

}

impl<C: Constrainer + ImplGraphMut> RemoveVertex for UnilateralGraph<C>
	where C::Graph: RemoveVertex<Directedness=Directed>
{
	fn remove_vertex(&mut self, v: Self::Vertex) -> Result<Self::VertexWeight, ()>
	{
		proxy_remove_vertex::<UnilateralGraph<_>,_>(self.0.graph_mut(), v)
	}
}

impl<C: Constrainer + ImplGraphMut> AddEdge for UnilateralGraph<C>
	where C::Graph: AddEdge<Directedness=Directed>
{
	fn add_edge_weighted<E>(&mut self, e: E) -> Result<(), ()>
		where E: EdgeWeighted<Self::Vertex, Self::EdgeWeight>
	{
		self.0.graph_mut().add_edge_weighted(e)
	}
}

impl<C: Constrainer + ImplGraphMut> RemoveEdge for UnilateralGraph<C>
	where C::Graph: RemoveEdge<Directedness=Directed>
{
	fn remove_edge_where<F>(&mut self, f: F)
		-> Result<(Self::Vertex, Self::Vertex, Self::EdgeWeight), ()>
		where F: Fn((Self::Vertex, Self::Vertex, &Self::EdgeWeight)) -> bool
	{
		proxy_remove_edge_where::<UnilateralGraph<_>,_,_>(self.0.graph_mut(), f)
	}
}

impl<C: Constrainer> Unilateral for UnilateralGraph<C>
	where C::Graph: Graph<Directedness=Directed>
{}

impl_constraints!{
	UnilateralGraph<C>: Unilateral
	where C::Graph: Graph<Directedness=Directed>
}

<commit_msg>Corrected use of new DFS design.<commit_after>use crate::core::{Directed, Graph, Constrainer, ImplGraph, ImplGraphMut, GraphMut, RemoveVertex, AddEdge, EdgeWeighted, RemoveEdge};
use crate::core::constraint::{proxy_remove_edge_where, proxy_remove_vertex};
use crate::algo::DFS;

///
/// A marker trait for graphs that are unilaterally connected.
///
/// A graph is unilaterally connected if, for each pair of vertices, there exists at least 1 path
/// from one of them to the other. This is contrasted with strongly
/// connected graphs, where there must exist a path from either to the other (i.e. a path in each
/// direction).
///
/// The distinction between unilaterally and strongly connected only exists for directed graphs,
/// for undirected ones, they are equal. For this reason, the companion constrainer graph
/// `UnilateralGraph` only allows directed graphs. For undirected graph, simply use
/// `ConnectedGraph`.
///
/// For type safety reasons, the trait itself does not restrict directedness.
///
pub trait Unilateral: Graph
{}

#[derive(Clone, Debug)]
pub struct UnilateralGraph<C: Constrainer>(C)
	where C::Graph: Graph<Directedness=Directed>
;

impl<C: Constrainer> UnilateralGraph<C>
	where C::Graph: Graph<Directedness=Directed>
{
	///
	/// Creates a new unilaterally connected graph.
	/// The given graph *must* be unilaterally connected.
	/// This method does not check for this!!
	///
	pub fn new(c: C) -> Self
	{
		Self(c)
	}
}

impl<C: Constrainer> ImplGraph for UnilateralGraph<C>
	where C::Graph: Graph<Directedness=Directed>
{
	type Graph = Self;

	fn graph(&self) -> &Self::Graph {
		self
	}
}
impl<C: Constrainer> ImplGraphMut for UnilateralGraph<C>
	where C::Graph: Graph<Directedness=Directed>
{
	fn graph_mut(&mut self) -> &mut Self::Graph {
		self
	}
}
impl<C: Constrainer> Constrainer for UnilateralGraph<C>
	where C::Graph: Graph<Directedness=Directed>
{
	type Base = C::Base;
	type Constrained = C;

	fn constrain_single(c: Self::Constrained) -> Result<Self, ()>{
		// TODO: An efficient algorithm: https://stackoverflow.com/questions/30642383/determine-if-a-graph-is-semi-connected-or-not

		let graph = c.graph();

		let verts = graph.all_vertices().collect::<Vec<_>>();
		let mut iter = verts.iter();

		while let Some(&v1) = iter.next() {
			let iter_rest = iter.clone();
			for &v2 in iter_rest {
				if !DFS::new(graph, v1, |_|{}).any(|v| v == v2) && !DFS::new(graph, v2, |_|{}).any(|v| v == v1) {
					return Err(())
				}
			}
		}

		Ok(Self::new(c))
	}

	fn unconstrain_single(self) -> Self::Constrained{
		self.0
	}
}

impl<C: Constrainer> Graph for UnilateralGraph<C>
	where C::Graph: Graph<Directedness=Directed>
{
	type Vertex = <C::Graph as Graph>::Vertex;
	type VertexWeight = <C::Graph as Graph>::VertexWeight;
	type EdgeWeight = <C::Graph as Graph>::EdgeWeight;
	type Directedness = <C::Graph as Graph>::Directedness;

	fn all_vertices_weighted<'a>(&'a self) -> Box<dyn 'a + Iterator<Item=
	(Self::Vertex, &'a Self::VertexWeight)>>
	{
		self.0.graph().all_vertices_weighted()
	}

	fn all_edges<'a>(&'a self) -> Box<dyn 'a + Iterator<Item=
	(Self::Vertex, Self::Vertex, &'a Self::EdgeWeight)>>
	{
		self.0.graph().all_edges()
	}
}

impl<C: Constrainer + ImplGraphMut> GraphMut for UnilateralGraph<C>
	where C::Graph: GraphMut<Directedness=Directed>
{
	fn all_vertices_weighted_mut<'a>(&'a mut self) -> Box<dyn 'a + Iterator<Item=
	(Self::Vertex, &'a mut Self::VertexWeight)>>
	{
		self.0.graph_mut().all_vertices_weighted_mut()
	}

	fn all_edges_mut<'a>(&'a mut self) -> Box<dyn 'a + Iterator<Item=
	(Self::Vertex, Self::Vertex, &'a mut Self::EdgeWeight)>>
	{
		self.0.graph_mut().all_edges_mut()
	}

}

impl<C: Constrainer + ImplGraphMut> RemoveVertex for UnilateralGraph<C>
	where C::Graph: RemoveVertex<Directedness=Directed>
{
	fn remove_vertex(&mut self, v: Self::Vertex) -> Result<Self::VertexWeight, ()>
	{
		proxy_remove_vertex::<UnilateralGraph<_>,_>(self.0.graph_mut(), v)
	}
}

impl<C: Constrainer + ImplGraphMut> AddEdge for UnilateralGraph<C>
	where C::Graph: AddEdge<Directedness=Directed>
{
	fn add_edge_weighted<E>(&mut self, e: E) -> Result<(), ()>
		where E: EdgeWeighted<Self::Vertex, Self::EdgeWeight>
	{
		self.0.graph_mut().add_edge_weighted(e)
	}
}

impl<C: Constrainer + ImplGraphMut> RemoveEdge for UnilateralGraph<C>
	where C::Graph: RemoveEdge<Directedness=Directed>
{
	fn remove_edge_where<F>(&mut self, f: F)
		-> Result<(Self::Vertex, Self::Vertex, Self::EdgeWeight), ()>
		where F: Fn((Self::Vertex, Self::Vertex, &Self::EdgeWeight)) -> bool
	{
		proxy_remove_edge_where::<UnilateralGraph<_>,_,_>(self.0.graph_mut(), f)
	}
}

impl<C: Constrainer> Unilateral for UnilateralGraph<C>
	where C::Graph: Graph<Directedness=Directed>
{}

impl_constraints!{
	UnilateralGraph<C>: Unilateral
	where C::Graph: Graph<Directedness=Directed>
}

<|endoftext|>


<commit_before>use orbclient::{Renderer, Color};
use orbimage;
use std::cell::{ Cell, RefCell };
use std::sync::Arc;

use cell::CheckSet;
use event::Event;
use point::Point;
use rect::Rect;
use theme::{ ITEM_BACKGROUND, WINDOW_BACKGROUND, ITEM_SELECTION };
use traits::{ Click, Place };
use widgets::Widget;
use std::ops::Index;

/// An entry in a list
/// Each entry stores widgets within.
pub struct Entry {
    pub height: Cell<u32>,
    click_callback: RefCell<Option<Arc<Fn(&Entry, Point)>>>,
    widgets: RefCell<Vec<Arc<Widget>>>,
    pub highlight: Cell<Color>,
    highlighted: Cell<bool>,
}

impl Entry {
    pub fn new(h: u32) -> Arc<Self> {
        Arc::new(Entry {
            height: Cell::new(h),
            click_callback: RefCell::new(None),
            widgets: RefCell::new(vec![]),
            highlight: Cell::new(ITEM_SELECTION),
            highlighted: Cell::new(false),
        })
    }

    /// Adds a widget to the entry
    pub fn add<T: Widget>(&self, widget: &Arc<T>) {
        let mut widgets = self.widgets.borrow_mut();
        widgets.push(widget.clone());
    }

    fn widgets(&self) -> &RefCell<Vec<Arc<Widget>>> {
        &self.widgets
    }
}

impl Click for Entry {
    fn emit_click(&self, point: Point) {
        if let Some(ref click_callback) = *self.click_callback.borrow() {
            click_callback(self, point);
        }
    }

    fn on_click<T: Fn(&Self, Point) + 'static>(&self, func: T) -> &Self {
        *self.click_callback.borrow_mut() = Some(Arc::new(func));
        self
    }
}

pub struct List {
    pub rect: Cell<Rect>,
    v_scroll: Cell<i32>,
    current_height: Cell<u32>,
    entries: RefCell<Vec<Arc<Entry>>>,
    pressed: Cell<bool>,
    selected: Cell<Option<u32>>,
}

impl List {
    pub fn new() -> Arc<Self> {
        Arc::new(List {
            rect: Cell::new(Rect::default()),
            v_scroll: Cell::new(0),
            current_height: Cell::new(0),
            entries: RefCell::new(vec![]),
            pressed: Cell::new(false),
            selected: Cell::new(None),
        })
    }

    pub fn push(&self, entry: &Arc<Entry>) {
        let h = entry.height.get();
        self.entries.borrow_mut().push(entry.clone());
        self.current_height.set(self.current_height.get() + h);
    }

    // Given absolute coordinates, returns the list entry index
    // drawn at that point.
    fn get_entry_index(&self, p: Point) -> Option<u32> {
        if self.rect.get().contains(p) {
            let mut current_y = 0;
            let x = self.rect.get().x;
            let y = self.rect.get().y;
            let width = self.rect.get().width;
            let scroll = self.v_scroll.get();

            for (i, entry) in self.entries.borrow().iter().enumerate() {
                if Rect::new(x, y+current_y-scroll, width, entry.height.get()).contains(p) {
                    return Some(i as u32)
                }
                current_y += entry.height.get() as i32
            }
        }

        None
    }

    pub fn scroll(&self, y: i32) {
        let mut set_to = self.v_scroll.get() - y * 48;
        if set_to < 0 {
            set_to = 0;
        } else if self.rect.get().height as i32 + set_to > self.current_height.get() as i32 {
            set_to = self.v_scroll.get() as i32;
        }
        self.v_scroll.set(set_to);
    }

    fn change_selection(&self, i: u32) {
        match self.selected.get() {
            Some(i) => {
                match self.entries.borrow().get(i as usize) {
                    Some(entry) => {
                        entry.highlighted.set(false);
                    },
                    None => {},
                }
            },
            _ => {},
        }

        if let Some(entry) = self.entries.borrow().get(i as usize) {
            entry.highlighted.set(true);
            self.selected.set(Some(i));

            let mut y = 0;

            for e in self.entries.borrow().index(0..(i as usize)) {
                y += e.height.get();
            }

            let v_scroll = self.v_scroll.get();

            if y < v_scroll as u32 {
                self.scroll(y as i32 - v_scroll);
            } else if (y + entry.height.get() as u32) > (v_scroll as u32 + self.rect.get().height) {
                self.scroll((y + entry.height.get()) as i32 - (v_scroll + self.rect.get().height as i32));
            }
        }
    }
}

impl Widget for List {
    fn rect(&self) -> &Cell<Rect> {
        &self.rect
    }

    fn draw(&self, renderer: &mut Renderer, _focused: bool) {
        let mut current_y = 0;
        let x = self.rect.get().x;
        let y = self.rect.get().y;
        let width = self.rect.get().width;
        let height = self.rect.get().height;

        let mut target = orbimage::Image::new(width, height);
        target.set(WINDOW_BACKGROUND);

        for entry in self.entries.borrow().iter() {
            let mut image = orbimage::Image::new(width, entry.height.get());

            if entry.highlighted.get() {
                image.set(entry.highlight.get());
            } else {
                image.set(ITEM_BACKGROUND);
            }

            for widget in entry.widgets().borrow().iter() {
                widget.draw(&mut image, false)
            }

            let image = image.data();
            target.image(x, current_y-self.v_scroll.get(), width, entry.height.get(), &image);

            current_y += entry.height.get() as i32
        }
        let target = target.data();
        renderer.image(x, y, width, height, &target)
    }

    fn event(&self, event: Event, focused: bool, redraw: &mut bool) -> bool {
        match event {
            Event::Mouse { point, left_button, .. } => {
                let mut click = false;

                let rect = self.rect.get();
                if rect.contains(point) {
                    if left_button {
                        if self.pressed.check_set(true) {
                            *redraw = true;
                        }
                    } else {
                        if self.pressed.check_set(false) {
                            click = true;
                            *redraw = true;
                        }
                    }
                } else {
                    if !left_button {
                        if self.pressed.check_set(false) {
                            *redraw = true;
                        }
                    }
                }

                if let Some(i) = self.get_entry_index(point) {
                    if click {
                        if let Some(entry) = self.entries.borrow().get(i as usize) {
                            entry.emit_click(point);
                        }
                    }

                    match self.selected.get() {
                        None => {
                            self.change_selection(i);
                            *redraw = true;
                        },
                        Some(selected) => {
                            if selected != i {
                                self.change_selection(i);
                                *redraw = true;
                            }
                        },
                    }
                }
            },
            Event::UpArrow => {
                match self.selected.get() {
                    None => {
                        self.change_selection(0);
                        *redraw = true;
                    },
                    Some(i) => {
                        if i > 0 {
                            self.change_selection(i - 1);
                            *redraw = true;
                        }
                    }
                }
            },
            Event::DownArrow => {
                match self.selected.get() {
                    None => {
                        self.change_selection(0);
                        *redraw = true;
                    },
                    Some(i) => {
                        if i < self.entries.borrow().len() as u32 - 1 {
                            self.change_selection(i + 1);
                            *redraw = true;
                        }
                    }
                }
            },
            Event::Home => {
                self.change_selection(0);
                *redraw = true
            },
            Event::End => {
                self.change_selection(self.entries.borrow().len() as u32 - 1);
                *redraw = true
            },
            Event::Enter => {
                match self.selected.get() {
                    Some(i) => {
                        match self.entries.borrow().get(i as usize) {
                            Some(entry) => {
                                entry.emit_click(Point { x: 0, y: 0});
                            },
                            None => {},
                        }
                    },
                    _ => {},
                }
            },
            Event::Scroll { y, .. } => {
                self.scroll(y * 2);
                *redraw = true;
            },
            _ => {}
        }
        focused
    }
}

impl Place for List {}

<commit_msg>fix List scrolling<commit_after>use orbclient::{Renderer, Color};
use orbimage;
use std::cell::{ Cell, RefCell };
use std::sync::Arc;

use cell::CheckSet;
use event::Event;
use point::Point;
use rect::Rect;
use theme::{ ITEM_BACKGROUND, WINDOW_BACKGROUND, ITEM_SELECTION };
use traits::{ Click, Place };
use widgets::Widget;
use std::ops::Index;

/// An entry in a list
/// Each entry stores widgets within.
pub struct Entry {
    pub height: Cell<u32>,
    click_callback: RefCell<Option<Arc<Fn(&Entry, Point)>>>,
    widgets: RefCell<Vec<Arc<Widget>>>,
    pub highlight: Cell<Color>,
    highlighted: Cell<bool>,
}

impl Entry {
    pub fn new(h: u32) -> Arc<Self> {
        Arc::new(Entry {
            height: Cell::new(h),
            click_callback: RefCell::new(None),
            widgets: RefCell::new(vec![]),
            highlight: Cell::new(ITEM_SELECTION),
            highlighted: Cell::new(false),
        })
    }

    /// Adds a widget to the entry
    pub fn add<T: Widget>(&self, widget: &Arc<T>) {
        let mut widgets = self.widgets.borrow_mut();
        widgets.push(widget.clone());
    }

    fn widgets(&self) -> &RefCell<Vec<Arc<Widget>>> {
        &self.widgets
    }
}

impl Click for Entry {
    fn emit_click(&self, point: Point) {
        if let Some(ref click_callback) = *self.click_callback.borrow() {
            click_callback(self, point);
        }
    }

    fn on_click<T: Fn(&Self, Point) + 'static>(&self, func: T) -> &Self {
        *self.click_callback.borrow_mut() = Some(Arc::new(func));
        self
    }
}

pub struct List {
    pub rect: Cell<Rect>,
    v_scroll: Cell<i32>,
    current_height: Cell<u32>,
    entries: RefCell<Vec<Arc<Entry>>>,
    pressed: Cell<bool>,
    selected: Cell<Option<u32>>,
}

impl List {
    pub fn new() -> Arc<Self> {
        Arc::new(List {
            rect: Cell::new(Rect::default()),
            v_scroll: Cell::new(0),
            current_height: Cell::new(0),
            entries: RefCell::new(vec![]),
            pressed: Cell::new(false),
            selected: Cell::new(None),
        })
    }

    pub fn push(&self, entry: &Arc<Entry>) {
        let h = entry.height.get();
        self.entries.borrow_mut().push(entry.clone());
        self.current_height.set(self.current_height.get() + h);
    }

    // Given absolute coordinates, returns the list entry index
    // drawn at that point.
    fn get_entry_index(&self, p: Point) -> Option<u32> {
        if self.rect.get().contains(p) {
            let mut current_y = 0;
            let x = self.rect.get().x;
            let y = self.rect.get().y;
            let width = self.rect.get().width;
            let scroll = self.v_scroll.get();

            for (i, entry) in self.entries.borrow().iter().enumerate() {
                if Rect::new(x, y+current_y-scroll, width, entry.height.get()).contains(p) {
                    return Some(i as u32)
                }
                current_y += entry.height.get() as i32
            }
        }

        None
    }

    pub fn scroll(&self, y: i32) {
        let mut set_to = self.v_scroll.get() + y;
        if set_to < 0 {
            set_to = 0;
        } else if self.rect.get().height as i32 + set_to > self.current_height.get() as i32 {
            set_to = self.v_scroll.get() as i32;
        }
        self.v_scroll.set(set_to);
    }

    fn change_selection(&self, i: u32) {
        match self.selected.get() {
            Some(i) => {
                match self.entries.borrow().get(i as usize) {
                    Some(entry) => {
                        entry.highlighted.set(false);
                    },
                    None => {},
                }
            },
            _ => {},
        }

        if let Some(entry) = self.entries.borrow().get(i as usize) {
            entry.highlighted.set(true);
            self.selected.set(Some(i));

            let mut y = 0;

            for e in self.entries.borrow().index(0..(i as usize)) {
                y += e.height.get();
            }

            let v_scroll = self.v_scroll.get();

            if y < v_scroll as u32 {
                self.scroll(y as i32 - v_scroll);
            } else if (y + entry.height.get() as u32) > (v_scroll as u32 + self.rect.get().height) {
                self.scroll((y + entry.height.get()) as i32 - (v_scroll + self.rect.get().height as i32));
            }
        }
    }
}

impl Widget for List {
    fn rect(&self) -> &Cell<Rect> {
        &self.rect
    }

    fn draw(&self, renderer: &mut Renderer, _focused: bool) {
        let mut current_y = 0;
        let x = self.rect.get().x;
        let y = self.rect.get().y;
        let width = self.rect.get().width;
        let height = self.rect.get().height;

        let mut target = orbimage::Image::new(width, height);
        target.set(WINDOW_BACKGROUND);

        for entry in self.entries.borrow().iter() {
            let mut image = orbimage::Image::new(width, entry.height.get());

            if entry.highlighted.get() {
                image.set(entry.highlight.get());
            } else {
                image.set(ITEM_BACKGROUND);
            }

            for widget in entry.widgets().borrow().iter() {
                widget.draw(&mut image, false)
            }

            let image = image.data();
            target.image(x, current_y-self.v_scroll.get(), width, entry.height.get(), &image);

            current_y += entry.height.get() as i32
        }
        let target = target.data();
        renderer.image(x, y, width, height, &target)
    }

    fn event(&self, event: Event, focused: bool, redraw: &mut bool) -> bool {
        match event {
            Event::Mouse { point, left_button, .. } => {
                let mut click = false;

                let rect = self.rect.get();
                if rect.contains(point) {
                    if left_button {
                        if self.pressed.check_set(true) {
                            *redraw = true;
                        }
                    } else {
                        if self.pressed.check_set(false) {
                            click = true;
                            *redraw = true;
                        }
                    }
                } else {
                    if !left_button {
                        if self.pressed.check_set(false) {
                            *redraw = true;
                        }
                    }
                }

                if let Some(i) = self.get_entry_index(point) {
                    if click {
                        if let Some(entry) = self.entries.borrow().get(i as usize) {
                            entry.emit_click(point);
                        }
                    }

                    match self.selected.get() {
                        None => {
                            self.change_selection(i);
                            *redraw = true;
                        },
                        Some(selected) => {
                            if selected != i {
                                self.change_selection(i);
                                *redraw = true;
                            }
                        },
                    }
                }
            },
            Event::UpArrow => {
                match self.selected.get() {
                    None => {
                        self.change_selection(0);
                        *redraw = true;
                    },
                    Some(i) => {
                        if i > 0 {
                            self.change_selection(i - 1);
                            *redraw = true;
                        }
                    }
                }
            },
            Event::DownArrow => {
                match self.selected.get() {
                    None => {
                        self.change_selection(0);
                        *redraw = true;
                    },
                    Some(i) => {
                        if i < self.entries.borrow().len() as u32 - 1 {
                            self.change_selection(i + 1);
                            *redraw = true;
                        }
                    }
                }
            },
            Event::Home => {
                self.change_selection(0);
                *redraw = true
            },
            Event::End => {
                self.change_selection(self.entries.borrow().len() as u32 - 1);
                *redraw = true
            },
            Event::Enter => {
                match self.selected.get() {
                    Some(i) => {
                        match self.entries.borrow().get(i as usize) {
                            Some(entry) => {
                                entry.emit_click(Point { x: 0, y: 0});
                            },
                            None => {},
                        }
                    },
                    _ => {},
                }
            },
            Event::Scroll { y, .. } => {
                self.scroll(y * -96);
                *redraw = true;
            },
            _ => {}
        }
        focused
    }
}

impl Place for List {}

<|endoftext|>


<commit_before>fn main() {
}
<commit_msg>translating program from string into Vec<char>. took me an hour hahah<commit_after>fn evaluate(program: Vec<char>) {
    for c in program {
        println!("{}", c);
    }
}

fn main() {
    let program: Vec<char> = "3 4 * 2 * 1 /".chars().filter(|&c| c != ' ').collect();

    evaluate(program);
}
<|endoftext|>


<commit_before>struct Stack {
    content: Vec<i32>,
    digits: Vec<i32>,
}

impl Stack {
    fn push(&mut self, d: i32) -> Result<i32, &str> {
        self.content.push(d);
        Ok(d)
    }

    fn pop(&mut self) -> Option<i32> {
        self.content.pop()
    }

    fn consume_digit(&mut self, d: i32) {
        self.digits.iter().position(|&i| i == d).expect("Cannot consume!");
    }

    fn valid_digit(&self, d: i32) -> bool {
        self.digits.contains(&d)
    }

    fn add_digit(&mut self, c: char) -> Result<i32, &str> {
        match c.to_digit(10) {
            Some(n) => match self.valid_digit(n as i32) {
                true => {
                    self.consume_digit(n as i32);
                    self.push(n as i32)
                },
                false => Err("Invalid or duplicate digit!"),
            },
            None => Err("Invalid character"),
        }
    }

    fn apply<F>(&mut self, f: F) -> Result<i32, &str>
        where F : Fn(i32, i32) -> i32 {

        let r = self.pop();
        let l = self.pop();

        match l {
            Some(n) => match r {
                Some(i) => self.push(f(n, i)),
                None => Err("Stack empty"),
            },
            None => Err("Stack empty"),
        }
    }
}

fn evaluate<'a>(program: Vec<char>, digits: Vec<i32>) -> Result<i32, &'a str> {
    let mut stack = Stack {
        content: vec![],
        digits: digits,
    };

    for c in program {
        let answer: Result<i32, &str> = match c {
            '*' => stack.apply(|l, r| l * r),
            '+' => stack.apply(|l, r| l + r),
            '-' => stack.apply(|l, r| l - r),
            '/' => stack.apply(|l, r| l / r),
            _   => stack.add_digit(c),
        };

        if answer.is_err() {
            // TODO: Fix this. Work out how to return "answer" without compiler error.
            // return answer;
            println!("Actual: {}", answer.unwrap_err());
            return Err("Program error");
        }
    }

    match stack.content.len() {
        1 => Ok(stack.content[0]),
        _ => Err("Invalid formula"),
    }
}

fn main() {
    let program: Vec<char> = "3 4 * 2 * 1 /".chars().filter(|&c| c != ' ').collect();
    let digits: Vec<i32> = vec![2, 3, 1, 4];

    match evaluate(program, digits) {
        Ok(n) => match n {
            24 => println!("Well done!"),
            _  => println!("Nice try, but {} is not 24!", n),
        },
        Err(s) => {
            println!("Oops: {}", s);
        },
    }
}
<commit_msg>Actually consuming digits now<commit_after>struct Stack {
    content: Vec<i32>,
    digits: Vec<i32>,
}

impl Stack {
    fn push(&mut self, d: i32) -> Result<i32, &str> {
        self.content.push(d);
        Ok(d)
    }

    fn pop(&mut self) -> Option<i32> {
        self.content.pop()
    }

    fn consume_digit(&mut self, d: i32) {
        let i = self.digits.iter().position(|&i| i == d).expect("Cannot consume!");
        self.digits.remove(i);
    }

    fn valid_digit(&self, d: i32) -> bool {
        self.digits.contains(&d)
    }

    fn add_digit(&mut self, c: char) -> Result<i32, &str> {
        match c.to_digit(10) {
            Some(n) => match self.valid_digit(n as i32) {
                true => {
                    self.consume_digit(n as i32);
                    self.push(n as i32)
                },
                false => Err("Invalid or duplicate digit!"),
            },
            None => Err("Invalid character"),
        }
    }

    fn apply<F>(&mut self, f: F) -> Result<i32, &str>
        where F : Fn(i32, i32) -> i32 {

        let r = self.pop();
        let l = self.pop();

        match l {
            Some(n) => match r {
                Some(i) => self.push(f(n, i)),
                None => Err("Stack empty"),
            },
            None => Err("Stack empty"),
        }
    }
}

fn evaluate<'a>(program: Vec<char>, digits: Vec<i32>) -> Result<i32, &'a str> {
    let mut stack = Stack {
        content: vec![],
        digits: digits,
    };

    for c in program {
        let answer: Result<i32, &str> = match c {
            '*' => stack.apply(|l, r| l * r),
            '+' => stack.apply(|l, r| l + r),
            '-' => stack.apply(|l, r| l - r),
            '/' => stack.apply(|l, r| l / r),
            _ => stack.add_digit(c),
        };

        if answer.is_err() {
            // TODO: Fix this. Work out how to return "answer" without compiler error.
            println!("Actual: {}", answer.unwrap_err());
            return Err("Program error");
        }
    }

    match stack.content.len() {
        1 => Ok(stack.content[0]),
        _ => Err("Invalid formula"),
    }
}

fn main() {
    let program: Vec<char> = "3 2 * 4 * 1 /".chars().filter(|&c| c != ' ').collect();
    let goal: i32 = 24;
    let digits: Vec<i32> = vec![2, 3, 1, 4];

    match evaluate(program, digits) {
        Ok(n) => if n == goal {
            println!("Well done!");
        } else {
            println!("Nice try, but {} is not {}!", n, goal);
        },
        Err(s) => {
            println!("Oops: {}", s);
        },
    }
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::path::Path;
use std::io::prelude::*;
use pest::prelude::*;
use std::collections::VecDeque;

#[derive(Debug)]
pub struct Variable<'a> {
    pub name: &'a str,
    pub vtype: &'a str,
}

#[derive(Debug)]
pub struct Function<'a> {
    pub name: &'a str,
    pub function_args: Vec<Variable<'a>>,
    pub return_val: Option<&'a str>,
    pub callback: bool,
}

#[derive(Debug)]
pub enum StructEntry<'a> {
    Var(Variable<'a>),
    Function(Function<'a>),
}

#[derive(Debug)]
pub struct Struct<'a> {
    pub name: &'a str,
    pub inherit: Option<&'a str>,
    pub entries: Vec<StructEntry<'a>>,
}

#[derive(Debug)]
pub struct ApiDef<'a> {
    pub text: String,
    pub entries: Vec<Struct<'a>>,
}

impl_rdp! {
    grammar! {
        chunk = _{ soi ~ structdef* ~ eoi }

        structdef   =  { name ~ derive? ~ ["{"] ~ fieldlist? ~ ["}"] }
        fieldlist   =  { field ~ (fieldsep ~ field)* ~ fieldsep* }
        field       =  { var | function }
        fieldsep    = _{ [","] }

        rettype     = { name }
        derive      = { [":"] ~ name }
        callback    = { ["[callback]"] }
        retexp      = { ["->"] ~ name }
        var         = { name ~ name }
        varlist     = { var ~ ([","] ~ var)* }
        function    = { callback? ~ name ~ ["("] ~ varlist? ~ [")"] ~ retexp? }

        name = @{
            (['a'..'z'] | ['A'..'Z'] | ["_"]) ~ (['a'..'z'] | ['A'..'Z'] | ["_"] | ['0'..'9'])*
        }

       comment = _{
            ["//"] ~ (!(["\r"] | ["\n"]) ~ any)* ~ (["\n"] | ["\r\n"] | ["\r"] | eoi)
        }

        whitespace = _{ [" "] | ["\t"] | ["\u{000C}"] | ["\r"] | ["\n"] }
    }

    process! {
        process(&self) -> Vec<Struct<'input>> {
            (structs: _chunk()) => {
                structs.into_iter().collect::<Vec<_>>()
            },
        }

        _chunk(&self) -> VecDeque<Struct<'input>> {
            (_: structdef, sdef: _structdef(), mut tail: _chunk()) => {
                tail.push_front(sdef);
                tail
            },

            () => VecDeque::new(),
        }

        _structdef(&self) -> Struct<'input> {
            (&name: name, inherit: _derive(), list: _fieldentries()) => {
                Struct {
                    name: name,
                    inherit: inherit,
                    entries: list.into_iter().collect::<Vec<_>>(),
                }
            },
        }

        _derive(&self) -> Option<&'input str> {
            (_: derive, &name: name) => Some(name),
            () => None,
        }

        _fieldentries(&self) -> VecDeque<StructEntry<'input>> {
            (_: field, entry: _fieldentry(), mut tail: _fieldentries()) => {
                tail.push_front(entry);
                tail
            },

            (_: fieldlist, entries: _fieldentries()) => entries,
            () => VecDeque::new(),
        }

        _fieldentry(&self) -> StructEntry<'input> {
            (_: function, func: _funcentry()) => func,

            (_: var, &vtype: name, &name: name) => {
                StructEntry::Var(Variable {
                    name: name,
                    vtype: vtype,
                })
            },
        }

        _funcentry(&self) -> StructEntry<'input> {
            (callback: _callback(), &name: name, func_args: _func_args_list(), ret_value: _returnvalue()) => {
                StructEntry::Function(Function {
                    name: name,
                    function_args: func_args.into_iter().collect::<Vec<_>>(),
                    return_val: ret_value,
                    callback: callback,
                })
            }
        }

        _callback(&self) -> bool {
            (_: callback) => true,
            () => false,
        }

        _returnvalue(&self) -> Option<&'input str> {
            (_: retexp, &name: name) => Some(name),
            () => None,
        }

        _func_args_list(&self) -> VecDeque<Variable<'input>> {
            (_: var, &name: name, &atype: name, mut tail: _func_args_list()) => {
                tail.push_front(Variable {
                    name: name,
                    vtype: atype,
                });

                tail
            },

            (_: varlist, tail: _func_args_list()) => tail,
            () => VecDeque::new(),
        }
    }
}

impl<'a> ApiDef<'a> {
    pub fn parse_file<P: AsRef<Path>>(&'a mut self, path: P) {
        let mut file = File::open(path).unwrap();
        file.read_to_string(&mut self.text).unwrap();

        let mut parser = Rdp::new(StringInput::new(&self.text));

        parser.chunk();

        if !parser.end() {
            let expected = parser.expected();
            panic!("Failed to parse {:?} - {}", parser.expected(), &self.text[expected.1..]);
        }

        self.entries = parser.process();

        println!("API {:?}", self.entries);
    }
}
<commit_msg>Switched to owned data<commit_after>use std::fs::File;
use std::path::Path;
use std::io::prelude::*;
use pest::prelude::*;
use std::collections::VecDeque;

#[derive(Debug)]
pub struct Variable {
    pub name: String,
    pub vtype: String,
}

#[derive(Debug)]
pub struct Function {
    pub name: String,
    pub function_args: Vec<Variable>,
    pub return_val: Option<String>,
    pub callback: bool,
}

#[derive(Debug)]
pub enum StructEntry {
    Var(Variable),
    Function(Function),
}

#[derive(Debug)]
pub struct Struct {
    pub name: String,
    pub inherit: Option<String>,
    pub entries: Vec<StructEntry>,
}

#[derive(Debug)]
pub struct ApiDef {
    pub entries: Vec<Struct>,
}

impl_rdp! {
    grammar! {
        chunk = _{ soi ~ structdef* ~ eoi }

        structdef   =  { name ~ derive? ~ ["{"] ~ fieldlist? ~ ["}"] }
        fieldlist   =  { field ~ (fieldsep ~ field)* ~ fieldsep* }
        field       =  { var | function }
        fieldsep    = _{ [","] }

        rettype     = { name }
        derive      = { [":"] ~ name }
        callback    = { ["[callback]"] }
        retexp      = { ["->"] ~ name }
        var         = { name ~ name }
        varlist     = { var ~ ([","] ~ var)* }
        function    = { callback? ~ name ~ ["("] ~ varlist? ~ [")"] ~ retexp? }

        name = @{
            (['a'..'z'] | ['A'..'Z'] | ["_"]) ~ (['a'..'z'] | ['A'..'Z'] | ["_"] | ['0'..'9'])*
        }

       comment = _{
            ["//"] ~ (!(["\r"] | ["\n"]) ~ any)* ~ (["\n"] | ["\r\n"] | ["\r"] | eoi)
        }

        whitespace = _{ [" "] | ["\t"] | ["\u{000C}"] | ["\r"] | ["\n"] }
    }

    process! {
        process(&self) -> Vec<Struct> {
            (structs: _chunk()) => {
                structs.into_iter().collect::<Vec<_>>()
            },
        }

        _chunk(&self) -> VecDeque<Struct> {
            (_: structdef, sdef: _structdef(), mut tail: _chunk()) => {
                tail.push_front(sdef);
                tail
            },

            () => VecDeque::new(),
        }

        _structdef(&self) -> Struct {
            (&name: name, inherit: _derive(), list: _fieldentries()) => {
                Struct {
                    name: name.to_owned(),
                    inherit: inherit,
                    entries: list.into_iter().collect::<Vec<_>>(),
                }
            },
        }

        _derive(&self) -> Option<String> {
            (_: derive, &name: name) => Some(name.to_owned()),
            () => None,
        }

        _fieldentries(&self) -> VecDeque<StructEntry> {
            (_: field, entry: _fieldentry(), mut tail: _fieldentries()) => {
                tail.push_front(entry);
                tail
            },

            (_: fieldlist, entries: _fieldentries()) => entries,
            () => VecDeque::new(),
        }

        _fieldentry(&self) -> StructEntry {
            (_: function, func: _funcentry()) => func,

            (_: var, &vtype: name, &name: name) => {
                StructEntry::Var(Variable {
                    name: name.to_owned(),
                    vtype: vtype.to_owned(),
                })
            },
        }

        _funcentry(&self) -> StructEntry {
            (callback: _callback(), &name: name, func_args: _func_args_list(), ret_value: _returnvalue()) => {
                StructEntry::Function(Function {
                    name: name.to_owned(),
                    function_args: func_args.into_iter().collect::<Vec<_>>(),
                    return_val: ret_value,
                    callback: callback,
                })
            }
        }

        _callback(&self) -> bool {
            (_: callback) => true,
            () => false,
        }

        _returnvalue(&self) -> Option<String> {
            (_: retexp, &name: name) => Some(name.to_owned()),
            () => None,
        }

        _func_args_list(&self) -> VecDeque<Variable> {
            (_: var, &name: name, &atype: name, mut tail: _func_args_list()) => {
                tail.push_front(Variable {
                    name: name.to_owned(),
                    vtype: atype.to_owned(),
                });

                tail
            },

            (_: varlist, tail: _func_args_list()) => tail,
            () => VecDeque::new(),
        }
    }
}

impl ApiDef {
    pub fn new<P: AsRef<Path>>(path: P) -> ApiDef {
        let mut text = String::new();

        let mut file = File::open(path).unwrap();
        file.read_to_string(&mut text).unwrap();

        let mut parser = Rdp::new(StringInput::new(&text));

        parser.chunk();

        if !parser.end() {
            let expected = parser.expected();
            panic!("Failed to parse file - {:?} - {}", parser.expected(), &text[expected.1..]);
        }

        ApiDef {
            entries: parser.process(),
        }
    }
}
<|endoftext|>


<commit_before>#![deny(unused_import_braces, unused_imports,
        unused_comparisons, unused_must_use,
        unused_variables, non_shorthand_field_patterns,
        unreachable_code)]

extern crate trie;
extern crate sputnikvm;
extern crate sha3;
extern crate block;
extern crate rlp;
extern crate bigint;

use bigint::{H256, U256, M256, Address};
use sputnikvm::{ValidTransaction, HeaderParams, Memory, TransactionVM, VM,
                AccountCommitment, Patch, AccountState, AccountChange};
use sputnikvm::errors::{PreExecutionError, RequireError};
use sha3::{Keccak256, Digest};
use trie::{FixedSecureTrie, DatabaseGuard, MemoryDatabase, Database, DatabaseOwned};
use block::{Account, Transaction};
use std::collections::HashMap;
use std::cmp::min;

pub struct Stateful<'a, D: 'a> {
    database: &'a D,
    root: H256,
}

impl<'a, D> Stateful<'a, D> {
    pub fn new(database: &'a D, root: H256) -> Self {
        Self {
            database,
            root
        }
    }

    pub fn empty(database: &'a D) -> Self {
        Self::new(database, MemoryDatabase::new().create_empty().root())
    }
}

impl<'b, D: DatabaseOwned> Stateful<'b, D> {
    fn is_empty_hash(hash: H256) -> bool {
        hash == H256::from(Keccak256::digest(&[]).as_slice())
    }

    pub fn code(&self, hash: H256) -> Option<Vec<u8>> {
        let code_hashes = self.database.create_guard();

        if Self::is_empty_hash(hash) {
            Some(Vec::new())
        } else {
            code_hashes.get(hash)
        }
    }

    pub fn call<M: Memory + Default, P: Patch>(
        &self, transaction: ValidTransaction, block: HeaderParams,
        most_recent_block_hashes: &[H256]
    ) -> TransactionVM<M, P> {
        assert!(U256::from(most_recent_block_hashes.len()) >=
                min(block.number, U256::from(256)));

        let mut vm = TransactionVM::new(transaction, block.clone());
        let state = self.database.create_fixed_secure_trie(self.root);
        let code_hashes = self.database.create_guard();

        loop {
            match vm.fire() {
                Ok(()) => break,
                Err(RequireError::Account(address)) => {
                    let account: Option<Account> = state.get(&address);

                    match account {
                        Some(account) => {
                            let code = if Self::is_empty_hash(account.code_hash) {
                                Vec::new()
                            } else {
                                code_hashes.get(account.code_hash).unwrap()
                            };

                            vm.commit_account(AccountCommitment::Full {
                                nonce: account.nonce,
                                address: address,
                                balance: account.balance,
                                code: code,
                            }).unwrap();
                        },
                        None => {
                            vm.commit_account(AccountCommitment::Nonexist(address)).unwrap();
                        },
                    }
                },
                Err(RequireError::AccountCode(address)) => {
                    let account: Option<Account> = state.get(&address);

                    match account {
                        Some(account) => {
                            let code = if Self::is_empty_hash(account.code_hash) {
                                Vec::new()
                            } else {
                                code_hashes.get(account.code_hash).unwrap()
                            };

                            vm.commit_account(AccountCommitment::Code {
                                address: address,
                                code: code,
                            }).unwrap();
                        },
                        None => {
                            vm.commit_account(AccountCommitment::Nonexist(address)).unwrap();
                        },
                    }
                },
                Err(RequireError::AccountStorage(address, index)) => {
                    let account: Option<Account> = state.get(&address);

                    match account {
                        Some(account) => {
                            let storage = self.database.create_fixed_secure_trie(account.storage_root);
                            let value = storage.get(&H256::from(index)).unwrap_or(M256::zero());

                            vm.commit_account(AccountCommitment::Storage {
                                address: address,
                                index, value
                            }).unwrap();
                        },
                        None => {
                            vm.commit_account(AccountCommitment::Nonexist(address)).unwrap();
                        },
                    }
                },
                Err(RequireError::Blockhash(number)) => {
                    let index = (block.number - number).as_usize();
                    vm.commit_blockhash(number, most_recent_block_hashes[index]).unwrap();
                },
            }
        }

        vm
    }

    pub fn transit(
        &mut self, accounts: &[AccountChange]
    ) {
        let mut state = self.database.create_fixed_secure_trie(self.root);
        let mut code_hashes = self.database.create_guard();

        for account in accounts {
            match account.clone() {
                AccountChange::Full {
                    nonce, address, balance, changing_storage, code
                } => {
                    let changing_storage: HashMap<U256, M256> = changing_storage.into();

                    let mut account: Account = state.get(&address).unwrap();

                    let mut storage_trie = self.database.create_fixed_secure_trie(account.storage_root);
                    for (key, value) in changing_storage {
                        if value == M256::zero() {
                            storage_trie.remove(&H256::from(key));
                        } else {
                            storage_trie.insert(H256::from(key), value);
                        }
                    }

                    account.balance = balance;
                    account.nonce = nonce;
                    account.storage_root = storage_trie.root();
                    assert!(account.code_hash == H256::from(Keccak256::digest(&code).as_slice()));

                    state.insert(address, account);
                },
                AccountChange::IncreaseBalance(address, value) => {
                    match state.get(&address) {
                        Some(mut account) => {
                            account.balance = account.balance + value;
                            state.insert(address, account);
                        },
                        None => {
                            let account = Account {
                                nonce: U256::zero(),
                                balance: value,
                                storage_root: self.database.create_empty().root(),
                                code_hash: H256::from(Keccak256::digest(&[]).as_slice())
                            };
                            state.insert(address, account);
                        }
                    }
                },
                AccountChange::DecreaseBalance(address, value) => {
                    let mut account: Account = state.get(&address).unwrap();

                    account.balance = account.balance - value;

                    state.insert(address, account);
                },
                AccountChange::Create {
                    nonce, address, balance, storage, code, exists
                } => {
                    if !exists {
                        state.remove(&address);
                    } else {
                        let storage: HashMap<U256, M256> = storage.into();

                        let mut storage_trie = self.database.create_fixed_secure_empty();
                        for (key, value) in storage {
                            if value == M256::zero() {
                                storage_trie.remove(&H256::from(key));
                            } else {
                                storage_trie.insert(H256::from(key), value);
                            }
                        }

                        let code_hash = H256::from(Keccak256::digest(&code).as_slice());
                        code_hashes.set(code_hash, code);

                        let account = Account {
                            nonce: nonce,
                            balance: balance,
                            storage_root: storage_trie.root(),
                            code_hash
                        };

                        state.insert(address, account);
                    }
                },
            }
        }

        self.root = state.root();
    }

    pub fn execute<M: Memory + Default, P: Patch>(
        &mut self, transaction: ValidTransaction, block: HeaderParams,
        most_recent_block_hashes: &[H256]
    ) -> TransactionVM<M, P> {
        let vm = self.call::<_, P>(transaction, block, most_recent_block_hashes);
        let mut accounts = Vec::new();
        for account in vm.accounts() {
            accounts.push(account.clone());
        }
        self.transit(&accounts);
        vm
    }

    pub fn to_valid<P: Patch>(
        &self, transaction: Transaction,
    ) -> Result<ValidTransaction, PreExecutionError> {
        let state = self.database.create_fixed_secure_trie(self.root);
        let code_hashes = self.database.create_guard();
        let mut account_state = AccountState::default();

        loop {
            match ValidTransaction::from_transaction::<P>(&transaction, &account_state) {
                Ok(val) => return val,
                Err(RequireError::Account(address)) => {
                    let account: Option<Account> = state.get(&address);

                    match account {
                        Some(account) => {
                            let code = if Self::is_empty_hash(account.code_hash) {
                                Vec::new()
                            } else {
                                code_hashes.get(account.code_hash).unwrap()
                            };

                            account_state.commit(AccountCommitment::Full {
                                nonce: account.nonce,
                                address: address,
                                balance: account.balance,
                                code: code,
                            }).unwrap();
                        },
                        None => {
                            account_state.commit(AccountCommitment::Nonexist(address)).unwrap();
                        },
                    }
                },
                Err(RequireError::AccountCode(address)) => {
                    let account: Option<Account> = state.get(&address);

                    match account {
                        Some(account) => {
                            let code = if Self::is_empty_hash(account.code_hash) {
                                Vec::new()
                            } else {
                                code_hashes.get(account.code_hash).unwrap()
                            };

                            account_state.commit(AccountCommitment::Code {
                                address: address,
                                code: code,
                            }).unwrap();
                        },
                        None => {
                            account_state.commit(AccountCommitment::Nonexist(address)).unwrap();
                        },
                    }
                },
                Err(RequireError::AccountStorage(address, index)) => {
                    let account: Option<Account> = state.get(&address);

                    match account {
                        Some(account) => {
                            let storage = self.database.create_fixed_secure_trie(account.storage_root);
                            let value = storage.get(&H256::from(index)).unwrap_or(M256::zero());

                            account_state.commit(AccountCommitment::Storage {
                                address: address,
                                index, value
                            }).unwrap();
                        },
                        None => {
                            account_state.commit(AccountCommitment::Nonexist(address)).unwrap();
                        },
                    }
                },
                Err(RequireError::Blockhash(_)) => {
                    panic!()
                },
            }
        }
    }

    pub fn root(&self) -> H256 {
        self.root
    }

    pub fn state_of<'a>(&'a self, root: H256) -> FixedSecureTrie<<D as Database<'a>>::Guard, Address, Account> {
        self.database.create_fixed_secure_trie::<Address, Account>(root)
    }

    pub fn state<'a>(&'a self) -> FixedSecureTrie<<D as Database<'a>>::Guard, Address, Account> {
        self.state_of(self.root())
    }

    pub fn storage_state_of<'a>(&'a self, root: H256) -> FixedSecureTrie<<D as Database<'a>>::Guard, H256, M256> {
        self.database.create_fixed_secure_trie::<H256, M256>(root)
    }

    pub fn storage_state<'a>(&'a self, address: Address) -> Option<FixedSecureTrie<<D as Database<'a>>::Guard, H256, M256>> {
        let state = self.state();
        let account = state.get(&address);

        match account {
            Some(account) => {
                Some(self.storage_state_of(account.storage_root))
            },
            None => None,
        }
    }
}

pub type MemoryStateful<'a> = Stateful<'a, MemoryDatabase>;
<commit_msg>Stateful::step which increment the VM by one step<commit_after>#![deny(unused_import_braces, unused_imports,
        unused_comparisons, unused_must_use,
        unused_variables, non_shorthand_field_patterns,
        unreachable_code)]

extern crate trie;
extern crate sputnikvm;
extern crate sha3;
extern crate block;
extern crate rlp;
extern crate bigint;

use bigint::{H256, U256, M256, Address};
use sputnikvm::{ValidTransaction, HeaderParams, Memory, TransactionVM, VM,
                AccountCommitment, Patch, AccountState, AccountChange};
use sputnikvm::errors::{PreExecutionError, RequireError};
use sha3::{Keccak256, Digest};
use trie::{FixedSecureTrie, DatabaseGuard, MemoryDatabase, Database, DatabaseOwned};
use block::{Account, Transaction};
use std::collections::HashMap;
use std::cmp::min;

pub struct Stateful<'a, D: 'a> {
    database: &'a D,
    root: H256,
}

impl<'a, D> Stateful<'a, D> {
    pub fn new(database: &'a D, root: H256) -> Self {
        Self {
            database,
            root
        }
    }

    pub fn empty(database: &'a D) -> Self {
        Self::new(database, MemoryDatabase::new().create_empty().root())
    }
}

impl<'b, D: DatabaseOwned> Stateful<'b, D> {
    fn is_empty_hash(hash: H256) -> bool {
        hash == H256::from(Keccak256::digest(&[]).as_slice())
    }

    pub fn code(&self, hash: H256) -> Option<Vec<u8>> {
        let code_hashes = self.database.create_guard();

        if Self::is_empty_hash(hash) {
            Some(Vec::new())
        } else {
            code_hashes.get(hash)
        }
    }

    pub fn step<V: VM>(
        &self, vm: &mut V, block_number: U256, most_recent_block_hashes: &[H256]
    ) {
        assert!(U256::from(most_recent_block_hashes.len()) >=
                min(block_number, U256::from(256)));

        let state = self.database.create_fixed_secure_trie(self.root);
        let code_hashes = self.database.create_guard();

        loop {
            match vm.step() {
                Ok(()) => break,
                Err(RequireError::Account(address)) => {
                    let account: Option<Account> = state.get(&address);

                    match account {
                        Some(account) => {
                            let code = if Self::is_empty_hash(account.code_hash) {
                                Vec::new()
                            } else {
                                code_hashes.get(account.code_hash).unwrap()
                            };

                            vm.commit_account(AccountCommitment::Full {
                                nonce: account.nonce,
                                address: address,
                                balance: account.balance,
                                code: code,
                            }).unwrap();
                        },
                        None => {
                            vm.commit_account(AccountCommitment::Nonexist(address)).unwrap();
                        },
                    }
                },
                Err(RequireError::AccountCode(address)) => {
                    let account: Option<Account> = state.get(&address);

                    match account {
                        Some(account) => {
                            let code = if Self::is_empty_hash(account.code_hash) {
                                Vec::new()
                            } else {
                                code_hashes.get(account.code_hash).unwrap()
                            };

                            vm.commit_account(AccountCommitment::Code {
                                address: address,
                                code: code,
                            }).unwrap();
                        },
                        None => {
                            vm.commit_account(AccountCommitment::Nonexist(address)).unwrap();
                        },
                    }
                },
                Err(RequireError::AccountStorage(address, index)) => {
                    let account: Option<Account> = state.get(&address);

                    match account {
                        Some(account) => {
                            let storage = self.database.create_fixed_secure_trie(account.storage_root);
                            let value = storage.get(&H256::from(index)).unwrap_or(M256::zero());

                            vm.commit_account(AccountCommitment::Storage {
                                address: address,
                                index, value
                            }).unwrap();
                        },
                        None => {
                            vm.commit_account(AccountCommitment::Nonexist(address)).unwrap();
                        },
                    }
                },
                Err(RequireError::Blockhash(number)) => {
                    let index = (block_number - number).as_usize();
                    vm.commit_blockhash(number, most_recent_block_hashes[index]).unwrap();
                },
            }
        }
    }

    pub fn call<M: Memory + Default, P: Patch>(
        &self, transaction: ValidTransaction, block: HeaderParams,
        most_recent_block_hashes: &[H256]
    ) -> TransactionVM<M, P> {
        assert!(U256::from(most_recent_block_hashes.len()) >=
                min(block.number, U256::from(256)));

        let mut vm = TransactionVM::new(transaction, block.clone());
        let state = self.database.create_fixed_secure_trie(self.root);
        let code_hashes = self.database.create_guard();

        loop {
            match vm.fire() {
                Ok(()) => break,
                Err(RequireError::Account(address)) => {
                    let account: Option<Account> = state.get(&address);

                    match account {
                        Some(account) => {
                            let code = if Self::is_empty_hash(account.code_hash) {
                                Vec::new()
                            } else {
                                code_hashes.get(account.code_hash).unwrap()
                            };

                            vm.commit_account(AccountCommitment::Full {
                                nonce: account.nonce,
                                address: address,
                                balance: account.balance,
                                code: code,
                            }).unwrap();
                        },
                        None => {
                            vm.commit_account(AccountCommitment::Nonexist(address)).unwrap();
                        },
                    }
                },
                Err(RequireError::AccountCode(address)) => {
                    let account: Option<Account> = state.get(&address);

                    match account {
                        Some(account) => {
                            let code = if Self::is_empty_hash(account.code_hash) {
                                Vec::new()
                            } else {
                                code_hashes.get(account.code_hash).unwrap()
                            };

                            vm.commit_account(AccountCommitment::Code {
                                address: address,
                                code: code,
                            }).unwrap();
                        },
                        None => {
                            vm.commit_account(AccountCommitment::Nonexist(address)).unwrap();
                        },
                    }
                },
                Err(RequireError::AccountStorage(address, index)) => {
                    let account: Option<Account> = state.get(&address);

                    match account {
                        Some(account) => {
                            let storage = self.database.create_fixed_secure_trie(account.storage_root);
                            let value = storage.get(&H256::from(index)).unwrap_or(M256::zero());

                            vm.commit_account(AccountCommitment::Storage {
                                address: address,
                                index, value
                            }).unwrap();
                        },
                        None => {
                            vm.commit_account(AccountCommitment::Nonexist(address)).unwrap();
                        },
                    }
                },
                Err(RequireError::Blockhash(number)) => {
                    let index = (block.number - number).as_usize();
                    vm.commit_blockhash(number, most_recent_block_hashes[index]).unwrap();
                },
            }
        }

        vm
    }

    pub fn transit(
        &mut self, accounts: &[AccountChange]
    ) {
        let mut state = self.database.create_fixed_secure_trie(self.root);
        let mut code_hashes = self.database.create_guard();

        for account in accounts {
            match account.clone() {
                AccountChange::Full {
                    nonce, address, balance, changing_storage, code
                } => {
                    let changing_storage: HashMap<U256, M256> = changing_storage.into();

                    let mut account: Account = state.get(&address).unwrap();

                    let mut storage_trie = self.database.create_fixed_secure_trie(account.storage_root);
                    for (key, value) in changing_storage {
                        if value == M256::zero() {
                            storage_trie.remove(&H256::from(key));
                        } else {
                            storage_trie.insert(H256::from(key), value);
                        }
                    }

                    account.balance = balance;
                    account.nonce = nonce;
                    account.storage_root = storage_trie.root();
                    assert!(account.code_hash == H256::from(Keccak256::digest(&code).as_slice()));

                    state.insert(address, account);
                },
                AccountChange::IncreaseBalance(address, value) => {
                    match state.get(&address) {
                        Some(mut account) => {
                            account.balance = account.balance + value;
                            state.insert(address, account);
                        },
                        None => {
                            let account = Account {
                                nonce: U256::zero(),
                                balance: value,
                                storage_root: self.database.create_empty().root(),
                                code_hash: H256::from(Keccak256::digest(&[]).as_slice())
                            };
                            state.insert(address, account);
                        }
                    }
                },
                AccountChange::DecreaseBalance(address, value) => {
                    let mut account: Account = state.get(&address).unwrap();

                    account.balance = account.balance - value;

                    state.insert(address, account);
                },
                AccountChange::Create {
                    nonce, address, balance, storage, code, exists
                } => {
                    if !exists {
                        state.remove(&address);
                    } else {
                        let storage: HashMap<U256, M256> = storage.into();

                        let mut storage_trie = self.database.create_fixed_secure_empty();
                        for (key, value) in storage {
                            if value == M256::zero() {
                                storage_trie.remove(&H256::from(key));
                            } else {
                                storage_trie.insert(H256::from(key), value);
                            }
                        }

                        let code_hash = H256::from(Keccak256::digest(&code).as_slice());
                        code_hashes.set(code_hash, code);

                        let account = Account {
                            nonce: nonce,
                            balance: balance,
                            storage_root: storage_trie.root(),
                            code_hash
                        };

                        state.insert(address, account);
                    }
                },
            }
        }

        self.root = state.root();
    }

    pub fn execute<M: Memory + Default, P: Patch>(
        &mut self, transaction: ValidTransaction, block: HeaderParams,
        most_recent_block_hashes: &[H256]
    ) -> TransactionVM<M, P> {
        let vm = self.call::<_, P>(transaction, block, most_recent_block_hashes);
        let mut accounts = Vec::new();
        for account in vm.accounts() {
            accounts.push(account.clone());
        }
        self.transit(&accounts);
        vm
    }

    pub fn to_valid<P: Patch>(
        &self, transaction: Transaction,
    ) -> Result<ValidTransaction, PreExecutionError> {
        let state = self.database.create_fixed_secure_trie(self.root);
        let code_hashes = self.database.create_guard();
        let mut account_state = AccountState::default();

        loop {
            match ValidTransaction::from_transaction::<P>(&transaction, &account_state) {
                Ok(val) => return val,
                Err(RequireError::Account(address)) => {
                    let account: Option<Account> = state.get(&address);

                    match account {
                        Some(account) => {
                            let code = if Self::is_empty_hash(account.code_hash) {
                                Vec::new()
                            } else {
                                code_hashes.get(account.code_hash).unwrap()
                            };

                            account_state.commit(AccountCommitment::Full {
                                nonce: account.nonce,
                                address: address,
                                balance: account.balance,
                                code: code,
                            }).unwrap();
                        },
                        None => {
                            account_state.commit(AccountCommitment::Nonexist(address)).unwrap();
                        },
                    }
                },
                Err(RequireError::AccountCode(address)) => {
                    let account: Option<Account> = state.get(&address);

                    match account {
                        Some(account) => {
                            let code = if Self::is_empty_hash(account.code_hash) {
                                Vec::new()
                            } else {
                                code_hashes.get(account.code_hash).unwrap()
                            };

                            account_state.commit(AccountCommitment::Code {
                                address: address,
                                code: code,
                            }).unwrap();
                        },
                        None => {
                            account_state.commit(AccountCommitment::Nonexist(address)).unwrap();
                        },
                    }
                },
                Err(RequireError::AccountStorage(address, index)) => {
                    let account: Option<Account> = state.get(&address);

                    match account {
                        Some(account) => {
                            let storage = self.database.create_fixed_secure_trie(account.storage_root);
                            let value = storage.get(&H256::from(index)).unwrap_or(M256::zero());

                            account_state.commit(AccountCommitment::Storage {
                                address: address,
                                index, value
                            }).unwrap();
                        },
                        None => {
                            account_state.commit(AccountCommitment::Nonexist(address)).unwrap();
                        },
                    }
                },
                Err(RequireError::Blockhash(_)) => {
                    panic!()
                },
            }
        }
    }

    pub fn root(&self) -> H256 {
        self.root
    }

    pub fn state_of<'a>(&'a self, root: H256) -> FixedSecureTrie<<D as Database<'a>>::Guard, Address, Account> {
        self.database.create_fixed_secure_trie::<Address, Account>(root)
    }

    pub fn state<'a>(&'a self) -> FixedSecureTrie<<D as Database<'a>>::Guard, Address, Account> {
        self.state_of(self.root())
    }

    pub fn storage_state_of<'a>(&'a self, root: H256) -> FixedSecureTrie<<D as Database<'a>>::Guard, H256, M256> {
        self.database.create_fixed_secure_trie::<H256, M256>(root)
    }

    pub fn storage_state<'a>(&'a self, address: Address) -> Option<FixedSecureTrie<<D as Database<'a>>::Guard, H256, M256>> {
        let state = self.state();
        let account = state.get(&address);

        match account {
            Some(account) => {
                Some(self.storage_state_of(account.storage_root))
            },
            None => None,
        }
    }
}

pub type MemoryStateful<'a> = Stateful<'a, MemoryDatabase>;
<|endoftext|>


<commit_before>// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::fmt;

use {Args, Context, MessagePart};

/// A placeholder for a value. Used by `PluralFormat`.
#[derive(Debug)]
pub struct PlaceholderFormat {
}

impl PlaceholderFormat {
    /// Construct a `PlaceholderFormat`.
    pub fn new() -> Self {
        PlaceholderFormat {}
    }
}

impl MessagePart for PlaceholderFormat {
    fn apply_format(&self,
                    _context: &Context,
                    _stream: &mut fmt::Write,
                    _args: &Args)
                    -> fmt::Result {
        unimplemented!();
    }
}
<commit_msg>Implement PlaceholderFormat.<commit_after>// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::fmt;

use {Args, Context, MessagePart};

/// A placeholder for a value. Used by `PluralFormat`.
#[derive(Debug)]
pub struct PlaceholderFormat {
}

impl PlaceholderFormat {
    /// Construct a `PlaceholderFormat`.
    pub fn new() -> Self {
        PlaceholderFormat {}
    }
}

impl MessagePart for PlaceholderFormat {
    fn apply_format(&self,
                    context: &Context,
                    stream: &mut fmt::Write,
                    _args: &Args)
                    -> fmt::Result {
        if let Some(value) = context.placeholder_value {
            try!(write!(stream, "{}", value));
            Ok(())
        } else {
            Err(fmt::Error {})
        }
    }
}

#[cfg(test)]
mod tests {
    use super::PlaceholderFormat;
    use {arg, Context, MessagePart};

    #[test]
    fn it_works() {
        let context = Context::new(Some(3));
        let fmt = PlaceholderFormat::new();

        let mut output = String::new();
        fmt.apply_format(&context, &mut output, &arg("count", 0)).unwrap();
        assert_eq!("3", output);
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(non_snake_case)]

register_long_diagnostics! {

E0515: r##"
A constant index expression was out of bounds. Erroneous code example:

```
let x = &[0, 1, 2][7]; // error: const index-expr is out of bounds
```

Please specify a valid index (not inferior to 0 or superior to array length).
Example:

```
let x = &[0, 1, 2][2]; // ok!
```
"##,

}

register_diagnostics! {
    E0510, // invalid use of `return_address` intrinsic: function does not use out pointer
    E0511, // invalid monomorphization of `{}` intrinsic
    E0512, // transmute called on types with potentially different sizes...
}
<commit_msg>Add E0512 error explanation<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(non_snake_case)]

register_long_diagnostics! {

E0512: r##"
A transmute was called on types with different sizes. Erroneous code example:

```
extern "rust-intrinsic" {
    pub fn ctpop8(x: u8) -> u8;
}

fn main() {
    unsafe { ctpop8(::std::mem::transmute(0u16)); }
    // error: transmute called on types with different sizes
}
```

Please use types with same size or use the awaited type directly. Example:

```
extern "rust-intrinsic" {
    pub fn ctpop8(x: u8) -> u8;
}

fn main() {
    unsafe { ctpop8(::std::mem::transmute(0i8)); } // ok!
    // or:
    unsafe { ctpop8(0u8); } // ok!
}
```
"##,

E0515: r##"
A constant index expression was out of bounds. Erroneous code example:

```
let x = &[0, 1, 2][7]; // error: const index-expr is out of bounds
```

Please specify a valid index (not inferior to 0 or superior to array length).
Example:

```
let x = &[0, 1, 2][2]; // ok
```
"##,

}

register_diagnostics! {
    E0510, // invalid use of `return_address` intrinsic: function does not use out pointer
    E0511, // invalid monomorphization of `{}` intrinsic
}
<|endoftext|>