<commit_before>//! Parser main file

use std::env;
use std::process;
use std::io::stderr;
use std::io::Write;

/// Check if the given character is a digit (between 0 and 9)
///
/// # Arguments
///
/// * `character` - character to check
fn is_digit(character: char) -> bool {
    let digits: [char; 10] = ['0','1','2','3','4','5','6','7','8','9'];
    return digits.contains(&character);
}

fn main() {

    let args: Vec<_> = env::args().collect();

    if args.len() != 2 {
        writeln!(&mut stderr(), "No input.").unwrap();
        process::exit(1);
    }

    let mut output = String::from(
r#"
bits 64

section .text
    global _start

_start:
"#
    );

    for character in args[1].chars() {

        if is_digit(character)
        {
            output += "mov al, ";
            output.push(character);
        }
    }

    output +=
r#"
mov eax, 1
int 0x80
"#;

    print!("{}", output);
}
<commit_msg>add details about single digits management<commit_after>//! Parser main file

use std::env;
use std::process;
use std::io::stderr;
use std::io::Write;

/// Check if the given character is a digit (between 0 and 9)
///
/// # Arguments
///
/// * `character` - character to check
fn is_digit(character: char) -> bool {
    let digits: [char; 10] = ['0','1','2','3','4','5','6','7','8','9'];
    return digits.contains(&character);
}

fn main() {

    let args: Vec<_> = env::args().collect();

    if args.len() != 2 {
        writeln!(&mut stderr(), "No input.").unwrap();
        process::exit(1);
    }

    let mut output = String::from(
r#"
bits 64

segment .text
    global _start

_start:
"#
    );

    for character in args[1].chars() {

        if is_digit(character)
        {
            // this assembly instruction is meaningless for now
            output += "mov al, ";
            output.push(character);
        }
    }

    output +=
r#"
mov eax, 1
int 0x80
"#;

    print!("{}", output);
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate glium;

fn main() {
    use glium::{glutin, Surface};

    let mut events_loop = glutin::EventsLoop::new();
    let window = glutin::WindowBuilder::new();
    let context = glutin::ContextBuilder::new();
    let display = glium::Display::new(window, context, &events_loop).unwrap();

    #[derive(Copy, Clone)]
    struct Vertex {
        position: [f32; 2],
    }

    implement_vertex!(Vertex, position);

    let vertex1 = Vertex { position: [-0.5, -0.5] };
    let vertex2 = Vertex { position: [ 0.0,  0.5] };
    let vertex3 = Vertex { position: [ 0.5, -0.25] };
    let shape = vec![vertex1, vertex2, vertex3];

    let vertex_buffer = glium::VertexBuffer::new(&display, &shape).unwrap();
    let indices = glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList);

    let vertex_shader_src = r#"
        #version 140
        in vec2 position;
        void main() {
            gl_Position = vec4(position, 0.0, 1.0);
        }
    "#;

    let fragment_shader_src = r#"
        #version 140
        out vec4 color;
        void main() {
            color = vec4(1.0, 0.0, 0.0, 1.0);
        }
    "#;

    let program = glium::Program::from_source(&display, vertex_shader_src, fragment_shader_src, None).unwrap();

    let mut closed = false;
    while !closed {
        let mut target = display.draw();
        target.clear_color(0.0, 0.0, 1.0, 1.0);
        target.draw(&vertex_buffer, &indices, &program, &glium::uniforms::EmptyUniforms,
                    &Default::default()).unwrap();
        target.finish().unwrap();

        events_loop.poll_events(|event| {
            match event {
                glutin::Event::WindowEvent { event, .. } => match event {
                    glutin::WindowEvent::Closed => closed = true,
                    _ => ()
                },
                _ => (),
            }
        });
    }
}
<commit_msg>Don't compile main when testing<commit_after>#[macro_use]
extern crate glium;

#[cfg(not(test))]
fn main() {
    use glium::{glutin, Surface};

    let mut events_loop = glutin::EventsLoop::new();
    let window = glutin::WindowBuilder::new();
    let context = glutin::ContextBuilder::new();
    let display = glium::Display::new(window, context, &events_loop).unwrap();

    #[derive(Copy, Clone)]
    struct Vertex {
        position: [f32; 2],
    }

    implement_vertex!(Vertex, position);

    let vertex1 = Vertex { position: [-0.5, -0.5] };
    let vertex2 = Vertex { position: [ 0.0,  0.5] };
    let vertex3 = Vertex { position: [ 0.5, -0.25] };
    let shape = vec![vertex1, vertex2, vertex3];

    let vertex_buffer = glium::VertexBuffer::new(&display, &shape).unwrap();
    let indices = glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList);

    let vertex_shader_src = r#"
        #version 140
        in vec2 position;
        void main() {
            gl_Position = vec4(position, 0.0, 1.0);
        }
    "#;

    let fragment_shader_src = r#"
        #version 140
        out vec4 color;
        void main() {
            color = vec4(1.0, 0.0, 0.0, 1.0);
        }
    "#;

    let program = glium::Program::from_source(&display, vertex_shader_src, fragment_shader_src, None).unwrap();

    let mut closed = false;
    while !closed {
        let mut target = display.draw();
        target.clear_color(0.0, 0.0, 1.0, 1.0);
        target.draw(&vertex_buffer, &indices, &program, &glium::uniforms::EmptyUniforms,
                    &Default::default()).unwrap();
        target.finish().unwrap();

        events_loop.poll_events(|event| {
            match event {
                glutin::Event::WindowEvent { event, .. } => match event {
                    glutin::WindowEvent::Closed => closed = true,
                    _ => ()
                },
                _ => (),
            }
        });
    }
}
<|endoftext|>


<commit_before>
extern crate crypto;
extern crate iron;
extern crate router;
extern crate params;
extern crate hyper;

use iron::prelude::*;
use router::{Router};
use iron::status;
use iron::{BeforeMiddleware};

/// generate the md5sum of a given file (io::Read)
pub fn md5sum<T : std::io::Read> (f: &mut T) -> String  {
  use crypto::digest::Digest;

  let mut digest = crypto::md5::Md5::new();
  let mut data: Vec<u8> = Vec::new();

  match f.read_to_end(&mut data) {
    Err(why) => { println!("Error reading the passed file to calculate the md5sum: {}", why); String::new() }
    Ok(size) => {
      if size > 0 {
        digest.input(&data);
        digest.result_str()
      } else {
        String::new()
      }
    }
  }
}

#[macro_use]
mod param_rules;

use param_rules::RequiredParam;

fn submit_form_file(req: &mut Request) -> IronResult<Response> {

  let passed_md5sum = &String::get_param_value(req, "md5sum").unwrap();
  let file_param = params::File::get_param_value(req, "filename").unwrap();
  let file_path = file_param.path().display();
  match file_param.open() {
    Err(why) => {
      let msg = format!("cannot open the uploaded file '{:?}' in path '{}' : '{}'", file_param.filename(), file_path, why);
      println!("{}", msg);
      Ok(Response::with((status::InternalServerError, msg)))
    },
    Ok(ref mut file) => {
      let calculated_md5sum = &md5sum(file);
      if calculated_md5sum != passed_md5sum {
        let msg = format!(
          "the md5sum '{}' calculate for the file {} doesn't correspond to the parameter '{}'",
          calculated_md5sum, file_path, passed_md5sum
        );
        return Ok(Response::with((status::PreconditionRequired, msg)))
      }

      return Ok(Response::with((status::Ok, "ciao mondo")))
    }
  }
}

require_param!(RequireMd5sumParam, "md5sum", String);
require_param!(RequireFileParam, "filename", params::File);

mod logger;

use logger::Logger;
use iron::{AroundMiddleware};
fn start_server() {
   let mut router = Router::new();
   let mut chain_form_file = Chain::new(submit_form_file);

   chain_form_file.link_before(RequireMd5sumParam);
   chain_form_file.link_before(RequireFileParam);

   router.post("/openact", Logger::default().around(Box::new(chain_form_file)));

   println!("started server at http://localhost:3000/");
   Iron::new(router).http("localhost:3000").unwrap();
}

#[cfg(test)]
mod tests {

    use std::fs::File;
    use super::md5sum;

#[test]
    fn md5sum_of_file() {
        static FP : &'static str = "/home/costa/pkg/lav/regione/attiweb/attività/20150107/definizione procedura di riavvio/Procedure_Riavvio_omnia.odt";

        let mut odt = match File::open(FP) {
            Err(why) => panic!("Cannot open the test file: {}", why),
            Ok(file) => file,
        };

        assert_eq!(md5sum(&mut odt), "a381cbe043c38a94af0983ffa934f338");
    }

    #[test]
    fn simple_get() {
        use hyper::Client;
        use hyper::header::Connection;
        use std::io::Read;
        use super::start_server;

        // start_server();

        // Create a client.
        let client = Client::new();
        //
        // Creating an outgoing request.
        let mut res = client.get("http://localhost:3000/openact")
            // set a header
            .header(Connection::close())
            // let 'er go!
            .send().unwrap();

        // Read the Response.
        let mut body = String::new();
        res.read_to_string(&mut body).unwrap();

        println!("Response: {}", body);
        assert_eq!(body, "Hello World");
    }

}

fn main() {
    println!("Hello, world!");
    start_server();
}
<commit_msg>added command conversion<commit_after>
extern crate crypto;
extern crate iron;
extern crate router;
extern crate params;
extern crate hyper;

use iron::prelude::*;
use router::{Router};
use iron::status;
use iron::{BeforeMiddleware};

/// generate the md5sum of a given file (io::Read)
pub fn md5sum<T : std::io::Read> (f: &mut T) -> String  {
  use crypto::digest::Digest;

  let mut digest = crypto::md5::Md5::new();
  let mut data: Vec<u8> = Vec::new();

  match f.read_to_end(&mut data) {
    Err(why) => { println!("Error reading the passed file to calculate the md5sum: {}", why); String::new() }
    Ok(size) => {
      if size > 0 {
        digest.input(&data);
        digest.result_str()
      } else {
        String::new()
      }
    }
  }
}

#[macro_use]
mod param_rules;

use param_rules::RequiredParam;
use std::process::Command;

fn submit_form_file(req: &mut Request) -> IronResult<Response> {

  use std::fs::{rename,File};

  let passed_md5sum = &String::get_param_value(req, "md5sum").unwrap();
  let file_param = params::File::get_param_value(req, "filename").unwrap();

  let file_path = format!("{}.ods" , file_param.path().display());
  match rename(&file_param.path(), &file_path) {
    Err(why) => Ok(Response::with((status::PreconditionRequired, format!("failed to elaborate the received file: {}", why)))),
    Ok(_) => {
      println!("elaborating the file {}", file_path);

      match File::open(&file_path) {
        Err(why) => Ok(Response::with((status::PreconditionRequired, format!("failed to opening the received file: {}", why)))),
        Ok(ref mut file) => {
          let calculated_md5sum = &md5sum(file);
          if calculated_md5sum != passed_md5sum {
            let msg = format!(
              "the md5sum '{}' calculate for the file {} doesn't correspond to the parameter '{}'",
              calculated_md5sum, file_path, passed_md5sum
            );
            return Ok(Response::with((status::PreconditionRequired, msg)))
          }

          // it seems good
          let res = Command::new("timeout")
          .arg("--kill-after")
          .arg("10s")
          .arg("1m")

          // ----------------------- time it
          .arg("time")
          .arg("-v")
          .arg("-a")
          .arg("-o")
          .arg(format!("{}",file_param.path().parent().unwrap().join("time.log").display()))

          // ----------------------- convert
          .arg("libreoffice")
          .arg("--headless")
          .arg("--convert-to")
          .arg("pdf:writer_pdf_Export")
          .arg("--outdir")
          .arg(format!("{}",file_param.path().parent().unwrap().display()))
          .arg(file_path)
          .status().unwrap_or_else(|e| {
            println!("failed to execute process: {}", e);
            panic!("failed to execute process: {}", e);
          });

          println!("process exited with: {}", res);

          Ok(Response::with((status::Ok, "ok")))
        }
      }
    }
  }

}

require_param!(RequireMd5sumParam, "md5sum", String);
require_param!(RequireFileParam, "filename", params::File);

mod logger;

use logger::Logger;
use iron::{AroundMiddleware};
fn start_server() {
   let mut router = Router::new();
   let mut chain_form_file = Chain::new(submit_form_file);

   chain_form_file.link_before(RequireMd5sumParam);
   chain_form_file.link_before(RequireFileParam);

   router.post("/openact", Logger::default().around(Box::new(chain_form_file)));

   println!("started server at http://localhost:3000/");
   Iron::new(router).http("localhost:3000").unwrap();
}

#[cfg(test)]
mod tests {

    use std::fs::File;
    use super::md5sum;

#[test]
    fn md5sum_of_file() {
        static FP : &'static str = "/home/costa/pkg/lav/regione/attiweb/attività/20150107/definizione procedura di riavvio/Procedure_Riavvio_omnia.odt";

        let mut odt = match File::open(FP) {
            Err(why) => panic!("Cannot open the test file: {}", why),
            Ok(file) => file,
        };

        assert_eq!(md5sum(&mut odt), "a381cbe043c38a94af0983ffa934f338");
    }

    #[test]
    fn simple_get() {
        use hyper::Client;
        use hyper::header::Connection;
        use std::io::Read;
        use super::start_server;

        // start_server();

        // Create a client.
        let client = Client::new();
        //
        // Creating an outgoing request.
        let mut res = client.get("http://localhost:3000/openact")
            // set a header
            .header(Connection::close())
            // let 'er go!
            .send().unwrap();

        // Read the Response.
        let mut body = String::new();
        res.read_to_string(&mut body).unwrap();

        println!("Response: {}", body);
        assert_eq!(body, "Hello World");
    }

}

fn main() {
    println!("Hello, world!");
    start_server();
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate log;
#[cfg(feature = "env_logger")]
extern crate env_logger;
#[macro_use]
extern crate clap;
extern crate futures;

extern crate gluon_base as base;
extern crate gluon;
extern crate gluon_check as check;
extern crate gluon_parser as parser;
#[macro_use]
extern crate gluon_vm as vm;

#[cfg(not(test))]
use gluon::{new_vm, Compiler, Thread, Error, Result};
#[cfg(not(test))]
use gluon::vm::thread::ThreadInternal;
#[cfg(not(test))]
use gluon::vm::Error as VMError;

mod repl;

const GLUON_VERSION: &'static str = env!("CARGO_PKG_VERSION");

#[cfg(not(test))]
fn run_files<'s, I>(vm: &Thread, files: I) -> Result<()>
    where I: Iterator<Item = &'s str>,
{
    let mut compiler = Compiler::new();
    for file in files {
        compiler.load_file(&vm, file)?;
    }
    Ok(())
}

#[cfg(all(not(test), feature = "env_logger"))]
fn init_env_logger() {
    ::env_logger::init().unwrap();
}

#[cfg(all(not(test), not(feature = "env_logger")))]
fn init_env_logger() {}

#[cfg(not(test))]
fn main() {
    // Need the extra stack size when compiling the program using the msvc compiler
    ::std::thread::Builder::new()
        .stack_size(2 * 1024 * 1024)
        .spawn(|| {
            init_env_logger();

            let matches = clap_app!(gluon =>
                (version: GLUON_VERSION)
                (about: "executes gluon programs")
                (@arg REPL: -i --interactive "Starts the repl")
                (@arg INPUT: ... "Executes each file as a gluon program")
            )
                .get_matches();
            if matches.is_present("REPL") {
                if let Err(err) = repl::run() {
                    println!("{}", err);
                }
            } else if let Some(args) = matches.values_of("INPUT") {
                let vm = new_vm();
                match run_files(&vm, args) {
                    Ok(()) => (),
                    Err(err @ Error::VM(VMError::Message(_))) => {
                        println!("{}\n{}", err, vm.context().stack.stacktrace(0));
                    }
                    Err(msg) => println!("{}", msg),
                }
            } else {
                println!("{}", matches.usage());
            }
        })
        .unwrap()
        .join()
        .unwrap();
}
<commit_msg>refactor: Suppress unused warning of GLUON_VERSION<commit_after>#[macro_use]
extern crate log;
#[cfg(feature = "env_logger")]
extern crate env_logger;
#[macro_use]
extern crate clap;
extern crate futures;

extern crate gluon_base as base;
extern crate gluon;
extern crate gluon_check as check;
extern crate gluon_parser as parser;
#[macro_use]
extern crate gluon_vm as vm;

#[cfg(not(test))]
use gluon::{new_vm, Compiler, Thread, Error, Result};
#[cfg(not(test))]
use gluon::vm::thread::ThreadInternal;
#[cfg(not(test))]
use gluon::vm::Error as VMError;

mod repl;

#[cfg(not(test))]
fn run_files<'s, I>(vm: &Thread, files: I) -> Result<()>
    where I: Iterator<Item = &'s str>,
{
    let mut compiler = Compiler::new();
    for file in files {
        compiler.load_file(&vm, file)?;
    }
    Ok(())
}

#[cfg(all(not(test), feature = "env_logger"))]
fn init_env_logger() {
    ::env_logger::init().unwrap();
}

#[cfg(all(not(test), not(feature = "env_logger")))]
fn init_env_logger() {}

#[cfg(not(test))]
fn main() {
    const GLUON_VERSION: &'static str = env!("CARGO_PKG_VERSION");

    // Need the extra stack size when compiling the program using the msvc compiler
    ::std::thread::Builder::new()
        .stack_size(2 * 1024 * 1024)
        .spawn(|| {
            init_env_logger();

            let matches = clap_app!(gluon =>
                (version: GLUON_VERSION)
                (about: "executes gluon programs")
                (@arg REPL: -i --interactive "Starts the repl")
                (@arg INPUT: ... "Executes each file as a gluon program")
            )
                .get_matches();
            if matches.is_present("REPL") {
                if let Err(err) = repl::run() {
                    println!("{}", err);
                }
            } else if let Some(args) = matches.values_of("INPUT") {
                let vm = new_vm();
                match run_files(&vm, args) {
                    Ok(()) => (),
                    Err(err @ Error::VM(VMError::Message(_))) => {
                        println!("{}\n{}", err, vm.context().stack.stacktrace(0));
                    }
                    Err(msg) => println!("{}", msg),
                }
            } else {
                println!("{}", matches.usage());
            }
        })
        .unwrap()
        .join()
        .unwrap();
}
<|endoftext|>


<commit_before>extern crate regex;
use regex::Regex;

use std::io::{self, BufReader};
use std::io::BufRead;
use std::fs::File;
extern crate time;
use time::Tm;
use time::strptime;
use time::Duration;

#[derive(Eq, PartialEq)]
#[derive(Debug)]
pub enum HttpStatus {
    Continue,
    SwitchingProtocols,
    Processing,
    OK,
    Created,
    Accepted,
    NonAuthoritativeInformation,
    NoContent,
    ResetContent,
    PartialContent,
    MultiStatus,
    AlreadyReported,
    IMUsed,
    MultipleChoices,
    MovedPermanently,
    Found,
    SeeOther,
    NotModified,
    UseProxy,
    TemporaryRedirect,
    PermanentRedirect,
    BadRequest,
    Unauthorized,
    PaymentRequired,
    Forbidden,
    NotFound,
    MethodNotAllowed,
    NotAcceptable,
    ProxyAuthenticationRequired,
    RequestTimeout,
    Conflict,
    Gone,
    LengthRequired,
    PreconditionFailed,
    PayloadTooLarge,
    URITooLong,
    UnsupportedMediaType,
    RangeNotSatisfiable,
    ExpectationFailed,
    ImaTeapot,
    MisdirectedRequest,
    UnprocessableEntity,
    Locked,
    FailedDependency,
    UpgradeRequired,
    PreconditionRequired,
    TooManyRequests,
    RequestHeaderFieldsTooLarge,
    UnavailableForLegalReasons,
    InternalServerError,
    NotImplemented,
    BadGateway,
    ServiceUnavailable,
    GatewayTimeout,
    HTTPVersionNotSupported,
    VariantAlsoNegotiates,
    InsufficientStorage,
    LoopDetected,
    NotExtended,
    NetworkAuthenticationRequired,
    Unregistered,
}

impl HttpStatus {
    fn from_code(code: i32) -> HttpStatus {
        match code {
            100 => HttpStatus::Continue,
            101 => HttpStatus::SwitchingProtocols,
            102 => HttpStatus::Processing,
            200 => HttpStatus::OK,
            201 => HttpStatus::Created,
            202 => HttpStatus::Accepted,
            203 => HttpStatus::NonAuthoritativeInformation,
            204 => HttpStatus::NoContent,
            205 => HttpStatus::ResetContent,
            206 => HttpStatus::PartialContent,
            207 => HttpStatus::MultiStatus,
            208 => HttpStatus::AlreadyReported,
            226 => HttpStatus::IMUsed,
            300 => HttpStatus::MultipleChoices,
            301 => HttpStatus::MovedPermanently,
            302 => HttpStatus::Found,
            303 => HttpStatus::SeeOther,
            304 => HttpStatus::NotModified,
            305 => HttpStatus::UseProxy,
            307 => HttpStatus::TemporaryRedirect,
            308 => HttpStatus::PermanentRedirect,
            400 => HttpStatus::BadRequest,
            401 => HttpStatus::Unauthorized,
            402 => HttpStatus::PaymentRequired,
            403 => HttpStatus::Forbidden,
            404 => HttpStatus::NotFound,
            405 => HttpStatus::MethodNotAllowed,
            406 => HttpStatus::NotAcceptable,
            407 => HttpStatus::ProxyAuthenticationRequired,
            408 => HttpStatus::RequestTimeout,
            409 => HttpStatus::Conflict,
            410 => HttpStatus::Gone,
            411 => HttpStatus::LengthRequired,
            412 => HttpStatus::PreconditionFailed,
            413 => HttpStatus::PayloadTooLarge,
            414 => HttpStatus::URITooLong,
            415 => HttpStatus::UnsupportedMediaType,
            416 => HttpStatus::RangeNotSatisfiable,
            417 => HttpStatus::ExpectationFailed,
            418 => HttpStatus::ImaTeapot,
            421 => HttpStatus::MisdirectedRequest,
            422 => HttpStatus::UnprocessableEntity,
            423 => HttpStatus::Locked,
            424 => HttpStatus::FailedDependency,
            426 => HttpStatus::UpgradeRequired,
            428 => HttpStatus::PreconditionRequired,
            429 => HttpStatus::TooManyRequests,
            431 => HttpStatus::RequestHeaderFieldsTooLarge,
            451 => HttpStatus::UnavailableForLegalReasons,
            500 => HttpStatus::InternalServerError,
            501 => HttpStatus::NotImplemented,
            502 => HttpStatus::BadGateway,
            503 => HttpStatus::ServiceUnavailable,
            504 => HttpStatus::GatewayTimeout,
            505 => HttpStatus::HTTPVersionNotSupported,
            506 => HttpStatus::VariantAlsoNegotiates,
            507 => HttpStatus::InsufficientStorage,
            508 => HttpStatus::LoopDetected,
            510 => HttpStatus::NotExtended,
            511 => HttpStatus::NetworkAuthenticationRequired,
            _ => HttpStatus::Unregistered,
        }
    }
}

#[derive(Eq, PartialEq)]
#[derive(Debug)]
pub struct Request {
    id: i32,
    time: Tm,
    url: String,
}

impl Request {
    fn get_matching_response<'a>(&'a self, responses: &'a Vec<Response>) -> Option<&'a Response> {
        for response in responses {
            if self.id == response.id {
                return Some(&response)
            }
        }

        None
    }
}

#[derive(Eq, PartialEq)]
#[derive(Debug)]
pub struct Response {
    id: i32,
    time: Tm,
    mime_type: String,
    response_time: Duration,
    http_status: HttpStatus,
}

pub fn open_logfile(path: &str) -> Result<(Vec<Request>,Vec<Response>), io::Error> {
    let f = try!(File::open(path));

    let f = BufReader::new(f);

    let mut requests: Vec<Request> = Vec::new();
    let mut responses: Vec<Response> = Vec::new();

    for line in f.lines() {
        let line_value = &line.unwrap();

        if line_value.contains("->") {
            let r = try!(parse_request_line(&line_value));
            println!("{:#?}", r);
            requests.push(r)
        }

        if line_value.contains("<-") {
            let r = try!(parse_response_line(&line_value));
            println!("{:#?}", r);
            responses.push(r)
        }

    }

    Ok((requests, responses))
}

pub fn parse_request_line(log_line: &String) -> Result<Request, io::Error> {
    let parts: Vec<&str> = log_line.split(" ").collect();

    let id = parts[2];
    let url = parts[5];

    Ok(Request {
        id: id[1..id.len()-1].parse().unwrap(),
        time: strptime(parts[0], "%d/%b/%Y:%H:%M:%S").unwrap(),
        url: url.to_string()
    })
}

pub fn parse_response_line(log_line: &String) -> Result<Response, io::Error> {
    let parts: Vec<&str> = log_line.split(" ").collect();

    let id = parts[2];
    let response_time = parts[parts.len()-1];
    let mime_type = parts[5];
    let status_code = parts[4];

    Ok(Response {
        id: id[1..id.len()-1].parse().unwrap(),
        time: strptime(parts[0], "%d/%b/%Y:%H:%M:%S").unwrap(),
        response_time: Duration::milliseconds(response_time[0..response_time.len()-2].parse().unwrap()),
        mime_type: mime_type.to_string(),
        http_status: HttpStatus::from_code(status_code.parse().unwrap()),
    })
}

pub struct RequestResponsePair<'a> {
    request: &'a Request,
    response: &'a Response
}

pub fn pair_requests_responses<'a>(requests: &'a Vec<Request>, responses: &'a Vec<Response>) -> &'a Vec<RequestResponsePair<'a>> {
    let mut request_response_pairs: Vec<RequestResponsePair> = Vec::new();

    for request in requests {
        match request.get_matching_response(responses) {
            Some(response) => request_response_pairs.push(RequestResponsePair{
                request: request,
                response: response
            }),
            None => println!("none"),
        }
    }

    &request_response_pairs
}

fn main() {
    let lines = open_logfile("src/test/simple-1.log");
    let (requests, responses) = lines.unwrap();
    println!("So many requests: {}", requests.len());
    println!("So many responses: {}", responses.len());
}

#[cfg(test)]
mod tests {
	use super::*;
    extern crate time;
    use time::strptime;
    use::time::Duration;

    #[test]
    fn test_parse_request_line() {
        let line = "08/Apr/2016:09:58:47 +0200 [02] -> GET /content/some/other.html HTTP/1.1".to_string();

        let expected = Request {
            id: 2,
            time: strptime("08/Apr/2016:09:58:47 +0200", "%d/%b/%Y:%H:%M:%S").unwrap(),
            url: "/content/some/other.html".to_string()
        };

        let result = parse_request_line(&line);

        assert_eq!(result.unwrap(), expected)
    }

    #[test]
    fn test_parse_response_line() {
        let line = "08/Apr/2016:09:58:48 +0200 [02] <- 200 text/html 10ms".to_string();

        let expected = Response {
            id: 2,
            time: strptime("08/Apr/2016:09:58:48 +0200", "%d/%b/%Y:%H:%M:%S").unwrap(),
            mime_type: "text/html".to_string(),
            response_time: Duration::milliseconds(10),
            http_status: HttpStatus::OK,
        };

        let result = parse_response_line(&line);

        assert_eq!(result.unwrap(), expected)
    }

    #[test]
    fn test_open_logfile() {
        let lines = open_logfile("src/test/simple-1.log");
        let (requests, responses) = lines.unwrap();

        assert_eq!(requests.len(), 2);
        assert_eq!(responses.len(), 2);
    }

    #[test]
    fn test_get_matching_response() {
        let lines = open_logfile("src/test/simple-1.log");
        let (requests, responses) = lines.unwrap();

        let result = requests[0].get_matching_response(&responses);

        let expected = Response {
            id: 1,
            time: strptime("08/Apr/2016:09:57:47 +0200", "%d/%b/%Y:%H:%M:%S").unwrap(),
            mime_type: "text/html".to_string(),
            response_time: Duration::milliseconds(7),
            http_status: HttpStatus::OK,
        };

        assert_eq!(*result.unwrap(), expected);
    }

    #[test]
    fn test_get_matching_response_none_found() {
        let lines = open_logfile("src/test/simple-1.log");
        let (requests, responses) = lines.unwrap();

        let request_without_matching = Request {
            id: 999,
            time: strptime("08/Apr/2016:09:58:47 +0200", "%d/%b/%Y:%H:%M:%S").unwrap(),
            url: "/content/some/other.html".to_string()
        };

        let result = request_without_matching.get_matching_response(&responses);

        assert!(result.is_none());
    }

    #[test]
    fn test_pair_requests_resonses() {
        let lines = open_logfile("src/test/simple-1.log");
        let (requests, responses) = lines.unwrap();

        let result = pair_requests_responses(&requests, &responses);
    }
}
<commit_msg>Avoid ownership trouble by cloning<commit_after>extern crate regex;
use regex::Regex;

use std::io::{self, BufReader};
use std::io::BufRead;
use std::fs::File;
extern crate time;
use time::Tm;
use time::strptime;
use time::Duration;

#[derive(Eq, PartialEq, Clone)]
#[derive(Debug)]
pub enum HttpStatus {
    Continue,
    SwitchingProtocols,
    Processing,
    OK,
    Created,
    Accepted,
    NonAuthoritativeInformation,
    NoContent,
    ResetContent,
    PartialContent,
    MultiStatus,
    AlreadyReported,
    IMUsed,
    MultipleChoices,
    MovedPermanently,
    Found,
    SeeOther,
    NotModified,
    UseProxy,
    TemporaryRedirect,
    PermanentRedirect,
    BadRequest,
    Unauthorized,
    PaymentRequired,
    Forbidden,
    NotFound,
    MethodNotAllowed,
    NotAcceptable,
    ProxyAuthenticationRequired,
    RequestTimeout,
    Conflict,
    Gone,
    LengthRequired,
    PreconditionFailed,
    PayloadTooLarge,
    URITooLong,
    UnsupportedMediaType,
    RangeNotSatisfiable,
    ExpectationFailed,
    ImaTeapot,
    MisdirectedRequest,
    UnprocessableEntity,
    Locked,
    FailedDependency,
    UpgradeRequired,
    PreconditionRequired,
    TooManyRequests,
    RequestHeaderFieldsTooLarge,
    UnavailableForLegalReasons,
    InternalServerError,
    NotImplemented,
    BadGateway,
    ServiceUnavailable,
    GatewayTimeout,
    HTTPVersionNotSupported,
    VariantAlsoNegotiates,
    InsufficientStorage,
    LoopDetected,
    NotExtended,
    NetworkAuthenticationRequired,
    Unregistered,
}

impl HttpStatus {
    fn from_code(code: i32) -> HttpStatus {
        match code {
            100 => HttpStatus::Continue,
            101 => HttpStatus::SwitchingProtocols,
            102 => HttpStatus::Processing,
            200 => HttpStatus::OK,
            201 => HttpStatus::Created,
            202 => HttpStatus::Accepted,
            203 => HttpStatus::NonAuthoritativeInformation,
            204 => HttpStatus::NoContent,
            205 => HttpStatus::ResetContent,
            206 => HttpStatus::PartialContent,
            207 => HttpStatus::MultiStatus,
            208 => HttpStatus::AlreadyReported,
            226 => HttpStatus::IMUsed,
            300 => HttpStatus::MultipleChoices,
            301 => HttpStatus::MovedPermanently,
            302 => HttpStatus::Found,
            303 => HttpStatus::SeeOther,
            304 => HttpStatus::NotModified,
            305 => HttpStatus::UseProxy,
            307 => HttpStatus::TemporaryRedirect,
            308 => HttpStatus::PermanentRedirect,
            400 => HttpStatus::BadRequest,
            401 => HttpStatus::Unauthorized,
            402 => HttpStatus::PaymentRequired,
            403 => HttpStatus::Forbidden,
            404 => HttpStatus::NotFound,
            405 => HttpStatus::MethodNotAllowed,
            406 => HttpStatus::NotAcceptable,
            407 => HttpStatus::ProxyAuthenticationRequired,
            408 => HttpStatus::RequestTimeout,
            409 => HttpStatus::Conflict,
            410 => HttpStatus::Gone,
            411 => HttpStatus::LengthRequired,
            412 => HttpStatus::PreconditionFailed,
            413 => HttpStatus::PayloadTooLarge,
            414 => HttpStatus::URITooLong,
            415 => HttpStatus::UnsupportedMediaType,
            416 => HttpStatus::RangeNotSatisfiable,
            417 => HttpStatus::ExpectationFailed,
            418 => HttpStatus::ImaTeapot,
            421 => HttpStatus::MisdirectedRequest,
            422 => HttpStatus::UnprocessableEntity,
            423 => HttpStatus::Locked,
            424 => HttpStatus::FailedDependency,
            426 => HttpStatus::UpgradeRequired,
            428 => HttpStatus::PreconditionRequired,
            429 => HttpStatus::TooManyRequests,
            431 => HttpStatus::RequestHeaderFieldsTooLarge,
            451 => HttpStatus::UnavailableForLegalReasons,
            500 => HttpStatus::InternalServerError,
            501 => HttpStatus::NotImplemented,
            502 => HttpStatus::BadGateway,
            503 => HttpStatus::ServiceUnavailable,
            504 => HttpStatus::GatewayTimeout,
            505 => HttpStatus::HTTPVersionNotSupported,
            506 => HttpStatus::VariantAlsoNegotiates,
            507 => HttpStatus::InsufficientStorage,
            508 => HttpStatus::LoopDetected,
            510 => HttpStatus::NotExtended,
            511 => HttpStatus::NetworkAuthenticationRequired,
            _ => HttpStatus::Unregistered,
        }
    }
}

#[derive(Eq, PartialEq, Clone)]
#[derive(Debug)]
pub struct Request {
    id: i32,
    time: Tm,
    url: String,
}

impl Request {
    fn get_matching_response<'a>(&'a self, responses: &'a Vec<Response>) -> Option<&Response> {
        for response in responses {
            if self.id == response.id {
                return Some(response)
            }
        }

        None
    }
}

#[derive(Eq, PartialEq, Clone)]
#[derive(Debug)]
pub struct Response {
    id: i32,
    time: Tm,
    mime_type: String,
    response_time: Duration,
    http_status: HttpStatus,
}

pub fn open_logfile(path: &str) -> Result<(Vec<Request>,Vec<Response>), io::Error> {
    let f = try!(File::open(path));

    let f = BufReader::new(f);

    let mut requests: Vec<Request> = Vec::new();
    let mut responses: Vec<Response> = Vec::new();

    for line in f.lines() {
        let line_value = &line.unwrap();

        if line_value.contains("->") {
            let r = try!(parse_request_line(&line_value));
            println!("{:#?}", r);
            requests.push(r)
        }

        if line_value.contains("<-") {
            let r = try!(parse_response_line(&line_value));
            println!("{:#?}", r);
            responses.push(r)
        }

    }

    Ok((requests, responses))
}

pub fn parse_request_line(log_line: &String) -> Result<Request, io::Error> {
    let parts: Vec<&str> = log_line.split(" ").collect();

    let id = parts[2];
    let url = parts[5];

    Ok(Request {
        id: id[1..id.len()-1].parse().unwrap(),
        time: strptime(parts[0], "%d/%b/%Y:%H:%M:%S").unwrap(),
        url: url.to_string()
    })
}

pub fn parse_response_line(log_line: &String) -> Result<Response, io::Error> {
    let parts: Vec<&str> = log_line.split(" ").collect();

    let id = parts[2];
    let response_time = parts[parts.len()-1];
    let mime_type = parts[5];
    let status_code = parts[4];

    Ok(Response {
        id: id[1..id.len()-1].parse().unwrap(),
        time: strptime(parts[0], "%d/%b/%Y:%H:%M:%S").unwrap(),
        response_time: Duration::milliseconds(response_time[0..response_time.len()-2].parse().unwrap()),
        mime_type: mime_type.to_string(),
        http_status: HttpStatus::from_code(status_code.parse().unwrap()),
    })
}

pub struct RequestResponsePair {
    request: Request,
    response: Response
}

pub fn pair_requests_responses(mut requests:Vec<Request>, responses: Vec<Response>) -> Vec<RequestResponsePair> {
    let mut request_response_pairs: Vec<RequestResponsePair> = Vec::new();

    for request in requests.drain(..) {
        match request.get_matching_response(&responses) {
            Some(response) => request_response_pairs.push(RequestResponsePair{
                request: request.clone(),
                response: response.clone()
            }),
            None => println!("none"),
        }
    }

    request_response_pairs
}

fn main() {
    let lines = open_logfile("src/test/simple-1.log");
    let (requests, responses) = lines.unwrap();
    println!("So many requests: {}", requests.len());
    println!("So many responses: {}", responses.len());
}

#[cfg(test)]
mod tests {
	use super::*;
    extern crate time;
    use time::strptime;
    use::time::Duration;

    #[test]
    fn test_parse_request_line() {
        let line = "08/Apr/2016:09:58:47 +0200 [02] -> GET /content/some/other.html HTTP/1.1".to_string();

        let expected = Request {
            id: 2,
            time: strptime("08/Apr/2016:09:58:47 +0200", "%d/%b/%Y:%H:%M:%S").unwrap(),
            url: "/content/some/other.html".to_string()
        };

        let result = parse_request_line(&line);

        assert_eq!(result.unwrap(), expected)
    }

    #[test]
    fn test_parse_response_line() {
        let line = "08/Apr/2016:09:58:48 +0200 [02] <- 200 text/html 10ms".to_string();

        let expected = Response {
            id: 2,
            time: strptime("08/Apr/2016:09:58:48 +0200", "%d/%b/%Y:%H:%M:%S").unwrap(),
            mime_type: "text/html".to_string(),
            response_time: Duration::milliseconds(10),
            http_status: HttpStatus::OK,
        };

        let result = parse_response_line(&line);

        assert_eq!(result.unwrap(), expected)
    }

    #[test]
    fn test_open_logfile() {
        let lines = open_logfile("src/test/simple-1.log");
        let (requests, responses) = lines.unwrap();

        assert_eq!(requests.len(), 2);
        assert_eq!(responses.len(), 2);
    }

    #[test]
    fn test_get_matching_response() {
        let lines = open_logfile("src/test/simple-1.log");
        let (requests, responses) = lines.unwrap();

        let result = requests[0].get_matching_response(&responses);

        let expected = Response {
            id: 1,
            time: strptime("08/Apr/2016:09:57:47 +0200", "%d/%b/%Y:%H:%M:%S").unwrap(),
            mime_type: "text/html".to_string(),
            response_time: Duration::milliseconds(7),
            http_status: HttpStatus::OK,
        };

        assert_eq!(*result.unwrap(), expected);
    }

    #[test]
    fn test_get_matching_response_none_found() {
        let lines = open_logfile("src/test/simple-1.log");
        let (requests, responses) = lines.unwrap();

        let request_without_matching = Request {
            id: 999,
            time: strptime("08/Apr/2016:09:58:47 +0200", "%d/%b/%Y:%H:%M:%S").unwrap(),
            url: "/content/some/other.html".to_string()
        };

        let result = request_without_matching.get_matching_response(&responses);

        assert!(result.is_none());
    }

    #[test]
    fn test_pair_requests_resonses() {
        let lines = open_logfile("src/test/simple-1.log");
        let (requests, responses) = lines.unwrap();

        let result = pair_requests_responses(requests, responses);
    }
}
<|endoftext|>


<commit_before>extern crate serde;
extern crate serde_json;
#[macro_use] extern crate serde_derive;
#[macro_use] extern crate exonum;
extern crate router;
extern crate bodyparser;
extern crate iron;

use exonum::blockchain::{self, Blockchain, Service, GenesisConfig, Transaction, ApiContext};
use exonum::messages::{RawTransaction, FromRaw, Message};
use exonum::node::{Node, NodeConfig, NodeApiConfig, TransactionSend};
use exonum::storage::{Fork, MemoryDB, MapIndex};
use exonum::crypto::{PublicKey, Hash};
use exonum::encoding::{self, Field};
use exonum::api::{Api, ApiError};
use iron::prelude::*;
use iron::Handler;
use router::Router;

// // // // // // // // // // PERSISTENT DATA // // // // // // // // // //

encoding_struct! {
    struct Wallet {
        const SIZE = 48;

        field pub_key:            &PublicKey  [00 => 32]
        field name:               &str        [32 => 40]
        field balance:            u64         [40 => 48]
    }
}

impl Wallet {
    pub fn increase(&mut self, amount: u64) {
        let balance = self.balance() + amount;
        Field::write(&balance, &mut self.raw, 40, 48);
    }

    pub fn decrease(&mut self, amount: u64) {
        let balance = self.balance() - amount;
        Field::write(&balance, &mut self.raw, 40, 48);
    }
}

// // // // // // // // // // TRANSACTIONS // // // // // // // // // //

pub const TX_WALLET_ID: u16 = 1;

message! {
    struct TxCreateWallet {
        const TYPE = SERVICE_ID;
        const ID = TX_WALLET_ID;
        const SIZE = 40;

        field pub_key:     &PublicKey  [00 => 32]
        field name:        &str        [32 => 40]
    }
}

pub const TX_TRANSFER_ID: u16 = 2;

message! {
    struct TxTransfer {
        const TYPE = SERVICE_ID;
        const ID = TX_TRANSFER_ID;
        const SIZE = 80;

        field from:        &PublicKey  [00 => 32]
        field to:          &PublicKey  [32 => 64]
        field amount:      u64         [64 => 72]
        field seed:        u64         [72 => 80]
    }
}

// // // // // // // // // // CONTRACTS // // // // // // // // // //

impl Transaction for TxCreateWallet {
    fn verify(&self) -> bool {
        self.verify_signature(self.pub_key())
    }

    fn execute(&self, view: &mut Fork) {
        let mut schema = CurrencySchema { view };
        if let None = schema.wallet(self.pub_key()) {
            let wallet = Wallet::new(self.pub_key(), self.name(), 100);
            println!("Create the wallet: {:?}", wallet);
            schema.wallets().put(self.pub_key(), wallet)
        }
    }
}

impl Transaction for TxTransfer {
    fn verify(&self) -> bool {
        (*self.from() != *self.to()) && self.verify_signature(self.from())
    }

    fn execute(&self, view: &mut Fork) {
        let mut schema = CurrencySchema { view };
        let sender = schema.wallet(self.from());
        let receiver = schema.wallet(self.to());
        if let (Some(mut sender), Some(mut receiver)) = (sender, receiver) {
            let amount = self.amount();
            if sender.balance() >= amount {
                sender.decrease(amount);
                receiver.increase(amount);
                println!("Transfer between wallets: {:?} => {:?}", sender, receiver);
                let mut wallets = schema.wallets();
                wallets.put(self.from(), sender);
                wallets.put(self.to(), receiver);
            }
        }
    }
}

// // // // // // // // // // REST API // // // // // // // // // //

#[derive(Clone)]
struct CryptocurrencyApi<T> {
    channel: T,
}

impl<T: TransactionSend + Clone + 'static> Api for CryptocurrencyApi<T> {
    fn wire(&self, router: &mut Router) {

        #[serde(untagged)]
        #[derive(Clone, Serialize, Deserialize)]
        enum TransactionRequest {
            CreateWallet(TxCreateWallet),
            Transfer(TxTransfer),
        }

        impl Into<Box<Transaction>> for TransactionRequest {
            fn into(self) -> Box<Transaction> {
                match self {
                    TransactionRequest::CreateWallet(trans) => Box::new(trans),
                    TransactionRequest::Transfer(trans) => Box::new(trans),
                }
            }
        }

        #[derive(Serialize, Deserialize)]
        struct TransactionResponse {
            tx_hash: Hash,
        }

        let self_ = self.clone();
        let transaction = move |req: &mut Request| -> IronResult<Response> {
            match req.get::<bodyparser::Struct<TransactionRequest>>() {
                Ok(Some(transaction)) => {
                    let transaction: Box<Transaction> = transaction.into();
                    let tx_hash = transaction.hash();
                    self_.channel.send(transaction).map_err(|e| ApiError::Events(e))?;
                    let json = TransactionResponse { tx_hash };
                    self_.ok_response(&serde_json::to_value(&json).unwrap())
                }
                Ok(None) => Err(ApiError::IncorrectRequest("Empty request body".into()))?,
                Err(e) => Err(ApiError::IncorrectRequest(Box::new(e)))?,
            }
        };
        let route_post = "/v1/wallets/transaction";
        router.post(&route_post, transaction, "transaction");
    }
}

// // // // // // // // // // STORAGE DATA LAYOUT // // // // // // // // // //

pub struct CurrencySchema<'a> {
    view: &'a mut Fork,
}

impl<'a> CurrencySchema<'a> {
    pub fn wallets(&mut self) -> MapIndex<&mut Fork, PublicKey, Wallet> {
        let prefix = blockchain::gen_prefix(SERVICE_ID, 0, &());
        MapIndex::new(prefix, self.view)
    }

    pub fn wallet(&mut self, pub_key: &PublicKey) -> Option<Wallet> {
        self.wallets().get(pub_key)
    }
}

// // // // // // // // // // SERVICE DECLARATION // // // // // // // // // //

pub const SERVICE_ID: u16 = 1;

struct CurrencyService;

impl Service for CurrencyService {
    fn service_name(&self) -> &'static str { "cryptocurrency" }

    fn service_id(&self) -> u16 { SERVICE_ID }

    fn tx_from_raw(&self, raw: RawTransaction) -> Result<Box<Transaction>, encoding::Error> {
        let trans: Box<Transaction> = match raw.message_type() {
            TX_TRANSFER_ID => Box::new(TxTransfer::from_raw(raw)?),
            TX_WALLET_ID => Box::new(TxCreateWallet::from_raw(raw)?),
            _ => {
                return Err(encoding::Error::IncorrectMessageType { message_type: raw.message_type() });
            },
        };
        Ok(trans)
    }

    fn public_api_handler(&self, ctx: &ApiContext) -> Option<Box<Handler>> {
        let mut router = Router::new();
        let api = CryptocurrencyApi {
            channel: ctx.node_channel().clone(),
        };
        api.wire(&mut router);
        Some(Box::new(router))
    }
}

// // // // // // // // // // ENTRY POINT // // // // // // // // // //

fn main() {
    exonum::helpers::init_logger().unwrap();

    println!("Creating in-memory database...");
    let db = MemoryDB::new();
    let services: Vec<Box<Service>> = vec![
        Box::new(CurrencyService),
    ];
    let blockchain = Blockchain::new(Box::new(db), services);

    let (public_key, secret_key) = exonum::crypto::gen_keypair();

    let peer_address = "0.0.0.0:2000".parse().unwrap();
    let api_address = "0.0.0.0:8000".parse().unwrap();

    let genesis = GenesisConfig::new(vec![public_key].into_iter());

    let api_cfg = NodeApiConfig {
        enable_blockchain_explorer: true,
        public_api_address: Some(api_address),
        private_api_address: None,
    };

    let node_cfg = NodeConfig {
        listen_address: peer_address,
        peers: vec![],
        public_key,
        secret_key,
        genesis,
        network: Default::default(),
        whitelist: Default::default(),
        api: api_cfg,
        mempool: Default::default(),
    };

    println!("Starting a single node...");
    let mut node = Node::new(blockchain, node_cfg);

    println!("Blockchain in ready for transactions!");
    node.run().unwrap();
}
<commit_msg>Add constatnt with default balance<commit_after>extern crate serde;
extern crate serde_json;
#[macro_use] extern crate serde_derive;
#[macro_use] extern crate exonum;
extern crate router;
extern crate bodyparser;
extern crate iron;

use exonum::blockchain::{self, Blockchain, Service, GenesisConfig, Transaction, ApiContext};
use exonum::messages::{RawTransaction, FromRaw, Message};
use exonum::node::{Node, NodeConfig, NodeApiConfig, TransactionSend};
use exonum::storage::{Fork, MemoryDB, MapIndex};
use exonum::crypto::{PublicKey, Hash};
use exonum::encoding::{self, Field};
use exonum::api::{Api, ApiError};
use iron::prelude::*;
use iron::Handler;
use router::Router;

// // // // // // // // // // PERSISTENT DATA // // // // // // // // // //

encoding_struct! {
    struct Wallet {
        const SIZE = 48;

        field pub_key:            &PublicKey  [00 => 32]
        field name:               &str        [32 => 40]
        field balance:            u64         [40 => 48]
    }
}

impl Wallet {
    pub fn increase(&mut self, amount: u64) {
        let balance = self.balance() + amount;
        Field::write(&balance, &mut self.raw, 40, 48);
    }

    pub fn decrease(&mut self, amount: u64) {
        let balance = self.balance() - amount;
        Field::write(&balance, &mut self.raw, 40, 48);
    }
}

// // // // // // // // // // TRANSACTIONS // // // // // // // // // //

pub const TX_CREATE_WALLET_ID: u16 = 1;

message! {
    struct TxCreateWallet {
        const TYPE = SERVICE_ID;
        const ID = TX_CREATE_WALLET_ID;
        const SIZE = 40;

        field pub_key:     &PublicKey  [00 => 32]
        field name:        &str        [32 => 40]
    }
}

pub const TX_TRANSFER_ID: u16 = 2;

message! {
    struct TxTransfer {
        const TYPE = SERVICE_ID;
        const ID = TX_TRANSFER_ID;
        const SIZE = 80;

        field from:        &PublicKey  [00 => 32]
        field to:          &PublicKey  [32 => 64]
        field amount:      u64         [64 => 72]
        field seed:        u64         [72 => 80]
    }
}

// // // // // // // // // // CONTRACTS // // // // // // // // // //

const INIT_BALANCE: u64 = 100;

impl Transaction for TxCreateWallet {
    fn verify(&self) -> bool {
        self.verify_signature(self.pub_key())
    }

    fn execute(&self, view: &mut Fork) {
        let mut schema = CurrencySchema { view };
        if let None = schema.wallet(self.pub_key()) {
            let wallet = Wallet::new(self.pub_key(), self.name(), INIT_BALANCE);
            println!("Create the wallet: {:?}", wallet);
            schema.wallets().put(self.pub_key(), wallet)
        }
    }
}

impl Transaction for TxTransfer {
    fn verify(&self) -> bool {
        (*self.from() != *self.to()) && self.verify_signature(self.from())
    }

    fn execute(&self, view: &mut Fork) {
        let mut schema = CurrencySchema { view };
        let sender = schema.wallet(self.from());
        let receiver = schema.wallet(self.to());
        if let (Some(mut sender), Some(mut receiver)) = (sender, receiver) {
            let amount = self.amount();
            if sender.balance() >= amount {
                sender.decrease(amount);
                receiver.increase(amount);
                println!("Transfer between wallets: {:?} => {:?}", sender, receiver);
                let mut wallets = schema.wallets();
                wallets.put(self.from(), sender);
                wallets.put(self.to(), receiver);
            }
        }
    }
}

// // // // // // // // // // REST API // // // // // // // // // //

#[derive(Clone)]
struct CryptocurrencyApi<T> {
    channel: T,
}

impl<T: TransactionSend + Clone + 'static> Api for CryptocurrencyApi<T> {
    fn wire(&self, router: &mut Router) {

        #[serde(untagged)]
        #[derive(Clone, Serialize, Deserialize)]
        enum TransactionRequest {
            CreateWallet(TxCreateWallet),
            Transfer(TxTransfer),
        }

        impl Into<Box<Transaction>> for TransactionRequest {
            fn into(self) -> Box<Transaction> {
                match self {
                    TransactionRequest::CreateWallet(trans) => Box::new(trans),
                    TransactionRequest::Transfer(trans) => Box::new(trans),
                }
            }
        }

        #[derive(Serialize, Deserialize)]
        struct TransactionResponse {
            tx_hash: Hash,
        }

        let self_ = self.clone();
        let transaction = move |req: &mut Request| -> IronResult<Response> {
            match req.get::<bodyparser::Struct<TransactionRequest>>() {
                Ok(Some(transaction)) => {
                    let transaction: Box<Transaction> = transaction.into();
                    let tx_hash = transaction.hash();
                    self_.channel.send(transaction).map_err(|e| ApiError::Events(e))?;
                    let json = TransactionResponse { tx_hash };
                    self_.ok_response(&serde_json::to_value(&json).unwrap())
                }
                Ok(None) => Err(ApiError::IncorrectRequest("Empty request body".into()))?,
                Err(e) => Err(ApiError::IncorrectRequest(Box::new(e)))?,
            }
        };
        let route_post = "/v1/wallets/transaction";
        router.post(&route_post, transaction, "transaction");
    }
}

// // // // // // // // // // STORAGE DATA LAYOUT // // // // // // // // // //

pub struct CurrencySchema<'a> {
    view: &'a mut Fork,
}

impl<'a> CurrencySchema<'a> {
    pub fn wallets(&mut self) -> MapIndex<&mut Fork, PublicKey, Wallet> {
        let prefix = blockchain::gen_prefix(SERVICE_ID, 0, &());
        MapIndex::new(prefix, self.view)
    }

    pub fn wallet(&mut self, pub_key: &PublicKey) -> Option<Wallet> {
        self.wallets().get(pub_key)
    }
}

// // // // // // // // // // SERVICE DECLARATION // // // // // // // // // //

pub const SERVICE_ID: u16 = 1;

struct CurrencyService;

impl Service for CurrencyService {
    fn service_name(&self) -> &'static str { "cryptocurrency" }

    fn service_id(&self) -> u16 { SERVICE_ID }

    fn tx_from_raw(&self, raw: RawTransaction) -> Result<Box<Transaction>, encoding::Error> {
        let trans: Box<Transaction> = match raw.message_type() {
            TX_TRANSFER_ID => Box::new(TxTransfer::from_raw(raw)?),
            TX_CREATE_WALLET_ID => Box::new(TxCreateWallet::from_raw(raw)?),
            _ => {
                return Err(encoding::Error::IncorrectMessageType { message_type: raw.message_type() });
            },
        };
        Ok(trans)
    }

    fn public_api_handler(&self, ctx: &ApiContext) -> Option<Box<Handler>> {
        let mut router = Router::new();
        let api = CryptocurrencyApi {
            channel: ctx.node_channel().clone(),
        };
        api.wire(&mut router);
        Some(Box::new(router))
    }
}

// // // // // // // // // // ENTRY POINT // // // // // // // // // //

fn main() {
    exonum::helpers::init_logger().unwrap();

    println!("Creating in-memory database...");
    let db = MemoryDB::new();
    let services: Vec<Box<Service>> = vec![
        Box::new(CurrencyService),
    ];
    let blockchain = Blockchain::new(Box::new(db), services);

    let (public_key, secret_key) = exonum::crypto::gen_keypair();

    let peer_address = "0.0.0.0:2000".parse().unwrap();
    let api_address = "0.0.0.0:8000".parse().unwrap();

    let genesis = GenesisConfig::new(vec![public_key].into_iter());

    let api_cfg = NodeApiConfig {
        enable_blockchain_explorer: true,
        public_api_address: Some(api_address),
        private_api_address: None,
    };

    let node_cfg = NodeConfig {
        listen_address: peer_address,
        peers: vec![],
        public_key,
        secret_key,
        genesis,
        network: Default::default(),
        whitelist: Default::default(),
        api: api_cfg,
        mempool: Default::default(),
    };

    println!("Starting a single node...");
    let mut node = Node::new(blockchain, node_cfg);

    println!("Blockchain in ready for transactions!");
    node.run().unwrap();
}
<|endoftext|>


<commit_before>extern crate clap;
extern crate notify;
extern crate term;

use clap::App;
use notify::{RecommendedWatcher, Error, Watcher};
use std::sync::mpsc::channel;

use std::io::Write;
use std::thread;
use std::string::String;
use std::path::Path;
use std::process::Command;
use std::convert::Into;

fn out<S:Into<String>>(label: &str, msg: S, color: term::color::Color) -> std::io::Result<()> {
  let mut out = term::stdout().unwrap();
  try!(out.reset());
  try!(out.fg(color));
  try!(write!(&mut std::io::stdout(), "{:>12}", label.to_owned()));
  try!(out.reset());
  try!(write!(&mut std::io::stdout(), " {}\n", msg.into()));
  try!(out.flush());
  Ok(())
}

fn err<S:Into<String>>(label: &str, msg: S) -> std::io::Result<()> {
  let mut out = term::stderr().unwrap();
  try!(out.reset());
  try!(out.fg(term::color::RED));
  try!(write!(&mut std::io::stderr(), "{:>12}", label.to_owned()));
  try!(out.reset());
  try!(write!(&mut std::io::stderr(), " {}\n", msg.into()));
  try!(out.flush());
  Ok(())
}

fn main() {
  let matches = App::new("capgun")
    .about("fires off commands when files change")
    .args_from_usage(
      "-c, --command=<CMD> 'cmd to run when files under <INPUT> change'
       <INPUT> 'Sets the directory to watch'"
    )
    .get_matches();

  let cmd = matches.value_of("CMD").unwrap();
  let input = matches.value_of("INPUT").unwrap();

  let _ = out("Watching", input, term::color::BRIGHT_CYAN);

  let (tx, rx) = channel();
  let watch: Result<RecommendedWatcher, Error> = Watcher::new(tx);

  match watch {
    Ok(mut watcher) =>  {
      match watcher.watch(&Path::new(input)) {
        Ok(_) => {},
        Err(e) => {
          let _ = err("Error", format!("Failed to load gun {:?}", e));
          return
        },
      }

      loop {
        thread::sleep_ms(5000);
        match rx.recv() {
          Ok(e) => fire(e, cmd),
          Err(e) => {
            let _ = err("Missfire", &(format!("{:?}", e)[..]));
            return
          }
        }
      }
    },
    Err(_) => println!("Couldn't generate directory watcher")
  }
}

fn fire(e: notify::Event, cmd:  &str) {
  match e.op {
    Ok(_) => {
      let mut split = cmd.split(" ");
      let mut task = Command::new(split.next().unwrap());
      for s in split {
        task.arg(s);
      }
      let output = task.output()
        .unwrap_or_else(|e| panic!("Failed to fire: {} {}", cmd, e));

      println!("{}", String::from_utf8_lossy(&output.stdout));
      match writeln!(&mut std::io::stderr(), "{}", String::from_utf8_lossy(&output.stderr)) {
        Err(x) => panic!("Unable to write to stderr: {}", x),
        Ok(_) => {}
      }
      if output.status.success() {
        let _ = out("Hit", cmd, term::color::BRIGHT_GREEN);
      } else {
        let _ = err("Miss", cmd);
      }
    },
    Err(e) => println!("{:?}", e),
  }
}
<commit_msg>prefix labels<commit_after>extern crate clap;
extern crate notify;
extern crate term;

use clap::App;
use notify::{RecommendedWatcher, Error, Watcher};
use std::io::Write;
use std::thread;
use std::string::String;
use std::path::Path;
use std::process::Command;
use std::convert::Into;
use std::sync::mpsc::channel;
use term::color;

fn out<S:Into<String>>(label: &str, msg: S, color: color::Color) -> std::io::Result<()> {
  let mut out = term::stdout().unwrap();
  try!(out.reset());
  try!(out.fg(color));
  try!(write!(&mut std::io::stdout(), "{:>12}", format!("Capgun {}", label)));
  try!(out.reset());
  try!(write!(&mut std::io::stdout(), " {}\n", msg.into()));
  try!(out.flush());
  Ok(())
}

fn err<S:Into<String>>(label: &str, msg: S) -> std::io::Result<()> {
  let mut out = term::stderr().unwrap();
  try!(out.reset());
  try!(out.fg(color::RED));
  try!(write!(&mut std::io::stderr(), "{:>12}", format!("Capgun {}", label)));
  try!(out.reset());
  try!(write!(&mut std::io::stderr(), " {}\n", msg.into()));
  try!(out.flush());
  Ok(())
}

fn main() {
  let matches = App::new("capgun")
    .about("fires off commands when files change")
    .args_from_usage(
      "-c, --command=<CMD> 'cmd to run when files under <INPUT> change'
       <INPUT> 'Sets the directory to watch'"
    )
    .get_matches();

  let cmd = matches.value_of("CMD").unwrap();
  let input = matches.value_of("INPUT").unwrap();

  let _ = out("Watching", input, color::BRIGHT_CYAN);

  let (tx, rx) = channel();
  let watch: Result<RecommendedWatcher, Error> = Watcher::new(tx);

  match watch {
    Ok(mut watcher) =>  {
      match watcher.watch(&Path::new(input)) {
        Ok(_) => {},
        Err(e) => {
          let _ = err("Error", format!("Failed to load gun {:?}", e));
          return
        },
      }

      loop {
        thread::sleep_ms(5000);
        match rx.recv() {
          Ok(e) => fire(e, cmd),
          Err(e) => {
            let _ = err("Missfire", &(format!("{:?}", e)[..]));
            return
          }
        }
      }
    },
    Err(_) => println!("Couldn't generate directory watcher")
  }
}

fn fire(e: notify::Event, cmd:  &str) {
  match e.op {
    Ok(_) => {
      let mut split = cmd.split(" ");
      let mut task = Command::new(split.next().unwrap());
      for s in split {
        task.arg(s);
      }
      let output = task.output()
        .unwrap_or_else(|e| panic!("Failed to fire: {} {}", cmd, e));

      println!("{}", String::from_utf8_lossy(&output.stdout));
      match writeln!(&mut std::io::stderr(), "{}", String::from_utf8_lossy(&output.stderr)) {
        Err(x) => panic!("Unable to write to stderr: {}", x),
        Ok(_) => {}
      }
      if output.status.success() {
        let _ = out("Hit", cmd, color::BRIGHT_GREEN);
      } else {
        let _ = err("Miss", cmd);
      }
    },
    Err(e) => println!("{:?}", e),
  }
}
<|endoftext|>


<commit_before>use std::env;

extern crate pihex;
use pihex::*;

fn main() {
    let place: u64 = env::args().nth(1).and_then(|x| x.parse().ok()).unwrap_or(0);
    print!("{}:", place);
    for i in 0..8 {
        print!(" {}", bbp::pihex(place + 4 * i));
    }
    print!("\n")
}
<commit_msg>use clap-rs to parse arguments, support --formula={bbp,bellard} flag<commit_after>#[macro_use]
extern crate clap;

extern crate pihex;
use pihex::*;

fn main() {
    let matches = clap_app!(pihex =>
        (version: "1.0")
        (author: "itchyny <itchyny@hatena.ne.jp>")
        (about: "Arbitrary place hexadecimal digits viewer of pi written in Rust")
        (@arg FORMULA: --formula +takes_value "Formula to use (bbp or bellard)")
        (@arg PLACE: "Place of digits to calculate (defaults to 0)"))
        .get_matches();
    let pihex: fn(u64) -> String = match matches.value_of("FORMULA") {
        Some("bellard") => bellard::pihex,
        _ => bbp::pihex,
    };
    let place: u64 = matches.value_of("PLACE").and_then(|x| x.parse().ok()).unwrap_or(0);
    print!("{}:", place);
    for i in 0..8 {
        print!(" {}", pihex(place + 4 * i));
    }
    print!("\n")
}
<|endoftext|>


<commit_before>extern crate ansi_term;

use ansi_term::Colour;

use std::env;
use std::fs;
use std::path;
use std::vec;

fn main() {
    let curdir = env::current_dir().unwrap();
    explore(&curdir);
}

trait IsDir {
    fn is_dir(&self) -> bool;
}

impl IsDir for fs::DirEntry {
    fn is_dir(&self) -> bool {
        self.metadata().unwrap().is_dir()
    }
}

impl IsDir for path::PathBuf {
    fn is_dir(&self) -> bool {
        fs::metadata(self).unwrap().is_dir()
    }
}

trait DisplayColour {
    fn display_colour(&self) -> String;
}

impl DisplayColour for path::PathBuf {
    fn display_colour(&self) -> String {
        match self.is_dir() {
            true => Colour::Yellow.bold().paint(self.to_str().unwrap()).to_string(),
            false => String::from(self.to_str().unwrap()),
        }
    }
}

fn explore(path: &path::PathBuf) -> () {
    println!("{}", path.display_colour());

    if !path.is_dir() {
        return;
    }

    let mut q: Vec<path::PathBuf> = Vec::new();
    for item in fs::read_dir(path).unwrap() {
        let f = item.unwrap(); // f is a DirEntry
        match f.is_dir() {
            true => {
                q.push(f.path());
            },
            false => {
                explore(&f.path());
            },
        };
    }

    for d in q {
        explore(&d);
    }
}
<commit_msg>Add ignored paths<commit_after>extern crate ansi_term;

use ansi_term::Colour;

use std::env;
use std::fs;
use std::path;

static IGNORE_PATHS: [&'static str; 1] = [
    ".git",
];

fn main() {
    let curdir = env::current_dir().unwrap();
    explore(&curdir);
}

trait IsDir {
    fn is_dir(&self) -> bool;
}

impl IsDir for fs::DirEntry {
    fn is_dir(&self) -> bool {
        self.metadata().unwrap().is_dir()
    }
}

impl IsDir for path::PathBuf {
    fn is_dir(&self) -> bool {
        fs::metadata(self).unwrap().is_dir()
    }
}

trait DisplayColour {
    fn display_colour(&self) -> String;
}

impl DisplayColour for path::PathBuf {
    fn display_colour(&self) -> String {
        match self.is_dir() {
            true => Colour::Yellow.bold().paint(self.to_str().unwrap()).to_string(),
            false => String::from(self.to_str().unwrap()),
        }
    }
}

fn explore(path: &path::PathBuf) -> () {
    if !path.is_dir() {
        println!("{}", path.display_colour());
        return;
    }

    if IGNORE_PATHS.contains(&path.file_name().unwrap().to_str().unwrap()) {
        return;
    }
    println!("{}:", path.display_colour());

    let mut q: Vec<path::PathBuf> = Vec::new();
    for item in fs::read_dir(path).unwrap() {
        let f = item.unwrap(); // f is a DirEntry
        match f.is_dir() {
            true => {
                q.push(f.path());
            },
            false => {
                explore(&f.path());
            },
        };
    }

    print!("\n");

    for d in q {
        explore(&d);
    }
}
<|endoftext|>


<commit_before>extern crate serde;
extern crate serde_json;
#[macro_use] extern crate serde_derive;
#[macro_use] extern crate exonum;
extern crate router;
extern crate bodyparser;
extern crate iron;

use exonum::blockchain::{self, Blockchain, Service, GenesisConfig, Transaction, ApiContext};
use exonum::messages::{RawTransaction, FromRaw, Message};
use exonum::node::{Node, NodeConfig, NodeApiConfig, TransactionSend};
use exonum::storage::{Fork, MemoryDB, MapIndex};
use exonum::crypto::{PublicKey, Hash};
use exonum::encoding::{self, Field};
use exonum::api::{Api, ApiError};
use iron::prelude::*;
use iron::Handler;
use router::Router;

// // // // // // // // // // PERSISTENT DATA // // // // // // // // // //

encoding_struct! {
    struct Wallet {
        const SIZE = 48;

        field pub_key:            &PublicKey  [00 => 32]
        field name:               &str        [32 => 40]
        field balance:            u64         [40 => 48]
    }
}

impl Wallet {
    pub fn increase(&mut self, amount: u64) {
        let balance = self.balance() + amount;
        Field::write(&balance, &mut self.raw, 40, 48);
    }

    pub fn decrease(&mut self, amount: u64) {
        let balance = self.balance() - amount;
        Field::write(&balance, &mut self.raw, 40, 48);
    }
}

// // // // // // // // // // TRANSACTIONS // // // // // // // // // //

pub const TX_WALLET_ID: u16 = 1;

message! {
    struct TxCreateWallet {
        const TYPE = SERVICE_ID;
        const ID = TX_WALLET_ID;
        const SIZE = 40;

        field pub_key:     &PublicKey  [00 => 32]
        field name:        &str        [32 => 40]
    }
}

pub const TX_ISSUE_ID: u16 = 2;

message! {
    struct TxIssue {
        const TYPE = SERVICE_ID;
        const ID = TX_ISSUE_ID;
        const SIZE = 48;

        field pub_key:     &PublicKey  [00 => 32]
        field amount:      u64         [32 => 40]
        field seed:        u64         [40 => 48]
    }
}

pub const TX_TRANSFER_ID: u16 = 3;

message! {
    struct TxTransfer {
        const TYPE = SERVICE_ID;
        const ID = TX_TRANSFER_ID;
        const SIZE = 80;

        field from:        &PublicKey  [00 => 32]
        field to:          &PublicKey  [32 => 64]
        field amount:      u64         [64 => 72]
        field seed:        u64         [72 => 80]
    }
}

// // // // // // // // // // CONTRACTS // // // // // // // // // //

impl Transaction for TxCreateWallet {
    fn verify(&self) -> bool {
        self.verify_signature(self.pub_key())
    }

    fn execute(&self, view: &mut Fork) {
        let mut schema = CurrencySchema { view };
        if let None = schema.wallet(self.pub_key()) {
            let wallet = Wallet::new(self.pub_key(), self.name(), 0);
            println!("Create the wallet: {:?}", wallet);
            schema.wallets().put(self.pub_key(), wallet)
        }
    }
}

impl Transaction for TxIssue {
    fn verify(&self) -> bool {
        self.verify_signature(self.pub_key())
    }

    fn execute(&self, view: &mut Fork) {
        let mut schema = CurrencySchema { view };
        if let Some(mut wallet) = schema.wallet(self.pub_key()) {
            wallet.increase(self.amount());
            println!("Add funds to wallet: {:?}", wallet);
            schema.wallets().put(self.pub_key(), wallet)
        }
    }
}

impl Transaction for TxTransfer {
    fn verify(&self) -> bool {
        (*self.from() != *self.to()) && self.verify_signature(self.from())
    }

    fn execute(&self, view: &mut Fork) {
        let mut schema = CurrencySchema { view };
        let sender = schema.wallet(self.from());
        let receiver = schema.wallet(self.to());
        if let (Some(mut sender), Some(mut receiver)) = (sender, receiver) {
            let amount = self.amount();
            if sender.balance() >= amount {
                sender.decrease(amount);
                receiver.increase(amount);
                println!("Transfer between wallets: {:?} => {:?}", sender, receiver);
                let mut wallets = schema.wallets();
                wallets.put(self.from(), sender);
                wallets.put(self.to(), receiver);
            }
        }
    }
}

// // // // // // // // // // REST API // // // // // // // // // //

#[derive(Clone)]
struct CryptocurrencyApi<T> {
    channel: T,
}

impl<T: TransactionSend + Clone + 'static> Api for CryptocurrencyApi<T> {
    fn wire(&self, router: &mut Router) {

        #[serde(untagged)]
        #[derive(Clone, Serialize, Deserialize)]
        enum TransactionRequest {
            CreateWallet(TxCreateWallet),
            Issue(TxIssue),
            Transfer(TxTransfer),
        }

        impl Into<Box<Transaction>> for TransactionRequest {
            fn into(self) -> Box<Transaction> {
                match self {
                    TransactionRequest::CreateWallet(trans) => Box::new(trans),
                    TransactionRequest::Issue(trans) => Box::new(trans),
                    TransactionRequest::Transfer(trans) => Box::new(trans),
                }
            }
        }

        #[derive(Serialize, Deserialize)]
        struct TransactionResponse {
            tx_hash: Hash,
        }

        let self_ = self.clone();
        let transaction = move |req: &mut Request| -> IronResult<Response> {
            match req.get::<bodyparser::Struct<TransactionRequest>>() {
                Ok(Some(transaction)) => {
                    let transaction: Box<Transaction> = transaction.into();
                    let tx_hash = transaction.hash();
                    self_.channel.send(transaction).map_err(|e| ApiError::Events(e))?;
                    let json = TransactionResponse { tx_hash };
                    self_.ok_response(&serde_json::to_value(&json).unwrap())
                }
                Ok(None) => Err(ApiError::IncorrectRequest("Empty request body".into()))?,
                Err(e) => Err(ApiError::IncorrectRequest(Box::new(e)))?,
            }
        };
        let route_post = "/v1/wallets/transaction";
        router.post(&route_post, transaction, "transaction");
    }
}

// // // // // // // // // // STORAGE DATA LAYOUT // // // // // // // // // //

pub struct CurrencySchema<'a> {
    view: &'a mut Fork,
}

impl<'a> CurrencySchema<'a> {
    pub fn wallets(&mut self) -> MapIndex<&mut Fork, PublicKey, Wallet> {
        let prefix = blockchain::gen_prefix(SERVICE_ID, 0, &());
        MapIndex::new(prefix, self.view)
    }

    pub fn wallet(&mut self, pub_key: &PublicKey) -> Option<Wallet> {
        self.wallets().get(pub_key)
    }
}

// // // // // // // // // // SERVICE DECLARATION // // // // // // // // // //

pub const SERVICE_ID: u16 = 1;

struct CurrencyService;

impl Service for CurrencyService {
    fn service_name(&self) -> &'static str { "cryptocurrency" }

    fn service_id(&self) -> u16 { SERVICE_ID }

    fn tx_from_raw(&self, raw: RawTransaction) -> Result<Box<Transaction>, encoding::Error> {
        let trans: Box<Transaction> = match raw.message_type() {
            TX_TRANSFER_ID => Box::new(TxTransfer::from_raw(raw)?),
            TX_ISSUE_ID => Box::new(TxIssue::from_raw(raw)?),
            TX_WALLET_ID => Box::new(TxCreateWallet::from_raw(raw)?),
            _ => {
                return Err(encoding::Error::IncorrectMessageType { message_type: raw.message_type() });
            },
        };
        Ok(trans)
    }

    fn public_api_handler(&self, ctx: &ApiContext) -> Option<Box<Handler>> {
        let mut router = Router::new();
        let api = CryptocurrencyApi {
            channel: ctx.node_channel().clone(),
        };
        api.wire(&mut router);
        Some(Box::new(router))
    }
}

// // // // // // // // // // ENTRY POINT // // // // // // // // // //

fn main() {
    exonum::crypto::init();
    exonum::helpers::init_logger().unwrap();

    println!("Creating in-memory database...");
    let db = MemoryDB::new();
    let services: Vec<Box<Service>> = vec![
        Box::new(CurrencyService),
    ];
    let blockchain = Blockchain::new(Box::new(db), services);

    let (public_key, secret_key) = exonum::crypto::gen_keypair();

    let peer_address = "0.0.0.0:2000".parse().unwrap();
    let api_address = "0.0.0.0:8000".parse().unwrap();

    let genesis = GenesisConfig::new(vec![public_key].into_iter());

    let api_cfg = NodeApiConfig {
        enable_blockchain_explorer: true,
        public_api_address: Some(api_address),
        private_api_address: None,
    };

    let node_cfg = NodeConfig {
        listen_address: peer_address,
        peers: vec![],
        public_key,
        secret_key,
        genesis,
        network: Default::default(),
        whitelist: Default::default(),
        api: api_cfg,
        mempool: Default::default(),
    };

    println!("Starting a single node...");
    let mut node = Node::new(blockchain, node_cfg);

    println!("Blockchain in ready for transactions!");
    node.run().unwrap();
}
<commit_msg>Remove unnecessary cryptography initialization<commit_after>extern crate serde;
extern crate serde_json;
#[macro_use] extern crate serde_derive;
#[macro_use] extern crate exonum;
extern crate router;
extern crate bodyparser;
extern crate iron;

use exonum::blockchain::{self, Blockchain, Service, GenesisConfig, Transaction, ApiContext};
use exonum::messages::{RawTransaction, FromRaw, Message};
use exonum::node::{Node, NodeConfig, NodeApiConfig, TransactionSend};
use exonum::storage::{Fork, MemoryDB, MapIndex};
use exonum::crypto::{PublicKey, Hash};
use exonum::encoding::{self, Field};
use exonum::api::{Api, ApiError};
use iron::prelude::*;
use iron::Handler;
use router::Router;

// // // // // // // // // // PERSISTENT DATA // // // // // // // // // //

encoding_struct! {
    struct Wallet {
        const SIZE = 48;

        field pub_key:            &PublicKey  [00 => 32]
        field name:               &str        [32 => 40]
        field balance:            u64         [40 => 48]
    }
}

impl Wallet {
    pub fn increase(&mut self, amount: u64) {
        let balance = self.balance() + amount;
        Field::write(&balance, &mut self.raw, 40, 48);
    }

    pub fn decrease(&mut self, amount: u64) {
        let balance = self.balance() - amount;
        Field::write(&balance, &mut self.raw, 40, 48);
    }
}

// // // // // // // // // // TRANSACTIONS // // // // // // // // // //

pub const TX_WALLET_ID: u16 = 1;

message! {
    struct TxCreateWallet {
        const TYPE = SERVICE_ID;
        const ID = TX_WALLET_ID;
        const SIZE = 40;

        field pub_key:     &PublicKey  [00 => 32]
        field name:        &str        [32 => 40]
    }
}

pub const TX_ISSUE_ID: u16 = 2;

message! {
    struct TxIssue {
        const TYPE = SERVICE_ID;
        const ID = TX_ISSUE_ID;
        const SIZE = 48;

        field pub_key:     &PublicKey  [00 => 32]
        field amount:      u64         [32 => 40]
        field seed:        u64         [40 => 48]
    }
}

pub const TX_TRANSFER_ID: u16 = 3;

message! {
    struct TxTransfer {
        const TYPE = SERVICE_ID;
        const ID = TX_TRANSFER_ID;
        const SIZE = 80;

        field from:        &PublicKey  [00 => 32]
        field to:          &PublicKey  [32 => 64]
        field amount:      u64         [64 => 72]
        field seed:        u64         [72 => 80]
    }
}

// // // // // // // // // // CONTRACTS // // // // // // // // // //

impl Transaction for TxCreateWallet {
    fn verify(&self) -> bool {
        self.verify_signature(self.pub_key())
    }

    fn execute(&self, view: &mut Fork) {
        let mut schema = CurrencySchema { view };
        if let None = schema.wallet(self.pub_key()) {
            let wallet = Wallet::new(self.pub_key(), self.name(), 0);
            println!("Create the wallet: {:?}", wallet);
            schema.wallets().put(self.pub_key(), wallet)
        }
    }
}

impl Transaction for TxIssue {
    fn verify(&self) -> bool {
        self.verify_signature(self.pub_key())
    }

    fn execute(&self, view: &mut Fork) {
        let mut schema = CurrencySchema { view };
        if let Some(mut wallet) = schema.wallet(self.pub_key()) {
            wallet.increase(self.amount());
            println!("Add funds to wallet: {:?}", wallet);
            schema.wallets().put(self.pub_key(), wallet)
        }
    }
}

impl Transaction for TxTransfer {
    fn verify(&self) -> bool {
        (*self.from() != *self.to()) && self.verify_signature(self.from())
    }

    fn execute(&self, view: &mut Fork) {
        let mut schema = CurrencySchema { view };
        let sender = schema.wallet(self.from());
        let receiver = schema.wallet(self.to());
        if let (Some(mut sender), Some(mut receiver)) = (sender, receiver) {
            let amount = self.amount();
            if sender.balance() >= amount {
                sender.decrease(amount);
                receiver.increase(amount);
                println!("Transfer between wallets: {:?} => {:?}", sender, receiver);
                let mut wallets = schema.wallets();
                wallets.put(self.from(), sender);
                wallets.put(self.to(), receiver);
            }
        }
    }
}

// // // // // // // // // // REST API // // // // // // // // // //

#[derive(Clone)]
struct CryptocurrencyApi<T> {
    channel: T,
}

impl<T: TransactionSend + Clone + 'static> Api for CryptocurrencyApi<T> {
    fn wire(&self, router: &mut Router) {

        #[serde(untagged)]
        #[derive(Clone, Serialize, Deserialize)]
        enum TransactionRequest {
            CreateWallet(TxCreateWallet),
            Issue(TxIssue),
            Transfer(TxTransfer),
        }

        impl Into<Box<Transaction>> for TransactionRequest {
            fn into(self) -> Box<Transaction> {
                match self {
                    TransactionRequest::CreateWallet(trans) => Box::new(trans),
                    TransactionRequest::Issue(trans) => Box::new(trans),
                    TransactionRequest::Transfer(trans) => Box::new(trans),
                }
            }
        }

        #[derive(Serialize, Deserialize)]
        struct TransactionResponse {
            tx_hash: Hash,
        }

        let self_ = self.clone();
        let transaction = move |req: &mut Request| -> IronResult<Response> {
            match req.get::<bodyparser::Struct<TransactionRequest>>() {
                Ok(Some(transaction)) => {
                    let transaction: Box<Transaction> = transaction.into();
                    let tx_hash = transaction.hash();
                    self_.channel.send(transaction).map_err(|e| ApiError::Events(e))?;
                    let json = TransactionResponse { tx_hash };
                    self_.ok_response(&serde_json::to_value(&json).unwrap())
                }
                Ok(None) => Err(ApiError::IncorrectRequest("Empty request body".into()))?,
                Err(e) => Err(ApiError::IncorrectRequest(Box::new(e)))?,
            }
        };
        let route_post = "/v1/wallets/transaction";
        router.post(&route_post, transaction, "transaction");
    }
}

// // // // // // // // // // STORAGE DATA LAYOUT // // // // // // // // // //

pub struct CurrencySchema<'a> {
    view: &'a mut Fork,
}

impl<'a> CurrencySchema<'a> {
    pub fn wallets(&mut self) -> MapIndex<&mut Fork, PublicKey, Wallet> {
        let prefix = blockchain::gen_prefix(SERVICE_ID, 0, &());
        MapIndex::new(prefix, self.view)
    }

    pub fn wallet(&mut self, pub_key: &PublicKey) -> Option<Wallet> {
        self.wallets().get(pub_key)
    }
}

// // // // // // // // // // SERVICE DECLARATION // // // // // // // // // //

pub const SERVICE_ID: u16 = 1;

struct CurrencyService;

impl Service for CurrencyService {
    fn service_name(&self) -> &'static str { "cryptocurrency" }

    fn service_id(&self) -> u16 { SERVICE_ID }

    fn tx_from_raw(&self, raw: RawTransaction) -> Result<Box<Transaction>, encoding::Error> {
        let trans: Box<Transaction> = match raw.message_type() {
            TX_TRANSFER_ID => Box::new(TxTransfer::from_raw(raw)?),
            TX_ISSUE_ID => Box::new(TxIssue::from_raw(raw)?),
            TX_WALLET_ID => Box::new(TxCreateWallet::from_raw(raw)?),
            _ => {
                return Err(encoding::Error::IncorrectMessageType { message_type: raw.message_type() });
            },
        };
        Ok(trans)
    }

    fn public_api_handler(&self, ctx: &ApiContext) -> Option<Box<Handler>> {
        let mut router = Router::new();
        let api = CryptocurrencyApi {
            channel: ctx.node_channel().clone(),
        };
        api.wire(&mut router);
        Some(Box::new(router))
    }
}

// // // // // // // // // // ENTRY POINT // // // // // // // // // //

fn main() {
    exonum::helpers::init_logger().unwrap();

    println!("Creating in-memory database...");
    let db = MemoryDB::new();
    let services: Vec<Box<Service>> = vec![
        Box::new(CurrencyService),
    ];
    let blockchain = Blockchain::new(Box::new(db), services);

    let (public_key, secret_key) = exonum::crypto::gen_keypair();

    let peer_address = "0.0.0.0:2000".parse().unwrap();
    let api_address = "0.0.0.0:8000".parse().unwrap();

    let genesis = GenesisConfig::new(vec![public_key].into_iter());

    let api_cfg = NodeApiConfig {
        enable_blockchain_explorer: true,
        public_api_address: Some(api_address),
        private_api_address: None,
    };

    let node_cfg = NodeConfig {
        listen_address: peer_address,
        peers: vec![],
        public_key,
        secret_key,
        genesis,
        network: Default::default(),
        whitelist: Default::default(),
        api: api_cfg,
        mempool: Default::default(),
    };

    println!("Starting a single node...");
    let mut node = Node::new(blockchain, node_cfg);

    println!("Blockchain in ready for transactions!");
    node.run().unwrap();
}
<|endoftext|>


<commit_before>use std::old_io;

fn main() {
    println!("Hello, it's a guessing game!");
    println!("I'll draw a number between 1-10 and you need to guess which one.");
    println!("Only one shot!");

    let input = old_io::stdin().read_line().ok().expect("You need to pass nummber");

    // It seems, that we need to remove newline before parsing (bug?)
    let parsed_input: Result<u32, _> = input.trim_right_matches("\n").parse();

    let num = match parsed_input {
        Ok(num) => num,
        Err(_) => {
            println!("Please input number!");
            return;
        }
    };

    println!("Your number is: {}", num);
}
<commit_msg>Final version from book<commit_after>use std::old_io;
use std::rand;

fn main() {
    let random = (rand::random::<u32>() % 10) + 1;
    println!("{}", random);
    println!("Hello, it's a guessing game!");
    println!("I'll draw a number between 1-10 and you need to guess which one.");
    println!("Only one shot!");

    let input = old_io::stdin().read_line().ok().expect("You need to pass nummber");

    // It seems, that we need to remove newline before parsing (bug?)
    let parsed_input: Result<u32, _> = input.trim_right_matches("\n").parse();

    let num = match parsed_input {
        Ok(num) => num,
        Err(_) => {
            println!("Please input number!");
            return;
        }
    };

    if random == num {
        println!("You won!");
    } else {
        println!("Looser!");
    }
}
<|endoftext|>


<commit_before>extern crate ordered_float;
extern crate thrift;
extern crate try_from;

mod kv_server;

use std::cell::RefCell;
use std::rc::Rc;
use thrift::protocol::{TInputProtocolFactory, TOutputProtocolFactory};
use thrift::protocol::{TCompactInputProtocolFactory, TCompactOutputProtocolFactory};
use thrift::server::TSimpleServer;

use thrift::transport::{TFramedTransportFactory, TTransportFactory};

use kv_server::{KeyNotFound, ServiceException};
use kv_server::{KVObject};

fn main() {
    println!("Hello, world!");
}
<commit_msg>Codegen<commit_after>extern crate ordered_float;
extern crate thrift;
extern crate try_from;

mod kv_server;

use std::cell::RefCell;
use std::rc::Rc;
use thrift::protocol::{TInputProtocolFactory, TOutputProtocolFactory};
use thrift::protocol::{TCompactInputProtocolFactory, TCompactOutputProtocolFactory};
use kv_server::{KeyNotFound, ServiceException};
use kv_server::{KVObject};

fn main() {
    println!("Hello, world!");
}
<|endoftext|>


<commit_before>struct AddressSpace {
    data: [u8; 0xFFFF],
}

impl AddressSpace {

    fn new() -> AddressSpace {
        AddressSpace { data: [0; 0xFFFF] }
    }

    fn read(&self, addr: u16) -> u8 {
        self.data[addr as usize]
    }

    fn read_slice(&self, addr: u16, bytes: u16) -> &[u8] {
        self.data.slice(addr as usize, (addr + bytes) as usize)
    }

    fn write(&mut self, addr: u16, data: u8) {
        self.data[addr as usize] = data;
    }

}

struct Instr<'a> {
    opcode: u8,
    data: Option<&'a [u8]>,
}

impl<'a> Instr<'a> {

    fn new(opcode: u8, data: Option<&[u8]>) -> Instr {
        Instr { opcode: opcode, data: data }
    }

    fn opcode(&self) -> u8 {
        self.opcode
    }

    fn param(&self, i: usize) -> u8 {
        self.data.expect("Instruction type does not carry parameters")[i]
    }

}

struct InstrParser<'a> {
    rom: &'a AddressSpace,
    pc: u16,
}

impl<'a> InstrParser<'a> {

    fn new(rom: &AddressSpace) -> InstrParser {
        InstrParser { rom: rom, pc: 0x100 }
    }

    fn next_instr(&mut self) -> Instr {
        let opcode = self.rom.read(self.pc);
        self.pc += 1;
        Instr {
            opcode: opcode,
            data: None,
        }
    }

    fn set_pc(&mut self, pc: u16) {
        self.pc = pc;
    }

}

enum RegFlag {
    Zero,
    Subtract,
    HalfCarry,
    Carry,
}

enum Register {
    A,
    B,
    C,
    D,
    E,
    F,
    H,
    L,
    AF,
    BC,
    DE,
    HL,
    SP,
    Flag,
}

struct RegData {
    a: u8,
    b: u8,
    c: u8,
    d: u8,
    e: u8,
    f: u8,
    h: u8,
    l: u8,
    sp: u16,
    flag: u8,
}

impl RegData {

    fn new() -> RegData {
        RegData {
            a: 0,
            b: 0,
            c: 0,
            d: 0,
            e: 0,
            f: 0,
            h: 0,
            l: 0,
            sp: 0xFFFE,
            flag: 0,
        }
    }

    fn read(&self, reg: Register) -> u8 {
        match reg {
            Register::A => self.a,
            Register::B => self.b,
            Register::C => self.c,
            Register::D => self.d,
            Register::E => self.e,
            Register::F => self.f,
            Register::H => self.h,
            Register::L => self.l,
            Register::Flag => self.flag,
            _ => panic!("Register not available for 8-bit read"),
        }
    }

    fn read_u16(&self, reg: Register) -> u16 {
        match reg {
            Register::AF => (self.a as u16) << 8 | self.f as u16,
            Register::BC => (self.b as u16) << 8 | self.c as u16,
            Register::DE => (self.d as u16) << 8 | self.e as u16,
            Register::HL => (self.h as u16) << 8 | self.l as u16,
            Register::SP => self.sp,
            _ => panic!("Register not available for 16-bit read"),
        }
    }

    fn write(&mut self, reg: Register, data: u8) {
        match reg {
            Register::A => self.a = data,
            Register::B => self.b = data,
            Register::C => self.c = data,
            Register::D => self.d = data,
            Register::E => self.e = data,
            Register::F => self.f = data,
            Register::H => self.h = data,
            Register::L => self.l = data,
            _ => panic!("Register not available for 8-bit write"),
        }
    }

    fn write_u16(&mut self, reg: Register, data: u16) {
        let (hi, lo) = ((data & 0xFF00 >> 8) as u8, (data & 0xFF) as u8);
        match reg {
            Register::AF => {
                self.a = hi;
                self.f = lo;
            },
            Register::BC => {
                self.b = hi;
                self.c = lo;
            },
            Register::DE => {
                self.d = hi;
                self.c = lo;
            },
            Register::HL => {
                self.h = hi;
                self.l = lo;
            },
            Register::SP => self.sp = data,
            _ => panic!("Register not available for 16-bit write"),
        }
    }

    fn set_flag(&mut self, flag: RegFlag, on: bool) {
        let bit = match flag {
            RegFlag::Zero => 0x80,
            RegFlag::Subtract => 0x40,
            RegFlag::HalfCarry => 0x20,
            RegFlag::Carry => 0x10,
        };
        if (on) {
            self.flag |= bit;
        } else {
            self.flag &= bit ^ 0xFF;
        }
    }

}

fn main() {
    println!("Hello, world!");
}
<commit_msg>Implement initial CPU design<commit_after>struct AddressSpace {
    data: [u8; 0xFFFF],
}

impl AddressSpace {

    fn new() -> AddressSpace {
        AddressSpace { data: [0; 0xFFFF] }
    }

    fn read(&self, addr: u16) -> u8 {
        self.data[addr as usize]
    }

    fn read_slice(&self, addr: u16, bytes: u16) -> &[u8] {
        self.data.slice(addr as usize, (addr + bytes) as usize)
    }

    fn write(&mut self, addr: u16, data: u8) {
        self.data[addr as usize] = data;
    }

}

struct Instr<'a> {
    opcode: u8,
    data: Option<&'a [u8]>,
}

impl<'a> Instr<'a> {

    fn new(opcode: u8, data: Option<&[u8]>) -> Instr {
        Instr { opcode: opcode, data: data }
    }

    fn opcode(&self) -> u8 {
        self.opcode
    }

    fn param(&self, i: usize) -> u8 {
        self.data.expect("Instruction type does not carry parameters")[i]
    }

}

struct InstrParser {
    pc: u16,
}

impl InstrParser {

    fn new() -> InstrParser {
        InstrParser { pc: 0x100 }
    }

    fn next_instr(&mut self, rom: &AddressSpace) -> Instr {
        let opcode = rom.read(self.pc);
        self.pc += 1;
        Instr {
            opcode: opcode,
            data: None,
        }
    }

    fn set_pc(&mut self, pc: u16) {
        self.pc = pc;
    }

}

enum RegFlag {
    Zero,
    Subtract,
    HalfCarry,
    Carry,
}

enum Register {
    A,
    B,
    C,
    D,
    E,
    F,
    H,
    L,
    AF,
    BC,
    DE,
    HL,
    SP,
    Flag,
}

struct RegData {
    a: u8,
    b: u8,
    c: u8,
    d: u8,
    e: u8,
    f: u8,
    h: u8,
    l: u8,
    sp: u16,
    flag: u8,
}

impl RegData {

    fn new() -> RegData {
        RegData {
            a: 0,
            b: 0,
            c: 0,
            d: 0,
            e: 0,
            f: 0,
            h: 0,
            l: 0,
            sp: 0xFFFE,
            flag: 0,
        }
    }

    fn read(&self, reg: Register) -> u8 {
        match reg {
            Register::A => self.a,
            Register::B => self.b,
            Register::C => self.c,
            Register::D => self.d,
            Register::E => self.e,
            Register::F => self.f,
            Register::H => self.h,
            Register::L => self.l,
            Register::Flag => self.flag,
            _ => panic!("Register not available for 8-bit read"),
        }
    }

    fn read_u16(&self, reg: Register) -> u16 {
        match reg {
            Register::AF => (self.a as u16) << 8 | self.f as u16,
            Register::BC => (self.b as u16) << 8 | self.c as u16,
            Register::DE => (self.d as u16) << 8 | self.e as u16,
            Register::HL => (self.h as u16) << 8 | self.l as u16,
            Register::SP => self.sp,
            _ => panic!("Register not available for 16-bit read"),
        }
    }

    fn write(&mut self, reg: Register, data: u8) {
        match reg {
            Register::A => self.a = data,
            Register::B => self.b = data,
            Register::C => self.c = data,
            Register::D => self.d = data,
            Register::E => self.e = data,
            Register::F => self.f = data,
            Register::H => self.h = data,
            Register::L => self.l = data,
            _ => panic!("Register not available for 8-bit write"),
        }
    }

    fn write_u16(&mut self, reg: Register, data: u16) {
        let (hi, lo) = ((data & 0xFF00 >> 8) as u8, (data & 0xFF) as u8);
        match reg {
            Register::AF => {
                self.a = hi;
                self.f = lo;
            },
            Register::BC => {
                self.b = hi;
                self.c = lo;
            },
            Register::DE => {
                self.d = hi;
                self.c = lo;
            },
            Register::HL => {
                self.h = hi;
                self.l = lo;
            },
            Register::SP => self.sp = data,
            _ => panic!("Register not available for 16-bit write"),
        }
    }

    fn set_flag(&mut self, flag: RegFlag, on: bool) {
        let bit = match flag {
            RegFlag::Zero => 0x80,
            RegFlag::Subtract => 0x40,
            RegFlag::HalfCarry => 0x20,
            RegFlag::Carry => 0x10,
        };
        if (on) {
            self.flag |= bit;
        } else {
            self.flag &= bit ^ 0xFF;
        }
    }

}

static GB_FREQUENCY: u32 = 4194304;

struct Cpu {
    reg: RegData,
    ram: AddressSpace,
    instr_parser: InstrParser,
    freq: u32,
    clock: u64,
    cycle_block: u32,
}

impl Cpu {

    fn new() -> Cpu {
        Cpu::new_with_freq(GB_FREQUENCY)
    }

    fn new_with_freq(freq: u32) -> Cpu {
        Cpu {
            reg: RegData::new(),
            ram: AddressSpace::new(),
            instr_parser: InstrParser::new(),
            freq: freq,
            clock: 0,
            cycle_block: 0,
        }
    }

    fn do_cycle(&mut self) {
        self.clock += 1;
        if self.cycle_block > 0 {
            self.cycle_block -= 1;
        } else {
            let instr = self.instr_parser.next_instr(&self.ram);
            match instr.opcode() {
                _ => panic!("Instruction not implemented!"),
            }
        }
    }

}

fn main() {
    println!("Hello, world!");
}
<|endoftext|>