<commit_before>extern crate hkg;
extern crate termion;
extern crate rustc_serialize;
extern crate kuchiki;
extern crate chrono;
extern crate hyper;
extern crate cancellation;
extern crate time;
extern crate url;

use std::io::{stdout, stdin, Write};
use std::thread;
use std::sync::mpsc::channel;
use std::sync::mpsc::Sender;
use cancellation::{CancellationToken, CancellationTokenSource, OperationCanceled};
use kuchiki::traits::*;
use rustc_serialize::json;
use termion::input::TermRead;
use termion::raw::IntoRawMode;
use termion::event::Key;
use hkg::status::*;
use hkg::model::IconItem;
use hkg::model::ListTopicItem;
use hkg::state_manager::*;
use hkg::screen_manager::*;
use hkg::resources::common::*;
use hkg::caches::file_cache::*;
use hkg::net::*;
use hkg::net::web_resource::*;

fn main() {

    // Initialize
    let stdout = stdout();
    let mut stdout = stdout.lock().into_raw_mode().unwrap();

    // Clear the screen.
    hkg::screen::common::clear_screen();

    let mut builder = hkg::builder::Builder::new();

    let mut state_manager = StateManager::new();
    let mut screen_manager = ScreenManager::new();

    let icon_manifest_string = hkg::utility::readfile(String::from("data/icon.manifest.json"));
    let icon_collection: Box<Vec<IconItem>> = Box::new(json::decode(&icon_manifest_string).unwrap());

    // initialize empty page
    let mut list_topic_items: Vec<ListTopicItem> = vec![];
    let mut show_item = builder.default_show_item();

    let mut status_bar = hkg::screen::status_bar::StatusBar::new();
    let mut index = hkg::screen::index::Index::new();
    let mut show = hkg::screen::show::Show::new(icon_collection);

    let (tx_req, rx_req) = channel::<ChannelItem>();
    let (tx_res, rx_res) = channel::<ChannelItem>();

    // web client
    thread::spawn(move || {
        let mut wr = WebResource::new();
        let mut fc = Box::new(FileCache::new());
        let ct = CancellationTokenSource::new();
        ct.cancel_after(std::time::Duration::new(10, 0));
        loop {
            match rx_req.recv() {
                Ok(item) => {

                    let th = thread::current();
                    ct.run(|| {
                               th.unpark();
                           },
                           || {
                                match item.extra.clone() {
                                    ChannelItemType::Index(_) => {
                                        let mut index_resource = hkg::resources::index_resource::IndexResource::new(&mut wr, &ct, &mut fc);
                                        tx_res.send(index_resource.fetch(&item)).unwrap();
                                    },
                                    ChannelItemType::Show(_) => {
                                        let mut show_resource = hkg::resources::show_resource::ShowResource::new(&mut wr, &ct, &mut fc);
                                        tx_res.send(show_resource.fetch(&item)).unwrap();
                                    },
                                    ChannelItemType::Image(_) => {
                                    }
                                }
                           });

                    if ct.is_canceled() {
                        thread::park_timeout(std::time::Duration::new(0, 250));
                        // Err(OperationCanceled)
                    } else {
                        // Ok(())
                    }
                }
                Err(_) => {}
            }
        }
    });

    // topics request
    let status_message = list_page(&mut state_manager, &tx_req);
    status_bar.append(&screen_manager, &status_message);

    loop {

        match rx_res.try_recv() {
            Ok(item) => {
                match item.extra {
                    ChannelItemType::Show(extra) => {
                        let document = kuchiki::parse_html().from_utf8().one(item.result.as_bytes());

                        let posturl = get_posturl(&extra.postid, extra.page);
                        show_item = builder.show_item(&document, &posturl);

                        status_bar.append(&screen_manager, &format!("[{}-{}:ROK][{}]",
                                 show_item.url_query.message,
                                 show_item.page,
                                 state_manager.isWebRequest()));

                        show.resetY();
                        hkg::screen::common::clear_screen();
                        state_manager.updateState(Status::Show); //state = Status::Show;
                        state_manager.setWebRequest(false); // is_web_requesting = false;
                    },
                    ChannelItemType::Index(_) => {
                        let document = kuchiki::parse_html().from_utf8().one(item.result.as_bytes());

                        list_topic_items = builder.list_topic_items(&document);

                        status_bar.append(&screen_manager,
                                               &format!("[TOPICS:ROK]"));

                        hkg::screen::common::clear_screen();

                        state_manager.updateState(Status::List); // state = Status::List;
                        state_manager.setWebRequest(false); // is_web_requesting = false;

                    },
                    ChannelItemType::Image(extra) => {
                    }
                }
            }
            Err(_) => {}
        }

        match state_manager.getState() {
            Status::Startup => {

            },
            Status::List => {
                index.print(&mut stdout, &list_topic_items);
            }
            Status::Show => {
                show.print(&mut stdout, &show_item);
            }
        }

        status_bar.print(&screen_manager);

        stdout.flush().unwrap();

        if !state_manager.isWebRequest() {

            let stdin = stdin();

            for c in stdin.keys() {

                if screen_manager.isWidthChanged() {
                    hkg::screen::common::clear_screen();
                }

                match state_manager.getState() {
                    Status::Startup => {},
                    Status::List => {
                        match c.unwrap() {
                            Key::Char('q') => {
                                hkg::screen::common::reset_screen();
                                return
                            },
                            Key::Char('\n') => {
                                status_bar.append(&screen_manager, "ENTER");
                                let i = index.get_selected_topic();
                                if i > 0 {
                                    let topic_item = &list_topic_items[i - 1];
                                    let postid = &topic_item.title.url_query.message;
                                    let page = 1;
                                    let status_message = show_page(&postid, page, &mut state_manager, &tx_req);

                                    status_bar.append(&screen_manager,
                                                           &get_show_page_status_message(postid, page, &status_message));
                                }
                                break
                            },
                            Key::PageUp => {
                                status_bar.append(&screen_manager, "↑");
                                let tmp = index.get_selected_topic();
                                status_bar.append(&screen_manager, &format!("{}", tmp));

                                if tmp > 1 {
                                    index.select_topic(tmp - 1);
                                }
                                break
                            },
                            Key::Up => {
                                status_bar.append(&screen_manager, "↑");
                                let tmp = index.get_selected_topic();
                                status_bar.append(&screen_manager, &format!("{}", tmp));

                                if tmp > 1 {
                                    index.select_topic(tmp - 1);
                                }
                                break
                            },
                            Key::Down => {
                                status_bar.append(&screen_manager, "↓");
                                let tmp = index.get_selected_topic();
                                status_bar.append(&screen_manager, &format!("{}", tmp));

                                if tmp < index.body_height() {
                                    index.select_topic(tmp + 1);
                                }
                                break
                            },
                            _ => {},
                        }
                    },
                    Status::Show => {
                            match c.unwrap() {
                                Key::Char('q') => {
                                    hkg::screen::common::reset_screen(); // print!("{}{}{}", termion::clear::All, style::Reset, termion::cursor::Show);
                                    return
                                },
                                Key::Left => {
                                    status_bar.append(&screen_manager, &format!("←"));
                                    if show_item.page > 1 {
                                        let postid = &show_item.url_query.message;
                                        let page = &show_item.page - 1;
                                        let status_message = show_page(&postid, page, &mut state_manager, &tx_req);

                                        status_bar.append(&screen_manager,
                                                               &get_show_page_status_message(postid, page, &status_message));
                                    }
                                    break
                                }
                                Key::Right => {
                                    status_bar.append(&screen_manager, &format!("→"));
                                    if show_item.max_page > show_item.page {
                                        let postid = &show_item.url_query.message;
                                        let page = &show_item.page + 1;
                                        let status_message = show_page(&postid, page, &mut state_manager, &tx_req);

                                        status_bar.append(&screen_manager,
                                                               &get_show_page_status_message(postid, page, &status_message));
                                    }
                                    break
                                },
                                Key::PageUp => {
                                    status_bar.append(&screen_manager, "↑");
                                    let bh = show.body_height();
                                    if show.scrollUp(bh) {
                                    hkg::screen::common::clear_screen();
                                    }
                                    break
                                },
                                Key::PageDown => {
                                    status_bar.append(&screen_manager, "↓");
                                    let bh = show.body_height();
                                    if show.scrollDown(bh) {
                                        hkg::screen::common::clear_screen();
                                    }
                                    break
                                },
                                Key::Up => {
                                    status_bar.append(&screen_manager, "↑");
                                    if show.scrollUp(2) {
                                        hkg::screen::common::clear_screen();
                                    }
                                    break
                                },
                                Key::Down => {
                                    status_bar.append(&screen_manager, "↓");
                                    if show.scrollDown(2) {
                                        hkg::screen::common::clear_screen();
                                    }
                                    break
                                },
                                Key::Backspace => {
                                    status_bar.append(&screen_manager, "B");
                                    state_manager.updateState(Status::List); // state = Status::List;
                                    hkg::screen::common::clear_screen();
                                    break
                                },
                                _ => {},
                            }
                        }
                }

            }
        }

    }
}
fn get_posturl(postid: &String, page: usize) -> String {
    let base_url = "http://forum1.hkgolden.com/view.aspx";
    let posturl = format!("{base_url}?type=BW&message={postid}&page={page}",
                          base_url = base_url,
                          postid = postid,
                          page = page);
    posturl
}

fn list_page(state_manager: &mut StateManager, tx_req: &Sender<ChannelItem>) -> String {

    let ci = ChannelItem {
        extra: ChannelItemType::Index(ChannelIndexItem { }),
        result: String::from(""),
    };

    let status_message = match tx_req.send(ci) {
        Ok(()) => {
            state_manager.setWebRequest(true);    // *is_web_requesting = true;
            "SOK".to_string()
        }
        Err(e) => format!("{}:{}", "SFAIL", e).to_string(),
    };

    status_message
}

fn show_page(postid: &String, page: usize, state_manager: &mut StateManager, tx_req: &Sender<ChannelItem>) -> String {

    let ci = ChannelItem {
        extra: ChannelItemType::Show(ChannelShowItem { postid: postid.clone(), page: page }),
        result: String::from(""),
    };

    let status_message = match tx_req.send(ci) {
        Ok(()) => {
            state_manager.setWebRequest(true); // *is_web_requesting = true;
            "SOK".to_string()
        }
        Err(e) => format!("{}:{}", "SFAIL", e).to_string(),
    };

    status_message
}

fn image_request(url: &String, state_manager: &mut StateManager, tx_req: &Sender<ChannelItem>) -> String {

    let ci = ChannelItem {
        extra: ChannelItemType::Image(ChannelImageItem { url: url.to_string(), bytes: Vec::new() }),
        result: String::from(""),
    };

    let status_message = match tx_req.send(ci) {
        Ok(()) => {
            state_manager.setWebRequest(true); // *is_web_requesting = true;
            "SOK".to_string()
        }
        Err(e) => format!("{}:{}", "SFAIL", e).to_string(),
    };

    status_message
}

fn get_show_page_status_message(postid: &String, page: usize, status_message: &String) -> String {
    format!("[{}-{}:{}]", postid, page, status_message)
}
<commit_msg>web client - use image resource to fetch image and return the result via channel<commit_after>extern crate hkg;
extern crate termion;
extern crate rustc_serialize;
extern crate kuchiki;
extern crate chrono;
extern crate hyper;
extern crate cancellation;
extern crate time;
extern crate url;

use std::io::{stdout, stdin, Write};
use std::thread;
use std::sync::mpsc::channel;
use std::sync::mpsc::Sender;
use cancellation::{CancellationToken, CancellationTokenSource, OperationCanceled};
use kuchiki::traits::*;
use rustc_serialize::json;
use termion::input::TermRead;
use termion::raw::IntoRawMode;
use termion::event::Key;
use hkg::status::*;
use hkg::model::IconItem;
use hkg::model::ListTopicItem;
use hkg::state_manager::*;
use hkg::screen_manager::*;
use hkg::resources::common::*;
use hkg::caches::file_cache::*;
use hkg::net::*;
use hkg::net::web_resource::*;

fn main() {

    // Initialize
    let stdout = stdout();
    let mut stdout = stdout.lock().into_raw_mode().unwrap();

    // Clear the screen.
    hkg::screen::common::clear_screen();

    let mut builder = hkg::builder::Builder::new();

    let mut state_manager = StateManager::new();
    let mut screen_manager = ScreenManager::new();

    let icon_manifest_string = hkg::utility::readfile(String::from("data/icon.manifest.json"));
    let icon_collection: Box<Vec<IconItem>> = Box::new(json::decode(&icon_manifest_string).unwrap());

    // initialize empty page
    let mut list_topic_items: Vec<ListTopicItem> = vec![];
    let mut show_item = builder.default_show_item();

    let mut status_bar = hkg::screen::status_bar::StatusBar::new();
    let mut index = hkg::screen::index::Index::new();
    let mut show = hkg::screen::show::Show::new(icon_collection);

    let (tx_req, rx_req) = channel::<ChannelItem>();
    let (tx_res, rx_res) = channel::<ChannelItem>();

    // web client
    thread::spawn(move || {
        let mut wr = WebResource::new();
        let mut fc = Box::new(FileCache::new());
        let ct = CancellationTokenSource::new();
        ct.cancel_after(std::time::Duration::new(10, 0));
        loop {
            match rx_req.recv() {
                Ok(item) => {

                    let th = thread::current();
                    ct.run(|| {
                               th.unpark();
                           },
                           || {
                                match item.extra.clone() {
                                    ChannelItemType::Index(_) => {
                                        let mut index_resource = hkg::resources::index_resource::IndexResource::new(&mut wr, &ct, &mut fc);
                                        tx_res.send(index_resource.fetch(&item)).unwrap();
                                    },
                                    ChannelItemType::Show(_) => {
                                        let mut show_resource = hkg::resources::show_resource::ShowResource::new(&mut wr, &ct, &mut fc);
                                        tx_res.send(show_resource.fetch(&item)).unwrap();
                                    },
                                    ChannelItemType::Image(_) => {
                                        let mut image_resource = hkg::resources::image_resource::ImageResource::new(&mut wr, &ct, &mut fc);
                                        tx_res.send(image_resource.fetch(&item)).unwrap();
                                    }
                                }
                           });

                    if ct.is_canceled() {
                        thread::park_timeout(std::time::Duration::new(0, 250));
                        // Err(OperationCanceled)
                    } else {
                        // Ok(())
                    }
                }
                Err(_) => {}
            }
        }
    });

    // topics request
    let status_message = list_page(&mut state_manager, &tx_req);
    status_bar.append(&screen_manager, &status_message);

    loop {

        match rx_res.try_recv() {
            Ok(item) => {
                match item.extra {
                    ChannelItemType::Show(extra) => {
                        let document = kuchiki::parse_html().from_utf8().one(item.result.as_bytes());

                        let posturl = get_posturl(&extra.postid, extra.page);
                        show_item = builder.show_item(&document, &posturl);

                        status_bar.append(&screen_manager, &format!("[{}-{}:ROK][{}]",
                                 show_item.url_query.message,
                                 show_item.page,
                                 state_manager.isWebRequest()));

                        show.resetY();
                        hkg::screen::common::clear_screen();
                        state_manager.updateState(Status::Show); //state = Status::Show;
                        state_manager.setWebRequest(false); // is_web_requesting = false;
                    },
                    ChannelItemType::Index(_) => {
                        let document = kuchiki::parse_html().from_utf8().one(item.result.as_bytes());

                        list_topic_items = builder.list_topic_items(&document);

                        status_bar.append(&screen_manager,
                                               &format!("[TOPICS:ROK]"));

                        hkg::screen::common::clear_screen();

                        state_manager.updateState(Status::List); // state = Status::List;
                        state_manager.setWebRequest(false); // is_web_requesting = false;

                    },
                    ChannelItemType::Image(extra) => {
                    }
                }
            }
            Err(_) => {}
        }

        match state_manager.getState() {
            Status::Startup => {

            },
            Status::List => {
                index.print(&mut stdout, &list_topic_items);
            }
            Status::Show => {
                show.print(&mut stdout, &show_item);
            }
        }

        status_bar.print(&screen_manager);

        stdout.flush().unwrap();

        if !state_manager.isWebRequest() {

            let stdin = stdin();

            for c in stdin.keys() {

                if screen_manager.isWidthChanged() {
                    hkg::screen::common::clear_screen();
                }

                match state_manager.getState() {
                    Status::Startup => {},
                    Status::List => {
                        match c.unwrap() {
                            Key::Char('q') => {
                                hkg::screen::common::reset_screen();
                                return
                            },
                            Key::Char('\n') => {
                                status_bar.append(&screen_manager, "ENTER");
                                let i = index.get_selected_topic();
                                if i > 0 {
                                    let topic_item = &list_topic_items[i - 1];
                                    let postid = &topic_item.title.url_query.message;
                                    let page = 1;
                                    let status_message = show_page(&postid, page, &mut state_manager, &tx_req);

                                    status_bar.append(&screen_manager,
                                                           &get_show_page_status_message(postid, page, &status_message));
                                }
                                break
                            },
                            Key::PageUp => {
                                status_bar.append(&screen_manager, "↑");
                                let tmp = index.get_selected_topic();
                                status_bar.append(&screen_manager, &format!("{}", tmp));

                                if tmp > 1 {
                                    index.select_topic(tmp - 1);
                                }
                                break
                            },
                            Key::Up => {
                                status_bar.append(&screen_manager, "↑");
                                let tmp = index.get_selected_topic();
                                status_bar.append(&screen_manager, &format!("{}", tmp));

                                if tmp > 1 {
                                    index.select_topic(tmp - 1);
                                }
                                break
                            },
                            Key::Down => {
                                status_bar.append(&screen_manager, "↓");
                                let tmp = index.get_selected_topic();
                                status_bar.append(&screen_manager, &format!("{}", tmp));

                                if tmp < index.body_height() {
                                    index.select_topic(tmp + 1);
                                }
                                break
                            },
                            _ => {},
                        }
                    },
                    Status::Show => {
                            match c.unwrap() {
                                Key::Char('q') => {
                                    hkg::screen::common::reset_screen(); // print!("{}{}{}", termion::clear::All, style::Reset, termion::cursor::Show);
                                    return
                                },
                                Key::Left => {
                                    status_bar.append(&screen_manager, &format!("←"));
                                    if show_item.page > 1 {
                                        let postid = &show_item.url_query.message;
                                        let page = &show_item.page - 1;
                                        let status_message = show_page(&postid, page, &mut state_manager, &tx_req);

                                        status_bar.append(&screen_manager,
                                                               &get_show_page_status_message(postid, page, &status_message));
                                    }
                                    break
                                }
                                Key::Right => {
                                    status_bar.append(&screen_manager, &format!("→"));
                                    if show_item.max_page > show_item.page {
                                        let postid = &show_item.url_query.message;
                                        let page = &show_item.page + 1;
                                        let status_message = show_page(&postid, page, &mut state_manager, &tx_req);

                                        status_bar.append(&screen_manager,
                                                               &get_show_page_status_message(postid, page, &status_message));
                                    }
                                    break
                                },
                                Key::PageUp => {
                                    status_bar.append(&screen_manager, "↑");
                                    let bh = show.body_height();
                                    if show.scrollUp(bh) {
                                    hkg::screen::common::clear_screen();
                                    }
                                    break
                                },
                                Key::PageDown => {
                                    status_bar.append(&screen_manager, "↓");
                                    let bh = show.body_height();
                                    if show.scrollDown(bh) {
                                        hkg::screen::common::clear_screen();
                                    }
                                    break
                                },
                                Key::Up => {
                                    status_bar.append(&screen_manager, "↑");
                                    if show.scrollUp(2) {
                                        hkg::screen::common::clear_screen();
                                    }
                                    break
                                },
                                Key::Down => {
                                    status_bar.append(&screen_manager, "↓");
                                    if show.scrollDown(2) {
                                        hkg::screen::common::clear_screen();
                                    }
                                    break
                                },
                                Key::Backspace => {
                                    status_bar.append(&screen_manager, "B");
                                    state_manager.updateState(Status::List); // state = Status::List;
                                    hkg::screen::common::clear_screen();
                                    break
                                },
                                _ => {},
                            }
                        }
                }

            }
        }

    }
}
fn get_posturl(postid: &String, page: usize) -> String {
    let base_url = "http://forum1.hkgolden.com/view.aspx";
    let posturl = format!("{base_url}?type=BW&message={postid}&page={page}",
                          base_url = base_url,
                          postid = postid,
                          page = page);
    posturl
}

fn list_page(state_manager: &mut StateManager, tx_req: &Sender<ChannelItem>) -> String {

    let ci = ChannelItem {
        extra: ChannelItemType::Index(ChannelIndexItem { }),
        result: String::from(""),
    };

    let status_message = match tx_req.send(ci) {
        Ok(()) => {
            state_manager.setWebRequest(true);    // *is_web_requesting = true;
            "SOK".to_string()
        }
        Err(e) => format!("{}:{}", "SFAIL", e).to_string(),
    };

    status_message
}

fn show_page(postid: &String, page: usize, state_manager: &mut StateManager, tx_req: &Sender<ChannelItem>) -> String {

    let ci = ChannelItem {
        extra: ChannelItemType::Show(ChannelShowItem { postid: postid.clone(), page: page }),
        result: String::from(""),
    };

    let status_message = match tx_req.send(ci) {
        Ok(()) => {
            state_manager.setWebRequest(true); // *is_web_requesting = true;
            "SOK".to_string()
        }
        Err(e) => format!("{}:{}", "SFAIL", e).to_string(),
    };

    status_message
}

fn image_request(url: &String, state_manager: &mut StateManager, tx_req: &Sender<ChannelItem>) -> String {

    let ci = ChannelItem {
        extra: ChannelItemType::Image(ChannelImageItem { url: url.to_string(), bytes: Vec::new() }),
        result: String::from(""),
    };

    let status_message = match tx_req.send(ci) {
        Ok(()) => {
            state_manager.setWebRequest(true); // *is_web_requesting = true;
            "SOK".to_string()
        }
        Err(e) => format!("{}:{}", "SFAIL", e).to_string(),
    };

    status_message
}

fn get_show_page_status_message(postid: &String, page: usize, status_message: &String) -> String {
    format!("[{}-{}:{}]", postid, page, status_message)
}
<|endoftext|>


<commit_before>extern crate git2;
extern crate regex;

use std::env;
use git2::Repository;
use regex::Regex;

macro_rules! filter_try {
    ($e:expr) => (match $e { Ok(t) => t, Err(e) => return Some(Err(e)) })
}

macro_rules! option_match {
    ($e:expr) => (match $e { Ok(t) => t, Err(e) => panic!("err! - {}", e) })
}

fn main() {
    let args: Vec<_> = env::args().collect();
    let repo = option_match!(Repository::open("./"));
    let mut revwalk = option_match!(repo.revwalk());
    let commit_from: &str = &args[1][..];
    let commit_to: &str = &args[2][..];
    let mut commit_range = String::from("");

    commit_range.push_str(commit_from);
    commit_range.push_str("..");
    commit_range.push_str(commit_to);

    option_match!(revwalk.push_range(&commit_range[..]));

    let revwalk = revwalk.filter_map(|id| {
        let id = option_match!(id);
        let commit = filter_try!(repo.find_commit(id));
        Some(Ok(commit))
    });

    for commit in revwalk {
        let commit = option_match!(commit);

        for line in String::from_utf8_lossy(commit.message_bytes()).lines() {
            let re = Regex::new(r"^#changelog.*$").unwrap();

            if re.is_match(line) {
                    println!("{} by {}", line, commit.author());
            }
        }
    };
}
<commit_msg>Refactoring and testing<commit_after>extern crate git2;
extern crate regex;

#[cfg(not(test))] use std::env;

use git2::{Repository, Commit};
use regex::Regex;

macro_rules! filter_option {
    ($e:expr) => (match $e { Ok(t) => t, Err(e) => return Some(Err(e)) })
}

macro_rules! option_match {
    ($e:expr) => (match $e { Ok(t) => t, Err(e) => panic!("err! - {}", e) })
}

fn main() {
    let repo = option_match!(Repository::open("./"));
    let mut revwalk = option_match!(repo.revwalk());

    option_match!(revwalk.push_range(&commit_range()[..]));

    let revwalk = revwalk.filter_map(|id| {
        let id = option_match!(id);
        let commit = filter_option!(repo.find_commit(id));
        Some(Ok(commit))
    });

    for commit in revwalk {
        let commit = option_match!(commit);
        print_to_stdout(&commit);
    }
}

fn print_to_stdout(commit: &Commit) {
    for line in String::from_utf8_lossy(commit.message_bytes()).lines() {
        let re = Regex::new(r"^#changelog.*$").unwrap();

        if re.is_match(line) {
            println!("{} by {}", line, commit.author());
        }
    };
}

fn commit_range() -> String {
    let args: Vec<_> = env::args().collect();
    let commit_from: &str = &args[1][..];
    let commit_to: &str = &args[2][..];
    let mut commit_range = String::from("");

    commit_range.push_str(commit_from);
    commit_range.push_str("..");
    commit_range.push_str(commit_to);

    commit_range
}

#[cfg(test)] mod env {
    use std::vec;
    pub fn args() -> vec::IntoIter<&'static str> { vec!["changelg", "377d686351969f27f288dec2fb09d0d5431fcde1", "3763e0e3ff218cbdfbf99c68109a04d666e81abeto"].into_iter() }
}

#[test]
#[should_panic]
fn it_should_panic_on_error_in_option_match() {
    fn something_bad_happens<T>() -> Result<T, &'static str> {
        Err("Fail")
    };

    option_match!(something_bad_happens());
}

#[test]
fn it_should_return_result_on_ok_in_option_match() {
    fn something_good_happens() -> Result<&'static str, &'static str> {
        Ok("Good")
    };

    let result = option_match!(something_good_happens());
    assert_eq!(result, "Good");
}

#[test]
fn it_should_return_expected_commit_range_string(){
    assert_eq!(commit_range(), "377d686351969f27f288dec2fb09d0d5431fcde1..3763e0e3ff218cbdfbf99c68109a04d666e81abeto");
}<|endoftext|>


<commit_before>use std::fmt::Display;
use std::collections::HashMap;

type FreeVariable = u64;
type VariableName<'a> = &'a str;

/// AST node expression
#[derive(Clone, Debug)]
enum Expression<'a> {
    Number(f64),
    Boolean(bool),

    /// simple variable
    Variable(VariableName<'a>),

    /// fn (x, y, z) -> expr
    Lambda(&'a [VariableName<'a>], &'a Expression<'a>),

    /// let x = expr in expr
    Let(VariableName<'a>, &'a Expression<'a>, &'a Expression<'a>),

    /// some_fn (x, y, z)
    FnCall(&'a Expression<'a>, &'a [ &'a Expression<'a>])
}

#[derive(Debug)]
enum Type<'a> {
    Number,
    Boolean,
    Unbound(FreeVariable),
    Lambda(&'a [Type<'a>], &'a Type<'a>),

}

type TaggedType<'a> = (Expression<'a>, Type<'a>);

type TypeEnv<'a> = HashMap<VariableName<'a>, Type<'a>>;

struct VariableGen { current: FreeVariable }
impl VariableGen {
    fn next(&mut self) -> FreeVariable { self.current += 1; self.current }
}

/// Run algorithm W on expr with given type env, yielding the resolved
/// type of the expression, or the type error encountered.
fn w<'a>(expr: &Expression<'a>, env: &mut TypeEnv<'a>, inst: &mut VariableGen) -> Type<'a> {
    match *expr {
        Expression::Number(_) => Type::Number,
        Expression::Boolean(_) => Type::Boolean,
        Expression::Variable(name) => Type::Unbound(inst.next()),
        _ => Type::Unbound(inst.next()),
    }
}

fn main() {
    // FIXME: this is so gnarly.
    // let incr = \x -> 123.0 in incr (123.0) :: Number
    let num = Expression::Number(123.0);
    let incr = Expression::Variable("incr");
    let args = ["x"];
    let args_ = [&num];
    let fn_call = Expression::FnCall(&incr, &args_);
    let lambda = Expression::Lambda(&args, &num);

    let expr = Expression::Let(
        "incr", &lambda,
        &fn_call);

    let mut inst = VariableGen {current: 0};
    let mut env = HashMap::new();

    println!("this is the thing: {:?}\n", w(&expr, &mut env, &mut inst))
}
<commit_msg>w(fncall)<commit_after>use std::fmt::Display;
use std::collections::HashMap;

type FreeVariable = u64;
type VariableName<'a> = &'a str;

/// AST node expression
#[derive(Clone, Debug)]
enum Expression<'a> {
    Number(f64),
    Boolean(bool),

    /// simple variable
    Variable(VariableName<'a>),

    /// fn (x, y, z) -> expr
    Lambda(&'a [VariableName<'a>], &'a Expression<'a>),

    /// let x = expr in expr
    Let(VariableName<'a>, &'a Expression<'a>, &'a Expression<'a>),

    /// some_fn (x, y, z)
    FnCall(&'a Expression<'a>, &'a [ &'a Expression<'a>])
}

#[derive(PartialEq, Clone, Debug)]
enum Type<'a> {
    Number,
    Boolean,
    Unbound(FreeVariable),
    Lambda(&'a [Type<'a>], &'a Type<'a>),

}

type TaggedType<'a> = (Expression<'a>, Type<'a>);

type TypeEnv<'a> = HashMap<VariableName<'a>, Type<'a>>;

#[derive(Clone, Copy)]
struct VariableGen { current: FreeVariable }
impl VariableGen {
    fn next(&mut self) -> FreeVariable { self.current += 1; self.current }
}

/// Run algorithm W on expr with given type env, yielding the resolved
/// type of the expression, or the type error encountered.
fn w<'a>(expr: &Expression<'a>, env: &mut TypeEnv<'a>, inst: &mut VariableGen) -> Type<'a> {
    match *expr {
        // simplest case: literals have immediately defined types.
        Expression::Number(_) => Type::Number,
        Expression::Boolean(_) => Type::Boolean,

        // variables we need to look up inside our type environment
        Expression::Variable(name) => Type::Unbound(inst.next()),

        Expression::Lambda(args, body) => Type::Unbound(inst.next()),

        Expression::Let(name, expr, body) => Type::Unbound(inst.next()),

        // 1. ensure that the callable in this function call is truly callable.
        // 2. ensure that the number and type of args match
        // 3. return type of body of lambda
        Expression::FnCall(callable, args) => {
            // FIXME: this seems broken.
            let mut env_ = env.clone();
            let mut inst_ = inst.clone();

            let mut type_args = args
                .iter()
                .map(|arg| {
                    w(arg, &mut env_, &mut inst_)
                })
                .collect::<Vec<Type>>();

            match w(callable, env, inst) {
                Type::Lambda(expected, _) if args.len() != expected.len() => {
                    panic!("wrong number of args given")
                },

                Type::Lambda(expected, body_type) => {
                    if expected != type_args.as_slice() {
                        panic!("bad types given")
                    }

                    body_type.clone()
                }

                _ => panic!("trying to call non-function")
            }
        }
    }
}

fn main() {
    // FIXME: this is so gnarly.
    // let incr = \x -> 123.0 in incr (123.0) :: Number
    let num = Expression::Number(123.0);
    let incr = Expression::Variable("incr");
    let args = ["x"];
    let args_ = [&num];
    let fn_call = Expression::FnCall(&incr, &args_);
    let lambda = Expression::Lambda(&args, &num);

    let expr = Expression::Let(
        "incr", &lambda,
        &fn_call);

    let mut inst = VariableGen {current: 0};
    let mut env = HashMap::new();

    println!("this is the thing: {:?}\n", w(&expr, &mut env, &mut inst))
}
<|endoftext|>


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

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

enum ParseAtomError {
    IncorrectSymbolName
}

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

impl FromStr for Atom {
    type Err = ParseAtomError;

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

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

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

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

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

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

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

enum ParseAtomError {
    IncorrectSymbolName
}

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

impl FromStr for Atom {
    type Err = ParseAtomError;

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

fn tokenize<'a>(s: &'a str) -> Vec<String> {
    s.replace("("," ( ")
        .replace(")", " ) ")
        .replace("\n", " ")
        .split(' ')
        .filter_map(|s| { if s.is_empty() { None } else { Some(s.to_string()) }})
        .collect()
}

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

#[cfg(test)]
mod test {
    use super::{Atom, 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 tokenize_dense_expression() {
        let expected_result = vec!("(", "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 = vec!("(", "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 termion;
extern crate thread_scoped;
extern crate time;
extern crate voodoo;

mod level;
mod program;

use std::io::{Write};
use std::sync::mpsc::channel;

use termion::event::{Key, Event, MouseEvent};
use termion::input::{TermRead};

use voodoo::color::ColorValue;
use voodoo::window::{Point, TermCell, Window};

use level::Level;
use program::{Program, ProgramRef};

const LEVEL_DESCR: [&'static str; 22] = [
    "                                                          ",
    "                                                          ",
    "                                                          ",
    "                                                          ",
    "          .........................                       ",
    "          .........................                       ",
    "          ..                     ..                       ",
    "          ..                     ..                       ",
    "          ..                     ..                       ",
    "          ..                     ..                       ",
    "   o................             .....                    ",
    "   o................             .....                    ",
    "          ..                     ..                       ",
    "          ..                     ..                       ",
    "          ..                     ..                       ",
    "          ..                     ..                       ",
    "          ..                     ..                       ",
    "          .........................                       ",
    "          .........................                       ",
    "                                                          ",
    "                                                          ",
    "                                                          ",
];

enum UiState {
    Unselected,
    Selected,
    Damage(ProgramRef, usize),
}

enum UiEvent {
    Tick,
    Test,
    Click(Point),
    // Movement
}

enum GameState {
    Setup,
    PlayerTurn,
    AITurn,
    AIExecute,
}

struct InfoView {
    window: Window,
}

impl InfoView {
    fn new(window: Window) -> InfoView {
        InfoView {
            window: window,
        }
    }

    fn refresh(&mut self, stdout: &mut std::io::Stdout) {
        self.window.refresh(stdout);
    }

    fn clear(&mut self) {
        for col in 2..self.window.width - 2 {
            self.window.put_at(Point::new(col, 2), ' ');
        }
    }

    fn display_program(&mut self, program: &Program) {
        self.window.print_at(Point::new(2, 2), &program.name);
    }
}

struct MapView {
    window: Window,
    highlight: Option<ProgramRef>,
    overlay: Vec<(Point, TermCell)>,
}

impl MapView {
    fn new(window: Window) -> MapView {
        MapView {
            window: window,
            highlight: None,
            overlay: Vec::new(),
        }
    }

    fn from_global_frame(&self, p: Point) -> Option<Point> {
        self.window.position.from_global_frame(p)
    }

    fn display(&mut self, level: &Level) {
        for (y, line) in level.layout.iter().enumerate() {
            let y = y + 1;
            for (x, tile) in line.chars().enumerate() {
                let x = x + 1;
                match Level::convert(tile) {
                    Some(c) => self.window.put_at(Point::new(x as u16, y as u16), c),
                    None => {},
                }
            }
        }

        for program in level.player_programs.iter() {
            program.borrow().display_color(ColorValue::Green, &mut self.window);
        }

        for program in level.enemy_programs.iter() {
            program.borrow().display_color(ColorValue::Red, &mut self.window);
        }

        if let Some(ref program) = self.highlight {
            program.borrow().display_color(ColorValue::Blue, &mut self.window);
        }

        for &(p, c) in self.overlay.iter() {
            self.window.put_at(p, c);
        }
    }

    fn refresh(&mut self, stdout: &mut std::io::Stdout) {
        self.window.refresh(stdout);
    }

    fn highlight(&mut self, program: ProgramRef, level: &Level) {
        self.highlight = Some(program.clone());
        self.update_highlight(level);
    }

    fn update_highlight(&mut self, level: &Level) {
        if let Some(ref program) = self.highlight {
            self.overlay.clear();
            let Point { x, y } = program.borrow().position;
            let east = Point::new(x + 1, y);
            if level.passable(east) {
                self.overlay.push((east, '→'.into()));
            }
            let west = Point::new(x - 1, y);
            if level.passable(west) {
                self.overlay.push((west, '←'.into()));
            }
            let north = Point::new(x, y - 1);
            if level.passable(north) {
                self.overlay.push((north, '↑'.into()));
            }
            let south = Point::new(x, y + 1);
            if level.passable(south) {
                self.overlay.push((south, '↓'.into()));
            }
        }
    }

    fn clear_highlight(&mut self) {
        self.highlight = None;
        self.overlay.clear();
    }
}

struct UiModelView {
    info: InfoView,
    map: MapView,
}

impl UiState {
    fn translate_click(click: Point, map: &MapView) -> Option<Point> {
        for &(point, _) in map.overlay.iter() {
            if click == point {
                return Some(point);
            }
        }
        None
    }

    fn next(self, event: UiEvent, level: &mut Level, mv: &mut UiModelView) -> UiState {
        use UiEvent::*;
        use UiState::*;

        let UiModelView { ref mut info, ref mut map } = *mv;

        match (self, event) {
            (Unselected, Click(p)) => {
                for program in level.player_programs.iter() {
                    if program.borrow().intersects(p) {
                        map.highlight(program.clone(), &level);
                        info.display_program(&program.borrow());
                        return Selected;
                    }
                }
                Unselected
            }
            (Selected, Click(p)) => {
                let result = Self::translate_click(p, map);
                if let Some(p) = result {
                    if let Some(ref mut program) = map.highlight {
                        program.borrow_mut().move_to(p);
                    }
                    map.update_highlight(&level);
                    Selected
                }
                else {
                    map.clear_highlight();
                    info.clear();
                    Unselected
                }
            }
            (Damage(program, damage), Tick) => {
                if damage == 0 {
                    if map.highlight.is_some() {
                        Selected
                    }
                    else {
                        Unselected
                    }
                }
                else {
                    if program.borrow_mut().damage() {
                        Damage(program, damage - 1)
                    }
                    else {
                        // TODO: remove program as it died
                        Damage(program, 0)
                    }
                }
            }
            (damage@Damage(_, _), _) => {
                damage
            }
            (state, Tick) => { state }
            (Selected, Test) => {
                if let Some(ref program) = map.highlight {
                    Damage(program.clone(), 2)
                }
                else {
                    Selected
                }
            }
            (state, Test) => { state },
        }
    }
}

fn main() {
    use std::sync::mpsc::TryRecvError::*;
    use voodoo::terminal::{Mode, Terminal};
    let mut level = Level::new(&LEVEL_DESCR);
    level.add_player_program(Program::new(Point::new(11, 11), "Hack"));
    level.add_player_program(Program::new(Point::new(5, 12), "Hack"));
    level.add_enemy_program(Program::new(Point::new(7, 12), "Hack"));

    let mut terminal = Terminal::new();
    terminal.cursor(Mode::Disabled);
    terminal.clear_color(ColorValue::Black);
    let Terminal { ref mut stdin, ref mut stdout } = terminal;

    stdout.flush().unwrap();

    let mut info = voodoo::window::Window::new(Point::new(0, 0), 20, 24);
    let mut map = voodoo::window::Window::new(Point::new(20, 0), 60, 24);
    info.border();
    map.border();

    let mut info_view = InfoView::new(info);
    let mut map_view = MapView::new(map);
    info_view.refresh(stdout);
    map_view.display(&level);
    map_view.refresh(stdout);

    let mut ui_modelview = UiModelView {
        info: info_view,
        map: map_view,
    };
    let mut ui_state = UiState::Unselected;

    let (tx, rx) = channel();
    let guard = unsafe {
        thread_scoped::scoped(move || {
            for c in stdin.events() {
                let evt = c.unwrap();
                if let Event::Key(Key::Char('q')) = evt {
                    break;
                }
                tx.send(evt).unwrap();
            }
        })
    };

    let mut t = time::precise_time_ns();
    let mut dt = 0;

    'main: loop {
        loop {
            // Handle all pending events
            let msg = rx.try_recv();
            match msg {
                Ok(evt) => {
                    match evt {
                        Event::Key(Key::Char('q')) => break 'main,
                        Event::Key(Key::Char(' ')) => {
                            ui_state = ui_state.next(UiEvent::Test, &mut level, &mut ui_modelview);
                        },
                        Event::Mouse(me) => {
                            match me {
                                MouseEvent::Press(_, x, y) => {
                                    if let Some(p) = ui_modelview.map.from_global_frame(Point::new(x, y)) {
                                        ui_state = ui_state.next(
                                            UiEvent::Click(p),
                                            &mut level,
                                            &mut ui_modelview,
                                        );
                                    }
                                },
                                _ => (),
                            }
                        }
                        _ => {}
                    }
                },
                Err(Disconnected) => break 'main,
                Err(Empty) => break,
            }
        }

        let now = time::precise_time_ns();
        dt += now - t;

        // TODO: use constant
        while dt >= 100000000 {
            ui_state = ui_state.next(UiEvent::Tick, &mut level, &mut ui_modelview);
            dt -= 100000000;
        }

        ui_modelview.info.refresh(stdout);
        ui_modelview.map.display(&level);
        ui_modelview.map.refresh(stdout);
        t = now;
    }
    guard.join();
}
<commit_msg>feat: sleep main thread in between frames<commit_after>extern crate termion;
extern crate thread_scoped;
extern crate time;
extern crate voodoo;

mod level;
mod program;

use std::io::{Write};
use std::sync::mpsc::channel;

use termion::event::{Key, Event, MouseEvent};
use termion::input::{TermRead};

use voodoo::color::ColorValue;
use voodoo::window::{Point, TermCell, Window};

use level::Level;
use program::{Program, ProgramRef};

const LEVEL_DESCR: [&'static str; 22] = [
    "                                                          ",
    "                                                          ",
    "                                                          ",
    "                                                          ",
    "          .........................                       ",
    "          .........................                       ",
    "          ..                     ..                       ",
    "          ..                     ..                       ",
    "          ..                     ..                       ",
    "          ..                     ..                       ",
    "   o................             .....                    ",
    "   o................             .....                    ",
    "          ..                     ..                       ",
    "          ..                     ..                       ",
    "          ..                     ..                       ",
    "          ..                     ..                       ",
    "          ..                     ..                       ",
    "          .........................                       ",
    "          .........................                       ",
    "                                                          ",
    "                                                          ",
    "                                                          ",
];

enum UiState {
    Unselected,
    Selected,
    Damage(ProgramRef, usize),
}

enum UiEvent {
    Tick,
    Test,
    Click(Point),
    // Movement
}

enum GameState {
    Setup,
    PlayerTurn,
    AITurn,
    AIExecute,
}

struct InfoView {
    window: Window,
}

impl InfoView {
    fn new(window: Window) -> InfoView {
        InfoView {
            window: window,
        }
    }

    fn refresh(&mut self, stdout: &mut std::io::Stdout) {
        self.window.refresh(stdout);
    }

    fn clear(&mut self) {
        for col in 2..self.window.width - 2 {
            self.window.put_at(Point::new(col, 2), ' ');
        }
    }

    fn display_program(&mut self, program: &Program) {
        self.window.print_at(Point::new(2, 2), &program.name);
    }
}

struct MapView {
    window: Window,
    highlight: Option<ProgramRef>,
    overlay: Vec<(Point, TermCell)>,
}

impl MapView {
    fn new(window: Window) -> MapView {
        MapView {
            window: window,
            highlight: None,
            overlay: Vec::new(),
        }
    }

    fn from_global_frame(&self, p: Point) -> Option<Point> {
        self.window.position.from_global_frame(p)
    }

    fn display(&mut self, level: &Level) {
        for (y, line) in level.layout.iter().enumerate() {
            let y = y + 1;
            for (x, tile) in line.chars().enumerate() {
                let x = x + 1;
                match Level::convert(tile) {
                    Some(c) => self.window.put_at(Point::new(x as u16, y as u16), c),
                    None => {},
                }
            }
        }

        for program in level.player_programs.iter() {
            program.borrow().display_color(ColorValue::Green, &mut self.window);
        }

        for program in level.enemy_programs.iter() {
            program.borrow().display_color(ColorValue::Red, &mut self.window);
        }

        if let Some(ref program) = self.highlight {
            program.borrow().display_color(ColorValue::Blue, &mut self.window);
        }

        for &(p, c) in self.overlay.iter() {
            self.window.put_at(p, c);
        }
    }

    fn refresh(&mut self, stdout: &mut std::io::Stdout) {
        self.window.refresh(stdout);
    }

    fn highlight(&mut self, program: ProgramRef, level: &Level) {
        self.highlight = Some(program.clone());
        self.update_highlight(level);
    }

    fn update_highlight(&mut self, level: &Level) {
        if let Some(ref program) = self.highlight {
            self.overlay.clear();
            let Point { x, y } = program.borrow().position;
            let east = Point::new(x + 1, y);
            if level.passable(east) {
                self.overlay.push((east, '→'.into()));
            }
            let west = Point::new(x - 1, y);
            if level.passable(west) {
                self.overlay.push((west, '←'.into()));
            }
            let north = Point::new(x, y - 1);
            if level.passable(north) {
                self.overlay.push((north, '↑'.into()));
            }
            let south = Point::new(x, y + 1);
            if level.passable(south) {
                self.overlay.push((south, '↓'.into()));
            }
        }
    }

    fn clear_highlight(&mut self) {
        self.highlight = None;
        self.overlay.clear();
    }
}

struct UiModelView {
    info: InfoView,
    map: MapView,
}

impl UiState {
    fn translate_click(click: Point, map: &MapView) -> Option<Point> {
        for &(point, _) in map.overlay.iter() {
            if click == point {
                return Some(point);
            }
        }
        None
    }

    fn next(self, event: UiEvent, level: &mut Level, mv: &mut UiModelView) -> UiState {
        use UiEvent::*;
        use UiState::*;

        let UiModelView { ref mut info, ref mut map } = *mv;

        match (self, event) {
            (Unselected, Click(p)) => {
                for program in level.player_programs.iter() {
                    if program.borrow().intersects(p) {
                        map.highlight(program.clone(), &level);
                        info.display_program(&program.borrow());
                        return Selected;
                    }
                }
                Unselected
            }
            (Selected, Click(p)) => {
                let result = Self::translate_click(p, map);
                if let Some(p) = result {
                    if let Some(ref mut program) = map.highlight {
                        program.borrow_mut().move_to(p);
                    }
                    map.update_highlight(&level);
                    Selected
                }
                else {
                    map.clear_highlight();
                    info.clear();
                    Unselected
                }
            }
            (Damage(program, damage), Tick) => {
                if damage == 0 {
                    if map.highlight.is_some() {
                        Selected
                    }
                    else {
                        Unselected
                    }
                }
                else {
                    if program.borrow_mut().damage() {
                        Damage(program, damage - 1)
                    }
                    else {
                        // TODO: remove program as it died
                        Damage(program, 0)
                    }
                }
            }
            (damage@Damage(_, _), _) => {
                damage
            }
            (state, Tick) => { state }
            (Selected, Test) => {
                if let Some(ref program) = map.highlight {
                    Damage(program.clone(), 2)
                }
                else {
                    Selected
                }
            }
            (state, Test) => { state },
        }
    }
}

fn main() {
    use std::sync::mpsc::TryRecvError::*;
    use std::thread;
    use std::time::Duration;

    use voodoo::terminal::{Mode, Terminal};

    let mut level = Level::new(&LEVEL_DESCR);
    level.add_player_program(Program::new(Point::new(11, 11), "Hack"));
    level.add_player_program(Program::new(Point::new(5, 12), "Hack"));
    level.add_enemy_program(Program::new(Point::new(7, 12), "Hack"));

    let mut terminal = Terminal::new();
    terminal.cursor(Mode::Disabled);
    terminal.clear_color(ColorValue::Black);
    let Terminal { ref mut stdin, ref mut stdout } = terminal;

    stdout.flush().unwrap();

    let mut info = voodoo::window::Window::new(Point::new(0, 0), 20, 24);
    let mut map = voodoo::window::Window::new(Point::new(20, 0), 60, 24);
    info.border();
    map.border();

    let mut info_view = InfoView::new(info);
    let mut map_view = MapView::new(map);
    info_view.refresh(stdout);
    map_view.display(&level);
    map_view.refresh(stdout);

    let mut ui_modelview = UiModelView {
        info: info_view,
        map: map_view,
    };
    let mut ui_state = UiState::Unselected;

    let (tx, rx) = channel();
    let guard = unsafe {
        thread_scoped::scoped(move || {
            for c in stdin.events() {
                let evt = c.unwrap();
                if let Event::Key(Key::Char('q')) = evt {
                    break;
                }
                tx.send(evt).unwrap();
            }
        })
    };

    let mut t = time::precise_time_ns();
    let mut dt = 0;

    'main: loop {
        loop {
            // Handle all pending events
            let msg = rx.try_recv();
            match msg {
                Ok(evt) => {
                    match evt {
                        Event::Key(Key::Char('q')) => break 'main,
                        Event::Key(Key::Char(' ')) => {
                            ui_state = ui_state.next(UiEvent::Test, &mut level, &mut ui_modelview);
                        },
                        Event::Mouse(me) => {
                            match me {
                                MouseEvent::Press(_, x, y) => {
                                    if let Some(p) = ui_modelview.map.from_global_frame(Point::new(x, y)) {
                                        ui_state = ui_state.next(
                                            UiEvent::Click(p),
                                            &mut level,
                                            &mut ui_modelview,
                                        );
                                    }
                                },
                                _ => (),
                            }
                        }
                        _ => {}
                    }
                },
                Err(Disconnected) => break 'main,
                Err(Empty) => break,
            }
        }

        let now = time::precise_time_ns();
        dt += now - t;

        // TODO: use constant
        while dt >= 100000000 {
            ui_state = ui_state.next(UiEvent::Tick, &mut level, &mut ui_modelview);
            dt -= 100000000;
        }

        ui_modelview.info.refresh(stdout);
        ui_modelview.map.display(&level);
        ui_modelview.map.refresh(stdout);
        t = now;

        thread::sleep(Duration::from_millis(100 - dt / 1000000));
    }
    guard.join();
}
<|endoftext|>


<commit_before>extern crate log;
extern crate pretty_env_logger;
extern crate reqwest;
extern crate serde;
extern crate serde_json;
extern crate trust_dns;

use log::info;

use serde_json::value::*;

use std::env;
use std::io;
use std::io::prelude::*;

use trust_dns::client::{Client as _Client, SyncClient};
use trust_dns::rr::dns_class::DNSClass;
use trust_dns::rr::record_type::RecordType;
use trust_dns::rr::domain;
use trust_dns::rr::record_data::RData;
use trust_dns::udp::UdpClientConnection;

const NS1_GOOGLE_COM_IP_ADDR: &'static str = "216.239.32.10:53";

fn env_var(n: &str) -> String {
    let err = format!("Environment Variable '{}' must be set!", &n);
    env::var(n).ok().expect(&err)
}

// overloaded function. no body is treated as a get, body is treated as a put
fn cloudflare_api(client: &reqwest::Client, url: &str, body: Option<String>) -> Result<Value, String> {
    let cloudflare_apikey = env_var("CLOUDFLARE_APIKEY");
    let cloudflare_email = env_var("CLOUDFLARE_EMAIL");

    let request = match body {
        Some(body) => { client.put(url).body(body) }
        None => { client.get(url) }
    };
    let response_json : Value = request
        .header("X-Auth-Key", cloudflare_apikey.to_owned())
        .header("X-Auth-Email", cloudflare_email.to_owned())
        .send().unwrap()
        .json().unwrap();

    let success = response_json
        .as_object().unwrap()
        .get("success").unwrap()
        .as_bool().unwrap();
    if !success {
        return Err(format!("Request not successful: {}", response_json));
    }

    Ok(response_json)
}

fn get_current_ip() -> Result<String, ()> {
    let gdns_addr = (NS1_GOOGLE_COM_IP_ADDR).parse().expect("Couldn't get Google DNS Socket Addr");
    let conn = UdpClientConnection::new(gdns_addr).expect("Couldn't open DNS UDP Connection");
    let client = SyncClient::new(conn);

    let name = domain::Name::new();
    let name = name.append_label("o-o").unwrap()
        .append_label("myaddr").unwrap()
        .append_label("l").unwrap()
        .append_label("google").unwrap()
        .append_label("com").unwrap();
    let response = client.query(&name, DNSClass::IN, RecordType::TXT).unwrap();

    let record = &response.answers()[0];
    match record.rdata() {
        &RData::TXT(ref txt) => {
            let val = txt.txt_data();
            return Ok(String::from_utf8(val[0].to_vec()).unwrap())
        },
        _ => return Err(())
    }
}

fn main() {
    pretty_env_logger::init();

    let current_ip = get_current_ip().ok().expect("Was unable to determine current IP address.");
    info!("{}", current_ip);
    let client = reqwest::Client::new();

    let cloudflare_records_env = env_var("CLOUDFLARE_RECORDS");
    let cloudflare_records: Vec<&str> = cloudflare_records_env.split(|c: char| c == ',').collect();

    let zones_url = "https://api.cloudflare.com/client/v4/zones";
    let zones_json = cloudflare_api(&client, zones_url, None).unwrap();

    let zone_ids = zones_json
        .as_object().unwrap()
        .get("result").unwrap()
        .as_array().unwrap()
        .iter()
        .map(|ref zone_node|
             zone_node.get("id").unwrap()
             .as_str().unwrap());

    for zone_id in zone_ids {
        let records_url = format!("https://api.cloudflare.com/client/v4/zones/{}/dns_records", zone_id);
        let records_json = cloudflare_api(&client, &*records_url, None).unwrap();

        let records = records_json
            .as_object().unwrap()
            .get("result").unwrap()
            .as_array().unwrap()
            .iter();

        for record in records {
            let record_id = record.get("id").unwrap().as_str().unwrap();
            let record_type = record.get("type").unwrap().as_str().unwrap();
            let record_name = record.get("name").unwrap().as_str().unwrap();
            let record_content = record.get("content").unwrap().as_str().unwrap();

            if !cloudflare_records.contains(&record_name) || record_type != "A" {
                continue
            }

            if record_content == current_ip {
                info!("{} skipped, up to date", record_name);
                continue;
            }

            print!("{} ({} -> {})... ", record_name, record_content, current_ip);
            io::stdout().flush().ok();

            let record_url = format!(
                "https://api.cloudflare.com/client/v4/zones/{}/dns_records/{}",
                zone_id,
                record_id);
            let record_update_body = format!(
                r#"{{"name": "{}", "content": "{}", "type": "{}", "proxied": true}}"#,
                record_name,
                current_ip,
                record_type);
            cloudflare_api(&client, &*record_url, Some(record_update_body.to_string())).unwrap();
        }
    }
}
<commit_msg>cargo fmt<commit_after>extern crate log;
extern crate pretty_env_logger;
extern crate reqwest;
extern crate serde;
extern crate serde_json;
extern crate trust_dns;

use log::info;

use serde_json::value::*;

use std::env;
use std::io;
use std::io::prelude::*;

use trust_dns::client::{Client as _Client, SyncClient};
use trust_dns::rr::dns_class::DNSClass;
use trust_dns::rr::domain;
use trust_dns::rr::record_data::RData;
use trust_dns::rr::record_type::RecordType;
use trust_dns::udp::UdpClientConnection;

const NS1_GOOGLE_COM_IP_ADDR: &'static str = "216.239.32.10:53";

fn env_var(n: &str) -> String {
    let err = format!("Environment Variable '{}' must be set!", &n);
    env::var(n).ok().expect(&err)
}

// overloaded function. no body is treated as a get, body is treated as a put
fn cloudflare_api(
    client: &reqwest::Client,
    url: &str,
    body: Option<String>,
) -> Result<Value, String> {
    let cloudflare_apikey = env_var("CLOUDFLARE_APIKEY");
    let cloudflare_email = env_var("CLOUDFLARE_EMAIL");

    let request = match body {
        Some(body) => client.put(url).body(body),
        None => client.get(url),
    };
    let response_json: Value = request
        .header("X-Auth-Key", cloudflare_apikey.to_owned())
        .header("X-Auth-Email", cloudflare_email.to_owned())
        .send()
        .unwrap()
        .json()
        .unwrap();

    let success = response_json
        .as_object()
        .unwrap()
        .get("success")
        .unwrap()
        .as_bool()
        .unwrap();
    if !success {
        return Err(format!("Request not successful: {}", response_json));
    }

    Ok(response_json)
}

fn get_current_ip() -> Result<String, ()> {
    let gdns_addr = (NS1_GOOGLE_COM_IP_ADDR)
        .parse()
        .expect("Couldn't get Google DNS Socket Addr");
    let conn = UdpClientConnection::new(gdns_addr).expect("Couldn't open DNS UDP Connection");
    let client = SyncClient::new(conn);

    let name = domain::Name::new();
    let name = name
        .append_label("o-o")
        .unwrap()
        .append_label("myaddr")
        .unwrap()
        .append_label("l")
        .unwrap()
        .append_label("google")
        .unwrap()
        .append_label("com")
        .unwrap();
    let response = client.query(&name, DNSClass::IN, RecordType::TXT).unwrap();

    let record = &response.answers()[0];
    match record.rdata() {
        &RData::TXT(ref txt) => {
            let val = txt.txt_data();
            return Ok(String::from_utf8(val[0].to_vec()).unwrap());
        }
        _ => return Err(()),
    }
}

fn main() {
    pretty_env_logger::init();

    let current_ip = get_current_ip()
        .ok()
        .expect("Was unable to determine current IP address.");
    info!("{}", current_ip);
    let client = reqwest::Client::new();

    let cloudflare_records_env = env_var("CLOUDFLARE_RECORDS");
    let cloudflare_records: Vec<&str> = cloudflare_records_env.split(|c: char| c == ',').collect();

    let zones_url = "https://api.cloudflare.com/client/v4/zones";
    let zones_json = cloudflare_api(&client, zones_url, None).unwrap();

    let zone_ids = zones_json
        .as_object()
        .unwrap()
        .get("result")
        .unwrap()
        .as_array()
        .unwrap()
        .iter()
        .map(|ref zone_node| zone_node.get("id").unwrap().as_str().unwrap());

    for zone_id in zone_ids {
        let records_url = format!(
            "https://api.cloudflare.com/client/v4/zones/{}/dns_records",
            zone_id
        );
        let records_json = cloudflare_api(&client, &*records_url, None).unwrap();

        let records = records_json
            .as_object()
            .unwrap()
            .get("result")
            .unwrap()
            .as_array()
            .unwrap()
            .iter();

        for record in records {
            let record_id = record.get("id").unwrap().as_str().unwrap();
            let record_type = record.get("type").unwrap().as_str().unwrap();
            let record_name = record.get("name").unwrap().as_str().unwrap();
            let record_content = record.get("content").unwrap().as_str().unwrap();

            if !cloudflare_records.contains(&record_name) || record_type != "A" {
                continue;
            }

            if record_content == current_ip {
                info!("{} skipped, up to date", record_name);
                continue;
            }

            print!("{} ({} -> {})... ", record_name, record_content, current_ip);
            io::stdout().flush().ok();

            let record_url = format!(
                "https://api.cloudflare.com/client/v4/zones/{}/dns_records/{}",
                zone_id, record_id
            );
            let record_update_body = format!(
                r#"{{"name": "{}", "content": "{}", "type": "{}", "proxied": true}}"#,
                record_name, current_ip, record_type
            );
            cloudflare_api(&client, &*record_url, Some(record_update_body.to_string())).unwrap();
        }
    }
}
<|endoftext|>


<commit_before>#![allow(non_upper_case_globals)]

#![allow(dead_code)]
#![allow(unused_assignments)]
#![allow(unused_variables)]

#[macro_use] extern crate lazy_static;

use std::ffi::OsStr;
use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;
use std::path::{ Path, PathBuf };

lazy_static! {
    static ref HOME: PathBuf = std::env::home_dir().unwrap();

    static ref build_props: PathBuf = PathBuf::from("project/build.properties");

    static ref sbt_launch_dir: PathBuf = { let mut p = PathBuf::from(&*HOME); p.push(".sbt/launchers"); p };
}

const sbt_launch_ivy_release_repo: &'static str = "http://repo.typesafe.com/typesafe/ivy-releases";
const sbt_launch_mvn_release_repo: &'static str = "http://repo.scala-sbt.org/scalasbt/maven-releases";

macro_rules! echoerr(($($arg:tt)*) => (writeln!(&mut ::std::io::stderr(), $($arg)*).unwrap();));

fn build_props_sbt() -> String {
    if let Ok(f) = File::open(&*build_props) {
        let f = BufReader::new(f);
        for line in f.lines() {
            let line = line.unwrap();
            if line.starts_with("sbt.version") {
                let line = line.replace("=", " ");
                let line = line.replace("\r", " ");
                return line.split_whitespace().nth(1).unwrap().to_owned();
            }
        }
    }
    "".to_owned()
}

fn jar_file(version: &str) -> PathBuf {
    let mut p = PathBuf::from(&*sbt_launch_dir);
    p.push(version);
    p.push("sbt-launch.jar");
    p
}

fn url_base(version: &str) -> &'static str { match version {
    s if s.starts_with("0.7.")  => "http://simple-build-tool.googlecode.com",
    s if s.starts_with("0.10.") => sbt_launch_ivy_release_repo,
    "0.11.1" | "0.11.2"         => sbt_launch_ivy_release_repo,
 // "0.*-yyyymmdd-hhMMss"       => sbt_launch_ivy_snapshot_repo, // https://repo.scala-sbt.org/scalasbt/ivy-snapshots
    s if s.starts_with("0.")    => sbt_launch_ivy_release_repo,
 // "*-yyyymmdd-hhMMss"         => sbt_launch_mvn_snapshot_repo, // http://repo.scala-sbt.org/scalasbt/maven-snapshots
    _                           => sbt_launch_mvn_release_repo,
} }

fn make_url(version: &str) -> String {
    let base = url_base(version);
    match version {
        s if s.starts_with("0.7.")  => format!("{}/files/sbt-launch-0.7.7.jar", base),
        s if s.starts_with("0.10.") => format!("{}/org.scala-tools.sbt/sbt-launch/{}/sbt-launch.jar", base, version),
        "0.11.1" | "0.11.2"         => format!("{}/org.scala-tools.sbt/sbt-launch/{}/sbt-launch.jar", base, version),
        s if s.starts_with("0.")    => format!("{}/org.scala-sbt/sbt-launch/{}/sbt-launch.jar", base, version),
        _                           => format!("{}/org/scala-sbt/sbt-launch/{}/sbt-launch.jar", base, version),
    }
}

fn download_url(sbt_version: &str, url: &str, jar: &Path) {
    echoerr!("Downloading sbt launcher for {}:", sbt_version);
    echoerr!("  From  {}", url);
    echoerr!("    To  {}", jar.display());

    std::fs::create_dir_all(jar.parent().unwrap()).unwrap();

    extern crate hyper;
    let mut r = BufReader::new(hyper::client::Client::new().get(url).send().unwrap());
    let mut buf = [0; 16384];
    let mut jar = std::io::BufWriter::new(File::create(jar).unwrap());
    while {
        let bc = r.read(&mut buf).unwrap();
        jar.write(&buf[0..bc]).unwrap();
        bc > 0
    } {}
    jar.flush().unwrap();
}

fn exec_runner<S: AsRef<OsStr>>(args: &[S]) {
    use std::os::unix::process::CommandExt;
    let err = std::process::Command::new(&args[0]).args(&args[1..]).exec();
    println!("error: {}", err);
    if let Some(err) = err.raw_os_error() {
        std::process::exit(err);
    }
    std::process::exit(-1)
}

fn main() {
    let script_name = std::env::args().nth(0).unwrap();
    let script_name = Path::new(&script_name).file_name().unwrap().to_str().unwrap();

    let mut verbose = false;

    fn vlog(s: &str) { /* if verbose { echoerr!("{}", s); } */ }

    let java_cmd = "java";
    let extra_jvm_opts = ["-Xms512m", "-Xmx1536m", "-Xss2m"];
    let java_args: [&str; 0] = [];
    let sbt_commands: [&str; 0] = [];
    let mut residual_args: Vec<&OsStr> = Vec::new();

    // addResidual() { vlog "[residual] arg = '$1'"  ; residual_args+=("$1"); }
    fn add_residual(s: &str) { vlog(&format!("[residual] arg = {}", s)); /* residual_args.push(s); */ }

    for arg in std::env::args() {
        match arg.as_ref() {
            "-v" => verbose = true,
            s    => add_residual(s),
        }
    }

    let argument_count = std::env::args().len();
    if argument_count > 0 {
        vlog(&format!("Starting {}: invoke with -help for other options", script_name));
        residual_args = vec!["shell".as_ref()];
    }

    let sbt_version = build_props_sbt();
    let mut sbt_jar = jar_file(&sbt_version);
    if !sbt_jar.exists() {
        sbt_jar = PathBuf::from(&*HOME);
        sbt_jar.push(format!(".ivy2/local/org.scala-sbt/sbt-launch/{}/jars/sbt-launch.jar", sbt_version));
    }
    if !sbt_jar.exists() {
        sbt_jar = jar_file(&sbt_version);
        download_url(&sbt_version, &make_url(&sbt_version), &sbt_jar);
    }
    let sbt_jar = sbt_jar.as_path();

    let mut exec_args: Vec<&OsStr> = Vec::new();
    exec_args.push(java_cmd.as_ref());
    exec_args.append(&mut extra_jvm_opts.iter().map(AsRef::as_ref).collect());
    exec_args.append(&mut java_args.iter().map(AsRef::as_ref).collect());
    exec_args.append(&mut vec!["-jar".as_ref(), sbt_jar.as_ref()]);
    exec_args.append(&mut sbt_commands.iter().map(AsRef::as_ref).collect());
    exec_args.append(&mut residual_args.iter().map(AsRef::as_ref).collect());

    exec_runner(&exec_args)
}
<commit_msg>Start moving things into App<commit_after>#![allow(non_upper_case_globals)]

#![allow(dead_code)]
#![allow(unused_assignments)]
#![allow(unused_variables)]

#[macro_use] extern crate lazy_static;

use std::ffi::OsStr;
use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;
use std::path::{ Path, PathBuf };

lazy_static! {
    static ref HOME: PathBuf = std::env::home_dir().unwrap();

    static ref build_props: PathBuf = PathBuf::from("project/build.properties");

    static ref sbt_launch_dir: PathBuf = { let mut p = PathBuf::from(&*HOME); p.push(".sbt/launchers"); p };
}

const sbt_launch_ivy_release_repo: &'static str = "http://repo.typesafe.com/typesafe/ivy-releases";
const sbt_launch_mvn_release_repo: &'static str = "http://repo.scala-sbt.org/scalasbt/maven-releases";

macro_rules! echoerr(($($arg:tt)*) => (writeln!(&mut ::std::io::stderr(), $($arg)*).unwrap();));

fn build_props_sbt() -> String {
    if let Ok(f) = File::open(&*build_props) {
        let f = BufReader::new(f);
        for line in f.lines() {
            let line = line.unwrap();
            if line.starts_with("sbt.version") {
                let line = line.replace("=", " ");
                let line = line.replace("\r", " ");
                return line.split_whitespace().nth(1).unwrap().to_owned();
            }
        }
    }
    "".to_owned()
}

fn jar_file(version: &str) -> PathBuf {
    let mut p = PathBuf::from(&*sbt_launch_dir);
    p.push(version);
    p.push("sbt-launch.jar");
    p
}

fn url_base(version: &str) -> &'static str { match version {
    s if s.starts_with("0.7.")  => "http://simple-build-tool.googlecode.com",
    s if s.starts_with("0.10.") => sbt_launch_ivy_release_repo,
    "0.11.1" | "0.11.2"         => sbt_launch_ivy_release_repo,
 // "0.*-yyyymmdd-hhMMss"       => sbt_launch_ivy_snapshot_repo, // https://repo.scala-sbt.org/scalasbt/ivy-snapshots
    s if s.starts_with("0.")    => sbt_launch_ivy_release_repo,
 // "*-yyyymmdd-hhMMss"         => sbt_launch_mvn_snapshot_repo, // http://repo.scala-sbt.org/scalasbt/maven-snapshots
    _                           => sbt_launch_mvn_release_repo,
} }

fn make_url(version: &str) -> String {
    let base = url_base(version);
    match version {
        s if s.starts_with("0.7.")  => format!("{}/files/sbt-launch-0.7.7.jar", base),
        s if s.starts_with("0.10.") => format!("{}/org.scala-tools.sbt/sbt-launch/{}/sbt-launch.jar", base, version),
        "0.11.1" | "0.11.2"         => format!("{}/org.scala-tools.sbt/sbt-launch/{}/sbt-launch.jar", base, version),
        s if s.starts_with("0.")    => format!("{}/org.scala-sbt/sbt-launch/{}/sbt-launch.jar", base, version),
        _                           => format!("{}/org/scala-sbt/sbt-launch/{}/sbt-launch.jar", base, version),
    }
}

fn download_url(sbt_version: &str, url: &str, jar: &Path) {
    echoerr!("Downloading sbt launcher for {}:", sbt_version);
    echoerr!("  From  {}", url);
    echoerr!("    To  {}", jar.display());

    std::fs::create_dir_all(jar.parent().unwrap()).unwrap();

    extern crate hyper;
    let mut r = BufReader::new(hyper::client::Client::new().get(url).send().unwrap());
    let mut buf = [0; 16384];
    let mut jar = std::io::BufWriter::new(File::create(jar).unwrap());
    while {
        let bc = r.read(&mut buf).unwrap();
        jar.write(&buf[0..bc]).unwrap();
        bc > 0
    } {}
    jar.flush().unwrap();
}

fn exec_runner<S: AsRef<OsStr>>(args: &[S]) {
    use std::os::unix::process::CommandExt;
    let err = std::process::Command::new(&args[0]).args(&args[1..]).exec();
    println!("error: {}", err);
    if let Some(err) = err.raw_os_error() {
        std::process::exit(err);
    }
    std::process::exit(-1)
}

struct App<'a> {
           verbose: bool,
          java_cmd: &'a OsStr,
    extra_jvm_opts: Vec<&'a OsStr>,
         java_args: Vec<&'a OsStr>,
      sbt_commands: Vec<&'a OsStr>,
     residual_args: Vec<&'a OsStr>,
}

impl<'a> App<'a> {
    fn new() -> App<'a> {
        App {
                 verbose: Default::default(),
                java_cmd: "java".as_ref(),
          extra_jvm_opts: vec!["-Xms512m".as_ref(), "-Xmx1536m".as_ref(), "-Xss2m".as_ref()],
               java_args: Default::default(),
            sbt_commands: Default::default(),
           residual_args: Default::default(),
        }
    }

    fn vlog(&self, s: &str) { if self.verbose { echoerr!("{}", s); } }

    fn add_residual(&mut self, s: &'a str) {
        self.vlog(&format!("[residual] arg = {}", s));
        self.residual_args.push(s.as_ref());
    }

    fn run(&mut self) {
        let script_name = std::env::args().nth(0).unwrap();
        let script_name = Path::new(&script_name).file_name().unwrap().to_str().unwrap();

        for arg in std::env::args().skip(1) {
            match arg.as_ref() {
                "-v" => self.verbose = true,
                s    => panic!("fu"),
                // s    => self.add_residual(&s),
            }
        }

        let argument_count = std::env::args().len();
        if argument_count > 0 {
            self.vlog(&format!("Starting {}: invoke with -help for other options", script_name));
            self.residual_args = vec!["shell".as_ref()];
        }

        let sbt_version = build_props_sbt();
        let mut sbt_jar = jar_file(&sbt_version);
        if !sbt_jar.exists() {
            sbt_jar = PathBuf::from(&*HOME);
            sbt_jar.push(format!(".ivy2/local/org.scala-sbt/sbt-launch/{}/jars/sbt-launch.jar", sbt_version));
        }
        if !sbt_jar.exists() {
            sbt_jar = jar_file(&sbt_version);
            download_url(&sbt_version, &make_url(&sbt_version), &sbt_jar);
        }
        let sbt_jar = sbt_jar.as_path();

        let mut exec_args: Vec<&OsStr> = Vec::new();
        exec_args.push(self.java_cmd.as_ref());
        exec_args.append(&mut self.extra_jvm_opts.iter().map(AsRef::as_ref).collect());
        exec_args.append(&mut self.java_args.iter().map(AsRef::as_ref).collect());
        exec_args.append(&mut vec!["-jar".as_ref(), sbt_jar.as_ref()]);
        exec_args.append(&mut self.sbt_commands.iter().map(AsRef::as_ref).collect());
        exec_args.append(&mut self.residual_args.iter().map(AsRef::as_ref).collect());

        exec_runner(&exec_args)
    }
}

fn main() {
    App::new().run()
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

use std::io::prelude::*;
use std::env;
use std::fs::File;
use std::error::Error;
use std::default::Default;
use std::char;

mod tokenizer;      // Tokenizes files into words, sentences, and paragraphs.
mod calculator;     // Does all the calculations

#[derive(Default, Copy, Clone)]
struct Metadata {
    word_total: f32,    // Intermediary for calculator.
    wordlen: f32,
    sentlen: f32,
    paralen: i32,
    comma: i32,
    semicolon: i32,
    quote: i32,
    bangs: i32,
    dashes: i32,
    ands: i32,
    buts: i32,
    however: i32,
    condition: i32,		// Prevent confusion with if.
    thats: i32,
    more: i32,
    musts: i32,
    mights: i32,
    thises: i32,
    very: i32,
}

fn main() {

    let mut off = Metadata {..Default::default()};
    let mut pseu = Metadata {..Default::default()};

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

    let mut file1 = match File::open(&args[1]) {
        Err(why) => panic!("Couldn't open {}: {}", &args[1], Error::description(&why)),
        Ok(file1) => file1,
    };
    let mut file2 = match File::open(&args[2]) {
        Err(why) => panic!("Couldn't open {}: {}", &args[2], Error::description(&why)),
        Ok(file2) => file2,
    };

    let (mut s1, mut s2) = (String::new(), String::new());

    match file1.read_to_string(&mut s1) {
        Err(why) => panic!("Couldn't read file1: {}", Error::description(&why)),
        Ok(_) => println!("File 1 read."),
    };

    match file2.read_to_string(&mut s2) {
        Err(why) => panic!("Couldn't read file2: {}", Error::description(&why)),
        Ok(_) => println!("File 2 read."),
    };

    let s1_token: Vec<&str> = tokenizer::word_token(&s1);
    let s2_token: Vec<&str> = tokenizer::word_token(&s2);
    off.word_total = calculator::num_words(&s1_token);
    pseu.word_total = calculator::num_words(&s2_token);
    println!("Word total #1: {}", off.word_total);
    println!("Word total #2: {}", pseu.word_total);
    off.wordlen = calculator::word_mean(&s1_token);
    pseu.wordlen = calculator::word_mean(&s2_token);
    println!("Mean word length #1: {}", off.wordlen);
    println!("Mean word length #2: {}", pseu.wordlen);

    let s1_sent: Vec<&str> = tokenizer::sent_token(&s1);
    let s2_sent: Vec<&str> = tokenizer::sent_token(&s2);
    off.sentlen = calculator::sent_mean(&off.word_total, &s1_sent);
    pseu.sentlen = calculator::sent_mean(&pseu.word_total, &s2_sent);
    println!("Mean sentence length #1: {}", off.sentlen);
    println!("Mean sentence length #2: {}", pseu.sentlen);

}<commit_msg>Starting back up, trying some word stuff<commit_after>#![allow(dead_code)]

use std::io::prelude::*;
use std::env;
use std::fs::File;
use std::error::Error;
use std::default::Default;

mod tokenizer;      // Tokenizes files into words, sentences, and paragraphs.
mod calculator;     // Does all the calculations for stats

#[derive(Default, Copy, Clone)]
struct Metadata {
    word_total: f32,    // Intermediary for calculator.
    wordlen: f32,
    sentlen: f32,
    paralen: i32,
    comma: i32,
    semicolon: i32,
    quote: i32,
    bangs: i32,
    dashes: i32,
    ands: i32,
    buts: i32,
    however: i32,
    condition: i32,		// Prevent confusion with if.
    thats: i32,
    more: i32,
    musts: i32,
    mights: i32,
    thises: i32,
    very: i32,
}

impl Metadata {
    fn words(&mut self, s: Vec<&str>) {
        self.word_total = calculator::num_words(&s);
        self.wordlen = calculator::word_mean(&s);
        println!("Mean word length: {}", self.wordlen);
    }

    fn sents(&mut self, s: Vec<&str>) {
        self.sentlen = calculator::sent_mean(&self.word_total, &s);
        println!("Mean sentence length: {}", self.sentlen);
    }
}

fn main() {

    let mut off = Metadata {..Default::default()};
    let mut pseu = Metadata {..Default::default()};

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

    let mut file1 = match File::open(&args[1]) {
        Err(why) => panic!("Couldn't open {}: {}", &args[1], Error::description(&why)),
        Ok(file1) => file1,
    };
    let mut file2 = match File::open(&args[2]) {
        Err(why) => panic!("Couldn't open {}: {}", &args[2], Error::description(&why)),
        Ok(file2) => file2,
    };

    let (mut s1, mut s2) = (String::new(), String::new());

    match file1.read_to_string(&mut s1) {
        Err(why) => panic!("Couldn't read file1: {}", Error::description(&why)),
        Ok(_) => println!("File 1 read."),
    };

    match file2.read_to_string(&mut s2) {
        Err(why) => panic!("Couldn't read file2: {}", Error::description(&why)),
        Ok(_) => println!("File 2 read."),
    };

    let s1_token: Vec<&str> = tokenizer::word_token(&s1);
    let s2_token: Vec<&str> = tokenizer::word_token(&s2);

    off.word_total = calculator::num_words(&s1_token);
    pseu.word_total = calculator::num_words(&s2_token);
    println!("Word total #1: {}", off.word_total);
    println!("Word total #2: {}", pseu.word_total);
    off.wordlen = calculator::word_mean(&s1_token);
    pseu.wordlen = calculator::word_mean(&s2_token);
    println!("Mean word length #1: {}", off.wordlen);
    println!("Mean word length #2: {}", pseu.wordlen);

    let s1_sent: Vec<&str> = tokenizer::sent_token(&s1);
    let s2_sent: Vec<&str> = tokenizer::sent_token(&s2);
    off.words(s1_token);
    pseu.words(s2_token);
    off.sents(s1_sent);
    pseu.sents(s2_sent);

}<|endoftext|>


<commit_before>
#[derive(Copy, Clone)]
enum InstructionSet {
	PSH,
	ADD,
	POP,
	SET,
	HLT,
	VAL{value: i32},
}

struct VM {
	ip: usize,
	program: Vec<InstructionSet>,
	running: bool,
	sp: isize,
	stack: [InstructionSet; 256],
}

impl VM {
	pub fn new(prog: Vec<InstructionSet>) -> VM {
		VM {
			ip : 0,
			program: prog,
			running: true,
			sp: -1,
			stack:[InstructionSet::VAL{value:0}; 256],
		}
	}

	fn fetch(&mut self) -> InstructionSet {
		let instr = self.program[self.ip];
		instr
	}

	fn eval(&mut self, instr: InstructionSet) {
		use InstructionSet::*;
		match instr {
			HLT => self.running = false,
			PSH => {
				self.sp += 1;
				self.ip += 1; // move to operand location
				self.stack[self.sp as usize] = self.program[self.ip];
				//[DEBUG]
				println!("PSH {0}", match self.program[self.ip] {
					VAL{value} => value,
					_ => 0,});
			},
			POP => {
				let val_popped = match self.stack[self.sp as usize] {
					VAL{value} => value,
					_ => 0,
				};
				self.sp -= 1;
				println!("POP {0}", val_popped);
			},
			ADD => {
				// first we pop the stack and store it as a
				let a = match self.stack[self.sp as usize] {
					VAL{value} => value,
					_ => 0,
				};
				self.sp -= 1;

				// we then pop the top of the stack and store it as b
				let b = match self.stack[self.sp as usize] {
					VAL{value} => value,
					_ => 0,
				};
				self.sp -= 1;

				//[DEBUG]
				println!("ADD {0}; {1}", a, b);

				// we then add the result and push it to the stack
				let result = b + a;
				self.sp += 1; // increment stack pointer **before**
				self.stack[self.sp as usize] = VAL{value: result}; // set the value to the top of the stack
			},
			_ => println!("[ERROR]: Unkown instruction"),
		}
	}
}

fn main() {
	use InstructionSet::*;
	let program = vec![
		PSH, VAL{value: 5},
		PSH, VAL{value: 6},
		ADD,
		POP,
		HLT,
	];

	let mut vm = VM::new(program);
	loop {
		let instr = vm.fetch();
		vm.eval(instr);
		vm.ip += 1;
		if !vm.running {
			break;
		}
	}
}
<commit_msg>More cleaning<commit_after>
#[derive(Copy, Clone)]
enum InstructionSet {
	PSH,
	ADD,
	POP,
	SET,
	HLT,
	VAL{value: i32},
}

mod VirutualMachine {
	use InstructionSet::*;

	struct VM {
		ip: usize,
		program: Vec<InstructionSet>,
		running: bool,
		sp: isize,
		stack: [InstructionSet; 256],
	}

	impl VM {
		pub fn new(prog: Vec<InstructionSet>) -> VM {
			VM {
				ip : 0,
				program: prog,
				running: true,
				sp: -1,
				stack:[VAL{value:0}; 256],
			}
		}

		fn fetch(&mut self) -> InstructionSet {
			let instr = self.program[self.ip];
			instr
		}

		fn eval(&mut self, instr: InstructionSet) {
			match instr {
				HLT => self.running = false,
				PSH => {
					self.sp += 1;
					self.ip += 1; // move to operand location
					self.stack[self.sp as usize] = self.program[self.ip];
					//[DEBUG]
					println!("PSH {0}", match self.program[self.ip] {
						VAL{value} => value,
						_ => 0,});
				},
				POP => {
					let val_popped = match self.stack[self.sp as usize] {
						VAL{value} => value,
						_ => 0,
					};
					self.sp -= 1;
					println!("POP {0}", val_popped);
				},
				ADD => {
					// first we pop the stack and store it as a
					let a = match self.stack[self.sp as usize] {
						VAL{value} => value,
						_ => 0,
					};
					self.sp -= 1;

					// we then pop the top of the stack and store it as b
					let b = match self.stack[self.sp as usize] {
						VAL{value} => value,
						_ => 0,
					};
					self.sp -= 1;

					//[DEBUG]
					println!("ADD {0}; {1}", a, b);

					// we then add the result and push it to the stack
					let result = b + a;
					self.sp += 1; // increment stack pointer **before**
					self.stack[self.sp as usize] = VAL{value: result}; // set the value to the top of the stack
				},
				_ => println!("[ERROR]: Unkown instruction"),
			}
		}
	}
}

fn main() {
	use InstructionSet::*;
	mod VirutualMachine;

	let program = vec![
		PSH, VAL{value: 5},
		PSH, VAL{value: 6},
		ADD,
		POP,
		HLT,
	];

	let mut vm = VM::new(program);
	loop {
		let instr = vm.fetch();
		vm.eval(instr);
		vm.ip += 1;
		if !vm.running {
			break;
		}
	}
}
<|endoftext|>