<commit_before>#![cfg_attr(test, allow(dead_code))]
#![feature(collections, env, libc, old_io, os)]
#![cfg_attr(not(windows), feature(old_path, fs, io, std_misc))]

extern crate libc;

mod args;
mod matching;
mod screen;
#[cfg(not(windows))] mod ansi;

use std::env;
use std::old_io;
use std::cmp::min;
use screen::Screen;
use screen::Key;
use screen::Key::*;
use self::SearchState::*;

fn main() {
    let args = match args::parse_args() {
        Some(args) => args,
        None => {
            env::set_exit_status(1);
            return;
        },
    };

    if args.help { return; }

    let choices = read_choices();
    let initial_search = args.initial_search.clone();
    let choices = choices.iter().map(|x| &x[..]).collect::<Vec<&str>>();
    if args.use_first {
        let matches = matching::compute_matches(&choices, &initial_search);
        println!("{}", matches.get(0).unwrap_or(&""));
        return;
    } else {
        event_loop(&choices, &initial_search);
    }
}

fn event_loop(choices: &[&str], initial_search: &str) {
    let mut search = Search::new(choices, initial_search.to_string());
    let mut screen = Screen::open_screen();

    loop {
        search.recompute_matches();

        match search.state {
            InProgress => draw_screen(&mut screen, &search),
            _ => break,
        }

        let keys = screen.get_buffered_keys();
        for key in keys.iter() {
            handle_key(&mut search, key, screen.visible_choices);
        }
    }

    screen.move_cursor_to_bottom();
    println!("{}", search.get_selection());
}

fn handle_key(search: &mut Search, key: &Key, visible_choices: u16) {
    match *key {
        Char(x) => search.append(x),
        Backspace => search.backspace(),
        Control('h') => search.backspace(),
        Control('w') => search.delete_word(),
        Control('u') => search.clear_query(),
        Control('c') => search.cancel(),
        Control('g') => search.cancel(),
        Control('n') => search.down(visible_choices),
        Control('p') => search.up(visible_choices),
        Enter => search.done(),
        _ => {}
    }
}

struct Search<'a> {
    choices: &'a [&'a str],
    query: String,
    matches: Vec<&'a str>,
    stale: bool,
    index: usize,
    state: SearchState,
}

#[derive(PartialEq, Eq)]
enum SearchState {
    InProgress,
    Done,
    Canceled,
}

impl<'a> Search<'a> {
    fn new(choices: &'a [&'a str], initial_search: String) -> Search<'a> {
        let matches = choices.to_vec();
        Search {
            choices: choices,
            query: initial_search,
            matches: matches,
            stale: true,
            index: 0,
            state: InProgress,
        }
    }

    fn up(&mut self, visible_choices: u16) {
        let limit = min(visible_choices as usize - 1, self.matches.len() - 1);
        self.index = if self.index == 0 { limit } else { self.index - 1 };
    }

    fn down(&mut self, visible_choices: u16) {
        let limit = min(visible_choices as usize - 1, self.matches.len() - 1);
        self.index = if self.index == limit { 0 } else { self.index + 1 }
    }

    fn backspace(&mut self) {
        self.query.pop();
        self.stale = true;
        self.index = 0;
        self.matches = self.choices.to_vec();
    }

    fn delete_word(&mut self) {
        self.stale = true;
        delete_last_word(&mut self.query);
        self.matches = self.choices.to_vec();
    }

    fn append(&mut self, c: char) {
        self.query.push(c);
        self.stale = true;
        self.index = 0;
    }

    fn clear_query(&mut self) {
        self.query.clear();
        self.matches = self.choices.to_vec();
    }

    fn recompute_matches(&mut self) {
        if self.stale {
            self.matches = matching::compute_matches(&self.matches, &self.query);
            self.stale = false;
        }
    }

    fn get_selection(&mut self) -> String {
        if self.state == Canceled {
            "".to_string()
        } else {
            self.recompute_matches();
            self.matches.get(self.index).unwrap_or(&"").to_string()
        }
    }

    fn cancel(&mut self) {
        self.state = Canceled
    }

    fn done(&mut self) {
        self.state = Done
    }
}

fn draw_screen(screen: &mut Screen, search: &Search) {
    screen.hide_cursor();
    screen.blank_screen();
    screen.write(&format!("> {} ({}/{} choices)\n", search.query, search.matches.len(), search.choices.len()));

    print_matches(screen, &search.matches, &search.query, search.index);

    let start = screen.start_line;
    screen.move_cursor(start, 2 + search.query.len() as u16);
    screen.show_cursor();
}

fn print_matches(screen: &mut Screen, matches: &[&str], query: &str, index: usize) {
    let mut i = 1;
    for choice in matches.iter() {
        let indices = matching::visual_score(choice, query);
        print_match(choice, &indices, &mut |s, highlight| {
            if i == index + 1 {
                if highlight { screen.write_red_inverted(s); } else { screen.write_inverted(s); }
            } else {
                if highlight { screen.write_red(s); } else { screen.write(s); }
            }
        });
        if i >= screen.visible_choices as usize {
            return;
        } else {
            screen.write("\n");
        }
        i += 1;
    }
}

fn print_match(choice: &str, indices: &[usize], writer: &mut FnMut(&str, bool)) {
    let mut last_idx = 0;
    let len = choice.chars().collect::<Vec<char>>().len();
    for &idx in indices {
        writer(&choice.slice_chars(last_idx, idx), false);
        writer(&choice.slice_chars(idx, idx + 1), true);
        last_idx = idx + 1;
    }
    writer(&choice.slice_chars(last_idx, len), false);
}

fn read_choices() -> Vec<String> {
    let mut stdin = old_io::stdio::stdin();
    let mut lines = Vec::new();

    while let Ok(mut s) = stdin.read_line() {
        trim(&mut s);
        lines.push(s);
    }

    lines
}

pub fn trim(s: &mut String) {
    while let Some(x) = s.pop() {
        if x != '\n' {
            s.push(x);
            return;
        }
    }
}

fn delete_last_word(s: &mut String) {
    let mut deleted_something = false;
    while let Some(x) = s.pop() {
        if x == ' ' {
            if deleted_something {
                s.push(x);
                return;
            }
        } else {
            deleted_something = true;
        }
    }
}

#[test]
fn trim_test() {
    fn should_become(before: &str, after: &str) {
        let mut x = before.to_string();
        trim(&mut x);
        assert_eq!(after.to_string(), x);
    }
    should_become("", "");
    should_become("\n", "");
    should_become("\n\n", "");
    should_become("asdf", "asdf");
    should_become("asdf\n", "asdf");
    should_become("asdf\nasdf\n", "asdf\nasdf");
}

#[test]
fn delete_word_test() {
    fn should_become(before: &str, after: &str) {
        let mut x = before.to_string();
        delete_last_word(&mut x);
        assert_eq!(after.to_string(), x);
    }
    should_become("", "");
    should_become("a", "");
    should_become("asdf", "");
    should_become("asdf asdf asdf", "asdf asdf ");
    should_become("asdf asdf asdf ", "asdf asdf ");
    should_become("asdf asdf asdf  ", "asdf asdf ");
}
<commit_msg>Truncate excessively long lines<commit_after>#![cfg_attr(test, allow(dead_code))]
#![feature(collections, env, libc, old_io, os)]
#![cfg_attr(not(windows), feature(old_path, fs, io, std_misc))]

extern crate libc;

mod args;
mod matching;
mod screen;
#[cfg(not(windows))] mod ansi;

use std::env;
use std::old_io;
use std::cmp::min;
use screen::Screen;
use screen::Key;
use screen::Key::*;
use self::SearchState::*;

fn main() {
    let args = match args::parse_args() {
        Some(args) => args,
        None => {
            env::set_exit_status(1);
            return;
        },
    };

    if args.help { return; }

    let choices = read_choices();
    let initial_search = args.initial_search.clone();
    let choices = choices.iter().map(|x| &x[..]).collect::<Vec<&str>>();
    if args.use_first {
        let matches = matching::compute_matches(&choices, &initial_search);
        println!("{}", matches.get(0).unwrap_or(&""));
        return;
    } else {
        event_loop(&choices, &initial_search);
    }
}

fn event_loop(choices: &[&str], initial_search: &str) {
    let mut search = Search::new(choices, initial_search.to_string());
    let mut screen = Screen::open_screen();

    loop {
        search.recompute_matches();

        match search.state {
            InProgress => draw_screen(&mut screen, &search),
            _ => break,
        }

        let keys = screen.get_buffered_keys();
        for key in keys.iter() {
            handle_key(&mut search, key, screen.visible_choices);
        }
    }

    screen.move_cursor_to_bottom();
    println!("{}", search.get_selection());
}

fn handle_key(search: &mut Search, key: &Key, visible_choices: u16) {
    match *key {
        Char(x) => search.append(x),
        Backspace => search.backspace(),
        Control('h') => search.backspace(),
        Control('w') => search.delete_word(),
        Control('u') => search.clear_query(),
        Control('c') => search.cancel(),
        Control('g') => search.cancel(),
        Control('n') => search.down(visible_choices),
        Control('p') => search.up(visible_choices),
        Enter => search.done(),
        _ => {}
    }
}

struct Search<'a> {
    choices: &'a [&'a str],
    query: String,
    matches: Vec<&'a str>,
    stale: bool,
    index: usize,
    state: SearchState,
}

#[derive(PartialEq, Eq)]
enum SearchState {
    InProgress,
    Done,
    Canceled,
}

impl<'a> Search<'a> {
    fn new(choices: &'a [&'a str], initial_search: String) -> Search<'a> {
        let matches = choices.to_vec();
        Search {
            choices: choices,
            query: initial_search,
            matches: matches,
            stale: true,
            index: 0,
            state: InProgress,
        }
    }

    fn up(&mut self, visible_choices: u16) {
        let limit = min(visible_choices as usize - 1, self.matches.len() - 1);
        self.index = if self.index == 0 { limit } else { self.index - 1 };
    }

    fn down(&mut self, visible_choices: u16) {
        let limit = min(visible_choices as usize - 1, self.matches.len() - 1);
        self.index = if self.index == limit { 0 } else { self.index + 1 }
    }

    fn backspace(&mut self) {
        self.query.pop();
        self.stale = true;
        self.index = 0;
        self.matches = self.choices.to_vec();
    }

    fn delete_word(&mut self) {
        self.stale = true;
        delete_last_word(&mut self.query);
        self.matches = self.choices.to_vec();
    }

    fn append(&mut self, c: char) {
        self.query.push(c);
        self.stale = true;
        self.index = 0;
    }

    fn clear_query(&mut self) {
        self.query.clear();
        self.matches = self.choices.to_vec();
    }

    fn recompute_matches(&mut self) {
        if self.stale {
            self.matches = matching::compute_matches(&self.matches, &self.query);
            self.stale = false;
        }
    }

    fn get_selection(&mut self) -> String {
        if self.state == Canceled {
            "".to_string()
        } else {
            self.recompute_matches();
            self.matches.get(self.index).unwrap_or(&"").to_string()
        }
    }

    fn cancel(&mut self) {
        self.state = Canceled
    }

    fn done(&mut self) {
        self.state = Done
    }
}

fn draw_screen(screen: &mut Screen, search: &Search) {
    screen.hide_cursor();
    screen.blank_screen();
    screen.write(&format!("> {} ({}/{} choices)\n", search.query, search.matches.len(), search.choices.len()));

    print_matches(screen, &search.matches, &search.query, search.index);

    let start = screen.start_line;
    screen.move_cursor(start, 2 + search.query.len() as u16);
    screen.show_cursor();
}

fn print_matches(screen: &mut Screen, matches: &[&str], query: &str, index: usize) {
    let mut i = 1;
    for choice in matches.iter() {
        let indices = matching::visual_score(choice, query);
        let max_width = screen.width;
        print_match(choice, &indices, max_width, &mut |s, highlight| {
            if i == index + 1 {
                if highlight { screen.write_red_inverted(s); } else { screen.write_inverted(s); }
            } else {
                if highlight { screen.write_red(s); } else { screen.write(s); }
            }
        });
        if i >= screen.visible_choices as usize {
            return;
        } else {
            screen.write("\n");
        }
        i += 1;
    }
}

fn print_match(choice: &str, indices: &[usize], max_width: u16, writer: &mut FnMut(&str, bool)) {
    let chars_in_choice = choice.chars().collect::<Vec<char>>().len();
    let chars_to_draw = min(chars_in_choice, max_width as usize);
    let mut last_idx = 0;
    for &idx in indices {
        let idx = min(idx, chars_to_draw);
        if last_idx >= chars_to_draw {
            return;
        }
        writer(&choice.slice_chars(last_idx, idx), false);
        if idx == chars_to_draw { return }
        writer(&choice.slice_chars(idx, idx + 1), true);
        last_idx = idx + 1;
    }
    writer(&choice.slice_chars(last_idx, chars_to_draw), false);
}

fn read_choices() -> Vec<String> {
    let mut stdin = old_io::stdio::stdin();
    let mut lines = Vec::new();

    while let Ok(mut s) = stdin.read_line() {
        trim(&mut s);
        lines.push(s);
    }

    lines
}

pub fn trim(s: &mut String) {
    while let Some(x) = s.pop() {
        if x != '\n' {
            s.push(x);
            return;
        }
    }
}

fn delete_last_word(s: &mut String) {
    let mut deleted_something = false;
    while let Some(x) = s.pop() {
        if x == ' ' {
            if deleted_something {
                s.push(x);
                return;
            }
        } else {
            deleted_something = true;
        }
    }
}

#[test]
fn trim_test() {
    fn should_become(before: &str, after: &str) {
        let mut x = before.to_string();
        trim(&mut x);
        assert_eq!(after.to_string(), x);
    }
    should_become("", "");
    should_become("\n", "");
    should_become("\n\n", "");
    should_become("asdf", "asdf");
    should_become("asdf\n", "asdf");
    should_become("asdf\nasdf\n", "asdf\nasdf");
}

#[test]
fn delete_word_test() {
    fn should_become(before: &str, after: &str) {
        let mut x = before.to_string();
        delete_last_word(&mut x);
        assert_eq!(after.to_string(), x);
    }
    should_become("", "");
    should_become("a", "");
    should_become("asdf", "");
    should_become("asdf asdf asdf", "asdf asdf ");
    should_become("asdf asdf asdf ", "asdf asdf ");
    should_become("asdf asdf asdf  ", "asdf asdf ");
}
<|endoftext|>


<commit_before>//Hello Rusty!

struct Point{
	x: i32, //int 32
	y: i32
}

fn main() {
    println!("Hello, world!");

    basic_if_example();
    switch_example();
    for_loop_example();
    while_loop_example();
    infinite_loop_example();
}

fn basic_if_example(){
    let name = "rusty";
    //this is kind of cool, hmm
    let is_rusty = if name == "rusty"{
        true
    } else{
        false
    };

    if is_rusty {
        println!("Hi Rusty!");
    }
}

fn switch_example(){
    let x = 5;
    let number = match x {
        1 => "one",
        2 => "two",
        3 => "three",
        4 => "four",
        5 => "five",
        _ => "something else",
    };
    println!("number = {}", number);
}

fn for_loop_example(){
    println!("running the for loop...");
    for x in 0..10 {
        println!("x = {}", x);
        match x{
            1 => println!("one for the money"),
            2 => println!("two for the show"),
            3 => println!("three to get ready"),
            4 => println!("four to go!"),
            5 => println!("Johnny Five is alive!"),
            _ => println!(""),
        }

        let pt = Point{x: x, y: x*2};
        println!("pt.x = {}, pt.y = {}", pt.x, pt.y);
    }
}

fn while_loop_example(){
    println!("running while loop...");
    let mut aa = 10;
    while aa > 0{
        aa -= 1;
        println!("{}", aa);
    }
}

fn infinite_loop_example(){
    println!("running infinite loop...");
    let mut count = 0u32;
    loop {
        count += 1;
        println!("{}", count);
        if count == 3{
            println!("THREE!");
        } else if count == 5{
            println!("DONE!");
            break;
        }
    }
}<commit_msg>adds some more play code<commit_after>//Hello Rusty!

struct Point{
	x: i32, //int 32
	y: i32
}

fn main() {
    println!("Hello, world!");

    basic_variables();
    basic_if_example();
    switch_example();
    for_loop_example();
    while_loop_example();
    infinite_loop_example();
    we_call_a_function();
}

fn basic_variables(){
    println!("using basic variables...");
    let (x, y, z) = (1, 3, 5);
    println!("x = {}, y = {}, z = {}", x, y, z);

    //using a data type
    let xx: i32 = 5;
    println!("xx = {}", xx);

    let name: &str = "peter";
    println!("name = {}", name);

    //using a mutable type
    //without the 'mut' keyword it throws an error on reassignment
    let mut yy = 5; // mut yy: i32
    if yy == 5{ //if we don't read/do something with it...it throws a warning
        yy = 10;
    }
    println!("yy = {}", yy);

    //tuple: ordered list of a fixed size
    let tuple = ("Frank", "Tom", "Norm");
    let f = tuple.0;
    println!("f = {}", f);
}

fn basic_if_example(){
    println!("using basic if statement...");
    let name = "rusty";
    //this is kind of cool, hmm
    let is_rusty = if name == "rusty"{
        true
    } else{
        false
    };

    if is_rusty {
        println!("Hi Rusty!");
    }
}

fn switch_example(){
    let x = 5;
    let number = match x {
        1 => "one",
        2 => "two",
        3 => "three",
        4 => "four",
        5 => "five",
        _ => "something else",
    };
    println!("number = {}", number);
}

fn for_loop_example(){
    println!("running the for loop...");
    for x in 0..10 {
        println!("x = {}", x);
        match x{
            1 => println!("one for the money"),
            2 => println!("two for the show"),
            3 => println!("three to get ready"),
            4 => println!("four to go!"),
            5 => println!("Johnny Five is alive!"),
            _ => println!(""),
        }

        let pt = Point{x: x, y: x*2};
        println!("pt.x = {}, pt.y = {}", pt.x, pt.y);
    }
}

fn while_loop_example(){
    println!("running while loop...");
    let mut aa = 10;
    while aa > 0{
        aa -= 1;
        println!("{}", aa);
    }
}

fn infinite_loop_example(){
    println!("running infinite loop...");
    let mut count = 0u32;
    loop {
        count += 1;
        println!("{}", count);
        if count == 3{
            println!("THREE!");
        } else if count == 5{
            println!("DONE!");
            break;
        }
    }
}

fn we_call_a_function(){
    println!("We call a function...");
    let a = foo(42);
    println!("a = {}", a);

    void_function();
}

//this function returns a value
fn foo(x: i32) -> i32 {
    return x;
}

fn void_function() {
    println!("calling a function that doesn't return anything");
}<|endoftext|>


<commit_before>extern crate arguments;
extern crate sqlite;
extern crate toml;

use std::path::Path;

const USAGE: &'static str = "
Usage: streamer [options]

Options:
    --database <path>        SQLite3 database (required).
    --table <name>           Table containing area estimates (required).

    --help                   Display this message.
";

macro_rules! raise(
    ($error:expr) => (return Err(Box::new($error)));
    ($($arg:tt)*) => (raise!(format!($($arg)*)));
);

macro_rules! ok(
    ($result:expr) => (match $result {
        Ok(result) => result,
        Err(error) => raise!(error),
    });
);

pub type Error = Box<std::fmt::Display>;
pub type Result<T> = std::result::Result<T, Error>;

fn main() {
    start().unwrap_or_else(|error| fail(error));
}

fn start() -> Result<()> {
    let arguments = ok!(arguments::parse(std::env::args()));

    if arguments.get::<bool>("help").unwrap_or(false) {
        help();
    }

    let _database = match arguments.get::<String>("database") {
        Some(ref database) => ok!(sqlite::open(&Path::new(database))),
        _ => raise!("a database filename is required"),
    };

    Ok(())
}

fn fail(error: Error) -> ! {
    use std::io::{stderr, Write};
    stderr().write_all(format!("Error: {}.\n", &*error).as_bytes()).unwrap();
    std::process::exit(1);
}

fn help() -> ! {
    println!("{}", USAGE.trim());
    std::process::exit(0);
}
<commit_msg>Open multiple databases<commit_after>extern crate arguments;
extern crate sqlite;
extern crate toml;

use std::path::Path;

const USAGE: &'static str = "
Usage: streamer [options] <database>...

Options:
    --help                   Display this message.
";

macro_rules! raise(
    ($error:expr) => (return Err(Box::new($error)));
    ($($arg:tt)*) => (raise!(format!($($arg)*)));
);

macro_rules! ok(
    ($result:expr) => (match $result {
        Ok(result) => result,
        Err(error) => raise!(error),
    });
);

pub type Error = Box<std::fmt::Display>;
pub type Result<T> = std::result::Result<T, Error>;

fn main() {
    start().unwrap_or_else(|error| fail(error));
}

fn start() -> Result<()> {
    let arguments = ok!(arguments::parse(std::env::args()));

    if arguments.get::<bool>("help").unwrap_or(false) {
        help();
    }

    let mut databases = vec![];
    for ref path in arguments.orphans.iter() {
        let path = Path::new(path);
        if std::fs::metadata(path).is_err() {
            raise!("the database {:?} does not exist", path);
        }
        databases.push(ok!(sqlite::open(path)));
    }
    if databases.is_empty() {
        raise!("at least one database is required");
    }

    Ok(())
}

fn help() -> ! {
    println!("{}", USAGE.trim());
    std::process::exit(0);
}

fn fail(error: Error) -> ! {
    use std::io::{stderr, Write};
    stderr().write_all(format!("Error: {}.\n", &*error).as_bytes()).unwrap();
    std::process::exit(1);
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate lazy_static;
extern crate capnp;
extern crate capnp_rpc;
extern crate cassandra;

use std::collections::HashMap;
use capnp::capability::{Server};
use capnp_rpc::ez_rpc::EzRpcServer;
use cassandra::*;

pub mod killranswers_capnp {
  include!(concat!(env!("OUT_DIR"), "/killranswers_capnp.rs"));
}

static CREATE_USER : &'static str = "insert into user (user_id), values (?)";

lazy_static! {

}

use killranswers_capnp::killr_answers;

struct KillrAnswersImpl;

impl killr_answers::Server for KillrAnswersImpl {
    // fn ask(&mut self, mut context: killr_answers::AskContext) {
    //     println!("Asking");
    // }
    fn register_user(&mut self, mut context: killr_answers::RegisterUserContext) {
        context.done();
    }

}

fn main() {
    println!("Starting up...");
    let rpc_server = EzRpcServer::new("127.0.0.1:6000").unwrap();
    let ka = Box::new(killr_answers::ServerDispatch { server : Box::new(KillrAnswersImpl)});
    //
    rpc_server.serve(ka);

    println!("Done");
}
<commit_msg>helpful note<commit_after>#[macro_use]
extern crate lazy_static;
extern crate capnp;
extern crate capnp_rpc;
extern crate cassandra;

use std::collections::HashMap;
use capnp::capability::{Server};
use capnp_rpc::ez_rpc::EzRpcServer;
use cassandra::*;

// this is generated automatically as part of the build process
// see build.rs
pub mod killranswers_capnp {
  include!(concat!(env!("OUT_DIR"), "/killranswers_capnp.rs"));
}
use killranswers_capnp::killr_answers;

static CREATE_USER : &'static str = "insert into user (user_id), values (?)";

lazy_static! {

}

struct KillrAnswersImpl;

impl killr_answers::Server for KillrAnswersImpl {
    // fn ask(&mut self, mut context: killr_answers::AskContext) {
    //     println!("Asking");
    // }
    fn register_user(&mut self, mut context: killr_answers::RegisterUserContext) {
        context.done();
    }

}

fn main() {
    println!("Starting up...");
    let rpc_server = EzRpcServer::new("127.0.0.1:6000").unwrap();
    let ka = Box::new(killr_answers::ServerDispatch { server : Box::new(KillrAnswersImpl)});
    //
    rpc_server.serve(ka);

    println!("Done");
}
<|endoftext|>


<commit_before>use std::env;

extern crate serial;

extern crate lora_driver;
use lora_driver::RadioConfig;
use lora_driver::Driver;
use lora_driver::RadioMode;

fn main() {

	// Get args that were passed
	let args: Vec<String> = env::args().collect();
	let platform = &args[1];
	let send_recv = &args[2];
	let mut passed_string = String::new();
	match args.len() {
		4 => {passed_string.push_str(args[3].as_str());},
		_ => {}
	}

	let mut e23_driver;
	let mut testconfig = RadioConfig::new();

	match &platform[..] {
		"vocore" => {
						e23_driver = Driver::new(23,24,26, "/dev/ttyS0");
						//set our serial rate to 57600 as well
						e23_driver.set_tty_params(
							serial::Baud115200,
							serial::Bits8,
							serial::ParityNone,
							serial::Stop1,
							serial::FlowNone
						);
						e23_driver.set_tty_baud(serial::Baud57600);
						testconfig.set_serial_rate("57600");
					}
		"chip" => {
						e23_driver = Driver::new(1013,1015,1017, "/dev/ttyS0");
						e23_driver.set_tty_params(
							serial::Baud115200,
							serial::Bits8,
							serial::ParityNone,
							serial::Stop1,
							serial::FlowNone
						);
						testconfig.set_serial_rate("115200");
				  }
		_ => panic!("Please enter either 'vocore' or 'chip'")
	}
	// we want it to be a mutable driver because we will be changing fields as we go.
	//let mut e23_driver = Driver::new(1013,1015,1017, "/dev/ttyS0"); //Pins for C.H.I.P.
	//let mut e23_driver = Driver::new(23,24,26, "/dev/ttyS0"); //Pins for Vocore.
	// Bring up our serial device with defaults

	testconfig.set_transmit_power("20dBm");
	testconfig.set_air_rate("1k");
	testconfig.set_address("FFFF"); // Channel 0
	e23_driver.set_mode(RadioMode::General);

	//let (m0_pin, m1_pin, aux_pin) = e23_driver.get_control_gpio_pins();
	//println!("M0: {} M1: {} AUX: {}", m0_pin, m1_pin, aux_pin);

	match &send_recv[..] {
		"r" => {
			// Recieve mode
			e23_driver.write_config(testconfig); // Write after change
			//let mut buffer: Vec<u8> = vec![0;256]; //initialize buffer of zeros
			println!("Waiting to receive from the radio");
			let packet = e23_driver.receive_packet();
			println!("Received a packet {} bytes long", packet.len());
			println!("{}",String::from_utf8(packet).unwrap());
			//println!("{:?}",packet);
		}
		"s" => {
			// Send mode
			e23_driver.write_config(testconfig); // Write after change
			//let send_buf: Vec<u8> = vec![0;256];
			let send_string = passed_string.clone();
			//let send_string = String::from("This is a test of how long a message can get. I should be able to keep typing and the entire packet should be sent.");
			let send_buf = send_string.into_bytes();
			//let send_buf: Vec<u8> = vec![255;116];
			e23_driver.send_packet(&send_buf);
		}
		_ => {
			panic!("Call with either 'r' or 's'");
		}
	}

	/*
	//Send some data
	let mut packet: Vec<u8> = vec![0; 10]; // create a vector of 256 bytes
	e23_driver.send_packet(&packet);
	e23_driver.receive_packet(&mut packet);
	*/

}
<commit_msg>Fixed a typo from me reading upside down<commit_after>use std::env;

extern crate serial;

extern crate lora_driver;
use lora_driver::RadioConfig;
use lora_driver::Driver;
use lora_driver::RadioMode;

fn main() {

	// Get args that were passed
	let args: Vec<String> = env::args().collect();
	let platform = &args[1];
	let send_recv = &args[2];
	let mut passed_string = String::new();
	match args.len() {
		4 => {passed_string.push_str(args[3].as_str());},
		_ => {}
	}

	let mut e32_driver;
	let mut testconfig = RadioConfig::new();

	match &platform[..] {
		"vocore" => {
						e32_driver = Driver::new(23,24,26, "/dev/ttyS0");
						//set our serial rate to 57600 as well
						e32_driver.set_tty_params(
							serial::Baud115200,
							serial::Bits8,
							serial::ParityNone,
							serial::Stop1,
							serial::FlowNone
						);
						e32_driver.set_tty_baud(serial::Baud57600);
						testconfig.set_serial_rate("57600");
					}
		"chip" => {
						e32_driver = Driver::new(1013,1015,1017, "/dev/ttyS0");
						e32_driver.set_tty_params(
							serial::Baud115200,
							serial::Bits8,
							serial::ParityNone,
							serial::Stop1,
							serial::FlowNone
						);
						testconfig.set_serial_rate("115200");
				  }
		_ => panic!("Please enter either 'vocore' or 'chip'")
	}
	// we want it to be a mutable driver because we will be changing fields as we go.
	//let mut e32_driver = Driver::new(1013,1015,1017, "/dev/ttyS0"); //Pins for C.H.I.P.
	//let mut e32_driver = Driver::new(23,24,26, "/dev/ttyS0"); //Pins for Vocore.
	// Bring up our serial device with defaults

	testconfig.set_transmit_power("20dBm");
	testconfig.set_air_rate("1k");
	testconfig.set_address("FFFF"); // Channel 0
	e32_driver.set_mode(RadioMode::General);

	//let (m0_pin, m1_pin, aux_pin) = e32_driver.get_control_gpio_pins();
	//println!("M0: {} M1: {} AUX: {}", m0_pin, m1_pin, aux_pin);

	match &send_recv[..] {
		"r" => {
			// Recieve mode
			e32_driver.write_config(testconfig); // Write after change
			//let mut buffer: Vec<u8> = vec![0;256]; //initialize buffer of zeros
			println!("Waiting to receive from the radio");
			let packet = e32_driver.receive_packet();
			println!("Received a packet {} bytes long", packet.len());
			println!("{}",String::from_utf8(packet).unwrap());
			//println!("{:?}",packet);
		}
		"s" => {
			// Send mode
			e32_driver.write_config(testconfig); // Write after change
			//let send_buf: Vec<u8> = vec![0;256];
			let send_string = passed_string.clone();
			//let send_string = String::from("This is a test of how long a message can get. I should be able to keep typing and the entire packet should be sent.");
			let send_buf = send_string.into_bytes();
			//let send_buf: Vec<u8> = vec![255;116];
			e32_driver.send_packet(&send_buf);
		}
		_ => {
			panic!("Call with either 'r' or 's'");
		}
	}

	/*
	//Send some data
	let mut packet: Vec<u8> = vec![0; 10]; // create a vector of 256 bytes
	e32_driver.send_packet(&packet);
	e32_driver.receive_packet(&mut packet);
	*/

}
<|endoftext|>


<commit_before>extern crate rff;

fn main() {
    let lines = rff::stdin::slurp();
    println!("Lines:\n{:?}", lines);
}
<commit_msg>Fetch search term from args<commit_after>extern crate rff;

use std::env;

fn main() {
    if let Some(search_term) = env::args().nth(1) {
        let lines = rff::stdin::slurp();
        println!("Lines:\n{:?}", lines);
        println!("Search: {}", search_term);
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::env;
use std::fs;
use std::io::{BufReader, BufRead, Write, Read};
use std::process::{Command, Stdio};

extern crate git2;
extern crate glob;
extern crate rustc_serialize;
extern crate tiny_http;

static INDEX_GIT_URL: &'static str = "https://github.com/rust-lang/crates.io-index";
static INDEX_LOCAL_PATH: &'static str = "crates.io-index";

#[derive(RustcDecodable)]
#[allow(dead_code)]
struct CrateInfo {
    name: String,
    vers: String,
    deps: Vec<DepInfo>,
    cksum: String,
    features: HashMap<String, Vec<String>>,
    yanked: bool,
}

#[derive(RustcDecodable)]
#[allow(dead_code)]
struct DepInfo {
    name: String,
    req: String,
    features: Vec<String>,
    optional: bool,
    default_features: bool,
    target: Option<String>,
    kind: Option<String>
}

fn build_dependency_map() -> HashMap<String, Vec<String>> {
    let mut match_options = glob::MatchOptions::new();
    match_options.require_literal_leading_dot = true;

    let index_paths1 = glob::glob_with("crates.io-index/*/*/*", &match_options).unwrap();
    let index_paths2 = glob::glob_with("crates.io-index/[12]/*", &match_options).unwrap();

    let index_paths = index_paths1.chain(index_paths2);

    let mut map = HashMap::new();

    for glob_result in index_paths {
        let index_path = glob_result.unwrap();
        let file = fs::File::open(&index_path).unwrap();
        let last_line = BufReader::new(file).lines().last().unwrap().unwrap();
        let crate_info: CrateInfo = rustc_serialize::json::decode(&last_line).unwrap();
        let deps_names = crate_info.deps.iter().map(|d| d.name.clone()).collect();
        map.insert(crate_info.name, deps_names);
    }

    map
}

fn build_dot(crate_name: &str, dep_map: &HashMap<String, Vec<String>>) -> Vec<u8> {
    let mut crate_names = vec![crate_name];

    let mut dot = String::new();
    dot.push_str("digraph graphname {");

    while let Some(crate_name) = crate_names.pop() {
        for crate_dep in dep_map.get(crate_name).unwrap() {
            dot.push_str(&format!("{} -> {};", crate_name.replace("-", "_"), crate_dep.replace("-", "_")))
        }
    }
    dot.push_str("}");

    let child = Command::new("dot").arg("-Tpng").stdin(Stdio::piped()).stdout(Stdio::piped()).spawn().unwrap();
    {
        child.stdin.unwrap().write_all(dot.as_bytes()).unwrap();
    }

    let mut ret = vec![];
    child.stdout.unwrap().read_to_end(&mut ret).unwrap();
    ret
}

fn main() {
    if fs::metadata(INDEX_LOCAL_PATH).is_err() {
        println!("Cloning crates.io-index");
        git2::Repository::clone(INDEX_GIT_URL, INDEX_LOCAL_PATH).unwrap();
    }

    let dep_map = build_dependency_map();

    let port = match env::var("PORT") {
        Ok(p) => p.parse::<u16>().unwrap(),
        Err(..) => 8000,
    };

    let server = tiny_http::ServerBuilder::new().with_port(port).build().unwrap();

    println!("Server listening on port {}", port);
    for req in server.incoming_requests() {
        let response = if dep_map.get(req.get_url().trim_left_matches("/")).is_some() {
            let data = build_dot(req.get_url().trim_left_matches("/"), &dep_map);
            let res = tiny_http::Response::from_data(data);
            res.with_header("Content-Type: image/png".parse::<tiny_http::Header>().unwrap())
        } else {
            tiny_http::Response::from_string("could not find crate")
        };
        req.respond(response);
    }
}
<commit_msg>Generate dependencies of dependencies<commit_after>use std::collections::{HashMap, HashSet};
use std::env;
use std::fs;
use std::io::{BufReader, BufRead, Write, Read};
use std::process::{Command, Stdio};

extern crate git2;
extern crate glob;
extern crate rustc_serialize;
extern crate tiny_http;

static INDEX_GIT_URL: &'static str = "https://github.com/rust-lang/crates.io-index";
static INDEX_LOCAL_PATH: &'static str = "crates.io-index";

#[derive(RustcDecodable)]
#[allow(dead_code)]
struct CrateInfo {
    name: String,
    vers: String,
    deps: Vec<DepInfo>,
    cksum: String,
    features: HashMap<String, Vec<String>>,
    yanked: bool,
}

#[derive(RustcDecodable)]
#[allow(dead_code)]
struct DepInfo {
    name: String,
    req: String,
    features: Vec<String>,
    optional: bool,
    default_features: bool,
    target: Option<String>,
    kind: Option<String>
}

fn build_dependency_map() -> HashMap<String, Vec<String>> {
    let mut match_options = glob::MatchOptions::new();
    match_options.require_literal_leading_dot = true;

    let index_paths1 = glob::glob_with("crates.io-index/*/*/*", &match_options).unwrap();
    let index_paths2 = glob::glob_with("crates.io-index/[12]/*", &match_options).unwrap();

    let index_paths = index_paths1.chain(index_paths2);

    let mut map = HashMap::new();

    for glob_result in index_paths {
        let index_path = glob_result.unwrap();
        let file = fs::File::open(&index_path).unwrap();
        let last_line = BufReader::new(file).lines().last().unwrap().unwrap();
        let crate_info: CrateInfo = rustc_serialize::json::decode(&last_line).unwrap();
        let deps_names = crate_info.deps.iter().map(|d| d.name.clone()).collect();
        map.insert(crate_info.name, deps_names);
    }

    map
}

fn build_dot(crate_name: &str, dep_map: &HashMap<String, Vec<String>>) -> Vec<u8> {
    let mut crate_names = vec![crate_name];

    let mut dot = String::new();
    dot.push_str("digraph graphname {");

    // Which dependencies we've already seen
    let mut seen_set = HashSet::new();

    while let Some(crate_name) = crate_names.pop() {
        seen_set.insert(crate_name);
        for crate_dep in dep_map.get(crate_name).unwrap() {
            dot.push_str(&format!("{} -> {};", crate_name.replace("-", "_"), crate_dep.replace("-", "_")));
            if !seen_set.contains(crate_dep as &str) {
                crate_names.push(crate_dep);
            }
        }
    }
    dot.push_str("}");

    let child = Command::new("dot").arg("-Tpng").stdin(Stdio::piped()).stdout(Stdio::piped()).spawn().unwrap();
    {
        child.stdin.unwrap().write_all(dot.as_bytes()).unwrap();
    }

    let mut ret = vec![];
    child.stdout.unwrap().read_to_end(&mut ret).unwrap();
    ret
}

fn main() {
    if fs::metadata(INDEX_LOCAL_PATH).is_err() {
        println!("Cloning crates.io-index");
        git2::Repository::clone(INDEX_GIT_URL, INDEX_LOCAL_PATH).unwrap();
    }

    let dep_map = build_dependency_map();

    let port = match env::var("PORT") {
        Ok(p) => p.parse::<u16>().unwrap(),
        Err(..) => 8000,
    };

    let server = tiny_http::ServerBuilder::new().with_port(port).build().unwrap();

    println!("Server listening on port {}", port);
    for req in server.incoming_requests() {
        let response = if dep_map.get(req.get_url().trim_left_matches("/")).is_some() {
            let data = build_dot(req.get_url().trim_left_matches("/"), &dep_map);
            let res = tiny_http::Response::from_data(data);
            res.with_header("Content-Type: image/png".parse::<tiny_http::Header>().unwrap())
        } else {
            tiny_http::Response::from_string("could not find crate")
        };
        req.respond(response);
    }
}
<|endoftext|>


<commit_before>extern crate liner;
#[macro_use]
extern crate serde_derive;
extern crate toml;

use liner::Context;
use liner::KeyBindings;
use std::collections::HashMap;
use std::fs::File;
use std::io::{ErrorKind, Read};
use std::mem;
use std::path::Path;

#[derive(Deserialize)]
struct CacheConfig {
    ttl: usize,
}

#[derive(Deserialize)]
struct Config {
    cache: CacheConfig,
}

fn main() {
    // Open and read configuration
    let config_path = Path::new("etc/carpool.toml");
    let mut config_file = match File::open(&config_path) {
        Err(_) => panic!("couldn't open {:?}", config_path),
        Ok(file) => file,
    };

    let mut config_content = String::new();
    let _ = config_file.read_to_string(&mut config_content);

    let config: Config = toml::from_str(config_content.as_str()).unwrap();

    // Set up cache
    let mut cache = Box::new(HashMap::new());
    let mut bytes_used:usize = 0;
    let empty_value = String::from("");

    // Start REPL
    let mut con = Context::new();

    loop {
        let res = con.read_line("> ", &mut |_| {});

        match res {
            Ok(res) => {
                match res.as_str() {
                    s if s.trim() == "" =>  {}
                    s if s.starts_with("get ") =>  {
                        let (_, key) = s.split_at(4);
                        let key_trimmed = String::from(key.trim());
                        if key_trimmed.find(' ').is_some() {
                            println!("key cannot contain space");
                            continue
                        }
                        println!("{}", cache.get(&key_trimmed).unwrap_or(&empty_value));
                    }
                    s if s.starts_with("del ") =>  {
                        let (_, key) = s.split_at(4);
                        let key_trimmed = String::from(key.trim());
                        if key_trimmed.find(' ').is_some() {
                            println!("key cannot contain space");
                            continue
                        }
                        let value = cache.remove(&key_trimmed);
                        bytes_used -= mem::size_of_val(&key_trimmed) + mem::size_of_val(&value);
                    }
                    s if s.starts_with("set ") =>  {
                        let (_, key_value) = s.split_at(4);
                        match key_value.find(' ') {
                            Some(i) => {
                                let (key, value) = key_value.split_at(i);
                                let key_trimmed = String::from(key.trim());
                                let value_trimmed = String::from(value.trim());
                                bytes_used += mem::size_of_val(&key_trimmed) + mem::size_of_val(&value_trimmed);
                                cache.insert(key_trimmed, value_trimmed);
                            }
                            None => println!("no value specified")
                        }
                    }
                    "size" =>  {
                        println!("{} bytes", bytes_used);
                    }
                    "keys" =>  {
                        for key in cache.keys() {
                            println!("{}", key);
                        }
                    }
                    "emacs" => {
                        con.key_bindings = KeyBindings::Emacs;
                        println!("emacs mode");
                    }
                    "vi" | "vim" =>  {
                        con.key_bindings = KeyBindings::Vi;
                        println!("vi mode");
                    }
                    "exit" =>  {
                        break;
                    }
                    _ => {
                        println!("operation not defined")
                    }
                }

                con.history.push(res.into()).unwrap();
            }
            Err(e) => {
                match e.kind() {
                    // ctrl-c pressed
                    ErrorKind::Interrupted => {}
                    // ctrl-d pressed
                    ErrorKind::UnexpectedEof => {
                        break;
                    }
                    _ => panic!("error: {:?}", e),
                }
            }
        }
    }
}
<commit_msg>Add Cache struct<commit_after>extern crate liner;
#[macro_use]
extern crate serde_derive;
extern crate toml;

use liner::Context;
use liner::KeyBindings;
use std::collections::HashMap;
use std::collections::hash_map::Keys;
use std::fs::File;
use std::io::{ErrorKind, Read};
use std::mem;
use std::path::Path;

type Data = HashMap<String, String>;

#[derive(Deserialize)]
struct CacheConfig {
    ttl: usize,
}

#[derive(Deserialize)]
struct Config {
    cache: CacheConfig,
}

struct Cache {
    data: Box<Data>,
    config: Config,
    bytes: usize
}

impl Cache {
    fn clear(&mut self) {
        self.data.clear();
        self.bytes = 0;
    }

    fn get(&mut self, key: &String) -> Option<&String> {
        self.data.get(key)
    }

    fn set(&mut self, key: String, value: String) {
        self.bytes += mem::size_of_val(&key) + mem::size_of_val(&value);
        self.data.insert(key, value);
    }

    fn delete(&mut self, key: &String) {
        let value = self.data.remove(key);
        self.bytes -= mem::size_of_val(key) + mem::size_of_val(&value);
    }

    fn keys(&self) -> Keys<String, String> {
        self.data.keys()
    }

    fn size(&self) -> usize {
        self.bytes
    }
}

fn main() {
    // Open and read configuration
    let config_path = Path::new("etc/carpool.toml");
    let mut config_file = match File::open(&config_path) {
        Err(_) => panic!("couldn't open {:?}", config_path),
        Ok(file) => file,
    };

    let mut config_content = String::new();
    let _ = config_file.read_to_string(&mut config_content);

    let config: Config = toml::from_str(config_content.as_str()).unwrap();

    // Set up cache
    let mut cache = Cache {
        config: config,
        data: Box::new(HashMap::new()),
        bytes: 0,
    };

    let empty_value = String::from("");

    // Start REPL
    let mut con = Context::new();

    loop {
        let res = con.read_line("> ", &mut |_| {});

        match res {
            Ok(res) => {
                match res.as_str() {
                    s if s.trim() == "" =>  {}
                    s if s.starts_with("get ") =>  {
                        let (_, key) = s.split_at(4);
                        let key_trimmed = String::from(key.trim());
                        if key_trimmed.find(' ').is_some() {
                            println!("key cannot contain space");
                            continue
                        }
                        println!("{}", cache.get(&key_trimmed).unwrap_or(&empty_value));
                    }
                    s if s.starts_with("del ") =>  {
                        let (_, key) = s.split_at(4);
                        let key_trimmed = String::from(key.trim());
                        if key_trimmed.find(' ').is_some() {
                            println!("key cannot contain space");
                            continue
                        }
                        let value = cache.delete(&key_trimmed);
                    }
                    s if s.starts_with("set ") =>  {
                        let (_, key_value) = s.split_at(4);
                        match key_value.find(' ') {
                            Some(i) => {
                                let (key, value) = key_value.split_at(i);
                                let key_trimmed = String::from(key.trim());
                                let value_trimmed = String::from(value.trim());
                                cache.set(key_trimmed, value_trimmed);
                            }
                            None => println!("no value specified")
                        }
                    }
                    "size" =>  {
                        println!("{} bytes", cache.size());
                    }
                    "keys" =>  {
                        for key in cache.keys() {
                            println!("{}", key);
                        }
                    }
                    "emacs" => {
                        con.key_bindings = KeyBindings::Emacs;
                        println!("emacs mode");
                    }
                    "vi" | "vim" =>  {
                        con.key_bindings = KeyBindings::Vi;
                        println!("vi mode");
                    }
                    "exit" =>  {
                        break;
                    }
                    _ => {
                        println!("operation not defined")
                    }
                }

                con.history.push(res.into()).unwrap();
            }
            Err(e) => {
                match e.kind() {
                    // ctrl-c pressed
                    ErrorKind::Interrupted => {}
                    // ctrl-d pressed
                    ErrorKind::UnexpectedEof => {
                        break;
                    }
                    _ => panic!("error: {:?}", e),
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>#![cfg_attr(feature = "dev", allow(unstable_features))]
#![cfg_attr(feature = "dev", feature(plugin))]
#![cfg_attr(feature = "dev", plugin(clippy))]

mod logger;
mod toml_file;
mod git;
mod changelog;
mod commit_analyzer;
mod cargo;
mod error;
mod github;
mod config;

extern crate rustc_serialize;
extern crate toml;
extern crate regex;
extern crate semver;
extern crate docopt;
extern crate git2;
extern crate clog;
extern crate hyper;
extern crate hubcaps;
extern crate url;

use docopt::Docopt;
use commit_analyzer::CommitType;
use config::ConfigBuilder;
use std::process;
use semver::Version;
use std::{env,fs};
use std::path::Path;
use std::error::Error;
use url::Url;

const VERSION: &'static str = env!("CARGO_PKG_VERSION");
const USERAGENT: &'static str = concat!("semantic-rs/", env!("CARGO_PKG_VERSION"));
const USAGE: &'static str = "
semantic.rs 🚀

Usage:
  semantic-rs [options]
  semantic-rs --version

Options:
  -h --help              Show this screen.
  --version              Show version.
  -p PATH, --path=PATH   Specifies the repository path. [default: .]
  -w, --write            Run with writing the changes afterwards.
  -r <r>, --release=<r>  Create release on GitHub and publish on crates.io (only in write mode) [default: yes]
  -b <b>, --branch=<b>   The branch on which releases should happen. [default: master]
";

macro_rules! print_exit {
    ($fmt:expr) => {{
        logger::stderr(format!($fmt));
        process::exit(1);
    }};
    ($fmt:expr, $($arg:tt)*) => {{
        logger::stderr(format!($fmt, $($arg)*));
        process::exit(1);
    }};
}

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_path: String,
    flag_write: bool,
    flag_version: bool,
    flag_release: String,
    flag_branch: String,
}

fn string_to_bool(answer: &str) -> bool {
    match &answer.to_lowercase()[..] {
        "yes" | "true" | "1" => true,
        "no" | "false" | "0" => false,
        _ => false
    }
}

fn version_bump(version: &Version, bump: CommitType) -> Option<Version> {
    let mut version = version.clone();
    match bump {
        CommitType::Unknown => return None,
        CommitType::Patch => version.increment_patch(),
        CommitType::Minor => version.increment_minor(),
        CommitType::Major => version.increment_major(),
    }

    Some(version)
}

fn ci_env_set() -> bool {
    env::var("CI").is_ok()
}

fn user_repo_from_url(url: Url) -> Result<(String, String), String> {
    let path = match url.path() {
        Some(path) => path,
        None => return Err("URL should contain user and repository".into()),
    };

    let user = path[0].clone();
    let repo = match path[1].rfind(".git") {
        None => path[1].clone(),
        Some(suffix_pos) => {
            let valid_pos = path[1].len() - 4;
            if valid_pos == suffix_pos {
                let path = &path[1][0..suffix_pos];
                path.into()
            } else {
                return Err(".git suffix not at the end of URL".into())
            }
        }
    };

    Ok((user, repo))
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());

    let mut cb = ConfigBuilder::new();

    if args.flag_version {
        println!("semantic.rs 🚀 -- v{}", VERSION);
        process::exit(0);
    }

    let is_dry_run = if ci_env_set() {
        false
    }
    else {
        !args.flag_write
    };

    let release_mode = string_to_bool(&args.flag_release);

    cb.write(args.flag_write);
    cb.release(release_mode);
    cb.branch(args.flag_branch);

    println!("semantic.rs 🚀");

    logger::stdout("Analyzing your repository");
    let path = Path::new(&args.flag_path);
    let path = fs::canonicalize(path)
        .unwrap_or_else(|_| print_exit!("Path does not exist or a component is not a directory"));
    let repository_path = path.to_str()
        .unwrap_or_else(|| print_exit!("Path is not valid unicode"));

    let repo = match git2::Repository::open(repository_path) {
        Ok(repo) => repo,
        Err(e) => {
            logger::stderr(format!("Could not open the git repository: {:?}", e));
            process::exit(1);
        }
    };

    cb.repository_path(repository_path.to_owned());

    // extra scope scope to make sure borrow of `repo` is dropped
    {
        let signature = match git::get_signature(&repo) {
            Ok(sig) => sig,
            Err(e) => {
                logger::stderr(format!("Failed to get the committer's name and email address: {}", e.description()));
                logger::stderr(r"
A release commit needs a committer name and email address.
We tried fetching it from different locations, but couldn't find one.

Committer information is taken from the following environment variables, if set:

GIT_COMMITTER_NAME
GIT_COMMITTER_EMAIL

If none is set the normal git config is tried in the following order:

Local repository config
User config
Global config");
                process::exit(1);
            }
        };

        cb.signature(signature.to_owned());
    }

    // In case we are in write-mode AND release mode,
    // we will make sure we got all configuration settings
    if !is_dry_run && release_mode {
        let remote_url = match repo.find_remote("origin") {
            Err(e) => print_exit!("Could not determine the origin remote url: {:?}", e),
            Ok(remote) => {
                let url = remote.url().expect("Remote URL is not valid UTF-8");
                Url::parse(&url).expect("Remote URL can't be parsed")
            }
        };

        let (user, repo_name) = user_repo_from_url(remote_url)
            .unwrap_or_else(|e| print_exit!("Could not extract user and repository name from URL: {:?}", e));
        cb.user(user);
        cb.repository_name(repo_name);

        let gh_token = env::var("GH_TOKEN")
            .unwrap_or_else(|err| print_exit!("GH_TOKEN not set: {:?}", err));

        let cargo_token = env::var("CARGO_TOKEN")
            .unwrap_or_else(|err| print_exit!("CARGO_TOKEN not set: {:?}", err));

        cb.gh_token(gh_token);
        cb.cargo_token(cargo_token);
    }

    cb.repository(repo);
    cb.branch("master".into());
    let config = cb.build();

    let version = toml_file::read_from_file(&config.repository_path)
        .unwrap_or_else(|err| print_exit!("Reading `Cargo.toml` failed: {:?}", err));

    let version = Version::parse(&version).expect("Not a valid version");
    logger::stdout(format!("Current version: {}", version.to_string()));

    logger::stdout("Analyzing commits");

    let bump = git::version_bump_since_latest(&config.repository);
    if is_dry_run {
        logger::stdout(format!("Commits analyzed. Bump would be {:?}", bump));
    }
    else {
        logger::stdout(format!("Commits analyzed. Bump will be {:?}", bump));
    }
    let new_version = match version_bump(&version, bump) {
        Some(new_version) => new_version.to_string(),
        None => {
            logger::stdout("No version bump. Nothing to do.");
            process::exit(0);
        }
    };

    if is_dry_run {
        logger::stdout(format!("New version would be: {}", new_version));
        logger::stdout("Would write the following Changelog:");
        let changelog = match changelog::generate(repository_path, &version.to_string(), &new_version) {
            Ok(log) => log,
            Err(err) => {
                logger::stderr(format!("Generating Changelog failed: {:?}", err));
                process::exit(1);
            }
        };
        logger::stdout("====================================");
        logger::stdout(changelog);
        logger::stdout("====================================");
        logger::stdout("Would create annotated git tag");
    }
    else {
        logger::stdout(format!("New version: {}", new_version));

        toml_file::write_new_version(repository_path, &new_version)
            .unwrap_or_else(|err| print_exit!("Writing `Cargo.toml` failed: {:?}", err));

        logger::stdout(format!("Writing Changelog"));
        changelog::write(repository_path, &version.to_string(), &new_version)
            .unwrap_or_else(|err| print_exit!("Writing Changelog failed: {:?}", err));

        if config.release_mode {
            logger::stdout("Updating lockfile");
            if !cargo::update_lockfile(repository_path) {
                print_exit!("`cargo fetch` failed. See above for the cargo error message.");
            }
        }

        logger::stdout("Package crate");
        if !cargo::package(repository_path) {
            print_exit!("`cargo package` failed. See above for the cargo error message.");
        }

        git::commit_files(&config, &new_version)
            .unwrap_or_else(|err| print_exit!("Committing files failed: {:?}", err));

        logger::stdout("Creating annotated git tag");
        let tag_message = changelog::generate(repository_path, &version.to_string(), &new_version)
            .unwrap_or_else(|err| print_exit!("Can't generate changelog: {:?}", err));

        let tag_name = format!("v{}", new_version);
        git::tag(&config, &tag_name, &tag_message)
            .unwrap_or_else(|err| print_exit!("Failed to create git tag: {:?}", err));

        if config.release_mode {
            logger::stdout("Pushing new commit and tag");
            git::push(&config, &tag_name)
                .unwrap_or_else(|err| print_exit!("Failed to push git: {:?}", err));

            logger::stdout("Creating GitHub release");
            github::release(&config, &tag_name, &tag_message)
                .unwrap_or_else(|err| print_exit!("Failed to create GitHub release: {:?}", err));

            logger::stdout("Publishing crate on crates.io");
            if !cargo::publish(&config.repository_path, &config.cargo_token.as_ref().unwrap()) {
                print_exit!("Failed to publish on crates.io");
            }

            println!("{} v{} is released. 🚀🚀🚀", config.repository_name, new_version);
        }
    }
}
<commit_msg>style: Nicer error message<commit_after>#![cfg_attr(feature = "dev", allow(unstable_features))]
#![cfg_attr(feature = "dev", feature(plugin))]
#![cfg_attr(feature = "dev", plugin(clippy))]

mod logger;
mod toml_file;
mod git;
mod changelog;
mod commit_analyzer;
mod cargo;
mod error;
mod github;
mod config;

extern crate rustc_serialize;
extern crate toml;
extern crate regex;
extern crate semver;
extern crate docopt;
extern crate git2;
extern crate clog;
extern crate hyper;
extern crate hubcaps;
extern crate url;

use docopt::Docopt;
use commit_analyzer::CommitType;
use config::ConfigBuilder;
use std::process;
use semver::Version;
use std::{env,fs};
use std::path::Path;
use std::error::Error;
use url::Url;

const VERSION: &'static str = env!("CARGO_PKG_VERSION");
const USERAGENT: &'static str = concat!("semantic-rs/", env!("CARGO_PKG_VERSION"));
const USAGE: &'static str = "
semantic.rs 🚀

Usage:
  semantic-rs [options]
  semantic-rs --version

Options:
  -h --help              Show this screen.
  --version              Show version.
  -p PATH, --path=PATH   Specifies the repository path. [default: .]
  -w, --write            Run with writing the changes afterwards.
  -r <r>, --release=<r>  Create release on GitHub and publish on crates.io (only in write mode) [default: yes]
  -b <b>, --branch=<b>   The branch on which releases should happen. [default: master]
";

macro_rules! print_exit {
    ($fmt:expr) => {{
        logger::stderr(format!($fmt));
        process::exit(1);
    }};
    ($fmt:expr, $($arg:tt)*) => {{
        logger::stderr(format!($fmt, $($arg)*));
        process::exit(1);
    }};
}

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_path: String,
    flag_write: bool,
    flag_version: bool,
    flag_release: String,
    flag_branch: String,
}

fn string_to_bool(answer: &str) -> bool {
    match &answer.to_lowercase()[..] {
        "yes" | "true" | "1" => true,
        "no" | "false" | "0" => false,
        _ => false
    }
}

fn version_bump(version: &Version, bump: CommitType) -> Option<Version> {
    let mut version = version.clone();
    match bump {
        CommitType::Unknown => return None,
        CommitType::Patch => version.increment_patch(),
        CommitType::Minor => version.increment_minor(),
        CommitType::Major => version.increment_major(),
    }

    Some(version)
}

fn ci_env_set() -> bool {
    env::var("CI").is_ok()
}

fn user_repo_from_url(url: Url) -> Result<(String, String), String> {
    let path = match url.path() {
        Some(path) => path,
        None => return Err("URL should contain user and repository".into()),
    };

    let user = path[0].clone();
    let repo = match path[1].rfind(".git") {
        None => path[1].clone(),
        Some(suffix_pos) => {
            let valid_pos = path[1].len() - 4;
            if valid_pos == suffix_pos {
                let path = &path[1][0..suffix_pos];
                path.into()
            } else {
                return Err("URL does not point to a git repository".into())
            }
        }
    };

    Ok((user, repo))
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());

    let mut cb = ConfigBuilder::new();

    if args.flag_version {
        println!("semantic.rs 🚀 -- v{}", VERSION);
        process::exit(0);
    }

    let is_dry_run = if ci_env_set() {
        false
    }
    else {
        !args.flag_write
    };

    let release_mode = string_to_bool(&args.flag_release);

    cb.write(args.flag_write);
    cb.release(release_mode);
    cb.branch(args.flag_branch);

    println!("semantic.rs 🚀");

    logger::stdout("Analyzing your repository");
    let path = Path::new(&args.flag_path);
    let path = fs::canonicalize(path)
        .unwrap_or_else(|_| print_exit!("Path does not exist or a component is not a directory"));
    let repository_path = path.to_str()
        .unwrap_or_else(|| print_exit!("Path is not valid unicode"));

    let repo = match git2::Repository::open(repository_path) {
        Ok(repo) => repo,
        Err(e) => {
            logger::stderr(format!("Could not open the git repository: {:?}", e));
            process::exit(1);
        }
    };

    cb.repository_path(repository_path.to_owned());

    // extra scope scope to make sure borrow of `repo` is dropped
    {
        let signature = match git::get_signature(&repo) {
            Ok(sig) => sig,
            Err(e) => {
                logger::stderr(format!("Failed to get the committer's name and email address: {}", e.description()));
                logger::stderr(r"
A release commit needs a committer name and email address.
We tried fetching it from different locations, but couldn't find one.

Committer information is taken from the following environment variables, if set:

GIT_COMMITTER_NAME
GIT_COMMITTER_EMAIL

If none is set the normal git config is tried in the following order:

Local repository config
User config
Global config");
                process::exit(1);
            }
        };

        cb.signature(signature.to_owned());
    }

    // In case we are in write-mode AND release mode,
    // we will make sure we got all configuration settings
    if !is_dry_run && release_mode {
        let remote_url = match repo.find_remote("origin") {
            Err(e) => print_exit!("Could not determine the origin remote url: {:?}", e),
            Ok(remote) => {
                let url = remote.url().expect("Remote URL is not valid UTF-8");
                Url::parse(&url).expect("Remote URL can't be parsed")
            }
        };

        let (user, repo_name) = user_repo_from_url(remote_url)
            .unwrap_or_else(|e| print_exit!("Could not extract user and repository name from URL: {:?}", e));
        cb.user(user);
        cb.repository_name(repo_name);

        let gh_token = env::var("GH_TOKEN")
            .unwrap_or_else(|err| print_exit!("GH_TOKEN not set: {:?}", err));

        let cargo_token = env::var("CARGO_TOKEN")
            .unwrap_or_else(|err| print_exit!("CARGO_TOKEN not set: {:?}", err));

        cb.gh_token(gh_token);
        cb.cargo_token(cargo_token);
    }

    cb.repository(repo);
    cb.branch("master".into());
    let config = cb.build();

    let version = toml_file::read_from_file(&config.repository_path)
        .unwrap_or_else(|err| print_exit!("Reading `Cargo.toml` failed: {:?}", err));

    let version = Version::parse(&version).expect("Not a valid version");
    logger::stdout(format!("Current version: {}", version.to_string()));

    logger::stdout("Analyzing commits");

    let bump = git::version_bump_since_latest(&config.repository);
    if is_dry_run {
        logger::stdout(format!("Commits analyzed. Bump would be {:?}", bump));
    }
    else {
        logger::stdout(format!("Commits analyzed. Bump will be {:?}", bump));
    }
    let new_version = match version_bump(&version, bump) {
        Some(new_version) => new_version.to_string(),
        None => {
            logger::stdout("No version bump. Nothing to do.");
            process::exit(0);
        }
    };

    if is_dry_run {
        logger::stdout(format!("New version would be: {}", new_version));
        logger::stdout("Would write the following Changelog:");
        let changelog = match changelog::generate(repository_path, &version.to_string(), &new_version) {
            Ok(log) => log,
            Err(err) => {
                logger::stderr(format!("Generating Changelog failed: {:?}", err));
                process::exit(1);
            }
        };
        logger::stdout("====================================");
        logger::stdout(changelog);
        logger::stdout("====================================");
        logger::stdout("Would create annotated git tag");
    }
    else {
        logger::stdout(format!("New version: {}", new_version));

        toml_file::write_new_version(repository_path, &new_version)
            .unwrap_or_else(|err| print_exit!("Writing `Cargo.toml` failed: {:?}", err));

        logger::stdout(format!("Writing Changelog"));
        changelog::write(repository_path, &version.to_string(), &new_version)
            .unwrap_or_else(|err| print_exit!("Writing Changelog failed: {:?}", err));

        if config.release_mode {
            logger::stdout("Updating lockfile");
            if !cargo::update_lockfile(repository_path) {
                print_exit!("`cargo fetch` failed. See above for the cargo error message.");
            }
        }

        logger::stdout("Package crate");
        if !cargo::package(repository_path) {
            print_exit!("`cargo package` failed. See above for the cargo error message.");
        }

        git::commit_files(&config, &new_version)
            .unwrap_or_else(|err| print_exit!("Committing files failed: {:?}", err));

        logger::stdout("Creating annotated git tag");
        let tag_message = changelog::generate(repository_path, &version.to_string(), &new_version)
            .unwrap_or_else(|err| print_exit!("Can't generate changelog: {:?}", err));

        let tag_name = format!("v{}", new_version);
        git::tag(&config, &tag_name, &tag_message)
            .unwrap_or_else(|err| print_exit!("Failed to create git tag: {:?}", err));

        if config.release_mode {
            logger::stdout("Pushing new commit and tag");
            git::push(&config, &tag_name)
                .unwrap_or_else(|err| print_exit!("Failed to push git: {:?}", err));

            logger::stdout("Creating GitHub release");
            github::release(&config, &tag_name, &tag_message)
                .unwrap_or_else(|err| print_exit!("Failed to create GitHub release: {:?}", err));

            logger::stdout("Publishing crate on crates.io");
            if !cargo::publish(&config.repository_path, &config.cargo_token.as_ref().unwrap()) {
                print_exit!("Failed to publish on crates.io");
            }

            println!("{} v{} is released. 🚀🚀🚀", config.repository_name, new_version);
        }
    }
}
<|endoftext|>


<commit_before>fn main() {
    println!("Hello, world!");
}
<commit_msg>Add naive commands handling<commit_after>use std::io;
use std::io::prelude::*;
use std::collections::HashMap;

enum Action {
    Output(String),
    Exit,
    None,
}

type Commands = HashMap<String, fn() -> Action>;

const _DB_PATH: &'static str = "~/.notes.db";

fn ls() -> Action {
    let result = "placeholder".to_string();
    Action::Output(result)
}

fn add() -> Action {
    Action::None
}

fn exit() -> Action {
    Action::Exit
}

fn process_command(commands: &Commands, command: String) -> Action {
    match commands.get(&command) {
        None => { return Action::Output("No such command!".to_string()) },
        Some(method) => {
            return method();
        },
    };
}

fn command_loop(commands: &Commands) {
    loop {
        print!("notes> ");
        io::stdout().flush().expect("Flush failed");

        let mut input = String::new();
        match io::stdin().read_line(&mut input) {
            Err(_) => continue,
            Ok(_) => {
                // EoF reached
                if input.is_empty() {
                    println!("");
                    break;
                }

                input = input.trim().to_string();
                if input.is_empty() {
                    continue;
                }

                match process_command(commands, input) {
                    Action::Output(output) => println!("{}", output),
                    Action::Exit => break,
                    Action::None => (),
                }
            },
        }
    }

    println!("Bye!");
}

fn main() {
    let mut commands: Commands = HashMap::new();

    commands.insert("ls".to_string(), ls);
    commands.insert("add".to_string(), add);
    commands.insert("exit".to_string(), exit);
    commands.insert("quit".to_string(), exit);

    command_loop(&commands);
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![plugin(serde_macros)]
#![feature(custom_derive)]
#![feature(custom_attribute)]
extern crate discord;
extern crate serde;
extern crate serde_json;
extern crate hyper;
extern crate url;
extern crate discord_bot;

use std::fs::File;
use std::io::Read;
use discord::{Discord, State};
use discord::model::{Event, ChannelId, UserId};
use url::Url;
use discord_bot::shortcuts::{send_discord_message, info, warn, warning, remove_quote};

fn main() {
    // Read and set config vars
    let mut file = File::open("config.json").unwrap();
    let mut config = String::new();
    file.read_to_string(&mut config).unwrap();

    #[derive(Deserialize)]
    pub struct Config {
        pub bot_token: String,
        pub welcome_message: String,
    }

    let bot_tokens = serde_json::from_str::<Config>(&config).unwrap().bot_token;
    let welcome_messages =
        serde_json::from_str::<Config>(&config).unwrap().welcome_message.pop().unwrap();

    info("[bot-token has been set to [REDACTED] from config");
    info(&format!("welcome-message has been set to {} from the config",
                  welcome_messages));

    // Login to the API
    let discord = Discord::from_bot_token(&bot_tokens).expect("Login Fail");

    // establish websocket and voice connection
    let (mut connection, ready) = discord.connect().expect("connect failed");
    println!("[Ready] {} is serving {} servers",
             ready.user.username,
             ready.servers.len());
    let mut state = State::new(ready);

    // receive events forever
    loop {
        let event = match connection.recv_event() {
            Ok(event) => event,
            Err(err) => {
                warning(&format!("Receive error: {:?}", err));
                if let discord::Error::WebSocket(..) = err {
                    // Handle the websocket connection being dropped
                    let (new_connection, ready) = discord.connect().expect("connect failed");
                    connection = new_connection;
                    state = State::new(ready);
                    println!("[Ready] Reconnected successfully.");
                }
                if let discord::Error::Closed(..) = err {
                    break;
                }
                continue;
            }
        };
        state.update(&event);

        match event {
            Event::MessageCreate(message) => {
                use std::ascii::AsciiExt;
                // safeguard: stop if the message is from us
                if message.author.id == state.user().id {
                    continue;
                }

                // reply to a command if there was one
                let mut split = message.content.split(' ');
                let first_word = split.next().unwrap_or("");
                let argument = split.next().unwrap_or("");

                if first_word.eq_ignore_ascii_case("!help") {
                    if argument.eq_ignore_ascii_case("dj") {
                        send_discord_message(&discord,
                                             &message.channel_id,
                                             "``!dj`` Plays YouTube videos in Voice \
                                              Chat:\n\n``!dj stop`` Stops the current playing \
                                              song.\n``!dj quit`` Stops the current playing \
                                              song, and exits the Voice Chat.");
                    } else {
                        send_discord_message(&discord,
                                             &message.channel_id,
                                             &format!("Here's the help that {} \
                                                       wanted:\n\n``!dj`` Plays YouTube videos \
                                                       in Voice Chat. See ``!help dj`` for more \
                                                       info\n\n``!catfacts`` Lists a random \
                                                       fact about cats.\n\n``!help`` Shows this \
                                                       output.",
                                                      message.author.id.mention()));
                    }
                } else if first_word.eq_ignore_ascii_case("!dj") {
                    let vchan = state.find_voice_user(message.author.id);
                    if argument.eq_ignore_ascii_case("stop") {
                        vchan.map(|(sid, _)| connection.voice(sid).stop());
                    } else if argument.eq_ignore_ascii_case("quit") {
                        vchan.map(|(sid, _)| connection.drop_voice(sid));
                    } else {
                        let output = if let Some((server_id, channel_id)) = vchan {
                            match discord::voice::open_ytdl_stream(argument) {
                                Ok(stream) => {
                                    let voice = connection.voice(server_id);
                                    voice.set_deaf(true);
                                    voice.connect(channel_id);
                                    voice.play(stream);
                                    String::new()
                                }
                                Err(error) => format!("Error: {}", error),
                            }
                        } else {
                            "You must be in a voice channel to DJ".to_owned()
                        };
                        if output.is_empty() {
                            warn(discord.send_message(&message.channel_id, &output, "", false));
                        }
                    }
                } else if first_word.eq_ignore_ascii_case("!catfacts") {
                    // Construct the URL you want to access
                    let url = "http://catfacts-api.appspot.com/api/facts?number=1"
                        .parse::<Url>()
                        .expect("Unable to parse URL");

                    // Initialize the Hyper client and make the request.
                    let client = hyper::Client::new();
                    let mut response = client.get(url).send().unwrap();

                    // Initialize a string buffer, and read the response into it.
                    let mut result = String::new();
                    response.read_to_string(&mut result).unwrap();

                    // Deserialize the result.
                    #[derive(Deserialize)]
                    pub struct CatFacts {
                        pub facts: Vec<String>,
                        pub success: bool,
                    }
                    let cat_fact =
                        serde_json::from_str::<CatFacts>(&result).unwrap().facts.pop().unwrap();
                    let cat_facts = remove_quote(&cat_fact);

                    send_discord_message(&discord,
                                         &message.channel_id,
                                         &format!("{}:\n {:?}",
                                                  message.author.id.mention(),
                                                  cat_facts));
                } else if first_word.eq_ignore_ascii_case("!quit") {
                    if message.author.id == UserId(77812253511913472) {
                        send_discord_message(&discord, &message.channel_id, "Shutting Down...");
                        info(&format!("{} has told me to quit.", message.author.name));
                        std::process::exit(0);
                    } else {
                        send_discord_message(&discord,
                                             &message.channel_id,
                                             "Your not authorized to do that");
                        warning(&format!("{} with the {:?} tried to kill me.",
                                         message.author.name,
                                         message.author.id));
                    }
                }
            }
            Event::VoiceStateUpdate(server_id, _) => {
                // If someone moves/hangs up, and we are in a voice channel,
                if let Some(cur_channel) = connection.voice(server_id).current_channel() {
                    // and our current voice channel is empty, disconnect from voice
                    if let Some(srv) = state.servers().iter().find(|srv| srv.id == server_id) {
                        if srv.voice_states
                            .iter()
                            .filter(|vs| vs.channel_id == Some(cur_channel))
                            .count() <= 1 {
                            connection.voice(server_id).disconnect();
                        }
                    }
                }
            }
            Event::ServerMemberAdd(server_joined_id, member) => {
                let channel_id = ChannelId(server_joined_id.0);

                for server in state.servers() {
                    if server.id == server_joined_id {
                        send_discord_message(&discord,
                                             &channel_id,
                                             &format!("Welcome {} to {}! {}",
                                                      member.user.name,
                                                      server.name,
                                                      welcome_messages));
                    }
                }
            }
            _ => {} // discard other events
        }
    }
}
<commit_msg>Change string fomatting.<commit_after>#![feature(plugin)]
#![plugin(serde_macros)]
#![feature(custom_derive)]
#![feature(custom_attribute)]
extern crate discord;
extern crate serde;
extern crate serde_json;
extern crate hyper;
extern crate url;
extern crate discord_bot;

use std::fs::File;
use std::io::Read;
use discord::{Discord, State};
use discord::model::{ChannelId, Event, UserId};
use url::Url;
use discord_bot::shortcuts::{info, remove_quote, send_discord_message, warn, warning};

fn main() {
    // Read and set config vars
    let mut file = File::open("config.json").unwrap();
    let mut config = String::new();
    file.read_to_string(&mut config).unwrap();

    #[derive(Deserialize)]
    pub struct Config {
        pub bot_token: String,
        pub welcome_message: String,
    }

    let bot_tokens = serde_json::from_str::<Config>(&config).unwrap().bot_token;
    let welcome_messages =
        serde_json::from_str::<Config>(&config).unwrap().welcome_message.pop().unwrap();

    info("[bot-token has been set to [REDACTED] from config");
    info(&format!("welcome-message has been set to {} from the config",
                  welcome_messages));

    // Login to the API
    let discord = Discord::from_bot_token(&bot_tokens).expect("Login Fail");

    // establish websocket and voice connection
    let (mut connection, ready) = discord.connect().expect("connect failed");
    println!("[Ready] {} is serving {} servers",
             ready.user.username,
             ready.servers.len());
    let mut state = State::new(ready);

    // receive events forever
    loop {
        let event = match connection.recv_event() {
            Ok(event) => event,
            Err(err) => {
                warning(&format!("Receive error: {:?}", err));
                if let discord::Error::WebSocket(..) = err {
                    // Handle the websocket connection being dropped
                    let (new_connection, ready) = discord.connect().expect("connect failed");
                    connection = new_connection;
                    state = State::new(ready);
                    println!("[Ready] Reconnected successfully.");
                }
                if let discord::Error::Closed(..) = err {
                    break;
                }
                continue;
            }
        };
        state.update(&event);

        match event {
            Event::MessageCreate(message) => {
                use std::ascii::AsciiExt;
                // safeguard: stop if the message is from us
                if message.author.id == state.user().id {
                    continue;
                }

                // reply to a command if there was one
                let mut split = message.content.split(' ');
                let first_word = split.next().unwrap_or("");
                let argument = split.next().unwrap_or("");

                if first_word.eq_ignore_ascii_case("!help") {
                    if argument.eq_ignore_ascii_case("dj") {
                        send_discord_message(&discord,
                                             &message.channel_id,
                                             "``!dj`` Plays YouTube videos in Voice Chat:\n\n\
                                  ``!dj stop`` Stops the current playing song.\n\
                                  ``!dj quit`` Stops the current playing song, and exits the Voice Chat.");
                    } else {
                        send_discord_message(&discord,
                                             &message.channel_id,
                                             &format!("Here's the help that {} wanted:\n\n\
                                  ``!dj`` Plays YouTube videos in Voice Chat. See ``!help dj`` for more info\n\n\
                                  ``!catfacts`` Lists a random fact about cats.\n\n\
                                  ``!help`` Shows this output.",
                                                      message.author.id.mention()));
                    }
                } else if first_word.eq_ignore_ascii_case("!dj") {
                    let vchan = state.find_voice_user(message.author.id);
                    if argument.eq_ignore_ascii_case("stop") {
                        vchan.map(|(sid, _)| connection.voice(sid).stop());
                    } else if argument.eq_ignore_ascii_case("quit") {
                        vchan.map(|(sid, _)| connection.drop_voice(sid));
                    } else {
                        let output = if let Some((server_id, channel_id)) = vchan {
                            match discord::voice::open_ytdl_stream(argument) {
                                Ok(stream) => {
                                    let voice = connection.voice(server_id);
                                    voice.set_deaf(true);
                                    voice.connect(channel_id);
                                    voice.play(stream);
                                    String::new()
                                }
                                Err(error) => format!("Error: {}", error),
                            }
                        } else {
                            "You must be in a voice channel to DJ".to_owned()
                        };
                        if output.is_empty() {
                            warn(discord.send_message(&message.channel_id, &output, "", false));
                        }
                    }
                } else if first_word.eq_ignore_ascii_case("!catfacts") {
                    // Construct the URL you want to access
                    let url = "http://catfacts-api.appspot.com/api/facts?number=1"
                        .parse::<Url>()
                        .expect("Unable to parse URL");

                    // Initialize the Hyper client and make the request.
                    let client = hyper::Client::new();
                    let mut response = client.get(url).send().unwrap();

                    // Initialize a string buffer, and read the response into it.
                    let mut result = String::new();
                    response.read_to_string(&mut result).unwrap();

                    // Deserialize the result.
                    #[derive(Deserialize)]
                    pub struct CatFacts {
                        pub facts: Vec<String>,
                        pub success: bool,
                    }
                    let cat_fact =
                        serde_json::from_str::<CatFacts>(&result).unwrap().facts.pop().unwrap();
                    let cat_facts = remove_quote(&cat_fact);

                    send_discord_message(&discord,
                                         &message.channel_id,
                                         &format!("{}:\n {:?}",
                                                  message.author.id.mention(),
                                                  cat_facts));
                } else if first_word.eq_ignore_ascii_case("!quit") {
                    if message.author.id == UserId(77812253511913472) {
                        send_discord_message(&discord, &message.channel_id, "Shutting Down...");
                        info(&format!("{} has told me to quit.", message.author.name));
                        std::process::exit(0);
                    } else {
                        send_discord_message(&discord,
                                             &message.channel_id,
                                             "Your not authorized to do that");
                        warning(&format!("{} with the {:?} tried to kill me.",
                                         message.author.name,
                                         message.author.id));
                    }
                }
            }
            Event::VoiceStateUpdate(server_id, _) => {
                // If someone moves/hangs up, and we are in a voice channel,
                if let Some(cur_channel) = connection.voice(server_id).current_channel() {
                    // and our current voice channel is empty, disconnect from voice
                    if let Some(srv) = state.servers().iter().find(|srv| srv.id == server_id) {
                        if srv.voice_states
                            .iter()
                            .filter(|vs| vs.channel_id == Some(cur_channel))
                            .count() <= 1 {
                            connection.voice(server_id).disconnect();
                        }
                    }
                }
            }
            Event::ServerMemberAdd(server_joined_id, member) => {
                let channel_id = ChannelId(server_joined_id.0);

                for server in state.servers() {
                    if server.id == server_joined_id {
                        send_discord_message(&discord,
                                             &channel_id,
                                             &format!("Welcome {} to {}! {}",
                                                      member.user.name,
                                                      server.name,
                                                      welcome_messages));
                    }
                }
            }
            _ => {} // discard other events
        }
    }
}
<|endoftext|>


<commit_before>extern crate rsdocs2docset;
extern crate html5ever;
#[macro_use]
extern crate quick_error;
extern crate clap;
extern crate url;
extern crate sqlite;

use clap::{Arg, App};
use html5ever::driver::{ParseOpts, parse_document};
use html5ever::rcdom::RcDom;
use html5ever::serialize::{SerializeOpts, serialize};
use html5ever::tendril::TendrilSink;
use html5ever::tree_builder::TreeBuilderOpts;

use std::ffi::OsStr;
use std::fs::{self, DirBuilder, DirEntry, File};
use std::io::{self,Write};
use std::path::Path;

use rsdocs2docset::dom::{manipulator, parser};

type Result = std::result::Result<(), RsDoc2DocsetError>;

quick_error! {
    #[derive(Debug)]
    pub enum RsDoc2DocsetError {
        Io(err: std::io::Error) {
            from()
                cause(err)
                description(err.description())
        }
        Utf8(err: std::string::FromUtf8Error) {
            from()
                cause(err)
                description(err.description())
        }
        Sqlite(err: sqlite::Error) {
            from()
                cause(err)
                description(err.description())
        }
    }
}

fn main() {
    let args = App::new("RsDoc2Docset")
        .version(include_str!("../VERSION"))
        .about("A tool that converts rust docs to Dash docset files")
        .arg(Arg::with_name("indir")
             .short("i")
             .long("rsdoc")
             .value_name("INDIR")
             .help("directory that contains rustdoc files")
             .required(true)
             .takes_value(true))
        .arg(Arg::with_name("name")
             .short("n")
             .long("name")
             .value_name("NAME")
             .help("name of the docset")
             .required(true)
             .takes_value(true))
        .get_matches();

    create_docset(args.value_of("indir").unwrap(), args.value_of("name").unwrap()).expect("error creating docset");
    println!("\n{}.docset successfully created!", args.value_of("name").unwrap())
}

fn create_docset(indir: &str, name: &str) -> Result {
    let db_filename = format!("{}.docset/Contents/Resources/docSet.dsidx", name);
    let db_path = Path::new(&db_filename);

    try!(write_file(Path::new(format!("{}.docset/Contents/Info.plist", name).as_str()), format!(include_str!("Info.plist.tmpl"), name = name, identifier = name.replace(" ", "-").to_lowercase()).as_ref()));
    try!(write_file(Path::new(format!("{}.docset/icon.png", name).as_str()), include_bytes!("icon.png")));
    try!(write_file(Path::new(format!("{}.docset/icon@2x.png", name).as_str()), include_bytes!("icon@2x.png")));

    try!(write_file(db_path, "".as_bytes()));
    try!(sqlite::open(db_path).and_then(|c| c.execute("CREATE TABLE searchIndex(id INTEGER PRIMARY KEY, name TEXT, type TEXT, path TEXT);")));

    try!(docset_from_rs_doc_tree(&Path::new(indir), format!("{}.docset/Contents/Resources/Documents/", name).as_str(), Path::new(db_path)));

    Ok(())
}

fn write_file(path: &Path, data: &[u8]) -> Result {
    let dir = path.parent().unwrap();

    try!(DirBuilder::new()
         .recursive(true)
         .create(dir));

    try!(File::create(path).and_then(|mut f| f.write_all(data)));
    Ok(())
}

fn docset_from_rs_doc_tree(source_dir: &Path, out_dir: &str, db_path: &Path) -> Result {
        if !source_dir.exists() {
            return Err(io::Error::new(io::ErrorKind::NotFound, format!("{} does not exist", source_dir.to_str().unwrap())).into());
        }

        if source_dir.is_dir() {
            for entry in fs::read_dir(source_dir)? {
                let entry = entry?;
                if entry.path().is_dir() {
                    try!(docset_from_rs_doc_tree(&entry.path(), &out_dir, &db_path));
                } else {
                    try!(annotate_file(&entry, &out_dir, &db_path));
                }
            }
        }
        Ok(())
    }

fn annotate_file(in_file: &DirEntry, output_prefix: &str, db_path: &Path) -> Result {
    let out_file = Path::new(output_prefix).join(in_file.path());

    if in_file.path().extension() != Some(OsStr::new("html")) {
        try!(write_file(Path::new(&out_file), "".as_bytes()));
        try!(fs::copy(in_file.path(), &out_file));
        //println!("{:70} | ", in_file.path().display());
        print!("."); io::stdout().flush().unwrap();
    } else {
        let opts = ParseOpts { tree_builder: TreeBuilderOpts { drop_doctype: true, ..Default::default() }, ..Default::default() };

        let mut dom = parse_document(RcDom::default(), opts)
            .from_utf8()
            .read_from( &mut File::open(&in_file.path())? )?;

        let entries = parser::find_entry_elements(&mut dom);
        for entry in entries.iter().filter_map(|x| x.as_ref()) {
            //println!("{:70} | {}", in_file.path().display(), entry);

            let sql_cmd = format!("INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES (\"{}\", \"{}\", \"{}#{}\");", entry.entry_name, entry.entry_type, in_file.path().to_str().unwrap(), entry.anchor_name);
            try!(sqlite::open(db_path).and_then(|c| c.execute(&sql_cmd)))
        }
        manipulator::add_dash_links(&mut dom, &entries);

        let mut bytes = vec![];
        try!(serialize(&mut bytes, &dom.document, SerializeOpts::default()));
        try!(write_file(&out_file, bytes.as_ref()));

        print!("o"); io::stdout().flush().unwrap();
    }

    Ok(())
}
<commit_msg>Use default options for parser<commit_after>extern crate rsdocs2docset;
extern crate html5ever;
#[macro_use]
extern crate quick_error;
extern crate clap;
extern crate url;
extern crate sqlite;

use clap::{Arg, App};
use html5ever::driver::{ParseOpts, parse_document};
use html5ever::rcdom::RcDom;
use html5ever::serialize::{SerializeOpts, serialize};
use html5ever::tendril::TendrilSink;

use std::ffi::OsStr;
use std::fs::{self, DirBuilder, DirEntry, File};
use std::io::{self,Write};
use std::path::Path;

use rsdocs2docset::dom::{manipulator, parser};

type Result = std::result::Result<(), RsDoc2DocsetError>;

quick_error! {
    #[derive(Debug)]
    pub enum RsDoc2DocsetError {
        Io(err: std::io::Error) {
            from()
                cause(err)
                description(err.description())
        }
        Utf8(err: std::string::FromUtf8Error) {
            from()
                cause(err)
                description(err.description())
        }
        Sqlite(err: sqlite::Error) {
            from()
                cause(err)
                description(err.description())
        }
    }
}

fn main() {
    let args = App::new("RsDoc2Docset")
        .version(include_str!("../VERSION"))
        .about("A tool that converts rust docs to Dash docset files")
        .arg(Arg::with_name("indir")
             .short("i")
             .long("rsdoc")
             .value_name("INDIR")
             .help("directory that contains rustdoc files")
             .required(true)
             .takes_value(true))
        .arg(Arg::with_name("name")
             .short("n")
             .long("name")
             .value_name("NAME")
             .help("name of the docset")
             .required(true)
             .takes_value(true))
        .get_matches();

    create_docset(args.value_of("indir").unwrap(), args.value_of("name").unwrap()).expect("error creating docset");
    println!("\n{}.docset successfully created!", args.value_of("name").unwrap())
}

fn create_docset(indir: &str, name: &str) -> Result {
    let db_filename = format!("{}.docset/Contents/Resources/docSet.dsidx", name);
    let db_path = Path::new(&db_filename);

    try!(write_file(Path::new(format!("{}.docset/Contents/Info.plist", name).as_str()), format!(include_str!("Info.plist.tmpl"), name = name, identifier = name.replace(" ", "-").to_lowercase()).as_ref()));
    try!(write_file(Path::new(format!("{}.docset/icon.png", name).as_str()), include_bytes!("icon.png")));
    try!(write_file(Path::new(format!("{}.docset/icon@2x.png", name).as_str()), include_bytes!("icon@2x.png")));

    try!(write_file(db_path, "".as_bytes()));
    try!(sqlite::open(db_path).and_then(|c| c.execute("CREATE TABLE searchIndex(id INTEGER PRIMARY KEY, name TEXT, type TEXT, path TEXT);")));

    try!(docset_from_rs_doc_tree(&Path::new(indir), format!("{}.docset/Contents/Resources/Documents/", name).as_str(), Path::new(db_path)));

    Ok(())
}

fn write_file(path: &Path, data: &[u8]) -> Result {
    let dir = path.parent().unwrap();

    try!(DirBuilder::new()
         .recursive(true)
         .create(dir));

    try!(File::create(path).and_then(|mut f| f.write_all(data)));
    Ok(())
}

fn docset_from_rs_doc_tree(source_dir: &Path, out_dir: &str, db_path: &Path) -> Result {
        if !source_dir.exists() {
            return Err(io::Error::new(io::ErrorKind::NotFound, format!("{} does not exist", source_dir.to_str().unwrap())).into());
        }

        if source_dir.is_dir() {
            for entry in fs::read_dir(source_dir)? {
                let entry = entry?;
                if entry.path().is_dir() {
                    try!(docset_from_rs_doc_tree(&entry.path(), &out_dir, &db_path));
                } else {
                    try!(annotate_file(&entry, &out_dir, &db_path));
                }
            }
        }
        Ok(())
    }

fn annotate_file(in_file: &DirEntry, output_prefix: &str, db_path: &Path) -> Result {
    let out_file = Path::new(output_prefix).join(in_file.path());

    if in_file.path().extension() != Some(OsStr::new("html")) {
        try!(write_file(&out_file, "".as_bytes())); // just so we are sure the parent's directory exists
        try!(fs::copy(in_file.path(), &out_file));
        //println!("{:70} | ", in_file.path().display());
        print!("."); io::stdout().flush().unwrap();
    } else {
        let mut dom = parse_document(RcDom::default(), ParseOpts::default())
            .from_utf8()
            .read_from( &mut File::open(&in_file.path())? )?;

        let entries = parser::find_entry_elements(&mut dom);
        for entry in entries.iter().filter_map(|x| x.as_ref()) {
            //println!("{:70} | {}", in_file.path().display(), entry);

            let sql_cmd = format!("INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES (\"{}\", \"{}\", \"{}#{}\");", entry.entry_name, entry.entry_type, in_file.path().to_str().unwrap(), entry.anchor_name);
            try!(sqlite::open(db_path).and_then(|c| c.execute(&sql_cmd)))
        }
        manipulator::add_dash_links(&mut dom, &entries);

        let mut bytes = vec![];
        try!(serialize(&mut bytes, &dom.document, SerializeOpts::default()));
        try!(write_file(&out_file, bytes.as_ref()));

        print!("o"); io::stdout().flush().unwrap();
    }

    Ok(())
}
<|endoftext|>