<commit_before>use std::env;
use std::f32;
use std::thread::sleep;
use std::time::Duration;

extern crate getopts;
use getopts::Options;
extern crate rand;
use rand::Rng;
use rand::distributions::{IndependentSample,Range};
extern crate sacn;
use sacn::DmxSource;

const DECAY_FACTOR: f32 = 2_f32;
const LIGHT_THRESHOLD: f32 = 0.10;
const MAX_BRIGHTNESS: f32 = 75_f32;

const UNIVERSE_SIZE: usize = 510;

#[derive(Debug)]
struct Params {
    decay:          f32,
    threshold:      f32,
    max_brightness: f32,
    sleep:          Duration
}

#[derive(Debug)]
#[derive(Clone)]
struct Pixel { level: i16, age: i16 }
// impl Pixel {
//     fn clone(&self) -> Pixel {
//         let mut pixel = Pixel { level: self.level, age: self.age };
//     }
// }

struct Zone  { head: u8, body: u8, tail: u8, name: String }

fn build_params () -> Params {
    // seed default params
    let mut params = Params { decay: 2_f32, threshold: 0.1, max_brightness: 75_f32, sleep: Duration::new(1, 500_000_000) };

    // parse command line args and adjust params accordingly
    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let mut opts = Options::new();
    opts.optopt("d", "decay", "slow decay by this factor, defaults to 2", "DECAY");
    opts.optopt("t", "threshold", "probablity that a pixel lights up, default 0.10", "THRESHOLD");
    opts.optopt("m", "maxbrightness", "maximum brightness, 1..255, default 75", "MAX");
    opts.optopt("s", "sleep", "sleep interval in seconds, default 1.5", "SECONDS");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(f) => { panic!(f.to_string()) }
    };
    if matches.opt_present("d") {
        params.decay = matches.opt_str("d").unwrap().parse::<f32>().unwrap();
    }
    if matches.opt_present("t") {
        params.threshold = matches.opt_str("t").unwrap().parse::<f32>().unwrap();
    }
    if matches.opt_present("m") {
        params.max_brightness = matches.opt_str("m").unwrap().parse::<f32>().unwrap();
    }
    if matches.opt_present("s") {
        // take float seconds
        // convert to int seconds and nanoseconds to make Duration happy
        let seconds: f32 = matches.opt_str("s").unwrap().parse::<f32>().unwrap();
        let whole_seconds: u64 = seconds as u64;
        let nano_seconds: u32 = ((seconds - whole_seconds as f32) * 1_000_000_000_f32) as u32;
        params.sleep = Duration::new(whole_seconds, nano_seconds);
    }
    return params;
}

fn main() {
    let params = build_params();

    let dmx = DmxSource::new("Controller").unwrap();

    let zones: [Zone; 6] = [
        Zone { head: 3, body: 47, tail: 0, name: "10".to_string() },
        Zone { head: 2, body: 92, tail: 2, name: "11a".to_string() },
        Zone { head: 2, body: 92, tail: 2, name: "11b".to_string() },
        Zone { head: 2, body: 90, tail: 3, name: "12a".to_string() },
        Zone { head: 2, body: 91, tail: 3, name: "12b".to_string() },
        Zone { head: 2, body: 43, tail: 0, name: "13".to_string() }
    ];

    let mut lights: Vec<Pixel> = vec![];
    // TODO: probably a more idiomatic way to built the default state
    for zone in zones.iter() {
        for i in 1..zone.body {
            let pixel = Pixel { level: 0, age: 0 };
            lights.push(pixel);
        }
    }

    let mut rng = rand::thread_rng();
    let bright_range = Range::new(0_f32, params.max_brightness);
    let zero_to_one = Range::new(0_f32, 1_f32);

    loop {
        for light in lights.iter_mut() {
            if light.level == 0 {
                // light is currently dark
                // test to see if we want to light it
                if zero_to_one.ind_sample(&mut rng) < params.threshold {
                    // we do, so pick a random
                    light.level = bright_range.ind_sample(&mut rng) as i16;
                    light.age += 1;
                }
            } else {
                // light is lit
                // test to see if we rise or fall
                // probability of falling should go up as light ages
                if zero_to_one.ind_sample(&mut rng) > 1.0/(light.age as f32) {
                    // falling
                    light.level -= (bright_range.ind_sample(&mut rng)/params.decay) as i16;
                    light.age += 1;
                    // test to see if we bottomed out
                    if light.level <= 0 {
                        light.level = 0;
                        light.age = 0;
                    }
                } else {
                    // rising
                    light.level += (zero_to_one.ind_sample(&mut rng) * (params.max_brightness - light.level as f32)) as i16;
                    light.age += 1;
                }
            }
        }
        render(&lights, &zones, &dmx);
        sleep(params.sleep);
    }
    dmx.terminate_stream(1);
}

// debug, rendor output to console
// fn render( lights: &[Pixel], zones: &[Zone], dmx: &DmxSource ) {
//    let mut out: Vec<i16> = vec![];
//    for light in lights {
//        out.push(light.level);
//   }
//    println!("{:?}", out)
//     let mut lit: u16 = 0;
//     let mut level: i16 = 0;
//     for light in lights {
//         if light.level > 0 {
//             lit += 1;
//             level += light.level;
//         }
//     }
//     println!("{} pixels, {} lit, {} avg level", lights.len(), lit, (level as f32)/(lit as f32));
// }

// output to lighting controller via sACN
fn render( lights: &[Pixel], zones: &[Zone], dmx: &DmxSource ) {
    let mut out: Vec<u8> = vec![];
    let mut copy: Vec<Pixel> = vec![];
    copy.extend_from_slice(lights);
    let mut idx: usize = 0;
    for zone in zones {
        // null pixels at head
        for i in 1..zone.head {
            out.push(0); // Red
            out.push(0); // Green
            out.push(0); // Blue
        }
        // set via light.level in the body
        for i in 0..(zone.body - 1) {
            out.push(copy[idx].level as u8); // Red
            out.push(copy[idx].level as u8); // Green
            out.push(copy[idx].level as u8); // Blue
            idx += 1;
        }
        // null pixels at tail
        for i in 1..zone.tail {
            out.push(0); // Red
            out.push(0); // Green
            out.push(0); // Blue
        }
    }
    let mut universes = Vec::new();
    while out.len() > UNIVERSE_SIZE {
        let u = out.split_off(UNIVERSE_SIZE);
        universes.push(out);
        out = u;
    }
    universes.push(out);
    let mut universe: u16 = 1;
    for u in universes {
        dmx.send(universe, &u);
        universe += 1;
    }
}

<commit_msg>pulling in the revised zone setup from lightbow<commit_after>use std::env;
use std::f32;
use std::thread::sleep;
use std::time::Duration;

extern crate getopts;
use getopts::Options;
extern crate rand;
use rand::Rng;
use rand::distributions::{IndependentSample,Range};
extern crate sacn;
use sacn::DmxSource;

const DECAY_FACTOR: f32 = 2_f32;
const LIGHT_THRESHOLD: f32 = 0.10;
const MAX_BRIGHTNESS: f32 = 75_f32;

const UNIVERSE_SIZE: usize = 510;

#[derive(Debug)]
struct Params {
    decay:          f32,
    threshold:      f32,
    max_brightness: f32,
    sleep:          Duration
}

#[derive(Debug)]
#[derive(Clone)]
struct Pixel { level: i16, age: i16 }
// impl Pixel {
//     fn clone(&self) -> Pixel {
//         let mut pixel = Pixel { level: self.level, age: self.age };
//     }
// }

struct Zone  { head: u8, body: u8, tail: u8, name: String }

fn build_params () -> Params {
    // seed default params
    let mut params = Params { decay: 2_f32, threshold: 0.1, max_brightness: 75_f32, sleep: Duration::new(1, 500_000_000) };

    // parse command line args and adjust params accordingly
    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let mut opts = Options::new();
    opts.optopt("d", "decay", "slow decay by this factor, defaults to 2", "DECAY");
    opts.optopt("t", "threshold", "probablity that a pixel lights up, default 0.10", "THRESHOLD");
    opts.optopt("m", "maxbrightness", "maximum brightness, 1..255, default 75", "MAX");
    opts.optopt("s", "sleep", "sleep interval in seconds, default 1.5", "SECONDS");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(f) => { panic!(f.to_string()) }
    };
    if matches.opt_present("d") {
        params.decay = matches.opt_str("d").unwrap().parse::<f32>().unwrap();
    }
    if matches.opt_present("t") {
        params.threshold = matches.opt_str("t").unwrap().parse::<f32>().unwrap();
    }
    if matches.opt_present("m") {
        params.max_brightness = matches.opt_str("m").unwrap().parse::<f32>().unwrap();
    }
    if matches.opt_present("s") {
        // take float seconds
        // convert to int seconds and nanoseconds to make Duration happy
        let seconds: f32 = matches.opt_str("s").unwrap().parse::<f32>().unwrap();
        let whole_seconds: u64 = seconds as u64;
        let nano_seconds: u32 = ((seconds - whole_seconds as f32) * 1_000_000_000_f32) as u32;
        params.sleep = Duration::new(whole_seconds, nano_seconds);
    }
    return params;
}

fn main() {
    let params = build_params();

    let dmx = DmxSource::new("Controller").unwrap();

    let zones: [Zone; 6] = [
        Zone { head: 0, body: 44, tail: 3, name: "10".to_string() },
        Zone { head: 2, body: 91, tail: 3, name: "11a".to_string() },
        Zone { head: 2, body: 92, tail: 2, name: "11b".to_string() },
        Zone { head: 2, body: 90, tail: 3, name: "12a".to_string() },
        Zone { head: 2, body: 91, tail: 3, name: "12b".to_string() },
        Zone { head: 2, body: 43, tail: 0, name: "13".to_string() }
    ];

    let mut lights: Vec<Pixel> = vec![];
    // TODO: probably a more idiomatic way to built the default state
    for zone in zones.iter() {
        for i in 1..zone.body {
            let pixel = Pixel { level: 0, age: 0 };
            lights.push(pixel);
        }
    }

    let mut rng = rand::thread_rng();
    let bright_range = Range::new(0_f32, params.max_brightness);
    let zero_to_one = Range::new(0_f32, 1_f32);

    loop {
        for light in lights.iter_mut() {
            if light.level == 0 {
                // light is currently dark
                // test to see if we want to light it
                if zero_to_one.ind_sample(&mut rng) < params.threshold {
                    // we do, so pick a random
                    light.level = bright_range.ind_sample(&mut rng) as i16;
                    light.age += 1;
                }
            } else {
                // light is lit
                // test to see if we rise or fall
                // probability of falling should go up as light ages
                if zero_to_one.ind_sample(&mut rng) > 1.0/(light.age as f32) {
                    // falling
                    light.level -= (bright_range.ind_sample(&mut rng)/params.decay) as i16;
                    light.age += 1;
                    // test to see if we bottomed out
                    if light.level <= 0 {
                        light.level = 0;
                        light.age = 0;
                    }
                } else {
                    // rising
                    light.level += (zero_to_one.ind_sample(&mut rng) * (params.max_brightness - light.level as f32)) as i16;
                    light.age += 1;
                }
            }
        }
        render(&lights, &zones, &dmx);
        sleep(params.sleep);
    }
    dmx.terminate_stream(1);
}

// debug, rendor output to console
// fn render( lights: &[Pixel], zones: &[Zone], dmx: &DmxSource ) {
//    let mut out: Vec<i16> = vec![];
//    for light in lights {
//        out.push(light.level);
//   }
//    println!("{:?}", out)
//     let mut lit: u16 = 0;
//     let mut level: i16 = 0;
//     for light in lights {
//         if light.level > 0 {
//             lit += 1;
//             level += light.level;
//         }
//     }
//     println!("{} pixels, {} lit, {} avg level", lights.len(), lit, (level as f32)/(lit as f32));
// }

// output to lighting controller via sACN
fn render( lights: &[Pixel], zones: &[Zone], dmx: &DmxSource ) {
    let mut out: Vec<u8> = vec![];
    let mut copy: Vec<Pixel> = vec![];
    copy.extend_from_slice(lights);
    let mut idx: usize = 0;
    for zone in zones {
        // null pixels at head
        for i in 1..zone.head {
            out.push(0); // Red
            out.push(0); // Green
            out.push(0); // Blue
        }
        // set via light.level in the body
        for i in 0..(zone.body - 1) {
            out.push(copy[idx].level as u8); // Red
            out.push(copy[idx].level as u8); // Green
            out.push(copy[idx].level as u8); // Blue
            idx += 1;
        }
        // null pixels at tail
        for i in 1..zone.tail {
            out.push(0); // Red
            out.push(0); // Green
            out.push(0); // Blue
        }
    }
    let mut universes = Vec::new();
    while out.len() > UNIVERSE_SIZE {
        let u = out.split_off(UNIVERSE_SIZE);
        universes.push(out);
        out = u;
    }
    universes.push(out);
    let mut universe: u16 = 1;
    for u in universes {
        dmx.send(universe, &u);
        universe += 1;
    }
}

<|endoftext|>


<commit_before>/*
	Full Monkey.
	Generic preprocessor tool.

	Copyright 2016 Sam Saint-Pettersen.
    Released under the MIT/X11 License.
*/

extern crate clioptions;
extern crate regex;
use clioptions::CliOptions;
use regex::Regex;
use std::io::{BufRead, BufReader, Write};
use std::fs::File;
use std::process::exit;

fn preprocess(input: &str, output: &str, conditions: &str, verbose: bool) {
    let mut loc: Vec<String> = Vec::new();
    let mut preprocessed: Vec<String> = Vec::new();
    let mut cond = String::new();
    let mut set_conds: Vec<String> = Vec::new();
    let mut prefixed: Vec<String> = Vec::new();
    let mut prefixes: Vec<String> = Vec::new();
    let mut in_pp = false;

    let conditions = conditions.split(";");
    for sc in conditions {
        set_conds.push(sc.to_string());
    }

    let f = File::open(input).unwrap();
    let file = BufReader::new(&f);
    for l in file.lines() {
        let l = l.unwrap();

        // Process prefix...
        let mut p = Regex::new("#prefix (.*) with (.*)").unwrap();
        if p.is_match(&l) {
            for cap in p.captures_iter(&l) {
                prefixed.push(cap.at(1).unwrap().to_string());
                prefixes.push(cap.at(2).unwrap().to_string());

            }
            continue;
        }
        // Process conditional (if/else/elseif)...
        p = Regex::new("#[else]*[if]* (.*)").unwrap();
        if p.is_match(&l) {
            for cap in p.captures_iter(&l) {
                cond = cap.at(1).unwrap().to_string();
                in_pp = true;
            }
            continue;
        }

        // Process end block...
        p = Regex::new("#[fi|endif]").unwrap();
        if p.is_match(&l) {
            in_pp = false;
            continue;
        }
        // Push relevant LoC to vector...
        for sc in set_conds.clone() {
            if in_pp && cond == sc {
                preprocessed.push(l.to_string());
            }
        }
        if !in_pp {
            preprocessed.push(l.to_string());
            continue;
        }
    }
    // Do any alterations:
    for line in preprocessed {
        let mut fl = line;
        for (i, p) in prefixed.iter().enumerate() {
            let r = Regex::new(&regex::quote(&p)).unwrap();
            let repl = format!("{}{}", &prefixes[i], &p);
            fl = r.replace_all(&fl, &repl[..]);
        }
        loc.push(fl);
    }
    loc.push(String::new());

    if verbose {
        println!("Preprocessing {} --> {}", input, output);
    }

    let mut w = File::create(output).unwrap();
    let _ = w.write_all(loc.join("\n").as_bytes());
}

fn display_version() {
	println!("Full Monkey v. 0.1");
	println!(r"     __");
    println!(r"w  c(..)o   (");
    println!(r" \__(-)    __)");
    println!(r"     /\   (");
    println!(r"    /(_)___)");
    println!(r"   w /|");
    println!(r"    | \");
    println!(r"   m  m");
    println!("\nMonkey appears courtesy of ejm97:");
    println!("http://www.ascii-art.de/ascii/mno/monkey.txt");
	exit(0);
}

fn display_error(program: &str, error: &str) {
	println!("Error: {}.", error);
	display_usage(&program, -1);
}

fn display_usage(program: &str, exit_code: i32) {
	println!("\nFull Monkey.");
	println!("Generic preprocessor tool.");
    println!("\nCopyright 2016 Sam Saint-Pettersen.");
    println!("Released under the MIT/X11 License.");
	println!("\n{} -f|--file <input> [-c|--condition <condition(s)>] -o|--out <output>", program);
	println!("[-l|--verbose][-h|--help | -v|--version]");
	println!("\n-f|--file: File to run preprocessing on.");
	println!("-c|--conditon: Comma delimited list of conditon(s) to apply.");
	println!("-o|--out: File to output preprocessed LoC to.");
    println!("-l|--verbose: Display output to console on process.");
	println!("-h|--help: Display this help information and exit.");
	println!("-v|--version: Display program versiona and exit.");
	exit(exit_code);
}

fn main() {
    let cli = CliOptions::new("fm");
    let program = cli.get_program();
    let mut input = String::new();
    let mut output = String::new();
    let mut conditions = String::new();
    let mut verbose = false;
    if cli.get_num() > 1 {
    	for (i, a) in cli.get_args().iter().enumerate() {
    		match a.trim() {
    			"-h" | "--help" => display_usage(&program, 0),
    			"-v" | "--version" => display_version(),
                "-f" | "--file" => input = cli.next_argument(i),
                "-c" | "--condition" => conditions = cli.next_argument(i),
                "-o" | "--out" => output = cli.next_argument(i),
                "-l" | "--verbose" => verbose = true,
    			_ => continue,
    		}
        }

        if input.is_empty() {
            display_error(&program, "No input specified");
        }

        if output.is_empty() {
            display_error(&program, "No output specified");
        }

        preprocess(&input, &output, &conditions, verbose);
    }
    else {
    	display_error(&program, "No options specified");
    }
}
<commit_msg>comma not semicolon.<commit_after>/*
	Full Monkey.
	Generic preprocessor tool.

	Copyright 2016 Sam Saint-Pettersen.
    Released under the MIT/X11 License.
*/

extern crate clioptions;
extern crate regex;
use clioptions::CliOptions;
use regex::Regex;
use std::io::{BufRead, BufReader, Write};
use std::fs::File;
use std::process::exit;

fn preprocess(input: &str, output: &str, conditions: &str, verbose: bool) {
    let mut loc: Vec<String> = Vec::new();
    let mut preprocessed: Vec<String> = Vec::new();
    let mut cond = String::new();
    let mut set_conds: Vec<String> = Vec::new();
    let mut prefixed: Vec<String> = Vec::new();
    let mut prefixes: Vec<String> = Vec::new();
    let mut in_pp = false;

    let conditions = conditions.split(",");
    for sc in conditions {
        set_conds.push(sc.to_string());
    }

    let f = File::open(input).unwrap();
    let file = BufReader::new(&f);
    for l in file.lines() {
        let l = l.unwrap();

        // Process prefix...
        let mut p = Regex::new("#prefix (.*) with (.*)").unwrap();
        if p.is_match(&l) {
            for cap in p.captures_iter(&l) {
                prefixed.push(cap.at(1).unwrap().to_string());
                prefixes.push(cap.at(2).unwrap().to_string());

            }
            continue;
        }
        // Process conditional (if/else/elseif)...
        p = Regex::new("#[else]*[if]* (.*)").unwrap();
        if p.is_match(&l) {
            for cap in p.captures_iter(&l) {
                cond = cap.at(1).unwrap().to_string();
                in_pp = true;
            }
            continue;
        }

        // Process end block...
        p = Regex::new("#[fi|endif]").unwrap();
        if p.is_match(&l) {
            in_pp = false;
            continue;
        }
        // Push relevant LoC to vector...
        for sc in set_conds.clone() {
            if in_pp && cond == sc {
                preprocessed.push(l.to_string());
            }
        }
        if !in_pp {
            preprocessed.push(l.to_string());
            continue;
        }
    }
    // Do any alterations:
    for line in preprocessed {
        let mut fl = line;
        for (i, p) in prefixed.iter().enumerate() {
            let r = Regex::new(&regex::quote(&p)).unwrap();
            let repl = format!("{}{}", &prefixes[i], &p);
            fl = r.replace_all(&fl, &repl[..]);
        }
        loc.push(fl);
    }
    loc.push(String::new());

    if verbose {
        println!("Preprocessing {} --> {}", input, output);
    }

    let mut w = File::create(output).unwrap();
    let _ = w.write_all(loc.join("\n").as_bytes());
}

fn display_version() {
	println!("Full Monkey v. 0.1");
	println!(r"     __");
    println!(r"w  c(..)o   (");
    println!(r" \__(-)    __)");
    println!(r"     /\   (");
    println!(r"    /(_)___)");
    println!(r"   w /|");
    println!(r"    | \");
    println!(r"   m  m");
    println!("\nMonkey appears courtesy of ejm97:");
    println!("http://www.ascii-art.de/ascii/mno/monkey.txt");
	exit(0);
}

fn display_error(program: &str, error: &str) {
	println!("Error: {}.", error);
	display_usage(&program, -1);
}

fn display_usage(program: &str, exit_code: i32) {
	println!("\nFull Monkey.");
	println!("Generic preprocessor tool.");
    println!("\nCopyright 2016 Sam Saint-Pettersen.");
    println!("Released under the MIT/X11 License.");
	println!("\n{} -f|--file <input> [-c|--condition <condition(s)>] -o|--out <output>", program);
	println!("[-l|--verbose][-h|--help | -v|--version]");
	println!("\n-f|--file: File to run preprocessing on.");
	println!("-c|--conditon: Comma delimited list of conditon(s) to apply.");
	println!("-o|--out: File to output preprocessed LoC to.");
    println!("-l|--verbose: Display output to console on process.");
	println!("-h|--help: Display this help information and exit.");
	println!("-v|--version: Display program versiona and exit.");
	exit(exit_code);
}

fn main() {
    let cli = CliOptions::new("fm");
    let program = cli.get_program();
    let mut input = String::new();
    let mut output = String::new();
    let mut conditions = String::new();
    let mut verbose = false;
    if cli.get_num() > 1 {
    	for (i, a) in cli.get_args().iter().enumerate() {
    		match a.trim() {
    			"-h" | "--help" => display_usage(&program, 0),
    			"-v" | "--version" => display_version(),
                "-f" | "--file" => input = cli.next_argument(i),
                "-c" | "--condition" => conditions = cli.next_argument(i),
                "-o" | "--out" => output = cli.next_argument(i),
                "-l" | "--verbose" => verbose = true,
    			_ => continue,
    		}
        }

        if input.is_empty() {
            display_error(&program, "No input specified");
        }

        if output.is_empty() {
            display_error(&program, "No output specified");
        }

        preprocess(&input, &output, &conditions, verbose);
    }
    else {
    	display_error(&program, "No options specified");
    }
}
<|endoftext|>


<commit_before>// Copyright 2017 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

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;
extern crate params;

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

// // // // // // // // // // CONSTANTS // // // // // // // // // //

const SERVICE_ID: u16 = 1;

const TX_CREATE_WALLET_ID: u16 = 1;

const TX_TRANSFER_ID: u16 = 2;

const INIT_BALANCE: u64 = 100;

// // // // // // // // // // 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);
    }
}

// // // // // // // // // // 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)
    }
}

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

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]
    }
}

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 schema.wallet(self.pub_key()).is_none() {
            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 {
    channel: ApiSender<NodeChannel>,
    blockchain: Blockchain,
}

impl CryptocurrencyApi {
    fn get_wallet(&self, pub_key: &PublicKey) -> Option<Wallet> {
        let mut view = self.blockchain.fork();
        let mut schema = CurrencySchema { view: &mut view };
        schema.wallet(pub_key)
    }

    fn get_wallets(&self) -> Option<Vec<Wallet>> {
        let mut view = self.blockchain.fork();
        let mut schema = CurrencySchema { view: &mut view };
        let idx = schema.wallets();
        let wallets: Vec<Wallet> = idx.values().collect();
        println!("wallets count: {}", wallets.len());
        if wallets.is_empty() {
            None
        } else {
            Some(wallets)
        }
    }
}

impl Api for CryptocurrencyApi {
    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(ApiError::Events)?;
                    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 self_ = self.clone();
        let wallets_info = move |req: &mut Request| -> IronResult<Response> {
            let map = req.get_ref::<Params>().unwrap();
            match map.find(&["pubkey"]) {
                Some(&Value::String(ref pub_key_string)) => {
                    let public_key = PublicKey::from_hex(pub_key_string).map_err(
                        ApiError::FromHex,
                    )?;
                    if let Some(wallet) = self_.get_wallet(&public_key) {
                        self_.ok_response(&serde_json::to_value(wallet).unwrap())
                    } else {
                        self_.not_found_response(&serde_json::to_value("Wallet not found").unwrap())
                    }

                }
                _ => {
                    if let Some(wallets) = self_.get_wallets() {
                        self_.ok_response(&serde_json::to_value(wallets).unwrap())
                    } else {
                        self_.not_found_response(
                            &serde_json::to_value("Wallets database is empty").unwrap(),
                        )
                    }
                }
            }
        };

        let route_post = "/v1/wallets/transaction";
        let route_get = "/v1/wallets/info";
        router.post(&route_post, transaction, "transaction");
        router.get(&route_get, wallets_info, "wallets_info");
    }
}

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

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(),
            blockchain: ctx.blockchain().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 (consensus_public_key, consensus_secret_key) = exonum::crypto::gen_keypair();
    let (service_public_key, service_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 validator_keys = ValidatorKeys {
        consensus_key: consensus_public_key,
        service_key: service_public_key,
    };
    let genesis = GenesisConfig::new(vec![validator_keys].into_iter());

    let api_cfg = NodeApiConfig {
        public_api_address: Some(api_address),
        ..Default::default()
    };

    let node_cfg = NodeConfig {
        listen_address: peer_address,
        peers: vec![],
        service_public_key,
        service_secret_key,
        consensus_public_key,
        consensus_secret_key,
        genesis,
        external_address: None,
        network: Default::default(),
        whitelist: Default::default(),
        api: api_cfg,
        mempool: Default::default(),
        services_configs: Default::default(),
    };

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

    println!("Blockchain is ready for transactions!");
    node.run().unwrap();
}
<commit_msg>Removed logging info<commit_after>// Copyright 2017 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

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;
extern crate params;

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

// // // // // // // // // // CONSTANTS // // // // // // // // // //

const SERVICE_ID: u16 = 1;

const TX_CREATE_WALLET_ID: u16 = 1;

const TX_TRANSFER_ID: u16 = 2;

const INIT_BALANCE: u64 = 100;

// // // // // // // // // // 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);
    }
}

// // // // // // // // // // 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)
    }
}

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

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]
    }
}

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 schema.wallet(self.pub_key()).is_none() {
            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 {
    channel: ApiSender<NodeChannel>,
    blockchain: Blockchain,
}

impl CryptocurrencyApi {
    fn get_wallet(&self, pub_key: &PublicKey) -> Option<Wallet> {
        let mut view = self.blockchain.fork();
        let mut schema = CurrencySchema { view: &mut view };
        schema.wallet(pub_key)
    }

    fn get_wallets(&self) -> Option<Vec<Wallet>> {
        let mut view = self.blockchain.fork();
        let mut schema = CurrencySchema { view: &mut view };
        let idx = schema.wallets();
        let wallets: Vec<Wallet> = idx.values().collect();
        if wallets.is_empty() {
            None
        } else {
            Some(wallets)
        }
    }
}

impl Api for CryptocurrencyApi {
    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(ApiError::Events)?;
                    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 self_ = self.clone();
        let wallets_info = move |req: &mut Request| -> IronResult<Response> {
            let map = req.get_ref::<Params>().unwrap();
            match map.find(&["pubkey"]) {
                Some(&Value::String(ref pub_key_string)) => {
                    let public_key = PublicKey::from_hex(pub_key_string).map_err(
                        ApiError::FromHex,
                    )?;
                    if let Some(wallet) = self_.get_wallet(&public_key) {
                        self_.ok_response(&serde_json::to_value(wallet).unwrap())
                    } else {
                        self_.not_found_response(&serde_json::to_value("Wallet not found").unwrap())
                    }

                }
                _ => {
                    if let Some(wallets) = self_.get_wallets() {
                        self_.ok_response(&serde_json::to_value(wallets).unwrap())
                    } else {
                        self_.not_found_response(
                            &serde_json::to_value("Wallets database is empty").unwrap(),
                        )
                    }
                }
            }
        };

        let route_post = "/v1/wallets/transaction";
        let route_get = "/v1/wallets/info";
        router.post(&route_post, transaction, "transaction");
        router.get(&route_get, wallets_info, "wallets_info");
    }
}

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

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(),
            blockchain: ctx.blockchain().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 (consensus_public_key, consensus_secret_key) = exonum::crypto::gen_keypair();
    let (service_public_key, service_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 validator_keys = ValidatorKeys {
        consensus_key: consensus_public_key,
        service_key: service_public_key,
    };
    let genesis = GenesisConfig::new(vec![validator_keys].into_iter());

    let api_cfg = NodeApiConfig {
        public_api_address: Some(api_address),
        ..Default::default()
    };

    let node_cfg = NodeConfig {
        listen_address: peer_address,
        peers: vec![],
        service_public_key,
        service_secret_key,
        consensus_public_key,
        consensus_secret_key,
        genesis,
        external_address: None,
        network: Default::default(),
        whitelist: Default::default(),
        api: api_cfg,
        mempool: Default::default(),
        services_configs: Default::default(),
    };

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

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


<commit_before>#[macro_use]
extern crate clap;
extern crate rand;
extern crate ultra;

use rand::Rng;
use ultra::{Enigma, decrypt};

trait CasedString {
    fn with_case_of(&self, target: &str) -> String;
}

impl CasedString for String {
    fn with_case_of(&self, target: &str) -> String {
        self.chars().zip(target.chars()).map(|(s, t)| {
            match t.is_lowercase() {
                true => s.to_ascii_lowercase(),
                false => s
            }
        }).collect()
    }
}

fn main() {
    let app = clap_app!(ultra =>
        (version: crate_version!())
        (@setting ArgRequiredElseHelp)
        (@setting ColoredHelp)
        (@arg decrypt: --decrypt -d "Decrypt a given piece of ciphertext")
        (@arg randomize: --randomize -R "Encrypt a message with random Enigma settings")
        (@arg ROTORS: --rotor -w +takes_value "Rotor order (default: \"123\")")
        (@arg KEY: --key -k +takes_value "Key settings (default: \"AAA\")")
        (@arg RING: --ring -r +takes_value "Ring settings (default: \"AAA\")")
        (@arg PLUGBOARD: --plugboard -p +takes_value "Plugboard settings (default: \"\")")
        (@arg MESSAGE: +required "The message to encrypt/decrypt")
    );

    let matches = app.get_matches();
    let msg = matches.value_of("MESSAGE").unwrap();

    if matches.is_present("decrypt") {
        let (plaintext, rotors, key, ring) = decrypt(msg);
        println!("{}", plaintext.with_case_of(msg));
        eprintln!("(Rotors: {}, Key Setting: {}, Ring Setting: {})", rotors, key, ring);
    }

    else if matches.is_present("randomize") {
        let mut rng = rand::thread_rng();

        let rotors: String = {
            let mut rotor_pool: Vec<char> = "12345".chars().collect();
            let mut rotors = Vec::with_capacity(3);

            for _ in 0..3 {
                let len = rotor_pool.len();
                rotors.push(rotor_pool.remove(rng.gen_range(0, len)));
            }

            rotors.into_iter().collect()
        };

        let mut key = String::with_capacity(3);
        let mut ring = String::with_capacity(3);
        let alpha: Vec<char> = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".chars().collect();

        for _ in 0..3 {
            key.push(*rng.choose(&alpha).unwrap());
            ring.push(*rng.choose(&alpha).unwrap());
        }

        let mut enigma = Enigma::new(&rotors, &key, &ring, 'B', "");
        println!("{}", enigma.encrypt(msg).with_case_of(msg));
        eprintln!("(Rotors: {}, Key Setting: {}, Ring Setting: {})", rotors, key, ring);
    }

    else {
        let rotors = matches.value_of("ROTORS").unwrap_or("123");
        let key = matches.value_of("KEY").unwrap_or("AAA");
        let ring = matches.value_of("RING").unwrap_or("AAA");
        let plugboard = matches.value_of("PLUGBOARD").unwrap_or("");

        let mut enigma = Enigma::new(rotors, key, ring, 'B', plugboard);
        println!("{}", enigma.encrypt(msg).with_case_of(msg));
    }
}
<commit_msg>Set plugboard settings with --randomize<commit_after>#[macro_use]
extern crate clap;
extern crate rand;
extern crate ultra;

use rand::Rng;
use ultra::{Enigma, decrypt};

trait CasedString {
    fn with_case_of(&self, target: &str) -> String;
}

impl CasedString for String {
    fn with_case_of(&self, target: &str) -> String {
        self.chars().zip(target.chars()).map(|(s, t)| {
            match t.is_lowercase() {
                true => s.to_ascii_lowercase(),
                false => s
            }
        }).collect()
    }
}

fn main() {
    let app = clap_app!(ultra =>
        (version: crate_version!())
        (@setting ArgRequiredElseHelp)
        (@setting ColoredHelp)
        (@arg decrypt: --decrypt -d "Decrypt a given piece of ciphertext")
        (@arg randomize: --randomize -R "Encrypt a message with random Enigma settings")
        (@arg ROTORS: --rotor -w +takes_value "Rotor order (default: \"123\")")
        (@arg KEY: --key -k +takes_value "Key settings (default: \"AAA\")")
        (@arg RING: --ring -r +takes_value "Ring settings (default: \"AAA\")")
        (@arg PLUGBOARD: --plugboard -p +takes_value "Plugboard settings (default: \"\")")
        (@arg MESSAGE: +required "The message to encrypt/decrypt")
    );

    let matches = app.get_matches();
    let msg = matches.value_of("MESSAGE").unwrap();

    if matches.is_present("decrypt") {
        let (plaintext, rotors, key, ring) = decrypt(msg);
        println!("{}", plaintext.with_case_of(msg));
        eprintln!("(Rotors: {}, Key Setting: {}, Ring Setting: {})", rotors, key, ring);
    }

    else if matches.is_present("randomize") {
        let mut rng = rand::thread_rng();

        let rotors: String = {
            let mut rotor_pool: Vec<char> = "12345".chars().collect();
            let mut rotors = Vec::with_capacity(3);

            for _ in 0..3 {
                let len = rotor_pool.len();
                rotors.push(rotor_pool.remove(rng.gen_range(0, len)));
            }

            rotors.into_iter().collect()
        };

        // Randomize key and ring settings for the rotors.
        let mut key = String::with_capacity(3);
        let mut ring = String::with_capacity(3);
        let alpha: Vec<char> = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".chars().collect();

        for _ in 0..3 {
            key.push(*rng.choose(&alpha).unwrap());
            ring.push(*rng.choose(&alpha).unwrap());
        }

        // Pick random plugs to fill plugboard with.
        let mut plug_pool = alpha.clone();
        rng.shuffle(&mut plug_pool);
        let plugboard = plug_pool
            .chunks(2)
            .take(rng.gen_range(0, 10))  // maximum of 10 plugs
            .map(|chrs| chrs.iter().collect::<String>())
            .collect::<Vec<_>>()
            .join(" ");

        let mut enigma = Enigma::new(&rotors, &key, &ring, 'B', &plugboard);
        println!("{}", enigma.encrypt(msg).with_case_of(msg));
        eprintln!("(Rotors: {}, Key Setting: {}, Ring Setting: {}, Plugboard: {})", rotors, key, ring, plugboard);
    }

    else {
        let rotors = matches.value_of("ROTORS").unwrap_or("123");
        let key = matches.value_of("KEY").unwrap_or("AAA");
        let ring = matches.value_of("RING").unwrap_or("AAA");
        let plugboard = matches.value_of("PLUGBOARD").unwrap_or("");

        let mut enigma = Enigma::new(rotors, key, ring, 'B', plugboard);
        println!("{}", enigma.encrypt(msg).with_case_of(msg));
    }
}
<|endoftext|>


<commit_before>#![feature(field_init_shorthand)]

extern crate chrono;
extern crate rusqlite;

#[macro_use]
extern crate bookmarkt;

use bookmarkt::dao::bookmark_dao::BookmarkDao;
use bookmarkt::common::bookmark::Bookmark;
use rusqlite::Connection;
use std::path::Path;

fn main() {
    let db = Connection::open(Path::new("res/BOOKMARKT.db")).unwrap();

    let base_bookmark = Bookmark {
        id: 0,
        name: String::from("test"),
        url: String::from("test_url"),
        rev_no: 0
    };

    let dao = BookmarkDao {
        connection: &db,
        read_sql: dump_file!("res/sql/bookmark/read.sql"),
        delete_sql: dump_file!("res/sql/bookmark/delete.sql"),
        insert_sql: dump_file!("res/sql/bookmark/insert.sql"),
        update_sql: dump_file!("res/sql/bookmark/update.sql"),
        list_sql: dump_file!("res/sql/bookmark/list.sql")
    };

    // TEST READ
    println!("\nTEST READ");
    match dao.read(base_bookmark) {
        Ok(b) => println!("{}", b.name),
        Err(_) => panic!("error")
    }

    // test insert
    println!("\nTEST INSERT");

    // test delete
    println!("\nTEST DELETE");

    // test list
    println!("\nTEST LIST");

}
<commit_msg>fix Link<commit_after>#![feature(field_init_shorthand)]

extern crate chrono;
extern crate rusqlite;

#[macro_use]
extern crate bookmarkt;

use bookmarkt::common::bookmark::Link;
use bookmarkt::dao::bookmark_dao::LinkDao;

use rusqlite::Connection;
use std::path::Path;

fn main() {
    let db = Connection::open(Path::new("res/BOOKMARKT.db")).unwrap();

    let base_bookmark = Link {
        id: 0,
        name: String::from("test"),
        url: String::from("test_url"),
        rev_no: 0
    };

    let dao = LinkDao {
        connection: &db,
        read_sql: dump_file!("res/sql/bookmark/read.sql"),
        delete_sql: dump_file!("res/sql/bookmark/delete.sql"),
        insert_sql: dump_file!("res/sql/bookmark/insert.sql"),
        update_sql: dump_file!("res/sql/bookmark/update.sql"),
        list_sql: dump_file!("res/sql/bookmark/list.sql")
    };

    // TEST READ
    println!("\nTEST READ");
    match dao.read(base_bookmark) {
        Ok(b) => println!("{}", b.name),
        Err(_) => panic!("error")
    }

    // test insert
    println!("\nTEST INSERT");

    // test delete
    println!("\nTEST DELETE");

    // test list
    println!("\nTEST LIST");

}
<|endoftext|>


<commit_before>use std::collections::LinkedList;

struct DataObj{
    data: String,
    t: String,
}
impl DataObj{
    fn new(data: String, t: String) -> DataObj{
        DataObj{
        data: data,
        t: t,
      }
    }
}
struct Column{
    name: String,
    dataobjs: LinkedList<DataObj>,
    t: String,
}
impl Column{
    fn new(name: String, t: String) -> Column{
      Column{
        name: name,
        dataobjs: LinkedList::<DataObj>::new(),
        t: t,
      }
    }
}
struct Table{
    columns: Vec<Column>,
}
impl Table{
    fn new() -> Table{
      Table{
        columns: Vec::<Column>::new(),
      }
    }
}
struct db{
  tables: Vec<Table>,
}
impl db{
    fn new() -> db{
      db{
        tables: Vec::<Table>::new(),
      }
    }
}
fn main(){
    //TODO: Implement server aspect.
}
<commit_msg>Update main.rs<commit_after>use std::collections::LinkedList;

// DataObj: This stores the data within the Column.
struct DataObj{
    data: String,
    t: String,
}
impl DataObj{
    fn new(data: String, t: String) -> DataObj{
        DataObj{
        data: data,
        t: t,
      }
    }
}
// Column: Stores each dataobj of particular type.
struct Column{
    name: String,
    dataobjs: LinkedList<DataObj>,
    t: String,
}
impl Column{
    fn new(name: String, t: String) -> Column{
      Column{
        name: name,
        dataobjs: LinkedList::<DataObj>::new(),
        t: t,
      }
    }
}
// Table: Stores the columns
struct Table{
    columns: Vec<Column>,
}
impl Table{
    fn new() -> Table{
      Table{
        columns: Vec::<Column>::new(),
      }
    }
}
// Database: Stores a set of tables
struct db{
  tables: Vec<Table>,
}
impl db{
    fn new() -> db{
      db{
        tables: Vec::<Table>::new(),
      }
    }
}
struct Server{
    dbs: Vec<db>.
}
impl Server{
    fn new() -> Server{
        Server{
            dbs: Vec::<db>::new(),
        }
    }
}
fn main(){
    //TODO: Implement server aspect.
}
<|endoftext|>


<commit_before>extern crate mio;

use mio::tcp::*;
use mio::*;
use mio::util::Slab;

const SERVER: mio::Token = mio::Token(0);

struct MiChat {
    listener: TcpListener,
    connections: Slab<Connection>,
}

#[derive(Debug)]
struct Connection {
    socket: TcpStream,
    token: mio::Token,
    state: Option<Vec<u8>>,
}

impl Connection {
    fn new(socket: TcpStream, token: mio::Token) -> Connection {
        Connection {
            socket: socket,
            token: token,
            state: Some(Vec::with_capacity(1024))
        }
    }
    fn ready(&mut self, event_loop: &mut mio::EventLoop<MiChat>, events: mio::EventSet) {
        println!("Connection::ready: {:?}; {:?}", self, events);
        if events.is_readable() {
            self.read(event_loop)
        }
    }

    fn read(&mut self, event_loop: &mut mio::EventLoop<MiChat>) {
        let mut abuf = Vec::new();
        match self.socket.try_read_buf(&mut abuf) {
            Ok(Some(0)) => {
                println!("{:?}: EOF!", self);
                self.finish()
            },
            Ok(Some(n)) => {
                println!("Read so far: {:?}", n);
                self.ingest(abuf);
                self.reregister(event_loop)
            },
            Ok(None) => {
                println!("{:?}: Noop!", self);
                self.reregister(event_loop)
            },
            Err(e) => panic!("got an error trying to read; err={:?}", e)
        }
    }
    fn reregister(&mut self, event_loop: &mut mio::EventLoop<MiChat>) {
        event_loop.reregister(
                &self.socket,
                self.token,
                mio::EventSet::readable(),
                mio::PollOpt::oneshot()).unwrap()

    }
    fn ingest(&mut self, inbuf: Vec<u8>) {
        match self.state {
            Some(ref mut buf)  => {
                let mut startpos = 0;
                while let Some(n) = inbuf.iter().skip(startpos).position(|e| *e == '\n' as u8) {
                    println!("Newline from {} @{}", startpos, n);
                    Self::buffer_slice(buf, &inbuf[startpos..startpos+n]);
                    println!("Line: {}", String::from_utf8_lossy(buf));
                    startpos += n+1;
                    buf.clear()
                }
                println!("Remainder: {}", String::from_utf8_lossy(&inbuf[startpos..]));
                Self::buffer_slice(buf, &inbuf[startpos..])
            },
            None => panic!("Ingest on closed connection?")
        }
    }

    fn finish(&mut self) {
        match self.state {
            Some(ref mut buf)  => println!("Remainder: {}", String::from_utf8_lossy(buf)),
            _ => ()
        }
        self.state = None
    }

    fn buffer_slice(buf: &mut Vec<u8>, slice: &[u8]) {
        buf.extend(slice.iter().cloned());
    }

    fn is_closed(&self) -> bool {
        self.state.is_none()
    }
}

impl mio::Handler for MiChat {
    type Timeout = ();
    type Message = ();
    fn ready(&mut self, event_loop: &mut mio::EventLoop<Self>, token: mio::Token, events: mio::EventSet) {
        println!("{:?}: {:?}", token, events);
        match token {
            SERVER => {
                // Only receive readable events
                assert!(events.is_readable());

                println!("the listener socket is ready to accept a connection");
                match self.listener.accept() {
                    Ok(Some(socket)) => {
                        println!("accepted a socket, exiting program");
                        let token = self.connections
                            .insert_with(|token| Connection::new(socket, token))
                            .unwrap();

                        event_loop.register_opt(
                            &self.connections[token].socket,
                            token,
                            mio::EventSet::readable(),
                            mio::PollOpt::edge() | mio::PollOpt::oneshot()).unwrap();
                    }
                    Ok(None) => {
                        println!("the listener socket wasn't actually ready");
                    }
                    Err(e) => {
                        println!("listener.accept() errored: {}", e);
                        event_loop.shutdown();
                    }
                }
            }
            _ => {
                self.connections[token].ready(event_loop, events);
                if self.connections[token].is_closed() {
                    self.connections.remove(token);
                }
            }
        }
    }
}

fn main() {
    let address = "0.0.0.0:6567".parse().unwrap();
    let listener = TcpListener::bind(&address).unwrap();

    let mut event_loop = mio::EventLoop::new().unwrap();
    event_loop.register(&listener, SERVER).unwrap();

    println!("running michat listener at: {:?}", address);
    let mut service = MiChat { listener: listener, connections: Slab::new_starting_at(mio::Token(1), 1024) };
    event_loop.run(&mut service).unwrap();
}
<commit_msg>Push events to a very simple state machine.<commit_after>extern crate mio;

use mio::tcp::*;
use mio::*;
use mio::util::Slab;
use std::thread;
use std::sync::mpsc::{self,channel};

const SERVER: mio::Token = mio::Token(0);

struct MiChat {
    listener: TcpListener,
    connections: Slab<Connection>,
    commands: mpsc::Sender<String>
}

impl MiChat {
    fn new(listener: TcpListener, commands: mpsc::Sender<String>) -> MiChat {
        MiChat {
            listener: listener,
            connections: Slab::new_starting_at(mio::Token(1), 1024),
            commands: commands
        }
    }
}
struct Connection {
    socket: TcpStream,
    token: mio::Token,
    state: Option<Vec<u8>>,
    commands: mpsc::Sender<String>,
}

impl Connection {
    fn new(socket: TcpStream, token: mio::Token, commands: mpsc::Sender<String>) -> Connection {
        Connection {
            socket: socket,
            token: token,
            state: Some(Vec::with_capacity(1024)),
            commands: commands,
        }
    }
    fn ready(&mut self, event_loop: &mut mio::EventLoop<MiChat>, events: mio::EventSet) {
        println!("Connection::ready: {:?}; {:?}", self.socket.peer_addr(), events);
        if events.is_readable() {
            self.read(event_loop)
        }
    }

    fn read(&mut self, event_loop: &mut mio::EventLoop<MiChat>) {
        let mut abuf = Vec::new();
        match self.socket.try_read_buf(&mut abuf) {
            Ok(Some(0)) => {
                println!("{:?}: EOF!", self.socket.peer_addr());
                self.finish()
            },
            Ok(Some(n)) => {
                self.ingest(abuf);
                self.reregister(event_loop)
            },
            Ok(None) => {
                println!("{:?}: Noop!", self.socket.peer_addr());
                self.reregister(event_loop)
            },
            Err(e) => panic!("got an error trying to read; err={:?}", e)
        }
    }
    fn reregister(&mut self, event_loop: &mut mio::EventLoop<MiChat>) {
        event_loop.reregister(
                &self.socket,
                self.token,
                mio::EventSet::readable(),
                mio::PollOpt::oneshot()).unwrap()

    }
    fn ingest(&mut self, inbuf: Vec<u8>) {
        match self.state {
            Some(ref mut buf)  => {
                let mut startpos = 0;
                while let Some(n) = inbuf.iter().skip(startpos).position(|e| *e == '\n' as u8) {
                    Self::buffer_slice(buf, &inbuf[startpos..startpos+n]);
                    let s = String::from_utf8_lossy(buf).into_owned();
                    self.commands.send(s).unwrap();
                    startpos += n+1;
                    buf.clear()
                }
                println!("Remainder: {}", String::from_utf8_lossy(&inbuf[startpos..]));
                Self::buffer_slice(buf, &inbuf[startpos..])
            },
            None => panic!("Ingest on closed connection?")
        }
    }

    fn finish(&mut self) {
        match self.state {
            Some(ref mut buf)  => println!("Remainder: {}", String::from_utf8_lossy(buf)),
            _ => ()
        }
        self.state = None
    }

    fn buffer_slice(buf: &mut Vec<u8>, slice: &[u8]) {
        buf.extend(slice.iter().cloned());
    }

    fn is_closed(&self) -> bool {
        self.state.is_none()
    }
}

impl mio::Handler for MiChat {
    type Timeout = ();
    type Message = ();
    fn ready(&mut self, event_loop: &mut mio::EventLoop<Self>, token: mio::Token, events: mio::EventSet) {
        println!("{:?}: {:?}", token, events);
        match token {
            SERVER => {
                // Only receive readable events
                assert!(events.is_readable());

                println!("the listener socket is ready to accept a connection");
                match self.listener.accept() {
                    Ok(Some(socket)) => {
                        let commands = self.commands.clone();
                        let token = self.connections
                            .insert_with(|token| Connection::new(socket, token, commands))
                            .unwrap();

                        event_loop.register_opt(
                            &self.connections[token].socket,
                            token,
                            mio::EventSet::readable(),
                            mio::PollOpt::edge() | mio::PollOpt::oneshot()).unwrap();
                    }
                    Ok(None) => {
                        println!("the listener socket wasn't actually ready");
                    }
                    Err(e) => {
                        println!("listener.accept() errored: {}", e);
                        event_loop.shutdown();
                    }
                }
            }
            _ => {
                self.connections[token].ready(event_loop, events);
                if self.connections[token].is_closed() {
                    self.connections.remove(token);
                }
            }
        }
    }
}

struct Model {
    count: usize
}

impl Model {
    fn new() -> Model {
        Model { count: 0 }
    }

    fn process_from(&mut self, rx: mpsc::Receiver<String>) {
        loop {
            let msg = rx.recv().unwrap();
            self.count += msg.len();
            println!("{}: {}; got {}", thread::current().name().unwrap_or("???"),
                    self.count, msg);
        }
    }
}

fn main() {
    let address = "0.0.0.0:6567".parse().unwrap();
    let listener = TcpListener::bind(&address).unwrap();

    let mut event_loop = mio::EventLoop::new().unwrap();
    event_loop.register(&listener, SERVER).unwrap();

    println!("running michat listener at: {:?}", address);

    let (tx, rx) = channel();
    let t = thread::Builder::new().name("Model".to_owned()).spawn(move|| {
        let mut model = Model::new();
        model.process_from(rx);
    }).unwrap();

    let mut service = MiChat::new(listener, tx);
    event_loop.run(&mut service).unwrap();
    t.join().unwrap();
}
<|endoftext|>


<commit_before>#![allow(unused_must_use)]
use std::fs;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;
use std::vec::Vec;
use std::env;

const INVALIDS: &'static [&'static str] = &[".", "/", "-", "::", ">", "<", " "];

pub fn asset_name_by_filepath(path: &Path) -> String {
    let mut strpath = path.to_str().unwrap().to_string();

    for invalid in INVALIDS {
        strpath = strpath.replace(invalid, "_");
    }
    strpath
}

fn recursive_read(list: &mut Vec<u8>, pp: &mut Vec<u8>, buffer: &mut Vec<u8>, filepath: &Path) {
    match fs::read_dir(filepath) {
        Err(why) => panic!("Directory {} {:?}", filepath.display(), why.kind()),
        Ok(paths) => for entry in paths {
            let path = entry.unwrap().path();
            println!("Reading -> {:?}", path.display());
            if fs::metadata(&path).unwrap().is_dir() {
                recursive_read(list, pp, buffer, &path);
            } else {
                let mut file = File::open(&path).unwrap_or_else(|e| {
                    panic!("couldn't open file {}: {}", e, filepath.display());
                });
                let mut text: Vec<u8> = vec![];
                file.read_to_end(&mut text).unwrap_or_else(|e| {
                    panic!("couldn't read file {}: {}", e, filepath.display());
                });;
                let asset_name = asset_name_by_filepath(&path);
                write!(list, "    \"");
                write!(list, "{}", path.display());
                write!(list, "\",\n");
                write!(pp, "    \"");
                write!(pp, "{}", path.display());
                write!(pp, "\"");
                write!(pp, " => Result::Ok(&");
                write!(pp, "{}", asset_name);
                write!(pp, "),\n");
                write!(buffer, "pub static ");
                write!(buffer, "{}", asset_name);
                write!(buffer, ": [u8; ");
                write!(buffer, "{}", &text.len().to_string());
                write!(buffer, "] = ");
                write!(buffer, "{:?}", text);
                write!(buffer, ";\n");
            }
        },
    }
}

fn print_usage() {
    print!("
rust-embed v0.2.0
Generates rust code to embed resource files into your library or executable

  Usage:
    rust-embed input_folder output_file

  where:
    input_folder  string is the path to the folder containing the assets.
    output_file   string is output filename.

  example:
    rust-embed ./src/public ./src/assets.rs
");
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() <= 2 {
        print_usage();
        return;
    }
    let ref input_folder = args[1];
    let ref output_file = args[2];

    // Recursive read section buffers
    let mut output_buffer: Vec<u8> = vec![];
    let mut pp: Vec<u8> = vec![];
    let mut list: Vec<u8> = vec![];

    write!(output_buffer, "#![allow(dead_code)]");
    write!(output_buffer, "#![allow(non_upper_case_globals)]");
    write!(output_buffer, "#![allow(clippy)]\n");
    write!(list, "{}", "\npub fn list() -> Vec<&'static str> {\n  vec![\n");
    write!(pp, "{}", "\npub fn get(name: &str) -> Result<&[u8], &str> {\n  match name {\n");
    recursive_read(&mut list, &mut pp, &mut output_buffer, Path::new(input_folder));
    write!(list, "{}", "]}");
    write!(pp, "    _=> Result::Err(\"File Not Found\")\n");
    write!(pp, "{}", "  }\n}\n");
    let op = Path::new(output_file);
    println!("Writing -> {:?}", pp);
    println!("Writing -> {:?}", list);
    println!("Writing -> {:?}", op.display());
    let mut file = File::create(&op).unwrap_or_else(|e| {
        panic!("couldn't create {} {:?}", op.display(), e)
    });
    file.write_all(&output_buffer).unwrap_or_else(|e| {
        panic!("couldn't write to {} {:?}", op.display(), e);
    });
    file.write_all(&pp).unwrap_or_else(|e| {
        panic!("couldn't write to {} {:?}", op.display(), e);
    });
    file.write_all(&list).unwrap_or_else(|e| {
        panic!("couldn't write to {} {:?}", op.display(), e);
    });
}
<commit_msg>add #![allow(unknown_lints)]<commit_after>#![allow(unused_must_use)]
use std::fs;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;
use std::vec::Vec;
use std::env;

const INVALIDS: &'static [&'static str] = &[".", "/", "-", "::", ">", "<", " "];

pub fn asset_name_by_filepath(path: &Path) -> String {
    let mut strpath = path.to_str().unwrap().to_string();

    for invalid in INVALIDS {
        strpath = strpath.replace(invalid, "_");
    }
    strpath
}

fn recursive_read(list: &mut Vec<u8>, pp: &mut Vec<u8>, buffer: &mut Vec<u8>, filepath: &Path) {
    match fs::read_dir(filepath) {
        Err(why) => panic!("Directory {} {:?}", filepath.display(), why.kind()),
        Ok(paths) => for entry in paths {
            let path = entry.unwrap().path();
            println!("Reading -> {:?}", path.display());
            if fs::metadata(&path).unwrap().is_dir() {
                recursive_read(list, pp, buffer, &path);
            } else {
                let mut file = File::open(&path).unwrap_or_else(|e| {
                    panic!("couldn't open file {}: {}", e, filepath.display());
                });
                let mut text: Vec<u8> = vec![];
                file.read_to_end(&mut text).unwrap_or_else(|e| {
                    panic!("couldn't read file {}: {}", e, filepath.display());
                });;
                let asset_name = asset_name_by_filepath(&path);
                write!(list, "    \"");
                write!(list, "{}", path.display());
                write!(list, "\",\n");
                write!(pp, "    \"");
                write!(pp, "{}", path.display());
                write!(pp, "\"");
                write!(pp, " => Result::Ok(&");
                write!(pp, "{}", asset_name);
                write!(pp, "),\n");
                write!(buffer, "pub static ");
                write!(buffer, "{}", asset_name);
                write!(buffer, ": [u8; ");
                write!(buffer, "{}", &text.len().to_string());
                write!(buffer, "] = ");
                write!(buffer, "{:?}", text);
                write!(buffer, ";\n");
            }
        },
    }
}

fn print_usage() {
    print!("
rust-embed v0.2.0
Generates rust code to embed resource files into your library or executable

  Usage:
    rust-embed input_folder output_file

  where:
    input_folder  string is the path to the folder containing the assets.
    output_file   string is output filename.

  example:
    rust-embed ./src/public ./src/assets.rs
");
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() <= 2 {
        print_usage();
        return;
    }
    let ref input_folder = args[1];
    let ref output_file = args[2];

    // Recursive read section buffers
    let mut output_buffer: Vec<u8> = vec![];
    let mut pp: Vec<u8> = vec![];
    let mut list: Vec<u8> = vec![];

    write!(output_buffer, "#![allow(dead_code)]");
    write!(output_buffer, "#![allow(non_upper_case_globals)]");
    write!(output_buffer, "#![allow(unknown_lints)]");
    write!(output_buffer, "#![allow(clippy)]\n");
    write!(list, "{}", "\npub fn list() -> Vec<&'static str> {\n  vec![\n");
    write!(pp, "{}", "\npub fn get(name: &str) -> Result<&[u8], &str> {\n  match name {\n");
    recursive_read(&mut list, &mut pp, &mut output_buffer, Path::new(input_folder));
    write!(list, "{}", "]}");
    write!(pp, "    _=> Result::Err(\"File Not Found\")\n");
    write!(pp, "{}", "  }\n}\n");
    let op = Path::new(output_file);
    println!("Writing -> {:?}", pp);
    println!("Writing -> {:?}", list);
    println!("Writing -> {:?}", op.display());
    let mut file = File::create(&op).unwrap_or_else(|e| {
        panic!("couldn't create {} {:?}", op.display(), e)
    });
    file.write_all(&output_buffer).unwrap_or_else(|e| {
        panic!("couldn't write to {} {:?}", op.display(), e);
    });
    file.write_all(&pp).unwrap_or_else(|e| {
        panic!("couldn't write to {} {:?}", op.display(), e);
    });
    file.write_all(&list).unwrap_or_else(|e| {
        panic!("couldn't write to {} {:?}", op.display(), e);
    });
}
<|endoftext|>


<commit_before>mod error;
mod file_utils;

enum ReturnCode {
    Ok = 0,
    WalkError = 2,
    FileTypeError = 4,
    TranspilationError = 8,
}

pub fn transpile_file<T: AsRef<std::path::Path>>(
    path: T,
    options: &indentexlib::TranspileOptions,
) -> Result<(), crate::error::IndentexError> {
    use crate::file_utils::{read_and_trim_lines, rename_indentex_file, write_to_file};

    let lines = read_and_trim_lines(path.as_ref())?;
    let transpiled_text = indentexlib::transpile(lines, options);
    let path_out = rename_indentex_file(path)?;
    write_to_file(path_out, &transpiled_text)?;

    Ok(())
}

fn main() {
    use crate::file_utils::walk_indentex_files;
    use clap::{crate_authors, crate_description, crate_version, App, Arg};
    use indentexlib::TranspileOptions;
    use rayon::prelude::*;
    use std::cmp;
    use std::path::{Path, PathBuf};
    use std::process;

    let m = App::new("indentex")
        .version(crate_version!())
        .author(crate_authors!())
        .about(crate_description!())
        .arg(
            Arg::with_name("path")
                .help(
                    "Path to a single indentex file or a directory (recursively transpile all \
                     indentex files)",
                )
                .index(1)
                .required(true),
        )
        .arg(
            Arg::with_name("verbose")
                .help("Show transpilation progress")
                .short("v")
                .long("verbose"),
        )
        .arg(
            Arg::with_name("disable-do-not-edit")
                .help("Disable prepending the 'DO NOT EDIT' notice")
                .long("disable-do-not-edit"),
        )
        .get_matches();

    let path = Path::new(m.value_of("path").unwrap());
    let verbose = m.is_present("verbose");
    let options = TranspileOptions {
        prepend_do_not_edit_notice: !m.is_present("disable-do-not-edit"),
    };

    let mut ret_val = ReturnCode::Ok as i32;

    let batch: Vec<PathBuf> = if path.is_file() {
        vec![path.to_path_buf()]
    } else if path.is_dir() {
        match walk_indentex_files(&path) {
            Ok(b) => b,
            Err(e) => {
                ret_val = ReturnCode::WalkError as i32;
                eprintln!("{}", e);
                Vec::new()
            }
        }
    } else {
        ret_val = ReturnCode::FileTypeError as i32;
        eprintln!(
            "Error: path '{}' is neither a file nor a directory",
            path.display()
        );
        Vec::new()
    };

    let ret_val_transpilation = batch
        .par_iter()
        .map(|p| match transpile_file(&p, &options) {
            Ok(_) => {
                if verbose {
                    println!("Transpiling file '{}'... ok", p.display());
                }
                ReturnCode::Ok
            }
            Err(e) => {
                if verbose {
                    println!("Transpiling file '{}'... failed", p.display());
                }
                eprintln!("Could not transpile '{}': {}", p.display(), e);
                ReturnCode::TranspilationError
            }
        } as i32)
        .max()
        .unwrap_or(ReturnCode::Ok as i32);

    process::exit(cmp::max(ret_val, ret_val_transpilation));
}
<commit_msg>Remove excessive use-s<commit_after>mod error;
mod file_utils;

enum ReturnCode {
    Ok = 0,
    WalkError = 2,
    FileTypeError = 4,
    TranspilationError = 8,
}

pub fn transpile_file<T: AsRef<std::path::Path>>(
    path: T,
    options: &indentexlib::TranspileOptions,
) -> Result<(), crate::error::IndentexError> {
    use crate::file_utils::{read_and_trim_lines, rename_indentex_file, write_to_file};

    let lines = read_and_trim_lines(path.as_ref())?;
    let transpiled_text = indentexlib::transpile(lines, options);
    let path_out = rename_indentex_file(path)?;
    write_to_file(path_out, &transpiled_text)?;

    Ok(())
}

fn main() {
    use crate::file_utils::walk_indentex_files;
    use clap::{crate_authors, crate_description, crate_version, App, Arg};
    use indentexlib::TranspileOptions;
    use rayon::prelude::*;
    use std::path::{Path, PathBuf};

    let m = App::new("indentex")
        .version(crate_version!())
        .author(crate_authors!())
        .about(crate_description!())
        .arg(
            Arg::with_name("path")
                .help(
                    "Path to a single indentex file or a directory (recursively transpile all \
                     indentex files)",
                )
                .index(1)
                .required(true),
        )
        .arg(
            Arg::with_name("verbose")
                .help("Show transpilation progress")
                .short("v")
                .long("verbose"),
        )
        .arg(
            Arg::with_name("disable-do-not-edit")
                .help("Disable prepending the 'DO NOT EDIT' notice")
                .long("disable-do-not-edit"),
        )
        .get_matches();

    let path = Path::new(m.value_of("path").unwrap());
    let verbose = m.is_present("verbose");
    let options = TranspileOptions {
        prepend_do_not_edit_notice: !m.is_present("disable-do-not-edit"),
    };

    let mut ret_val = ReturnCode::Ok as i32;

    let batch: Vec<PathBuf> = if path.is_file() {
        vec![path.to_path_buf()]
    } else if path.is_dir() {
        match walk_indentex_files(&path) {
            Ok(b) => b,
            Err(e) => {
                ret_val = ReturnCode::WalkError as i32;
                eprintln!("{}", e);
                Vec::new()
            }
        }
    } else {
        ret_val = ReturnCode::FileTypeError as i32;
        eprintln!(
            "Error: path '{}' is neither a file nor a directory",
            path.display()
        );
        Vec::new()
    };

    let ret_val_transpilation = batch
        .par_iter()
        .map(|p| match transpile_file(&p, &options) {
            Ok(_) => {
                if verbose {
                    println!("Transpiling file '{}'... ok", p.display());
                }
                ReturnCode::Ok
            }
            Err(e) => {
                if verbose {
                    println!("Transpiling file '{}'... failed", p.display());
                }
                eprintln!("Could not transpile '{}': {}", p.display(), e);
                ReturnCode::TranspilationError
            }
        } as i32)
        .max()
        .unwrap_or(ReturnCode::Ok as i32);

    std::process::exit(std::cmp::max(ret_val, ret_val_transpilation));
}
<|endoftext|>


<commit_before>#![feature(collections_bound, btree_range)]
#![feature(plugin, proc_macro)]
#![plugin(maud_macros)]

extern crate caseless;
extern crate env_logger;
extern crate iron;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate logger;
extern crate maud;
extern crate notify;
extern crate persistent;
extern crate pulldown_cmark;
#[macro_use]
extern crate router;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate staticfile;
extern crate unicode_normalization;
extern crate unicode_segmentation;
extern crate urlencoded;

use iron::prelude::*;
use iron::status;
use iron::typemap::Key;
use logger::Logger;
use notify::{DebouncedEvent, RecursiveMode, Watcher};
use router::Router;
use persistent::State;
use staticfile::Static;
use std::env;
use std::sync::{Arc, RwLock};
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
use urlencoded::UrlEncodedQuery;

mod models;
mod search;
mod views;

use models::Users;

const DATA_PATH: &'static str = "rustaceans.org/data";

lazy_static! {
    static ref IS_PRODUCTION: bool = {
        let p = env::var("KARKINOS_ENVIRONMENT")
            .map(|s| s.to_lowercase() == "production")
            .unwrap_or(false);
        if p {
            info!("running in production environment");
        } else {
            info!("running in development environment");
        }
        p
    };
}

#[derive(Copy, Clone)]
struct UsersKey;
impl Key for UsersKey { type Value = Users; }

fn main() {
    env_logger::init().unwrap();

    let mut router = Router::new();
    router.get("/", home, "home");
    router.get("/user/:id", user, "user");
    router.get("/search", search, "search");
    router.get("/static/:path", Static::new("."), "static");
    router.get("*", not_found, "not_found");

    fn home(r: &mut Request) -> IronResult<Response> {
        let body = views::home(r);
        Ok(Response::with((status::Ok, body)))
    }

    fn user(r: &mut Request) -> IronResult<Response> {
        let route = r.extensions.get::<Router>().unwrap();
        let id = route.find("id").unwrap();
        let users = r.extensions.get::<State<UsersKey>>().unwrap();
        match users.read().unwrap().get(id) {
            Some(Ok(user)) => {
                let body = views::user(r, id, &user);
                Ok(Response::with((status::Ok, body)))
            },
            Some(Err(error)) => {
                let body = views::user_error(r, id, error);
                Ok(Response::with((status::Ok, body)))
            }
            None => {
                let body = views::user_not_found(r, id);
                Ok(Response::with((status::NotFound, body)))
            },
        }
    }

    fn search(r: &mut Request) -> IronResult<Response> {
        let q: Option<String> = r.get_ref::<UrlEncodedQuery>().ok()
            .and_then(|query| query.get("q"))
            .and_then(|q| q.first().cloned());
        let users = r.extensions.get::<State<UsersKey>>().unwrap();
        let users = users.read().unwrap();
        if let Some(q) = q {
            let results = users.search(&q);
            let results = results.into_iter()
                // Restrict search to 20 results, so the server isn't bogged
                // down too much
                .take(20)
                .map(|(id, weight)| (users.get(&id).unwrap(), id, weight));
            let body = views::search_results(r, &q, results);
            Ok(Response::with((status::Ok, body)))
        } else {
            let body = views::search(r);
            Ok(Response::with((status::Ok, body)))
        }
    }

    fn not_found(r: &mut Request) -> IronResult<Response> {
        let body = views::not_found(r);
        Ok(Response::with((status::NotFound, body)))
    }

    let mut chain = Chain::new(router);

    chain.link(Logger::new(None));

    chain.link({
        // Load user data
        let users = Users::load(DATA_PATH).unwrap();
        let arc = Arc::new(RwLock::new(users));
        // Reload data automatically when changed
        let arc_cloned = arc.clone();
        thread::spawn(move || {
            let (tx, rx) = mpsc::channel();
            let mut watcher = notify::watcher(tx, Duration::from_secs(10)).unwrap();
            watcher.watch(DATA_PATH, RecursiveMode::NonRecursive).unwrap();
            loop {
                match rx.recv() {
                    Ok(DebouncedEvent::NoticeWrite(..)) |
                    Ok(DebouncedEvent::NoticeRemove(..)) |
                    Ok(DebouncedEvent::Chmod(..)) => continue,  // Ignore trivial events
                    Ok(DebouncedEvent::Error(e, _path)) => error!("watch error: {}", e),
                    Ok(_) => info!("received file system update; reloading"),
                    Err(e) => error!("watch error: {}", e),
                }
                let users = Users::load(DATA_PATH).unwrap();
                *arc_cloned.write().unwrap() = users;
            }
        });
        State::<UsersKey>::both(arc)
    });

    if *IS_PRODUCTION {
        chain.link_before(|r: &mut Request| {
            // Since we're running behind a reverse proxy, the headers are kind
            // of messed up
            r.headers.set(iron::headers::Host {
                hostname: "karkinos.lambda.xyz".to_string(),
                port: None,
            });
            let mut url = r.url.clone().into_generic_url();
            url.set_scheme("https").unwrap();
            url.set_host(Some("karkinos.lambda.xyz")).unwrap();
            url.set_port(None).unwrap();
            r.url = iron::Url::from_generic_url(url).unwrap();
            Ok(())
        });
    }

    let bind_addr = "localhost:8344";
    info!("starting on {}", bind_addr);
    Iron::new(chain).http(bind_addr).unwrap();
}
<commit_msg>Clean up reloading code<commit_after>#![feature(collections_bound, btree_range)]
#![feature(plugin, proc_macro)]
#![plugin(maud_macros)]

extern crate caseless;
extern crate env_logger;
extern crate iron;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate logger;
extern crate maud;
extern crate notify;
extern crate persistent;
extern crate pulldown_cmark;
#[macro_use]
extern crate router;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate staticfile;
extern crate unicode_normalization;
extern crate unicode_segmentation;
extern crate urlencoded;

use iron::prelude::*;
use iron::status;
use iron::typemap::Key;
use logger::Logger;
use notify::{RecursiveMode, Watcher};
use router::Router;
use persistent::State;
use staticfile::Static;
use std::env;
use std::sync::{Arc, RwLock};
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
use urlencoded::UrlEncodedQuery;

mod models;
mod search;
mod views;

use models::Users;

const DATA_PATH: &'static str = "rustaceans.org/data";

lazy_static! {
    static ref IS_PRODUCTION: bool = {
        let p = env::var("KARKINOS_ENVIRONMENT")
            .map(|s| s.to_lowercase() == "production")
            .unwrap_or(false);
        if p {
            info!("running in production environment");
        } else {
            info!("running in development environment");
        }
        p
    };
}

#[derive(Copy, Clone)]
struct UsersKey;
impl Key for UsersKey { type Value = Users; }

fn main() {
    env_logger::init().unwrap();

    let mut router = Router::new();
    router.get("/", home, "home");
    router.get("/user/:id", user, "user");
    router.get("/search", search, "search");
    router.get("/static/:path", Static::new("."), "static");
    router.get("*", not_found, "not_found");

    fn home(r: &mut Request) -> IronResult<Response> {
        let body = views::home(r);
        Ok(Response::with((status::Ok, body)))
    }

    fn user(r: &mut Request) -> IronResult<Response> {
        let route = r.extensions.get::<Router>().unwrap();
        let id = route.find("id").unwrap();
        let users = r.extensions.get::<State<UsersKey>>().unwrap();
        match users.read().unwrap().get(id) {
            Some(Ok(user)) => {
                let body = views::user(r, id, &user);
                Ok(Response::with((status::Ok, body)))
            },
            Some(Err(error)) => {
                let body = views::user_error(r, id, error);
                Ok(Response::with((status::Ok, body)))
            }
            None => {
                let body = views::user_not_found(r, id);
                Ok(Response::with((status::NotFound, body)))
            },
        }
    }

    fn search(r: &mut Request) -> IronResult<Response> {
        let q: Option<String> = r.get_ref::<UrlEncodedQuery>().ok()
            .and_then(|query| query.get("q"))
            .and_then(|q| q.first().cloned());
        let users = r.extensions.get::<State<UsersKey>>().unwrap();
        let users = users.read().unwrap();
        if let Some(q) = q {
            let results = users.search(&q);
            let results = results.into_iter()
                // Restrict search to 20 results, so the server isn't bogged
                // down too much
                .take(20)
                .map(|(id, weight)| (users.get(&id).unwrap(), id, weight));
            let body = views::search_results(r, &q, results);
            Ok(Response::with((status::Ok, body)))
        } else {
            let body = views::search(r);
            Ok(Response::with((status::Ok, body)))
        }
    }

    fn not_found(r: &mut Request) -> IronResult<Response> {
        let body = views::not_found(r);
        Ok(Response::with((status::NotFound, body)))
    }

    let mut chain = Chain::new(router);

    chain.link(Logger::new(None));

    chain.link({
        // Load user data
        let users = Users::load(DATA_PATH).unwrap();
        let arc = Arc::new(RwLock::new(users));
        // Reload data automatically when changed
        let arc_cloned = arc.clone();
        thread::spawn(move || {
            let (tx, rx) = mpsc::channel();
            let mut watcher = notify::raw_watcher(tx).unwrap();
            watcher.watch(DATA_PATH, RecursiveMode::NonRecursive).unwrap();
            loop {
                // Wait for a filesystem event
                let event = rx.recv().unwrap();
                if let Err(e) = event.op {
                    error!("watch error: {}", e);
                }
                // Drain out any remaining events
                thread::sleep(Duration::from_secs(5));
                while let Ok(event) = rx.try_recv() {
                    if let Err(e) = event.op {
                        error!("watch error: {}", e);
                    }
                }
                // Reload the data
                info!("reloading data!");
                match Users::load(DATA_PATH) {
                    Ok(users) => *arc_cloned.write().unwrap() = users,
                    Err(e) => error!("error loading data: {}", e),
                }
            }
        });
        State::<UsersKey>::both(arc)
    });

    if *IS_PRODUCTION {
        chain.link_before(|r: &mut Request| {
            // Since we're running behind a reverse proxy, the headers are kind
            // of messed up
            r.headers.set(iron::headers::Host {
                hostname: "karkinos.lambda.xyz".to_string(),
                port: None,
            });
            let mut url = r.url.clone().into_generic_url();
            url.set_scheme("https").unwrap();
            url.set_host(Some("karkinos.lambda.xyz")).unwrap();
            url.set_port(None).unwrap();
            r.url = iron::Url::from_generic_url(url).unwrap();
            Ok(())
        });
    }

    let bind_addr = "localhost:8344";
    info!("starting on {}", bind_addr);
    Iron::new(chain).http(bind_addr).unwrap();
}
<|endoftext|>