<commit_before>extern crate getopts;
extern crate iron;
extern crate mote;
extern crate rgb;
extern crate router;
extern crate serde_json;
extern crate unicase;
extern crate url;

#[macro_use]
extern crate serde_derive;

#[macro_use]
extern crate maplit;

use std::env;
use std::io::Read;
use std::str::FromStr;
use std::sync::{Arc, Mutex};

use getopts::Options;
use iron::headers::{AccessControlAllowHeaders, AccessControlAllowOrigin, ContentType};
use iron::middleware::Handler;
use iron::prelude::{IronResult, Request, Response};
use iron::prelude::*;
use iron::status;
use router::Router;
use unicase::UniCase;

mod google_actions;
use google_actions::{ActionRequest, ExecuteResponse, ExecuteResponseCommand,
                     ExecuteResponsePayload, Name, QueryResponse, QueryResponsePayload,
                     SyncResponse, SyncResponseDevice, SyncResponsePayload};

mod light;
use light::{Light, LightMode, LightStatus, LightType};

mod thermostat;
use thermostat::ThermostatMode;

mod scene;
use scene::Scene;

mod device;
use device::Device;

mod oauth;

struct Hub {
    devices: Mutex<Vec<Device>>,
}

impl Handler for Hub {
    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        println!("hub handler");
        let mut body = String::new();
        req.body.read_to_string(&mut body).unwrap();
        let action_request: ActionRequest = serde_json::from_str(&body).unwrap();

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

        for input in action_request.inputs {
            if input.intent == "action.devices.SYNC" {
                let mut response = SyncResponse {
                    request_id: action_request.request_id.clone(),
                    payload: SyncResponsePayload {
                        agent_user_id: "1111".to_string(),
                        devices: vec![],
                    },
                };

                let ref devices = *self.devices.lock().unwrap();
                for device in devices {
                    match device {
                        &Device::Light(ref light) => {
                            response.payload.devices.push(SyncResponseDevice {
                                id: light.id.clone(),
                                type_: light.type_.to_string(),
                                traits: light
                                    .available_light_modes
                                    .iter()
                                    .map(LightMode::to_string)
                                    .collect(),
                                name: Name {
                                    default_name: vec![light.name.to_string()],
                                    name: Some(light.name.clone()),
                                    nicknames: vec![],
                                },
                                will_report_state: false,
                                device_info: None,
                                room_hint: None,
                                structure_hint: None,
                                attributes: None,
                            })
                        }
                        &Device::Thermostat(ref thermostat) => {
                            response.payload.devices.push(SyncResponseDevice {
                                id: thermostat.id.clone(),
                                type_: "".to_string(), // XXX
                                traits: vec![
                                    "action.devices.traits.TemperatureSetting".to_string(),
                                ],
                                name: Name {
                                    default_name: vec![thermostat.name.to_string()],
                                    name: Some(thermostat.name.clone()),
                                    nicknames: vec![],
                                },
                                // TODO: attributes.
                                will_report_state: false,
                                device_info: None,
                                room_hint: None,
                                structure_hint: None,
                                attributes: None,
                            })
                        }
                        &Device::Scene(ref scene) => {
                            response.payload.devices.push(SyncResponseDevice {
                                id: scene.id.clone(),
                                type_: "action.devices.types.SCENE".to_string(),
                                traits: vec!["action.devices.traits.Scene".to_string()],
                                name: Name {
                                    default_name: vec![scene.name.to_string()],
                                    name: Some(scene.name.clone()),
                                    nicknames: vec![],
                                },
                                will_report_state: false,
                                device_info: None,
                                room_hint: None,
                                structure_hint: None,
                                attributes: None,
                            })
                        }
                    }
                }

                let res = serde_json::to_string(&response).unwrap_or("".to_string());
                println!("action_response: {:?}", res);
                let mut rsp = Response::with((status::Ok, res));
                rsp.headers.set(ContentType::json());
                // For browser access.
                rsp.headers.set(AccessControlAllowOrigin::Any);
                return Ok(rsp);
            } else if input.intent == "action.devices.QUERY" {
                let mut response = QueryResponse {
                    request_id: action_request.request_id.clone(),
                    payload: QueryResponsePayload {
                        devices: btreemap!{},
                    },
                };

                let ref devices = *self.devices.lock().unwrap();
                if let Some(payload) = input.payload {
                    for request_device in payload.devices {
                        for device in devices {
                            match device {
                                &Device::Light(ref light) => if light.id == request_device.id {
                                    response
                                        .payload
                                        .devices
                                        .insert(light.id.clone(), light.status.clone().into());
                                },
                                &Device::Thermostat(ref thermostat) => {
                                    if thermostat.id == request_device.id {
                                        // TODO
                                    }
                                }
                                &Device::Scene(ref _scene) => {}
                            }
                        }
                    }
                }

                let res = serde_json::to_string(&response).unwrap_or("".to_string());
                println!("action_response: {:?}", res);
                let mut rsp = Response::with((status::Ok, res));
                rsp.headers.set(ContentType::json());
                // For browser access.
                rsp.headers.set(AccessControlAllowOrigin::Any);
                return Ok(rsp);
            } else if input.intent == "action.devices.EXECUTE" {
                let mut response = ExecuteResponse {
                    request_id: action_request.request_id.clone(),
                    payload: ExecuteResponsePayload {
                        error_code: None,
                        debug_string: None,
                        commands: vec![],
                    },
                };

                if let Some(ref p) = input.payload {
                    for command in &p.commands {
                        println!("command: {:?}", command);
                        for execution in &command.execution {
                            println!("execution: {:?}", execution);
                            for request_device in &command.devices {
                                println!("request_device: {:?}", request_device);
                                let ref mut devices = *self.devices.lock().unwrap();
                                for device in devices {
                                    match device {
                                        &mut Device::Light(ref mut light) => {
                                            if light.id == request_device.id {
                                                if let Some(s) = execution.params.on {
                                                    light.set_on(s);
                                                }
                                                if let Some(s) = execution.params.brightness {
                                                    light.set_brightness(s);
                                                }
                                                if let Some(ref s) = execution.params.color {
                                                    if let Some(s) = s.spectrum_rgb {
                                                        light.set_color(to_rgb(s));
                                                    }
                                                }
                                                response.payload.commands.push(
                                                    ExecuteResponseCommand {
                                                        ids: vec![light.id.clone()],
                                                        status: "SUCCESS".to_string(),
                                                        states: light.status.clone().into(),
                                                    },
                                                );
                                            }
                                        }
                                        &mut Device::Thermostat(ref mut thermostat) => {
                                            if thermostat.id == request_device.id {
                                                if let Some(s) =
                                                    execution.params.thermostat_temperature_setpoint
                                                {
                                                    thermostat.temperature_setpoint(s);
                                                }
                                                if let (Some(low), Some(high)) = (
                                                    execution
                                                        .params
                                                        .thermostat_temperature_setpoint_low,
                                                    execution
                                                        .params
                                                        .thermostat_temperature_setpoint_high,
                                                ) {
                                                    thermostat.temperature_set_range(low, high);
                                                }
                                                if let Some(ref mode) =
                                                    execution.params.thermostat_mode
                                                {
                                                    if let Ok(mode) = ThermostatMode::from_str(mode)
                                                    {
                                                        thermostat.thermostat_set_mode(mode);
                                                    }
                                                }
                                                response.payload.commands.push(
                                                    ExecuteResponseCommand {
                                                        ids: vec![thermostat.id.clone()],
                                                        status: "SUCCESS".to_string(),
                                                        states: thermostat.status.clone().into(),
                                                    },
                                                );
                                            }
                                        }
                                        &mut Device::Scene(ref mut _scene) => {}
                                    }
                                }
                            }
                        }
                    }
                }

                let res = serde_json::to_string(&response).unwrap_or("".to_string());
                println!("action_response: {:?}", res);
                let mut rsp = Response::with((status::Ok, res));
                rsp.headers.set(ContentType::json());
                // For browser access.
                rsp.headers.set(AccessControlAllowOrigin::Any);
                return Ok(rsp);
            }
        }

        let mut rsp = Response::with((status::Ok, "ACTION"));
        rsp.headers.set(ContentType::json());
        // For browser access.
        rsp.headers.set(AccessControlAllowOrigin::Any);
        Ok(rsp)
    }
}

fn to_rgb(c: u64) -> rgb::RGB8 {
    rgb::RGB8 {
        r: ((c & 0xFF0000) >> 16) as u8,
        g: ((c & 0x00FF00) >> 8) as u8,
        b: ((c & 0x0000FF) >> 0) as u8,
    }
}

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

    let mut opts = Options::new();
    opts.optopt("", "http_address", "HTTP address to listen on", "ADDRESS");
    opts.optopt("", "mote_dev", "Serial port connecting to Mote", "FILE");

    let matches = opts.parse(&args[1..]).unwrap();
    let http_address = matches.opt_str("http_address").unwrap_or("0.0.0.0:1234".to_string());
    let mote_dev = matches.opt_str("mote_dev").unwrap_or("/dev/ttyACM0".to_string());

    let mote = Arc::new(Mutex::new(mote::Mote::new(&mote_dev, true)));
    let hub = Hub {
        devices: Mutex::new(vec![
            Device::Light(Light {
                id: "11".to_string(),
                name: "Bedroom lights".to_string(),
                status: LightStatus::default(),
                type_: LightType::Light,
                available_light_modes: vec![
                    LightMode::OnOff,
                    LightMode::Brightness,
                    LightMode::ColorSpectrum,
                ],
                mote: mote.clone(),
                pixel_low: 0,
                pixel_high: 16,
            }),
            Device::Light(Light {
                id: "22".to_string(),
                name: "Kitchen lights".to_string(),
                status: LightStatus::default(),
                type_: LightType::Light,
                available_light_modes: vec![
                    LightMode::OnOff,
                    LightMode::Brightness,
                    LightMode::ColorSpectrum,
                ],
                mote: mote.clone(),
                pixel_low: 16,
                pixel_high: 32,
            }),
            Device::Light(Light {
                id: "33".to_string(),
                name: "Bathroom lights".to_string(),
                status: LightStatus::default(),
                type_: LightType::Light,
                available_light_modes: vec![
                    LightMode::OnOff,
                    LightMode::Brightness,
                    LightMode::ColorSpectrum,
                ],
                mote: mote.clone(),
                pixel_low: 32,
                pixel_high: 48,
            }),
            Device::Light(Light {
                id: "44".to_string(),
                name: "Living Room lights".to_string(),
                status: LightStatus::default(),
                type_: LightType::Light,
                available_light_modes: vec![
                    LightMode::OnOff,
                    LightMode::Brightness,
                    LightMode::ColorSpectrum,
                ],
                mote: mote.clone(),
                pixel_low: 48,
                pixel_high: 64,
            }),
            Device::Scene(Scene {
                id: "55".to_string(),
                name: "Party mode".to_string(),
                reversible: false,
            }),
        ]),
    };
    let oauth = oauth::OAuth::new();
    let mut control = Router::new();
    control
        .get("/auth", oauth.auth, "auth")
        .post("/token", oauth.token, "token")
        .get("/login", oauth.login, "login")
        .post("/action", hub, "post action")
        .get("/action", get_action_handler, "get action")
        .options("/action", options_action_handler, "get action")
        .get("/", index_handler, "index");
    println!("Listening on {}", http_address);
    Iron::new(control).http(http_address).unwrap();
}

fn index_handler(_: &mut Request) -> IronResult<Response> {
    Ok(Response::with((status::Ok, "index")))
}

fn get_action_handler(_: &mut Request) -> IronResult<Response> {
    Ok(Response::with((status::Ok, "get action")))
}

fn options_action_handler(_: &mut Request) -> IronResult<Response> {
    let mut rsp = Response::with((status::Ok, "options"));
    rsp.headers.set(AccessControlAllowOrigin::Any);
    rsp.headers.set(AccessControlAllowHeaders(
        vec![UniCase("Content-Type".to_string())],
    ));
    Ok(rsp)
}
<commit_msg>thermostat<commit_after>extern crate getopts;
extern crate iron;
extern crate mote;
extern crate rgb;
extern crate router;
extern crate serde_json;
extern crate unicase;
extern crate url;

#[macro_use]
extern crate serde_derive;

#[macro_use]
extern crate maplit;

use std::env;
use std::io::Read;
use std::str::FromStr;
use std::sync::{Arc, Mutex};

use getopts::Options;
use iron::headers::{AccessControlAllowHeaders, AccessControlAllowOrigin, ContentType};
use iron::middleware::Handler;
use iron::prelude::{IronResult, Request, Response};
use iron::prelude::*;
use iron::status;
use router::Router;
use unicase::UniCase;

mod google_actions;
use google_actions::{ActionRequest, ExecuteResponse, ExecuteResponseCommand,
                     ExecuteResponsePayload, Name, QueryResponse, QueryResponsePayload,
                     SyncResponse, SyncResponseDevice, SyncResponsePayload};

mod light;
use light::{Light, LightMode, LightStatus, LightType};

mod thermostat;
use thermostat::{Thermostat, ThermostatMode, ThermostatStatus, TemperatureUnit};

mod scene;
use scene::Scene;

mod device;
use device::Device;

mod oauth;

struct Hub {
    devices: Mutex<Vec<Device>>,
}

impl Handler for Hub {
    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        println!("hub handler");
        let mut body = String::new();
        req.body.read_to_string(&mut body).unwrap();
        let action_request: ActionRequest = serde_json::from_str(&body).unwrap();

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

        for input in action_request.inputs {
            if input.intent == "action.devices.SYNC" {
                let mut response = SyncResponse {
                    request_id: action_request.request_id.clone(),
                    payload: SyncResponsePayload {
                        agent_user_id: "1111".to_string(),
                        devices: vec![],
                    },
                };

                let ref devices = *self.devices.lock().unwrap();
                for device in devices {
                    match device {
                        &Device::Light(ref light) => {
                            response.payload.devices.push(SyncResponseDevice {
                                id: light.id.clone(),
                                type_: light.type_.to_string(),
                                traits: light
                                    .available_light_modes
                                    .iter()
                                    .map(LightMode::to_string)
                                    .collect(),
                                name: Name {
                                    default_name: vec![light.name.to_string()],
                                    name: Some(light.name.clone()),
                                    nicknames: vec![],
                                },
                                will_report_state: false,
                                device_info: None,
                                room_hint: None,
                                structure_hint: None,
                                attributes: None,
                            })
                        }
                        &Device::Thermostat(ref thermostat) => {
                            response.payload.devices.push(SyncResponseDevice {
                                id: thermostat.id.clone(),
                                type_: "".to_string(), // XXX
                                traits: vec![
                                    "action.devices.traits.TemperatureSetting".to_string(),
                                ],
                                name: Name {
                                    default_name: vec![thermostat.name.to_string()],
                                    name: Some(thermostat.name.clone()),
                                    nicknames: vec![],
                                },
                                // TODO: attributes.
                                will_report_state: false,
                                device_info: None,
                                room_hint: None,
                                structure_hint: None,
                                attributes: None,
                            })
                        }
                        &Device::Scene(ref scene) => {
                            response.payload.devices.push(SyncResponseDevice {
                                id: scene.id.clone(),
                                type_: "action.devices.types.SCENE".to_string(),
                                traits: vec!["action.devices.traits.Scene".to_string()],
                                name: Name {
                                    default_name: vec![scene.name.to_string()],
                                    name: Some(scene.name.clone()),
                                    nicknames: vec![],
                                },
                                will_report_state: false,
                                device_info: None,
                                room_hint: None,
                                structure_hint: None,
                                attributes: None,
                            })
                        }
                    }
                }

                let res = serde_json::to_string(&response).unwrap_or("".to_string());
                println!("action_response: {:?}", res);
                let mut rsp = Response::with((status::Ok, res));
                rsp.headers.set(ContentType::json());
                // For browser access.
                rsp.headers.set(AccessControlAllowOrigin::Any);
                return Ok(rsp);
            } else if input.intent == "action.devices.QUERY" {
                let mut response = QueryResponse {
                    request_id: action_request.request_id.clone(),
                    payload: QueryResponsePayload {
                        devices: btreemap!{},
                    },
                };

                let ref devices = *self.devices.lock().unwrap();
                if let Some(payload) = input.payload {
                    for request_device in payload.devices {
                        for device in devices {
                            match device {
                                &Device::Light(ref light) => if light.id == request_device.id {
                                    response
                                        .payload
                                        .devices
                                        .insert(light.id.clone(), light.status.clone().into());
                                },
                                &Device::Thermostat(ref thermostat) => {
                                    if thermostat.id == request_device.id {
                                        // TODO
                                    }
                                }
                                &Device::Scene(ref _scene) => {}
                            }
                        }
                    }
                }

                let res = serde_json::to_string(&response).unwrap_or("".to_string());
                println!("action_response: {:?}", res);
                let mut rsp = Response::with((status::Ok, res));
                rsp.headers.set(ContentType::json());
                // For browser access.
                rsp.headers.set(AccessControlAllowOrigin::Any);
                return Ok(rsp);
            } else if input.intent == "action.devices.EXECUTE" {
                let mut response = ExecuteResponse {
                    request_id: action_request.request_id.clone(),
                    payload: ExecuteResponsePayload {
                        error_code: None,
                        debug_string: None,
                        commands: vec![],
                    },
                };

                if let Some(ref p) = input.payload {
                    for command in &p.commands {
                        println!("command: {:?}", command);
                        for execution in &command.execution {
                            println!("execution: {:?}", execution);
                            for request_device in &command.devices {
                                println!("request_device: {:?}", request_device);
                                let ref mut devices = *self.devices.lock().unwrap();
                                for device in devices {
                                    match device {
                                        &mut Device::Light(ref mut light) => {
                                            if light.id == request_device.id {
                                                if let Some(s) = execution.params.on {
                                                    light.set_on(s);
                                                }
                                                if let Some(s) = execution.params.brightness {
                                                    light.set_brightness(s);
                                                }
                                                if let Some(ref s) = execution.params.color {
                                                    if let Some(s) = s.spectrum_rgb {
                                                        light.set_color(to_rgb(s));
                                                    }
                                                }
                                                response.payload.commands.push(
                                                    ExecuteResponseCommand {
                                                        ids: vec![light.id.clone()],
                                                        status: "SUCCESS".to_string(),
                                                        states: light.status.clone().into(),
                                                    },
                                                );
                                            }
                                        }
                                        &mut Device::Thermostat(ref mut thermostat) => {
                                            if thermostat.id == request_device.id {
                                                if let Some(s) =
                                                    execution.params.thermostat_temperature_setpoint
                                                {
                                                    thermostat.temperature_setpoint(s);
                                                }
                                                if let (Some(low), Some(high)) = (
                                                    execution
                                                        .params
                                                        .thermostat_temperature_setpoint_low,
                                                    execution
                                                        .params
                                                        .thermostat_temperature_setpoint_high,
                                                ) {
                                                    thermostat.temperature_set_range(low, high);
                                                }
                                                if let Some(ref mode) =
                                                    execution.params.thermostat_mode
                                                {
                                                    if let Ok(mode) = ThermostatMode::from_str(mode)
                                                    {
                                                        thermostat.thermostat_set_mode(mode);
                                                    }
                                                }
                                                response.payload.commands.push(
                                                    ExecuteResponseCommand {
                                                        ids: vec![thermostat.id.clone()],
                                                        status: "SUCCESS".to_string(),
                                                        states: thermostat.status.clone().into(),
                                                    },
                                                );
                                            }
                                        }
                                        &mut Device::Scene(ref mut _scene) => {}
                                    }
                                }
                            }
                        }
                    }
                }

                let res = serde_json::to_string(&response).unwrap_or("".to_string());
                println!("action_response: {:?}", res);
                let mut rsp = Response::with((status::Ok, res));
                rsp.headers.set(ContentType::json());
                // For browser access.
                rsp.headers.set(AccessControlAllowOrigin::Any);
                return Ok(rsp);
            }
        }

        let mut rsp = Response::with((status::Ok, "ACTION"));
        rsp.headers.set(ContentType::json());
        // For browser access.
        rsp.headers.set(AccessControlAllowOrigin::Any);
        Ok(rsp)
    }
}

fn to_rgb(c: u64) -> rgb::RGB8 {
    rgb::RGB8 {
        r: ((c & 0xFF0000) >> 16) as u8,
        g: ((c & 0x00FF00) >> 8) as u8,
        b: ((c & 0x0000FF) >> 0) as u8,
    }
}

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

    let mut opts = Options::new();
    opts.optopt("", "http_address", "HTTP address to listen on", "ADDRESS");
    opts.optopt("", "mote_dev", "Serial port connecting to Mote", "FILE");

    let matches = opts.parse(&args[1..]).unwrap();
    let http_address = matches.opt_str("http_address").unwrap_or("0.0.0.0:1234".to_string());
    let mote_dev = matches.opt_str("mote_dev").unwrap_or("/dev/ttyACM0".to_string());

    let mote = Arc::new(Mutex::new(mote::Mote::new(&mote_dev, true)));
    let hub = Hub {
        devices: Mutex::new(vec![
            Device::Light(Light {
                id: "11".to_string(),
                name: "Bedroom lights".to_string(),
                status: LightStatus::default(),
                type_: LightType::Light,
                available_light_modes: vec![
                    LightMode::OnOff,
                    LightMode::Brightness,
                    LightMode::ColorSpectrum,
                ],
                mote: mote.clone(),
                pixel_low: 0,
                pixel_high: 16,
            }),
            Device::Light(Light {
                id: "22".to_string(),
                name: "Kitchen lights".to_string(),
                status: LightStatus::default(),
                type_: LightType::Light,
                available_light_modes: vec![
                    LightMode::OnOff,
                    LightMode::Brightness,
                    LightMode::ColorSpectrum,
                ],
                mote: mote.clone(),
                pixel_low: 16,
                pixel_high: 32,
            }),
            Device::Light(Light {
                id: "33".to_string(),
                name: "Bathroom lights".to_string(),
                status: LightStatus::default(),
                type_: LightType::Light,
                available_light_modes: vec![
                    LightMode::OnOff,
                    LightMode::Brightness,
                    LightMode::ColorSpectrum,
                ],
                mote: mote.clone(),
                pixel_low: 32,
                pixel_high: 48,
            }),
            Device::Light(Light {
                id: "44".to_string(),
                name: "Living Room lights".to_string(),
                status: LightStatus::default(),
                type_: LightType::Light,
                available_light_modes: vec![
                    LightMode::OnOff,
                    LightMode::Brightness,
                    LightMode::ColorSpectrum,
                ],
                mote: mote.clone(),
                pixel_low: 48,
                pixel_high: 64,
            }),
            Device::Scene(Scene {
                id: "55".to_string(),
                name: "Party mode".to_string(),
                reversible: false,
            }),
            Device::Thermostat(Thermostat {
                id: "66".to_string(),
                name: "Thermo".to_string(),
                available_thermostat_modes: vec![],
                thermostat_temperature_unit: TemperatureUnit::C,
                status: ThermostatStatus {
                    mode: ThermostatMode::Off,
                    temperature_setpoint: 21.0,
                    temperature_ambient: 20.0,
                    temperature_setpoint_low: 10.0,
                    temperature_setpoint_high: 30.0,
                    temperature_humidity_ambient: 50.0,
                },
            }),
        ]),
    };
    let oauth = oauth::OAuth::new();
    let mut control = Router::new();
    control
        .get("/auth", oauth.auth, "auth")
        .post("/token", oauth.token, "token")
        .get("/login", oauth.login, "login")
        .post("/action", hub, "post action")
        .get("/action", get_action_handler, "get action")
        .options("/action", options_action_handler, "get action")
        .get("/", index_handler, "index");
    println!("Listening on {}", http_address);
    Iron::new(control).http(http_address).unwrap();
}

fn index_handler(_: &mut Request) -> IronResult<Response> {
    Ok(Response::with((status::Ok, "index")))
}

fn get_action_handler(_: &mut Request) -> IronResult<Response> {
    Ok(Response::with((status::Ok, "get action")))
}

fn options_action_handler(_: &mut Request) -> IronResult<Response> {
    let mut rsp = Response::with((status::Ok, "options"));
    rsp.headers.set(AccessControlAllowOrigin::Any);
    rsp.headers.set(AccessControlAllowHeaders(
        vec![UniCase("Content-Type".to_string())],
    ));
    Ok(rsp)
}
<|endoftext|>


<commit_before>extern crate ansi_term;
extern crate regex;

use regex::Regex;

use std::env;
use ansi_term::Colour::{Cyan, Blue, Purple};

fn fmt_current_path(cwd: &str) -> String {
    let home: Regex = match env::home_dir() {
        Some(path) => Regex::new(path.to_str().unwrap()).unwrap(),
        None => Regex::new("").unwrap(),
    };
    let friendly_path = home.replace(cwd, "~").to_string();
    let mut friendly_path_split: Vec<&str> = friendly_path.split("/").collect();
    let current_dir = friendly_path_split.pop().unwrap().to_string();
    let mut short_path: Vec<String> = friendly_path_split.iter().map(|s| s.chars().next().unwrap().to_string()).collect();
    short_path.push(current_dir);
    short_path.join("/")
}

fn main() {
    let my_path = env::current_dir().unwrap();
    let display_path = Blue.paint(fmt_current_path(my_path.to_str().unwrap()));

    let branch ="master";
    let display_branch = Cyan.paint(branch);

    println!("{} {}", display_path, display_branch);
    print!(" {} ", Purple.paint("❯"));
}
<commit_msg>Displays short paths<commit_after>extern crate ansi_term;
extern crate regex;

use regex::Regex;

use std::env;
use ansi_term::Colour::{Cyan, Blue, Purple};

fn first_char(s: &str) -> String {
    let chars: Vec<char> = s.chars().collect();
    return match chars.len() {
        0 => String::from(""),
        _ => chars[0].to_string()
    }
}

fn fmt_current_path(cwd: &str) -> String {
    let home: Regex = match env::home_dir() {
        Some(path) => Regex::new(path.to_str().unwrap()).unwrap(),
        None => Regex::new("").unwrap(),
    };
    let friendly_path = home.replace(cwd, "~").to_string();
    let mut friendly_path_split: Vec<&str> = friendly_path.split("/").collect();
    let current_dir = friendly_path_split.pop().unwrap().to_string();
    let mut short_path: Vec<String> = friendly_path_split.iter().map(|s| first_char(s)).collect();
    short_path.push(current_dir);
    short_path.join("/")
}

fn main() {
    let my_path = env::current_dir().unwrap();
    let display_path = Blue.paint(fmt_current_path(my_path.to_str().unwrap()));

    let branch ="master";
    let display_branch = Cyan.paint(branch);

    println!("{} {}", display_path, display_branch);
    print!(" {} ", Purple.paint("❯"));
}
<|endoftext|>


<commit_before>use std::env;

extern crate zwreec;

fn main() {
    println!("#main started");

    // handling commandline parameters
    let args: Vec<String> = env::args().collect();

    let mut input_file_name: &str;
    let mut output_file_name: &str;

    match args.len() {
        1 => {
            input_file_name = "a.in";
            output_file_name = "a.out";
        },
        3 => {
            input_file_name = &args[1];
            output_file_name = &args[2];
        },
        _ => help()
    };

    // call library
    zwreec::compile(input_file_name, output_file_name);

    // only for testing
    println!("(1) {}", zwreec::frontend::temp_hello());
    println!("(2) {}", zwreec::backend::temp_hello());
    println!("(3) {}", zwreec::file::temp_hello());

    println!("#main finished");
}

fn help() {
    println!("usage:\n    zwreec <input_file> <output_file>");
}
<commit_msg>Return if invalid number of arguments<commit_after>use std::env;

extern crate zwreec;

fn main() {
    println!("#main started");

    // handling commandline parameters
    let args: Vec<String> = env::args().collect();

    let mut input_file_name: &str;
    let mut output_file_name: &str;

    match args.len() {
        1 => {
            input_file_name = "a.in";
            output_file_name = "a.out";
        },
        3 => {
            input_file_name = &args[1];
            output_file_name = &args[2];
        },
        _ => {
            help();
            return;
        }
    };

    // call library
    zwreec::compile(input_file_name, output_file_name);

    // only for testing
    println!("(1) {}", zwreec::frontend::temp_hello());
    println!("(2) {}", zwreec::backend::temp_hello());
    println!("(3) {}", zwreec::file::temp_hello());

    println!("#main finished");
}

fn help() {
    println!("usage:\n    zwreec <input_file> <output_file>");
}
<|endoftext|>


<commit_before>use std::env;
fn main() {
    println!("Hello kitaman");
    let command = env::args().nth(1);
    println!("{:?}", command);
}
<commit_msg>Building !!!<commit_after>use std::env;
use std::path::PathBuf;
use std::process;

struct BuildJob {
    source_directory: PathBuf
}

impl BuildJob {
    fn build(&self) {
        process::Command::new("./configure")
            .arg(String::from("--prefix=") + self.prefix().as_str())
            .status().
            expect("Configure failed");

        process::Command::new("make").status().expect("make failed");
    }

    fn name(&self) -> String {
        let dir_name = self.source_directory.components().last().unwrap();
        match dir_name {
            std::path::Component::Normal(name) => {
                 name.to_os_string().into_string().unwrap()
            },
            _ => {
                println!("Failed");
                "Failed".to_string()
            }

        }
    }

    fn prefix(&self) -> String {
        String::from("/home/kirillvr/.kitaman/pool/") + self.name().as_str()
    }
}

fn main() {
    let command = env::args().nth(1).expect("Please provide at least one argument");

    let job = BuildJob{source_directory: env::current_dir().expect("Failed to get current directory")};
    if command == "build" {
        job.build();
    }
    if command == "prefix" {
        job.prefix();
    }

    if command == "name" {
        let name = job.name();
        println!("{}", name);
    }
}
<|endoftext|>


<commit_before>#![feature(iterator_step_by)]

extern crate easy_hash;

use easy_hash::{Sha256, Hasher, HashResult};
use std::thread;
use std::sync::mpsc;

const BASE: usize = 42;
const THREADS: usize = 4;
static DIFFICULTY: &'static str = "000000";

struct Solution(usize, String);

fn search_for_solution(start_at: usize, sender: mpsc::Sender<Option<Solution>>) {
    for i in (start_at..).step_by(THREADS) {
        let hash: String = Sha256::hash(format!("{}", i * BASE).as_bytes()).hex();

        let result = if hash.ends_with(DIFFICULTY) {
            Some(Solution(i, hash))
        } else {
            None
        };

        match sender.send(result) {
            Ok(_)  => {},
            Err(_) => {
                println!("Receiver has stopped listening, dropping worker number {}", start_at);
                break;
            },
        }
    }
}

fn main() {
    println!("Attempting to find a number, which - while multiplied by {} and hashed using SHA-256 - will result in a hash ending with {}.", BASE, DIFFICULTY);
    println!("Please wait...");

    /*
     * Here, we have 4 threads (as specified by the value of THREADS constant).
     * Thread 1 will start at number 1 and check 5, 9,  13 and so on.
     * Thread 2 will start at number 2 and check 6, 10, 14 and so on.
     * Thread 3 will start at number 3 and check 7, 11, 15 and so on.
     * Thread 4 will start at number 4 and check 8, 12, 16 and so on.
     *
     * This way, we have 4 parallel threads of execution and we're sure
     * that each number will be examined exactly once.
     */
    let (sender, receiver) = mpsc::channel();
    for i in 1..THREADS+1 {
        let sender_n = sender.clone();
        thread::spawn(move || {
            search_for_solution(i, sender_n);
        });
    }

    /*
     * In a loop, receive messages from the producers.
     * As long as there is no solution found (None is received),
     * spin the loop. When the message with a solution arrives
     * (Some(Solution(i, hash))), print out the result and break
     * out from the loop.
     *
     * Note that breaking out from the loop drops the receiver,
     * so that producers will receive an Err(_) on a next attempt to
     * send a message. This way, producers will "know" that the solution
     * was found by one of the worker threads and the receiver does no
     * longer "listen", so they can stop their work too.
     */
    loop {
        match receiver.recv() {
            Ok(None) => continue,
            Ok(Some(Solution(i, hash))) => {
                println!("Found the solution.");
                println!("The number is: {}.", i);
                println!("Result hash: {}.", hash);
                break;
            },
            _ => {},
        }
    }
}
<commit_msg>code review changes<commit_after>#![feature(iterator_step_by)]

extern crate easy_hash;

use easy_hash::{Sha256, Hasher, HashResult};
use std::thread;
use std::sync::mpsc;

const BASE: usize = 42;
const THREADS: usize = 4;
static DIFFICULTY: &'static str = "000000";

struct Solution(usize, String);

fn search_for_solution(start_at: usize, sender: mpsc::Sender<Option<Solution>>) {
    for i in (start_at..).step_by(THREADS) {
        let hash: String = Sha256::hash((i * BASE).to_string().as_bytes()).hex();

        let result = if hash.ends_with(DIFFICULTY) {
            Some(Solution(i, hash))
        } else {
            None
        };

        match sender.send(result) {
            Ok(_)  => {},
            Err(_) => {
                println!("Receiver has stopped listening, dropping worker number {}", start_at);
                break;
            },
        }
    }
}

fn main() {
    println!("Attempting to find a number, which - while multiplied by {} and hashed using SHA-256 - will result in a hash ending with {}.", BASE, DIFFICULTY);
    println!("Please wait...");

    /*
     * Here, we have 4 threads (as specified by the value of THREADS constant).
     * Thread 1 will start at number 1 and check 5, 9,  13 and so on.
     * Thread 2 will start at number 2 and check 6, 10, 14 and so on.
     * Thread 3 will start at number 3 and check 7, 11, 15 and so on.
     * Thread 4 will start at number 4 and check 8, 12, 16 and so on.
     *
     * This way, we have 4 parallel threads of execution and we're sure
     * that each number will be examined exactly once.
     */
    let (sender, receiver) = mpsc::channel();
    for i in 1..THREADS+1 {
        let sender_n = sender.clone();
        thread::spawn(move || {
            search_for_solution(i, sender_n);
        });
    }

    /*
     * In a loop, receive messages from the producers.
     * As long as there is no solution found (None is received),
     * spin the loop. When the message with a solution arrives
     * (Some(Solution(i, hash))), print out the result and break
     * out from the loop.
     *
     * Note that breaking out from the loop drops the receiver,
     * so that producers will receive an Err(_) on a next attempt to
     * send a message. This way, producers will "know" that the solution
     * was found by one of the worker threads and the receiver does no
     * longer "listen", so they can stop their work too.
     */
    loop {
        match receiver.recv() {
            Ok(None) => continue,
            Ok(Some(Solution(i, hash))) => {
                println!("Found the solution.");
                println!("The number is: {}.", i);
                println!("Result hash: {}.", hash);
                break;
            },
            Err(_) => panic!("Worker threads disconnected before the solution was found!"),
        }
    }
}
<|endoftext|>


<commit_before>extern crate git2;
extern crate "rustc-serialize" as rustc_serialize;
extern crate docopt;

use git2::{Repository, Branch, BranchType};
use docopt::Docopt;
use std::old_io as io;

// Write the Docopt usage string.
static USAGE: &'static str = "
Usage: transit [options] <repo> [<branch>]

Options:
    -f, --flag  Flags a flag, note the multiple spaces!
";

#[derive(RustcDecodable, Show)]
struct Args {
    arg_repo: String,
    arg_branch: Option<String>,
    flag_flag: bool,
}

fn main() {
    // Parse the args above or die.
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());

    let path = Path::new(args.arg_repo);
    let repo = Repository::discover(&path)
        .ok().expect("Could not discover a repository.");

    // Which branch?
    let branch = match args.arg_branch {
        Some(branch) => repo.find_branch(&branch[], BranchType::Local),
        None => choose_branch(&repo),
    }.ok().expect("Could not get branch.");

    // Mostly debugging.
    println!("Repo: {:?}, Branch: {:?}", path, branch.name()
       .ok().expect("Couldn't get branch name.")
       .expect("Branch name is not UTF-8."));

    // Get the reference of the branch.
    let reference = branch.into_reference();
    let oid = reference.target()
        .expect("Could not get target.");
    println!("Target Commit: {:?}", oid);
}

fn choose_branch(repo: &Repository) -> Result<Branch, git2::Error> {
    println!("Please choose a branch:");
    let mut branches = repo.branches(Some(BranchType::Local))
        .ok().expect("Could find any branches.");
    for (branch, _) in branches {
        let name = branch.name()
            .ok().expect("Could not get branch name.")
            .expect("Branch name was not valid UTF-8");
        println!("{}", name);
    }
    io::stdout().write_str(&"Choose your branch: "[]);
    let chosen = io::stdin().lock().read_line()
        .ok().expect("Could not read from stdin");
    repo.find_branch(&chosen.trim()[], BranchType::Local)
}
<commit_msg>Show parents of a commit.<commit_after>#![feature(io)]
#![feature(core)]
#![feature(path)]
extern crate git2;
extern crate "rustc-serialize" as rustc_serialize;
extern crate docopt;

use git2::{Repository, Branch, BranchType};
use docopt::Docopt;
use std::old_io as io;

// Write the Docopt usage string.
static USAGE: &'static str = "
Usage: transit [options] <repo> [<branch>]

Options:
    -f, --flag  Flags a flag, note the multiple spaces!
";

#[derive(RustcDecodable, Debug)]
struct Args {
    arg_repo: String,
    arg_branch: Option<String>,
    flag_flag: bool,
}

fn main() {
    // Parse the args above or die.
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());

    let path = Path::new(args.arg_repo);
    let repo = Repository::discover(&path)
        .ok().expect("Could not discover a repository.");

    // Which branch?
    let branch = match args.arg_branch {
        Some(branch) => repo.find_branch(&branch[], BranchType::Local),
        None => choose_branch(&repo),
    }.ok().expect("Could not get branch.");

    // Mostly debugging.
    println!("Repo: {:?}, Branch: {:?}", path, branch.name()
       .ok().expect("Couldn't get branch name.")
       .expect("Branch name is not UTF-8."));

    // Get the reference of the branch.
    let reference = branch.into_reference();
    let oid = reference.target()
        .expect("Could not get target.");
    println!("Target Commit: {:?}", oid);

    let top_commit = repo.find_commit(oid)
        .ok().expect("Could not get commit.");

    // There might be more than one parent of a commit... Hrm...
    for commit in top_commit.parents() {
        println!("Parent: {:?}, {:?}", commit.id(), commit.message()
            .expect("Could not get commit message"));

    }
}

fn choose_branch(repo: &Repository) -> Result<Branch, git2::Error> {
    println!("Please choose a branch:");
    let mut branches = repo.branches(Some(BranchType::Local))
        .ok().expect("Could find any branches.");
    for (branch, _) in branches {
        let name = branch.name()
            .ok().expect("Could not get branch name.")
            .expect("Branch name was not valid UTF-8");
        println!("{}", name);
    }
    io::stdout().write_str(&"Choose your branch: "[]);
    let chosen = io::stdin().lock().read_line()
        .ok().expect("Could not read from stdin");
    repo.find_branch(&chosen.trim()[], BranchType::Local)
}
<|endoftext|>


<commit_before>// TODO:
//  * add option to debug: print all errors
//  * colors

extern crate git2;

use std::collections::HashMap;

use git2::*;

struct Program {
    repo: Repository,
}

fn get_branch_remote(reference: Reference) -> Option<Oid> {
    let b = Branch::wrap(reference);
    let upstream = match b.upstream() {
        Ok(u) => u,
        Err(_) => return None,
    };
    upstream.get().target()
}

impl Program {
    fn get_head(&self) -> Option<Reference> {
        match self.repo.head() {
            Ok(head) => Some(head),
            Err(_) => None,
        }
    }

    fn get_current_branch_oid(&self) -> Option<Oid> {
        let head = self.get_head();
        match head {
            Some(v) => v.target(),
            None => None,
        }
    }

    fn get_current_branch_name(&self) -> String {
        let blank = String::from("");
        let h = match self.get_head() {
            Some(v) => v,
            None => return blank,
        };
        if h.is_branch() {
            match h.shorthand() {
                Some(v) => v.to_string(),
                None => blank,
            }
        } else {
            let hash = match h.target() {
                Some(v) => v.to_string(),
                None => blank,
            };
            let (s, _) = hash.split_at(7);
            s.to_string()
        }
    }

    fn get_current_branch_remote_oid(&self) -> Option<Oid> {
        match self.get_head() {
            Some(r) => get_branch_remote(r),
            None => None
        }
    }

    fn get_current_branch_ahead_behind(&self) -> Option<(usize, usize)> {
        let rm_oid = match self.get_current_branch_remote_oid() {
            Some(r) => r,
            None => return None
        };
        let oid = match self.get_current_branch_oid() {
            Some(r) => r,
            None => return None
        };
        let res = self.repo.graph_ahead_behind(oid, rm_oid);
        match res {
            Ok(r) => Some(r),
            Err(_) => None
        }
    }

    fn get_upstream_branch_ahead_behind(&self) -> Option<(usize, usize)>  {
        let upstream_reference = match self.find_upstream_repo_branch() {
            Ok(u) => u.into_reference(),
            Err(_) => return None,
        };
        let upstream_reference_oid = match upstream_reference.target() {
            Some(u) => u,
            None => return None,
        };
        let oid = match self.get_current_branch_oid() {
            Some(r) => r,
            None => return None
        };
        let res = self.repo.graph_ahead_behind(oid, upstream_reference_oid);
        match res {
            Ok(r) => Some(r),
            Err(_) => None
        }
    }

    fn find_upstream_repo_branch(&self) -> Result<Branch, Error> {
        let us_branch_name = format!("{}{}", "upstream/", self.get_current_branch_name());
        self.repo.find_branch(&us_branch_name, BranchType::Remote)
    }

    fn get_status(&self) -> Option<Statuses> {
        let mut so = StatusOptions::new();
        let mut opts = so.show(StatusShow::IndexAndWorkdir);
        opts.include_untracked(true);
        match self.repo.statuses(Some(&mut opts)) {
            Ok(s) => Some(s),
            Err(_) => None,
        }
    }

    fn get_repository_state(&self) -> String {
        let state = self.repo.state();
        match state {
            RepositoryState::Clean => String::from(""),
            RepositoryState::Merge => String::from("merge"),
            RepositoryState::Revert => String::from("revert"),
            RepositoryState::RevertSequence => String::from("revert"),
            RepositoryState::CherryPick => String::from("cherry-pick"),
            RepositoryState::CherryPickSequence => String::from("cherry-pick"),
            RepositoryState::Bisect => String::from("bisect"),
            RepositoryState::Rebase => String::from("rebase"),
            RepositoryState::RebaseInteractive => String::from("rebase"),
            RepositoryState::RebaseMerge => String::from("rebase"),
            RepositoryState::ApplyMailbox => String::from("apply"),
            RepositoryState::ApplyMailboxOrRebase => String::from("apply"),
        }
    }

    fn get_file_status(&self) -> Option<HashMap<&str, u32>> {
        let mut d = HashMap::new();

        let changed = STATUS_WT_MODIFIED | STATUS_WT_DELETED | STATUS_WT_TYPECHANGE | STATUS_WT_RENAMED;
        let staged = STATUS_INDEX_MODIFIED | STATUS_INDEX_DELETED | STATUS_INDEX_TYPECHANGE | STATUS_INDEX_RENAMED | STATUS_INDEX_NEW;

        let statuses = match self.get_status() {
            Some(x) => x,
            None => return None,
        };

        for s in statuses.iter() {
            let file_status = s.status();
            // println!("{}", s.path().unwrap());

            if file_status.intersects(changed) {
                let counter = d.entry("■").or_insert(0);
                *counter += 1;
            };
            if file_status.contains(STATUS_WT_NEW) {
                let counter = d.entry("✚").or_insert(0);
                *counter += 1;
            };
            if file_status.intersects(staged) {
                let counter = d.entry("●").or_insert(0);
                *counter += 1;
            };
            if file_status.intersects(STATUS_CONFLICTED) {
                let counter = d.entry("✖").or_insert(0);
                *counter += 1;
            };
        }
        Some(d)
    }

    fn run(&self) {
        let mut out = Vec::new();

        let repo_state = self.get_repository_state();
        if repo_state.len() > 0 {
            out.push(repo_state);
        }

        // master↑3↓4
        let mut local = self.get_current_branch_name().clone();
        let (ahead, behind) = match self.get_current_branch_ahead_behind() {
            Some(x) => x,
            None => (0, 0),
        };
        if ahead > 0 { local += &format!("↑{}", ahead); }
        if behind > 0 { local += &format!("↓{}", behind); }
        out.push(local);

        // upstream↑2↓1
        let (ahead, behind) = match self.get_upstream_branch_ahead_behind() {
            Some(x) => x,
            None => (0, 0),
        };
        if ahead > 0 || behind > 0 {
            let mut local = String::from("u");
            if ahead > 0 { local += &format!("↑{}", ahead); }
            if behind > 0 { local += &format!("↓{}", behind); }
            out.push(local);
        }

        match self.get_file_status() {
            Some(s) => {
                let mut o = String::from("");
                for (k, v) in s {
                    if v > 0 {
                        o += &format!("{}{}", k, v);
                    }
                }
                out.push(o);
            },
            None => {}
        };

        println!("{}", out.join("|"));
    }
}

fn main() {
    let repo = match Repository::open(".") {
        Ok(repo) => repo,
        Err(_) => return (),
    };
    let program = Program{ repo: repo };
    program.run();
}
<commit_msg>do not print empty blocks<commit_after>// TODO:
//  * add option to debug: print all errors
//  * colors

extern crate git2;

use std::collections::HashMap;

use git2::*;

struct Program {
    repo: Repository,
}

fn get_branch_remote(reference: Reference) -> Option<Oid> {
    let b = Branch::wrap(reference);
    let upstream = match b.upstream() {
        Ok(u) => u,
        Err(_) => return None,
    };
    upstream.get().target()
}

impl Program {
    fn get_head(&self) -> Option<Reference> {
        match self.repo.head() {
            Ok(head) => Some(head),
            Err(_) => None,
        }
    }

    fn get_current_branch_oid(&self) -> Option<Oid> {
        let head = self.get_head();
        match head {
            Some(v) => v.target(),
            None => None,
        }
    }

    fn get_current_branch_name(&self) -> String {
        let blank = String::from("");
        let h = match self.get_head() {
            Some(v) => v,
            None => return blank,
        };
        if h.is_branch() {
            match h.shorthand() {
                Some(v) => v.to_string(),
                None => blank,
            }
        } else {
            let hash = match h.target() {
                Some(v) => v.to_string(),
                None => blank,
            };
            let (s, _) = hash.split_at(7);
            s.to_string()
        }
    }

    fn get_current_branch_remote_oid(&self) -> Option<Oid> {
        match self.get_head() {
            Some(r) => get_branch_remote(r),
            None => None
        }
    }

    fn get_current_branch_ahead_behind(&self) -> Option<(usize, usize)> {
        let rm_oid = match self.get_current_branch_remote_oid() {
            Some(r) => r,
            None => return None
        };
        let oid = match self.get_current_branch_oid() {
            Some(r) => r,
            None => return None
        };
        let res = self.repo.graph_ahead_behind(oid, rm_oid);
        match res {
            Ok(r) => Some(r),
            Err(_) => None
        }
    }

    fn get_upstream_branch_ahead_behind(&self) -> Option<(usize, usize)>  {
        let upstream_reference = match self.find_upstream_repo_branch() {
            Ok(u) => u.into_reference(),
            Err(_) => return None,
        };
        let upstream_reference_oid = match upstream_reference.target() {
            Some(u) => u,
            None => return None,
        };
        let oid = match self.get_current_branch_oid() {
            Some(r) => r,
            None => return None
        };
        let res = self.repo.graph_ahead_behind(oid, upstream_reference_oid);
        match res {
            Ok(r) => Some(r),
            Err(_) => None
        }
    }

    fn find_upstream_repo_branch(&self) -> Result<Branch, Error> {
        let us_branch_name = format!("{}{}", "upstream/", self.get_current_branch_name());
        self.repo.find_branch(&us_branch_name, BranchType::Remote)
    }

    fn get_status(&self) -> Option<Statuses> {
        let mut so = StatusOptions::new();
        let mut opts = so.show(StatusShow::IndexAndWorkdir);
        opts.include_untracked(true);
        match self.repo.statuses(Some(&mut opts)) {
            Ok(s) => Some(s),
            Err(_) => None,
        }
    }

    fn get_repository_state(&self) -> String {
        let state = self.repo.state();
        match state {
            RepositoryState::Clean => String::from(""),
            RepositoryState::Merge => String::from("merge"),
            RepositoryState::Revert => String::from("revert"),
            RepositoryState::RevertSequence => String::from("revert"),
            RepositoryState::CherryPick => String::from("cherry-pick"),
            RepositoryState::CherryPickSequence => String::from("cherry-pick"),
            RepositoryState::Bisect => String::from("bisect"),
            RepositoryState::Rebase => String::from("rebase"),
            RepositoryState::RebaseInteractive => String::from("rebase"),
            RepositoryState::RebaseMerge => String::from("rebase"),
            RepositoryState::ApplyMailbox => String::from("apply"),
            RepositoryState::ApplyMailboxOrRebase => String::from("apply"),
        }
    }

    fn get_file_status(&self) -> Option<HashMap<&str, u32>> {
        let mut d = HashMap::new();

        let changed = STATUS_WT_MODIFIED | STATUS_WT_DELETED | STATUS_WT_TYPECHANGE | STATUS_WT_RENAMED;
        let staged = STATUS_INDEX_MODIFIED | STATUS_INDEX_DELETED | STATUS_INDEX_TYPECHANGE | STATUS_INDEX_RENAMED | STATUS_INDEX_NEW;

        let statuses = match self.get_status() {
            Some(x) => x,
            None => return None,
        };

        for s in statuses.iter() {
            let file_status = s.status();
            // println!("{}", s.path().unwrap());

            if file_status.intersects(changed) {
                let counter = d.entry("■").or_insert(0);
                *counter += 1;
            };
            if file_status.contains(STATUS_WT_NEW) {
                let counter = d.entry("✚").or_insert(0);
                *counter += 1;
            };
            if file_status.intersects(staged) {
                let counter = d.entry("●").or_insert(0);
                *counter += 1;
            };
            if file_status.intersects(STATUS_CONFLICTED) {
                let counter = d.entry("✖").or_insert(0);
                *counter += 1;
            };
        }
        Some(d)
    }

    fn run(&self) {
        let mut out = Vec::new();

        let repo_state = self.get_repository_state();
        if repo_state.len() > 0 {
            out.push(repo_state);
        }

        // master↑3↓4
        let mut local = self.get_current_branch_name().clone();
        let (ahead, behind) = match self.get_current_branch_ahead_behind() {
            Some(x) => x,
            None => (0, 0),
        };
        if ahead > 0 { local += &format!("↑{}", ahead); }
        if behind > 0 { local += &format!("↓{}", behind); }
        out.push(local);

        // upstream↑2↓1
        let (ahead, behind) = match self.get_upstream_branch_ahead_behind() {
            Some(x) => x,
            None => (0, 0),
        };
        if ahead > 0 || behind > 0 {
            let mut local = String::from("u");
            if ahead > 0 { local += &format!("↑{}", ahead); }
            if behind > 0 { local += &format!("↓{}", behind); }
            out.push(local);
        }

        match self.get_file_status() {
            Some(s) => {
                if s.len() > 0 {
                    let mut o = String::from("");
                    for (k, v) in s {
                        if v > 0 {
                            o += &format!("{}{}", k, v);
                        }
                    }
                    out.push(o);
                }
            },
            None => {}
        };

        // println!("{}", out.len());
        println!("{}", out.join("|"));
    }
}

fn main() {
    let repo = match Repository::open(".") {
        Ok(repo) => repo,
        Err(_) => return (),
    };
    let program = Program{ repo: repo };
    program.run();
}
<|endoftext|>


<commit_before>use std::env;
use std::io::{self, Write};
use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;

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

    for file in &args[1..] {
        readfile(file);
    }
}

fn readfile(file: &String) {
    let fd = File::open(file);
    if fd.is_ok() {
        let fdu = fd.unwrap();
        let metadata = fdu.metadata().unwrap();
        if metadata.is_file() {
            print_file(fdu)
        }
    } else {
        eprintln!("{}: No such file!", file);
    }
}

fn print_file(mut fd: File) {
    const BUFFERSIZE: usize = 1024;
    let mut buffer = [0; BUFFERSIZE];
        loop {
        let rstat = fd.read(&mut buffer);
        if rstat.is_ok() {
            io::stdout().write(&buffer);

            if rstat.unwrap() < BUFFERSIZE {
                break;
            }
        } else {
            break;
    }
    }
}
<commit_msg>Changed to a more rust compliant error handling.<commit_after>use std::env;
use std::io::{self, Write};
use std::fs::File;
use std::io::prelude::*;

//#[cfg(unix)]
//use std::os::unix::fs::MetadataExt;

#[cfg(linux)]
use std::os::linux::fs::MetadataExt;

#[cfg(target_os="macos")]
use std::os::macos::fs::MetadataExt;

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

    for file in &args[1..] {
        read_file(file);
    }
}

fn read_file(file: &String) {
    let mut buffersize: usize = 1024;
    match File::open(file) {
        Ok(mut handle) => {
            if let Ok(meta) = handle.metadata() {
                let blk = meta.st_blksize();
                if blk < std::usize::MAX as u64 {
                    buffersize = blk as usize;
                }
            }

            println!("Using buffersize: {:?}", buffersize);
            let mut buffer = vec![0; buffersize];

            while let Ok(n) = handle.read(&mut buffer) {
                eprintln!("Data read: {}", n);
                if n == 0 {
                    break;
                };
                eprintln!("Read data!");
                if let Err(e) = io::stdout().write_all(&buffer) {
                    eprintln!("{}", e);
                }
            }
        }
        Err(error) => {
            eprintln!("{}", error);
        }
    }
}
<|endoftext|>