<commit_before>//! Coredump implementation of the Space API server.
//!
//! Start this via the commandline:
//!
//!     ./coredump_status [-p PORT] [-i IP]
extern crate env_logger;
extern crate docopt;
#[macro_use]
extern crate serde_derive;
extern crate spaceapi_server;

use std::env;
use docopt::Docopt;
use spaceapi_server::SpaceapiServerBuilder;
use spaceapi_server::api;
use spaceapi_server::modifiers::StateFromPeopleNowPresent;
use spaceapi_server::api::sensors::{TemperatureSensorTemplate, PeopleNowPresentSensorTemplate};

static USAGE: &'static str = "
Usage: coredump_status [-p PORT] [-i IP]

Options:
    -p PORT  The port to listen on [default: 3000].
    -i IP    The IP address to listen on [default: 127.0.0.1].
";

#[derive(Deserialize, Debug)]
struct Args {
    flag_p: u16,
    flag_i: std::net::IpAddr,
}

#[cfg_attr(test, allow(dead_code))]
fn main() {
    env_logger::init().unwrap();

    // Parse arguments
    let args: Args = Docopt::new(USAGE).and_then(|d| d.deserialize())
                                       .unwrap_or_else(|e| e.exit());
    let host = args.flag_i;
    let port = args.flag_p;

    // Create new Status instance
    let mut status = api::StatusBuilder::new("coredump")
        .logo("https://www.coredump.ch/wp-content/uploads/2016/11/logo.png")
        .url("https://www.coredump.ch/")
        .location(api::Location {
            address: Some("Zürcherstrasse 6, 8640 Rapperswil, Switzerland".into()),
            lat: 47.22939,
            lon: 8.82041,
        })
        .contact(api::Contact {
            irc: Some("irc://freenode.net/#coredump".into()),
            twitter: Some("@coredump_ch".into()),
            email: Some("vorstand@lists.coredump.ch".into()),
            ..Default::default()
        })
        .add_issue_report_channel("email")
        .add_issue_report_channel("twitter")
        .spacefed(api::Spacefed {
            spacenet: false,
            spacesaml: false,
            spacephone: false,
        })
        .feeds(api::Feeds {
            blog: Some(api::Feed {
                type_: Some("rss".into()),
                url: "https://www.coredump.ch/feed/".into(),
            }),
            wiki: None,
            calendar: None,
            flickr: None,
        })
        .add_project("https://www.coredump.ch/projekte/")
        .add_project("https://forum.coredump.ch/c/projects")
        .add_project("https://github.com/coredump-ch/")
        .add_cam("https://webcam.coredump.ch/cams/ultimaker_0.jpg")
        .build()
        .expect("Couldn't create status object");

    status.state.message = Some("Open Mondays from 20:00".into());

    // Redis connection info
    let redis_host: String = env::var("REDIS_HOST")
        .unwrap_or("127.0.0.1".to_string());
    let redis_port: u16 = env::var("REDIS_PORT")
        .unwrap_or("6379".to_string()).parse().unwrap_or(6379);
    let redis_db: i64 = env::var("REDIS_DB")
        .unwrap_or("0".to_string()).parse().unwrap_or(0);
    let redis_url = format!("redis://{}:{}/{}", redis_host, redis_port, redis_db);

    SpaceapiServerBuilder::new(status)
        .redis_connection_info(&*redis_url)
        .add_status_modifier(StateFromPeopleNowPresent)
        .add_sensor(TemperatureSensorTemplate {
            unit: "°C".into(),
            location: "Hackerspace".into(),
            name: Some("Raspberry CPU".into()),
            description: None,
        }, "temperature_raspi".into())
        .add_sensor(TemperatureSensorTemplate {
            unit: "°C".into(),
            location: "Hackerspace".into(),
            name: Some("Room Temperature".into()),
            description: None,
        }, "temperature_room".into())
        .add_sensor(PeopleNowPresentSensorTemplate {
            location: Some("Hackerspace".into()),
            name: None,
            description: None,
            names: None,
        }, "people_now_present".into())
        .build()
        .expect("Could not build server")
        .serve((host, port)).expect("Could not start the server");
}
<commit_msg>Update location data (#113)<commit_after>//! Coredump implementation of the Space API server.
//!
//! Start this via the commandline:
//!
//!     ./coredump_status [-p PORT] [-i IP]
extern crate env_logger;
extern crate docopt;
#[macro_use]
extern crate serde_derive;
extern crate spaceapi_server;

use std::env;
use docopt::Docopt;
use spaceapi_server::SpaceapiServerBuilder;
use spaceapi_server::api;
use spaceapi_server::modifiers::StateFromPeopleNowPresent;
use spaceapi_server::api::sensors::{TemperatureSensorTemplate, PeopleNowPresentSensorTemplate};

static USAGE: &'static str = "
Usage: coredump_status [-p PORT] [-i IP]

Options:
    -p PORT  The port to listen on [default: 3000].
    -i IP    The IP address to listen on [default: 127.0.0.1].
";

#[derive(Deserialize, Debug)]
struct Args {
    flag_p: u16,
    flag_i: std::net::IpAddr,
}

#[cfg_attr(test, allow(dead_code))]
fn main() {
    env_logger::init().unwrap();

    // Parse arguments
    let args: Args = Docopt::new(USAGE).and_then(|d| d.deserialize())
                                       .unwrap_or_else(|e| e.exit());
    let host = args.flag_i;
    let port = args.flag_p;

    // Create new Status instance
    let mut status = api::StatusBuilder::new("coredump")
        .logo("https://www.coredump.ch/wp-content/uploads/2016/11/logo.png")
        .url("https://www.coredump.ch/")
        .location(api::Location {
            address: Some("Holzwiesstrasse 50, 8645 Jona, Switzerland".into()),
            lat: 47.2359607,
            lon: 8.8410057,
        })
        .contact(api::Contact {
            irc: Some("irc://freenode.net/#coredump".into()),
            twitter: Some("@coredump_ch".into()),
            email: Some("vorstand@lists.coredump.ch".into()),
            ..Default::default()
        })
        .add_issue_report_channel("email")
        .add_issue_report_channel("twitter")
        .spacefed(api::Spacefed {
            spacenet: false,
            spacesaml: false,
            spacephone: false,
        })
        .feeds(api::Feeds {
            blog: Some(api::Feed {
                type_: Some("rss".into()),
                url: "https://www.coredump.ch/feed/".into(),
            }),
            wiki: None,
            calendar: None,
            flickr: None,
        })
        .add_project("https://www.coredump.ch/projekte/")
        .add_project("https://forum.coredump.ch/c/projects")
        .add_project("https://github.com/coredump-ch/")
        .add_cam("https://webcam.coredump.ch/cams/ultimaker_0.jpg")
        .build()
        .expect("Couldn't create status object");

    status.state.message = Some("Open Mondays from 20:00".into());

    // Redis connection info
    let redis_host: String = env::var("REDIS_HOST")
        .unwrap_or("127.0.0.1".to_string());
    let redis_port: u16 = env::var("REDIS_PORT")
        .unwrap_or("6379".to_string()).parse().unwrap_or(6379);
    let redis_db: i64 = env::var("REDIS_DB")
        .unwrap_or("0".to_string()).parse().unwrap_or(0);
    let redis_url = format!("redis://{}:{}/{}", redis_host, redis_port, redis_db);

    SpaceapiServerBuilder::new(status)
        .redis_connection_info(&*redis_url)
        .add_status_modifier(StateFromPeopleNowPresent)
        .add_sensor(TemperatureSensorTemplate {
            unit: "°C".into(),
            location: "Hackerspace".into(),
            name: Some("Raspberry CPU".into()),
            description: None,
        }, "temperature_raspi".into())
        .add_sensor(TemperatureSensorTemplate {
            unit: "°C".into(),
            location: "Hackerspace".into(),
            name: Some("Room Temperature".into()),
            description: None,
        }, "temperature_room".into())
        .add_sensor(PeopleNowPresentSensorTemplate {
            location: Some("Hackerspace".into()),
            name: None,
            description: None,
            names: None,
        }, "people_now_present".into())
        .build()
        .expect("Could not build server")
        .serve((host, port)).expect("Could not start the server");
}
<|endoftext|>


<commit_before>extern crate rand;

use rand::Rng;
use rand::distributions;
use individual::Individual;

mod individual;

fn select<R: Rng>(population: &Vec<Individual>, rng: &mut R)
                  -> Individual {
    if let Some(selected) = (0..4).map(|_| rng.choose(population)).min() {
        selected.unwrap().clone()
    } else {
        unimplemented!();
    }
}

fn main() {
    let mut rng = rand::thread_rng();
    let range = distributions::Range::new(-512.03_f64, 511.97);

    // initialize population
    let mut population: Vec<_> = (0..512).map(|_| {
        Individual::new(&range, &mut rng)
    }).collect();

    for i in 0..10000 {
        // select, mutate, and recombine individuals for next population
        let mut offspring: Vec<Individual> = Vec::with_capacity(population.len());
        for _ in (0..population.len()/2) {
            let (mut x, mut y) = (select(&population, &mut rng),
                                  select(&population, &mut rng));
            x.mutate(&range, &mut rng);
            y.mutate(&range, &mut rng);
            Individual::combine(&mut x, &mut y, &mut rng);
            offspring.push(x);
            offspring.push(y);
        }
        assert!(offspring.len() == population.len());
        population = offspring;

        if let Some(x) = population.iter().min() {
            if i % 100 == 0 {
                println!("{}th fitness: {}", i, x.fitness);
            }

            if x.fitness < 1000_f64 {
                println!("{}th solution converged at {}: {:?}",
                         i, x.fitness, x.solution);
                return;
            }
        } else { unimplemented!() }
    }
    println!("Failed to converge.");
}
<commit_msg>Implement elitism<commit_after>extern crate rand;

use rand::Rng;
use rand::distributions;
use individual::Individual;

mod individual;

fn select<R: Rng>(population: &Vec<Individual>, rng: &mut R)
                  -> Individual {
    if let Some(selected) = (0..4).map(|_| rng.choose(population)).min() {
        selected.unwrap().clone()
    } else {
        unimplemented!();
    }
}

fn main() {
    let mut rng = rand::thread_rng();
    let range = distributions::Range::new(-512.03_f64, 511.97);

    // initialize population
    let mut population: Vec<_> = (0..512).map(|_| {
        Individual::new(&range, &mut rng)
    }).collect();

    for i in 0..10000 {
        // select, mutate, and recombine individuals for next population
        let mut offspring: Vec<Individual> = Vec::with_capacity(population.len());
        for _ in (0..population.len()/2) {
            let (mut x, mut y) = (select(&population, &mut rng),
                                  select(&population, &mut rng));
            x.mutate(&range, &mut rng);
            y.mutate(&range, &mut rng);
            Individual::combine(&mut x, &mut y, &mut rng);
            offspring.push(x);
            offspring.push(y);
        }
        assert!(offspring.len() == population.len());

        // replace random individuals with elite of prior generation
        for _ in 0..2 {
            if let Some(x) = population.iter().min() {
                offspring[rng.gen_range(0, population.len())] = x.clone();
            }
        }

        population = offspring;

        if let Some(x) = population.iter().min() {
            if i % 100 == 0 {
                println!("{}th fitness: {}", i, x.fitness);
            }

            if x.fitness < 1000_f64 {
                println!("{}th solution converged at {}: {:?}",
                         i, x.fitness, x.solution);
                return;
            }
        } else { unimplemented!() }
    }
    println!("Failed to converge.");
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate log;
extern crate env_logger;
extern crate libc;
extern crate x11;

use std::ffi::CString;
use std::os::raw::{c_int, c_char};
use std::ptr;
use std::convert::From;

use x11::xlib;
use x11::xlib::{BadAccess, Display, Window, XErrorEvent, XOpenDisplay, XDefaultRootWindow,
                XSetErrorHandler};

#[derive(Debug)]
struct Win {
    display: *mut Display,
    xwindow: Window,
}

impl Win {
    // Does this really need to be &mut self? It feels light it ought to be as it is actually
    // modifying the underlying window, even if we're not actually modifying the value as far as
    // Rust is concerned.
    fn position(&mut self, x: i32, y: i32, width: i32, height: i32) -> Result<(), ()> {
        let mut changes = xlib::XWindowChanges {
            x: x,
            y: y,
            width: width,
            height: height,

            // Ignored:
            border_width: 0,
            sibling: 0,
            stack_mode: 0,
        };
        let flags = (xlib::CWX | xlib::CWY | xlib::CWWidth | xlib::CWHeight) as u32;

        unsafe {
            xlib::XConfigureWindow(self.display, self.xwindow, flags, &mut changes);
        };

        Ok(())
    }
}

trait Layout {
    fn layout(&self, width: i32, height: i32, stack: &mut [Win]) -> Result<(), ()>;
}

struct TiledLayout;

impl Layout for TiledLayout {
    fn layout(&self, width: i32, height: i32, stack: &mut [Win]) -> Result<(), ()> {
        if stack.len() == 0 {
            return Ok(());
        }

        let tile_height = height / stack.len() as i32;

        for (i, window) in stack.iter_mut().enumerate() {
            window.position(0, i as i32 * tile_height, width, tile_height)?;
        }

        Ok(())
    }
}

// Error handler used during setup, which simply checks for the BadAccess error
// which indicates that another WM is already running.
unsafe extern "C" fn error_handler_init(disp: *mut Display, err: *mut XErrorEvent) -> c_int {
    if (*err).error_code == BadAccess {
        panic!("Another WM is already running");
    }
    0
}

// Actual error handler used during normal operation.
unsafe extern "C" fn error_handler(disp: *mut Display, err: *mut XErrorEvent) -> c_int {
    let buffer_size: usize = 1024;
    let mut buffer = Vec::<u8>::with_capacity(buffer_size);
    // XXX the docs say this returns the error text in the 'current locale'. We're
    // being extremely naughty and assuming this is UTF-8.
    // We're also assuming the return value of XGetErrorText is the actual length
    // of the string.
    let len: c_int = xlib::XGetErrorText(disp,
                                         (*err).error_code as i32,
                                         buffer.as_mut_ptr() as *mut c_char,
                                         buffer_size as i32);
    buffer.truncate(len as usize);
    let error_text = CString::new(buffer).unwrap().into_string().unwrap();
    error!("Received X error: request={}, error_code=({}, {}), resource_id={}",
           (*err).request_code,
           (*err).error_code,
           error_text,
           (*err).resourceid);
    0
}

fn xevent_to_str(event: &xlib::XEvent) -> &str {
    match event.get_type() {
        2 => "KeyPress",
        3 => "KeyRelease",
        4 => "ButtonPress",
        5 => "ButtonRelease",
        6 => "MotionNotify",
        7 => "EnterNotify",
        8 => "LeaveNotify",
        9 => "FocusIn",
        10 => "FocusOut",
        11 => "KeymapNotify",
        12 => "Expose",
        13 => "GraphicsExpose",
        14 => "NoExpose",
        15 => "VisibilityNotify",
        16 => "CreateNotify",
        17 => "DestroyNotify",
        18 => "UnmapNotify",
        19 => "MapNotify",
        20 => "MapRequest",
        21 => "ReparentNotify",
        22 => "ConfigureNotify",
        23 => "ConfigureRequest",
        24 => "GravityNotify",
        25 => "ResizeRequest",
        26 => "CirculateNotify",
        27 => "CirculateRequest",
        28 => "PropertyNotify",
        29 => "SelectionClear",
        30 => "SelectionRequest",
        31 => "SelectionNotify",
        32 => "ColormapNotify",
        33 => "ClientMessage",
        34 => "MappingNotify",
        35 => "GenericEvent",
        36 => "LASTEvent",
        _ => {
            error!("Unknown XEvent type: {}", event.get_type());
            "Unknown"
        }
    }
}

fn main() {
    env_logger::init().unwrap();

    unsafe {
        let disp: *mut Display = XOpenDisplay(ptr::null_mut());
        assert!(!disp.is_null());
        let root: Window = XDefaultRootWindow(disp);
        assert!(root != 0);

        XSetErrorHandler(Some(error_handler_init));
        xlib::XSelectInput(disp,
                           root,
                           xlib::SubstructureNotifyMask | xlib::SubstructureRedirectMask);
        xlib::XSync(disp, 0);

        // If we get this far, then our panicing error handler didn't complain!
        info!("We are now the WM");

        XSetErrorHandler(Some(error_handler));

        let mut attrs: xlib::XWindowAttributes = std::mem::zeroed();
        xlib::XGetWindowAttributes(disp, root, &mut attrs);
        info!("Root window has geometry: {}x{}", attrs.width, attrs.height);

        let mut stack: Vec<Win> = Vec::new();

        let layout = TiledLayout {};

        loop {
            info!("Getting event...");
            let mut event = xlib::XEvent { pad: [0; 24] };
            xlib::XNextEvent(disp, &mut event);
            info!("Received event: {}", xevent_to_str(&event));

            match event.get_type() {
                xlib::MapRequest => {
                    let event = xlib::XMapRequestEvent::from(event);

                    stack.push(Win {
                                   display: disp,
                                   xwindow: event.window,
                               });

                    layout.layout(attrs.width, attrs.height, stack.as_mut());

                    // TODO: Make this into a method on Win?
                    xlib::XMapWindow(disp, event.window);
                }

                xlib::DestroyNotify => {
                    let event = xlib::XDestroyWindowEvent::from(event);

                    stack.iter().position(|ref w| w.xwindow == event.window).map(|index| stack.remove(index));

                    layout.layout(attrs.width, attrs.height, stack.as_mut());
                }
                _ => {}
            }

            println!("Stack: {:?}", stack);
        }

    };
    println!("Hello, world!");
}
<commit_msg>Basic infrastructure for handling key-presses.<commit_after>#[macro_use]
extern crate log;
extern crate env_logger;
extern crate libc;
extern crate x11;

use std::ffi::CString;
use std::os::raw::{c_int, c_char};
use std::ptr;
use std::convert::From;

use x11::xlib;
use x11::xlib::{BadAccess, Display, Window, XErrorEvent, XOpenDisplay, XDefaultRootWindow,
                XSetErrorHandler};

#[derive(Debug)]
struct Win {
    display: *mut Display,
    xwindow: Window,
}

impl Win {
    // Does this really need to be &mut self? It feels light it ought to be as it is actually
    // modifying the underlying window, even if we're not actually modifying the value as far as
    // Rust is concerned.
    fn position(&mut self, x: i32, y: i32, width: i32, height: i32) -> Result<(), ()> {
        let mut changes = xlib::XWindowChanges {
            x: x,
            y: y,
            width: width,
            height: height,

            // Ignored:
            border_width: 0,
            sibling: 0,
            stack_mode: 0,
        };
        let flags = (xlib::CWX | xlib::CWY | xlib::CWWidth | xlib::CWHeight) as u32;

        unsafe {
            xlib::XConfigureWindow(self.display, self.xwindow, flags, &mut changes);
        };

        Ok(())
    }

    fn grab_keys(&mut self, keys: &[Key]) {
        for key in keys.iter() {
            unsafe {
                let keycode = xlib::XKeysymToKeycode(self.display, key.keysym as u64) as i32;
                xlib::XGrabKey(self.display,
                               keycode,
                               key.mod_mask,
                               self.xwindow,
                               0,
                               xlib::GrabModeAsync,
                               xlib::GrabModeAsync);
            }
        }
    }
}

trait Layout {
    fn layout(&self, width: i32, height: i32, stack: &mut [Win]) -> Result<(), ()>;
}

struct TiledLayout;

impl Layout for TiledLayout {
    fn layout(&self, width: i32, height: i32, stack: &mut [Win]) -> Result<(), ()> {
        if stack.len() == 0 {
            return Ok(());
        }

        let tile_height = height / stack.len() as i32;

        for (i, window) in stack.iter_mut().enumerate() {
            window.position(0, i as i32 * tile_height, width, tile_height)?;
        }

        Ok(())
    }
}

// Error handler used during setup, which simply checks for the BadAccess error
// which indicates that another WM is already running.
unsafe extern "C" fn error_handler_init(disp: *mut Display, err: *mut XErrorEvent) -> c_int {
    if (*err).error_code == BadAccess {
        panic!("Another WM is already running");
    }
    0
}

// Actual error handler used during normal operation.
unsafe extern "C" fn error_handler(disp: *mut Display, err: *mut XErrorEvent) -> c_int {
    let buffer_size: usize = 1024;
    let mut buffer = Vec::<u8>::with_capacity(buffer_size);
    // XXX the docs say this returns the error text in the 'current locale'. We're
    // being extremely naughty and assuming this is UTF-8.
    // We're also assuming the return value of XGetErrorText is the actual length
    // of the string.
    let len: c_int = xlib::XGetErrorText(disp,
                                         (*err).error_code as i32,
                                         buffer.as_mut_ptr() as *mut c_char,
                                         buffer_size as i32);
    buffer.truncate(len as usize);
    let error_text = CString::new(buffer).unwrap().into_string().unwrap();
    error!("Received X error: request={}, error_code=({}, {}), resource_id={}",
           (*err).request_code,
           (*err).error_code,
           error_text,
           (*err).resourceid);
    0
}

fn xevent_to_str(event: &xlib::XEvent) -> &str {
    match event.get_type() {
        2 => "KeyPress",
        3 => "KeyRelease",
        4 => "ButtonPress",
        5 => "ButtonRelease",
        6 => "MotionNotify",
        7 => "EnterNotify",
        8 => "LeaveNotify",
        9 => "FocusIn",
        10 => "FocusOut",
        11 => "KeymapNotify",
        12 => "Expose",
        13 => "GraphicsExpose",
        14 => "NoExpose",
        15 => "VisibilityNotify",
        16 => "CreateNotify",
        17 => "DestroyNotify",
        18 => "UnmapNotify",
        19 => "MapNotify",
        20 => "MapRequest",
        21 => "ReparentNotify",
        22 => "ConfigureNotify",
        23 => "ConfigureRequest",
        24 => "GravityNotify",
        25 => "ResizeRequest",
        26 => "CirculateNotify",
        27 => "CirculateRequest",
        28 => "PropertyNotify",
        29 => "SelectionClear",
        30 => "SelectionRequest",
        31 => "SelectionNotify",
        32 => "ColormapNotify",
        33 => "ClientMessage",
        34 => "MappingNotify",
        35 => "GenericEvent",
        36 => "LASTEvent",
        _ => {
            error!("Unknown XEvent type: {}", event.get_type());
            "Unknown"
        }
    }
}

fn key_handler() {
    info!("Key press!");
}

struct Key {
    mod_mask: std::os::raw::c_uint,
    keysym: std::os::raw::c_uint,
    handler: Box<Fn()>,
}

impl std::fmt::Display for Key {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f,
               "Key {{ mod_mask: {}, keysym: {} }}",
               self.mod_mask,
               self.keysym)
    }
}

fn main() {
    env_logger::init().unwrap();

    let keys = vec![Key {
                        mod_mask: xlib::Mod4Mask,
                        keysym: x11::keysym::XK_T,
                        handler: Box::new(key_handler),
                    }];

    unsafe {
        let disp: *mut Display = XOpenDisplay(ptr::null_mut());
        assert!(!disp.is_null());
        let root: Window = XDefaultRootWindow(disp);
        assert!(root != 0);

        XSetErrorHandler(Some(error_handler_init));
        xlib::XSelectInput(disp,
                           root,
                           xlib::SubstructureNotifyMask | xlib::SubstructureRedirectMask);
        xlib::XSync(disp, 0);

        // If we get this far, then our panicing error handler didn't complain!
        info!("We are now the WM");

        XSetErrorHandler(Some(error_handler));

        let mut attrs: xlib::XWindowAttributes = std::mem::zeroed();
        xlib::XGetWindowAttributes(disp, root, &mut attrs);
        info!("Root window has geometry: {}x{}", attrs.width, attrs.height);

        let mut stack: Vec<Win> = Vec::new();

        let layout = TiledLayout {};

        loop {
            info!("Getting event...");
            let mut event = xlib::XEvent { pad: [0; 24] };
            xlib::XNextEvent(disp, &mut event);
            info!("Received event: {}", xevent_to_str(&event));

            match event.get_type() {
                xlib::MapRequest => {
                    let event = xlib::XMapRequestEvent::from(event);
                    let mut window = Win {
                        display: disp,
                        xwindow: event.window,
                    };
                    window.grab_keys(&keys);

                    stack.push(window);

                    layout.layout(attrs.width, attrs.height, stack.as_mut());

                    // TODO: Make this into a method on Win?
                    xlib::XMapWindow(disp, event.window);

                }

                xlib::DestroyNotify => {
                    let event = xlib::XDestroyWindowEvent::from(event);

                    stack.iter().position(|ref w| w.xwindow == event.window).map(|index| stack.remove(index));

                    layout.layout(attrs.width, attrs.height, stack.as_mut());
                }

                xlib::KeyPress => {
                    let event = xlib::XKeyEvent::from(event);

                    for key in keys.iter() {
                        let keycode = xlib::XKeysymToKeycode(disp, key.keysym as u64) as u32;
                        debug!("KeyPress: state={}, keycode={}", event.state, event.keycode);

                        // TODO: Allow extra mod keys to be pressed at the same time. (Add test!)
                        if (event.state & key.mod_mask != 0) && event.keycode == keycode {
                            info!("KeyPress matches key: {}", key);
                            (key.handler)();
                            break;
                        }
                    }

                }

                _ => {}
            }

            println!("Stack: {:?}", stack);
        }

    };
    println!("Hello, world!");
}
<|endoftext|>


<commit_before>// See LICENSE file for copyright and license details.

#![feature(old_path, old_io, core, std_misc, collections, str_words, box_syntax)] // TODO

#[cfg(target_os = "android")]
#[macro_use]
extern crate android_glue;

extern crate rand;
extern crate libc;
extern crate time;
extern crate cgmath;
extern crate "zoc_gl" as gl;
extern crate glutin;
extern crate image;
extern crate stb_tt;

mod core;
mod visualizer;

use visualizer::{Visualizer};

#[cfg(target_os = "android")]
android_start!(main);

pub fn main() {
    let mut visualizer = Visualizer::new();
    while visualizer.is_running() {
        visualizer.tick();
    }
}

#[cfg(target_os = "android")]
#[no_mangle]
pub fn rust_android_main(app: *mut()) {
    android_glue::android_main2(app, move|| main());
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<commit_msg>Removed unused 'rust_android_main' func<commit_after>// See LICENSE file for copyright and license details.

#![feature(old_path, old_io, core, std_misc, collections, str_words, box_syntax)] // TODO

#[cfg(target_os = "android")]
#[macro_use]
extern crate android_glue;

extern crate rand;
extern crate libc;
extern crate time;
extern crate cgmath;
extern crate "zoc_gl" as gl;
extern crate glutin;
extern crate image;
extern crate stb_tt;

mod core;
mod visualizer;

use visualizer::{Visualizer};

#[cfg(target_os = "android")]
android_start!(main);

pub fn main() {
    let mut visualizer = Visualizer::new();
    while visualizer.is_running() {
        visualizer.tick();
    }
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<|endoftext|>


<commit_before>#![feature(convert)]
extern crate clipboard;
extern crate byteorder;
extern crate argparse;

use clipboard::ClipboardContext;
use std::net::{TcpListener,TcpStream};
use std::io::{Error, ErrorKind, Result, Read,Write};
use std::thread;
use byteorder::{ReadBytesExt, WriteBytesExt,  LittleEndian};
use std::sync::mpsc::{Sender, channel};
use std::time::Duration;
use argparse::{ArgumentParser, Store};

struct Config {
    port : u16,
    localip : String,
    outsideip : String
}

fn run_reading(stream : &mut TcpStream,content : Sender<String>) -> Result<()>{
    loop {
        println!("Waiting for a data");
        let length : u32 = try!(stream.read_u32::<LittleEndian>());
        if length == 0{
            // ignore empty
            continue;
        }
        println!("Got the data size: {}", length);
        let mut data = vec![0u8;length as usize];
        try!(stream.take(length as u64).read_to_end(&mut data));
        match String::from_utf8(data){
            Ok(s) => {
                println!("Received new content from the other side: {}", s);
                let _ = content.send(s);
            }
            Err(_) => {
                println!("Failed to convert received content to string.");
            }
        };
    }
}

fn run_sync(stream : &mut TcpStream) -> Result<()>{
    let mut ctx = match ClipboardContext::new(){
        Ok(c) => c,
        Err(_) => return Err(Error::new(ErrorKind::Other,"Failed to create clipboard context"))
    };
    // println!("{}", ctx.get_contents().unwrap());
    //
    // ctx.set_contents("the new content".to_owned()).unwrap();
    let mut current_content = match ctx.get_contents(){
        Ok(s) => s,
        Err(_) => "".to_owned()
    };
    let (wx, rx) = channel::<String>();
    // // create thread which will read the stream for changes from outside, and apply changes to this system
    //
    let mut reading = stream.try_clone().unwrap();
    thread::spawn(move||{run_reading(&mut reading,wx)});
    let mut writer = stream.try_clone().unwrap();

    println!("initial clipboard value is: {}",current_content );

    loop{
        thread::sleep(Duration::new(1,0));
        println!("Checking for new content!");
        match ctx.get_contents(){
            Ok(s) => {

                if s != current_content{
                    println!("A new content, sending it to the other side: {}!={}",s,current_content);
                    current_content = s.clone();
                    let data = s.as_bytes();
                    try!(writer.write_u32::<LittleEndian>(data.len() as u32));
                    try!(writer.write(data));
                }
                match rx.try_recv(){
                    Ok(v) =>{
                        println!("Received a new value for cb: {}", v );
                        if v != current_content{
                            current_content = v.clone();
                            match ctx.set_contents(v){
                                Ok(_) => println!("Seting the new value as clipboard content."),
                                Err(_) => println!("Failde to set the new value as clipboard content.")
                            }
                        }
                    }
                    Err(_) => ()
                }
            }
            Err(_) => ()
        };

    }
}

fn try_run_client(config : &Config) -> Result<()>{
    let mut stream = try!(TcpStream::connect((config.outsideip.as_str(),config.port)));
    run_sync(&mut stream)
}

fn run_server(config : &Config) -> Result<()> {
    let listener = try!(TcpListener::bind((config.localip.as_str(),config.port)));

    for stream in listener.incoming(){
        match stream{
            Ok(stream) => {
                thread::spawn(move||{
                    println!("connected");
                    run_sync(&mut stream.try_clone().unwrap())
                });
            }
            Err(e) => {
                println!("Connection failed {}",e );
            }
        }
    }

    drop(listener);
    Ok(())
}

fn main() {
    let mut config = Config{
        port: 24011,
        localip : "127.0.0.1".to_owned(),
        outsideip : "127.0.0.1".to_owned()
    };
    {
        let mut ap = ArgumentParser::new();
        ap.set_description("Synchronise clipboard content between two computers.");
        ap.refer(&mut config.port)
            .add_option(&["-p","--port"],Store,"Port address");
        ap.refer(&mut config.localip)
            .add_option(&["-l","--local"],Store,"Local ip address");
        ap.refer(&mut config.outsideip)
            .add_option(&["-o","--outside"],Store,"Outside ip address");
        ap.parse_args_or_exit();
    }
    println!("local: {}, outside: {}, port: {}",config.localip, config.outsideip, config.port );
    let res = match try_run_client(&config){
        Err(_) => {
            println!("Could not connect to server, creating own.");
            run_server(&config)},
        _ => Ok(())
    };

    match res {
        Ok(_) => println!("done"),
        Err(e) => println!("Failed: {}", e),
    }
}
<commit_msg>Removed the use of #feature.<commit_after>extern crate clipboard;
extern crate byteorder;
extern crate argparse;

use clipboard::ClipboardContext;
use std::net::{TcpListener,TcpStream};
use std::io::{Error, ErrorKind, Result, Read,Write};
use std::thread;
use byteorder::{ReadBytesExt, WriteBytesExt,  LittleEndian};
use std::sync::mpsc::{Sender, channel};
use std::time::Duration;
use argparse::{ArgumentParser, Store};

struct Config {
    port : u16,
    localip : String,
    outsideip : String
}

fn run_reading(stream : &mut TcpStream,content : Sender<String>) -> Result<()>{
    loop {
        println!("Waiting for a data");
        let length : u32 = try!(stream.read_u32::<LittleEndian>());
        if length == 0{
            // ignore empty
            continue;
        }
        println!("Got the data size: {}", length);
        let mut data = vec![0u8;length as usize];
        try!(stream.take(length as u64).read_to_end(&mut data));
        match String::from_utf8(data){
            Ok(s) => {
                println!("Received new content from the other side: {}", s);
                let _ = content.send(s);
            }
            Err(_) => {
                println!("Failed to convert received content to string.");
            }
        };
    }
}

fn run_sync(stream : &mut TcpStream) -> Result<()>{
    let mut ctx = match ClipboardContext::new(){
        Ok(c) => c,
        Err(_) => return Err(Error::new(ErrorKind::Other,"Failed to create clipboard context"))
    };
    // println!("{}", ctx.get_contents().unwrap());
    //
    // ctx.set_contents("the new content".to_owned()).unwrap();
    let mut current_content = match ctx.get_contents(){
        Ok(s) => s,
        Err(_) => "".to_owned()
    };
    let (wx, rx) = channel::<String>();
    // // create thread which will read the stream for changes from outside, and apply changes to this system
    //
    let mut reading = stream.try_clone().unwrap();
    thread::spawn(move||{run_reading(&mut reading,wx)});
    let mut writer = stream.try_clone().unwrap();

    println!("initial clipboard value is: {}",current_content );

    loop{
        thread::sleep(Duration::new(1,0));
        println!("Checking for new content!");
        match ctx.get_contents(){
            Ok(s) => {

                if s != current_content{
                    println!("A new content, sending it to the other side: {}!={}",s,current_content);
                    current_content = s.clone();
                    let data = s.as_bytes();
                    try!(writer.write_u32::<LittleEndian>(data.len() as u32));
                    try!(writer.write(data));
                }
                match rx.try_recv(){
                    Ok(v) =>{
                        println!("Received a new value for cb: {}", v );
                        if v != current_content{
                            current_content = v.clone();
                            match ctx.set_contents(v){
                                Ok(_) => println!("Seting the new value as clipboard content."),
                                Err(_) => println!("Failde to set the new value as clipboard content.")
                            }
                        }
                    }
                    Err(_) => ()
                }
            }
            Err(_) => ()
        };

    }
}

fn try_run_client(config : &Config) -> Result<()>{
    let mut stream = try!(TcpStream::connect((&config.outsideip as &str,config.port)));
    run_sync(&mut stream)
}

fn run_server(config : &Config) -> Result<()> {
    let listener = try!(TcpListener::bind((&config.localip as &str,config.port)));

    for stream in listener.incoming(){
        match stream{
            Ok(stream) => {
                thread::spawn(move||{
                    println!("connected");
                    run_sync(&mut stream.try_clone().unwrap())
                });
            }
            Err(e) => {
                println!("Connection failed {}",e );
            }
        }
    }

    drop(listener);
    Ok(())
}

fn main() {
    let mut config = Config{
        port: 24011,
        localip : "127.0.0.1".to_owned(),
        outsideip : "127.0.0.1".to_owned()
    };
    {
        let mut ap = ArgumentParser::new();
        ap.set_description("Synchronise clipboard content between two computers.");
        ap.refer(&mut config.port)
            .add_option(&["-p","--port"],Store,"Port address");
        ap.refer(&mut config.localip)
            .add_option(&["-l","--local"],Store,"Local ip address");
        ap.refer(&mut config.outsideip)
            .add_option(&["-o","--outside"],Store,"Outside ip address");
        ap.parse_args_or_exit();
    }
    println!("local: {}, outside: {}, port: {}",config.localip, config.outsideip, config.port );
    let res = match try_run_client(&config){
        Err(_) => {
            println!("Could not connect to server, creating own.");
            run_server(&config)},
        _ => Ok(())
    };

    match res {
        Ok(_) => println!("done"),
        Err(e) => println!("Failed: {}", e),
    }
}
<|endoftext|>


<commit_before>extern crate rustc_serialize;
extern crate docopt;

use std::io::{Read, stdin, stderr, BufReader, Write, BufRead};
use std::fs::File;
use std::process::exit;
use std::str::from_utf8;
use std::cmp::max;
use std::collections::HashMap;

use docopt::Docopt;

static LF: char = '\n';
static VERSION: &'static str = "0.0.1";
static USAGE: &'static str = "
Usage: wc [options] FILE...
       wc [options] --files0-from=F
       wc (-h|--help)
       wc (-v|--version)

Print newline, word, and byte counts for each FILE, and a total line if
more than one FILE is specified. With no FILE, or when FILE is -,
read standard input. A word is a non-zero-length sequence of characters
delimited by white space.
The options below may be used to select which counts are printed, always in
the following order: newline, word, character, byte, maximum line length.

Options:
   -c, --bytes            print the byte counts
   -m, --chars            print the character counts
   -l, --lines            print the newline counts
   --files0-from=F        read input from the files specified by NUL-terminated
                          names in file F; If F is - then read names from
                          standard input
   -L, --max-line-length  print the length of the longest line
   -w, --words            print the word counts
   -h, --help             display this help and quit
   -v, --version          output version information and exit
";

#[allow(non_snake_case)]
#[derive(RustcDecodable, Debug)]
struct Args {
    arg_FILE: Vec<String>,
    flag_bytes: bool,
    flag_chars: bool,
    flag_lines: bool,
    flag_max_line_length: bool,
    flag_words: bool,
    flag_help: bool,
    flag_version: bool,
    flag_files0_from: String,
}

#[derive(Debug)]
enum ProcessingError {
    IO(std::io::Error),
    Utf8(std::str::Utf8Error),
}

impl From<std::io::Error> for ProcessingError {
    fn from(e: std::io::Error) -> ProcessingError {
        ProcessingError::IO(e)
    }
}
impl From<std::str::Utf8Error> for ProcessingError {
    fn from(e: std::str::Utf8Error) -> ProcessingError {
        ProcessingError::Utf8(e)
    }
}

#[derive(Debug)]
struct FileInfo{
    bytes: usize,
    chars: usize,
    lines: usize,
    words: usize,
    max_line_length: usize,
}

type FileInfoResult = Result<FileInfo, ProcessingError>;

impl FileInfo {
    fn wrap_error<'a>(e: std::io::Error) -> FileInfoResult {
        Err(ProcessingError::IO(e))
    }
    fn process<T: Read>(reader: T) -> FileInfoResult {
        // TODO: Process reader
        let mut info = FileInfo{
            bytes: 0,
            chars: 0,
            lines: 0,
            words: 0,
            max_line_length: 0,
        };

        let mut rbuf = BufReader::new(reader);
        let mut lbuf: Vec<u8> = Vec::new();
        loop {
            let size = try!(rbuf.read_until(LF as u8, &mut lbuf));
            info.bytes += size;
            if size == 0 {
                break;
            }
            {
                let line = try!(from_utf8(&lbuf));
                let size = line.chars().count();
                info.max_line_length = match line.chars().last() {
                    Some(x) => {
                        if x == LF {
                            info.lines += 1;
                            max(info.max_line_length, size - 1)
                        } else {
                            max(info.max_line_length, size)
                        }
                    },
                    None => max(info.max_line_length, size),
                };
                info.chars += size;
                let words: Vec<&str> = line.split(|c: char| c.is_whitespace()).collect();
                for word in words {
                    if word.len() > 0 {
                        info.words += 1;
                    }

                }
            }
            lbuf.clear()
        }
        Ok(info)
    }
}

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

    if args.flag_version {
        println!("wc v{}", VERSION);
        exit(0);
    }

    if args.flag_files0_from.len() != 0  && args.arg_FILE.len() != 0 {
        match writeln!(&mut stderr(), "wc: file operands cannot be combined with --files0-from") {
            Ok(_) => {},
            Err(e) => panic!("Unable to write to stderr: {}", e)
        }
        match writeln!(&mut stderr(), "Try 'wc --help' for more information") {
            Ok(_) => {},
            Err(e) => panic!("Unable to write to stderr: {}", e)
        }
        exit(1);
    }

    // TODO: Process --files0-from
    let mut results = HashMap::new();

    let mut totals = FileInfo{
        bytes: 0,
        chars: 0,
        lines: 0,
        words: 0,
        max_line_length: 0,
    };
    for file_arg in &args.arg_FILE {
        let filename = file_arg.as_ref();
        results.insert(filename, match filename {
            "-" => FileInfo::process(stdin()),
            _ => {
                let file = File::open(filename.to_string());
                match file {
                    Ok(f) => FileInfo::process(f),
                    Err(e) => FileInfo::wrap_error(e),
                }
            }
        });
    }
    for (filename, result) in results.iter() {
        match *result {
            Ok(ref r) => {
                totals.chars += r.chars;
                totals.lines += r.lines;
                totals.bytes += r.bytes;
                totals.words += r.words;
                totals.max_line_length = max(totals.max_line_length, r.max_line_length);
            },
            Err(_) => {},
        }
        println!("{}: {:?}", filename, result);
    }
    println!("total: {:?}", totals);

}
<commit_msg>Explain the block<commit_after>extern crate rustc_serialize;
extern crate docopt;

use std::io::{Read, stdin, stderr, BufReader, Write, BufRead};
use std::fs::File;
use std::process::exit;
use std::str::from_utf8;
use std::cmp::max;
use std::collections::HashMap;

use docopt::Docopt;

static LF: char = '\n';
static VERSION: &'static str = "0.0.1";
static USAGE: &'static str = "
Usage: wc [options] FILE...
       wc [options] --files0-from=F
       wc (-h|--help)
       wc (-v|--version)

Print newline, word, and byte counts for each FILE, and a total line if
more than one FILE is specified. With no FILE, or when FILE is -,
read standard input. A word is a non-zero-length sequence of characters
delimited by white space.
The options below may be used to select which counts are printed, always in
the following order: newline, word, character, byte, maximum line length.

Options:
   -c, --bytes            print the byte counts
   -m, --chars            print the character counts
   -l, --lines            print the newline counts
   --files0-from=F        read input from the files specified by NUL-terminated
                          names in file F; If F is - then read names from
                          standard input
   -L, --max-line-length  print the length of the longest line
   -w, --words            print the word counts
   -h, --help             display this help and quit
   -v, --version          output version information and exit
";

#[allow(non_snake_case)]
#[derive(RustcDecodable, Debug)]
struct Args {
    arg_FILE: Vec<String>,
    flag_bytes: bool,
    flag_chars: bool,
    flag_lines: bool,
    flag_max_line_length: bool,
    flag_words: bool,
    flag_help: bool,
    flag_version: bool,
    flag_files0_from: String,
}

#[derive(Debug)]
enum ProcessingError {
    IO(std::io::Error),
    Utf8(std::str::Utf8Error),
}

impl From<std::io::Error> for ProcessingError {
    fn from(e: std::io::Error) -> ProcessingError {
        ProcessingError::IO(e)
    }
}
impl From<std::str::Utf8Error> for ProcessingError {
    fn from(e: std::str::Utf8Error) -> ProcessingError {
        ProcessingError::Utf8(e)
    }
}

#[derive(Debug)]
struct FileInfo{
    bytes: usize,
    chars: usize,
    lines: usize,
    words: usize,
    max_line_length: usize,
}

type FileInfoResult = Result<FileInfo, ProcessingError>;

impl FileInfo {
    fn wrap_error<'a>(e: std::io::Error) -> FileInfoResult {
        Err(ProcessingError::IO(e))
    }
    fn process<T: Read>(reader: T) -> FileInfoResult {
        // TODO: Process reader
        let mut info = FileInfo{
            bytes: 0,
            chars: 0,
            lines: 0,
            words: 0,
            max_line_length: 0,
        };

        let mut rbuf = BufReader::new(reader);
        let mut lbuf: Vec<u8> = Vec::new();
        loop {
            let size = try!(rbuf.read_until(LF as u8, &mut lbuf));
            info.bytes += size;
            if size == 0 {
                break;
            }
            // Create a scope because we're going to borrow lbuf and
            // the borrow must end before we can clear it.
            {
                let line = try!(from_utf8(&lbuf));
                let size = line.chars().count();
                info.max_line_length = match line.chars().last() {
                    Some(x) => {
                        if x == LF {
                            info.lines += 1;
                            max(info.max_line_length, size - 1)
                        } else {
                            max(info.max_line_length, size)
                        }
                    },
                    None => max(info.max_line_length, size),
                };
                info.chars += size;
                let words: Vec<&str> = line.split(|c: char| c.is_whitespace()).collect();
                for word in words {
                    if word.len() > 0 {
                        info.words += 1;
                    }

                }
            }
            lbuf.clear()
        }
        Ok(info)
    }
}

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

    if args.flag_version {
        println!("wc v{}", VERSION);
        exit(0);
    }

    if args.flag_files0_from.len() != 0  && args.arg_FILE.len() != 0 {
        match writeln!(&mut stderr(), "wc: file operands cannot be combined with --files0-from") {
            Ok(_) => {},
            Err(e) => panic!("Unable to write to stderr: {}", e)
        }
        match writeln!(&mut stderr(), "Try 'wc --help' for more information") {
            Ok(_) => {},
            Err(e) => panic!("Unable to write to stderr: {}", e)
        }
        exit(1);
    }

    // TODO: Process --files0-from
    let mut results = HashMap::new();

    let mut totals = FileInfo{
        bytes: 0,
        chars: 0,
        lines: 0,
        words: 0,
        max_line_length: 0,
    };
    for file_arg in &args.arg_FILE {
        let filename = file_arg.as_ref();
        results.insert(filename, match filename {
            "-" => FileInfo::process(stdin()),
            _ => {
                let file = File::open(filename.to_string());
                match file {
                    Ok(f) => FileInfo::process(f),
                    Err(e) => FileInfo::wrap_error(e),
                }
            }
        });
    }
    for (filename, result) in results.iter() {
        match *result {
            Ok(ref r) => {
                totals.chars += r.chars;
                totals.lines += r.lines;
                totals.bytes += r.bytes;
                totals.words += r.words;
                totals.max_line_length = max(totals.max_line_length, r.max_line_length);
            },
            Err(_) => {},
        }
        println!("{}: {:?}", filename, result);
    }
    println!("total: {:?}", totals);

}
<|endoftext|>


<commit_before>// Copyright Istio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate core;
#[cfg(feature = "gperftools")]
extern crate gperftools;

use std::sync::atomic::{AtomicUsize, Ordering};
use ztunnel::*;

// #[global_allocator]
// static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;

// #[global_allocator]
// static GLOBAL: tcmalloc::TCMalloc = tcmalloc::TCMalloc;

fn main() -> anyhow::Result<()> {
    telemetry::setup_logging();
    let config: config::Config = Default::default();
    tokio::runtime::Builder::new_multi_thread()
        .worker_threads(config.num_worker_threads)
        .thread_name_fn(|| {
            static ATOMIC_ID: AtomicUsize = AtomicUsize::new(0);
            let id = ATOMIC_ID.fetch_add(1, Ordering::SeqCst);
            format!("proxy-{}", id)
        })
        .enable_all()
        .build()
        .unwrap()
        .block_on(async move { run(config).await })
}

async fn run(cfg: config::Config) -> anyhow::Result<()> {
    // For now we don't need a complex CLI, so rather than pull in dependencies just use basic argv[1]
    match std::env::args().nth(1).as_deref() {
        None | Some("proxy") => proxy(cfg).await,
        Some("version") => version().await,
        Some(unknown) => {
            eprintln!("unknown command: {unknown}");
            std::process::exit(1)
        }
    }
}

async fn version() -> anyhow::Result<()> {
    println!("{}", version::BuildInfo::new());
    Ok(())
}

async fn proxy(cfg: config::Config) -> anyhow::Result<()> {
    app::build(cfg).await?.spawn().await
}
<commit_msg>Move the argv handling out of async context (#200)<commit_after>// Copyright Istio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate core;
#[cfg(feature = "gperftools")]
extern crate gperftools;

use std::sync::atomic::{AtomicUsize, Ordering};
use ztunnel::*;

// #[global_allocator]
// static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;

// #[global_allocator]
// static GLOBAL: tcmalloc::TCMalloc = tcmalloc::TCMalloc;

fn main() -> anyhow::Result<()> {
    telemetry::setup_logging();
    let config: config::Config = Default::default();

    // For now we don't need a complex CLI, so rather than pull in dependencies just use basic argv[1]
    match std::env::args().nth(1).as_deref() {
        None | Some("proxy") => (),
        Some("version") => return version(),
        Some(unknown) => {
            eprintln!("unknown command: {unknown}");
            std::process::exit(1)
        }
    };

    tokio::runtime::Builder::new_multi_thread()
        .worker_threads(config.num_worker_threads)
        .thread_name_fn(|| {
            static ATOMIC_ID: AtomicUsize = AtomicUsize::new(0);
            let id = ATOMIC_ID.fetch_add(1, Ordering::SeqCst);
            format!("proxy-{}", id)
        })
        .enable_all()
        .build()
        .unwrap()
        .block_on(async move { proxy(config).await })
}

fn version() -> anyhow::Result<()> {
    println!("{}", version::BuildInfo::new());
    Ok(())
}

async fn proxy(cfg: config::Config) -> anyhow::Result<()> {
    app::build(cfg).await?.spawn().await
}
<|endoftext|>


<commit_before>extern crate libusb;
use std::time::Duration;
use std::thread;
use std::process;
use std::io::{self, Write};

fn main() {
    let context = libusb::Context::new().unwrap();
    let device = find_device(&context);

    match device {
        Ok(handle) => {
            if let Err(e) = run(handle) {
                println!("{}", e);
                process::exit(2);
            }
        },
        Err(libusb::Error::NotFound) => {
            println!("Device not found");
            process::exit(1);
        }
        Err(e) => {
            println!("{}", e);
            process::exit(1);
        }
    }
}

fn find_device<'a>(context: &'a libusb::Context) -> Result<libusb::DeviceHandle<'a>, libusb::Error> {
    let devices = try!(context.devices());
    devices.iter().find(|device| {
        device.device_descriptor().ok().map_or(false, |desc| desc.vendor_id() == 0x05c6)
    }).map_or(Err(libusb::Error::NotFound), |device| device.open())
}

fn run(mut handle: libusb::DeviceHandle) -> Result<(), libusb::Error> {
    let mut stdout = io::stdout();
    println!("Found device");
    try!(handle.claim_interface(0));

    let mut read_buf = [0; 4096];

    loop {
        println!("Connecting DMSS");

        try!(handle.write_bulk(0x01, &[0x0c, 0x00, 0x00, 0x00,  0x00, 0x47, 0xb8, 0x7e], Duration::from_secs(10)));
        let len = try!(handle.read_bulk(0x81, &mut read_buf, Duration::from_secs(10)));
        let rx = &read_buf[0..len];

        if rx == &[0x13, 0x0c, 0x00, 0x00,  0x00, 0x00, 0x72, 0xce, 0x7e] {
            break;
        } else {
            thread::sleep(Duration::from_millis(100));
        }
    }

    try!(handle.write_bulk(0x01, &[0x7d, 0x5d, 0x04, 0x34,  0x21, 0x34, 0x21, 0x00,  0x00, 0x1f, 0x00, 0x00,  0x00, 0xab, 0xdf, 0x7e], Duration::from_secs(1)));
    println!("DMSS is connected");

    loop {
        let len = try!(handle.read_bulk(0x81, &mut read_buf, Duration::from_secs(0)));

        for packet in Hdlc::new(read_buf[0..len].iter().map(|&x| x)) {
            if packet.len() > 0 {
                parse_packet(&mut stdout, packet).unwrap();
            }
        }
    }
}

fn split_byte(s: &[u8], sep: u8) -> (&[u8], &[u8]) {
    if let Some(pos) = s.iter().position(|&i| i == sep) {
        let (a, b) = s.split_at(pos);
        (a, &b[1..])
    } else {
        (s, &[])
    }
}

fn strip_trailing_newlines(mut s: &[u8]) -> &[u8] {
    while s.ends_with(b"\n") {
        s = &s[0..s.len()-1];
    }
    s
}

fn le32(s: &[u8]) -> u32 {
    (s[0] as u32) | (s[1] as u32) << 8 | (s[2] as u32) << 16 | (s[3] as u32) << 24
}

fn le16(s: &[u8]) -> u16 {
    (s[0] as u16) | (s[1] as u16) << 8
}

fn parse_packet(stdout: &mut Write, packet: Vec<u8>) -> io::Result<()> {
    if packet.len() < 24 || packet[0] != 0x79 || packet[2] != 0 {
        print!("[unknown packet: ");
        for b in &packet { print!("{:02x}", b); }
        println!("]");
        return Ok(());
    }

    let (header, rest) = packet.split_at(20);
    let timestamp = le32(&header[6..10]);
    let lineno = le16(&header[12..14]);
    let (msg, rest) = split_byte(rest, 0);
    let (file, _) = split_byte(rest, 0);

    //for b in &packet { print!("{:02x} ", b); }

    try!(write!(stdout, "{:10}: ", timestamp));
    try!(stdout.write_all(strip_trailing_newlines(msg)));
    try!(write!(stdout, " ("));
    try!(stdout.write_all(file));
    try!(write!(stdout, ":{})\n", lineno));

    Ok(())
}

/// Iterator over packets in a HDLC-framed sequence of bytes
struct Hdlc<I> {
    input: I,
    end: bool,
}

impl<I> Hdlc<I> where I:Iterator<Item=u8> {
    fn new(input: I) -> Hdlc<I> {
        Hdlc {
            input: input,
            end: false,
        }
    }

    fn input_byte(&mut self) -> Option<u8> {
        let x = self.input.next();
        self.end |= x.is_none();
        x
    }
}

impl<I> Iterator for Hdlc<I> where I:Iterator<Item=u8> {
    type Item = Vec<u8>;
    fn next(&mut self) -> Option<Vec<u8>> {
        if self.end {
            return None;
        }

        let mut out = vec![];

        loop {
            match self.input_byte() {
                Some(0x7e) | None => break,
                Some(0x7d) => {
                    match self.input_byte() {
                        Some(c) => out.push(c ^ 0x20),
                        None => break,
                    }
                }
                Some(c) => out.push(c),
            };
        }

        Some(out)
    }
}<commit_msg>main: removed trailing whitespace<commit_after>extern crate libusb;
use std::time::Duration;
use std::thread;
use std::process;
use std::io::{self, Write};

fn main() {
    let context = libusb::Context::new().unwrap();
    let device = find_device(&context);

    match device {
        Ok(handle) => {
            if let Err(e) = run(handle) {
                println!("{}", e);
                process::exit(2);
            }
        },
        Err(libusb::Error::NotFound) => {
            println!("Device not found");
            process::exit(1);
        }
        Err(e) => {
            println!("{}", e);
            process::exit(1);
        }
    }
}

fn find_device<'a>(context: &'a libusb::Context) -> Result<libusb::DeviceHandle<'a>, libusb::Error> {
    let devices = try!(context.devices());
    devices.iter().find(|device| {
        device.device_descriptor().ok().map_or(false, |desc| desc.vendor_id() == 0x05c6)
    }).map_or(Err(libusb::Error::NotFound), |device| device.open())
}

fn run(mut handle: libusb::DeviceHandle) -> Result<(), libusb::Error> {
    let mut stdout = io::stdout();
    println!("Found device");
    try!(handle.claim_interface(0));

    let mut read_buf = [0; 4096];

    loop {
        println!("Connecting DMSS");

        try!(handle.write_bulk(0x01, &[0x0c, 0x00, 0x00, 0x00,  0x00, 0x47, 0xb8, 0x7e], Duration::from_secs(10)));
        let len = try!(handle.read_bulk(0x81, &mut read_buf, Duration::from_secs(10)));
        let rx = &read_buf[0..len];

        if rx == &[0x13, 0x0c, 0x00, 0x00,  0x00, 0x00, 0x72, 0xce, 0x7e] {
            break;
        } else {
            thread::sleep(Duration::from_millis(100));
        }
    }

    try!(handle.write_bulk(0x01, &[0x7d, 0x5d, 0x04, 0x34,  0x21, 0x34, 0x21, 0x00,  0x00, 0x1f, 0x00, 0x00,  0x00, 0xab, 0xdf, 0x7e], Duration::from_secs(1)));
    println!("DMSS is connected");

    loop {
        let len = try!(handle.read_bulk(0x81, &mut read_buf, Duration::from_secs(0)));

        for packet in Hdlc::new(read_buf[0..len].iter().map(|&x| x)) {
            if packet.len() > 0 {
                parse_packet(&mut stdout, packet).unwrap();
            }
        }
    }
}

fn split_byte(s: &[u8], sep: u8) -> (&[u8], &[u8]) {
    if let Some(pos) = s.iter().position(|&i| i == sep) {
        let (a, b) = s.split_at(pos);
        (a, &b[1..])
    } else {
        (s, &[])
    }
}

fn strip_trailing_newlines(mut s: &[u8]) -> &[u8] {
    while s.ends_with(b"\n") {
        s = &s[0..s.len()-1];
    }
    s
}

fn le32(s: &[u8]) -> u32 {
    (s[0] as u32) | (s[1] as u32) << 8 | (s[2] as u32) << 16 | (s[3] as u32) << 24
}

fn le16(s: &[u8]) -> u16 {
    (s[0] as u16) | (s[1] as u16) << 8
}

fn parse_packet(stdout: &mut Write, packet: Vec<u8>) -> io::Result<()> {
    if packet.len() < 24 || packet[0] != 0x79 || packet[2] != 0 {
        print!("[unknown packet: ");
        for b in &packet { print!("{:02x}", b); }
        println!("]");
        return Ok(());
    }

    let (header, rest) = packet.split_at(20);
    let timestamp = le32(&header[6..10]);
    let lineno = le16(&header[12..14]);
    let (msg, rest) = split_byte(rest, 0);
    let (file, _) = split_byte(rest, 0);

    //for b in &packet { print!("{:02x} ", b); }

    try!(write!(stdout, "{:10}: ", timestamp));
    try!(stdout.write_all(strip_trailing_newlines(msg)));
    try!(write!(stdout, " ("));
    try!(stdout.write_all(file));
    try!(write!(stdout, ":{})\n", lineno));

    Ok(())
}

/// Iterator over packets in a HDLC-framed sequence of bytes
struct Hdlc<I> {
    input: I,
    end: bool,
}

impl<I> Hdlc<I> where I:Iterator<Item=u8> {
    fn new(input: I) -> Hdlc<I> {
        Hdlc {
            input: input,
            end: false,
        }
    }

    fn input_byte(&mut self) -> Option<u8> {
        let x = self.input.next();
        self.end |= x.is_none();
        x
    }
}

impl<I> Iterator for Hdlc<I> where I:Iterator<Item=u8> {
    type Item = Vec<u8>;
    fn next(&mut self) -> Option<Vec<u8>> {
        if self.end {
            return None;
        }

        let mut out = vec![];

        loop {
            match self.input_byte() {
                Some(0x7e) | None => break,
                Some(0x7d) => {
                    match self.input_byte() {
                        Some(c) => out.push(c ^ 0x20),
                        None => break,
                    }
                }
                Some(c) => out.push(c),
            };
        }

        Some(out)
    }
}
<|endoftext|>


<commit_before>
extern crate love2d;
use love2d::{Window, Action, Event};
use love2d::{ElementState, VirtualKeyCode};

fn main() {
    let mut window = Window::new("Hello World", 640, 480);

    window.start_loop(|app, _| {
        app.clear();

        app.set_color_html("312");
        app.draw_rect((-0.5, -0.5), (0.5, 0.5));

        app.set_color_html("#033112");
        app.draw_rect((0.0, 0.0), (-1.0, -1.0));

        app.set_color(1.0, 0.0, 0.0, 1.0);
        app.draw_line(0.0, 0.0, 1.0, 1.0);

        app.set_color(0.0, 0.0, 1.0, 0.3);
        app.draw(&[(0.0, 0.0), (1.0, 1.0), (1.0, 0.0)]);

        app.set_color(0.0, 1.0, 0.0, 0.3);
        app.draw(&[(0.0, 0.0), (0.0, 1.0), (1.0, 1.0)]);

        app.set_color(1.0, 0.0, 0.0, 0.3);
        app.draw_circle(0.25, -0.25, 0.75, 0.25, 10);

        for ev in app.poll_events() {
            match ev {
                Event::Closed => return Action::Stop,
                Event::KeyboardInput(ElementState::Pressed, Some(VirtualKeyCode::Space)) => {
                    println!("Space!");
                }
                _ => (),
            }
        }

        Action::Continue
    });
}
<commit_msg>Added keymap to store keystates<commit_after>
extern crate love2d;
use love2d::{Window, Action, Event};
use love2d::{ElementState, VirtualKeyCode};

use std::collections::HashMap;

fn main() {
    let mut window = Window::new("Hello World", 640, 480);
    let mut keymap: HashMap<VirtualKeyCode, bool> = HashMap::new();

    window.start_loop(|app, _| {
        app.clear();

        app.set_color_html("312");
        app.draw_rect((-0.5, -0.5), (0.5, 0.5));

        app.set_color_html("#033112");
        app.draw_rect((0.0, 0.0), (-1.0, -1.0));

        app.set_color(1.0, 0.0, 0.0, 1.0);
        app.draw_line(0.0, 0.0, 1.0, 1.0);

        app.set_color(0.0, 0.0, 1.0, 0.3);
        app.draw(&[(0.0, 0.0), (1.0, 1.0), (1.0, 0.0)]);

        app.set_color(0.0, 1.0, 0.0, 0.3);
        app.draw(&[(0.0, 0.0), (0.0, 1.0), (1.0, 1.0)]);

        app.set_color(1.0, 0.0, 0.0, 0.3);
        app.draw_circle(0.25, -0.25, 0.75, 0.25, 10);

        for ev in app.poll_events() {
            match ev {
                Event::Closed => return Action::Stop,
                Event::KeyboardInput(ElementState::Pressed, Some(key)) => {
                    match key {
                        VirtualKeyCode::Space => println!("Space!"),
                        VirtualKeyCode::Escape => return Action::Stop,
                        _ => (),
                    };
                    keymap.insert(key, true);
                }
                Event::KeyboardInput(ElementState::Released, Some(key)) => {
                    keymap.insert(key, false);
                }
                _ => (),
            }
        }

        Action::Continue
    });
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![feature(custom_derive)]
#![plugin(rocket_codegen)]

#[macro_use]
extern crate serde_derive;

extern crate chrono;
#[macro_use]
extern crate hyper;
extern crate hyper_native_tls;
extern crate serde_json;

extern crate rocket;
extern crate rocket_contrib;

use std::env;
use hyper::Client;
use hyper::header::Connection;
use hyper::net::HttpsConnector;
use hyper_native_tls::NativeTlsClient;
use std::vec::Vec;
use std::collections::BTreeSet;
use chrono::{NaiveDate as Date, Utc};
use rocket::Outcome;
use chrono::Datelike;
use rocket_contrib::Template;

header! { (XToken, "x-token") => [String] }

static DEBITOOR_TOKEN: &'static str = "DEBITOOR_TOKEN";

fn default_description() -> String {
    "<empty>".to_string()
}

#[derive(Serialize, Deserialize, Debug)]
struct Expense {
    date: String,
    lines: Vec<Line>,
}

#[derive(Serialize, Deserialize, Debug)]
struct Line {
    #[serde(rename = "categoryType")]
    category_type: Option<String>,
    #[serde(rename = "netAmount")]
    net_amount: f64,
    #[serde(default = "default_description")]
    description: String,
    #[serde(rename = "assetDepreciation")]
    #[serde(default = "Vec::new")]
    asset_depreciation: Vec<AssetDepreciation>,
}

#[derive(Serialize, Deserialize, Debug)]
struct AssetDepreciation {
    #[serde(rename = "depreciationCost")]
    depreciation_cost: f64,
    #[serde(rename = "depreciationDate")]
    depreciation_date: Date,
    #[serde(rename = "bookValue")]
    book_value: f64,
}

#[derive(Deserialize, Debug)]
struct AccessToken {
    access_token: String,
}

impl<'a, 'r> rocket::request::FromRequest<'a, 'r> for AccessToken {
    type Error = ();

    fn from_request(
        request: &'a rocket::request::Request<'r>,
    ) -> rocket::request::Outcome<Self, Self::Error> {
        let token = request
            .cookies()
            .get(DEBITOOR_TOKEN)
            .map(|c| c.value().to_owned());

        match token {
            None => Outcome::Forward(()),
            Some(token) => Outcome::Success(AccessToken {
                access_token: token,
            }),
        }
    }
}

#[derive(Deserialize, Debug)]
struct BaseURL {
    base_url: String,
}

impl<'a, 'r> rocket::request::FromRequest<'a, 'r> for BaseURL {
    type Error = ();

    fn from_request(
        request: &'a rocket::request::Request<'r>,
    ) -> rocket::request::Outcome<Self, Self::Error> {
        println!("Header: {:?}", request.headers());

        let schema = request
            .headers()
            .get_one("X-Forwarded-Proto")
            .unwrap_or("http");
        let host = request.headers().get_one("Host").unwrap();

        Outcome::Success(BaseURL {
            base_url: format!("{}://{}", schema, host),
        })
    }
}

#[derive(FromForm)]
struct CodeWrapper {
    code: String,
}

fn create_ssl_client() -> Client {
    let ssl = NativeTlsClient::new().unwrap();
    let connector = HttpsConnector::new(ssl);
    Client::with_connector(connector)
}

#[get("/?<code>", rank = 1)]
fn check_code(
    mut cookies: rocket::http::Cookies,
    code: CodeWrapper,
    base_url: BaseURL,
) -> rocket::response::Redirect {
    let client_secret = env::var("CLIENT_SECRET").unwrap();

    println!("got code {:?}", code.code);

    let client = create_ssl_client();

    let body = format!(
        "code={}&client_secret={}&redirect_uri={}",
        code.code, client_secret, base_url.base_url
    );

    println!("body {}", body);

    let res = client.
        post("https://app.debitoor.com/login/oauth2/access_token").
        //if we keep the connection open the parsing will wait for a minute in between for a timeout
        //don't know why this is, so just disable keep alive for now
        body(body.as_bytes()).
        header(Connection::close()).
        header(hyper::header::ContentType::form_url_encoded()).
        //the access token to authenticate with
        send().unwrap();

    assert_eq!(res.status, hyper::Ok);

    let access_token: AccessToken = serde_json::from_reader(res).unwrap();

    println!("{:?}", access_token);

    //set cookie and redirect
    cookies.add(rocket::http::Cookie::new(
        DEBITOOR_TOKEN.to_owned(),
        access_token.access_token.to_owned(),
    ));
    rocket::response::Redirect::temporary("/")
}

#[allow(unused_variables)]
#[get("/", rank = 2)]
fn index(token: AccessToken) -> rocket::response::Redirect {
    rocket::response::Redirect::temporary(format!("/assets/{}", Utc::now().year()).as_str())
}

#[get("/", rank = 3)]
fn redirect_auth() -> rocket::response::Redirect {
    let client_id = env::var("CLIENT_ID").unwrap();

    rocket::response::Redirect::temporary(
        format!(
            "https://app.debitoor.com/login/oauth2/authorize?client_id={}&response_type=code",
            client_id
        ).as_str(),
    )
}

#[get("/assets/<year>")]
fn asset_list(token: AccessToken, year: i32) -> Template {
    let client = create_ssl_client();

    println!("send request for token {:?}", token);
    let res = client.
        get("https://api.debitoor.com/api/expenses/v4").
        //if we keep the connection open the parsing will wait for a minute in between for a timeout
        //don't know why this is, so just disable keep alive for now
        header(Connection::close()).
        //the access token to authenticate with
        header(XToken(token.access_token.to_owned())).
        send().unwrap();
    assert_eq!(res.status, hyper::Ok);

    println!("create parser");

    let expenses: Vec<Expense> = serde_json::from_reader(res).unwrap();

    #[derive(Serialize, Deserialize, Debug)]
    struct AssetInformation {
        description: String,
        #[serde(rename = "netAmount")]
        net_amount: f64,
        #[serde(rename = "purchasingDate")]
        purchasing_date: Date,
        #[serde(rename = "depreciationCost")]
        depreciation_cost: f64,
        #[serde(rename = "depreciationDate")]
        depreciation_date: Date,
        #[serde(rename = "bookValuePeriodBegin")]
        book_value_period_begin: f64,
        #[serde(rename = "bookValuePeriodEnd")]
        book_value_period_end: f64,
    }

    #[derive(Serialize, Deserialize, Debug)]
    struct Context {
        year: i32,
        asset_information: Vec<AssetInformation>,
        available_years: BTreeSet<i32>,
        total_depreciation_cost: f64,
        total_book_value: f64,
    }

    let mut asset_information: Vec<AssetInformation> = Vec::new();
    let mut available_years: BTreeSet<i32> = BTreeSet::new();

    println!("printing value");

    let mut total_depreciation_cost = 0.0f64;
    let mut total_book_value = 0.0f64;

    for expense in expenses {
        for line in expense.lines {
            let description = line.description.as_str();

            let asset_deprecations = &line.asset_depreciation;

            if asset_deprecations.is_empty() {
                continue;
            }

            //find the first depreciation data, which is the poruchase date
            let purchase_info = asset_deprecations
                .iter()
                .fold(None, |min, x| match min {
                    None => Some(x),
                    Some(y) => Some(if x.depreciation_date < y.depreciation_date {
                        x
                    } else {
                        y
                    }),
                })
                .unwrap();

            for asset_depreciation in asset_deprecations {
                available_years.insert(asset_depreciation.depreciation_date.year());
                if asset_depreciation.depreciation_date.year() == year {
                    total_depreciation_cost += asset_depreciation.depreciation_cost;
                    total_book_value += asset_depreciation.book_value;
                    asset_information.push(AssetInformation {
                        description: description.to_string(),
                        net_amount: line.net_amount,
                        purchasing_date: purchase_info.depreciation_date,
                        depreciation_cost: asset_depreciation.depreciation_cost,
                        depreciation_date: asset_depreciation.depreciation_date,
                        book_value_period_begin: asset_depreciation.book_value
                            + asset_depreciation.depreciation_cost,
                        book_value_period_end: asset_depreciation.book_value,
                    });
                }
            }
        }
    }

    println!("Rendering tenplate");

    Template::render(
        "asset_list",
        Context {
            year: year,
            asset_information: asset_information,
            available_years: available_years,
            total_depreciation_cost: total_depreciation_cost,
            total_book_value: total_book_value,
        },
    )
}

fn main() {
    rocket::ignite()
        .attach(Template::fairing())
        .mount("/", routes![index, asset_list, check_code, redirect_auth])
        .launch();
}
<commit_msg>Code Cleanup<commit_after>#![feature(plugin)]
#![feature(custom_derive)]
#![plugin(rocket_codegen)]

#[macro_use]
extern crate serde_derive;

extern crate chrono;
#[macro_use]
extern crate hyper;
extern crate hyper_native_tls;
extern crate serde_json;

extern crate rocket;
extern crate rocket_contrib;

use std::env;
use hyper::Client;
use hyper::header::Connection;
use hyper::net::HttpsConnector;
use hyper_native_tls::NativeTlsClient;
use std::vec::Vec;
use std::collections::BTreeSet;
use chrono::{NaiveDate as Date, Utc};
use rocket::Outcome;
use chrono::Datelike;
use rocket_contrib::Template;

header! { (XToken, "x-token") => [String] }

static DEBITOOR_TOKEN: &'static str = "DEBITOOR_TOKEN";

fn default_description() -> String {
    "<empty>".to_string()
}

#[derive(Serialize, Deserialize, Debug)]
struct Expense {
    date: String,
    lines: Vec<Line>,
}

#[derive(Serialize, Deserialize, Debug)]
struct Line {
    #[serde(rename = "categoryType")]
    category_type: Option<String>,
    #[serde(rename = "netAmount")]
    net_amount: f64,
    #[serde(default = "default_description")]
    description: String,
    #[serde(rename = "assetDepreciation")]
    #[serde(default = "Vec::new")]
    asset_depreciation: Vec<AssetDepreciation>,
}

#[derive(Serialize, Deserialize, Debug)]
struct AssetDepreciation {
    #[serde(rename = "depreciationCost")]
    depreciation_cost: f64,
    #[serde(rename = "depreciationDate")]
    depreciation_date: Date,
    #[serde(rename = "bookValue")]
    book_value: f64,
}

#[derive(Deserialize, Debug)]
struct AccessToken {
    access_token: String,
}

impl<'a, 'r> rocket::request::FromRequest<'a, 'r> for AccessToken {
    type Error = ();

    fn from_request(
        request: &'a rocket::request::Request<'r>,
    ) -> rocket::request::Outcome<Self, Self::Error> {
        let token = request
            .cookies()
            .get(DEBITOOR_TOKEN)
            .map(|c| c.value().to_owned());

        match token {
            None => Outcome::Forward(()),
            Some(token) => Outcome::Success(AccessToken {
                access_token: token,
            }),
        }
    }
}

#[derive(Deserialize, Debug)]
struct BaseURL {
    base_url: String,
}

impl<'a, 'r> rocket::request::FromRequest<'a, 'r> for BaseURL {
    type Error = ();

    fn from_request(
        request: &'a rocket::request::Request<'r>,
    ) -> rocket::request::Outcome<Self, Self::Error> {
        println!("Header: {:?}", request.headers());

        let schema = request
            .headers()
            .get_one("X-Forwarded-Proto")
            .unwrap_or("http");
        let host = request.headers().get_one("Host").unwrap();

        Outcome::Success(BaseURL {
            base_url: format!("{}://{}", schema, host),
        })
    }
}

#[derive(FromForm)]
struct CodeWrapper {
    code: String,
}

fn create_ssl_client() -> Client {
    let ssl = NativeTlsClient::new().unwrap();
    let connector = HttpsConnector::new(ssl);
    Client::with_connector(connector)
}

#[get("/?<code>", rank = 1)]
fn check_code(
    mut cookies: rocket::http::Cookies,
    code: CodeWrapper,
    base_url: BaseURL,
) -> rocket::response::Redirect {
    let client_secret = env::var("CLIENT_SECRET").unwrap();

    println!("got code {:?}", code.code);

    let client = create_ssl_client();

    let body = format!(
        "code={}&client_secret={}&redirect_uri={}",
        code.code, client_secret, base_url.base_url
    );

    println!("body {}", body);

    let res = client.
        post("https://app.debitoor.com/login/oauth2/access_token").
        //if we keep the connection open the parsing will wait for a minute in between for a timeout
        //don't know why this is, so just disable keep alive for now
        body(body.as_bytes()).
        header(Connection::close()).
        header(hyper::header::ContentType::form_url_encoded()).
        //the access token to authenticate with
        send().unwrap();

    assert_eq!(res.status, hyper::Ok);

    let access_token: AccessToken = serde_json::from_reader(res).unwrap();

    println!("{:?}", access_token);

    //set cookie and redirect
    cookies.add(rocket::http::Cookie::new(
        DEBITOOR_TOKEN.to_owned(),
        access_token.access_token.to_owned(),
    ));
    rocket::response::Redirect::temporary("/")
}

#[allow(unused_variables)]
#[get("/", rank = 2)]
fn index(token: AccessToken) -> rocket::response::Redirect {
    rocket::response::Redirect::temporary(format!("/assets/{}", Utc::now().year()).as_str())
}

#[get("/", rank = 3)]
fn redirect_auth() -> rocket::response::Redirect {
    let client_id = env::var("CLIENT_ID").unwrap();

    rocket::response::Redirect::temporary(
        format!(
            "https://app.debitoor.com/login/oauth2/authorize?client_id={}&response_type=code",
            client_id
        ).as_str(),
    )
}

#[get("/assets/<year>")]
fn asset_list(token: AccessToken, year: i32) -> Template {
    let client = create_ssl_client();

    println!("send request for token {:?}", token);
    let res = client.
        get("https://api.debitoor.com/api/expenses/v4").
        //if we keep the connection open the parsing will wait for a minute in between for a timeout
        //don't know why this is, so just disable keep alive for now
        header(Connection::close()).
        //the access token to authenticate with
        header(XToken(token.access_token.to_owned())).
        send().unwrap();
    assert_eq!(res.status, hyper::Ok);

    println!("create parser");

    let expenses: Vec<Expense> = serde_json::from_reader(res).unwrap();

    #[derive(Serialize, Deserialize, Debug)]
    struct AssetInformation {
        description: String,
        #[serde(rename = "netAmount")]
        net_amount: f64,
        #[serde(rename = "purchasingDate")]
        purchasing_date: Date,
        #[serde(rename = "depreciationCost")]
        depreciation_cost: f64,
        #[serde(rename = "depreciationDate")]
        depreciation_date: Date,
        #[serde(rename = "bookValuePeriodBegin")]
        book_value_period_begin: f64,
        #[serde(rename = "bookValuePeriodEnd")]
        book_value_period_end: f64,
    }

    #[derive(Serialize, Deserialize, Debug)]
    struct Context {
        year: i32,
        asset_information: Vec<AssetInformation>,
        available_years: BTreeSet<i32>,
        total_depreciation_cost: f64,
        total_book_value: f64,
    }

    let mut asset_information: Vec<AssetInformation> = Vec::new();
    let mut available_years: BTreeSet<i32> = BTreeSet::new();

    println!("printing value");

    let mut total_depreciation_cost = 0.0f64;
    let mut total_book_value = 0.0f64;

    for expense in expenses {
        for line in expense.lines {
            let description = line.description.as_str();

            let asset_deprecations = &line.asset_depreciation;

            if asset_deprecations.is_empty() {
                continue;
            }

            //find the first depreciation data, which is the purchase date
            let purchase_info = asset_deprecations
                .iter()
                .fold(None, |min, x| match min {
                    None => Some(x),
                    Some(y) => Some(if x.depreciation_date < y.depreciation_date {
                        x
                    } else {
                        y
                    }),
                })
                .unwrap();

            for asset_depreciation in asset_deprecations {
                available_years.insert(asset_depreciation.depreciation_date.year());
                if asset_depreciation.depreciation_date.year() == year {
                    total_depreciation_cost += asset_depreciation.depreciation_cost;
                    total_book_value += asset_depreciation.book_value;
                    asset_information.push(AssetInformation {
                        description: description.to_string(),
                        net_amount: line.net_amount,
                        purchasing_date: purchase_info.depreciation_date,
                        depreciation_cost: asset_depreciation.depreciation_cost,
                        depreciation_date: asset_depreciation.depreciation_date,
                        book_value_period_begin: asset_depreciation.book_value
                            + asset_depreciation.depreciation_cost,
                        book_value_period_end: asset_depreciation.book_value,
                    });
                }
            }
        }
    }

    println!("Rendering template");

    Template::render(
        "asset_list",
        Context {
            year,
            asset_information,
            available_years,
            total_depreciation_cost,
            total_book_value,
        },
    )
}

fn main() {
    rocket::ignite()
        .attach(Template::fairing())
        .mount("/", routes![index, asset_list, check_code, redirect_auth])
        .launch();
}
<|endoftext|>


<commit_before>use std::io;

fn main() {

    let mut m = String::new();
    let mut w = String::new();
    let mut k = String::new();

    let mut m2: i8;

    loop {
        println!("Choose one of these methods\n0 > Encipher\n1 > Decipher");
        io::stdin().read_line(&mut m).expect("Error");

        m2 = match m.trim().parse() {
            Ok(x) => x,
            Err(_) => continue
        };

        break;
    }

    println!("Type in a message to write");
    io::stdin().read_line(&mut w).expect("Error!");

    println!("Type in a key");
    io::stdin().read_line(&mut k).expect("Error!");

    let k: i32 = match k.trim().parse() {
        Ok(x) => x,
        Err(_) => 0
    };

    println!("Your translated string is\n{:?}", trs(w, k, m2));
}

fn trs(w: String, k: i32, m: i8) -> String {
    if m == 0 {
        return encsr(w.trim(), k);
    }
    return decsr(w.trim(), k);
}

fn key_v(starting: &str, key: i32) -> Vec<char> {
    let k: i32 = key;
    let s = starting;

    let s_v: Vec<char> = s.chars().collect();
    let mut new_v: Vec<char> = Vec::new();

    let mut i: i32 = k-1;

    while i < (s_v.len() as i32) {
        new_v.push(s_v[(i as usize)]);
        i += 1;
    }

    let mut new_i = 0;
    while new_i <= k-2 {
        new_v.push(s_v[(new_i as usize)]);
        new_i += 1;
    }

    return new_v;
}

fn l_to_n(l: char) -> i16 {
    match l {
        'A' => 0,
        'B' => 1,
        'C' => 2,
        'D' => 3,
        'E' => 4,
        'F' => 5,
        'G' => 6,
        'H' => 7,
        'I' => 8,
        'J' => 9,
        'K' => 10,
        'L' => 11,
        'M' => 12,
        'N' => 13,
        'O' => 14,
        'P' => 15,
        'Q' => 16,
        'R' => 17,
        'S' => 18,
        'T' => 19,
        'U' => 20,
        'V' => 21,
        'W' => 22,
        'X' => 23,
        'Y' => 24,
        'Z' => 25,
        _ => 30
    }
}

fn encsr_w(word: &str, key: i32) -> String {
    let starting = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    let key_v = key_v(starting, key);

    let mut index_v: Vec<i16> = Vec::new();

    for l in word.to_uppercase().chars() {
        index_v.push(l_to_n(l));
    }

    let mut new_w_v: Vec<char> = Vec::new();

    for i in index_v {
        new_w_v.push(key_v[(i as usize)]);
    }

    let s: String = new_w_v.into_iter().collect();

    return s;
}

fn decsr_w(word: &str, key: i32) -> String {

    let starting = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    let key_v = key_v(starting, key);

    let mut pos_v: Vec<i16> = Vec::new();
    let mut cur_i: i16 = 0;

    for c in word.to_uppercase().chars() {
        while cur_i < (key_v.len() as i16) - 1 {
            if c == key_v[(cur_i as usize)] {
                pos_v.push(cur_i);
                cur_i = 0;
                break;
            }
            cur_i += 1
        }
    }

    let c_vec: Vec<char> = starting.chars().collect();
    let mut fin_v: Vec<char> = Vec::new();

    for p in pos_v {
        fin_v.push(c_vec[(p as usize)]);
    }

    let s: String = fin_v.into_iter().collect();
    return s;
}

fn encsr(word: &str, key: i32) -> String {
    let sp_w: Vec<&str> = word.split(" ").collect();
    let mut w_v: Vec<String> = Vec::new();

    for cur_w in sp_w {
        w_v.push(encsr_w(cur_w, key));
    }

    return w_v.join(" ");
}

fn decsr(enc: &str, key: i32) -> String {
    let mut fin_v: Vec<String> = Vec::new();

    for pt in enc.split(" ") {
        fin_v.push(decsr_w(pt.trim(), key));
    }

    return fin_v.join(" ");
}
<commit_msg>Optimize code<commit_after>use std::io;

fn main() {

    let mut m = String::new();
    let mut w = String::new();
    let mut k = String::new();

    let m2: i8;

    loop {
        println!("Choose one of these methods\n0 > Encipher\n1 > Decipher");
        io::stdin().read_line(&mut m).expect("Error");

        m2 = match m.trim().parse() {
            Ok(x) => x,
            Err(_) => continue
        };

        break;
    }

    println!("Type in a message to write");
    io::stdin().read_line(&mut w).expect("Error!");

    println!("Type in a key");
    io::stdin().read_line(&mut k).expect("Error!");

    let k: i32 = match k.trim().parse() {
        Ok(x) => x,
        Err(_) => 0
    };

    println!("Your translated string is\n{:?}", trs(w, k, m2));
}

fn trs(w: String, k: i32, m: i8) -> String {
    if m == 0 {
        return encsr(w.trim(), k);
    }
    return decsr(w.trim(), k);
}

fn key_v(starting: &str, key: i32) -> Vec<char> {
    let k: i32 = key;
    let s = starting;

    let s_v: Vec<char> = s.chars().collect();
    let mut new_v: Vec<char> = Vec::new();

    let mut i: i32 = k-1;

    while i < (s_v.len() as i32) {
        new_v.push(s_v[(i as usize)]);
        i += 1;
    }

    let mut new_i = 0;
    while new_i <= k-2 {
        new_v.push(s_v[(new_i as usize)]);
        new_i += 1;
    }

    return new_v;
}

fn l_to_n(l: char) -> i16 {
    match l {
        'A' => 0,
        'B' => 1,
        'C' => 2,
        'D' => 3,
        'E' => 4,
        'F' => 5,
        'G' => 6,
        'H' => 7,
        'I' => 8,
        'J' => 9,
        'K' => 10,
        'L' => 11,
        'M' => 12,
        'N' => 13,
        'O' => 14,
        'P' => 15,
        'Q' => 16,
        'R' => 17,
        'S' => 18,
        'T' => 19,
        'U' => 20,
        'V' => 21,
        'W' => 22,
        'X' => 23,
        'Y' => 24,
        'Z' => 25,
        _ => 30
    }
}

fn encsr_w(word: &str, key: i32) -> String {
    let starting = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    let key_v = key_v(starting, key);

    let mut index_v: Vec<i16> = Vec::new();

    for l in word.to_uppercase().chars() {
        index_v.push(l_to_n(l));
    }

    let mut new_w_v: Vec<char> = Vec::new();

    for i in index_v {
        new_w_v.push(key_v[(i as usize)]);
    }

    let s: String = new_w_v.into_iter().collect();

    return s;
}

fn decsr_w(word: &str, key: i32) -> String {

    let starting = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    let key_v = key_v(starting, key);

    let mut pos_v: Vec<i16> = Vec::new();
    let mut cur_i: i16 = 0;

    for c in word.to_uppercase().chars() {
        while cur_i < (key_v.len() as i16) - 1 {
            if c == key_v[(cur_i as usize)] {
                pos_v.push(cur_i);
                cur_i = 0;
                break;
            }
            cur_i += 1
        }
    }

    let c_vec: Vec<char> = starting.chars().collect();
    let mut fin_v: Vec<char> = Vec::new();

    for p in pos_v {
        fin_v.push(c_vec[(p as usize)]);
    }

    let s: String = fin_v.into_iter().collect();
    return s;
}

fn encsr(word: &str, key: i32) -> String {
    let sp_w: Vec<&str> = word.split(" ").collect();
    let mut w_v: Vec<String> = Vec::new();

    for cur_w in sp_w {
        w_v.push(encsr_w(cur_w, key));
    }

    return w_v.join(" ");
}

fn decsr(enc: &str, key: i32) -> String {
    let mut fin_v: Vec<String> = Vec::new();

    for pt in enc.split(" ") {
        fin_v.push(decsr_w(pt.trim(), key));
    }

    return fin_v.join(" ");
}
<|endoftext|>


<commit_before>use std::io::prelude::*;
use std::net::TcpStream;

fn read_u32(packet: &[u8], offset: usize) -> u32 {
    (packet[offset] as u32) + ((packet[offset + 1]) as u32) +
        ((packet[offset + 2]) as u32) + ((packet[offset + 3]) as u32)
}

fn main() {
    let mut stream = match TcpStream::connect("127.0.0.1:3306") {
        Ok(v) => v,
        Err(e) => panic!("Err connecting to MySQL: {:?}", e)
    };

    let mut first_packet = [ 0u8; 128 ];
    let read_length = match stream.read(&mut first_packet) {
        Ok(v) => {
            if 0 == v {
                panic!("No length read in the first packet");
            }

            v
        },
        Err(e) => panic!("Err read the first packet: {:?}", e)
    };

    println!("Packet Read: {}", read_length);

    let content_length =
        (first_packet[0] as u32) + ((first_packet[1] as u32) << 8u32) + ((first_packet[2] as u32) << 16u32);
    println!("Content Length: {}", content_length);
    println!("Packet Number: {}", first_packet[3]);
    println!("Protocol Version: {}", first_packet[4]);

    let mut offset;
    let mut version_info = String::new();
    {
        offset = 5;
        for i in offset..offset + 31 {
            if 0 == first_packet[i] {
                break;
            }

            version_info.push(first_packet[i] as char);
        }
    }
    println!("Protocol Information: {}", version_info);

    let server_thread_id = read_u32(&first_packet, 32);
    println!("Server Thread ID: {}", server_thread_id);
}
<commit_msg>finish the first packet<commit_after>use std::io::prelude::*;
use std::net::TcpStream;

fn read_u32(packet: &[u8], offset: usize) -> u32 {
    (packet[offset] as u32) + ((packet[offset + 1]) as u32) +
        ((packet[offset + 2]) as u32) + ((packet[offset + 3]) as u32)
}

fn read_8bytes(packet: &[u8], offset: usize) -> [u8;8] {
    let mut _packet = [0u8; 8];
    for i in 0..8 {
        _packet[i] = packet[i + offset];
    }

    _packet
}

fn read_n_bytes(packet: &[u8], offset: usize, size: usize) -> Vec<u8> {
    let mut vec = vec![];
    for i in 0..size {
        vec.push(packet[i + offset]);
    }

    vec
}

fn read_u16(packet: &[u8], offset: usize) -> u16 {
    (packet[offset] as u16) + ((packet[offset + 1]) as u16)
}

fn vec_to_string(vec: Vec<u8>) -> String {
    let mut str = String::new();
    for i in 0..vec.len() {
        if 0 == vec[i] {
            break;
        }

        str.push(vec[i] as char);
    }

    str
}

fn main() {
    let mut stream = match TcpStream::connect("127.0.0.1:3306") {
        Ok(v) => v,
        Err(e) => panic!("Err connecting to MySQL: {:?}", e)
    };

    let mut first_packet = [ 0u8; 128 ];
    let read_length = match stream.read(&mut first_packet) {
        Ok(v) => {
            if 0 == v {
                panic!("No length read in the first packet");
            }

            v
        },
        Err(e) => panic!("Err read the first packet: {:?}", e)
    };

    println!("Packet Read: {}", read_length);

    let content_length =
        (first_packet[0] as u32) + ((first_packet[1] as u32) << 8u32) + ((first_packet[2] as u32) << 16u32);
    println!("Content Length: {}", content_length);
    println!("Packet Number: {}", first_packet[3]);
    println!("Protocol Version: {}", first_packet[4]);

    let mut offset;
    let mut version_info = String::new();
    {
        offset = 5;
        for i in offset..offset + 32 {
            if 0 == first_packet[i] {
                offset = i + 1;
                break;
            }

            version_info.push(first_packet[i] as char);
        }
    }
    println!("Protocol Information: {}", version_info);

    let server_thread_id = read_u32(&first_packet, offset);
    println!("Server Thread ID: {}", server_thread_id);

    offset += 4;
    let challenge_random_number1 = read_8bytes(&first_packet, offset);
    println!("Challenge Random Number 1: {:?}", challenge_random_number1);

    offset += 8 + 1;
    let server_capabilities_identified = read_u16(&first_packet, offset);
    println!("Server Capabilities Identified: {}", server_capabilities_identified);

    offset += 2;
    let char_code = first_packet[offset];
    println!("Char Code: {}", char_code);

    offset += 1;
    let server_status = read_u16(&first_packet, offset);
    println!("Server Status: {}", server_status);

    offset += 2;
    let server_capabilities_identified_high = read_u16(&first_packet, offset);
    println!("Server Capabilities Identified High: {}", server_capabilities_identified_high);

    offset += 2;
    let challenge_length = first_packet[offset];
    println!("Challenge Length: {}", challenge_length);

    offset += 1;
    let fill_value = read_n_bytes(&first_packet, offset, 10);
    println!("Fill Value: {:?}", fill_value);

    offset += 10;

    let mut challenge_random_number2 : Vec<u8> = vec![];
    {
        for i in offset..read_length as usize {
            if 0 == first_packet[i] {
                offset = i + 1;
                break;
            }

            challenge_random_number2.push(first_packet[i]);
        }
    }
    println!("Challenge Random Number 2: {:?}", challenge_random_number2);

    println!("Left: {:?}", vec_to_string(read_n_bytes(&first_packet, offset, read_length - offset)));
}
<|endoftext|>


<commit_before>#![feature(panic_implementation)] // required for defining the panic handler
#![feature(panic_info_message)]
#![feature(abi_x86_interrupt)]
#![no_std] // don't link the Rust standard library
#![cfg_attr(not(test), no_main)] // disable all Rust-level entry points
#![cfg_attr(test, allow(dead_code, unused_macros, unused_imports))]

#[macro_use]
extern crate eduos_rs;

use core::panic::PanicInfo;
use eduos_rs::arch::processor::{shutdown,halt};
use eduos_rs::scheduler;
use eduos_rs::scheduler::task::{NORMAL_PRIORITY,HIGH_PRIORITY};

extern "C" fn foo() {
	for _i in 0..5 {
		println!("hello from task {}", scheduler::get_current_taskid());
		scheduler::reschedule();
	}
}

/// This function is the entry point, since the linker looks for a function
/// named `_start` by default.
#[cfg(not(test))]
#[no_mangle] // don't mangle the name of this function
pub extern "C" fn main() -> ! {
	scheduler::init();

	println!("Hello from eduOS-rs!");

	for _i in 0..2 {
		scheduler::spawn(foo, NORMAL_PRIORITY).unwrap();
	}
	scheduler::spawn(foo, HIGH_PRIORITY).unwrap();

	scheduler::reschedule();

	println!("Shutdown system!");

	// shutdown system
	shutdown();
}

/// This function is called on panic.
#[cfg(not(test))]
#[panic_handler]
pub fn panic(info: &PanicInfo) -> ! {
	print!("[!!!PANIC!!!] ");

	if let Some(location) = info.location() {
		print!("{}:{}: ", location.file(), location.line());
	}

	if let Some(message) = info.message() {
		print!("{}", message);
	}

	print!("\n");

	loop {
		halt();
	}
}
<commit_msg>remove obsolte line #![feature(panic_implementation)]<commit_after>#![feature(panic_info_message)]
#![feature(abi_x86_interrupt)]
#![no_std] // don't link the Rust standard library
#![cfg_attr(not(test), no_main)] // disable all Rust-level entry points
#![cfg_attr(test, allow(dead_code, unused_macros, unused_imports))]

#[macro_use]
extern crate eduos_rs;

use core::panic::PanicInfo;
use eduos_rs::arch::processor::{shutdown,halt};
use eduos_rs::scheduler;
use eduos_rs::scheduler::task::{NORMAL_PRIORITY,HIGH_PRIORITY};

extern "C" fn foo() {
	for _i in 0..5 {
		println!("hello from task {}", scheduler::get_current_taskid());
		scheduler::reschedule();
	}
}

/// This function is the entry point, since the linker looks for a function
/// named `_start` by default.
#[cfg(not(test))]
#[no_mangle] // don't mangle the name of this function
pub extern "C" fn main() -> ! {
	scheduler::init();

	println!("Hello from eduOS-rs!");

	for _i in 0..2 {
		scheduler::spawn(foo, NORMAL_PRIORITY).unwrap();
	}
	scheduler::spawn(foo, HIGH_PRIORITY).unwrap();

	scheduler::reschedule();

	println!("Shutdown system!");

	// shutdown system
	shutdown();
}

/// This function is called on panic.
#[cfg(not(test))]
#[panic_handler]
pub fn panic(info: &PanicInfo) -> ! {
	print!("[!!!PANIC!!!] ");

	if let Some(location) = info.location() {
		print!("{}:{}: ", location.file(), location.line());
	}

	if let Some(message) = info.message() {
		print!("{}", message);
	}

	print!("\n");

	loop {
		halt();
	}
}
<|endoftext|>