<commit_before>extern crate libc;

use libc::funcs::posix88::unistd;
use std::ffi::CString;
use std::cmp;
use std::os;
use std::ptr;
use std::rand::Rng;

fn main() {
    let version = "0.1.0";
    match parse_args(os::args().as_slice().tail()) {
        Err(Exit::Usage) => {
            os::set_exit_status(1);
            print_usage(version);
        }
        Err(Exit::Help) =>
            print_usage(version),
        Err(Exit::Version) =>
            print_version(version),
        Ok(opts) => {
            if whack(&opts) {
                os::set_exit_status(1);
            } else {
                opts.exe.map_or((), |exe| {
                    execvp(exe.name, exe.args)
                });
            }
        }
    }
}

type ArgParse<T> = Result<T, Exit>;

#[derive(Debug)]
struct Options<'a> {
    chance: i32,
    exe: Option<Exe<'a>>,
}

#[derive(Debug)]
struct Exe<'a> {
    name: &'a str,
    args: &'a[String],
}

#[derive(Debug)]
enum Exit {
    Usage,
    Help,
    Version,
}

fn parse_args(args: &[String]) -> ArgParse<Options> {
    args.uncons().map_or(Err(Exit::Usage), |(s, args)| {
        match s.as_slice() {
            "--help"    | "-h" => Err(Exit::Help),
            "--version" | "-v" => Err(Exit::Version),
            "--chance"  | "-c" => {
                args.uncons().map_or(Err(Exit::Usage), |(s, args)| {
                    s.parse().map_or(Err(Exit::Usage), |val| {
                        args.skip("--").uncons().map_or(
                            Ok(Options {
                                chance: val,
                                exe: None
                            }), |(exe, args)| {
                                Ok(Options {
                                    chance: val,
                                    exe: Some(Exe {
                                        name: exe.as_slice(),
                                        args: args,
                                    })
                                })
                            })
                        })
                    })
                }
            _ => Err(Exit::Usage),
        }
    })
}

trait Uncons<'a, A> { fn uncons(&self) -> Option<(&'a A, &'a [A])>; }
trait Skip<'a, A, B> { fn skip(&self, x: A) -> &'a [B]; }

impl<'a, A> Uncons<'a, A> for &'a [A] {
    fn uncons(&self) -> Option<(&'a A, &'a [A])> {
        self.first().map(|x| (x, self.tail()))
    }
}

impl<'a > Skip<'a, &'a str, String> for &'a [String] {
    fn skip(&self, x: &'a str) -> &'a [String] {
        self.uncons().map_or(*self, |(y, ys)| { if x == y.as_slice() { ys } else { *self } })
    }
}

fn whack(opts: &Options) -> bool {
    std::rand::thread_rng().gen_range(0, 100) > cmp::min(cmp::max(opts.chance, 0), 100)
}

fn execvp(name: &str, args: &[String]) {
    let c_name: CString = CString::from_slice(name.as_bytes());
    let c_args: Vec<CString> = args.iter().map(|tmp| CString::from_slice(tmp.as_bytes())).collect();

    let mut xs: Vec<*const libc::c_char> = Vec::with_capacity(args.len() + 2);

    xs.push(c_name.as_ptr());
    xs.extend(c_args.iter().map(|tmp| tmp.as_ptr()));
    xs.push(ptr::null());

    let c_arg0 = xs[0];
    let c_argv = xs.as_mut_ptr();

    unsafe {
        unistd::execvp(c_arg0, c_argv);
    };

    panic!("execvp(3) failed with: {}", os::last_os_error());
}

fn print_usage(version: &str) {
    print_version(version);
    println!("\n\
        Usage: whacky (-c PERCENTAGE|--chance PERCENTAGE) [[--] COMMAND]\n\
          whacky, yet another randomly failing program\n\
        \n\
        Available options:\n\
          -h,--help           show this help text\n\
          -c,--chance         set success chance");
}

fn print_version(version: &str) {
    println!("whacky {}", version);
}
<commit_msg>Ignore useful information about parse errors<commit_after>extern crate libc;

use libc::funcs::posix88::unistd;
use std::ffi::CString;
use std::cmp;
use std::os;
use std::ptr;
use std::rand::Rng;

fn main() {
    let version = "0.1.0";
    match parse_args(os::args().as_slice().tail()) {
        Err(Exit::Usage) => {
            os::set_exit_status(1);
            print_usage(version);
        }
        Err(Exit::Help) =>
            print_usage(version),
        Err(Exit::Version) =>
            print_version(version),
        Ok(opts) => {
            if whack(&opts) {
                os::set_exit_status(1);
            } else {
                opts.exe.map_or((), |exe| {
                    execvp(exe.name, exe.args)
                });
            }
        }
    }
}

type ArgParse<T> = Result<T, Exit>;

#[derive(Debug)]
struct Options<'a> {
    chance: i32,
    exe: Option<Exe<'a>>,
}

#[derive(Debug)]
struct Exe<'a> {
    name: &'a str,
    args: &'a[String],
}

#[derive(Debug)]
enum Exit {
    Usage,
    Help,
    Version,
}

fn parse_args(args: &[String]) -> ArgParse<Options> {
    args.uncons().map_or(Err(Exit::Usage), |(s, args)| {
        match s.as_slice() {
            "--help"    | "-h" => Err(Exit::Help),
            "--version" | "-v" => Err(Exit::Version),
            "--chance"  | "-c" => {
                args.uncons().map_or(Err(Exit::Usage), |(s, args)| {
                    s.parse().ok().map_or(Err(Exit::Usage), |val| {
                        args.skip("--").uncons().map_or(
                            Ok(Options {
                                chance: val,
                                exe: None
                            }), |(exe, args)| {
                                Ok(Options {
                                    chance: val,
                                    exe: Some(Exe {
                                        name: exe.as_slice(),
                                        args: args,
                                    })
                                })
                            })
                        })
                    })
                }
            _ => Err(Exit::Usage),
        }
    })
}

trait Uncons<'a, A> { fn uncons(&self) -> Option<(&'a A, &'a [A])>; }
trait Skip<'a, A, B> { fn skip(&self, x: A) -> &'a [B]; }

impl<'a, A> Uncons<'a, A> for &'a [A] {
    fn uncons(&self) -> Option<(&'a A, &'a [A])> {
        self.first().map(|x| (x, self.tail()))
    }
}

impl<'a > Skip<'a, &'a str, String> for &'a [String] {
    fn skip(&self, x: &'a str) -> &'a [String] {
        self.uncons().map_or(*self, |(y, ys)| { if x == y.as_slice() { ys } else { *self } })
    }
}

fn whack(opts: &Options) -> bool {
    std::rand::thread_rng().gen_range(0, 100) > cmp::min(cmp::max(opts.chance, 0), 100)
}

fn execvp(name: &str, args: &[String]) {
    let c_name: CString = CString::from_slice(name.as_bytes());
    let c_args: Vec<CString> = args.iter().map(|tmp| CString::from_slice(tmp.as_bytes())).collect();

    let mut xs: Vec<*const libc::c_char> = Vec::with_capacity(args.len() + 2);

    xs.push(c_name.as_ptr());
    xs.extend(c_args.iter().map(|tmp| tmp.as_ptr()));
    xs.push(ptr::null());

    let c_arg0 = xs[0];
    let c_argv = xs.as_mut_ptr();

    unsafe {
        unistd::execvp(c_arg0, c_argv);
    };

    panic!("execvp(3) failed with: {}", os::last_os_error());
}

fn print_usage(version: &str) {
    print_version(version);
    println!("\n\
        Usage: whacky (-c PERCENTAGE|--chance PERCENTAGE) [[--] COMMAND]\n\
          whacky, yet another randomly failing program\n\
        \n\
        Available options:\n\
          -h,--help           show this help text\n\
          -c,--chance         set success chance");
}

fn print_version(version: &str) {
    println!("whacky {}", version);
}
<|endoftext|>


<commit_before>// NOTE: for development purposes only. Will be removed soon
use std::io::prelude::*;
use std::net::TcpStream;

extern crate cdrs;
use cdrs::frame::Frame;
use cdrs::parser::parse_frame;
use cdrs::IntoBytes;
use cdrs::consistency::Consistency;
// use cadrs::frame_startup::BodyReqStartup;

fn main() {
    println!("connecting");
    let startup_message = Frame::new_req_startup(None);
    let use_query = String::from("USE loghub;");
    let q = Frame::new_req_query(use_query.clone(), Consistency::Any, None, None, None, None, None, None);
    println!(">>>>> {:?}", String::from_utf8_lossy(use_query.into_bytes().as_slice()));
    match TcpStream::connect("127.0.0.1:9042") {
        Err(err) => println!("{:?}", err),
        Ok(mut stream) => {
            println!("Ok. Starting connection");
            let vec: Vec<u8> = startup_message.into_cbytes();
            println!("Frame {:?}", vec);
            println!("Frame text {:?}", String::from_utf8(vec.clone()).unwrap());
            match stream.write(vec.as_slice()) {
                Ok(_) => {
                    println!("frame sent");
                },
                Err(err) => panic!("Error during writing into socket {}", err)
            }

            loop {
                let mut res = [0; 1024];
                match stream.read(&mut res) {
                    Ok(n) => {
                        if n > 0 {
                            // println!("Server response {:?}", String::from_utf8_lossy(&res[..]));
                            let parsed = parse_frame(res[..].to_vec());
                            println!("Parsed response {:?}", String::from_utf8_lossy(parsed.body.as_slice()));
                            match stream.write(q.into_cbytes().as_slice()) {
                                Ok(_) => {
                                    println!("frame sent use");
                                    // return;
                                },
                                Err(err) => panic!("Error during writing into socket {}", err)
                            }
                            continue;
                        } else {
                            println!("waiting...");
                        }

                    },
                    Err(err) => panic!("Error during reading from socket {}", err)
                }
            }
        }
    }
}
<commit_msg>Rid of main.rs<commit_after><|endoftext|>


<commit_before>#![feature(io, os, env, core, collections, rustc_private)]

extern crate getopts;
extern crate selecta;

use getopts::{optopt,getopts};

use selecta::configuration::Configuration;
use selecta::search::Search;
use selecta::tty::IO;
use selecta::screen::Screen;

#[allow(dead_code)]
fn main() {
    let initial_query = extract_initial_query();
    let lines = read_lines();

    let config = Configuration::from_inputs(lines, initial_query, Some(20));
    let mut search = Search::blank(&config);

    let mut screen = Screen::new();

    for _ in 0..(search.config.visible_limit) {
        screen.ansi.io.write("\n");
    }

    while !search.is_done() {
        screen.print(&search);
        let input = screen.ansi.io.read();
        match input {
            Some(character) => {
                search = screen.handle_keystroke(search, character.as_slice());
            },
            None => break,
        };
    }
    screen.move_cursor_to_end();
    screen.ansi.io.reset();
    println!("\n{}", search.selection().unwrap_or("".to_string()));
}

fn extract_initial_query() -> Option<String> {
    let args: Vec<String> = get_args();
    let opts = &[
        optopt("s", "search", "initial search query", ""),
    ];
    let matches = getopts(args.tail(), opts).unwrap();

    matches.opt_str("s")
}

fn get_args() -> Vec<String> {
    std::env::args().map( |os| os.into_string().ok().unwrap() ).collect()
}

fn read_lines() -> Vec<String> {
    std::old_io::stdio::stdin().lock().lines().map( |line| {
        line.unwrap().trim().to_string()
    }).collect()
}
<commit_msg>Dont add a linebreak after the result<commit_after>#![feature(io, os, env, core, collections, rustc_private)]

extern crate getopts;
extern crate selecta;

use getopts::{optopt,getopts};

use selecta::configuration::Configuration;
use selecta::search::Search;
use selecta::tty::IO;
use selecta::screen::Screen;

#[allow(dead_code)]
fn main() {
    let initial_query = extract_initial_query();
    let lines = read_lines();

    let config = Configuration::from_inputs(lines, initial_query, Some(20));
    let mut search = Search::blank(&config);

    let mut screen = Screen::new();

    for _ in 0..(search.config.visible_limit) {
        screen.ansi.io.write("\n");
    }

    while !search.is_done() {
        screen.print(&search);
        let input = screen.ansi.io.read();
        match input {
            Some(character) => {
                search = screen.handle_keystroke(search, character.as_slice());
            },
            None => break,
        };
    }
    screen.move_cursor_to_end();
    screen.ansi.io.reset();
    println!("{}", search.selection().unwrap_or("".to_string()));
}

fn extract_initial_query() -> Option<String> {
    let args: Vec<String> = get_args();
    let opts = &[
        optopt("s", "search", "initial search query", ""),
    ];
    let matches = getopts(args.tail(), opts).unwrap();

    matches.opt_str("s")
}

fn get_args() -> Vec<String> {
    std::env::args().map( |os| os.into_string().ok().unwrap() ).collect()
}

fn read_lines() -> Vec<String> {
    std::old_io::stdio::stdin().lock().lines().map( |line| {
        line.unwrap().trim().to_string()
    }).collect()
}
<|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,
        TEXTBOX,
        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(300.0, 50.0)
        .mid_left_of(MASTER)
        .rgb(0.4, 0.75, 0.6)
        .label("Send a message to Odin")
        .react(|| {
            *clicked = true;
        });

    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 prototype of a 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) {

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


<commit_before>#![recursion_limit = "128"]

extern crate ape;
extern crate app_dirs;
extern crate core;
#[macro_use]
extern crate error_chain;
extern crate getopts;
extern crate hyper;
extern crate id3;
extern crate image;
extern crate iron;
extern crate lewton;
extern crate metaflac;
extern crate mount;
extern crate params;
extern crate reqwest;
extern crate regex;
extern crate secure_session;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate staticfile;
extern crate sqlite;
extern crate toml;
extern crate typemap;
extern crate url;

#[cfg(windows)]
extern crate uuid;
#[cfg(windows)]
extern crate winapi;
#[cfg(windows)]
extern crate kernel32;
#[cfg(windows)]
extern crate shell32;
#[cfg(windows)]
extern crate user32;

#[cfg(unix)]
extern crate unix_daemonize;

#[cfg(unix)]
use unix_daemonize::{daemonize_redirect, ChdirMode};

use errors::*;
use getopts::Options;
use iron::prelude::*;
use mount::Mount;
use staticfile::Static;
use std::path::Path;
use std::sync::Arc;

mod api;
mod collection;
mod config;
mod ddns;
mod errors;
mod index;
mod metadata;
mod ui;
mod utils;
mod thumbnails;
mod vfs;

fn main() {
	if let Err(ref e) = run() {
		println!("Error: {}", e);

		for e in e.iter().skip(1) {
			println!("caused by: {}", e);
		}
		if let Some(backtrace) = e.backtrace() {
			println!("backtrace: {:?}", backtrace);
		}
		::std::process::exit(1);
	}
}

#[cfg(unix)]
fn daemonize() -> Result<()> {
	let mut log_file = utils::get_data_root()?;
	log_file.push("polaris.log");
	match daemonize_redirect(Some(&log_file), Some(&log_file), ChdirMode::NoChdir) {
		Ok(_) => Ok(()),
		Err(_) => bail!(ErrorKind::DaemonError),
	}
}

fn run() -> Result<()> {

	#[cfg(unix)]
	daemonize()?;

	// Parse CLI options
	let args: Vec<String> = std::env::args().collect();
	let mut options = Options::new();
	options.optopt("c", "config", "set the configuration file", "FILE");
	options.optopt("w", "web", "set the path to web client files", "DIRECTORY");
	let matches = options.parse(&args[1..])?;

	// Parse config
	let config_file_name = matches.opt_str("c");
	let config_file_path = config_file_name.map(|n| Path::new(n.as_str()).to_path_buf());
	let config = config::Config::parse(config_file_path)?;

	// Init VFS
	let vfs = Arc::new(vfs::Vfs::new(config.vfs.clone()));

	// Init index
	println!("Starting up index");
	let index = Arc::new(index::Index::new(vfs.clone(), &config.index)?);
	let index_ref = index.clone();
	std::thread::spawn(move || index_ref.run());

	// Mount API
	println!("Mounting API");
	let mut mount = Mount::new();
	let mut collection = collection::Collection::new(vfs, index);
	collection.load_config(&config)?;
	let handler = api::get_handler(collection, &config.secret);
	mount.mount("/api/", handler);

	// Mount static files
	println!("Mounting static files");
	let web_dir_name = matches.opt_str("w");
	let mut default_web_dir = utils::get_data_root()?;
	default_web_dir.push("web");
	let web_dir_path = web_dir_name
		.map(|n| Path::new(n.as_str()).to_path_buf())
		.unwrap_or(default_web_dir);

	mount.mount("/", Static::new(web_dir_path));

	println!("Starting up server");
	let mut server = Iron::new(mount).http(("0.0.0.0", 5050))?;

	// Start DDNS updates
	match config.ddns {
		Some(ref ddns_config) => {
			let ddns_config = ddns_config.clone();
			std::thread::spawn(|| { ddns::run(ddns_config); });
		}
		None => (),
	};

	// Run UI
	ui::run();

	println!("Shutting down server");
	server.close()?;

	Ok(())
}
<commit_msg>Added CLI option for custom DB path<commit_after>#![recursion_limit = "128"]

extern crate ape;
extern crate app_dirs;
extern crate core;
#[macro_use]
extern crate error_chain;
extern crate getopts;
extern crate hyper;
extern crate id3;
extern crate image;
extern crate iron;
extern crate lewton;
extern crate metaflac;
extern crate mount;
extern crate params;
extern crate reqwest;
extern crate regex;
extern crate secure_session;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate staticfile;
extern crate sqlite;
extern crate toml;
extern crate typemap;
extern crate url;

#[cfg(windows)]
extern crate uuid;
#[cfg(windows)]
extern crate winapi;
#[cfg(windows)]
extern crate kernel32;
#[cfg(windows)]
extern crate shell32;
#[cfg(windows)]
extern crate user32;

#[cfg(unix)]
extern crate unix_daemonize;

#[cfg(unix)]
use unix_daemonize::{daemonize_redirect, ChdirMode};

use errors::*;
use getopts::Options;
use iron::prelude::*;
use mount::Mount;
use staticfile::Static;
use std::path::Path;
use std::sync::Arc;

mod api;
mod collection;
mod config;
mod ddns;
mod errors;
mod index;
mod metadata;
mod ui;
mod utils;
mod thumbnails;
mod vfs;

fn main() {
	if let Err(ref e) = run() {
		println!("Error: {}", e);

		for e in e.iter().skip(1) {
			println!("caused by: {}", e);
		}
		if let Some(backtrace) = e.backtrace() {
			println!("backtrace: {:?}", backtrace);
		}
		::std::process::exit(1);
	}
}

#[cfg(unix)]
fn daemonize() -> Result<()> {
	let mut log_file = utils::get_data_root()?;
	log_file.push("polaris.log");
	match daemonize_redirect(Some(&log_file), Some(&log_file), ChdirMode::NoChdir) {
		Ok(_) => Ok(()),
		Err(_) => bail!(ErrorKind::DaemonError),
	}
}

fn run() -> Result<()> {

	#[cfg(unix)]
	daemonize()?;

	// Parse CLI options
	let args: Vec<String> = std::env::args().collect();
	let mut options = Options::new();
	options.optopt("c", "config", "set the configuration file", "FILE");
	options.optopt("d", "database", "set the path to index database", "FILE");
	options.optopt("w", "web", "set the path to web client files", "DIRECTORY");
	let matches = options.parse(&args[1..])?;

	// Parse config
	let config_file_name = matches.opt_str("c");
	let config_file_path = config_file_name.map(|n| Path::new(n.as_str()).to_path_buf());
	let mut config = config::Config::parse(config_file_path)?;

	// Init VFS
	let vfs = Arc::new(vfs::Vfs::new(config.vfs.clone()));

	// Init index
	println!("Starting up index");
	let index_file_name = matches.opt_str("d");
	let index_file_path = index_file_name.map(|n| Path::new(n.as_str()).to_path_buf());
	config.index.path = index_file_path.unwrap_or( config.index.path );
	let index = Arc::new(index::Index::new(vfs.clone(), &config.index)?);
	let index_ref = index.clone();
	std::thread::spawn(move || index_ref.run());

	// Mount API
	println!("Mounting API");
	let mut mount = Mount::new();
	let mut collection = collection::Collection::new(vfs, index);
	collection.load_config(&config)?;
	let handler = api::get_handler(collection, &config.secret);
	mount.mount("/api/", handler);

	// Mount static files
	println!("Mounting static files");
	let web_dir_name = matches.opt_str("w");
	let mut default_web_dir = utils::get_data_root()?;
	default_web_dir.push("web");
	let web_dir_path = web_dir_name
		.map(|n| Path::new(n.as_str()).to_path_buf())
		.unwrap_or(default_web_dir);

	mount.mount("/", Static::new(web_dir_path));

	println!("Starting up server");
	let mut server = Iron::new(mount).http(("0.0.0.0", 5050))?;

	// Start DDNS updates
	match config.ddns {
		Some(ref ddns_config) => {
			let ddns_config = ddns_config.clone();
			std::thread::spawn(|| { ddns::run(ddns_config); });
		}
		None => (),
	};

	// Run UI
	ui::run();

	println!("Shutting down server");
	server.close()?;

	Ok(())
}
<|endoftext|>


<commit_before>extern crate ppbert;
#[macro_use] extern crate clap;

use std::io::{self, ErrorKind, Read, Write, BufWriter};
use std::fs;
use std::process::exit;
use std::time::{Duration, Instant};

use clap::{Arg, App};

use ppbert::bertterm::BertTerm;
use ppbert::error::{BertError, Result};
use ppbert::parser;

const PROG_NAME: &str = "ppbert";

fn main() {
    let matches = App::new(PROG_NAME)
        .version(crate_version!())
        .author("Vincent Foley")
        .about("Pretty print structure encoded in Erlang's External Term Format")
        .arg(Arg::with_name("input_files")
             .value_name("FILES")
             .multiple(true))
        .arg(Arg::with_name("indent_width")
             .help("Indents with <num> spaces")
             .value_name("num")
             .short("i")
             .long("indent-width")
             .default_value("2")
             .takes_value(true))
        .arg(Arg::with_name("max_per_line")
             .help("Prints at most <num> basic terms per line")
             .value_name("num")
             .short("m")
             .long("max-terms-per-line")
             .default_value("5")
             .takes_value(true))
        .arg(Arg::with_name("verbose")
             .help("Enables verbose mode")
             .short("v")
             .long("verbose"))
        .arg(Arg::with_name("parse")
             .help("Parses the input, doesn't pretty print it")
             .short("p")
             .long("parse"))
        .arg(Arg::with_name("bert2")
             .help("Parses .bert2 files")
             .conflicts_with("disk_log")
             .short("2")
             .long("bert2"))
        .arg(Arg::with_name("disk_log")
             .help("Parses disk_log files")
             .conflicts_with("bert2")
             .short("d")
             .long("disk-log"))
        .arg(Arg::with_name("json")
             .help("Outputs in JSON")
             .short("j")
             .long("json"))
        .arg(Arg::with_name("transform-proplists")
             .help("Transforms proplists into JSON objects (only valid with --json)")
             .short("t")
             .long("transform-proplists"))
        .get_matches();

    let files: Vec<&str> = match matches.values_of("input_files") {
        Some(files) => files.collect(),
        None => vec!["-"]
    };
    let indent_level = value_t!(matches, "indent_width", usize).unwrap();
    let max_per_line = value_t!(matches, "max_per_line", usize).unwrap();
    let verbose = matches.is_present("verbose");
    let parse_only = matches.is_present("parse");
    let json = matches.is_present("json");
    let transform_proplists = matches.is_present("transform-proplists");

    let parse_fn =
        if matches.is_present("bert2") {
            parser::Parser::bert2_next
        } else if matches.is_present("disk_log") {
            parser::Parser::disk_log_next
        } else {
            parser::Parser::bert_next
        };
    let output_fn = match (json, transform_proplists) {
        (true, false)  => pp_json,
        (true, true)   => pp_json_proplist,
        (false, false) => pp_bert,
        (false, true)  => {
            eprintln!("{}: --transform-proplists is only valid with the --json flag", PROG_NAME);
            pp_bert
        }
    };

    let mut return_code = 0;
    for file in files {
        let res = handle_file(file, parse_only, verbose,
                              indent_level, max_per_line,
                              parse_fn, output_fn);
        match res {
            Ok(()) => (),
            Err(ref e) => {
                if broken_pipe(e) {
                    break;
                }
                return_code = 1;
                eprintln!("{}: {}: {}", PROG_NAME, file, e);
            }
        }
    }
    exit(return_code);
}

fn broken_pipe(err: &BertError) -> bool {
    match *err {
        BertError::IoError(ref ioerr) =>
            ioerr.kind() == ErrorKind::BrokenPipe,
        _ => false
    }
}

fn handle_file(
    file: &str,
    parse_only: bool,
    verbose: bool,
    indent: usize,
    terms_per_line: usize,
    parse_fn: fn(&mut parser::Parser) -> Option<Result<BertTerm>>,
    pp_fn: fn(BertTerm, usize, usize) -> Result<()>
) -> Result<()> {

    // Read file or stdin into buffer
    let now = Instant::now();
    let buf = if file == "-" {
        let stdin = io::stdin();
        let mut stdin = stdin.lock();
        let mut buf: Vec<u8> = Vec::with_capacity(4096);
        stdin.read_to_end(&mut buf)?;
        buf
    } else {
        fs::read(file)?
    };
    let read_dur = now.elapsed();

    let mut parser = parser::Parser::new(buf);
    let mut parse_dur = Duration::new(0, 0);
    let mut pp_dur = Duration::new(0, 0);

    loop {
        let now = Instant::now();
        let next_item = parse_fn(&mut parser);
        parse_dur += now.elapsed();

        match next_item {
            None => { break; }
            Some(Err(e)) => { return Err(e); }
            Some(Ok(t)) => {
                if !parse_only {
                    let now = Instant::now();
                    pp_fn(t, indent, terms_per_line)?;
                    pp_dur += now.elapsed();
                }
            }
        }
    }

    if verbose {
        eprintln!("{}: {} read time: {}.{:06} seconds", PROG_NAME, file, read_dur.as_secs(), read_dur.subsec_micros());
        eprintln!("{}: {} parse time: {}.{:06} seconds", PROG_NAME, file, parse_dur.as_secs(), parse_dur.subsec_micros());
        if !parse_only {
            eprintln!("{}: {} print time: {}.{:06} seconds", PROG_NAME, file, pp_dur.as_secs(), pp_dur.subsec_micros());
        }
    }

    return Ok(());
}

/// Outputs a BertTerm to stdout.
fn pp_bert(term: BertTerm, indent_width: usize, terms_per_line: usize) -> Result <()> {
    let stdout = io::stdout();
    let stdout = stdout.lock();
    let mut stdout = BufWriter::new(stdout);
    term.write_as_erlang(&mut stdout, indent_width, terms_per_line)?;
    writeln!(&mut stdout, "")?;
    return Ok(());
}

/// Outputs a BertTerm as JSON to stdout.
fn pp_json(term: BertTerm, _: usize, _: usize) -> Result <()> {
    let stdout = io::stdout();
    let stdout = stdout.lock();
    let mut stdout = BufWriter::new(stdout);
    term.write_as_json(&mut stdout, false)?;
    writeln!(&mut stdout, "")?;
    return Ok(());
}

/// Outputs a BertTerm as JSON to stdout;
/// Erlang proplists are converted to JSON objects.
fn pp_json_proplist(term: BertTerm, _: usize, _: usize) -> Result <()> {
    let stdout = io::stdout();
    let stdout = stdout.lock();
    let mut stdout = BufWriter::new(stdout);
    term.write_as_json(&mut stdout, true)?;
    writeln!(&mut stdout, "")?;
    return Ok(());
}
<commit_msg>Add calls to flush() to ensure errors are propagated<commit_after>extern crate ppbert;
#[macro_use] extern crate clap;

use std::io::{self, ErrorKind, Read, Write, BufWriter};
use std::fs;
use std::process::exit;
use std::time::{Duration, Instant};

use clap::{Arg, App};

use ppbert::bertterm::BertTerm;
use ppbert::error::{BertError, Result};
use ppbert::parser;

const PROG_NAME: &str = "ppbert";

fn main() {
    let matches = App::new(PROG_NAME)
        .version(crate_version!())
        .author("Vincent Foley")
        .about("Pretty print structure encoded in Erlang's External Term Format")
        .arg(Arg::with_name("input_files")
             .value_name("FILES")
             .multiple(true))
        .arg(Arg::with_name("indent_width")
             .help("Indents with <num> spaces")
             .value_name("num")
             .short("i")
             .long("indent-width")
             .default_value("2")
             .takes_value(true))
        .arg(Arg::with_name("max_per_line")
             .help("Prints at most <num> basic terms per line")
             .value_name("num")
             .short("m")
             .long("max-terms-per-line")
             .default_value("5")
             .takes_value(true))
        .arg(Arg::with_name("verbose")
             .help("Enables verbose mode")
             .short("v")
             .long("verbose"))
        .arg(Arg::with_name("parse")
             .help("Parses the input, doesn't pretty print it")
             .short("p")
             .long("parse"))
        .arg(Arg::with_name("bert2")
             .help("Parses .bert2 files")
             .conflicts_with("disk_log")
             .short("2")
             .long("bert2"))
        .arg(Arg::with_name("disk_log")
             .help("Parses disk_log files")
             .conflicts_with("bert2")
             .short("d")
             .long("disk-log"))
        .arg(Arg::with_name("json")
             .help("Outputs in JSON")
             .short("j")
             .long("json"))
        .arg(Arg::with_name("transform-proplists")
             .help("Transforms proplists into JSON objects (only valid with --json)")
             .short("t")
             .long("transform-proplists"))
        .get_matches();

    let files: Vec<&str> = match matches.values_of("input_files") {
        Some(files) => files.collect(),
        None => vec!["-"]
    };
    let indent_level = value_t!(matches, "indent_width", usize).unwrap();
    let max_per_line = value_t!(matches, "max_per_line", usize).unwrap();
    let verbose = matches.is_present("verbose");
    let parse_only = matches.is_present("parse");
    let json = matches.is_present("json");
    let transform_proplists = matches.is_present("transform-proplists");

    let parse_fn =
        if matches.is_present("bert2") {
            parser::Parser::bert2_next
        } else if matches.is_present("disk_log") {
            parser::Parser::disk_log_next
        } else {
            parser::Parser::bert_next
        };
    let output_fn = match (json, transform_proplists) {
        (true, false)  => pp_json,
        (true, true)   => pp_json_proplist,
        (false, false) => pp_bert,
        (false, true)  => {
            eprintln!("{}: --transform-proplists is only valid with the --json flag", PROG_NAME);
            pp_bert
        }
    };

    let mut return_code = 0;
    for file in files {
        let res = handle_file(file, parse_only, verbose,
                              indent_level, max_per_line,
                              parse_fn, output_fn);
        match res {
            Ok(()) => (),
            Err(ref e) => {
                if broken_pipe(e) {
                    break;
                }
                return_code = 1;
                eprintln!("{}: {}: {}", PROG_NAME, file, e);
            }
        }
    }
    exit(return_code);
}

fn broken_pipe(err: &BertError) -> bool {
    match *err {
        BertError::IoError(ref ioerr) =>
            ioerr.kind() == ErrorKind::BrokenPipe,
        _ => false
    }
}

fn handle_file(
    file: &str,
    parse_only: bool,
    verbose: bool,
    indent: usize,
    terms_per_line: usize,
    parse_fn: fn(&mut parser::Parser) -> Option<Result<BertTerm>>,
    pp_fn: fn(BertTerm, usize, usize) -> Result<()>
) -> Result<()> {

    // Read file or stdin into buffer
    let now = Instant::now();
    let buf = if file == "-" {
        let stdin = io::stdin();
        let mut stdin = stdin.lock();
        let mut buf: Vec<u8> = Vec::with_capacity(4096);
        stdin.read_to_end(&mut buf)?;
        buf
    } else {
        fs::read(file)?
    };
    let read_dur = now.elapsed();

    let mut parser = parser::Parser::new(buf);
    let mut parse_dur = Duration::new(0, 0);
    let mut pp_dur = Duration::new(0, 0);

    loop {
        let now = Instant::now();
        let next_item = parse_fn(&mut parser);
        parse_dur += now.elapsed();

        match next_item {
            None => { break; }
            Some(Err(e)) => { return Err(e); }
            Some(Ok(t)) => {
                if !parse_only {
                    let now = Instant::now();
                    pp_fn(t, indent, terms_per_line)?;
                    pp_dur += now.elapsed();
                }
            }
        }
    }

    if verbose {
        eprintln!("{}: {} read time: {}.{:06} seconds", PROG_NAME, file, read_dur.as_secs(), read_dur.subsec_micros());
        eprintln!("{}: {} parse time: {}.{:06} seconds", PROG_NAME, file, parse_dur.as_secs(), parse_dur.subsec_micros());
        if !parse_only {
            eprintln!("{}: {} print time: {}.{:06} seconds", PROG_NAME, file, pp_dur.as_secs(), pp_dur.subsec_micros());
        }
    }

    return Ok(());
}

/// Outputs a BertTerm to stdout.
fn pp_bert(term: BertTerm, indent_width: usize, terms_per_line: usize) -> Result<()> {
    let stdout = io::stdout();
    let stdout = stdout.lock();
    let mut stdout = BufWriter::new(stdout);
    term.write_as_erlang(&mut stdout, indent_width, terms_per_line)?;
    stdout.flush()?;
    writeln!(&mut stdout, "")?;
    return Ok(());
}

/// Outputs a BertTerm as JSON to stdout.
fn pp_json(term: BertTerm, _: usize, _: usize) -> Result<()> {
    let stdout = io::stdout();
    let stdout = stdout.lock();
    let mut stdout = BufWriter::new(stdout);
    term.write_as_json(&mut stdout, false)?;
    writeln!(&mut stdout, "")?;
    stdout.flush()?;
    return Ok(());
}

/// Outputs a BertTerm as JSON to stdout;
/// Erlang proplists are converted to JSON objects.
fn pp_json_proplist(term: BertTerm, _: usize, _: usize) -> Result<()> {
    let stdout = io::stdout();
    let stdout = stdout.lock();
    let mut stdout = BufWriter::new(stdout);
    term.write_as_json(&mut stdout, true)?;
    writeln!(&mut stdout, "")?;
    stdout.flush()?;
    return Ok(());
}
<|endoftext|>


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

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

#[derive(Debug, PartialEq)]
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() => {
                        Ok(Atom::Symbol(s.to_string()))
                    },
                    _ => {
                        Err(ParseAtomError::IncorrectSymbolName)
                    }
                }
            }
        }
    }
}

fn tokenize(s: &str) -> Vec<String> {
    s.replace("("," ( ")
        .replace(")", " ) ")
        .replace("\n", " ")
        .split(' ')
        .filter(|s| { !s.is_empty() })
        .map(|s| { s.to_string() })
        .collect()
}

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

#[cfg(test)]
mod test {
    use super::{Atom, ParseAtomError, tokenize};

    #[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())
    }

    #[test]
    fn parse_incorrect_symbol_starting_with_digit() {
        assert_eq!(ParseAtomError::IncorrectSymbolName, "6name".parse::<Atom>().err().unwrap())
    }

    #[test]
    fn tokenize_dense_expression() {
        let expected_result = ["(", "def", "a", "1", ")"]
                                .iter()
                                .map(|s| { s.to_string() })
                                .collect();
        assert_eq!(expected_result, tokenize("(def a 1)"))
    }

    #[test]
    fn tokenize_sparse_expression() {
        let expected_result = ["(", "def", "a", "1", ")"]
                                .iter()
                                .map(|s| { s.to_string() })
                                .collect();
        assert_eq!(expected_result, tokenize(" ( \n def a\n1)   \n"))
    }
}
<commit_msg>Add test prefix for test functions and rename test module to tests<commit_after>use std::fmt;
use std::str::FromStr;

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

#[derive(Debug, PartialEq)]
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() => {
                        Ok(Atom::Symbol(s.to_string()))
                    },
                    _ => {
                        Err(ParseAtomError::IncorrectSymbolName)
                    }
                }
            }
        }
    }
}

fn tokenize(s: &str) -> Vec<String> {
    s.replace("("," ( ")
        .replace(")", " ) ")
        .replace("\n", " ")
        .split(' ')
        .filter(|s| { !s.is_empty() })
        .map(|s| { s.to_string() })
        .collect()
}

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

#[cfg(test)]
mod tests {
    use super::{Atom, ParseAtomError, tokenize};

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

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

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

    #[test]
    fn test_parse_incorrect_symbol_starting_with_digit() {
        assert_eq!(ParseAtomError::IncorrectSymbolName, "6name".parse::<Atom>().err().unwrap())
    }

    #[test]
    fn test_tokenize_dense_expression() {
        let expected_result = ["(", "def", "a", "1", ")"]
                                .iter()
                                .map(|s| { s.to_string() })
                                .collect();
        assert_eq!(expected_result, tokenize("(def a 1)"))
    }

    #[test]
    fn test_tokenize_sparse_expression() {
        let expected_result = ["(", "def", "a", "1", ")"]
                                .iter()
                                .map(|s| { s.to_string() })
                                .collect();
        assert_eq!(expected_result, tokenize(" ( \n def a\n1)   \n"))
    }
}
<|endoftext|>


<commit_before>extern crate hyper;
extern crate rustc_serialize;

use rustc_serialize::json;

mod state;

use hyper::server::{Server, Request, Response};

fn hello(req: Request, res: Response) {
	let game = state::initialState();
	let encoded = json::encode(&game).unwrap();

	res.send(encoded.as_bytes()).unwrap();
}

fn main() {
    println!("Starting server on localhost:3001");
	Server::http("localhost:3001").unwrap().handle(hello).unwrap();
}
<commit_msg>Handle each http request based on it's path and method<commit_after>extern crate hyper;
extern crate rustc_serialize;

mod state;

use rustc_serialize::json;
use hyper::Get;
use hyper::server::{Server, Request, Response};
use hyper::uri::RequestUri::AbsolutePath;

macro_rules! try_return(
    ($e:expr) => {{
        match $e {
            Ok(v) => v,
	    Err(e) => { println!("Error: {}", e); return; }
	}
    }}
);

fn handle_request(req: Request, mut res: Response) {
	match req.uri {
		AbsolutePath(ref path) => match (&req.method, &path[..]) {
			(&Get, "/") => {
				try_return!(res.send(b"Hey, what up."));
				return;
			},
			(&Get, "/state") => {
				let game = state::initialState();
				let encoded = json::encode(&game).unwrap();
				try_return!(res.send(encoded.as_bytes()));
				return;
			}
			_ => {
				*res.status_mut() = hyper::NotFound;
				return;
			}
		},
		_ => {
			return;
		}
	};
}

fn main() {
    let server = Server::http("localhost:3001").unwrap();
    let _guard = server.handle(handle_request);
    println!("Starting server on localhost:3001");
}
<|endoftext|>


<commit_before>#![feature(collections, convert, core, exit_status, file_type, fs_ext, fs_mode)]
#![feature(metadata_ext, raw_ext, symlink_metadata)]

extern crate ansi_term;
extern crate datetime;
extern crate getopts;
extern crate libc;
extern crate locale;
extern crate natord;
extern crate num_cpus;
extern crate number_prefix;
extern crate pad;
extern crate threadpool;
extern crate unicode_width;
extern crate users;

#[cfg(feature="git")]
extern crate git2;

use std::env;
use std::fs;
use std::path::{Component, Path, PathBuf};
use std::sync::mpsc::channel;

use threadpool::ThreadPool;

use dir::Dir;
use file::File;
use options::{Options, View};

mod colours;
mod column;
mod dir;
mod feature;
mod file;
mod filetype;
mod options;
mod output;
mod term;

#[cfg(not(test))]
struct Exa<'dir> {
    count:   usize,
    options: Options,
    dirs:    Vec<PathBuf>,
    files:   Vec<File<'dir>>,
}

#[cfg(not(test))]
impl<'dir> Exa<'dir> {
    fn new(options: Options) -> Exa<'dir> {
        Exa {
            count: 0,
            options: options,
            dirs: Vec::new(),
            files: Vec::new(),
        }
    }

    fn load(&mut self, files: &[String]) {

        // Separate the user-supplied paths into directories and files.
        // Files are shown first, and then each directory is expanded
        // and listed second.
        let is_tree = self.options.dir_action.is_tree() || self.options.dir_action.is_as_file();
        let total_files = files.len();

        // Communication between consumer thread and producer threads
        enum StatResult<'dir> {
            File(File<'dir>),
            Dir(PathBuf),
            Error
        }

        let pool = ThreadPool::new(8 * num_cpus::get());
        let (tx, rx) = channel();

        for file in files.iter() {
            let tx = tx.clone();
            let file = file.clone();

            // Spawn producer thread
            pool.execute(move || {
                let path = Path::new(&*file);
                let _ = tx.send(match fs::metadata(&path) {
                    Ok(metadata) => {
                        if !metadata.is_dir() {
                            StatResult::File(File::with_metadata(metadata, &path, None, false))
                        }
                        else if is_tree {
                            StatResult::File(File::with_metadata(metadata, &path, None, true))
                        }
                        else {
                            StatResult::Dir(path.to_path_buf())
                        }
                    }
                    Err(e) => {
                        println!("{}: {}", file, e);
                        StatResult::Error
                    }
                });
            });
        }

        // Spawn consumer thread
        for result in rx.iter().take(total_files) {
            match result {
                StatResult::File(file)  => self.files.push(file),
                StatResult::Dir(path)   => self.dirs.push(path),
                StatResult::Error       => ()
            }
            self.count += 1;
        }
    }

    fn print_files(&self) {
        if !self.files.is_empty() {
            self.print(None, &self.files[..]);
        }
    }

    fn print_dirs(&mut self) {
        let mut first = self.files.is_empty();

        // Directories are put on a stack rather than just being iterated through,
        // as the vector can change as more directories are added.
        loop {
            let dir_path = match self.dirs.pop() {
                None => break,
                Some(f) => f,
            };

            // Put a gap between directories, or between the list of files and the
            // first directory.
            if first {
                first = false;
            }
            else {
                print!("\n");
            }

            match Dir::readdir(&dir_path) {
                Ok(ref dir) => {
                    let mut files = dir.files(false);
                    self.options.transform_files(&mut files);

                    // When recursing, add any directories to the dirs stack
                    // backwards: the *last* element of the stack is used each
                    // time, so by inserting them backwards, they get displayed in
                    // the correct sort order.
                    if let Some(recurse_opts) = self.options.dir_action.recurse_options() {
                        let depth = dir_path.components().filter(|&c| c != Component::CurDir).count() + 1;
                        if !recurse_opts.tree && !recurse_opts.is_too_deep(depth) {
                            for dir in files.iter().filter(|f| f.is_directory()).rev() {
                                self.dirs.push(dir.path.clone());
                            }
                        }
                    }

                    if self.count > 1 {
                        println!("{}:", dir_path.display());
                    }
                    self.count += 1;

                    self.print(Some(dir), &files[..]);
                }
                Err(e) => {
                    println!("{}: {}", dir_path.display(), e);
                    return;
                }
            };
        }
    }

    fn print(&self, dir: Option<&Dir>, files: &[File]) {
        match self.options.view {
            View::Grid(g)     => g.view(files),
            View::Details(d)  => d.view(dir, files),
            View::Lines(l)    => l.view(files),
        }
    }
}

#[cfg(not(test))]
fn main() {
    let args: Vec<String> = env::args().collect();

    match Options::getopts(args.tail()) {
        Ok((options, paths)) => {
            let mut exa = Exa::new(options);
            exa.load(&paths);
            exa.print_files();
            exa.print_dirs();
        },
        Err(e) => {
            println!("{}", e);
            env::set_exit_status(e.error_code());
        },
    };
}
<commit_msg>Remove a few feature flags<commit_after>#![feature(collections, convert, core, exit_status, fs_mode)]

extern crate ansi_term;
extern crate datetime;
extern crate getopts;
extern crate libc;
extern crate locale;
extern crate natord;
extern crate num_cpus;
extern crate number_prefix;
extern crate pad;
extern crate threadpool;
extern crate unicode_width;
extern crate users;

#[cfg(feature="git")]
extern crate git2;

use std::env;
use std::fs;
use std::path::{Component, Path, PathBuf};
use std::sync::mpsc::channel;

use threadpool::ThreadPool;

use dir::Dir;
use file::File;
use options::{Options, View};

mod colours;
mod column;
mod dir;
mod feature;
mod file;
mod filetype;
mod options;
mod output;
mod term;

#[cfg(not(test))]
struct Exa<'dir> {
    count:   usize,
    options: Options,
    dirs:    Vec<PathBuf>,
    files:   Vec<File<'dir>>,
}

#[cfg(not(test))]
impl<'dir> Exa<'dir> {
    fn new(options: Options) -> Exa<'dir> {
        Exa {
            count: 0,
            options: options,
            dirs: Vec::new(),
            files: Vec::new(),
        }
    }

    fn load(&mut self, files: &[String]) {

        // Separate the user-supplied paths into directories and files.
        // Files are shown first, and then each directory is expanded
        // and listed second.
        let is_tree = self.options.dir_action.is_tree() || self.options.dir_action.is_as_file();
        let total_files = files.len();

        // Communication between consumer thread and producer threads
        enum StatResult<'dir> {
            File(File<'dir>),
            Dir(PathBuf),
            Error
        }

        let pool = ThreadPool::new(8 * num_cpus::get());
        let (tx, rx) = channel();

        for file in files.iter() {
            let tx = tx.clone();
            let file = file.clone();

            // Spawn producer thread
            pool.execute(move || {
                let path = Path::new(&*file);
                let _ = tx.send(match fs::metadata(&path) {
                    Ok(metadata) => {
                        if !metadata.is_dir() {
                            StatResult::File(File::with_metadata(metadata, &path, None, false))
                        }
                        else if is_tree {
                            StatResult::File(File::with_metadata(metadata, &path, None, true))
                        }
                        else {
                            StatResult::Dir(path.to_path_buf())
                        }
                    }
                    Err(e) => {
                        println!("{}: {}", file, e);
                        StatResult::Error
                    }
                });
            });
        }

        // Spawn consumer thread
        for result in rx.iter().take(total_files) {
            match result {
                StatResult::File(file)  => self.files.push(file),
                StatResult::Dir(path)   => self.dirs.push(path),
                StatResult::Error       => ()
            }
            self.count += 1;
        }
    }

    fn print_files(&self) {
        if !self.files.is_empty() {
            self.print(None, &self.files[..]);
        }
    }

    fn print_dirs(&mut self) {
        let mut first = self.files.is_empty();

        // Directories are put on a stack rather than just being iterated through,
        // as the vector can change as more directories are added.
        loop {
            let dir_path = match self.dirs.pop() {
                None => break,
                Some(f) => f,
            };

            // Put a gap between directories, or between the list of files and the
            // first directory.
            if first {
                first = false;
            }
            else {
                print!("\n");
            }

            match Dir::readdir(&dir_path) {
                Ok(ref dir) => {
                    let mut files = dir.files(false);
                    self.options.transform_files(&mut files);

                    // When recursing, add any directories to the dirs stack
                    // backwards: the *last* element of the stack is used each
                    // time, so by inserting them backwards, they get displayed in
                    // the correct sort order.
                    if let Some(recurse_opts) = self.options.dir_action.recurse_options() {
                        let depth = dir_path.components().filter(|&c| c != Component::CurDir).count() + 1;
                        if !recurse_opts.tree && !recurse_opts.is_too_deep(depth) {
                            for dir in files.iter().filter(|f| f.is_directory()).rev() {
                                self.dirs.push(dir.path.clone());
                            }
                        }
                    }

                    if self.count > 1 {
                        println!("{}:", dir_path.display());
                    }
                    self.count += 1;

                    self.print(Some(dir), &files[..]);
                }
                Err(e) => {
                    println!("{}: {}", dir_path.display(), e);
                    return;
                }
            };
        }
    }

    fn print(&self, dir: Option<&Dir>, files: &[File]) {
        match self.options.view {
            View::Grid(g)     => g.view(files),
            View::Details(d)  => d.view(dir, files),
            View::Lines(l)    => l.view(files),
        }
    }
}

#[cfg(not(test))]
fn main() {
    let args: Vec<String> = env::args().collect();

    match Options::getopts(args.tail()) {
        Ok((options, paths)) => {
            let mut exa = Exa::new(options);
            exa.load(&paths);
            exa.print_files();
            exa.print_dirs();
        },
        Err(e) => {
            println!("{}", e);
            env::set_exit_status(e.error_code());
        },
    };
}
<|endoftext|>


<commit_before>//! This is part 1 of Ruslan Spivak's Let’s Build A Simple Interpreter series.

#[derive(Debug)]
enum Token {
    Integer(i32),
    Star,
    Slash,
    EOF
}

#[derive(Debug)]
struct Lexer {
    text: Vec<char>,
    position: usize,
    current_char: Option<char>
}

impl Lexer {
    fn new(source: String) -> Lexer {
        let s = source.chars().collect::<Vec<char>>();
        let c = if s.len() > 0 { Some(s[0]) } else { None };
        Lexer {
            text: s,
            position: 0,
            current_char: c
        }
    }

    fn done(&self) -> bool {
        self.position + 1 > self.text.len()
    }

    fn advance(&mut self) {
        self.position += 1;
        if self.position > self.text.len() - 1 {
            self.current_char = None;
        } else {
            self.current_char = Some(self.text[self.position]);
        }
    }

    fn skip_whitespace(&mut self) {
        while !self.done() && self.current_char.unwrap().is_whitespace() {
            self.advance();
        }
    }

    fn scan_integer(&mut self) -> Token {
        let mut integer = String::new();
        while !self.done() && self.current_char.unwrap().is_digit(10) {
            integer.push(self.current_char.unwrap());
            self.advance();
        }
        Token::Integer(integer.parse::<i32>().unwrap())
    }

    fn get_next_token(&mut self) -> Token {
        self.skip_whitespace();
        if let Some(c) = self.current_char {
            match c {
                '0' ... '9' => self.scan_integer(),
                '*' => { self.advance(); Token::Star },
                '/' => { self.advance(); Token::Slash },
                 c  => panic!("Error: unexpected character: {}.", c),
            }
        } else {
            Token::EOF
        }
    }
}

#[derive(Debug)]
struct Interpreter {
    lexer: Lexer,
    current_token: Token,
}

impl Interpreter {
    fn new(source: String) -> Interpreter {
        let mut l = Lexer::new(source);
        let t = l.get_next_token();
        Interpreter {
            lexer: l,
            current_token: t,
        }
    }

    fn eat(&mut self) {
        self.current_token = self.lexer.get_next_token();
    }

    fn parse_factor(&mut self) -> i32 {
        match self.current_token {
            Token::Integer(i) => { self.eat(); i },
            ref t => panic!("Error: expected an integer and found a '{:?}'", t),
        }
    }

    fn parse_expression(&mut self) -> i32 {
        let mut result = self.parse_factor();

        loop {
            match self.current_token {
                Token::Star  => { self.eat(); result *= self.parse_factor() },
                Token::Slash => { self.eat(); result /= self.parse_factor() },
                _ => break,
            }
        }

        result
    }
}

macro_rules! prompt(
    ($($arg:tt)*) => { {
        print!($($arg)*);
        stdout().flush().expect("Could not flush stdout");
    } }
);

fn main() {
    use std::io::{BufRead, stdin, stdout, Write};

    prompt!("calc> ");
    let stdin = stdin();
    for line in stdin.lock().lines() {
        let mut interpreter = Interpreter::new(line.unwrap());
        let result = interpreter.parse_expression();
        println!("{}", result);
        prompt!("calc> ");
    }
}
<commit_msg>Finished Part 5.<commit_after>
#[derive(Debug, PartialEq)]
enum Token {
    Integer(i32),
    Star, Slash,
    Plus, Minus
}

#[derive(Debug)]
struct Lexer {
    source: Vec<char>,
    position: usize,
}

impl Lexer {
    fn new(source: String) -> Lexer {
        Lexer {
            source: source.chars().collect(),
            position: 0,
        }
    }

    fn done(&self) -> bool {
        self.position >= self.source.len()
    }

    fn advance(&mut self) {
        self.position += 1;
    }

    fn string(&self, start: usize, end: usize) -> String {
        (&self.source[start..end]).to_vec().into_iter().collect()
    }

    fn next_char_is<P>(&self, pred: P) -> bool where P: Fn(char) -> bool {
        if self.position + 1 < self.source.len() {
            pred(self.source[self.position + 1])
        } else {
            false
        }
    }

    fn char(&mut self) -> Option<char> {
        if !self.done() {
            Some(self.source[self.position])
        } else {
            None
        }
    }

    fn skip_whitespace(&mut self) {
        while !self.done() && self.source[self.position].is_whitespace() {
            self.advance();
        }
    }

    fn scan_integer(&mut self) -> Token {
        let start = self.position;
        while self.next_char_is(|c| c.is_digit(10)) {
            self.advance();
        }
        Token::Integer(self.string(start, self.position + 1).parse::<i32>().unwrap())
    }

    fn get_next_token(&mut self) -> Option<Token> {
        self.skip_whitespace();
        if self.done() { return None; }
        let token = match self.char().unwrap() {
            '0' ... '9' => self.scan_integer(),
            '+'         => Token::Plus,
            '-'         => Token::Minus,
            '*'         => Token::Star,
            '/'         => Token::Slash,
             c          => panic!("Error: unexpected character: '{}'.", c),
        };
        self.advance();
        Some(token)
    }
}

#[derive(Debug)]
struct Interpreter {
    lexer: Lexer,
    current_token: Option<Token>,
}

impl Interpreter {
    fn new(source: String) -> Interpreter {
        let mut l = Lexer::new(source);
        let t = l.get_next_token();
        Interpreter {
            lexer: l,
            current_token: t,
        }
    }

    fn advance(&mut self) {
        self.current_token = self.lexer.get_next_token();
    }

    fn factor(&mut self) -> i32 {
        let result = match self.current_token {
            Some(Token::Integer(i)) => i,
            ref t => panic!("Error: expected an integer and found a '{:?}'.", t),
        };
        self.advance();
        result
    }

    fn term(&mut self) -> i32 {
        let mut result = self.factor();

        loop {
            match self.current_token {
                Some(Token::Star)  => { self.advance(); result *= self.factor(); },
                Some(Token::Slash) => { self.advance(); result /= self.factor(); },
                _ => break,
            }
        }
        result
    }

    fn expression(&mut self) -> i32 {
        let mut result = self.term();

        loop {
            match self.current_token {
                Some(Token::Plus)  => { self.advance(); result += self.term() },
                Some(Token::Minus) => { self.advance(); result -= self.term() },
                _ => break,
            }
        }
        result
    }
}

macro_rules! prompt(
    ($($arg:tt)*) => { {
        print!($($arg)*);
        stdout().flush().expect("Could not flush stdout");
    } }
);

fn main() {
    use std::io::{BufRead, stdin, stdout, Write};

    prompt!("calc> ");
    let stdin = stdin();
    for line in stdin.lock().lines() {
        let mut interpreter = Interpreter::new(line.unwrap());
        let result = interpreter.expression();
        println!("{}", result);
        prompt!("calc> ");
    }
}
<|endoftext|>


<commit_before>#![feature(process)]

extern crate docopt;

#[macro_use]
extern crate standard_error;

use docopt::Docopt;
use standard_error::StandardResult as Result;
use std::rc::Rc;

mod git;
mod author;
mod config;

use author::Author;
use config::Config;

const CONFIG_PATH: &'static str = "./partners.cfg";
const CFG: git::Config = git::Config::File(CONFIG_PATH);

// Write the Docopt usage string.
static USAGE: &'static str = "
Usage: partners current
       partners list
       partners add --nick=<nick> --name=<name> [--email=<email>]
       partners add
       partners set <nick>
       partners (--help | --version)

Options:
    -h, --help      Show help
    --version       Show version information
";

fn print_author_list(list: &[Author]) {
    for item in list.iter() {
        println!("{}:", item.nick);
        println!("  Name:  {}", item.name);
        println!("  Email: {}", item.get_email());
    }
}

fn parse_author_line(config: &Rc<Config>, line: &str) -> Result<Author> {
    let mut parts = line.splitn(1, ' ');
    let nick = parts.next().unwrap().split('.').nth(1).unwrap().to_string();
    let name = parts.next().unwrap().to_string();
    let email = CFG.get(&format!("author.{}.email", nick)).ok();

    Ok(Author { config: config.clone(), nick: nick, name: name, email: email })
}

fn get_authors(config: &Rc<Config>) -> Result<Vec<Author>> {
    let lines = try!(CFG.list("author.\\w+.name"));
    lines.iter().map(|line| parse_author_line(config, &line)).collect()
}

fn write_author(author: &Author) -> Result<()> {
    try!(CFG.set(&format!("author.{}.name", author.nick), &author.name));
    if let Some(ref email) = author.email {
        try!(CFG.set(&format!("author.{}.email", author.nick), &email));
    }
    Ok(())
}

fn print_current() {
    if let Ok(nick) = git::Config::None.get("partners.current") {
        println!("Nick:  {}", nick);
    }
    if let Ok(name) = git::Config::None.get("user.name") {
        println!("Name:  {}", name);
    }
    if let Ok(email) = git::Config::None.get("user.email") {
        println!("Email: {}", email);
    }
}

fn main() {
    let docopt = Docopt::new(USAGE).unwrap().help(true).version(Some(env!("CARGO_PKG_VERSION").to_string()));
    let args = docopt.parse().unwrap_or_else(|e| e.exit());

    let config = Rc::new(Config {
        domain: CFG.get("config.domain").unwrap_or_else(|_| "example.com".to_string()),
        prefix: CFG.get("config.prefix").unwrap_or_else(|_| "dev".to_string()),
        separator: CFG.get("config.separator").unwrap_or_else(|_| "+".to_string()),
    });

    if args.get_bool("list") {
        let authors = get_authors(&config).unwrap();
        print_author_list(&authors);
    } else if args.get_bool("add") {
        let email = args.get_str("--email");
        let nick = args.get_str("--nick");
        let name = args.get_str("--name");

        let email = if email.is_empty() { None } else { Some(email.to_string()) };

        let author = Author { config: config.clone(), nick: nick.to_string(), name: name.to_string(), email: email };
        write_author(&author).unwrap();
    } else if args.get_bool("current") {
        print_current();
    } else if args.get_bool("set") {
        let nick = args.get_str("<nick>");

        match get_authors(&config).unwrap().iter().find(|a| a.nick == nick) {
            Some(author) => {
                git::Config::Global.set("partners.current", &author.nick).unwrap();
                git::Config::Global.set("user.name", &author.name).unwrap();
                git::Config::Global.set("user.email", &author.get_email()).unwrap();
                print_current();
            }
            None => {
                println!("no such author");
            }
        }
    }
}
<commit_msg>Use deref coercions<commit_after>#![feature(process)]

extern crate docopt;

#[macro_use]
extern crate standard_error;

use docopt::Docopt;
use standard_error::StandardResult as Result;
use std::rc::Rc;

mod git;
mod author;
mod config;

use author::Author;
use config::Config;

const CONFIG_PATH: &'static str = "./partners.cfg";
const CFG: git::Config = git::Config::File(CONFIG_PATH);

// Write the Docopt usage string.
static USAGE: &'static str = "
Usage: partners current
       partners list
       partners add --nick=<nick> --name=<name> [--email=<email>]
       partners add
       partners set <nick>
       partners (--help | --version)

Options:
    -h, --help      Show help
    --version       Show version information
";

fn print_author_list(list: &[Author]) {
    for item in list.iter() {
        println!("{}:", item.nick);
        println!("  Name:  {}", item.name);
        println!("  Email: {}", item.get_email());
    }
}

fn parse_author_line(config: &Rc<Config>, line: &str) -> Result<Author> {
    let mut parts = line.splitn(1, ' ');
    let nick = parts.next().unwrap().split('.').nth(1).unwrap().to_string();
    let name = parts.next().unwrap().to_string();
    let email = CFG.get(&format!("author.{}.email", nick)).ok();

    Ok(Author { config: config.clone(), nick: nick, name: name, email: email })
}

fn get_authors(config: &Rc<Config>) -> Result<Vec<Author>> {
    let lines = try!(CFG.list("author.\\w+.name"));
    lines.iter().map(|line| parse_author_line(config, line)).collect()
}

fn write_author(author: &Author) -> Result<()> {
    try!(CFG.set(&format!("author.{}.name", author.nick), &author.name));
    if let Some(ref email) = author.email {
        try!(CFG.set(&format!("author.{}.email", author.nick), email));
    }
    Ok(())
}

fn print_current() {
    if let Ok(nick) = git::Config::None.get("partners.current") {
        println!("Nick:  {}", nick);
    }
    if let Ok(name) = git::Config::None.get("user.name") {
        println!("Name:  {}", name);
    }
    if let Ok(email) = git::Config::None.get("user.email") {
        println!("Email: {}", email);
    }
}

fn main() {
    let docopt = Docopt::new(USAGE).unwrap().help(true).version(Some(env!("CARGO_PKG_VERSION").to_string()));
    let args = docopt.parse().unwrap_or_else(|e| e.exit());

    let ref config = Rc::new(Config {
        domain: CFG.get("config.domain").unwrap_or_else(|_| "example.com".to_string()),
        prefix: CFG.get("config.prefix").unwrap_or_else(|_| "dev".to_string()),
        separator: CFG.get("config.separator").unwrap_or_else(|_| "+".to_string()),
    });

    if args.get_bool("list") {
        let authors = get_authors(config).unwrap();
        print_author_list(&authors);
    } else if args.get_bool("add") {
        let email = args.get_str("--email");
        let nick = args.get_str("--nick");
        let name = args.get_str("--name");

        let email = if email.is_empty() { None } else { Some(email.to_string()) };

        let author = Author { config: config.clone(), nick: nick.to_string(), name: name.to_string(), email: email };
        write_author(&author).unwrap();
    } else if args.get_bool("current") {
        print_current();
    } else if args.get_bool("set") {
        let nick = args.get_str("<nick>");

        match get_authors(config).unwrap().iter().find(|a| a.nick == nick) {
            Some(author) => {
                git::Config::Global.set("partners.current", &author.nick).unwrap();
                git::Config::Global.set("user.name", &author.name).unwrap();
                git::Config::Global.set("user.email", &author.get_email()).unwrap();
                print_current();
            }
            None => {
                println!("no such author");
            }
        }
    }
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![plugin(clippy)]

extern crate env_logger;
extern crate mio;
#[macro_use] extern crate mioco;
extern crate trust_dns;
extern crate rand;
#[macro_use] extern crate quick_error;
#[macro_use] extern crate log;
extern crate byteorder;
extern crate itertools;

mod utils;
mod transport;
mod cache;
mod nscache;
mod query;
mod serve;
mod resolver;

use std::net::{SocketAddr, SocketAddrV4};
use std::sync::Arc;

use mioco::mio::Ipv4Addr;

use resolver::Resolver;
use serve::{serve_tcp, serve_udp};

fn mioco_config_start<F, T>(f: F) -> std::thread::Result<T>
    where F: FnOnce() -> T,
          F: Send + 'static,
          T: Send + 'static
{
    let mut config = mioco::Config::new();
    config.set_catch_panics(false);
    mioco::Mioco::new_configured(config).start(f)
}
fn main() {
    env_logger::init().expect("What the ...?");
    println!("Hello, world!");

    mioco_config_start(move || {
        let ip = Ipv4Addr::new(0, 0, 0, 0);
        let port = 5354;
        let addr = SocketAddr::V4(SocketAddrV4::new(ip, port));

        let resolver = Arc::new(Resolver::default());
        serve_tcp(&addr, resolver.clone()).expect("Failed to initialize TCP listener");
        serve_udp(&addr, resolver).expect("Failed to initialize UDP listener");
    }).expect("Unexpected error from mioco::start");
}
<commit_msg>Startup message<commit_after>#![feature(plugin)]
#![plugin(clippy)]

extern crate env_logger;
extern crate mio;
#[macro_use] extern crate mioco;
extern crate trust_dns;
extern crate rand;
#[macro_use] extern crate quick_error;
#[macro_use] extern crate log;
extern crate byteorder;
extern crate itertools;

mod utils;
mod transport;
mod cache;
mod nscache;
mod query;
mod serve;
mod resolver;

use std::net::{SocketAddr, SocketAddrV4};
use std::sync::Arc;

use mioco::mio::Ipv4Addr;

use resolver::Resolver;
use serve::{serve_tcp, serve_udp};

fn mioco_config_start<F, T>(f: F) -> std::thread::Result<T>
    where F: FnOnce() -> T,
          F: Send + 'static,
          T: Send + 'static
{
    let mut config = mioco::Config::new();
    config.set_catch_panics(false);
    mioco::Mioco::new_configured(config).start(f)
}
fn main() {
    env_logger::init().expect("What the ...?");

    mioco_config_start(move || {
        let ip = Ipv4Addr::new(0, 0, 0, 0);
        let port = 5354;
        let addr = SocketAddr::V4(SocketAddrV4::new(ip, port));
        info!("Listening on {}:{}", ip, port);

        let resolver = Arc::new(Resolver::default());
        serve_tcp(&addr, resolver.clone()).expect("Failed to initialize TCP listener");
        serve_udp(&addr, resolver).expect("Failed to initialize UDP listener");
    }).expect("Unexpected error from mioco::start");
}
<|endoftext|>


<commit_before>//
//  SOS: the Stupid Operating System
//  by Eliza Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2015-2016 Eliza Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
//! # SOS kernel
//! This crate contains the kernel for SOS, the Stupid Operating System.
//!
//! # SOS: the Stupid Operating System
//! SOS is a simple, tiny toy OS implemented in Rust. It targets the x86,
//! x86_64, and ARM v7 CPU architectures.
//!
//! I'm writing this mostly for fun, to learn more about OS design and kernel
//! hacking, so don't expect anything new or exciting out of this project.
//!
//! SOS is copyright 2015-2016 Eliza Weisman, and is released under the terms
//! of the MIT license.

#![crate_name = "sos_kernel"]

#![doc(html_root_url = "https://hawkw.github.io/sos-kernel/")]

#![feature( lang_items, asm, naked_functions )]
#![feature( linkage )]
#![feature( const_fn
          , slice_patterns
          , associated_consts
          , type_ascription
          , custom_derive )]
#![feature(collections)]

#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]

#![no_std]
#![cfg_attr(not(test), no_main)]

// -- non-SOS dependencies --------------------------------------------------
#[macro_use] extern crate lazy_static;
#[macro_use] extern crate bitflags;
#[macro_use] extern crate log;

extern crate collections;
extern crate rlibc;
extern crate spin;

// -- SOS dependencies ------------------------------------------------------
#[macro_use] extern crate vga;
#[macro_use] extern crate cpu;

extern crate util;
extern crate alloc;
extern crate memory;
extern crate elf;
extern crate paging;
extern crate params;

#[macro_use] pub mod io;

pub mod heap;
pub mod arch;
pub mod logger;

use params::InitParams;

#[macro_use]
macro_rules! init_log {
    (f$dots:expr, $task:expr, $msg:expr) => (
        println!( "{task:<40}{res:>38}\n{msg:>.width$}"
                , task = format!("{:>.width$}", $task, width = $dots)
                , res = "[ FAIL ]"
                , msg = $msg
                , width = $dots + 1
                )
    );
    (fail: $dots:expr, $task:expr) => (
            println!( "{task:<40}{res:>38}"
                    , task = format!("{:>.width$}", $task, width = $dots)
                    , res = "[ FAIL ]"
                    )
    );
    (okay: $dots:expr, $task:expr, $msg:expr) => (
        println!( "{task:<40}{res:>38}\n{msg:>.width$}"
                , task = format!("{:>.width$}", $task, width = $dots)
                , res = "[ OKAY ]"
                , msg = $msg
                , width = $dots + 1
                )
    );
    (okay: $dots:expr, $task:expr) => (
            println!( "{task:<40}{res:>38}"
                    , task = format!("{:>.width$}", $task, width = $dots)
                    , res = "[ OKAY ]"
                    )
    );
}

/// SOS version number
pub const VERSION_STRING: &'static str
    = concat!("Stupid Operating System v", env!("CARGO_PKG_VERSION"));

/// Kernel main loop
pub fn kernel_main() -> ! {
    let mut a_vec = collections::vec::Vec::<usize>::new();
    info!(target: "test", "Created a vector in kernel space! {:?}", a_vec);
    a_vec.push(1);
    info!(target: "test", "pushed to vec: {:?}", a_vec);
    a_vec.push(2);
    info!(target: "test", "pushed to vec: {:?}", a_vec);

    // let mut frame_allocator = frame_alloc::BuddyFrameAllocator::new();
    // paging::test_paging(&mut frame_allocator);

    loop { }
}

/// Kernel initialization function called into by architecture-specific init
///
/// Our initialization process essentially looks like this:
///
/// ```text
/// +-------------+     +-----------+     +-------------------------------+
/// | bootloader  |     | start.asm |     | rust init functions           |
/// | (multiboot) | --> |           | -----> arch_init() -> kernel_init() |
/// +-------------+     +-----------+     +----------------------|--------+
///                                                              V
///                                                         kernel_main()
/// ```
pub fn kernel_init(params: InitParams) {
    kinfoln!("Hello from the kernel!");
    // -- initialize interrupts ----------------------------------------------
    kinfoln!(dots: " . ", "Initializing interrupts:");
    unsafe {
        arch::interrupts::initialize();
    };
    kinfoln!(dots: " . ", target: "Enabling interrupts", "[ OKAY ]");

    // -- initialize the heap ------------------------------------------------
    if let Ok(_) =  unsafe { heap::initialize(&params) } {
        kinfoln!( dots: " . ", target: "Intializing heap"
                , "[ OKAY ]"
                );
        kinfoln!( dots: " . . "
                , "Heap begins at {:#x} and ends at {:#x}"
                , params.heap_base, params.heap_top);
    } else {
        kinfoln!( dots: " . ", target: "Intializing heap"
                , "[ FAIL ]"
                );
    }

    // -- remap the kernel ----------------------------------------------------
    kinfoln!(dots: " . ", "Remapping the kernel:");

    let frame_allocator = alloc::buddy::BuddyFrameAllocator::new();
    ::paging::kernel_remap(&params, &frame_allocator);

    kinfoln!( dots: " . ", target: "Remapping the kernel", "[ OKAY ]");

    println!("\n{} {}-bit\n", VERSION_STRING, arch::ARCH_BITS);

    // -- call into kernel main loop ------------------------------------------
    // (currently, this does nothing)
    kernel_main()
}

/// This fake `main` function exists only to placate `cargo test`.
#[cfg(test)]
fn main() {

}
<commit_msg>[kernel] made bad ASCII graphic different (better???)<commit_after>//
//  SOS: the Stupid Operating System
//  by Eliza Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2015-2016 Eliza Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
//! # SOS kernel
//! This crate contains the kernel for SOS, the Stupid Operating System.
//!
//! # SOS: the Stupid Operating System
//! SOS is a simple, tiny toy OS implemented in Rust. It targets the x86,
//! x86_64, and ARM v7 CPU architectures.
//!
//! I'm writing this mostly for fun, to learn more about OS design and kernel
//! hacking, so don't expect anything new or exciting out of this project.
//!
//! SOS is copyright 2015-2016 Eliza Weisman, and is released under the terms
//! of the MIT license.

#![crate_name = "sos_kernel"]

#![doc(html_root_url = "https://hawkw.github.io/sos-kernel/")]

#![feature( lang_items, asm, naked_functions )]
#![feature( linkage )]
#![feature( const_fn
          , slice_patterns
          , associated_consts
          , type_ascription
          , custom_derive )]
#![feature(collections)]

#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]

#![no_std]
#![cfg_attr(not(test), no_main)]

// -- non-SOS dependencies --------------------------------------------------
#[macro_use] extern crate lazy_static;
#[macro_use] extern crate bitflags;
#[macro_use] extern crate log;

extern crate collections;
extern crate rlibc;
extern crate spin;

// -- SOS dependencies ------------------------------------------------------
#[macro_use] extern crate vga;
#[macro_use] extern crate cpu;

extern crate util;
extern crate alloc;
extern crate memory;
extern crate elf;
extern crate paging;
extern crate params;

#[macro_use] pub mod io;

pub mod heap;
pub mod arch;
pub mod logger;

use params::InitParams;

#[macro_use]
macro_rules! init_log {
    (f$dots:expr, $task:expr, $msg:expr) => (
        println!( "{task:<40}{res:>38}\n{msg:>.width$}"
                , task = format!("{:>.width$}", $task, width = $dots)
                , res = "[ FAIL ]"
                , msg = $msg
                , width = $dots + 1
                )
    );
    (fail: $dots:expr, $task:expr) => (
            println!( "{task:<40}{res:>38}"
                    , task = format!("{:>.width$}", $task, width = $dots)
                    , res = "[ FAIL ]"
                    )
    );
    (okay: $dots:expr, $task:expr, $msg:expr) => (
        println!( "{task:<40}{res:>38}\n{msg:>.width$}"
                , task = format!("{:>.width$}", $task, width = $dots)
                , res = "[ OKAY ]"
                , msg = $msg
                , width = $dots + 1
                )
    );
    (okay: $dots:expr, $task:expr) => (
            println!( "{task:<40}{res:>38}"
                    , task = format!("{:>.width$}", $task, width = $dots)
                    , res = "[ OKAY ]"
                    )
    );
}

/// SOS version number
pub const VERSION_STRING: &'static str
    = concat!("Stupid Operating System v", env!("CARGO_PKG_VERSION"));

/// Kernel main loop
pub fn kernel_main() -> ! {
    let mut a_vec = collections::vec::Vec::<usize>::new();
    info!(target: "test", "Created a vector in kernel space! {:?}", a_vec);
    a_vec.push(1);
    info!(target: "test", "pushed to vec: {:?}", a_vec);
    a_vec.push(2);
    info!(target: "test", "pushed to vec: {:?}", a_vec);

    // let mut frame_allocator = frame_alloc::BuddyFrameAllocator::new();
    // paging::test_paging(&mut frame_allocator);

    loop { }
}

/// Kernel initialization function called into by architecture-specific init
///
/// Our initialization process essentially looks like this:
///
/// ```text
/// +------------+ +----------+ +----------------------------------------------+
/// | bootloader | | assembly | | rust                                         |
/// | (multiboot) -> start.asm -> arch_init() -> kernel_init() -> kernel_main()|
/// +------------+ +----------+ +----------------------------------------------+
/// ```
pub fn kernel_init(params: InitParams) {
    kinfoln!("Hello from the kernel!");
    // -- initialize interrupts ----------------------------------------------
    kinfoln!(dots: " . ", "Initializing interrupts:");
    unsafe {
        arch::interrupts::initialize();
    };
    kinfoln!(dots: " . ", target: "Enabling interrupts", "[ OKAY ]");

    // -- initialize the heap ------------------------------------------------
    if let Ok(_) =  unsafe { heap::initialize(&params) } {
        kinfoln!( dots: " . ", target: "Intializing heap"
                , "[ OKAY ]"
                );
        kinfoln!( dots: " . . "
                , "Heap begins at {:#x} and ends at {:#x}"
                , params.heap_base, params.heap_top);
    } else {
        kinfoln!( dots: " . ", target: "Intializing heap"
                , "[ FAIL ]"
                );
    }

    // -- remap the kernel ----------------------------------------------------
    kinfoln!(dots: " . ", "Remapping the kernel:");

    let frame_allocator = alloc::buddy::BuddyFrameAllocator::new();
    ::paging::kernel_remap(&params, &frame_allocator);

    kinfoln!( dots: " . ", target: "Remapping the kernel", "[ OKAY ]");

    println!("\n{} {}-bit\n", VERSION_STRING, arch::ARCH_BITS);

    // -- call into kernel main loop ------------------------------------------
    // (currently, this does nothing)
    kernel_main()
}

/// This fake `main` function exists only to placate `cargo test`.
#[cfg(test)]
fn main() {

}
<|endoftext|>