<commit_before>#![feature(globs)]
extern crate libc;

use xlib::{XOpenDisplay, XDisplayName, XQueryExtension, XInitExtension, XSynchronize, XKeysymToString, XKeycodeToKeysym};
use libc::{c_int};
use std::ptr;
use xtst::{XRecordCreateContext, XRecordAllClients, XRecordAllocRange, XRecordRange, XRecordQueryVersion, XRecordEnableContext, XRecordEnableContextAsync,XRecordInterceptData, XRecordProcessReplies, XRecordFreeData};
use std::mem;
use std::c_str::CString;
mod xtst;
mod xlib;
mod xlibint;
mod xutil;

struct XRecordDatum {
  xtype: ::libc::c_uchar,
  event: ::xlib::XEvent,
  req:   ::xlibint::xResourceReq,
  reply: ::xlibint::xGenericReply,
  error: ::xlibint::xError,
  setup: ::xlibint::xConnSetupPrefix,
}

// let mut display_control: *mut xlib::Display  = std::mem::transmute(0);
// let mut display_data: *mut xlib::Display  = std::mem::transmute(0);
static mut display_control: *mut xlib::Display = 0 as *mut xlib::Struct__XDisplay;
static mut display_data: *mut xlib::Display = 0 as *mut xlib::Struct__XDisplay;
static mut event_count:u32 = 0;
fn main() {
	unsafe {
		let mut a:  i8 = 0;
		display_control = XOpenDisplay(&a);
		display_data = XOpenDisplay(&a);

		if display_data.is_null() || display_control.is_null() {
			fail!("XOpenDisplay() failed!");
		}

		XSynchronize(display_control, 1);

		let display_name = unsafe {XDisplayName(&a)};
		let ext_name = "RECORD";
		// Check presence of Record extension
		let arg2:*mut c_int = &mut 1;
		let arg3:*mut c_int = &mut 1;
		let arg4:*mut c_int = &mut 1;
		let has_record = XQueryExtension(display_control, ext_name.to_c_str().as_ptr() as *const i8,arg2,arg3,arg4);
		let extension = XInitExtension(display_control, ext_name.to_c_str().as_ptr() as *const i8);
		if extension.is_null() {
			fail!("XInitExtension() failed!");
		}

		// Get version
		let mut versionMajor: c_int = 0;
		let mut versionMinor: c_int = 0;
		XRecordQueryVersion(display_control, &mut versionMajor, &mut versionMinor);
		println!("RECORD extension version {}.{}", versionMajor, versionMinor);

		// Prepare record range
		let mut recordRange: XRecordRange = *XRecordAllocRange();
		let mut recordRangePtr: *mut *mut XRecordRange = std::mem::transmute(&mut &mut recordRange);
		recordRange.device_events.first = 2; // KeyPress
		recordRange.device_events.last = 6; // MotionNotify

		// Create context
		let context = XRecordCreateContext(
			display_control,
			0,
			&mut XRecordAllClients,
			1,
			recordRangePtr,
			1
		);
		if context == 0 {
			fail!("Fail create Record context\n");
		}

		// Run
		let res = XRecordEnableContextAsync(display_data, context, Some(recordCallback), &mut 0);
		if res == 0 {
			fail!("Cound not enable the Record context!\n");
		}
		xtst::XRecordFreeContext(display_data, context);
		loop {
			XRecordProcessReplies(display_data);
		}
	}
}

extern "C" fn recordCallback(pointer:*mut i8, raw_data: *mut XRecordInterceptData) {

	unsafe {

		let data = &*raw_data;
		// println!("Category {}", data.category);
		if data.category != xtst::XRecordFromServer {
			return;
		}
		println!("Event count: {}", event_count);
		event_count += 1;
		println!("Time {}", data.server_time);
		println!("Datalen {}", data.data_len);
		let mut xdatum_ptr: *mut XRecordDatum = data.data as *mut XRecordDatum;
		let mut xdatum = &*xdatum_ptr;

		let mut event = xdatum.event;
		println!("Type {}", xdatum.xtype);

		// Catch key event
		if xdatum.xtype == xtst::KeyPress || xdatum.xtype == xtst::KeyRelease {
			// extract key code
			let raw_bytes: &mut [u8,..4] = std::mem::transmute(data.data);
			let c_char  = XKeysymToString(XKeycodeToKeysym(display_control, raw_bytes[1], 0));
			let c_string = CString::new(std::mem::transmute(c_char), false);
			let char: &str = c_string.as_str().unwrap();
			println!("Keycode: {}, Character {}", raw_bytes[1], char);

			// println!("nitems {}", (&*wm_name).nitems);
		}
		// get current focus window
		let current_window: *mut xlib::Window = &mut 0;
		let revert_to_return: *mut i32 = &mut 0;
		xlib::XGetInputFocus(display_control, current_window, revert_to_return);
		println!("revertToReturn {}", *revert_to_return);
		let mut j = 0u;
		let mut wm_name: *mut xutil::XTextProperty = std::mem::transmute(&mut j);
		let mut wm_name_true: &str = "";
		let mut tmp =0i8;
		let mut c_wm_name: CString = CString::new(&tmp,false);
		let mut res = 0;
		// res = xutil::XGetWMName(display_control, *current_window, wm_name);
		let mut i = 0u;
		while res == 0 && i < 2 {
			print!(".");
			println!("current_window {}", *current_window);
			res = xutil::XGetWMName(display_control, *current_window, wm_name);

			if res == 0 {
				println!("Move to parent");
				let mut root: xlib::Window = 0;
				let mut parent: xlib::Window = 0;
				let mut childrens: *mut xlib::Window = &mut 0u64;
				let mut nchildren: u32 = 0;
				let r2 = xlib::XQueryTree(display_control, *current_window, &mut root, &mut parent, &mut childrens, &mut nchildren);
				if r2 == 0 {
					print!("*");
				} else {
					println!("parent {}", parent);
					*current_window = parent;
				}
			}
			// get parent window
			i += 1;
		}
		println!("---");
		if res == 0 {
			println!("no wmname");
		} else {
			// extract name from XTextProperty
			println!("wmname found!");
			println!("format: {}", (*wm_name).format);
			if (*wm_name).format != 8 {
				fail!("");
			}
			println!("encoding: {}", (*wm_name).encoding);
			let encoding_name = xlib::XGetAtomName(display_control, (*wm_name).encoding);
			let encoding_name_string = CString::new(std::mem::transmute(encoding_name), false);
			println!("encoding name: {}", encoding_name_string.as_str().unwrap());
			let mut tmp2 = 0i8;
			let mut list: *mut *mut ::libc::c_char = std::mem::transmute(&mut &mut tmp2);
			let mut list_count: i32 = 0;
			let res3 = xutil::XmbTextPropertyToTextList(display_control, std::mem::transmute(wm_name), &mut list, &mut list_count);
			println!("convert result: {}", res3);
			if res3 == 0 {
				println!("list count {}", list_count);
				c_wm_name = CString::new(std::mem::transmute(*list), false);
				wm_name_true = c_wm_name.as_str().unwrap();
				println!("wm_name: {}", wm_name_true);
				xlib::XFreeStringList(list);
			} else {
				c_wm_name = CString::new(std::mem::transmute((*wm_name).value), false);
				// wm_name_true = c_wm_name.as_str().unwrap();
				println!("wm_name bytes: {}", c_wm_name.as_bytes());
				// ая -      27 45 76 208 239 32 27 37 71 226 128 162 27 37 64 32 45 32 83 117 98 108 105 109 101 32 84 101 120 116 32 40 85 78 82 69 71 73 83 84 69 82 69 68 41 0
				// бв -      27 45 76 209 210 32 27 37 71 226 128 162 27 37 64 32 45 32 83 117 98 108 105 109 101 32 84 101 120 116 32 40 85 78 82 69 71 73 83 84 69 82 69 68 41 0
				// длодлод - 27 45 76 212 219 222 212 219 222 212 32 27 37 71 226 128 162 27 37 64 32 45 32 83 117 98 108 105 109 101 32 84 101 120 116 32 40 85 78 82 69 71 73 83 84 69 82 69 68 41 0

				println!("wm_name: {}", c_wm_name);
				println!("wm_name len w/o null: {}", c_wm_name.len());
			}

		}

		XRecordFreeData(raw_data);
	}
	println!("\n");
}

// fn string_convert(string: *mut libc::c_char) -> &'static str{
// 	let temp = unsafe{CString::new(std::mem::transmute(string), true)};
// 	let a: &str = temp.as_str().unwrap();
// }<commit_msg>comments+<commit_after>#![feature(globs)]
extern crate libc;

use xlib::{XOpenDisplay, XDisplayName, XQueryExtension, XInitExtension, XSynchronize, XKeysymToString, XKeycodeToKeysym};
use libc::{c_int};
use std::ptr;
use xtst::{XRecordCreateContext, XRecordAllClients, XRecordAllocRange, XRecordRange, XRecordQueryVersion, XRecordEnableContext, XRecordEnableContextAsync,XRecordInterceptData, XRecordProcessReplies, XRecordFreeData};
use std::mem;
use std::c_str::CString;
mod xtst;
mod xlib;
mod xlibint;
mod xutil;

struct XRecordDatum {
  xtype: ::libc::c_uchar,
  event: ::xlib::XEvent,
  req:   ::xlibint::xResourceReq,
  reply: ::xlibint::xGenericReply,
  error: ::xlibint::xError,
  setup: ::xlibint::xConnSetupPrefix,
}

// let mut display_control: *mut xlib::Display  = std::mem::transmute(0);
// let mut display_data: *mut xlib::Display  = std::mem::transmute(0);
static mut display_control: *mut xlib::Display = 0 as *mut xlib::Struct__XDisplay;
static mut display_data: *mut xlib::Display = 0 as *mut xlib::Struct__XDisplay;
static mut event_count:u32 = 0;
fn main() {
	unsafe {
		let mut a:  i8 = 0;
		display_control = XOpenDisplay(&a);
		display_data = XOpenDisplay(&a);

		if display_data.is_null() || display_control.is_null() {
			fail!("XOpenDisplay() failed!");
		}

		XSynchronize(display_control, 1);

		let display_name = unsafe {XDisplayName(&a)};
		let ext_name = "RECORD";
		// Check presence of Record extension
		let arg2:*mut c_int = &mut 1;
		let arg3:*mut c_int = &mut 1;
		let arg4:*mut c_int = &mut 1;
		let has_record = XQueryExtension(display_control, ext_name.to_c_str().as_ptr() as *const i8,arg2,arg3,arg4);
		let extension = XInitExtension(display_control, ext_name.to_c_str().as_ptr() as *const i8);
		if extension.is_null() {
			fail!("XInitExtension() failed!");
		}

		// Get version
		let mut versionMajor: c_int = 0;
		let mut versionMinor: c_int = 0;
		XRecordQueryVersion(display_control, &mut versionMajor, &mut versionMinor);
		println!("RECORD extension version {}.{}", versionMajor, versionMinor);

		// Prepare record range
		let mut recordRange: XRecordRange = *XRecordAllocRange();
		let mut recordRangePtr: *mut *mut XRecordRange = std::mem::transmute(&mut &mut recordRange);
		recordRange.device_events.first = 2; // KeyPress
		recordRange.device_events.last = 6; // MotionNotify

		// Create context
		let context = XRecordCreateContext(
			display_control,
			0,
			&mut XRecordAllClients,
			1,
			recordRangePtr,
			1
		);
		if context == 0 {
			fail!("Fail create Record context\n");
		}

		// Run
		let res = XRecordEnableContextAsync(display_data, context, Some(recordCallback), &mut 0);
		if res == 0 {
			fail!("Cound not enable the Record context!\n");
		}
		xtst::XRecordFreeContext(display_data, context);
		loop {
			XRecordProcessReplies(display_data);
		}
	}
}

extern "C" fn recordCallback(pointer:*mut i8, raw_data: *mut XRecordInterceptData) {

	unsafe {

		let data = &*raw_data;
		// println!("Category {}", data.category);
		if data.category != xtst::XRecordFromServer {
			return;
		}
		println!("Event count: {}", event_count);
		event_count += 1;
		println!("Time {}", data.server_time);
		println!("Datalen {}", data.data_len);
		let mut xdatum_ptr: *mut XRecordDatum = data.data as *mut XRecordDatum;
		let mut xdatum = &*xdatum_ptr;

		let mut event = xdatum.event;
		println!("Type {}", xdatum.xtype);

		// Catch key event
		if xdatum.xtype == xtst::KeyPress || xdatum.xtype == xtst::KeyRelease {
			// extract key code
			let raw_bytes: &mut [u8,..4] = std::mem::transmute(data.data);
			let c_char  = XKeysymToString(XKeycodeToKeysym(display_control, raw_bytes[1], 0));
			let c_string = CString::new(std::mem::transmute(c_char), false);
			let char: &str = c_string.as_str().unwrap();
			println!("Keycode: {}, Character {}", raw_bytes[1], char);

			// println!("nitems {}", (&*wm_name).nitems);
		}
		// get current focus window
		let current_window: *mut xlib::Window = &mut 0;
		let revert_to_return: *mut i32 = &mut 0;
		xlib::XGetInputFocus(display_control, current_window, revert_to_return);
		println!("revertToReturn {}", *revert_to_return);
		let mut j = 0u;
		let mut wm_name: *mut xutil::XTextProperty = std::mem::transmute(&mut j);
		let mut wm_name_true: &str = "";
		let mut tmp =0i8;
		let mut c_wm_name: CString = CString::new(&tmp,false);
		let mut res = 0;
		// res = xutil::XGetWMName(display_control, *current_window, wm_name);
		let mut i = 0u;
		while res == 0 && i < 2 {
			print!(".");
			println!("current_window {}", *current_window);
			res = xutil::XGetWMName(display_control, *current_window, wm_name);

			if res == 0 {
				println!("Move to parent");
				let mut root: xlib::Window = 0;
				let mut parent: xlib::Window = 0;
				let mut childrens: *mut xlib::Window = &mut 0u64;
				let mut nchildren: u32 = 0;
				let r2 = xlib::XQueryTree(display_control, *current_window, &mut root, &mut parent, &mut childrens, &mut nchildren);
				if r2 == 0 {
					print!("*");
				} else {
					println!("parent {}", parent);
					*current_window = parent;
				}
			}
			// get parent window
			i += 1;
		}
		println!("---");
		if res == 0 {
			println!("no wmname");
		} else {
			// extract name from XTextProperty
			println!("wmname found!");
			println!("format: {}", (*wm_name).format);
			if (*wm_name).format != 8 {
				fail!("");
			}
			println!("encoding: {}", (*wm_name).encoding);
			let encoding_name = xlib::XGetAtomName(display_control, (*wm_name).encoding);
			let encoding_name_string = CString::new(std::mem::transmute(encoding_name), false);
			println!("encoding name: {}", encoding_name_string.as_str().unwrap());
			let mut tmp2 = 0i8;
			let mut list: *mut *mut ::libc::c_char = std::mem::transmute(&mut &mut tmp2);
			let mut list_count: i32 = 0;
			let res3 = xutil::XmbTextPropertyToTextList(display_control, std::mem::transmute(wm_name), &mut list, &mut list_count);
			println!("convert result: {}", res3);
			if res3 == 0 {
				println!("list count {}", list_count);
				c_wm_name = CString::new(std::mem::transmute(*list), false);
				wm_name_true = c_wm_name.as_str().unwrap();
				println!("wm_name: {}", wm_name_true);
				xlib::XFreeStringList(list);
			} else {
				c_wm_name = CString::new(std::mem::transmute((*wm_name).value), false);
				// wm_name_true = c_wm_name.as_str().unwrap();
				println!("wm_name bytes: {}", c_wm_name.as_bytes());
				// ая -      27 45 76 208 239 32 27 37 71 226 128 162 27 37 64 32 45 32 83 117 98 108 105 109 101 32 84 101 120 116 32 40 85 78 82 69 71 73 83 84 69 82 69 68 41 0
				// бв -      27 45 76 209 210 32 27 37 71 226 128 162 27 37 64 32 45 32 83 117 98 108 105 109 101 32 84 101 120 116 32 40 85 78 82 69 71 73 83 84 69 82 69 68 41 0
				// zx -      122 120 32 27 37 71 226 128 162 27 37 64 32 45 32 83 117 98 108 105 109 101 32 84 101 120 116 32 40 85 78 82 69 71 73 83 84 69 82 69 68 41 0
				// длодлод - 27 45 76 212 219 222 212 219 222 212 32 27 37 71 226 128 162 27 37 64 32 45 32 83 117 98 108 105 109 101 32 84 101 120 116 32 40 85 78 82 69 71 73 83 84 69 82 69 68 41 0
				// zx • - Sublime Text (UNREGISTERED)

				println!("wm_name: {}", c_wm_name);
				println!("wm_name len w/o null: {}", c_wm_name.len());
			}

		}

		XRecordFreeData(raw_data);
	}
	println!("\n");
}

// fn string_convert(string: *mut libc::c_char) -> &'static str{
// 	let temp = unsafe{CString::new(std::mem::transmute(string), true)};
// 	let a: &str = temp.as_str().unwrap();
// }<|endoftext|>


<commit_before>
use std::time::{Instant, Duration};
use std::ops::{Add, Sub, AddAssign, SubAssign};

/// Utility to track time in a program
#[derive(Clone)]
pub struct Timer {
    start: Instant,
    last: Instant,
}

impl Timer {
    pub fn new() -> Timer {
        let now = Instant::now();

        Timer {
            start: now,
            last: now,
        }
    }

    /// Returns `(time_since_start, time_since_last_tick)`
    pub fn tick(&mut self) -> (Timing, Timing) {
        let now = Instant::now();

        let age = (now - self.start).into();
        let delta = (now - self.last).into();

        self.last = now;

        (age, delta)
    }
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Timing(pub u64);

impl Timing {
    pub fn zero() -> Timing { Timing(0) }

    pub fn from_ms(ms: u64) -> Timing { Timing(ms * 1_000_000) }
    pub fn from_secs(s: u64) -> Timing { Timing(s * 1_000_000_000) }
    pub fn from_secs_float(s: f32) -> Timing { Timing((s * 1_000_000_000.0) as u64) }

    /// Converts this timing to seconds, truncating any overflow. 1.999 ms will be converted to 1 ms.
    pub fn as_ms(self) -> u64 { self.0 / 1_000_000 }

    /// Converts this timing to seconds, truncating any overflow. 1.999 seconds will be converted to 1.
    pub fn as_secs(self) -> u64 { self.0 / 1_000_000_000 }

    pub fn as_secs_float(self) -> f32 { self.0 as f32 / 1_000_000_000.0 }

    pub fn max(self, other: Timing) -> Timing {
        ::std::cmp::max(self, other)
    }

    pub fn min(self, other: Timing) -> Timing {
        ::std::cmp::min(self, other)
    }
}

impl Add for Timing {
    type Output = Timing;
    fn add(self, rhs: Timing) -> Timing {
        Timing(self.0 + rhs.0)
    }
}

impl Sub for Timing {
    type Output = Timing;
    fn sub(self, rhs: Timing) -> Timing {
        Timing(self.0 - rhs.0)
    }
}

impl AddAssign for Timing {
    fn add_assign(&mut self, rhs: Timing) {
        self.0 += rhs.0;
    }
}

impl SubAssign for Timing {
    fn sub_assign(&mut self, rhs: Timing) {
        self.0 -= rhs.0;
    }
}

impl From<Duration> for Timing {
    fn from(d: Duration) -> Timing {
        Timing(d.as_secs()*1_000_000_000 + (d.subsec_nanos() as u64))
    }
}

impl From<Timing> for Duration {
    fn from(t: Timing) -> Duration {
        let nanos = t.0 % 1_000_000_000;
        let secs = t.0 / 1_000_000_000;
        Duration::new(secs, nanos as u32)
    }
}
<commit_msg>Associated consts in time, Timing to Time<commit_after>
use std::time::{Instant, Duration};
use std::ops::{Add, Sub, AddAssign, SubAssign};

/// Utility to track time in a program
#[derive(Clone)]
pub struct Timer {
    start: Instant,
    last: Instant,
}

impl Timer {
    pub fn new() -> Timer {
        let now = Instant::now();

        Timer {
            start: now,
            last: now,
        }
    }

    /// Returns `(time_since_start, time_since_last_tick)`
    pub fn tick(&mut self) -> (Time, Time) {
        let now = Instant::now();

        let age = (now - self.start).into();
        let delta = (now - self.last).into();

        self.last = now;

        (age, delta)
    }
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Time(pub u64);

impl Time {
    pub const ZERO: Time = Time(0);

    pub fn from_ms(ms: u64) -> Time { Time(ms * 1_000_000) }
    pub fn from_secs(s: u64) -> Time { Time(s * 1_000_000_000) }
    pub fn from_secs_float(s: f32) -> Time { Time((s * 1_000_000_000.0) as u64) }

    /// Converts this timing to seconds, truncating any overflow. 1.999 ms will be converted to 1 ms.
    pub fn as_ms(self) -> u64 { self.0 / 1_000_000 }

    /// Converts this timing to seconds, truncating any overflow. 1.999 seconds will be converted to 1.
    pub fn as_secs(self) -> u64 { self.0 / 1_000_000_000 }

    pub fn as_secs_float(self) -> f32 { self.0 as f32 / 1_000_000_000.0 }

    pub fn max(self, other: Time) -> Time {
        ::std::cmp::max(self, other)
    }

    pub fn min(self, other: Time) -> Time {
        ::std::cmp::min(self, other)
    }
}

impl Add for Time {
    type Output = Time;
    fn add(self, rhs: Time) -> Time {
        Time(self.0 + rhs.0)
    }
}

impl Sub for Time {
    type Output = Time;
    fn sub(self, rhs: Time) -> Time {
        Time(self.0 - rhs.0)
    }
}

impl AddAssign for Time {
    fn add_assign(&mut self, rhs: Time) {
        self.0 += rhs.0;
    }
}

impl SubAssign for Time {
    fn sub_assign(&mut self, rhs: Time) {
        self.0 -= rhs.0;
    }
}

impl From<Duration> for Time {
    fn from(d: Duration) -> Time {
        Time(d.as_secs()*1_000_000_000 + (d.subsec_nanos() as u64))
    }
}

impl From<Time> for Duration {
    fn from(t: Time) -> Duration {
        let nanos = t.0 % 1_000_000_000;
        let secs = t.0 / 1_000_000_000;
        Duration::new(secs, nanos as u32)
    }
}
<|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::{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
        }
    }
}
<commit_msg>Formatting changes, use break instead of system.exit<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 Failed, Please make sure that you set a correct bot token.");

    // 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));
                        break;
                    } 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>use std::path::Path;
use std::io::Error;
use std::env;

extern crate walkdir;
extern crate xattr;
extern crate uuid;

use walkdir::{DirEntry, WalkDir, WalkDirIterator};
use uuid::Uuid;

fn filter_dirs(en: &DirEntry) -> bool {
    // To ignore internal directories
    en.file_name()
        .to_str()
        .map(|s| s.starts_with(".glusterfs") || s.starts_with(".trashcan") || s.starts_with(".shard"))
        .unwrap_or(false)
}

fn get_gfid(path: &str) -> Result<String, Error> {
    // Gets trusted.gfid xattr from the given path, Returns
    // empty string if UUID parsing fails
    let v = try!(xattr::get(path, "trusted.gfid"));
    let uuid = Uuid::from_bytes(&v);
    match uuid {
        Ok(v) => Ok(v.hyphenated().to_string()),
        Err(_) => Ok("".to_string()),
    }
}

// All output combinations
enum Reasons {
    Ok,
    NoGfid,
    NoPgfid,
    NoSymlink,
    WrongSymlink,
    InvalidGfid,
    InvalidPGfid,
}

fn output_display(reason: Reasons, entry: &DirEntry, gfid: &str, pgfid: &str) {
    let ok_msg = match reason {
        Reasons::Ok => "[    OK]              ",
        Reasons::NoGfid => "[NOT OK] NO GFID      ",
        Reasons::NoPgfid => "[NOT OK] NO PGFID     ",
        Reasons::NoSymlink => "[NOT OK] NO SYMLINK   ",
        Reasons::WrongSymlink => "[NOT OK] WRONG SYMLINK",
        Reasons::InvalidGfid => "[NOT OK] INVALID GFID ",
        Reasons::InvalidPGfid => "[NOT OK] INVALID PGFID",
    };
    println!("{} {:36} {:36} {}",
             ok_msg,
             gfid,
             pgfid,
             entry.path().display());
}

// path_is_symbolic_link

fn get_paths(path: &str) {
    println!("STATUS   DESCRIPTION   {:36} {:36} PATH", "GFID", "PGFID");
    println!("-------- ------------- ------------------------------------ \
              ------------------------------------ ---------------------");

    // Recursive crawl
    for entry in WalkDir::new(path).into_iter().filter_entry(|e| !filter_dirs(e)) {
        let entry = entry.unwrap();

        // Ignore Brick Root
        if entry.path().to_str().unwrap() == path {
            continue;
        }

        // If it is a directory
        if entry.file_type().is_dir() {
            // Collect the GFID of dir
            let gfid = match get_gfid(entry.path().to_str().unwrap()) {
                Ok(v) => {
                    if v == "".to_string() {
                        output_display(Reasons::InvalidGfid, &entry, "", "");
                        continue;
                    }
                    v
                }
                Err(_) => {
                    output_display(Reasons::NoGfid, &entry, "", "");
                    continue;
                }
            };

            // Construct the gfid path as
            // $BRICK/.glusterfs/<gfid[0:2]>/<gfid[2:4]>/<gfid>
            let (first_two, last) = gfid.split_at(2);
            let (next_two, _) = last.split_at(2);
            let gfid_path = Path::new(path)
                .join(".glusterfs")
                .join(first_two)
                .join(next_two)
                .join(&gfid);

            // Get Parent Dir GFID
            let pgfid = match get_gfid(entry.path().parent().unwrap().to_str().unwrap()) {
                Ok(v) => {
                    if v == "".to_string() {
                        output_display(Reasons::InvalidPGfid, &entry, &gfid, "");
                        continue;
                    }
                    v
                }
                Err(_) => {
                    output_display(Reasons::NoPgfid, &entry, &gfid, "");
                    continue;
                }
            };

            // Construct the pgfid path to compare with symlink target
            // ../../<pgfid[0:2]>/<pgfid[2:4]>/<pgfid>/<dirname>
            let (first_two_pgfid, last) = pgfid.split_at(2);
            let (next_two_pgfid, _) = last.split_at(2);
            let pgfid_path = Path::new("../../")
                .join(first_two_pgfid)
                .join(next_two_pgfid)
                .join(&pgfid)
                .join(entry.file_name().to_str().unwrap());

            // Try reading the symlink, All good if read link matches with expected pgfid_path
            // If target is different then it may have wrongly linked to different directory
            match gfid_path.read_link() {
                Ok(v) => {
                    if v == pgfid_path {
                        output_display(Reasons::Ok, &entry, &gfid, &pgfid);
                    } else {
                        output_display(Reasons::WrongSymlink, &entry, &gfid, &pgfid);
                    }
                }
                Err(_) => {
                    output_display(Reasons::NoSymlink, &entry, &gfid, &pgfid);
                }
            }
        }
    }
}

fn main() {
    let mut args = env::args();
    match args.nth(1) {
        Some(v) => get_paths(&v),
        None => println!("Brick path is required"),
    }
}
<commit_msg>Simplified backend path formation by using slice<commit_after>use std::path::Path;
use std::io::Error;
use std::env;

extern crate walkdir;
extern crate xattr;
extern crate uuid;

use walkdir::{DirEntry, WalkDir, WalkDirIterator};
use uuid::Uuid;

fn filter_dirs(en: &DirEntry) -> bool {
    // To ignore internal directories
    en.file_name()
        .to_str()
        .map(|s| s.starts_with(".glusterfs") || s.starts_with(".trashcan") || s.starts_with(".shard"))
        .unwrap_or(false)
}

fn get_gfid(path: &str) -> Result<String, Error> {
    // Gets trusted.gfid xattr from the given path, Returns
    // empty string if UUID parsing fails
    let v = try!(xattr::get(path, "trusted.gfid"));
    let uuid = Uuid::from_bytes(&v);
    match uuid {
        Ok(v) => Ok(v.hyphenated().to_string()),
        Err(_) => Ok("".to_string()),
    }
}

// All output combinations
enum Reasons {
    Ok,
    NoGfid,
    NoPgfid,
    NoSymlink,
    WrongSymlink,
    InvalidGfid,
    InvalidPGfid,
}

fn output_display(reason: Reasons, entry: &DirEntry, gfid: &str, pgfid: &str) {
    let ok_msg = match reason {
        Reasons::Ok => "[    OK]              ",
        Reasons::NoGfid => "[NOT OK] NO GFID      ",
        Reasons::NoPgfid => "[NOT OK] NO PGFID     ",
        Reasons::NoSymlink => "[NOT OK] NO SYMLINK   ",
        Reasons::WrongSymlink => "[NOT OK] WRONG SYMLINK",
        Reasons::InvalidGfid => "[NOT OK] INVALID GFID ",
        Reasons::InvalidPGfid => "[NOT OK] INVALID PGFID",
    };
    println!("{} {:36} {:36} {}",
             ok_msg,
             gfid,
             pgfid,
             entry.path().display());
}

// path_is_symbolic_link

fn get_paths(path: &str) {
    println!("STATUS   DESCRIPTION   {:36} {:36} PATH", "GFID", "PGFID");
    println!("-------- ------------- ------------------------------------ \
              ------------------------------------ ---------------------");

    // Recursive crawl
    for entry in WalkDir::new(path).into_iter().filter_entry(|e| !filter_dirs(e)) {
        let entry = entry.unwrap();

        // Ignore Brick Root
        if entry.path().to_str().unwrap() == path {
            continue;
        }

        // If it is a directory
        if entry.file_type().is_dir() {
            // Collect the GFID of dir
            let gfid = match get_gfid(entry.path().to_str().unwrap()) {
                Ok(v) => {
                    if v == "".to_string() {
                        output_display(Reasons::InvalidGfid, &entry, "", "");
                        continue;
                    }
                    v
                }
                Err(_) => {
                    output_display(Reasons::NoGfid, &entry, "", "");
                    continue;
                }
            };

            // Construct the gfid path as
            // $BRICK/.glusterfs/<gfid[0:2]>/<gfid[2:4]>/<gfid>
            let gfid_path = Path::new(path)
                .join(".glusterfs")
                .join(&gfid[0..2])
                .join(&gfid[2..4])
                .join(&gfid);

            // Get Parent Dir GFID
            let pgfid = match get_gfid(entry.path().parent().unwrap().to_str().unwrap()) {
                Ok(v) => {
                    if v == "".to_string() {
                        output_display(Reasons::InvalidPGfid, &entry, &gfid, "");
                        continue;
                    }
                    v
                }
                Err(_) => {
                    output_display(Reasons::NoPgfid, &entry, &gfid, "");
                    continue;
                }
            };

            // Construct the pgfid path to compare with symlink target
            // ../../<pgfid[0:2]>/<pgfid[2:4]>/<pgfid>/<dirname>
            let pgfid_path = Path::new("../../")
                .join(&pgfid[0..2])
                .join(&pgfid[2..4])
                .join(&pgfid)
                .join(entry.file_name().to_str().unwrap());

            // Try reading the symlink, All good if read link matches with expected pgfid_path
            // If target is different then it may have wrongly linked to different directory
            match gfid_path.read_link() {
                Ok(v) => {
                    if v == pgfid_path {
                        output_display(Reasons::Ok, &entry, &gfid, &pgfid);
                    } else {
                        output_display(Reasons::WrongSymlink, &entry, &gfid, &pgfid);
                    }
                }
                Err(_) => {
                    output_display(Reasons::NoSymlink, &entry, &gfid, &pgfid);
                }
            }
        }
    }
}

fn main() {
    let mut args = env::args();
    match args.nth(1) {
        Some(v) => get_paths(&v),
        None => println!("Brick path is required"),
    }
}
<|endoftext|>


<commit_before>use core::fmt::Show;
use std::hash::Hash;
use std::default::Default;

pub trait Time: Ord+Eq+PartialOrd+PartialEq+Copy+Default+Hash+Show+'static { }

impl Time for () { }
impl Time for uint { }
<commit_msg>cleaning up<commit_after><|endoftext|>


<commit_before>extern crate clock_ticks;
extern crate rand;
extern crate sdl2;

use rand::distributions::{IndependentSample, Range};

use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::keyboard::Scancode;
use sdl2::rect::Rect;
use sdl2::render::Renderer;
use sdl2::Sdl;
use sdl2::TimerSubsystem;
use sdl2::VideoSubsystem;

use std::default::Default;
use std::f32;
use std::path::Path;
use std::thread;

pub const FPS: u32 = 40;
pub const SCREEN_WIDTH: f32 = 600.;
pub const SCREEN_HEIGHT: f32 = 300.;

pub struct Ui {
    sdl_ctx: Sdl,
    renderer: Renderer<'static>
}

impl Ui {
    pub fn new() -> Ui {
        let sdl_ctx = sdl2::init().unwrap();
        let video_subsystem = sdl_ctx.video().unwrap();
        let window = video_subsystem.window("pong",
                SCREEN_WIDTH as u32, SCREEN_HEIGHT as u32)
                .position_centered()
                .build()
                .unwrap();
        let renderer = window.renderer().build().unwrap();
        Ui {
            sdl_ctx: sdl_ctx,
            renderer: renderer
        }
    }

    pub fn poll_event(&self) -> Option<Event> {
        let mut event_pump = self.sdl_ctx.event_pump().unwrap();
        return event_pump.poll_event();
    }
}

pub struct Ball {
    pub x: f32,         // x pixel co-ordinate of top left corner
    pub y: f32,         // y pixel co-ordinate of top left corner
    pub width: f32,     // pixels
    pub height: f32,    // pixels
    pub speed: f32,     // pixels per second
    pub vx: f32,        // pixels per second
    pub vy: f32         // pixels per second
}

impl Ball {
    pub fn new() -> Ball {
        let width = 10.;
        let height = 10.;

        // Place ball at center of screen.
        let x = (SCREEN_WIDTH - width) / 2.;
        let y = (SCREEN_HEIGHT - height) / 2.;

        // Able to travel height of screen in 1 second
        let speed = SCREEN_HEIGHT;
        let mut rng = rand::thread_rng();

        // Launch at an angle less than or equal to 45 degrees.
        let angle = Range::new(0., f32::consts::PI/4.).ind_sample(&mut rng);
        let dir = [-1., 1.];

        // Use the sine of the angle to determine the vertical speed. Then,
        // choose a direction (up or down) to select a vertical velocity.
        let up_or_down = rand::sample(&mut rng, dir.into_iter(),1)[0];
        let vy = angle.sin() * speed * up_or_down;
        let left_or_right = rand::sample(&mut rng, dir.into_iter(),1)[0];

        // Use Pythagoras to determine the horizontal speed. Then, choose a
        // direction (left or right) to select a horizontal velocity.
        let vx = ((speed * speed) - (vy * vy)).sqrt() * left_or_right;
        Ball {
            x: x,
            y: y,
            width: width,
            height: height,
            speed: speed,
            vx: vx,
            vy: vy
        }
    }
}

pub struct Game {
    ui: Ui,
    ball: Ball,
    running: bool
}

impl Game {

    /// Create initial game state.
    pub fn new() -> Game {
        Game {
            ui: Ui::new(),
            ball: Ball::new(),
            running: false,
        }
    }

    /// Start the game and block until finished.
    pub fn start(&mut self) {
        self.running = true;
        let mut time_last_invocation = clock_ticks::precise_time_ms();
        while self.running {
            let time_this_invocation = clock_ticks::precise_time_ms();
            let delta_time = time_this_invocation - time_last_invocation;
            self.update(delta_time as f32 / 1000.);
            self.cap_fps(delta_time);
            time_last_invocation = time_this_invocation;
        }
    }

    /// Called once per frame.
    fn update(&mut self, dt_sec: f32) {
        self.handle_input();
        self.update_ball_position(dt_sec);
        self.check_for_ball_and_wall_collisions();
        self.ui.renderer.clear();
        let ball = &mut self.ball;
        let rect = Rect::new_unwrap(ball.x as i32,
                                    ball.y as i32,
                                    ball.width as u32,
                                    ball.height as u32);
        self.ui.renderer.fill_rect(rect);
        self.ui.renderer.present();
    }

    fn handle_input(&mut self) {
        match self.ui.poll_event() {
            Some(event) => {
                match event {
                    Event::Quit{..} => {
                        self.running = false;
                    },
                    Event::KeyDown{keycode,..} => match keycode {
                        Option::Some(Keycode::Escape) => {
                            self.running = false;
                        },
                        _ => {}
                    },
                    _ => {}
                }
            },
            None => {}
        }
    }

    fn update_ball_position(&mut self, dt_sec: f32) {
        let ball = &mut self.ball;
        ball.x += ball.vx * dt_sec;
        ball.y += ball.vy * dt_sec;
    }

    fn check_for_ball_and_wall_collisions(&mut self) {
        self.check_for_ball_and_top_wall_collision();
        self.check_for_ball_and_right_wall_collision();
        self.check_for_ball_and_bottom_wall_collision();
        self.check_for_ball_and_left_wall_collision();
    }

    fn check_for_ball_and_top_wall_collision(&mut self) {
        let ball = &mut self.ball;
        if ball.y <= 0. && ball.vy < -0. {
            ball.y = 0.;
            ball.vy = -ball.vy;
        }
    }

    fn check_for_ball_and_right_wall_collision(&mut self) {
        let ball = &mut self.ball;
        if ball.x + ball.width >= SCREEN_WIDTH && ball.vx > 0. {
            ball.x = SCREEN_WIDTH - ball.width;
            ball.vx = -ball.vx;
        }
    }

    fn check_for_ball_and_bottom_wall_collision(&mut self) {
        let ball = &mut self.ball;
        if ball.y + ball.height >= SCREEN_HEIGHT && ball.vy > 0. {
            ball.y = SCREEN_HEIGHT - ball.height;
            ball.vy = -ball.vy;
        }
    }

    fn check_for_ball_and_left_wall_collision(&mut self) {
        let ball = &mut self.ball;
        if ball.x <= 0. && ball.vx < -0. {
            ball.x = 0.;
            ball.vx = -ball.vx;
        }
    }

    // Ensure we run no faster than the desired fps by introducing
    // a delay if necessary.
    fn cap_fps(&self, took_ms: u64) {
        let max_ms = 1000 / FPS as u64;
        if max_ms > took_ms {
            thread::sleep_ms((max_ms - took_ms) as u32);
        }
    }
}

fn main() {
    let mut game = Game::new();
    game.start();
}
<commit_msg>Use builder pattern to build game.<commit_after>extern crate clock_ticks;
extern crate rand;
extern crate sdl2;

use rand::distributions::{IndependentSample, Range};

use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::keyboard::Scancode;
use sdl2::rect::Rect;
use sdl2::render::Renderer;
use sdl2::Sdl;
use sdl2::TimerSubsystem;
use sdl2::VideoSubsystem;

use std::default::Default;
use std::f32;
use std::path::Path;
use std::thread;

pub struct Ui {
    width: f32,
    height: f32,
    sdl_ctx: Sdl,
    renderer: Renderer<'static>
}

impl Ui {
    pub fn new(width: f32, height: f32, sdl_ctx: Sdl, renderer: Renderer<'static>) -> Ui {
        Ui {
            width: width,
            height: height,
            sdl_ctx: sdl_ctx,
            renderer: renderer
        }
    }

    pub fn poll_event(&self) -> Option<Event> {
        let mut event_pump = self.sdl_ctx.event_pump().unwrap();
        return event_pump.poll_event();
    }
}

pub struct Ball {
    pub x: f32,         // x pixel co-ordinate of top left corner
    pub y: f32,         // y pixel co-ordinate of top left corner
    pub width: f32,     // pixels
    pub height: f32,    // pixels
    pub speed: f32,     // pixels per second
    pub vx: f32,        // pixels per second
    pub vy: f32         // pixels per second
}

impl Ball {
    pub fn new(x: f32, y: f32, width: f32, height: f32,
               speed: f32, vx: f32, vy: f32) -> Ball {
        Ball {
            x: x,
            y: y,
            width: width,
            height: height,
            speed: speed,
            vx: vx,
            vy: vy
        }
    }
}

pub struct Paddle {
    pub x: f32,         // x pixel co-ordinate of top left corner
    pub y: f32,         // y pixel co-ordinate of top left corner
    pub width: f32,     // pixels
    pub height: f32,    // pixels
    pub vy: f32,        // pixels per second
    pub score: u32
}

pub struct Game {
    ui: Ui,
    fps: u32,
    ball: Ball,
    running: bool
}

impl Game {

    /// Create initial game state.
    pub fn new(ui: Ui, fps: u32, ball: Ball) -> Game {
        Game {
            ui: ui,
            fps: fps,
            ball: ball,
            running: false,
        }
    }

    /// Start the game and block until finished.
    pub fn start(&mut self) {
        self.running = true;
        let mut time_last_invocation = clock_ticks::precise_time_ms();
        while self.running {
            let time_this_invocation = clock_ticks::precise_time_ms();
            let delta_time = time_this_invocation - time_last_invocation;
            self.update(delta_time as f32 / 1000.);
            self.cap_fps(delta_time);
            time_last_invocation = time_this_invocation;
        }
    }

    /// Called once per frame.
    fn update(&mut self, dt_sec: f32) {
        self.handle_input();
        self.update_ball_position(dt_sec);
        self.check_for_ball_and_wall_collisions();
        self.ui.renderer.clear();
        let ball = &mut self.ball;
        let rect = Rect::new_unwrap(ball.x as i32,
                                    ball.y as i32,
                                    ball.width as u32,
                                    ball.height as u32);
        self.ui.renderer.fill_rect(rect);
        self.ui.renderer.present();
    }

    fn handle_input(&mut self) {
        match self.ui.poll_event() {
            Some(event) => {
                match event {
                    Event::Quit{..} => {
                        self.running = false;
                    },
                    Event::KeyDown{keycode,..} => match keycode {
                        Option::Some(Keycode::Escape) => {
                            self.running = false;
                        },
                        _ => {}
                    },
                    _ => {}
                }
            },
            None => {}
        }
    }

    fn update_ball_position(&mut self, dt_sec: f32) {
        let ball = &mut self.ball;
        ball.x += ball.vx * dt_sec;
        ball.y += ball.vy * dt_sec;
    }

    fn check_for_ball_and_wall_collisions(&mut self) {
        let ball = &mut self.ball;

        // Left or right wall.
        if ball.x <= 0. && ball.vx < -0. {
            ball.x = 0.;
            ball.vx = -ball.vx;
        } else if ball.x + ball.width >= self.ui.width && ball.vx > 0. {
            ball.x = self.ui.width - ball.width;
            ball.vx = -ball.vx;
        }

        // Top or bottom wall.
        if ball.y <= 0. && ball.vy < -0. {
            ball.y = 0.;
            ball.vy = -ball.vy;
        } else if ball.y + ball.height >= self.ui.height && ball.vy > 0. {
            ball.y = self.ui.height - ball.height;
            ball.vy = -ball.vy;
        }
    }

    // Ensure we run no faster than the desired fps by introducing
    // a delay if necessary.
    fn cap_fps(&self, took_ms: u64) {
        let max_ms = 1000 / self.fps as u64;
        if max_ms > took_ms {
            thread::sleep_ms((max_ms - took_ms) as u32);
        }
    }
}

struct GameBuilder {
    screen_width: f32,
    screen_height: f32,
    fps: u32,
    ball_speed: f32,
    paddle_speed: f32
}

impl GameBuilder {

    pub fn new() -> GameBuilder {
        GameBuilder {
            screen_width: 480.,
            screen_height: 320.,
            fps: 40,
            ball_speed: 320.,
            paddle_speed: 640.
        }
    }

    pub fn with_dimensions(mut self, width: f32, height: f32) -> GameBuilder {
        self.screen_width = width;
        self.screen_height = height;
        self
    }

    pub fn with_fps(mut self, fps: u32) -> GameBuilder {
        self.fps = fps;
        self
    }

    pub fn with_ball_speed_per_sec(mut self, ball_speed: f32) -> GameBuilder {
        self.ball_speed = ball_speed;
        self
    }

    pub fn with_paddle_speed_per_sec(mut self, paddle_speed: f32) -> GameBuilder {
        self.paddle_speed = paddle_speed;
        self
    }

    fn create_ui(&self) -> Ui {
        let sdl_ctx = sdl2::init().unwrap();
        let video_subsystem = sdl_ctx.video().unwrap();
        let window = video_subsystem.window("pong",
                self.screen_width as u32, self.screen_height as u32)
                .position_centered()
                .build()
                .unwrap();
        let renderer = window.renderer().build().unwrap();
        Ui::new(self.screen_width, self.screen_height, sdl_ctx, renderer)
    }

    fn create_ball(&self) -> Ball {
        let width = 10.;
        let height = 10.;

        // Place ball at center of screen.
        let x = (self.screen_width - width) / 2.;
        let y = (self.screen_height - height) / 2.;

        let speed = self.ball_speed;
        let mut rng = rand::thread_rng();

        // Launch at an angle less than or equal to 45 degrees.
        let angle = Range::new(0., f32::consts::PI/4.).ind_sample(&mut rng);
        let dir = [-1., 1.];

        // Use the sine of the angle to determine the vertical speed. Then,
        // choose a direction (up or down) to select a vertical velocity.
        let up_or_down = rand::sample(&mut rng, dir.into_iter(),1)[0];
        let vy = angle.sin() * speed * up_or_down;
        let left_or_right = rand::sample(&mut rng, dir.into_iter(),1)[0];

        // Use Pythagoras to determine the horizontal speed. Then, choose a
        // direction (left or right) to select a horizontal velocity.
        let vx = ((speed * speed) - (vy * vy)).sqrt() * left_or_right;
        Ball::new(x, y, width, height, speed, vx, vy)
    }

    pub fn build(&self) -> Game {
        Game::new(self.create_ui(), self.fps, self.create_ball())
    }
}

fn main() {
    let mut game = GameBuilder::new()
        .with_dimensions(480., 320.)
        .with_fps(40)
        .with_ball_speed_per_sec(320.)
        .with_paddle_speed_per_sec(320.)
        .build();
    game.start();
}
<|endoftext|>


<commit_before>use error::Error;
use std::process::{Command,ExitStatus};
use super::Result;

const RED: &'static str = "red";
const BLACK: &'static str = "black";

pub fn flash_background() -> Result<()> {
    set_background(RED)?;
    set_background(BLACK)?;
    set_background(RED)?;
    set_background(BLACK)?;
    Ok(())
}

fn set_background(color: &str) -> Result<ExitStatus> {
    Command::new("tmux")
        .arg("select-pane")
        .arg("-P")
        .arg(format!("'bg={}'", color))
        .status()
        .map_err(|error| Error::Io(error))
}
<commit_msg>refactor: Cleanup tmux background flashing<commit_after>use error::Error;
use std::process::{Command,ExitStatus};
use std::thread::sleep;
use std::time::Duration;
use super::Result;

const RED: &'static str = "red";
const BLACK: &'static str = "black";

pub fn flash_background() -> Result<()> {
    for _ in 0..3 {
        set_background(RED)?;
        sleep(Duration::from_millis(300));
        set_background(BLACK)?;
        sleep(Duration::from_millis(300));
    }

    Ok(())
}

fn set_background(color: &str) -> Result<ExitStatus> {
    Command::new("tmux")
        .arg("select-pane")
        .arg("-P")
        .arg(format!("bg={}", color))
        .status()
        .map_err(|error| Error::Io(error))
}
<|endoftext|>


<commit_before>#![warn(bad_style)]
#![warn(missing_copy_implementations)]
#![warn(missing_debug_implementations)]
// #![warn(missing_docs)]
#![warn(trivial_casts)]
#![warn(trivial_numeric_casts)]
#![warn(unused)]
#![warn(unused_extern_crates)]
#![warn(unused_import_braces)]
#![warn(unused_qualifications)]
#![warn(unused_results)]
#![cfg_attr(feature = "nightly", feature(plugin))]
#![cfg_attr(feature = "nightly", plugin(clippy))]
#![cfg_attr(feature = "nightly", warn(mut_mut))]
#![cfg_attr(feature = "nightly", warn(string_add))]
#![cfg_attr(feature = "nightly", warn(string_add_assign))]
#![cfg_attr(feature = "nightly", feature(windows_subsystem))]
#![cfg_attr(feature = "nightly", windows_subsystem = "windows")]

#[macro_use]
extern crate conrod;
#[macro_use]
extern crate conrod_derive;
extern crate rand;
extern crate ttf_noto_sans;
extern crate vecmath;

use conrod::UiBuilder;
use conrod::backend::glium::Renderer;
use conrod::backend::glium::glium::{self, Display, Surface};
use conrod::backend::glium::glium::glutin::{ContextBuilder, Event, KeyboardInput, VirtualKeyCode,
                                            WindowBuilder, WindowEvent};
use conrod::backend::glium::glium::texture::Texture2d;
use conrod::image::Map as ImageMap;
use conrod::text::FontCollection;
use std::fmt;
use view::Ids;
use view_model::App;

mod model;
mod view;
mod view_model;

fn main() {
    const WIDTH: u32 = 1024;
    const HEIGHT: u32 = 768;

    let mut event_loop = EventLoop::new();
    let window = WindowBuilder::new()
        .with_title("Othello")
        .with_dimensions(WIDTH, HEIGHT);
    let context = ContextBuilder::new().with_vsync(true).with_multisampling(4);
    let display = Display::new(window, context, &event_loop.raw).expect("failed to create Display");
    let mut ui = UiBuilder::new([WIDTH as f64, HEIGHT as f64]).build();

    let font_collection = FontCollection::from_bytes(ttf_noto_sans::REGULAR);
    let _ = ui.fonts
        .insert(font_collection.into_font().expect("failed to into_font"));

    let mut renderer = Renderer::new(&display).expect("failed to create Renderer");
    let image_map = ImageMap::<Texture2d>::new();

    let mut app = App::default();
    let mut ids = Ids::new(ui.widget_id_generator());
    'main: loop {
        for event in event_loop.next() {
            // Use the `winit` backend feature to convert the winit event to a conrod one.
            if let Some(event) = conrod::backend::winit::convert_event(event.clone(), &display) {
                ui.handle_event(event);
                event_loop.needs_update();
            }

            match event {
                Event::WindowEvent { event, .. } => match event {
                    // Break from the loop upon `Escape`.
                    WindowEvent::Closed
                    | WindowEvent::KeyboardInput {
                        input:
                            KeyboardInput {
                                virtual_keycode: Some(VirtualKeyCode::Escape),
                                ..
                            },
                        ..
                    } => break 'main,
                    _ => (),
                },
                _ => (),
            }
        }

        {
            let ui = &mut ui.set_widgets();
            view::set_widgets(ui, &mut ids, &mut app);
        }

        if let Some(primitives) = ui.draw_if_changed() {
            renderer.fill(&display, primitives, &image_map);
            let mut target = display.draw();

            target.clear_color(0.0, 0.0, 0.0, 1.0);
            renderer.draw(&display, &mut target, &image_map).unwrap();
            target.finish().unwrap();
        }
    }
}

/// In most of the examples the `glutin` crate is used for providing the window context and
/// events while the `glium` crate is used for displaying `conrod::render::Primitives` to the
/// screen.
///
/// This `Iterator`-like type simplifies some of the boilerplate involved in setting up a
/// glutin+glium event loop that works efficiently with conrod.
pub struct EventLoop {
    raw: glium::glutin::EventsLoop,
    ui_needs_update: bool,
    last_update: std::time::Instant,
}

impl fmt::Debug for EventLoop {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "EventLoop {{ raw: ..., ui_needs_update: {:?}, last_update: {:?} }}",
            self.ui_needs_update,
            self.last_update
        )
    }
}

impl EventLoop {
    pub fn new() -> Self {
        EventLoop {
            raw: glium::glutin::EventsLoop::new(),
            last_update: std::time::Instant::now(),
            ui_needs_update: true,
        }
    }

    /// Produce an iterator yielding all available events.
    pub fn next(&mut self) -> Vec<glium::glutin::Event> {
        // We don't want to loop any faster than 60 FPS, so wait until it has been at least 16ms
        // since the last yield.
        let last_update = self.last_update;
        let sixteen_ms = std::time::Duration::from_millis(16);
        let duration_since_last_update = std::time::Instant::now().duration_since(last_update);
        if duration_since_last_update < sixteen_ms {
            std::thread::sleep(sixteen_ms - duration_since_last_update);
        }

        // Collect all pending events.
        let mut events = Vec::new();
        self.raw.poll_events(|event| events.push(event));

        // If there are no events and the `Ui` does not need updating, wait for the next event.
        if events.is_empty() && !self.ui_needs_update {
            self.raw.run_forever(|event| {
                events.push(event);
                glium::glutin::ControlFlow::Break
            });
        }

        self.ui_needs_update = false;
        self.last_update = std::time::Instant::now();

        events
    }

    /// Notifies the event loop that the `Ui` requires another update whether or not there are any
    /// pending events.
    ///
    /// This is primarily used on the occasion that some part of the `Ui` is still animating and
    /// requires further updates to do so.
    pub fn needs_update(&mut self) {
        self.ui_needs_update = true;
    }
}
<commit_msg>Fix unused qualification warning<commit_after>#![warn(bad_style)]
#![warn(missing_copy_implementations)]
#![warn(missing_debug_implementations)]
// #![warn(missing_docs)]
#![warn(trivial_casts)]
#![warn(trivial_numeric_casts)]
#![warn(unused)]
#![warn(unused_extern_crates)]
#![warn(unused_import_braces)]
#![warn(unused_qualifications)]
#![warn(unused_results)]
#![cfg_attr(feature = "nightly", feature(plugin))]
#![cfg_attr(feature = "nightly", plugin(clippy))]
#![cfg_attr(feature = "nightly", warn(mut_mut))]
#![cfg_attr(feature = "nightly", warn(string_add))]
#![cfg_attr(feature = "nightly", warn(string_add_assign))]
#![cfg_attr(feature = "nightly", feature(windows_subsystem))]
#![cfg_attr(feature = "nightly", windows_subsystem = "windows")]

#[macro_use]
extern crate conrod;
#[macro_use]
extern crate conrod_derive;
extern crate rand;
extern crate ttf_noto_sans;
extern crate vecmath;

use conrod::UiBuilder;
use conrod::backend::glium::Renderer;
use conrod::backend::glium::glium::{self, Display, Surface};
use conrod::backend::glium::glium::glutin::{ContextBuilder, Event, KeyboardInput, VirtualKeyCode,
                                            WindowBuilder, WindowEvent};
use conrod::backend::glium::glium::texture::Texture2d;
use conrod::image::Map as ImageMap;
use conrod::text::FontCollection;
use std::fmt;
use view::Ids;
use view_model::App;

mod model;
mod view;
mod view_model;

fn main() {
    const WIDTH: u32 = 1024;
    const HEIGHT: u32 = 768;

    let mut event_loop = EventLoop::new();
    let window = WindowBuilder::new()
        .with_title("Othello")
        .with_dimensions(WIDTH, HEIGHT);
    let context = ContextBuilder::new().with_vsync(true).with_multisampling(4);
    let display = Display::new(window, context, &event_loop.raw).expect("failed to create Display");
    let mut ui = UiBuilder::new([WIDTH as f64, HEIGHT as f64]).build();

    let font_collection = FontCollection::from_bytes(ttf_noto_sans::REGULAR);
    let _ = ui.fonts
        .insert(font_collection.into_font().expect("failed to into_font"));

    let mut renderer = Renderer::new(&display).expect("failed to create Renderer");
    let image_map = ImageMap::<Texture2d>::new();

    let mut app = App::default();
    let mut ids = Ids::new(ui.widget_id_generator());
    'main: loop {
        for event in event_loop.next() {
            // Use the `winit` backend feature to convert the winit event to a conrod one.
            if let Some(event) = conrod::backend::winit::convert_event(event.clone(), &display) {
                ui.handle_event(event);
                event_loop.needs_update();
            }

            match event {
                Event::WindowEvent { event, .. } => match event {
                    // Break from the loop upon `Escape`.
                    WindowEvent::Closed
                    | WindowEvent::KeyboardInput {
                        input:
                            KeyboardInput {
                                virtual_keycode: Some(VirtualKeyCode::Escape),
                                ..
                            },
                        ..
                    } => break 'main,
                    _ => (),
                },
                _ => (),
            }
        }

        {
            let ui = &mut ui.set_widgets();
            view::set_widgets(ui, &mut ids, &mut app);
        }

        if let Some(primitives) = ui.draw_if_changed() {
            renderer.fill(&display, primitives, &image_map);
            let mut target = display.draw();

            target.clear_color(0.0, 0.0, 0.0, 1.0);
            renderer.draw(&display, &mut target, &image_map).unwrap();
            target.finish().unwrap();
        }
    }
}

/// In most of the examples the `glutin` crate is used for providing the window context and
/// events while the `glium` crate is used for displaying `conrod::render::Primitives` to the
/// screen.
///
/// This `Iterator`-like type simplifies some of the boilerplate involved in setting up a
/// glutin+glium event loop that works efficiently with conrod.
pub struct EventLoop {
    raw: glium::glutin::EventsLoop,
    ui_needs_update: bool,
    last_update: std::time::Instant,
}

impl fmt::Debug for EventLoop {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "EventLoop {{ raw: ..., ui_needs_update: {:?}, last_update: {:?} }}",
            self.ui_needs_update,
            self.last_update
        )
    }
}

impl EventLoop {
    pub fn new() -> Self {
        EventLoop {
            raw: glium::glutin::EventsLoop::new(),
            last_update: std::time::Instant::now(),
            ui_needs_update: true,
        }
    }

    /// Produce an iterator yielding all available events.
    pub fn next(&mut self) -> Vec<Event> {
        // We don't want to loop any faster than 60 FPS, so wait until it has been at least 16ms
        // since the last yield.
        let last_update = self.last_update;
        let sixteen_ms = std::time::Duration::from_millis(16);
        let duration_since_last_update = std::time::Instant::now().duration_since(last_update);
        if duration_since_last_update < sixteen_ms {
            std::thread::sleep(sixteen_ms - duration_since_last_update);
        }

        // Collect all pending events.
        let mut events = Vec::new();
        self.raw.poll_events(|event| events.push(event));

        // If there are no events and the `Ui` does not need updating, wait for the next event.
        if events.is_empty() && !self.ui_needs_update {
            self.raw.run_forever(|event| {
                events.push(event);
                glium::glutin::ControlFlow::Break
            });
        }

        self.ui_needs_update = false;
        self.last_update = std::time::Instant::now();

        events
    }

    /// Notifies the event loop that the `Ui` requires another update whether or not there are any
    /// pending events.
    ///
    /// This is primarily used on the occasion that some part of the `Ui` is still animating and
    /// requires further updates to do so.
    pub fn needs_update(&mut self) {
        self.ui_needs_update = true;
    }
}
<|endoftext|>


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

mod download;
mod extract;
mod find_package;
mod package;
mod package_version;
mod verify;

use clap::{App, Arg};

arg_enum! {
    #[derive(Debug)]
    enum Method {
        Install,
        Remove
    }
}

fn main() {
    let arg_matches = App::new("wiz")
        .version("0.0.1")

        .arg(Arg::with_name("method")
             .help("Specifies what to do with the specified package")
             .index(1)
             .possible_values(&Method::variants())
             .required(true))

        .arg(Arg::with_name("package")
             .help("Specifies package")
             .index(2)
             .required(true))

        .get_matches();

    let method = value_t!(arg_matches.value_of("method"), Method).unwrap();
    let package = arg_matches.value_of("package").unwrap_or("invalid");

    match method {
        Method::Install => println!("install: {}", package),
        Method::Remove => println!("remove: {}", package)
    }
}
<commit_msg>Some command implementations<commit_after>#[macro_use]
extern crate clap;
extern crate rustc_serialize;

mod download;
mod extract;
mod find_package;
mod package;
mod package_version;
mod verify;

use clap::{App, Arg};
use std::path::Path;

arg_enum! {
    #[derive(Debug)]
    enum Method {
        Install,
        Remove
    }
}

fn main() {
    let arg_matches = App::new("wiz")
        .version("0.0.1")

        .arg(Arg::with_name("method")
             .help("Specifies what to do with the specified package")
             .index(1)
             .possible_values(&Method::variants())
             .required(true))

        .arg(Arg::with_name("package")
             .help("Specifies package")
             .index(2)
             .required(true))

        .get_matches();

    let method = value_t!(arg_matches.value_of("method"), Method).unwrap();
    let package = arg_matches.value_of("package").unwrap_or("invalid");

    match method {
        Method::Install => {
            println!("Installing package: {}", package);
            match package::installation::install_package(package, Path::new("wiz")) {
                Ok(_) => println!("Install complete"),
                Err(why) => println!("Install failed.\nReason: {}", why)
            }
        },
        Method::Remove => {
            println!("Uninstalling package: {}", package);
            match package::uninstallation::uninstall(package, Path::new("wiz")) {
                Ok(_) => println!("Uninstall complete"),
                Err(why) => println!("Uninstall failed.\nReason: {}", why)
            }
        }
    }
}
<|endoftext|>


<commit_before>#![feature(exit_status, std_misc, scoped)]
extern crate rustc_serialize;
extern crate unix_socket;

use std::io;
use std::io::{Read, Write, BufRead, BufReader};
use std::fs;
use std::net::TcpStream;
use std::env;
use std::error::Error;
use std::clone::Clone;
use std::thread;
use std::sync::mpsc::{channel, Sender, Receiver};

use rustc_serialize::{json, Decodable};
use unix_socket::UnixListener;

#[derive(RustcDecodable, RustcEncodable)]
struct Config  {
      path     : String
    , host     : String
    , port     : u16
    , nick     : String
    , user     : String
    , realname : String
    , channel  : String
}

fn strip_prefix<'a>(prefix : &str, s : &'a str) -> Option<&'a str>{
    if s.starts_with(prefix) {
        Some(&s[s.len()..])
    } else {
        None
    }
}

fn local_ipc(conf : &Config, tx : &Sender<String>) {
    // Delete old socket if necessary
    let _ = fs::remove_file(&conf.path);

    // Bind to socket
    let stream = UnixListener::bind(&conf.path).unwrap();
    let mut id = 0usize;
    for client in stream.incoming() {
        let tx = tx.clone();
        thread::spawn(move || {
            println!("Client {} connected", id);
            let reader = BufReader::new(client.unwrap());
            for line in reader.lines() {
                let line = line.unwrap();
                if line.len() == 0 {
                    continue;
                }
                println!("{}: {}", id, line);
                tx.send(line).unwrap();
            }
            println!("Client {} disconnected", id);
        });
        id += 1;
    }
}

fn irc_client(conf : &Config, rx : &Receiver<String>) -> Result<(), io::Error> {

    let stream = try!(TcpStream::connect((&conf.host[..], conf.port)));

    // Connect
    try!(writeln!(&stream, "USER {} 0 * :{}", conf.user, conf.realname));
    try!(writeln!(&stream, "NICK {}", conf.nick));
    try!(writeln!(&stream, "JOIN {}", conf.channel));

    let (irc_tx, irc_rx) = channel::<String>();

    let reader = BufReader::new(try!(stream.try_clone()));
    // Receieve network
    let guard = thread::scoped(move || {
        for line in reader.lines() {
            irc_tx.send(line.unwrap()).unwrap();
        }
    });

    loop {
        select! (
            msg = rx.recv() => {
                try!(writeln!(&stream, "PRIVMSG {} :{}", conf.channel, msg.unwrap()));
            },
            msg = irc_rx.recv() => {
                let s = msg.unwrap();
                let s = s[..].trim_right();
                println!("{}", s);
                strip_prefix("PING ", s).and_then(|s| writeln!(&stream, "PONG {}", s).ok());
            }
        )
    }
}

fn get_config() -> Result<Config, String> {
    let path = env::args().nth(1).unwrap_or("/etc/irc-relay.json".to_owned());

    let mut raw_file_utf8 = String::new();
    let _ = try!(fs::File::open(&path)
        .map_err(|x| format!("{}: {}", path, x)))
        .read_to_string(&mut raw_file_utf8);

    let json_object = try!(json::Json::from_str(&raw_file_utf8)
        .map_err(|x| format!("{}: {}", path, x)));
    let mut decoder = json::Decoder::new(json_object);
    Decodable::decode(&mut decoder)
        .map_err(|x| format!("{}: {}", path, x))

}

fn main() {
    let conf = match get_config() {
        Ok(s) => s,
        Err(e) => {
            println!("Error reading config: {}", e);
            env::set_exit_status(1);
            return;
        }
    };
    let (tx, rx) = channel::<String>();

    let guard = thread::scoped(|| {
        let tx = tx;
        local_ipc(&conf, &tx)
    });

    loop {
        match irc_client(&conf, &rx) {
            Err(e) => println!("Error: {}\nReconnecting..", e),
            Ok(_)  => ()
        }
    }
}
<commit_msg>bug fix pong<commit_after>#![feature(exit_status, std_misc, scoped)]
extern crate rustc_serialize;
extern crate unix_socket;

use std::io;
use std::io::{Read, Write, BufRead, BufReader};
use std::fs;
use std::net::TcpStream;
use std::env;
use std::error::Error;
use std::clone::Clone;
use std::thread;
use std::sync::mpsc::{channel, Sender, Receiver};

use rustc_serialize::json;
use unix_socket::UnixListener;

#[derive(RustcDecodable, RustcEncodable)]
struct Config  {
      path     : String
    , host     : String
    , port     : u16
    , nick     : String
    , user     : String
    , realname : String
    , channel  : String
}

fn strip_prefix<'a>(prefix : &str, s : &'a str) -> Option<&'a str>{
    if s.starts_with(prefix) {
        Some(&s[prefix.len()..])
    } else {
        None
    }
}

fn local_ipc(conf : &Config, tx : &Sender<String>) {
    // Delete old socket if necessary
    let _ = fs::remove_file(&conf.path);

    // Bind to socket
    let stream = UnixListener::bind(&conf.path).unwrap();
    let mut id = 0usize;
    for client in stream.incoming() {
        let tx = tx.clone();
        thread::spawn(move || {
            println!("Client {} connected", id);
            let reader = BufReader::new(client.unwrap());
            for line in reader.lines() {
                let line = line.unwrap();
                if line.len() == 0 {
                    continue;
                }
                println!("{}: {}", id, line);
                tx.send(line).unwrap();
            }
            println!("Client {} disconnected", id);
        });
        id += 1;
    }
}

fn irc_client(conf : &Config, rx : &Receiver<String>) -> Result<(), io::Error> {

    let stream = try!(TcpStream::connect((&conf.host[..], conf.port)));

    // Connect
    try!(writeln!(&stream, "USER {} 0 * :{}", conf.user, conf.realname));
    try!(writeln!(&stream, "NICK {}", conf.nick));
    try!(writeln!(&stream, "JOIN {}", conf.channel));

    let (irc_tx, irc_rx) = channel::<String>();

    let reader = BufReader::new(try!(stream.try_clone()));
    // Receieve network
    let guard = thread::scoped(move || {
        for line in reader.lines() {
            irc_tx.send(line.unwrap()).unwrap();
        }
    });

    loop {
        select! (
            msg = rx.recv() => {
                try!(writeln!(&stream, "PRIVMSG {} :{}", conf.channel, msg.unwrap()));
            },
            msg = irc_rx.recv() => {
                let s = msg.unwrap();
                let s = s[..].trim_right();
                println!("{}", s);
                strip_prefix("PING ", s).and_then(|s| writeln!(&stream, "PONG {}", s).ok());
            }
        )
    }
}

fn get_config() -> Result<Config, String> {
    let path = env::args().nth(1).unwrap_or("/etc/irc-relay.json".to_owned());

    let mut raw_file_utf8 = String::new();
    let _ = try!(fs::File::open(&path)
        .map_err(|x| format!("{}: {}", path, x)))
        .read_to_string(&mut raw_file_utf8);

    json::decode(&raw_file_utf8)
        .map_err(|x| format!("{}: {}", path, x))
}

fn main() {
    let conf = match get_config() {
        Ok(s) => s,
        Err(e) => {
            println!("Error reading config: {}", e);
            env::set_exit_status(1);
            return;
        }
    };
    let (tx, rx) = channel::<String>();

    let guard = thread::scoped(|| {
        let tx = tx;
        local_ipc(&conf, &tx)
    });

    loop {
        match irc_client(&conf, &rx) {
            Err(e) => println!("Error: {}\nReconnecting..", e),
            Ok(_)  => ()
        }
    }
}
<|endoftext|>


<commit_before>use std::io::{self, stdin, stdout, Write};
use std::iter::Peekable;
use std::str::CharIndices;

// TODO(tsion): Use the readline library.
fn prompt(line: &mut String) -> io::Result<usize> {
    let current_dir = try!(std::env::current_dir());
    print!("{}> ", current_dir.display());
    try!(stdout().flush());
    stdin().read_line(line)
}

#[derive(Clone, Debug, Eq, PartialEq)]
enum Ast {
    Empty,
    Call { command: String, args: Vec<String> }
}

#[derive(Clone, Debug, Eq, PartialEq)]
enum Token {
    Newline,
    Whitespace,
    Text(String),
}

#[derive(Clone)]
struct Lexer<'a> {
    input: &'a str,
    iter: Peekable<CharIndices<'a>>,
}

impl<'a> Lexer<'a> {
    fn new(input: &str) -> Lexer {
        Lexer {
            input: input,
            iter: input.char_indices().peekable(),
        }
    }

    fn pos(&mut self) -> usize {
        self.iter.peek().map(|p| p.0).unwrap_or(self.input.len())
    }

    fn peek_char(&mut self) -> Option<char> {
        self.iter.peek().map(|p| p.1)
    }

    fn is_whitespace(c: char) -> bool {
        c == ' ' || c == '\t'
    }

    fn lex_whitespace(&mut self) -> Token {
        while let Some(c) = self.peek_char() {
            if !Lexer::is_whitespace(c) { break; }
            self.iter.next();
        }

        Token::Whitespace
    }

    fn lex_unquoted_text(&mut self) -> Token {
        let start = self.pos();

        while let Some(c) = self.peek_char() {
            if Lexer::is_whitespace(c) || c == '\r' || c == '\n' { break; }
            self.iter.next();
        }

        let end = self.pos();

        // TODO(tsion): Do this without allocation.
        Token::Text(String::from(&self.input[start..end]))
    }
}

impl<'a> Iterator for Lexer<'a> {
    type Item = Token;

    fn next(&mut self) -> Option<Token> {
        self.peek_char().map(|peek_char| {
            match peek_char {
                '\r' | '\n'                  => Token::Newline,
                c if Lexer::is_whitespace(c) => self.lex_whitespace(),
                _                            => self.lex_unquoted_text(),
            }
        })
    }
}

#[derive(Clone)]
struct Parser<'a> {
    lexer: Lexer<'a>,
}

impl<'a> Parser<'a> {
    fn new(input: &str) -> Parser {
        Parser { lexer: Lexer::new(input) }
    }

    fn parse(&mut self) -> Ast {
        match self.lexer.next() {
            Some(Token::Whitespace) | Some(Token::Newline) => self.parse(),
            Some(Token::Text(command)) => self.parse_call(command),
            None => Ast::Empty,
        }
    }

    fn parse_call(&mut self, command: String) -> Ast {
        let mut args = vec![];

        for token in &mut self.lexer {
            match token {
                Token::Newline    => break,
                Token::Whitespace => {},
                Token::Text(arg)  => { args.push(arg); },
            }
        }

        Ast::Call { command: command, args: args }
    }
}

fn execute(ast: &Ast) -> io::Result<()> {
    match *ast {
        Ast::Empty => Ok(()),
        Ast::Call { ref command, ref args } => {
            match &command[..] {
                "cd" => {
                    if args.len() > 1 {
                        return Err(io::Error::new(io::ErrorKind::Other, "cd: too many arguments"));
                    }

                    if let Some(path) = args.get(0) {
                        std::env::set_current_dir(path)
                    } else if let Some(home) = std::env::home_dir() {
                        std::env::set_current_dir(home)
                    } else {
                        Err(io::Error::new(io::ErrorKind::Other, "cd: couldn't find home dir"))
                    }
                },

                "exit" => {
                    if args.len() > 1 {
                        return Err(io::Error::new(io::ErrorKind::Other,
                                                  "exit: too many arguments"));
                    }

                    if let Some(exit_code_str) = args.get(0) {
                        if let Ok(exit_code) = exit_code_str.parse() {
                            std::process::exit(exit_code);
                        } else {
                            Err(io::Error::new(io::ErrorKind::Other,
                                               "exit: couldn't parse exit code as integer"))
                        }
                    } else {
                        std::process::exit(0);
                    }
                }

                _ => {
                    std::process::Command::new(command).args(args).status().map(|_| ())
                },
            }
        },
    }
}

fn main() {
    let mut line = String::new();
    loop {
        prompt(&mut line).unwrap();
        let ast = Parser::new(&line).parse();
        if let Err(e) = execute(&ast) {
            println!("shroom: error: {}", e);
        }
        line.clear();
    }
}
<commit_msg>Factor out builtin command implementation.<commit_after>use std::collections::HashMap;
use std::io::{self, stdin, stdout, Write};
use std::iter::Peekable;
use std::str::CharIndices;

// TODO(tsion): Use the readline library.
fn prompt(line: &mut String) -> io::Result<usize> {
    let current_dir = try!(std::env::current_dir());
    print!("{}> ", current_dir.display());
    try!(stdout().flush());
    stdin().read_line(line)
}

#[derive(Clone, Debug, Eq, PartialEq)]
enum Ast {
    Empty,
    Call { command: String, args: Vec<String> }
}

#[derive(Clone, Debug, Eq, PartialEq)]
enum Token {
    Newline,
    Whitespace,
    Text(String),
}

#[derive(Clone)]
struct Lexer<'a> {
    input: &'a str,
    iter: Peekable<CharIndices<'a>>,
}

impl<'a> Lexer<'a> {
    fn new(input: &str) -> Lexer {
        Lexer {
            input: input,
            iter: input.char_indices().peekable(),
        }
    }

    fn pos(&mut self) -> usize {
        self.iter.peek().map(|p| p.0).unwrap_or(self.input.len())
    }

    fn peek_char(&mut self) -> Option<char> {
        self.iter.peek().map(|p| p.1)
    }

    fn is_whitespace(c: char) -> bool {
        c == ' ' || c == '\t'
    }

    fn lex_whitespace(&mut self) -> Token {
        while let Some(c) = self.peek_char() {
            if !Lexer::is_whitespace(c) { break; }
            self.iter.next();
        }

        Token::Whitespace
    }

    fn lex_unquoted_text(&mut self) -> Token {
        let start = self.pos();

        while let Some(c) = self.peek_char() {
            if Lexer::is_whitespace(c) || c == '\r' || c == '\n' { break; }
            self.iter.next();
        }

        let end = self.pos();

        // TODO(tsion): Do this without allocation.
        Token::Text(String::from(&self.input[start..end]))
    }
}

impl<'a> Iterator for Lexer<'a> {
    type Item = Token;

    fn next(&mut self) -> Option<Token> {
        self.peek_char().map(|peek_char| {
            match peek_char {
                '\r' | '\n'                  => Token::Newline,
                c if Lexer::is_whitespace(c) => self.lex_whitespace(),
                _                            => self.lex_unquoted_text(),
            }
        })
    }
}

#[derive(Clone)]
struct Parser<'a> {
    lexer: Lexer<'a>,
}

impl<'a> Parser<'a> {
    fn new(input: &str) -> Parser {
        Parser { lexer: Lexer::new(input) }
    }

    fn parse(&mut self) -> Ast {
        match self.lexer.next() {
            Some(Token::Whitespace) | Some(Token::Newline) => self.parse(),
            Some(Token::Text(command)) => self.parse_call(command),
            None => Ast::Empty,
        }
    }

    fn parse_call(&mut self, command: String) -> Ast {
        let mut args = vec![];

        for token in &mut self.lexer {
            match token {
                Token::Newline    => break,
                Token::Whitespace => {},
                Token::Text(arg)  => { args.push(arg); },
            }
        }

        Ast::Call { command: command, args: args }
    }
}

struct Builtin {
    name: &'static str,
    min_args: usize,
    max_args: usize,
    func: fn(&[String]) -> io::Result<()>,
}

fn builtin_cd(args: &[String]) -> io::Result<()> {
    if let Some(path) = args.get(0) {
        std::env::set_current_dir(path)
    } else if let Some(home) = std::env::home_dir() {
        std::env::set_current_dir(home)
    } else {
        Err(io::Error::new(io::ErrorKind::Other, "cd: couldn't find home dir"))
    }
}

fn builtin_exit(args: &[String]) -> io::Result<()> {
    if let Some(exit_code_str) = args.get(0) {
        if let Ok(exit_code) = exit_code_str.parse() {
            std::process::exit(exit_code);
        } else {
            Err(io::Error::new(io::ErrorKind::Other, "exit: couldn't parse exit code as integer"))
        }
    } else {
        std::process::exit(0);
    }
}

fn execute(ast: &Ast) -> io::Result<()> {
    let mut builtins = HashMap::new();

    builtins.insert("cd", Builtin {
        name: "cd",
        min_args: 0,
        max_args: 1,
        func: builtin_cd,
    });

    builtins.insert("exit", Builtin {
        name: "exit",
        min_args: 0,
        max_args: 1,
        func: builtin_exit,
    });

    match *ast {
        Ast::Empty => Ok(()),

        Ast::Call { ref command, ref args } => {
            if let Some(builtin) = builtins.get(&command[..]) {
                if args.len() < builtin.min_args {
                    return Err(io::Error::new(io::ErrorKind::Other,
                                              format!("{}: not enough arguments", builtin.name)));
                }

                if args.len() > builtin.max_args {
                    return Err(io::Error::new(io::ErrorKind::Other,
                                              format!("{}: too many arguments", builtin.name)));
                }

                (builtin.func)(args)
            } else {
                std::process::Command::new(command).args(args).status().map(|_| ())
            }
        },
    }
}

fn main() {
    let mut line = String::new();
    loop {
        prompt(&mut line).unwrap();
        let ast = Parser::new(&line).parse();
        if let Err(e) = execute(&ast) {
            println!("shroom: error: {}", e);
        }
        line.clear();
    }
}
<|endoftext|>