<commit_before>extern crate centralgithook;
extern crate git2;
extern crate clap;
extern crate env_logger;

use std::env;
use std::process::exit;
use std::path::Path;
use centralgithook::CentralGit;
use centralgithook::Scratch;
use centralgithook::Gerrit;

const GERRIT_PORT: &'static str = "29418";
const AUTOMATION_USER: &'static str = "centralgit";
const GERRIT_HOST: &'static str = "localhost";
const CENTRAL_NAME: &'static str = "central";
const BRANCH: &'static str = "master";

fn main()
{
    // ::std::env::set_var("RUST_LOG", "centralgithook=debug");
    env_logger::init().expect("can't init logger");

    let git_dir = env::var("GIT_DIR").expect("GIT_DIR not set");
    if let Some((gerrit_path, gerrit)) = Gerrit::new(&Path::new(&git_dir),
                                                     CENTRAL_NAME,
                                                     AUTOMATION_USER,
                                                     GERRIT_HOST,
                                                     GERRIT_PORT) {

        let scratch_dir = gerrit_path.join("centralgithook_scratch");
        let scratch = Scratch::new(&scratch_dir);

        let mut args = vec![];
        for arg in env::args() {
            args.push(arg);
        }
        let hooks = CentralGit::new(BRANCH);
        exit(centralgithook::dispatch(args, &hooks, &gerrit, &scratch));
    }
}
<commit_msg>one scratch per central<commit_after>extern crate centralgithook;
extern crate git2;
extern crate clap;
extern crate env_logger;

use std::env;
use std::process::exit;
use std::path::Path;
use centralgithook::CentralGit;
use centralgithook::Scratch;
use centralgithook::Gerrit;
use centralgithook::RepoHost;

const GERRIT_PORT: &'static str = "29418";
const AUTOMATION_USER: &'static str = "centralgit";
const GERRIT_HOST: &'static str = "localhost";
const CENTRAL_NAME: &'static str = "central";
const BRANCH: &'static str = "master";

fn main()
{
    // ::std::env::set_var("RUST_LOG", "centralgithook=debug");
    env_logger::init().expect("can't init logger");

    let git_dir = env::var("GIT_DIR").expect("GIT_DIR not set");
    if let Some((gerrit_path, gerrit)) = Gerrit::new(&Path::new(&git_dir),
                                                     CENTRAL_NAME,
                                                     AUTOMATION_USER,
                                                     GERRIT_HOST,
                                                     GERRIT_PORT) {

        let scratch_dir = gerrit_path.join("centralgithook_scratch").join(gerrit.prefix());
        let scratch = Scratch::new(&scratch_dir);

        let mut args = vec![];
        for arg in env::args() {
            args.push(arg);
        }
        let hooks = CentralGit::new(BRANCH);
        exit(centralgithook::dispatch(args, &hooks, &gerrit, &scratch));
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate conrod;
extern crate find_folder;
extern crate piston_window;
extern crate websocket;

use std::borrow::Cow;
use std::str::from_utf8;
use std::thread;
use std::io::stdin;
use std::sync::mpsc::channel;
use websocket::{Message, Sender, Receiver};
use websocket::message::Type;
use websocket::client::request::Url;
use websocket::Client;
use websocket::stream::WebSocketStream;
use std::sync::mpsc::{Sender as TrueSender, Receiver as TrueReceiver, RecvError as TrueRecvError,
                      TryRecvError};

use conrod::{color, Scalar, Button, Canvas, Circle, Color, Colorable, DropDownList,
             EnvelopeEditor, Frameable, Labelable, NumberDialer, Point, Positionable, Slider,
             Sizeable, Text, TextBox, Theme, Toggle, Widget, WidgetMatrix, XYPad};

use piston_window::{EventLoop, Glyphs, PistonWindow, UpdateEvent, WindowSettings};

// Use `piston_window` for UI backend.
type Backend = (<piston_window::G2d<'static> as conrod::Graphics>::Texture, Glyphs);
type Ui = conrod::Ui<Backend>;
type UiCell<'a> = conrod::UiCell<'a, Backend>;

fn main() {
    // Reply from Odin.
    let (reply_tx, reply_rx): (TrueSender<String>, TrueReceiver<String>) = channel();

    let url = Url::parse("ws://127.0.0.1:2794").unwrap();

    println!("Connecting to {}", url);

    let request = Client::connect(url).unwrap();

    let response = request.send().unwrap(); // Send the request and retrieve a response

    println!("Validating response...");

    response.validate().unwrap(); // Validate the response

    println!("Successfully connected");

    let (mut sender, mut receiver) = response.begin().split();

    let (tx, rx) = channel();

    let tx_1 = tx.clone();

    let send_loop = thread::spawn(move || {
        loop {
            // Send loop
            let message: Message = match rx.recv() {
                Ok(m) => m,
                Err(e) => {
                    println!("Send Loop: {:?}", e);
                    return;
                }
            };
            match message.opcode {
                Type::Close => {
                    let _ = sender.send_message(&message);
                    // If it's a close message, just send it and then return.
                    return;
                }
                _ => (),
            }
            // Send the message
            match sender.send_message(&message) {
                Ok(()) => (),
                Err(e) => {
                    println!("Send Loop: {:?}", e);
                    let _ = sender.send_message(&Message::close());
                    return;
                }
            }
        }
    });

    let receive_loop = thread::spawn(move || {
        // Receive loop
        for message in receiver.incoming_messages() {
            let message: Message = match message {
                Ok(m) => m,
                Err(e) => {
                    println!("Receive Loop: {:?}", e);
                    let _ = tx_1.send(Message::close());
                    return;
                }
            };
            match message.opcode {
                Type::Close => {
                    // Got a close message, so send a close message and return
                    let _ = tx_1.send(Message::close());
                    return;
                }
                Type::Ping => {
                    match tx_1.send(Message::pong(message.payload)) {
                        // Send a pong in response
                        Ok(()) => (),
                        Err(e) => {
                            println!("Receive Loop: {:?}", e);
                            return;
                        }
                    }
                }
                // Parse message from Odin.
                _ => {
                    reply_tx.send(from_utf8(&*message.payload).unwrap().to_string());
                }
            }
        }
    });

    // Construct the window.
    let window: PistonWindow = WindowSettings::new("Thor", [1024, 768])
                                   .exit_on_esc(true)
                                   .fullscreen(true)
                                   .build()
                                   .unwrap();

    // Construct the UI.
    let mut ui = {
        // Get path for "assets".
        let assets = find_folder::Search::KidsThenParents(3, 5)
                         .for_folder("assets")
                         .unwrap();

        // Get path for the font.
        let font_path = assets.join("fonts/NotoSans/NotoSans-Regular.ttf");

        // Use the "default" theme.
        let theme = Theme::default();

        // Glyph cache.
        let glyph_cache = Glyphs::new(&font_path, window.factory.borrow().clone());

        // Finally, create the UI.
        Ui::new(glyph_cache.unwrap(), theme)
    };

    // Did the user click on the button?
    let mut clicked = false;
    // Did we press Enter in the textbox?
    let mut submitted = false;
    // Textbox input.
    let mut input: String = "".to_string();
    // Reply from Odin.
    let mut reply = String::new();

    // Poll events from the window.
    for event in window.ups(60) {

        // Listen to sockets without blocking.
        let res = reply_rx.try_recv();
        match res {
            Ok(val) => reply = val,
            Err(err) => {
                match err {
                    TryRecvError::Empty => {
                        // Channel is empty. This event fires frequently.
                    }
                    TryRecvError::Disconnected => {
                        // Channel is disconnected.
                    }
                }
            }
        }
        ui.handle_event(&event);
        event.update(|_| {
            ui.set_widgets(|mut ui| {
                set_widgets(&mut ui,
                            &mut reply,
                            &mut clicked,
                            &mut submitted,
                            &mut input)
            })
        });
        event.draw_2d(|c, g| ui.draw(c, g));
        if clicked == true {
            let message = Message::text("This drink... I like it! ANOTHER!");
            tx.send(message);
            clicked = false;
        }
        if submitted == true {
            let message = Message::text(input);
            tx.send(message);
            // Clear input.
            input = "".to_string();
            // Reset submitted state.
            submitted = false;
        }
    }
}

fn set_widgets(ui: &mut UiCell,
               text: &mut String,
               clicked: &mut bool,
               submitted: &mut bool,
               input: &mut String) {

    // Unique ID's for each widget.
    widget_ids!{
        MASTER,
        COL,
        LABEL,
        BUTTON,
        BUTTON2,
        SUBMIT_BUTTON,
        TEXTBOX,
        BACKSPACE,
        INSTRUCTIONS_LABEL,
    }

    // Create the canvas.
    Canvas::new()
        .flow_right(&[(COL, Canvas::new().color(color::WHITE))])
        .set(MASTER, ui);

    const PAD: Scalar = 20.0;

    Text::new(text)
        .color(color::BLUE)
        .padded_w_of(COL, PAD)
        .middle_of(COL)
        .align_text_middle()
        .line_spacing(2.5)
        .set(LABEL, ui);

    Text::new("Enter your message in the green field and press Enter to send to \
                            everyone.")
        .color(color::BLUE)
        .padded_w_of(COL, PAD)
        .mid_top_of(COL)
        .align_text_middle()
        .line_spacing(2.5)
        .set(INSTRUCTIONS_LABEL, ui);

    Button::new()
        .w_h(44.0, 44.0)
        .mid_left_of(MASTER)
        .rgb(0.4, 0.75, 0.6)
        .label("A")
        .react(|| {
            let mut n = input.clone();
            n.push('A');
            *input = n;
        })
        .set(BUTTON, ui);

    Button::new()
        .w_h(44.0, 44.0)
        .right_from(BUTTON, 20.0)
        .rgb(0.4, 0.75, 0.6)
        .label("B")
        .react(|| {
            let mut n = input.clone();
            n.push('B');
            *input = n;
        })
        .set(BUTTON2, ui);

    Button::new()
        .w_h(200.0, 44.0)
        .bottom_left_of(MASTER)
        .rgb(0.4, 0.75, 0.6)
        .label("Backspace")
        .react(|| {
            let mut n = input.clone();
            n.pop();
            *input = n;
        })
        .set(BACKSPACE, ui);

    Button::new()
        .w_h(200.0, 44.0)
        .bottom_right_of(MASTER)
        .rgb(0.4, 0.75, 0.6)
        .label("Submit")
        .react(|| {
            *submitted = true;
        })
        .set(SUBMIT_BUTTON, ui);

    TextBox::new(input)
        .w_h(300.0, 50.0)
        .font_size(20)
        .mid_bottom_of(COL)
        .rgb(0.4, 0.75, 0.6)
        .react(|_string: &mut String| {
            *submitted = true;
        })
        .set(TEXTBOX, ui);
}
<commit_msg>Add A-Z characters and spacebar to virtual keyboard.<commit_after>#[macro_use]
extern crate conrod;
extern crate find_folder;
extern crate piston_window;
extern crate websocket;

use std::borrow::Cow;
use std::str::from_utf8;
use std::thread;
use std::io::stdin;
use std::sync::mpsc::channel;
use websocket::{Message, Sender, Receiver};
use websocket::message::Type;
use websocket::client::request::Url;
use websocket::Client;
use websocket::stream::WebSocketStream;
use std::sync::mpsc::{Sender as TrueSender, Receiver as TrueReceiver, RecvError as TrueRecvError,
                      TryRecvError};

use conrod::{color, Scalar, Button, Canvas, Circle, Color, Colorable, DropDownList,
             EnvelopeEditor, Frameable, Labelable, NumberDialer, Point, Positionable, Slider,
             Sizeable, Text, TextBox, Theme, Toggle, Widget, WidgetMatrix, XYPad};

use piston_window::{EventLoop, Glyphs, PistonWindow, UpdateEvent, WindowSettings};

// Use `piston_window` for UI backend.
type Backend = (<piston_window::G2d<'static> as conrod::Graphics>::Texture, Glyphs);
type Ui = conrod::Ui<Backend>;
type UiCell<'a> = conrod::UiCell<'a, Backend>;

fn main() {
    // Reply from Odin.
    let (reply_tx, reply_rx): (TrueSender<String>, TrueReceiver<String>) = channel();

    let url = Url::parse("ws://127.0.0.1:2794").unwrap();

    println!("Connecting to {}", url);

    let request = Client::connect(url).unwrap();

    let response = request.send().unwrap(); // Send the request and retrieve a response

    println!("Validating response...");

    response.validate().unwrap(); // Validate the response

    println!("Successfully connected");

    let (mut sender, mut receiver) = response.begin().split();

    let (tx, rx) = channel();

    let tx_1 = tx.clone();

    let send_loop = thread::spawn(move || {
        loop {
            // Send loop
            let message: Message = match rx.recv() {
                Ok(m) => m,
                Err(e) => {
                    println!("Send Loop: {:?}", e);
                    return;
                }
            };
            match message.opcode {
                Type::Close => {
                    let _ = sender.send_message(&message);
                    // If it's a close message, just send it and then return.
                    return;
                }
                _ => (),
            }
            // Send the message
            match sender.send_message(&message) {
                Ok(()) => (),
                Err(e) => {
                    println!("Send Loop: {:?}", e);
                    let _ = sender.send_message(&Message::close());
                    return;
                }
            }
        }
    });

    let receive_loop = thread::spawn(move || {
        // Receive loop
        for message in receiver.incoming_messages() {
            let message: Message = match message {
                Ok(m) => m,
                Err(e) => {
                    println!("Receive Loop: {:?}", e);
                    let _ = tx_1.send(Message::close());
                    return;
                }
            };
            match message.opcode {
                Type::Close => {
                    // Got a close message, so send a close message and return
                    let _ = tx_1.send(Message::close());
                    return;
                }
                Type::Ping => {
                    match tx_1.send(Message::pong(message.payload)) {
                        // Send a pong in response
                        Ok(()) => (),
                        Err(e) => {
                            println!("Receive Loop: {:?}", e);
                            return;
                        }
                    }
                }
                // Parse message from Odin.
                _ => {
                    reply_tx.send(from_utf8(&*message.payload).unwrap().to_string());
                }
            }
        }
    });

    // Construct the window.
    let window: PistonWindow = WindowSettings::new("Thor", [1024, 768])
                                   .exit_on_esc(true)
                                   .fullscreen(true)
                                   .build()
                                   .unwrap();

    // Construct the UI.
    let mut ui = {
        // Get path for "assets".
        let assets = find_folder::Search::KidsThenParents(3, 5)
                         .for_folder("assets")
                         .unwrap();

        // Get path for the font.
        let font_path = assets.join("fonts/NotoSans/NotoSans-Regular.ttf");

        // Use the "default" theme.
        let theme = Theme::default();

        // Glyph cache.
        let glyph_cache = Glyphs::new(&font_path, window.factory.borrow().clone());

        // Finally, create the UI.
        Ui::new(glyph_cache.unwrap(), theme)
    };

    // Did the user click on the button?
    let mut clicked = false;
    // Did we press Enter in the textbox?
    let mut submitted = false;
    // Textbox input.
    let mut input: String = "".to_string();
    // Reply from Odin.
    let mut reply = String::new();

    // Poll events from the window.
    for event in window.ups(60) {

        // Listen to sockets without blocking.
        let res = reply_rx.try_recv();
        match res {
            Ok(val) => reply = val,
            Err(err) => {
                match err {
                    TryRecvError::Empty => {
                        // Channel is empty. This event fires frequently.
                    }
                    TryRecvError::Disconnected => {
                        // Channel is disconnected.
                    }
                }
            }
        }
        ui.handle_event(&event);
        event.update(|_| {
            ui.set_widgets(|mut ui| {
                set_widgets(&mut ui,
                            &mut reply,
                            &mut clicked,
                            &mut submitted,
                            &mut input)
            })
        });
        event.draw_2d(|c, g| ui.draw(c, g));
        if clicked == true {
            let message = Message::text("This drink... I like it! ANOTHER!");
            tx.send(message);
            clicked = false;
        }
        if submitted == true {
            let message = Message::text(input);
            tx.send(message);
            // Clear input.
            input = "".to_string();
            // Reset submitted state.
            submitted = false;
        }
    }
}

fn set_widgets(ui: &mut UiCell,
               text: &mut String,
               clicked: &mut bool,
               submitted: &mut bool,
               input: &mut String) {
    // let keys_first_row = ["Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P"];
    // let keys_second_row = ["A", "S", "D", "F", "G", "H", "J", "K", "L"];
    // let keys_third_row = ["Z", "X", "C", "V", "B", "N", "M"];

    // Unique ID's for each widget.
    widget_ids!{
        MASTER,
        COL,
        LABEL,
        SUBMIT_BUTTON,
        TEXTBOX,
        BACKSPACE,
        INSTRUCTIONS_LABEL,
        BUTTON_Q,
        BUTTON_W,
        BUTTON_E,
        BUTTON_R,
        BUTTON_T,
        BUTTON_Y,
        BUTTON_U,
        BUTTON_I,
        BUTTON_O,
        BUTTON_P,
        BUTTON_A,
        BUTTON_S,
        BUTTON_D,
        BUTTON_F,
        BUTTON_G,
        BUTTON_H,
        BUTTON_J,
        BUTTON_K,
        BUTTON_L,
        BUTTON_Z,
        BUTTON_X,
        BUTTON_C,
        BUTTON_V,
        BUTTON_B,
        BUTTON_N,
        BUTTON_M,
        BUTTON_SPACE
    }

    // Create the canvas.
    Canvas::new()
        .flow_right(&[(COL, Canvas::new().color(color::WHITE))])
        .set(MASTER, ui);

    const PAD: Scalar = 20.0;

    Text::new(text)
        .color(color::BLUE)
        .padded_w_of(COL, PAD)
        .middle_of(COL)
        .align_text_middle()
        .line_spacing(2.5)
        .set(LABEL, ui);

    Text::new("Type in your message and press Enter to send to \
                            everyone.")
        .color(color::BLUE)
        .padded_w_of(COL, PAD)
        .mid_top_of(COL)
        .align_text_middle()
        .line_spacing(2.5)
        .set(INSTRUCTIONS_LABEL, ui);

    Button::new()
        .w_h(200.0, 44.0)
        .bottom_left_of(MASTER)
        .rgb(0.4, 0.75, 0.6)
        .label("Backspace")
        .react(|| {
            let mut n = input.clone();
            n.pop();
            *input = n;
        })
        .set(BACKSPACE, ui);

    Button::new()
        .w_h(200.0, 44.0)
        .bottom_right_of(MASTER)
        .rgb(0.4, 0.75, 0.6)
        .label("Submit")
        .react(|| {
            *submitted = true;
        })
        .set(SUBMIT_BUTTON, ui);

    TextBox::new(input)
        .w_h(300.0, 50.0)
        .font_size(20)
        .mid_bottom_of(COL)
        .rgb(0.4, 0.75, 0.6)
        .react(|_string: &mut String| {
            *submitted = true;
        })
        .set(TEXTBOX, ui);

    Button::new()
        .w_h(200.0, 44.0)
        .bottom_right_of(MASTER)
        .rgb(0.4, 0.75, 0.6)
        .label("Submit")
        .react(|| {
            *submitted = true;
        })
        .set(SUBMIT_BUTTON, ui);

    let button_size = 44.0;
    let button_padding = 5.0;

    // NOTE: This is very much a prototype. Please don't judge.

    Button::new()
        .w_h(button_size, button_size)
        .mid_left_of(MASTER)
        .rgb(0.4, 0.75, 0.6)
        .label("Q")
        .react(|| {
            let mut n = input.clone();
            n.push('Q');
            *input = n;
        })
        .set(BUTTON_Q, ui);

    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_Q, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("W")
        .react(|| {
            let mut n = input.clone();
            n.push('W');
            *input = n;
        })
        .set(BUTTON_W, ui);

    // E.
    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_W, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("E")
        .react(|| {
            let mut n = input.clone();
            n.push('E');
            *input = n;
        })
        .set(BUTTON_E, ui);

    // R.
    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_E, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("R")
        .react(|| {
            let mut n = input.clone();
            n.push('R');
            *input = n;
        })
        .set(BUTTON_R, ui);

    // T.
    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_R, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("T")
        .react(|| {
            let mut n = input.clone();
            n.push('T');
            *input = n;
        })
        .set(BUTTON_T, ui);

    // Y.
    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_T, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("Y")
        .react(|| {
            let mut n = input.clone();
            n.push('Y');
            *input = n;
        })
        .set(BUTTON_Y, ui);

    // U.
    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_Y, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("U")
        .react(|| {
            let mut n = input.clone();
            n.push('U');
            *input = n;
        })
        .set(BUTTON_U, ui);

    // I.
    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_U, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("I")
        .react(|| {
            let mut n = input.clone();
            n.push('I');
            *input = n;
        })
        .set(BUTTON_I, ui);

    // O.
    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_I, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("O")
        .react(|| {
            let mut n = input.clone();
            n.push('O');
            *input = n;
        })
        .set(BUTTON_O, ui);

    // P.
    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_O, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("P")
        .react(|| {
            let mut n = input.clone();
            n.push('P');
            *input = n;
        })
        .set(BUTTON_P, ui);

    // A.
    Button::new()
        .w_h(button_size, button_size)
        .down_from(BUTTON_Q, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("A")
        .react(|| {
            let mut n = input.clone();
            n.push('A');
            *input = n;
        })
        .set(BUTTON_A, ui);

    // S.
    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_A, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("S")
        .react(|| {
            let mut n = input.clone();
            n.push('S');
            *input = n;
        })
        .set(BUTTON_S, ui);

    // D.
    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_S, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("D")
        .react(|| {
            let mut n = input.clone();
            n.push('D');
            *input = n;
        })
        .set(BUTTON_D, ui);

    // F.
    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_D, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("F")
        .react(|| {
            let mut n = input.clone();
            n.push('F');
            *input = n;
        })
        .set(BUTTON_F, ui);

    // G.
    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_F, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("G")
        .react(|| {
            let mut n = input.clone();
            n.push('G');
            *input = n;
        })
        .set(BUTTON_G, ui);

    // H.
    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_G, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("H")
        .react(|| {
            let mut n = input.clone();
            n.push('H');
            *input = n;
        })
        .set(BUTTON_H, ui);

    // J.
    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_H, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("J")
        .react(|| {
            let mut n = input.clone();
            n.push('J');
            *input = n;
        })
        .set(BUTTON_J, ui);

    // K.
    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_J, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("K")
        .react(|| {
            let mut n = input.clone();
            n.push('K');
            *input = n;
        })
        .set(BUTTON_K, ui);

    // L.
    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_K, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("L")
        .react(|| {
            let mut n = input.clone();
            n.push('L');
            *input = n;
        })
        .set(BUTTON_L, ui);

    // Z.
    Button::new()
        .w_h(button_size, button_size)
        .down_from(BUTTON_A, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("Z")
        .react(|| {
            let mut n = input.clone();
            n.push('Z');
            *input = n;
        })
        .set(BUTTON_Z, ui);

    // X.
    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_Z, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("X")
        .react(|| {
            let mut n = input.clone();
            n.push('X');
            *input = n;
        })
        .set(BUTTON_X, ui);

    // C.
    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_X, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("C")
        .react(|| {
            let mut n = input.clone();
            n.push('C');
            *input = n;
        })
        .set(BUTTON_C, ui);

    // V.
    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_C, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("V")
        .react(|| {
            let mut n = input.clone();
            n.push('V');
            *input = n;
        })
        .set(BUTTON_V, ui);

    // B.
    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_V, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("V")
        .react(|| {
            let mut n = input.clone();
            n.push('B');
            *input = n;
        })
        .set(BUTTON_B, ui);

    // N.
    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_B, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("N")
        .react(|| {
            let mut n = input.clone();
            n.push('N');
            *input = n;
        })
        .set(BUTTON_N, ui);

    // M.
    Button::new()
        .w_h(button_size, button_size)
        .right_from(BUTTON_N, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("M")
        .react(|| {
            let mut n = input.clone();
            n.push('M');
            *input = n;
        })
        .set(BUTTON_M, ui);

    // Space.
    Button::new()
        .w_h(200.0, button_size)
        .down_from(BUTTON_Z, button_padding)
        .rgb(0.4, 0.75, 0.6)
        .label("Space")
        .react(|| {
            let mut n = input.clone();
            n.push(' ');
            *input = n;
        })
        .set(BUTTON_SPACE, ui);
}
<|endoftext|>


<commit_before>extern crate piston_window;
extern crate graphics;
extern crate itertools;
extern crate opengl_graphics;
extern crate piston;
extern crate rand;

mod drawing;
mod game;
mod models;
mod traits;

use piston_window::*;
use opengl_graphics::GlGraphics;

use game::Game;

fn main() {

    let opengl = OpenGL::V3_2;

    let mut game = Game::new(drawing::Size::new(1024.0, 600.0));

    let mut window: PistonWindow = WindowSettings::new("Rocket!", [1024, 600])
        .opengl(opengl).samples(8).exit_on_esc(true).build().unwrap();

    window.set_ups(60);
    window.set_max_fps(60);

    let mut gl = GlGraphics::new(opengl);

    let mut events = window.events();

    while let Some(e) = events.next(&mut window) {
    // Event handling
        match e {
            Event::Input(Input::Press(Button::Keyboard(key))) => {
                game.key_press(key);
            }

            Event::Input(Input::Release(Button::Keyboard(key))) => {
                game.key_release(key);
            }

            Event::Input(Input::Press(Button::Controller(button))) => {
                game.button_press(button);
            }

            Event::Input(Input::Release(Button::Controller(button))) => {
                game.button_release(button);
            }

            // Controller Axis are Move Input types
            Event::Input(Input::Move(Motion::ControllerAxis(axis))) => {
                game.handle_axis(axis);
            }

            Event::Render(args) => {
                gl.draw(args.viewport(), |c, g| game.render(c, g));
            }

            Event::Update(args) => {
                game.update(args.dt);
            }

            _ => {}
        }
    }

}
<commit_msg>Remove glob import.<commit_after>extern crate piston_window;
extern crate graphics;
extern crate itertools;
extern crate opengl_graphics;
extern crate piston;
extern crate rand;

mod drawing;
mod game;
mod models;
mod traits;

use piston_window::{Button, Event, Events, EventLoop, Input, Motion, OpenGL, PistonWindow,
    WindowSettings};
use opengl_graphics::GlGraphics;

use game::Game;

fn main() {

    let opengl = OpenGL::V3_2;

    let mut game = Game::new(drawing::Size::new(1024.0, 600.0));

    let mut window: PistonWindow = WindowSettings::new("Rocket!", [1024, 600])
        .opengl(opengl).samples(8).exit_on_esc(true).build().unwrap();

    window.set_ups(60);
    window.set_max_fps(60);

    let mut gl = GlGraphics::new(opengl);

    let mut events = window.events();

    while let Some(e) = events.next(&mut window) {
    // Event handling
        match e {
            Event::Input(Input::Press(Button::Keyboard(key))) => {
                game.key_press(key);
            }

            Event::Input(Input::Release(Button::Keyboard(key))) => {
                game.key_release(key);
            }

            Event::Input(Input::Press(Button::Controller(button))) => {
                game.button_press(button);
            }

            Event::Input(Input::Release(Button::Controller(button))) => {
                game.button_release(button);
            }

            // Controller Axis are Move Input types
            Event::Input(Input::Move(Motion::ControllerAxis(axis))) => {
                game.handle_axis(axis);
            }

            Event::Render(args) => {
                gl.draw(args.viewport(), |c, g| game.render(c, g));
            }

            Event::Update(args) => {
                game.update(args.dt);
            }

            _ => {}
        }
    }

}
<|endoftext|>


<commit_before>extern crate serde;
extern crate serde_json;

#[macro_use]
extern crate nickel;
#[macro_use]
extern crate serde_derive;

extern crate bincode;
extern crate leveldb;

use bincode::{serialize, deserialize, Infinite};

use std::path::Path;
use std::sync::Arc;

use leveldb::database::Database;
use leveldb::kv::KV;
use leveldb::iterator::Iterable;
use leveldb::options::{Options,WriteOptions,ReadOptions};

use nickel::{Nickel, HttpRouter, NickelError, Request, Action};
use nickel::status::StatusCode;

mod raw_body;
use self::raw_body::*;

const DEFAULT_DIR: &'static str = "./tokendb";

#[derive(Serialize, Deserialize)]
pub struct SSDeposit {
    status: String,
    address: String,
    params: Vec<String>,
    id: usize,
}

fn main() {
    let mut server = Nickel::new();

    let path = Path::new(DEFAULT_DIR);
    let db = Arc::new(TokenDB::new(path));
    let read_db = db.clone();
    let all_db = db.clone();

    server.post("/", middleware! { |req, res|
        let raw = req.raw_body();
        let deposit = serde_json::from_str::<SSDeposit>(&raw).unwrap();
        db.write_deposit(&deposit);

        format!("Deposit Received {} {}", deposit.address, deposit.status)
    });

    server.get("/key/:id", middleware! { |req|
        let id = req.param("id").unwrap();
        println!("id: {}", id);
        let key: i32 = id.parse()
                    .expect("Failed to parse key");

        let data = read_db.read_deposit(key)
            .expect("Failed to lookup key");

        let deposit: SSDeposit = deserialize(&data)
            .expect("Corrupted entry in db");

        match serde_json::to_string(&deposit) {
            Ok(res) => { (StatusCode::Ok, res.to_string()) },
            Err(e) => { (StatusCode::NotFound, e.to_string()) }
        }
    });

    server.get("/all", middleware! { |req|
        let mut last: Option<usize> = None;
        loop {
            match all_db.dump() {
                Some(data) => {
                    let deposit: SSDeposit = deserialize(&data)
                                    .expect("Corrupted entry in db");
                    if Some(deposit.id) == last {
                        break;
                    }
                    last = Some(deposit.id);
                    println!("{}", serde_json::to_string(&deposit).unwrap());
                },
                _ => { break; }
            };
        }

    });

    server.listen("127.0.0.1:8675");

}

pub struct TokenDB {
  db: Database<i32>
}

impl TokenDB {
  pub fn new(path: &Path) -> TokenDB {
      let mut options = Options::new();
      options.create_if_missing = true;
      let db = match Database::open(path, options) {
        Ok(db) => { db },
        Err(e) => { panic!("failed to open database: {:?}", e) }
      };
      TokenDB {
        db: db,
      }
  }

  pub fn write_deposit(&self, deposit: &SSDeposit) -> () {
      let write_opts = WriteOptions::new();
      // turn into buffer
      let bytes: Vec<u8> = serialize(deposit, Infinite).unwrap();
      match self.db.put(write_opts, deposit.id as i32, &bytes) {
          Ok(_) => { () },
          Err(e) => { panic!("failed to write to database: {:?}", e) }
      };
  }

  pub fn read_deposit(&self, key: i32) -> Option<Vec<u8>> {
      let read_opts = ReadOptions::new();
      let res = self.db.get(read_opts, key);
      let data = match res {
        Ok(data) => { data },
        Err(e) => { panic!("failed reading data: {:?}", e) }
      };
      data
  }

  pub fn dump(&self) -> Option<Vec<u8>> {
      let read_opts = ReadOptions::new();
      let mut iter = self.db.value_iter(read_opts);
      let data = iter.next();
      data
  }

}
<commit_msg>cleanup<commit_after>extern crate serde;
extern crate serde_json;

#[macro_use]
extern crate nickel;
#[macro_use]
extern crate serde_derive;

extern crate bincode;
extern crate leveldb;

use bincode::{serialize, deserialize, Infinite};

use std::path::Path;
use std::sync::Arc;

use leveldb::database::Database;
use leveldb::kv::KV;
use leveldb::iterator::Iterable;
use leveldb::options::{Options,WriteOptions,ReadOptions};

use nickel::{Nickel, HttpRouter};
use nickel::status::StatusCode;

mod raw_body;
use self::raw_body::*;

const DEFAULT_DIR: &'static str = "./tokendb";

#[derive(Serialize, Deserialize)]
pub struct SSDeposit {
    status: String,
    address: String,
    params: Vec<String>,
    id: usize,
}

fn main() {
    let mut server = Nickel::new();

    let path = Path::new(DEFAULT_DIR);
    let db = Arc::new(TokenDB::new(path));
    let read_db = db.clone();
    let all_db = db.clone();

    server.post("/", middleware! { |req, res|
        let raw = req.raw_body();
        let deposit = serde_json::from_str::<SSDeposit>(&raw).unwrap();
        db.write_deposit(&deposit);

        format!("Deposit Received {} {}", deposit.address, deposit.status)
    });

    server.get("/key/:id", middleware! { |req|
        let id = req.param("id").unwrap();
        println!("id: {}", id);
        let key: i32 = id.parse()
                    .expect("Failed to parse key");

        let data = read_db.read_deposit(key)
            .expect("Failed to lookup key");

        let deposit: SSDeposit = deserialize(&data)
            .expect("Corrupted entry in db");

        match serde_json::to_string(&deposit) {
            Ok(res) => { (StatusCode::Ok, res.to_string()) },
            Err(e) => { (StatusCode::NotFound, e.to_string()) }
        }
    });

    server.get("/all", middleware! {
        let mut last: Option<usize> = None;
        loop {
            match all_db.dump() {
                Some(data) => {
                    let deposit: SSDeposit = deserialize(&data)
                                    .expect("Corrupted entry in db");
                    if Some(deposit.id) == last {
                        break;
                    }
                    last = Some(deposit.id);
                    println!("{}", serde_json::to_string(&deposit).unwrap());
                },
                _ => { break; }
            };
        }

    });

    server.listen("127.0.0.1:8675");

}

pub struct TokenDB {
  db: Database<i32>
}

impl TokenDB {
  pub fn new(path: &Path) -> TokenDB {
      let mut options = Options::new();
      options.create_if_missing = true;
      let db = match Database::open(path, options) {
        Ok(db) => { db },
        Err(e) => { panic!("failed to open database: {:?}", e) }
      };
      TokenDB {
        db: db,
      }
  }

  pub fn write_deposit(&self, deposit: &SSDeposit) -> () {
      let write_opts = WriteOptions::new();
      // turn into buffer
      let bytes: Vec<u8> = serialize(deposit, Infinite).unwrap();
      match self.db.put(write_opts, deposit.id as i32, &bytes) {
          Ok(_) => { () },
          Err(e) => { panic!("failed to write to database: {:?}", e) }
      };
  }

  pub fn read_deposit(&self, key: i32) -> Option<Vec<u8>> {
      let read_opts = ReadOptions::new();
      let res = self.db.get(read_opts, key);
      let data = match res {
        Ok(data) => { data },
        Err(e) => { panic!("failed reading data: {:?}", e) }
      };
      data
  }

  pub fn dump(&self) -> Option<Vec<u8>> {
      let read_opts = ReadOptions::new();
      let mut iter = self.db.value_iter(read_opts);
      let data = iter.next();
      data
  }

}
<|endoftext|>


<commit_before>
mod curses;

use std::ffi::CString;

use curses::*;

enum DrawMe {
    Rec { width : i32, height : i32, x : i32, y : i32 },
    /*
    Character
    */
}

enum Mode { Normal, EnterRec, MoveRec }

fn inc_width( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width + 1, height: height, x: x, y: y },
        _ => panic!( "inc width encounters non-rec" ),
    }
}

fn inc_height( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height + 1, x: x, y: y },
        _ => panic!( "inc width encounters non-rec" ),
    }
}

fn dec_width( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width - 1, height: height, x: x, y: y },
        _ => panic!( "inc width encounters non-rec" ),
    }
}

fn dec_height( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height - 1, x: x, y: y },
        _ => panic!( "inc width encounters non-rec" ),
    }
}

fn inc_x( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x + 1, y: y },
        _ => panic!( "inc width encounters non-rec" ),
    }
}

fn inc_y( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x, y: y + 1 },
        _ => panic!( "inc width encounters non-rec" ),
    }
}

fn dec_x( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x - 1, y: y },
        _ => panic!( "inc width encounters non-rec" ),
    }
}

fn dec_y( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x, y: y - 1 },
        _ => panic!( "inc width encounters non-rec" ),
    }
}
fn mod_rec<F>( maybe_d : Option<DrawMe>, f : F ) -> Option<DrawMe>
    where F : Fn( DrawMe ) -> DrawMe {

    match maybe_d {
        Some( d ) => Some( f( d ) ),
        None => { None },
    }
}

unsafe fn render_shape( s : &DrawMe ) {
    match s {
        &DrawMe::Rec { width, height, x, y } => render_rec( width, height, x, y ),
        _ => (),
    }
}

unsafe fn render_rec( w : i32, h : i32, x : i32, y : i32 ) {
    let dot = CString::new( "." ).unwrap();
    let h_line = CString::new( "-" ).unwrap();
    let v_line = CString::new( "|" ).unwrap();
    let plus = CString::new( "+" ).unwrap();

    let mut h2 = h + 2;
    while h2 > 0 {
        let d : &CString = if h2 == h + 2 {
            &h_line
        } else if h2 == 1 {
            &h_line
        } else {
            &dot
        };
        let mut w2 = w;

        let other_d : &CString = if h2 == h + 2 {
            &plus
        } else if h2 == 1 {
            &plus
        } else {
            &v_line
        };
        mvprintw( y + h2 + UserY, x + w2 + 1 + UserX, other_d.as_ptr() );
        while w2 > 0 {
            mvprintw( y + h2 + UserY, x + w2 + UserX, d.as_ptr() );
            w2 -= 1;
        }
        mvprintw( y + h2 + UserY, x + UserX, other_d.as_ptr() );
        h2 -= 1;
    }
}

static mut UserX : i32 = 0;
static mut UserY : i32 = 0;

fn main() {
    let mut x = 0;
    let mut y = 0;
    unsafe {
        initscr();
        cbreak();
        noecho();

        let mut c = getch();
        let mut shapes : Vec<DrawMe> = vec! [];
        let mut mode : Mode = Mode::Normal;

        // TODO need mode for entering rech, etc

        while c as u8 as char != 'q' {
            let c2 = c as u8 as char;

            match c2 {
                'r' => {
                    shapes.push( DrawMe::Rec { width: 0, height: 0, x: x - UserX, y: y - UserY } );
                },
                'j' => {
                    y+=1;
                },
                'k' => {
                    y-=1;
                },
                'l' => {
                    x+=1;
                },
                'h' => {
                    x-=1;
                },
                'J' => {
                    UserY += 1;
                },
                'K' => {
                    UserY -= 1;
                },
                'L' => {
                    UserX += 1;
                },
                'H' => {
                    UserX -= 1;
                },
                _ => (),
            }

            clear();

            for s in &shapes {
                render_shape( s );
            }

            cursor_move( y, x );
            refresh();

            c = getch();
        }

        endwin();
    }
}

<commit_msg>active rec<commit_after>
mod curses;

use std::ffi::CString;

use curses::*;

enum DrawMe {
    Rec { width : i32, height : i32, x : i32, y : i32 },
    /*
    Character
    */
}

enum Mode { Normal, EnterRec, MoveRec }

fn inc_width( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width + 1, height: height, x: x, y: y },
        _ => panic!( "inc width encounters non-rec" ),
    }
}

fn inc_height( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height + 1, x: x, y: y },
        _ => panic!( "inc width encounters non-rec" ),
    }
}

fn dec_width( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width - 1, height: height, x: x, y: y },
        _ => panic!( "inc width encounters non-rec" ),
    }
}

fn dec_height( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height - 1, x: x, y: y },
        _ => panic!( "inc width encounters non-rec" ),
    }
}

fn inc_x( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x + 1, y: y },
        _ => panic!( "inc width encounters non-rec" ),
    }
}

fn inc_y( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x, y: y + 1 },
        _ => panic!( "inc width encounters non-rec" ),
    }
}

fn dec_x( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x - 1, y: y },
        _ => panic!( "inc width encounters non-rec" ),
    }
}

fn dec_y( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x, y: y - 1 },
        _ => panic!( "inc width encounters non-rec" ),
    }
}
fn mod_rec<F>( maybe_d : Option<DrawMe>, f : F ) -> Option<DrawMe>
    where F : Fn( DrawMe ) -> DrawMe {

    match maybe_d {
        Some( d ) => Some( f( d ) ),
        None => { None },
    }
}

unsafe fn render_shape( s : &DrawMe ) {
    match s {
        &DrawMe::Rec { width, height, x, y } => render_rec( width, height, x, y ),
        _ => (),
    }
}

unsafe fn render_rec( w : i32, h : i32, x : i32, y : i32 ) {
    let dot = CString::new( "." ).unwrap();
    let h_line = CString::new( "-" ).unwrap();
    let v_line = CString::new( "|" ).unwrap();
    let plus = CString::new( "+" ).unwrap();

    let mut h2 = h + 2;
    while h2 > 0 {
        let d : &CString = if h2 == h + 2 {
            &h_line
        } else if h2 == 1 {
            &h_line
        } else {
            &dot
        };
        let mut w2 = w;

        let other_d : &CString = if h2 == h + 2 {
            &plus
        } else if h2 == 1 {
            &plus
        } else {
            &v_line
        };
        mvprintw( y + h2 + UserY, x + w2 + 1 + UserX, other_d.as_ptr() );
        while w2 > 0 {
            mvprintw( y + h2 + UserY, x + w2 + UserX, d.as_ptr() );
            w2 -= 1;
        }
        mvprintw( y + h2 + UserY, x + UserX, other_d.as_ptr() );
        h2 -= 1;
    }
}

static mut UserX : i32 = 0;
static mut UserY : i32 = 0;

fn main() {
    let mut x = 0;
    let mut y = 0;
    unsafe {
        initscr();
        cbreak();
        noecho();

        let mut c = getch();
        let mut shapes : Vec<DrawMe> = vec! [];
        let mut mode : Mode = Mode::Normal;
        let mut active_rec : Option<DrawMe> = None;

        // TODO need mode for entering rech, etc

        while c as u8 as char != 'q' {
            let c2 = c as u8 as char;

            match c2 {
                'r' => {
                    match mode {
                        Mode::Normal => {
                            active_rec = Some( DrawMe::Rec { width: 0, height: 0, x: x - UserX, y: y - UserY });
                            mode = Mode::EnterRec;
                        },
                        Mode::EnterRec => {
                            mode = Mode::MoveRec;
                        },
                        Mode::MoveRec => {
                            mode = Mode::Normal;
                            shapes.push( active_rec.unwrap() );
                            active_rec = None;
                        },
                    }
                },
                'j' => {
                    match mode {
                        Mode::Normal => {
                            y+=1;
                        },
                        Mode::EnterRec => {
                            active_rec = mod_rec( active_rec, inc_height );
                        },
                        Mode::MoveRec => {
                            active_rec = mod_rec( active_rec, inc_y );
                        },
                    }
                },
                'k' => {
                    y-=1;
                },
                'l' => {
                    x+=1;
                },
                'h' => {
                    x-=1;
                },
                'J' => {
                    UserY += 1;
                },
                'K' => {
                    UserY -= 1;
                },
                'L' => {
                    UserX += 1;
                },
                'H' => {
                    UserX -= 1;
                },
                _ => (),
            }

            clear();

            match active_rec {
                Some( ref shape ) => render_shape( &shape ),
                None => {},
            }

            for s in &shapes {
                render_shape( s );
            }

            cursor_move( y, x );
            refresh();

            c = getch();
        }

        endwin();
    }
}

<|endoftext|>


<commit_before>use std::fmt;
use std::str::FromStr;

#[derive(Debug, PartialEq)]
enum Atom {
	Number(f64),
	Symbol(String)
}

enum ParseAtomError {
    IncorrectSymbolName
}

impl fmt::Display for Atom {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		match self {
			&Atom::Number(n) => {
				write!(f, "{}", n)
			},
			&Atom::Symbol(ref name) => {
				write!(f, "'{}'", name)
			}
		}
	}
}

impl FromStr for Atom {
	type Err = ParseAtomError;

	fn from_str(s: &str) -> Result<Atom, ParseAtomError> {
		match s.parse::<f64>() {
			Ok(f) => {
				Ok(Atom::Number(f))
			},
			Err(..) => {
				match s.chars().next() {
					Some(c) => {
						if c.is_numeric() {
							Err(ParseAtomError::IncorrectSymbolName)
						} else {
							Ok(Atom::Symbol(s.to_string()))
						}
					},
					None => {
						Err(ParseAtomError::IncorrectSymbolName)
					}
				}
			}
		}
	}
}

#[cfg_attr(test, allow(dead_code))]
fn main() {
}

#[cfg(test)]
mod test {
	use super::Atom;

	#[test]
	fn parse_integer() {
		assert_eq!(Atom::Number(64f64), "64".parse::<Atom>().ok().unwrap())
	}

	#[test]
	fn parse_float() {
		assert_eq!(Atom::Number(64.5), "64.5".parse::<Atom>().ok().unwrap())
	}

	#[test]
	fn parse_symbol() {
		assert_eq!(Atom::Symbol("name".to_string()), "name".parse::<Atom>().ok().unwrap())
	}
}
<commit_msg>Fix indentations<commit_after>use std::fmt;
use std::str::FromStr;

#[derive(Debug, PartialEq)]
enum Atom {
  Number(f64),
    Symbol(String)
}

enum ParseAtomError {
    IncorrectSymbolName
}

impl fmt::Display for Atom {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    match self {
      &Atom::Number(n) => {
        write!(f, "{}", n)
      },
      &Atom::Symbol(ref name) => {
        write!(f, "'{}'", name)
      }
    }
  }
}

impl FromStr for Atom {
  type Err = ParseAtomError;

  fn from_str(s: &str) -> Result<Atom, ParseAtomError> {
    match s.parse::<f64>() {
      Ok(f) => {
        Ok(Atom::Number(f))
      },
      Err(..) => {
        match s.chars().next() {
          Some(c) => {
            if c.is_numeric() {
              Err(ParseAtomError::IncorrectSymbolName)
            } else {
              Ok(Atom::Symbol(s.to_string()))
            }
          },
          None => {
            Err(ParseAtomError::IncorrectSymbolName)
          }
        }
      }
    }
  }
}

#[cfg_attr(test, allow(dead_code))]
fn main() {
}

#[cfg(test)]
mod test {
  use super::Atom;

  #[test]
  fn parse_integer() {
    assert_eq!(Atom::Number(64f64), "64".parse::<Atom>().ok().unwrap())
  }

  #[test]
  fn parse_float() {
    assert_eq!(Atom::Number(64.5), "64.5".parse::<Atom>().ok().unwrap())
  }

  #[test]
  fn parse_symbol() {
    assert_eq!(Atom::Symbol("name".to_string()), "name".parse::<Atom>().ok().unwrap())
  }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate lazy_static;
extern crate regex;
extern crate rand;

pub mod basetypes;
pub mod chess_move;
pub mod position;
pub mod search;
pub mod uci;
pub mod tt;
pub mod time_manager;

use std::process::exit;
use std::sync::Arc;
use std::time::SystemTime;
use std::collections::VecDeque;
use basetypes::NodeCount;
use tt::{Tt, BOUND_EXACT, BOUND_UPPER, BOUND_LOWER};
use position::Position;
use uci::{UciEngine, UciEngineFactory, EngineReply, OptionName, OptionDescription};
use search::{Variation, SearchStatus, MultipvSearch};
use time_manager::TimeManager;

/// The version of the program.
pub const VERSION: &'static str = "0.1";

// The name of the program.
const NAME: &'static str = "Alcibiades";

// The author of the program.
const AUTHOR: &'static str = "Evgeni Pandurski";

// The starting position in Forsyth–Edwards notation (FEN).
const STARTING_POSITION: &'static str = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w QKqk - 0 1";

// Represents a condition for terminating the search.
enum PlayWhen {
    TimeManagement(TimeManager), // Stop when the time manager says.
    MoveTime(u64), // Stop after the given number of milliseconds.
    Nodes(NodeCount), // Stop when the given number of nodes has been searched.
    Depth(u8), // Stop when the given search depth has been reached.
    Never, // An infinite search.
}

/// Implements `UciEngine` trait.
pub struct Engine {
    tt: Arc<Tt>,
    position: Position,
    current_depth: u8,

    // `Engine` will hand over the real work to `MultipvSearch`.
    search: MultipvSearch,

    // Tells the engine when it must stop thinking and play the best
    // move it has found.
    play_when: PlayWhen,

    // Tells the engine how many best lines to calculate and send to
    // the GUI (the first move in each best line is different). This
    // is the so called "MultiPV" mode.
    variations_count: usize,

    // Tells the engine if it will be allowed to ponder. This option
    // is needed because the engine might change its time management
    // algorithm when pondering is allowed.
    pondering_is_allowed: bool,

    // `true` if the engine is thinking in pondering mode.
    is_pondering: bool,

    // Marks the last time when a message was sent by the engine to
    // the GUI, or if no message has been sent yet -- the time when
    // the search stared.
    silent_since: SystemTime,

    // A queue for the messages send by the engine to the GUI.
    queue: VecDeque<EngineReply>,
}

impl Engine {
    /// Creates a new instance.
    ///
    /// `tt_size_mb` is the preferred size of the transposition
    /// table in Mbytes.
    pub fn new(tt_size_mb: usize) -> Engine {
        let mut tt = Tt::new();
        tt.resize(tt_size_mb);
        let tt = Arc::new(tt);

        Engine {
            tt: tt.clone(),
            position: Position::from_fen(STARTING_POSITION).ok().unwrap(),
            current_depth: 0,
            search: MultipvSearch::new(tt),
            play_when: PlayWhen::Never,
            variations_count: 1,
            pondering_is_allowed: false,
            is_pondering: false,
            silent_since: SystemTime::now(),
            queue: VecDeque::new(),
        }
    }

    // A helper method. It it adds a progress report message to
    // `self.queue`.
    fn queue_progress_report(&mut self) {
        let &SearchStatus { depth, searched_nodes, nps, .. } = self.search.status();
        self.queue.push_back(EngineReply::Info(vec![
            ("depth".to_string(), format!("{}", depth)),
            ("nodes".to_string(), format!("{}", searched_nodes)),
            ("nps".to_string(), format!("{}", nps)),
        ]));
        self.silent_since = SystemTime::now();
    }

    // A helper method. It it adds a message containing the current
    // (multi)PV to `self.queue`.
    fn queue_pv(&mut self) {
        let &SearchStatus { depth, ref variations, searched_nodes, duration_millis, nps, .. } =
            self.search.status();
        for (i, &Variation { ref moves, value, bound }) in variations.iter().enumerate() {
            let bound_suffix = match bound {
                BOUND_EXACT => "",
                BOUND_UPPER => " upperbound",
                BOUND_LOWER => " lowerbound",
                _ => panic!("unexpected bound type"),
            };
            let mut moves_string = String::new();
            for m in moves {
                moves_string.push_str(&m.notation());
                moves_string.push(' ');
            }
            self.queue.push_back(EngineReply::Info(vec![
            ("depth".to_string(), format!("{}", depth)),
            ("multipv".to_string(), format!("{}", i + 1)),
            ("score".to_string(), format!("cp {}{}", value, bound_suffix)),
            ("time".to_string(), format!("{}", duration_millis)),
            ("nodes".to_string(), format!("{}", searched_nodes)),
            ("nps".to_string(), format!("{}", nps)),
            ("pv".to_string(), moves_string),
        ]));
        }
        self.silent_since = SystemTime::now();
    }

    // A helper method. It it adds a message containing the current
    // best move to `self.queue`.
    fn queue_best_move(&mut self) {
        let &SearchStatus { ref variations, .. } = self.search.status();
        self.queue.push_back(EngineReply::BestMove {
            best_move: variations[0].moves.get(0).map_or("0000".to_string(), |m| m.notation()),
            ponder_move: variations[0].moves.get(1).map(|m| m.notation()),
        });
        self.silent_since = SystemTime::now();
    }
}

impl UciEngine for Engine {
    fn set_option(&mut self, name: &str, value: &str) {
        match name {
            "Ponder" => {
                self.pondering_is_allowed = value == "true";
            }

            "MultiPV" => {
                self.variations_count = match value.parse::<usize>().unwrap_or(0) {
                    0 => 1,
                    n if n > 500 => 500,
                    n => n,
                };
            }

            // An invalid option. Notice that we do not support
            // re-sizing of the transposition table once the engine
            // had started.
            _ => (),
        }
    }

    fn new_game(&mut self) {
        self.tt.clear();
    }

    fn position(&mut self, fen: &str, moves: &mut Iterator<Item = &str>) {
        if let Ok(p) = Position::from_history(fen, moves) {
            self.position = p;
        }
    }

    #[allow(unused_variables)]
    fn go(&mut self,
          searchmoves: Option<Vec<String>>,
          ponder: bool,
          wtime: Option<u64>,
          btime: Option<u64>,
          winc: Option<u64>,
          binc: Option<u64>,
          movestogo: Option<u64>,
          depth: Option<u64>,
          nodes: Option<u64>,
          mate: Option<u64>,
          movetime: Option<u64>,
          infinite: bool) {
        // Note: We ignore the "mate" parameter.

        self.search.stop();
        self.tt.new_search();
        self.current_depth = 0;
        self.is_pondering = ponder;
        self.play_when = if infinite {
            PlayWhen::Never
        } else if movetime.is_some() {
            PlayWhen::MoveTime(movetime.unwrap())
        } else if nodes.is_some() {
            PlayWhen::Nodes(nodes.unwrap())
        } else if depth.is_some() {
            PlayWhen::Depth(depth.unwrap() as u8)
        } else {
            PlayWhen::TimeManagement(TimeManager::new(&self.position,
                                                      self.pondering_is_allowed,
                                                      wtime,
                                                      btime,
                                                      winc,
                                                      binc,
                                                      movestogo))
        };
        self.silent_since = SystemTime::now();
        self.search.start(&self.position, searchmoves, self.variations_count);
    }

    fn ponder_hit(&mut self) {
        if self.search.status().done {
            self.queue_best_move();
        } else {
            self.is_pondering = false;
        }
    }

    fn stop(&mut self) {
        self.search.stop();
        self.queue_best_move();
    }

    fn get_reply(&mut self) -> Option<EngineReply> {
        if !self.search.status().done {
            // Update the search status.
            self.search.update_status();
            let &SearchStatus { done, depth, searched_nodes, duration_millis, .. } = self.search
                                                                                .status();

            // Send the (multi)PV when changed.
            if depth > self.current_depth {
                self.current_depth = depth;
                self.queue_pv();
            }

            // Send periodic progress reports.
            if self.silent_since.elapsed().unwrap().as_secs() > 10 {
                self.queue_progress_report();
            }

            // Register the updated search status with the time manager.
            if let PlayWhen::TimeManagement(ref mut tm) = self.play_when {
                tm.update_status(self.search.status());
            }

            // Check if we must play now.
            if !self.is_pondering &&
               match self.play_when {
                PlayWhen::TimeManagement(ref tm) => done || tm.must_play(),
                PlayWhen::MoveTime(t) => done || duration_millis >= t,
                PlayWhen::Nodes(n) => done || searched_nodes >= n,
                PlayWhen::Depth(d) => done || depth >= d,
                PlayWhen::Never => false,
            } {
                self.stop();
            }
        }

        self.queue.pop_front()
    }

    fn exit(&mut self) {
        self.search.exit();
    }
}

/// Implements `UciEngineFactory` trait.
pub struct EngineFactory;

impl UciEngineFactory<Engine> for EngineFactory {
    fn name(&self) -> String {
        format!("{} {}", NAME, VERSION)
    }

    fn author(&self) -> String {
        AUTHOR.to_string()
    }

    fn options(&self) -> Vec<(OptionName, OptionDescription)> {
        vec![
            // TODO: Calculate a sane limit for the hash size.
            ("Hash".to_string(), OptionDescription::Spin { min: 1, max: 2048, default: 16 }),
            ("Ponder".to_string(), OptionDescription::Check { default: false }),
            ("MultiPV".to_string(), OptionDescription::Spin { min: 1, max: 500, default: 1 }),
        ]
    }

    fn create(&self, hash_size_mb: Option<usize>) -> Engine {
        Engine::new(hash_size_mb.unwrap_or(16))
    }
}

fn main() {
    if let Ok(mut uci_loop) = uci::Server::wait_for_hanshake(EngineFactory) {
        match uci_loop.serve() {
            Ok(_) => {
                exit(0);
            }
            Err(_) => {
                exit(1);
            }
        }
    }
    exit(2);
}
<commit_msg>more beauti in main.rs<commit_after>#[macro_use]
extern crate lazy_static;
extern crate regex;
extern crate rand;

pub mod basetypes;
pub mod chess_move;
pub mod position;
pub mod search;
pub mod uci;
pub mod tt;
pub mod time_manager;

use std::process::exit;
use std::sync::Arc;
use std::time::SystemTime;
use std::collections::VecDeque;
use basetypes::NodeCount;
use tt::{Tt, BOUND_EXACT, BOUND_UPPER, BOUND_LOWER};
use position::Position;
use uci::{UciEngine, UciEngineFactory};
use search::{Variation, SearchStatus, MultipvSearch};
use time_manager::TimeManager;

/// The version of the program.
pub const VERSION: &'static str = "0.1";

// The name of the program.
const NAME: &'static str = "Alcibiades";

// The author of the program.
const AUTHOR: &'static str = "Evgeni Pandurski";

// The starting position in Forsyth–Edwards notation (FEN).
const STARTING_POSITION: &'static str = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w QKqk - 0 1";

// Represents a condition for terminating the search.
enum PlayWhen {
    TimeManagement(TimeManager), // Stop when the time manager says.
    MoveTime(u64), // Stop after the given number of milliseconds.
    Nodes(NodeCount), // Stop when the given number of nodes has been searched.
    Depth(u8), // Stop when the given search depth has been reached.
    Never, // An infinite search.
}

/// Implements `UciEngine` trait.
pub struct Engine {
    tt: Arc<Tt>,
    position: Position,
    current_depth: u8,

    // `Engine` will hand over the real work to `MultipvSearch`.
    search: MultipvSearch,

    // Tells the engine when it must stop thinking and play the best
    // move it has found.
    play_when: PlayWhen,

    // Tells the engine how many best lines to calculate and send to
    // the GUI (the first move in each best line is different). This
    // is the so called "MultiPV" mode.
    variations_count: usize,

    // Tells the engine if it will be allowed to ponder. This option
    // is needed because the engine might change its time management
    // algorithm when pondering is allowed.
    pondering_is_allowed: bool,

    // `true` if the engine is thinking in pondering mode.
    is_pondering: bool,

    // Marks the last time when a message was sent by the engine to
    // the GUI, or if no message has been sent yet -- the time when
    // the search stared.
    silent_since: SystemTime,

    // A queue for the messages send by the engine to the GUI.
    queue: VecDeque<uci::EngineReply>,
}

impl Engine {
    /// Creates a new instance.
    ///
    /// `tt_size_mb` is the preferred size of the transposition
    /// table in Mbytes.
    pub fn new(tt_size_mb: usize) -> Engine {
        let mut tt = Tt::new();
        tt.resize(tt_size_mb);
        let tt = Arc::new(tt);

        Engine {
            tt: tt.clone(),
            position: Position::from_fen(STARTING_POSITION).ok().unwrap(),
            current_depth: 0,
            search: MultipvSearch::new(tt),
            play_when: PlayWhen::Never,
            variations_count: 1,
            pondering_is_allowed: false,
            is_pondering: false,
            silent_since: SystemTime::now(),
            queue: VecDeque::new(),
        }
    }

    // A helper method. It it adds a progress report message to
    // `self.queue`.
    fn queue_progress_report(&mut self) {
        let &SearchStatus { depth, searched_nodes, nps, .. } = self.search.status();
        self.queue.push_back(uci::EngineReply::Info(vec![
            ("depth".to_string(), format!("{}", depth)),
            ("nodes".to_string(), format!("{}", searched_nodes)),
            ("nps".to_string(), format!("{}", nps)),
        ]));
        self.silent_since = SystemTime::now();
    }

    // A helper method. It it adds a message containing the current
    // (multi)PV to `self.queue`.
    fn queue_pv(&mut self) {
        let &SearchStatus { depth, ref variations, searched_nodes, duration_millis, nps, .. } =
            self.search.status();
        for (i, &Variation { ref moves, value, bound }) in variations.iter().enumerate() {
            let bound_suffix = match bound {
                BOUND_EXACT => "",
                BOUND_UPPER => " upperbound",
                BOUND_LOWER => " lowerbound",
                _ => panic!("unexpected bound type"),
            };
            let mut moves_string = String::new();
            for m in moves {
                moves_string.push_str(&m.notation());
                moves_string.push(' ');
            }
            self.queue.push_back(uci::EngineReply::Info(vec![
            ("depth".to_string(), format!("{}", depth)),
            ("multipv".to_string(), format!("{}", i + 1)),
            ("score".to_string(), format!("cp {}{}", value, bound_suffix)),
            ("time".to_string(), format!("{}", duration_millis)),
            ("nodes".to_string(), format!("{}", searched_nodes)),
            ("nps".to_string(), format!("{}", nps)),
            ("pv".to_string(), moves_string),
        ]));
        }
        self.silent_since = SystemTime::now();
    }

    // A helper method. It it adds a message containing the current
    // best move to `self.queue`.
    fn queue_best_move(&mut self) {
        let &SearchStatus { ref variations, .. } = self.search.status();
        self.queue.push_back(uci::EngineReply::BestMove {
            best_move: variations[0].moves.get(0).map_or("0000".to_string(), |m| m.notation()),
            ponder_move: variations[0].moves.get(1).map(|m| m.notation()),
        });
        self.silent_since = SystemTime::now();
    }
}

impl UciEngine for Engine {
    fn set_option(&mut self, name: &str, value: &str) {
        match name {
            "Ponder" => {
                self.pondering_is_allowed = value == "true";
            }

            "MultiPV" => {
                self.variations_count = match value.parse::<usize>().unwrap_or(0) {
                    0 => 1,
                    n if n > 500 => 500,
                    n => n,
                };
            }

            // An invalid option. Notice that we do not support
            // re-sizing of the transposition table once the engine
            // had started.
            _ => (),
        }
    }

    fn new_game(&mut self) {
        self.tt.clear();
    }

    fn position(&mut self, fen: &str, moves: &mut Iterator<Item = &str>) {
        if let Ok(p) = Position::from_history(fen, moves) {
            self.position = p;
        }
    }

    #[allow(unused_variables)]
    fn go(&mut self,
          searchmoves: Option<Vec<String>>,
          ponder: bool,
          wtime: Option<u64>,
          btime: Option<u64>,
          winc: Option<u64>,
          binc: Option<u64>,
          movestogo: Option<u64>,
          depth: Option<u64>,
          nodes: Option<u64>,
          mate: Option<u64>,
          movetime: Option<u64>,
          infinite: bool) {
        // Note: We ignore the "mate" parameter.

        self.search.stop();
        self.tt.new_search();
        self.current_depth = 0;
        self.is_pondering = ponder;
        self.play_when = if infinite {
            PlayWhen::Never
        } else if movetime.is_some() {
            PlayWhen::MoveTime(movetime.unwrap())
        } else if nodes.is_some() {
            PlayWhen::Nodes(nodes.unwrap())
        } else if depth.is_some() {
            PlayWhen::Depth(depth.unwrap() as u8)
        } else {
            PlayWhen::TimeManagement(TimeManager::new(&self.position,
                                                      self.pondering_is_allowed,
                                                      wtime,
                                                      btime,
                                                      winc,
                                                      binc,
                                                      movestogo))
        };
        self.silent_since = SystemTime::now();
        self.search.start(&self.position, searchmoves, self.variations_count);
    }

    fn ponder_hit(&mut self) {
        if self.search.status().done {
            self.queue_best_move();
        } else {
            self.is_pondering = false;
        }
    }

    fn stop(&mut self) {
        self.search.stop();
        self.queue_best_move();
    }

    fn get_reply(&mut self) -> Option<uci::EngineReply> {
        if !self.search.status().done {
            // Update the search status.
            self.search.update_status();
            let &SearchStatus { done, depth, searched_nodes, duration_millis, .. } = self.search
                                                                                .status();

            // Send the (multi)PV when changed.
            if depth > self.current_depth {
                self.current_depth = depth;
                self.queue_pv();
            }

            // Send periodic progress reports.
            if self.silent_since.elapsed().unwrap().as_secs() > 10 {
                self.queue_progress_report();
            }

            // Register the updated search status with the time manager.
            if let PlayWhen::TimeManagement(ref mut tm) = self.play_when {
                tm.update_status(self.search.status());
            }

            // Check if we must play now.
            if !self.is_pondering &&
               match self.play_when {
                PlayWhen::TimeManagement(ref tm) => done || tm.must_play(),
                PlayWhen::MoveTime(t) => done || duration_millis >= t,
                PlayWhen::Nodes(n) => done || searched_nodes >= n,
                PlayWhen::Depth(d) => done || depth >= d,
                PlayWhen::Never => false,
            } {
                self.stop();
            }
        }

        self.queue.pop_front()
    }

    fn exit(&mut self) {
        self.search.exit();
    }
}

/// Implements `UciEngineFactory` trait.
pub struct EngineFactory;

impl UciEngineFactory<Engine> for EngineFactory {
    fn name(&self) -> String {
        format!("{} {}", NAME, VERSION)
    }

    fn author(&self) -> String {
        AUTHOR.to_string()
    }

    fn options(&self) -> Vec<(uci::OptionName, uci::OptionDescription)> {
        vec![
            // TODO: Calculate a sane limit for the hash size.
            ("Hash".to_string(), uci::OptionDescription::Spin { min: 1, max: 2048, default: 16 }),
            ("Ponder".to_string(), uci::OptionDescription::Check { default: false }),
            ("MultiPV".to_string(), uci::OptionDescription::Spin { min: 1, max: 500, default: 1 }),
        ]
    }

    fn create(&self, hash_size_mb: Option<usize>) -> Engine {
        Engine::new(hash_size_mb.unwrap_or(16))
    }
}

fn main() {
    if let Ok(mut uci_loop) = uci::Server::wait_for_hanshake(EngineFactory) {
        match uci_loop.serve() {
            Ok(_) => {
                exit(0);
            }
            Err(_) => {
                exit(1);
            }
        }
    }
    exit(2);
}
<|endoftext|>


<commit_before>mod simulation;

extern crate getopts;
extern crate rand;

use std::env;
use std::str;
use std::path::Path;
use std::fs::File;
use std::io::BufReader;
use std::io::BufRead;
use getopts::Options;
use rand::Rng;
use simulation::CellState;
use simulation::Simulator;

fn print_usage(program: &str, opts: Options) {
	let brief = format!("Usage: {} OUTPUT_DIR [options]", program);
	print!("{}", opts.usage(&brief));
}

fn generate_grid(height: usize, width: usize) -> Vec<Vec<CellState>> {
	let mut grid = Vec::new();
	for _ in 0..height {
		let mut row = Vec::new();
		for _ in 0..width {
			let rn = rand::thread_rng().gen_range(0, 2);
			let cell = match rn {
				0 => CellState::Dead,
				1 => CellState::Alive,
				_ => panic!("Somehow got a incorrect random number!?")
			};
			row.push(cell);
		}
		grid.push(row);
	}
	return grid;
}

fn parse_input_file(path: &Path) -> Vec<Vec<CellState>> {
	match File::open(&path) {
		Ok(file) => {
			let input_file = BufReader::new(file);
			let mut grid: Vec<Vec<CellState>> = Vec::new();
			for line in input_file.lines().filter_map(|result| result.ok()) {
				let chars = line.split(",");
				let mut row: Vec<CellState> = Vec::new();
				for cell in chars {
					let c: CellState = match cell {
						"0" => CellState::Dead,
						"1" => CellState::Alive,
						_ => panic!("Invalid value in input file")
					};
					row.push(c);
				}
				grid.push(row);
			}
			grid
		},
		Err(e) => {
			panic!("Could not open input file: {}", e);
		}
	}
}

fn main() {
	// Define args
	let args: Vec<String> = env::args().collect();
	let program = args[0].clone();

	let mut opts = Options::new();
	opts.optflag("h", "help", "Display the help text");
	opts.optopt("w", "width", "Provide a width for the grid", "WIDTH");
	opts.optopt("t", "height", "Provide a height for the grid", "HEIGHT");
	opts.optopt("n", "interations", "Provide the number of iterations to run",
		"ITERATIONS");
	opts.optopt("i", "input_file", "Provide a file containing the initial state",
		"INPUT_FILE");
	opts.optopt("o", "output_dir", "Provide a directory for output", "OUTPUT_DIR");

	// Parse args
	let matches = match opts.parse(&args[1..]) {
		Ok(m) => { m }
		Err(f) => { panic!(f.to_string()) }
	};
	// Check for help request
	if matches.opt_present("h") {
		print_usage(&program, opts);
		return;
	}
	// Parse number of iterations to run
	let iterations_str = match matches.opt_str("n") {
		Some(s) => { s }
		None => {
			println!("Required parameter 'iterations' missing");
			print_usage(&program, opts);
			return;
		}
	};
	let iterations = match iterations_str.parse::<u32>() {
		Ok(i) => i,
		Err(err) => {
			println!("Invalid value for iterations (flag 'i'):\n{}\n", err);
			return;
		}
	};
	// Parse output dir
	let output = matches.opt_str("o");
	// let output = if !matches.free.is_empty() {
	// 	matches.free[0].clone()
	// } else {
	// 	println!("Required argument OUTPUT_DIR missing\n");
	// 	print_usage(&program, opts);
	// 	return;
	// };
	// Create starting states
	let grid: Vec<Vec<CellState>> = match matches.opt_str("i") {
		Some(i) => {
			// An input file is specified
			let path = Path::new(&i);
			parse_input_file(path)
		},
		None => {
			// Parse height and width of grid
			let height_str = match matches.opt_str("t") {
				Some(expr) => expr,
				None => String::from("None"),
			};
			let height: usize = match height_str.parse::<usize>() {
				Ok(h) => h,
				Err(err) => panic!("Invalid value for height (flag 't'):\n{}\n", err)
			};
			let width_str = match matches.opt_str("w") {
				Some(expr) => expr,
				None => String::from("None"),
			};
			let width: usize = match width_str.parse::<usize>() {
				Ok(w) => w,
				Err(err) => panic!("Invalid value for width (flag 'w'):\n{}\n", err)
			};
			// Generation random grid
			generate_grid(height, width)
		}
	};
	// Run simulation
	let mut sim = Simulator::new(iterations, output, grid);
	sim.run_simulation();
}
<commit_msg>Removed old output directory read code<commit_after>mod simulation;

extern crate getopts;
extern crate rand;

use std::env;
use std::str;
use std::path::Path;
use std::fs::File;
use std::io::BufReader;
use std::io::BufRead;
use getopts::Options;
use rand::Rng;
use simulation::CellState;
use simulation::Simulator;

fn print_usage(program: &str, opts: Options) {
	let brief = format!("Usage: {} OUTPUT_DIR [options]", program);
	print!("{}", opts.usage(&brief));
}

fn generate_grid(height: usize, width: usize) -> Vec<Vec<CellState>> {
	let mut grid = Vec::new();
	for _ in 0..height {
		let mut row = Vec::new();
		for _ in 0..width {
			let rn = rand::thread_rng().gen_range(0, 2);
			let cell = match rn {
				0 => CellState::Dead,
				1 => CellState::Alive,
				_ => panic!("Somehow got a incorrect random number!?")
			};
			row.push(cell);
		}
		grid.push(row);
	}
	return grid;
}

fn parse_input_file(path: &Path) -> Vec<Vec<CellState>> {
	match File::open(&path) {
		Ok(file) => {
			let input_file = BufReader::new(file);
			let mut grid: Vec<Vec<CellState>> = Vec::new();
			for line in input_file.lines().filter_map(|result| result.ok()) {
				let chars = line.split(",");
				let mut row: Vec<CellState> = Vec::new();
				for cell in chars {
					let c: CellState = match cell {
						"0" => CellState::Dead,
						"1" => CellState::Alive,
						_ => panic!("Invalid value in input file")
					};
					row.push(c);
				}
				grid.push(row);
			}
			grid
		},
		Err(e) => {
			panic!("Could not open input file: {}", e);
		}
	}
}

fn main() {
	// Define args
	let args: Vec<String> = env::args().collect();
	let program = args[0].clone();

	let mut opts = Options::new();
	opts.optflag("h", "help", "Display the help text");
	opts.optopt("w", "width", "Provide a width for the grid", "WIDTH");
	opts.optopt("t", "height", "Provide a height for the grid", "HEIGHT");
	opts.optopt("n", "interations", "Provide the number of iterations to run",
		"ITERATIONS");
	opts.optopt("i", "input_file", "Provide a file containing the initial state",
		"INPUT_FILE");
	opts.optopt("o", "output_dir", "Provide a directory for output", "OUTPUT_DIR");

	// Parse args
	let matches = match opts.parse(&args[1..]) {
		Ok(m) => { m }
		Err(f) => { panic!(f.to_string()) }
	};
	// Check for help request
	if matches.opt_present("h") {
		print_usage(&program, opts);
		return;
	}
	// Parse number of iterations to run
	let iterations_str = match matches.opt_str("n") {
		Some(s) => { s }
		None => {
			println!("Required parameter 'iterations' missing");
			print_usage(&program, opts);
			return;
		}
	};
	let iterations = match iterations_str.parse::<u32>() {
		Ok(i) => i,
		Err(err) => {
			println!("Invalid value for iterations (flag 'i'):\n{}\n", err);
			return;
		}
	};
	// Parse output dir
	let output = matches.opt_str("o");
	// Create starting states
	let grid: Vec<Vec<CellState>> = match matches.opt_str("i") {
		Some(i) => {
			// An input file is specified
			let path = Path::new(&i);
			parse_input_file(path)
		},
		None => {
			// Parse height and width of grid
			let height_str = match matches.opt_str("t") {
				Some(expr) => expr,
				None => String::from("None"),
			};
			let height: usize = match height_str.parse::<usize>() {
				Ok(h) => h,
				Err(err) => panic!("Invalid value for height (flag 't'):\n{}\n", err)
			};
			let width_str = match matches.opt_str("w") {
				Some(expr) => expr,
				None => String::from("None"),
			};
			let width: usize = match width_str.parse::<usize>() {
				Ok(w) => w,
				Err(err) => panic!("Invalid value for width (flag 'w'):\n{}\n", err)
			};
			// Generation random grid
			generate_grid(height, width)
		}
	};
	// Run simulation
	let mut sim = Simulator::new(iterations, output, grid);
	sim.run_simulation();
}
<|endoftext|>


<commit_before>fn main() {
    let (x,y) = (1,2);
    println!("x,y=({},{})", x,y);
}

<commit_msg>structs<commit_after>struct Vec3 {
    x: f32,
    y: f32,
    z: f32,
}

fn sum(x: Vec3, y: Vec3) -> Vec3 {
    Vec3{x: x.x + y.x, y: x.y + y.y, z: x.z + y.z}
}

fn main() {
    let a = Vec3{x: 1.0, y: 2.0, z: 3.0};
    let b = Vec3{x: 4.0, y: 5.0, z: 6.0};
    let c = sum(a, b);
    println!("a+b=({}, {}, {})", c.x, c.y, c.z);
}
<|endoftext|>