<commit_before>use std::io::prelude::*;
use std::io::stdin;
use std::error::Error;
use std::env;

/// Joins two blocks of text, such that row 1 of the first block will be
/// appended to row 1 of the second block and so on.
///
/// Input is read from stdin until EOF, output to stdout. The the first half of
/// the input lines will become the first block.
fn main() {
    run().unwrap();
}

fn run() -> Result<(), Box<Error>> {
    let separator: String = env::args().nth(1).unwrap_or("".to_string());
    let mut buffer = String::new();
    try!(stdin().read_to_string(&mut buffer));
    let lines: Vec<&str> = buffer.lines().collect();
    let lines_per_block = lines.len() / 2;
    let first = &lines[0..lines_per_block];
    let second = &lines[lines_per_block..];
    for (&left, &right) in first.iter().zip(second.iter()) {
        println!("{}{}{}", left, separator, right);
    }
    Ok(())
}
<commit_msg>Make main() public so docs are generated<commit_after>use std::io::prelude::*;
use std::io::stdin;
use std::error::Error;
use std::env;

/// Joins two blocks of text, such that row 1 of the first block will be
/// appended to row 1 of the second block and so on.
///
/// Input is read from stdin until EOF, output to stdout. The the first half of
/// the input lines will become the first block.
pub fn main() {
    run().unwrap();
}

fn run() -> Result<(), Box<Error>> {
    let separator: String = env::args().nth(1).unwrap_or("".to_string());
    let mut buffer = String::new();
    try!(stdin().read_to_string(&mut buffer));
    let lines: Vec<&str> = buffer.lines().collect();
    let lines_per_block = lines.len() / 2;
    let first = &lines[0..lines_per_block];
    let second = &lines[lines_per_block..];
    for (&left, &right) in first.iter().zip(second.iter()) {
        println!("{}{}{}", left, separator, right);
    }
    Ok(())
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate wayland_client;

extern crate tempfile;

extern crate byteorder;
extern crate image;
extern crate dbus;

use std::env;
use std::process::exit;
use image::{load_from_memory, open};
use std::mem::transmute;
use std::os::unix::io::AsRawFd;
use std::io::Write;

use wayland_client::wayland::get_display;
use wayland_client::wayland::compositor::{WlCompositor, WlSurface};
use wayland_client::wayland::shell::WlShell;
use wayland_client::wayland::shm::{WlBuffer, WlShm, WlShmFormat};
use wayland_client::wayland::seat::{WlSeat, WlPointerEvent};
use wayland_client::{EventIterator, Proxy};

use byteorder::{NativeEndian, WriteBytesExt};

use dbus::{Connection, Message, MessageItem, BusType};

wayland_env!(WaylandEnv,
             compositor: WlCompositor,
             shell: WlShell,
             shm: WlShm,
             seat: WlSeat
);

const CURSOR: &'static [u8; 656] = include_bytes!("../assets/arrow.png");

// DBus wait time
const DBUS_WAIT_TIME: i32 = 2000;

type BufferResult = Result<WlBuffer, ()>;

#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
/// Holds the bytes to represent a colored background.
/// To be written into a wayland surface.
pub struct Color(pub [u8; 4]);

impl Color {
    /// Generate a new color out of a u32.
    /// E.G: 0xFFFFFF
    pub fn from_u32(color: u32) -> Self {
        unsafe { Color(transmute(color)) }
    }

    pub fn as_u32(&self) -> u32 {
        unsafe { transmute(self.0)}
    }
}

pub enum BackgroundMode {
    /// Scale image to make the shortest dimension (i.e. height or width)
    /// fit it's container pertaining aspect ratio.
    Fill,

    /// Scale image width to fit container width pertaining aspect ratio.
    Fit,

    /// Scale height and width to fit container's. May create distortion.
    Stretch,

    /// Do not scale image and place to center.
    Center,

    /// Do not scale image and create repeated image forming tile-pattern.
    Tile,
}

impl BackgroundMode {
    fn from_str(s: &str) -> BackgroundMode {
         match s {
            "fill"    => BackgroundMode::Fill,
            "fit"     => BackgroundMode::Fit,
            "stretch" => BackgroundMode::Stretch,
            "center"  => BackgroundMode::Center,
            "tile"    => BackgroundMode::Tile,
            _         => BackgroundMode::Fill,
        }
    }
}

fn main() {
    let args: Vec<_> = env::args().collect();
    if args.len() < 1 {
        println!("Please supply either a file path or a color (written in hex)");
        exit(1);
    }
    let input = &args[1];

    let (display, iter) = get_display()
        .expect("Unable to connect to a wayland compositor");
    let (env, evt_iter) = WaylandEnv::init(display, iter);
    let compositor = env.compositor.as_ref().map(|o| &o.0).unwrap();
    let shell = env.shell.as_ref().map(|o| &o.0).unwrap();
    let mut background_surface = compositor.create_surface();
    let shell_surface = shell.get_shell_surface(&background_surface);
    shell_surface.set_class("Background".into());
    // TODO Actually give it the path or something idk
    shell_surface.set_title(input.clone());

    // We need to hold on to this buffer, this holds the background image!
    let _background_buffer = if let Ok(color) = input.parse::<u32>() {
        let color = Color::from_u32(color);
        generate_solid_background(color, &mut background_surface, &env)
    } else {
        generate_image_background(input.as_str(), &mut background_surface, &env)
    }.expect("could not generate image");

    background_surface.commit();
    background_surface.set_buffer_scale(1);
    let mut cursor_surface = compositor.create_surface();
    let _cursor_buffer = self::cursor_surface(&mut cursor_surface, &env);
    main_background_loop(background_surface, cursor_surface, evt_iter, &env);
}

fn rgba_conversion(num: u8, third_num: u32) -> u8 {
    let big_num = num as u32;
    ((big_num * third_num) / 255) as u8
}

fn get_screen_resolution(con: Connection) -> (i32, i32) {
    let screens_msg = Message::new_method_call("org.way-cooler",
                                               "/org/way_cooler/Screen",
                                               "org.way_cooler.Screen",
                                               "List")
        .expect("Could not construct message -- is Way Cooler running?");
    let screen_r = con.send_with_reply_and_block(screens_msg, DBUS_WAIT_TIME)
        .expect("Could not talk to Way Cooler -- is Way Cooler running?");
    let screen_r = &screen_r.get_items()[0];
    let output_id = match screen_r {
        &MessageItem::Array(ref items, _) => {
            match items[0] {
                MessageItem::Str(ref string) => string.clone(),
                _ => panic!("Array didn't contain output id")
            }
        }
        _ => panic!("Wrong type from Screen")
    };
    let res_msg = Message::new_method_call("org.way-cooler",
                                           "/org/way_cooler/Screen",
                                           "org.way_cooler.Screen",
                                           "Resolution")
        .expect("Could not construct message -- is Way Cooler running?")
        .append(MessageItem::Str(output_id));
    let reply: MessageItem = con.send_with_reply_and_block(res_msg, DBUS_WAIT_TIME)
        .expect("Could not talk to Way Cooler -- is Way Cooler running?")
        .get1()
        .expect("Way Cooler returned an unexpected value");
    match reply {
        MessageItem::Struct(items) => {
            let (width, height) = (
                (&items[0]).inner::<u32>()
                    .expect("Way Cooler returned an unexpected value"),
                (&items[1]).inner::<u32>()
                    .expect("Way Cooler returned an unexpected value")
            );
            println!("{:?}, {:?}", width, height);
            (width as i32, height as i32)
        },
        _ => panic!("Could not get resolution of screen")
    }
}

/// Given a solid color, writes bytes associated with that color to
/// a special Wayland surface which is then rendered as a background for Way Cooler.
fn generate_solid_background(color: Color, background_surface: &mut WlSurface,
                                 env: &WaylandEnv) -> BufferResult {
    // Get shortcuts to the globals.
    let shm = env.shm.as_ref().map(|o| &o.0).unwrap();

    // Create the surface we are going to write into
    let mut tmp = tempfile::tempfile().ok().expect("Unable to create a tempfile.");

    // Calculate how big the buffer needs to be from the output resolution
    let dbus_con = Connection::get_private(BusType::Session).unwrap();
    let (width, height) = get_screen_resolution(dbus_con);
    let size = (width * height) as i32;

    // Write in the color coding to the surface
    for _ in 0..size {
        unsafe {
            tmp.write_u32::<NativeEndian>(transmute(color.0))
                .expect("Could not write to file")
        }
    }
    tmp.flush()
        .expect("Could not flush buffer");

    // Create the buffer that is mem-mapped to the temp file descriptor
    let pool = shm.create_pool(tmp.as_raw_fd(), size);
    let background_buffer = pool.create_buffer(0, width, height, width, WlShmFormat::Argb8888);
    // Tell Way Cooler not to set put this in the tree, treat as background

    // Attach the buffer to the surface
    background_surface.attach(Some(&background_buffer), 0, 0);
    Ok(background_buffer)
}

/// Given the data from an image, writes it to a special Wayland surface
/// which is then rendered as a background for Way Cooler.
fn generate_image_background(path: &str, background_surface: &mut WlSurface,
                             env: &WaylandEnv) -> BufferResult {
    // TODO support more formats, split into separate function
    let image = open(path)
        .unwrap_or_else(|_| {
            println!("Could not open image file \"{:?}\"", path);
            ::std::process::exit(1);
        });
    /*let image = load_from_memory(CURSOR)
        .expect("Could not read cursor data, report to maintainer!");*/
    let mut image = image.to_rgba();
    let width = image.width();
    let height = image.height();
    let stride = width * 4;
    let size = stride * height;
    // TODO Split this into its own function
    {
        let pixels = image.enumerate_pixels_mut();
        for (_x, _y, pixel) in pixels {
            let alpha = pixel[3] as u32;
            pixel[0] = rgba_conversion(pixel[0], alpha);
            pixel[1] = rgba_conversion(pixel[1], alpha);
            pixel[2] = rgba_conversion(pixel[2], alpha);

            let tmp = pixel[2];
            pixel[2] = pixel[0];
            pixel[0] = tmp;
        }
    }
    let vec = image.into_vec();
    let mut tmp = tempfile::NamedTempFile::new().expect("Unable to create a tempfile.");
    tmp.set_len(size as u64).expect("Could not truncate length of file");
    tmp.write_all(&*vec).unwrap();

    let shm = env.shm.as_ref().map(|o| &o.0).unwrap();

    // Create the surface we are going to write into

    let pool = shm.create_pool(tmp.as_raw_fd(), size as i32);
    let background_buffer = pool.create_buffer(0, width as i32, height as i32, stride as i32, WlShmFormat::Argb8888);

    // Attach the buffer to the surface
    background_surface.attach(Some(&background_buffer), 0, 0);
    background_surface.damage(0, 0, width as i32, height as i32);
    Ok(background_buffer)
}

fn cursor_surface(cursor_surface: &mut WlSurface, env: &WaylandEnv) -> BufferResult {
    let shm = env.shm.as_ref().map(|o| &o.0).unwrap();

    let image = load_from_memory(CURSOR)
        .expect("Could not read cursor data, report to maintainer!");
    let mut image = image.to_rgba();
    let width = image.width();
    let height = image.height();
    let stride = width * 4;
    let size = stride * height;
    {
        let pixels = image.enumerate_pixels_mut();
        for (_x, _y, pixel) in pixels {
            let alpha = pixel[3] as u32;
            pixel[0] = rgba_conversion(pixel[0], alpha);
            pixel[1] = rgba_conversion(pixel[1], alpha);
            pixel[2] = rgba_conversion(pixel[2], alpha);

            let tmp = pixel[2];
            pixel[2] = pixel[0];
            pixel[0] = tmp;
        }
    }
    let vec = image.into_vec();
    let mut tmp = tempfile::NamedTempFile::new().expect("Unable to create a tempfile.");
    tmp.set_len(size as u64).expect("Could not truncate length of file");
    tmp.write_all(&*vec).unwrap();
    let pool = shm.create_pool(tmp.as_raw_fd(), size as i32);
    let cursor_buffer = pool.create_buffer(0, width as i32, height as i32, stride as i32, WlShmFormat::Argb8888);
    cursor_surface.attach(Some(&cursor_buffer), 0, 0);
    Ok(cursor_buffer)
}

/// Main loop for rendering backgrounds.
/// Need to keep the surface alive, and update it if the
/// user wants to change the background.
#[allow(unused_variables)]
fn main_background_loop(background_surface: WlSurface, cursor_surface: WlSurface, mut event_iter: EventIterator, env: &WaylandEnv) {
    use wayland_client::wayland::WaylandProtocolEvent;
    use wayland_client::Event;
    let seat = env.seat.as_ref().map(|o| &o.0).unwrap();
    let mut pointer = seat.get_pointer();

    pointer.set_event_iterator(&event_iter);
    pointer.set_cursor(0, Some(&cursor_surface), 0, 0);
    background_surface.commit();
    event_iter.sync_roundtrip().unwrap();
    loop {
        for event in &mut event_iter {
            match event {
                Event::Wayland(wayland_event) => {
                    match wayland_event {
                        WaylandProtocolEvent::WlPointer(id, pointer_event) => {
                            match pointer_event {
                                WlPointerEvent::Enter(serial, background_surface, surface_x, surface_y) => {
                                    pointer.set_cursor(0, Some(&cursor_surface), 0, 0);
                                },
                                _ => {
                                }
                            }
                        },
                        _ => {/* unhandled events */}
                    }
                }
                _ => { /* unhandled events */ }
            }
        }
        event_iter.dispatch().expect("Connection with the compositor was lost.");
    }
}

#[test]
fn test_rgba_conversion() {
    assert_eq!(rgba_conversion(10, 254), 9);
    assert_eq!(rgba_conversion(2, 255), 2);
    assert_eq!(rgba_conversion(255, 500), 500);
}
<commit_msg>Implement background modes: fill, fit, stretch, tile<commit_after>#[macro_use]
extern crate wayland_client;

extern crate tempfile;

extern crate byteorder;
extern crate image;
extern crate dbus;

use std::env;
use std::process::exit;
use image::{load_from_memory, open};
use image::{GenericImage, DynamicImage, FilterType};
use std::mem::transmute;
use std::os::unix::io::AsRawFd;
use std::io::Write;

use wayland_client::wayland::get_display;
use wayland_client::wayland::compositor::{WlCompositor, WlSurface};
use wayland_client::wayland::shell::WlShell;
use wayland_client::wayland::shm::{WlBuffer, WlShm, WlShmFormat};
use wayland_client::wayland::seat::{WlSeat, WlPointerEvent};
use wayland_client::{EventIterator, Proxy};

use byteorder::{NativeEndian, WriteBytesExt};

use dbus::{Connection, Message, MessageItem, BusType};

wayland_env!(WaylandEnv,
             compositor: WlCompositor,
             shell: WlShell,
             shm: WlShm,
             seat: WlSeat
);

const CURSOR: &'static [u8; 656] = include_bytes!("../assets/arrow.png");

// DBus wait time
const DBUS_WAIT_TIME: i32 = 2000;

type BufferResult = Result<WlBuffer, ()>;

#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
/// Holds the bytes to represent a colored background.
/// To be written into a wayland surface.
pub struct Color(pub [u8; 4]);

impl Color {
    /// Generate a new color out of a u32.
    /// E.G: 0xFFFFFF
    pub fn from_u32(color: u32) -> Self {
        unsafe { Color(transmute(color)) }
    }

    pub fn as_u32(&self) -> u32 {
        unsafe { transmute(self.0)}
    }
}

pub enum BackgroundMode {
    /// Scale image to make the shortest dimension (i.e. height or width)
    /// fit it's container pertaining aspect ratio.
    Fill,

    /// Scale image width to fit container width pertaining aspect ratio.
    Fit,

    /// Scale height and width to fit container's. May create distortion.
    Stretch,

    /// Do not scale image and place to center.
    Center,

    /// Do not scale image and create repeated image forming tile-pattern.
    Tile,
}

impl BackgroundMode {
    fn from_str(s: &str) -> BackgroundMode {
         match s {
            "fill"    => BackgroundMode::Fill,
            "fit"     => BackgroundMode::Fit,
            "stretch" => BackgroundMode::Stretch,
            "center"  => BackgroundMode::Center,
            "tile"    => BackgroundMode::Tile,
            _         => BackgroundMode::Fill,
        }
    }
}

fn main() {
    let args: Vec<_> = env::args().collect();
    if args.len() < 1 {
        println!("Please supply either a file path or a color (written in hex)");
        exit(1);
    }
    let input = &args[1];

    let (display, iter) = get_display()
        .expect("Unable to connect to a wayland compositor");
    let (env, evt_iter) = WaylandEnv::init(display, iter);
    let compositor = env.compositor.as_ref().map(|o| &o.0).unwrap();
    let shell = env.shell.as_ref().map(|o| &o.0).unwrap();
    let mut background_surface = compositor.create_surface();
    let shell_surface = shell.get_shell_surface(&background_surface);
    shell_surface.set_class("Background".into());
    // TODO Actually give it the path or something idk
    shell_surface.set_title(input.clone());

    // We need to hold on to this buffer, this holds the background image!
    let _background_buffer = if let Ok(color) = input.parse::<u32>() {
        let color = Color::from_u32(color);
        generate_solid_background(color, &mut background_surface, &env)
    } else {
        let mode = if args.len() >= 3 {
            BackgroundMode::from_str(&args[2])
        } else {
            BackgroundMode::Fill
        };
        generate_image_background(input.as_str(), mode, &mut background_surface, &env)
    }.expect("could not generate image");

    background_surface.commit();
    background_surface.set_buffer_scale(1);
    let mut cursor_surface = compositor.create_surface();
    let _cursor_buffer = self::cursor_surface(&mut cursor_surface, &env);
    main_background_loop(background_surface, cursor_surface, evt_iter, &env);
}

fn rgba_conversion(num: u8, third_num: u32) -> u8 {
    let big_num = num as u32;
    ((big_num * third_num) / 255) as u8
}

fn get_screen_resolution(con: Connection) -> (i32, i32) {
    let screens_msg = Message::new_method_call("org.way-cooler",
                                               "/org/way_cooler/Screen",
                                               "org.way_cooler.Screen",
                                               "List")
        .expect("Could not construct message -- is Way Cooler running?");
    let screen_r = con.send_with_reply_and_block(screens_msg, DBUS_WAIT_TIME)
        .expect("Could not talk to Way Cooler -- is Way Cooler running?");
    let screen_r = &screen_r.get_items()[0];
    let output_id = match screen_r {
        &MessageItem::Array(ref items, _) => {
            match items[0] {
                MessageItem::Str(ref string) => string.clone(),
                _ => panic!("Array didn't contain output id")
            }
        }
        _ => panic!("Wrong type from Screen")
    };
    let res_msg = Message::new_method_call("org.way-cooler",
                                           "/org/way_cooler/Screen",
                                           "org.way_cooler.Screen",
                                           "Resolution")
        .expect("Could not construct message -- is Way Cooler running?")
        .append(MessageItem::Str(output_id));
    let reply: MessageItem = con.send_with_reply_and_block(res_msg, DBUS_WAIT_TIME)
        .expect("Could not talk to Way Cooler -- is Way Cooler running?")
        .get1()
        .expect("Way Cooler returned an unexpected value");
    match reply {
        MessageItem::Struct(items) => {
            let (width, height) = (
                (&items[0]).inner::<u32>()
                    .expect("Way Cooler returned an unexpected value"),
                (&items[1]).inner::<u32>()
                    .expect("Way Cooler returned an unexpected value")
            );
            println!("{:?}, {:?}", width, height);
            (width as i32, height as i32)
        },
        _ => panic!("Could not get resolution of screen")
    }
}

/// Given a solid color, writes bytes associated with that color to
/// a special Wayland surface which is then rendered as a background for Way Cooler.
fn generate_solid_background(color: Color, background_surface: &mut WlSurface,
                                 env: &WaylandEnv) -> BufferResult {
    // Get shortcuts to the globals.
    let shm = env.shm.as_ref().map(|o| &o.0).unwrap();

    // Create the surface we are going to write into
    let mut tmp = tempfile::tempfile().ok().expect("Unable to create a tempfile.");

    // Calculate how big the buffer needs to be from the output resolution
    let dbus_con = Connection::get_private(BusType::Session).unwrap();
    let (width, height) = get_screen_resolution(dbus_con);
    let size = (width * height) as i32;

    // Write in the color coding to the surface
    for _ in 0..size {
        unsafe {
            tmp.write_u32::<NativeEndian>(transmute(color.0))
                .expect("Could not write to file")
        }
    }
    tmp.flush()
        .expect("Could not flush buffer");

    // Create the buffer that is mem-mapped to the temp file descriptor
    let pool = shm.create_pool(tmp.as_raw_fd(), size);
    let background_buffer = pool.create_buffer(0, width, height, width, WlShmFormat::Argb8888);
    // Tell Way Cooler not to set put this in the tree, treat as background

    // Attach the buffer to the surface
    background_surface.attach(Some(&background_buffer), 0, 0);
    Ok(background_buffer)
}

/// Given the data from an image, writes it to a special Wayland surface
/// which is then rendered as a background for Way Cooler.
fn generate_image_background(path: &str, mode: BackgroundMode, background_surface: &mut WlSurface,
                             env: &WaylandEnv) -> BufferResult {
    // TODO support more formats, split into separate function
    let mut image = open(path)
        .unwrap_or_else(|_| {
            println!("Could not open image file \"{:?}\"", path);
            ::std::process::exit(1);
        });
    /*let image = load_from_memory(CURSOR)
        .expect("Could not read cursor data, report to maintainer!");*/
    let mut img_width = image.width();
    let mut img_height = image.height();

    let dbus_con = Connection::get_private(BusType::Session).unwrap();
    let resolution = get_screen_resolution(dbus_con);
    let (scr_width, scr_height) = (resolution.0 as u32, resolution.1 as u32);

    // Mode image processing
    // The output must be scr_width x scr_height resolution
    image = match mode {
        BackgroundMode::Fill    => {
            // Find fit scale
            let width_sr: f64  = scr_width as f64 / img_width as f64;
            let height_sr: f64 = scr_height as f64 / img_height as f64;
            let scale_ratio: f64 = if width_sr > height_sr {
                width_sr
            } else {
                height_sr
            };
            img_width = (scale_ratio * img_width as f64) as u32;
            img_height = (scale_ratio * img_height as f64) as u32;

            image = image.resize(img_width, img_height, FilterType::Gaussian);
            image.crop(((img_width as i32 - scr_width as i32) / 2).abs() as u32,
                ((img_height as i32 - scr_height as i32) / 2).abs() as u32,
                scr_width,
                scr_height)
        },
        // TODO: Padding background color
        BackgroundMode::Fit     => {
            // Find fit scale ratio
            let width_sr: f64  = scr_width as f64 / img_width as f64;
            let height_sr: f64 = scr_height as f64 / img_height as f64;
            let scale_ratio: f64 = if width_sr < height_sr {
                width_sr
            } else {
                height_sr
            };
            img_width = (scale_ratio * img_width as f64) as u32;
            img_height = (scale_ratio * img_height as f64) as u32;

            image = image.resize(img_width, img_height, FilterType::Gaussian);

            let mut imagepad = DynamicImage::new_rgba8(scr_width, scr_height);
            imagepad.copy_from(&image, 0, ((scr_height - img_height) / 2) as u32);

            imagepad
        },
        BackgroundMode::Stretch => {
            image.resize_exact(scr_width, scr_height, FilterType::Gaussian)
        },
        // TODO: Padding background color
        BackgroundMode::Center  => {
            // FIXME: How if image bigger than screen size?
            let mut imagepad = DynamicImage::new_rgba8(scr_width, scr_height);
            imagepad.copy_from(&image, ((scr_width - img_width) / 2) as u32, ((scr_height - img_height) / 2) as u32);

            imagepad
        },
        BackgroundMode::Tile    => {
            // TODO: Create image buffer (lowest multiple of its dimension)
            // .. which bigger than container
            // Iterate pixel on buffer
            // Crop image
            let repeat_x_count: u32 = ((scr_width / img_width) as f64).ceil() as u32 + 1;
            let repeat_y_count: u32 = ((scr_height / img_height) as f64).ceil() as u32 + 1;
            println!("Image w: {}, h: {}", img_width, img_height);
            println!("Repeat x: {}, y: {}", repeat_x_count, repeat_y_count);

            let mut imagepad = DynamicImage::new_rgba8(img_width * repeat_x_count, img_height * repeat_y_count);
            for x in 0..repeat_x_count {
                for y in 0..repeat_y_count {
                    imagepad.copy_from(&image, x * img_width, y * img_height);
                }
            }
            imagepad.crop(0, 0, scr_width, scr_height)
        },
    };

    img_height = scr_height;
    img_width = scr_width;
    let img_stride = img_width * 4;
    let img_size = img_stride * img_height;

    let mut image_rgba = image.to_rgba();

    // TODO Split this into its own function
    {
        let pixels = image_rgba.enumerate_pixels_mut();
        for (_x, _y, pixel) in pixels {
            let alpha = pixel[3] as u32;
            pixel[0] = rgba_conversion(pixel[0], alpha);
            pixel[1] = rgba_conversion(pixel[1], alpha);
            pixel[2] = rgba_conversion(pixel[2], alpha);

            let tmp = pixel[2];
            pixel[2] = pixel[0];
            pixel[0] = tmp;
        }
    }

    let vec = image_rgba.into_vec();
    let mut tmp = tempfile::NamedTempFile::new().expect("Unable to create a tempfile.");
    tmp.set_len(img_size as u64).expect("Could not truncate length of file");
    tmp.write_all(&*vec).unwrap();

    let shm = env.shm.as_ref().map(|o| &o.0).unwrap();

    // Create the surface we are going to write into
    let pool = shm.create_pool(tmp.as_raw_fd(), img_size as i32);
    let background_buffer = pool.create_buffer(0, scr_width as i32, scr_height as i32, img_stride as i32, WlShmFormat::Argb8888);

    // Attach the buffer to the surface
    background_surface.attach(Some(&background_buffer), 0, 0);
    background_surface.damage(0, 0, scr_width as i32, scr_height as i32);
    Ok(background_buffer)
}

fn cursor_surface(cursor_surface: &mut WlSurface, env: &WaylandEnv) -> BufferResult {
    let shm = env.shm.as_ref().map(|o| &o.0).unwrap();

    let image = load_from_memory(CURSOR)
        .expect("Could not read cursor data, report to maintainer!");
    let mut image = image.to_rgba();
    let width = image.width();
    let height = image.height();
    let stride = width * 4;
    let size = stride * height;
    {
        let pixels = image.enumerate_pixels_mut();
        for (_x, _y, pixel) in pixels {
            let alpha = pixel[3] as u32;
            pixel[0] = rgba_conversion(pixel[0], alpha);
            pixel[1] = rgba_conversion(pixel[1], alpha);
            pixel[2] = rgba_conversion(pixel[2], alpha);

            let tmp = pixel[2];
            pixel[2] = pixel[0];
            pixel[0] = tmp;
        }
    }
    let vec = image.into_vec();
    let mut tmp = tempfile::NamedTempFile::new().expect("Unable to create a tempfile.");
    tmp.set_len(size as u64).expect("Could not truncate length of file");
    tmp.write_all(&*vec).unwrap();
    let pool = shm.create_pool(tmp.as_raw_fd(), size as i32);
    let cursor_buffer = pool.create_buffer(0, width as i32, height as i32, stride as i32, WlShmFormat::Argb8888);
    cursor_surface.attach(Some(&cursor_buffer), 0, 0);
    Ok(cursor_buffer)
}

/// Main loop for rendering backgrounds.
/// Need to keep the surface alive, and update it if the
/// user wants to change the background.
#[allow(unused_variables)]
fn main_background_loop(background_surface: WlSurface, cursor_surface: WlSurface, mut event_iter: EventIterator, env: &WaylandEnv) {
    use wayland_client::wayland::WaylandProtocolEvent;
    use wayland_client::Event;
    let seat = env.seat.as_ref().map(|o| &o.0).unwrap();
    let mut pointer = seat.get_pointer();

    pointer.set_event_iterator(&event_iter);
    pointer.set_cursor(0, Some(&cursor_surface), 0, 0);
    background_surface.commit();
    event_iter.sync_roundtrip().unwrap();
    loop {
        for event in &mut event_iter {
            match event {
                Event::Wayland(wayland_event) => {
                    match wayland_event {
                        WaylandProtocolEvent::WlPointer(id, pointer_event) => {
                            match pointer_event {
                                WlPointerEvent::Enter(serial, background_surface, surface_x, surface_y) => {
                                    pointer.set_cursor(0, Some(&cursor_surface), 0, 0);
                                },
                                _ => {
                                }
                            }
                        },
                        _ => {/* unhandled events */}
                    }
                }
                _ => { /* unhandled events */ }
            }
        }
        event_iter.dispatch().expect("Connection with the compositor was lost.");
    }
}

#[test]
fn test_rgba_conversion() {
    assert_eq!(rgba_conversion(10, 254), 9);
    assert_eq!(rgba_conversion(2, 255), 2);
    assert_eq!(rgba_conversion(255, 500), 500);
}
<|endoftext|>


<commit_before>mod game;

use game::*;
use std::time::Instant;

#[allow(unreachable_code)]
fn main()
{
	train();
	test();
	match 4
	{
		0 => test_io(),
		1 => test(),
		2 => train(),
		3 => {
				println!("Training:");
				for i in 0..10
				{
					println!("Training {}:", i);
					train();
				}
				println!("Testing:");
				test();
				test_io();
			},
		_ => {}
	}
}

#[allow(dead_code)]
fn test_io()
{
	let num = 2; //number of games to play
	let gps = 1; //games per side
	let p1 = PlayerType::IO;
	let p2 = PlayerType::AIQFixed;

	println!("Player X: {:?}", p1);
	println!("Player O: {:?}", p2);
	println!("Playing {} games..", num);

	let mut game = Game::new();
	game.set_start_player(1);
	game.set_player1(p1);
	game.set_player2(p2);

	let now = Instant::now();
	game.play_many(num, gps);
	let elapsed = now.elapsed();
	let sec = (elapsed.as_secs() as f64) + (elapsed.subsec_nanos() as f64 / 1000_000_000.0);
	println!("Time: {} min {:.3} s", (sec / 60.0).floor(), sec % 60.0);
	println!("");
}

#[allow(dead_code)]
fn test()
{
	let num = 1_000; //number of games to play
	let gps = 1; //games per side
	let p1 = PlayerType::Minimax;
	let p2 = PlayerType::AIQFixed;

	println!("Player X: {:?}", p1);
	println!("Player O: {:?}", p2);
	println!("Playing {} games..", num);

	let mut game = Game::new();
	game.set_start_player(1);
	game.set_player1(p1);
	game.set_player2(p2);

	let now = Instant::now();
	game.play_many(num, gps);
	let elapsed = now.elapsed();
	let sec = (elapsed.as_secs() as f64) + (elapsed.subsec_nanos() as f64 / 1000_000_000.0);
	println!("Time: {} min {:.3} s", (sec / 60.0).floor(), sec % 60.0);
	println!("");
}

#[allow(dead_code)]
fn train()
{
	let num = 10_000; //number of games to play
	let gps = 10; //games per side
	let p1 = PlayerType::AIQFixed;
	let p2 = PlayerType::AIQ;

	println!("Player X: {:?}", p1);
	println!("Player O: {:?}", p2);
	println!("Playing {} games..", num);

	let mut game = Game::new();
	game.set_start_player(1);
	game.set_player1(p1);
	game.set_player2(p2);

	let now = Instant::now();
	game.play_many(num, gps);
	let elapsed = now.elapsed();
	let sec = (elapsed.as_secs() as f64) + (elapsed.subsec_nanos() as f64 / 1000_000_000.0);
	println!("Time: {} min {:.3} s", (sec / 60.0).floor(), sec % 60.0);
	println!("");
}

<commit_msg>prepare for training<commit_after>mod game;

use game::*;
use std::time::Instant;

#[allow(unreachable_code)]
fn main()
{
	match 3
	{
		0 => test_io(),
		1 => test(),
		2 => train(),
		3 => {
				println!("Training:");
				for i in 0..5
				{
					println!("Training {}:", i);
					train();
					println!("Testing {}:", i);
					test();
				}
				test_io();
			},
		_ => {}
	}
}

#[allow(dead_code)]
fn test_io()
{
	let num = 2; //number of games to play
	let gps = 1; //games per side
	let p1 = PlayerType::IO;
	let p2 = PlayerType::AIQFixed;

	println!("Player X: {:?}", p1);
	println!("Player O: {:?}", p2);
	println!("Playing {} games..", num);

	let mut game = Game::new();
	game.set_start_player(1);
	game.set_player1(p1);
	game.set_player2(p2);

	let now = Instant::now();
	game.play_many(num, gps);
	let elapsed = now.elapsed();
	let sec = (elapsed.as_secs() as f64) + (elapsed.subsec_nanos() as f64 / 1000_000_000.0);
	println!("Time: {} min {:.3} s", (sec / 60.0).floor(), sec % 60.0);
	println!("");
}

#[allow(dead_code)]
fn test()
{
	let num = 1_000; //number of games to play
	let gps = 1; //games per side
	let p1 = PlayerType::Minimax;
	let p2 = PlayerType::AIQFixed;

	println!("Player X: {:?}", p1);
	println!("Player O: {:?}", p2);
	println!("Playing {} games..", num);

	let mut game = Game::new();
	game.set_start_player(1);
	game.set_player1(p1);
	game.set_player2(p2);

	let now = Instant::now();
	game.play_many(num, gps);
	let elapsed = now.elapsed();
	let sec = (elapsed.as_secs() as f64) + (elapsed.subsec_nanos() as f64 / 1000_000_000.0);
	println!("Time: {} min {:.3} s", (sec / 60.0).floor(), sec % 60.0);
	println!("");
}

#[allow(dead_code)]
fn train()
{
	let num = 10_000; //number of games to play
	let gps = 10; //games per side
	let p1 = PlayerType::AIQFixed;
	let p2 = PlayerType::AIQ;

	println!("Player X: {:?}", p1);
	println!("Player O: {:?}", p2);
	println!("Playing {} games..", num);

	let mut game = Game::new();
	game.set_start_player(1);
	game.set_player1(p1);
	game.set_player2(p2);

	let now = Instant::now();
	game.play_many(num, gps);
	let elapsed = now.elapsed();
	let sec = (elapsed.as_secs() as f64) + (elapsed.subsec_nanos() as f64 / 1000_000_000.0);
	println!("Time: {} min {:.3} s", (sec / 60.0).floor(), sec % 60.0);
	println!("");
}

<|endoftext|>


<commit_before>extern crate crypto;
extern crate base64;
extern crate byteorder;
extern crate docopt;
extern crate rustc_serialize;
extern crate rpassword;
extern crate ring;
extern crate untrusted;
#[macro_use]
extern crate error_chain;

use std::process;
use std::mem;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::{OpenOptions, File};
use std::path::Path;

use ring::rand::SystemRandom;
use ring::signature::Ed25519KeyPair;
use ring::digest;
use crypto::bcrypt_pbkdf::bcrypt_pbkdf;

use docopt::Docopt;

mod structs;
mod errors;

use structs::*;
use errors::*;

const USAGE: &'static str = "
signify-rs

Usage:
  signify -h
  signify -G [-n] [-c <comment>] -p <pubkey> -s <seckey>
  signify -S [-x <sigfile>] -s <seckey> -m <message>
  signify -V [-x <sigfile>] -p <pubkey> -m <message>

Options:
  -h --help     Show this screen.
  -c <comment>  Specify the comment to be added during key generation.
  -m <message>  When signing, the file containing the message to sign.  When verifying, the file containing the
                message to verify.  When verifying with -e, the file to create.
  -n            Do not ask for a passphrase during key generation. Otherwise, signify will prompt the user for a
                passphrase to protect the secret key.
  -p <pubkey>   Public key produced by -G, and used by -V to check a signature.
  -s <seckey>   Secret (private) key produced by -G, and used by -S to sign a message.
  -x <sigfile>  The signature file to create or verify.  The default is <message>.sig.
";

#[allow(non_snake_case)]
#[derive(Debug, RustcDecodable)]
struct Args {
    flag_G: bool,
    flag_S: bool,
    flag_V: bool,

    flag_x: Option<String>,
    flag_c: Option<String>,

    flag_p: String,
    flag_s: String,
    flag_m: String,
    flag_n: bool,
}

enum FileContent {
    PublicKey(PublicKey),
    PrivateKey(PrivateKey),
    Signature(Signature),
}

fn write_base64_file<P: AsRef<Path>>(file: P, comment: &str, buf: &[u8]) -> Result<()> {
    let mut f = try!(OpenOptions::new().write(true).create_new(true).open(file));

    try!(write!(f, "{}", COMMENTHDR));
    try!(write!(f, "{}\n", comment));
    let out = base64::encode(buf);
    try!(write!(f, "{}\n", out));

    Ok(())
}

fn read_base64_file<P: AsRef<Path>>(file: P) -> Result<FileContent> {
    let file_display = format!("{}", file.as_ref().display());
    let f = try!(File::open(file));
    let mut reader = BufReader::new(f);

    let mut comment_line = String::new();
    let len = try!(reader.read_line(&mut comment_line));

    if len == 0 || len < COMMENTHDRLEN || !comment_line.starts_with(COMMENTHDR) {
        return Err(format!("invalid comment in {}; must start with '{}'", file_display, COMMENTHDR).into());
    }

    if &comment_line[len-1..len] != "\n" {
        return Err(format!("missing new line after comment in {}", file_display).into());
    }

    if len > COMMENTHDRLEN + COMMENTMAXLEN {
        return Err("comment too long".into());
    }

    let mut base64_line = String::new();
    let len = try!(reader.read_line(&mut base64_line));

    if len == 0 {
        return Err(format!("missing line in {}", file_display).into());
    }

    if &base64_line[len-1..len] != "\n" {
        return Err(format!("missing new line after comment in {}", file_display).into());
    }

    let base64_line = &base64_line[0..len-1];

    let data = try!(base64::decode(base64_line)
                    .chain_err(|| format!("invalid base64 encoding in {}", file_display)));

    if &data[0..2] != PKGALG {
        return Err(format!("unsupported file {}", file_display).into());
    }

    match data.len() {
        x if x == mem::size_of::<PublicKey>() => {
            PublicKey::from_buf(&data)
                .map(FileContent::PublicKey)
        }
        x if x == mem::size_of::<PrivateKey>() => {
            PrivateKey::from_buf(&data)
                .map(FileContent::PrivateKey)
        }
        x if x == mem::size_of::<Signature>() => {
            Signature::from_buf(&data)
                .map(FileContent::Signature)
        },
        _ => {
            Err(format!("unsupported file {}", file_display).into())
        }
    }
}

fn verify(pubkey_path: String, msg_path: String, signature_path: Option<String>) -> Result<()> {
    let pkey = match read_base64_file(&pubkey_path) {
        Ok(FileContent::PublicKey(pkey)) => pkey,
        _ => return Err("an error occured.".into()),
    };

    let signature_path = match signature_path {
        Some(path) => path,
        None => format!("{}.sig", msg_path)
    };

    let signature = match read_base64_file(&signature_path) {
        Ok(FileContent::Signature(sig)) => sig,
        _ => return Err(format!("Can't read signature from {}", signature_path).into()),
    };

    let mut msgfile = try!(File::open(&msg_path).chain_err(|| read_error(&msg_path)));
    let mut msg = vec![];
    try!(msgfile.read_to_end(&mut msg).chain_err(|| read_error(&msg_path)));

    if signature.keynum != pkey.keynum {
        return Err("signature verification failed: checked against wrong key".into());
    }

    if signature.verify(&msg, &pkey) {
        println!("Signature Verified");
        Ok(())
    } else {
        Err("signature verification failed".into())
    }
}

fn sign(seckey_path: String, msg_path: String, signature_path: Option<String>) -> Result<()> {
    let mut skey = match read_base64_file(&seckey_path) {
        Ok(FileContent::PrivateKey(skey)) => skey,
        _ => return Err("an error occured.".into()),
    };

    let rounds = skey.kdfrounds;
    let xorkey = try!(kdf(&skey.salt, rounds, false, SECRETBYTES));

    for (prv, xor) in skey.seckey.iter_mut().zip(xorkey.iter()) {
        *prv = *prv ^ xor;
    }
    let skey = skey;

    let mut msgfile = try!(File::open(&msg_path)
                           .chain_err(|| read_error(&msg_path)).into());
    let mut msg = vec![];
    try!(msgfile.read_to_end(&mut msg).chain_err(|| read_error(&msg_path)));

    let signature_path = match signature_path {
        Some(path) => path,
        None => format!("{}.sig", msg_path)
    };

    let sig = try!(skey.sign(&msg).chain_err(|| "Failed to sign message"));

    let mut out = vec![];
    try!(sig.write(&mut out).chain_err(|| "Can't write to internal buffer"));

    let sig_comment = "signature from signify secret key";

    write_base64_file(&signature_path, sig_comment, &out)
        .chain_err(|| "Failed to write signature file")
}

fn read_password(prompt: &str) -> Result<String> {
    let mut stdout = std::io::stdout();
    try!(stdout.write_all(prompt.as_bytes()).chain_err(|| "Write to stdout failed"));
    try!(stdout.flush().chain_err(|| "Flushing stdout failed"));

    rpassword::read_password()
        .chain_err(|| "unable to read passphrase")
}

fn kdf(salt: &[u8], rounds: u32, confirm: bool, keylen: usize) -> Result<Vec<u8>> {
    let mut result = vec![0; keylen];
    if rounds == 0 {
        return Ok(result);
    }

    let passphrase = try!(read_password("passphrase: "));

    if confirm {
        let confirm_passphrase = try!(read_password("confirm passphrase: "));

        if passphrase != confirm_passphrase {
            return Err("passwords don't match".into());
        }
    }

    bcrypt_pbkdf(passphrase.as_bytes(), salt, rounds, &mut result);
    Ok(result)
}

fn generate(pubkey_path: String, privkey_path: String, comment: Option<String>, kdfrounds: u32) -> Result<()> {
    let comment = match comment {
        Some(s) => s,
        None    => "signify".into()
    };

    let mut keynum = [0; KEYNUMLEN];
    try!(SystemRandom.fill(&mut keynum).chain_err(|| "Can't fill keynum randomly"));

    let (_, keypair_bytes) = try!(Ed25519KeyPair::generate_serializable(&SystemRandom));
    let mut skey = keypair_bytes.private_key;
    let pkey = keypair_bytes.public_key;

    let mut salt = [0; 16];
    try!(SystemRandom.fill(&mut salt).chain_err(|| "Can't fill salt randomly"));

    let xorkey = try!(kdf(&salt, kdfrounds, true, SECRETBYTES));

    for (prv, xor) in skey.iter_mut().zip(xorkey.iter()) {
        *prv = *prv ^ xor;
    }

    // signify stores the extended key as the private key,
    // that is the 32 byte of the secret key, followed by the 32 byte of the public key,
    // summing up to 64 byte.
    //
    //  *ring* separates them, so we need to stick them together again.
    let mut complete_key = [0; 64];
    complete_key[0..32].copy_from_slice(&skey[0..32]);
    complete_key[32..].copy_from_slice(&pkey);

    // Store private key
    let digest = digest::digest(&digest::SHA512, &complete_key);
    let mut checksum = [0; 8];
    checksum.copy_from_slice(&digest.as_ref()[0..8]);

    let private_key = PrivateKey {
        pkgalg: PKGALG,
        kdfalg: KDFALG,
        kdfrounds: kdfrounds,
        salt: salt,
        checksum: checksum,
        keynum: keynum,
        seckey: complete_key,
    };

    let mut out = vec![];
    try!(private_key.write(&mut out).chain_err(|| "Can't write to internal buffer"));

    let priv_comment = format!("{} secret key", comment);
    try!(write_base64_file(&privkey_path, &priv_comment, &out)
        .chain_err(|| write_error(&privkey_path))
    );

    // Store public key
    let public_key = PublicKey::with_key_and_keynum(pkey, keynum);

    let mut out = vec![];
    try!(public_key.write(&mut out).chain_err(|| "Can't write to internal buffer"));

    let pub_comment = format!("{} public key", comment);
    write_base64_file(&pubkey_path, &pub_comment, &out)
        .chain_err(|| write_error(&pubkey_path))
}

fn human(res: Result<()>) {
    match res {
        Err(e) => {
            let mut it = e.iter();
            let e = it.next().unwrap(); // We have an error, so we can definitely unwrap it.
            let next_err = it.next();
            if let Some(next_err) = next_err {
                println!("{}: {}", e, next_err);
            } else {
                println!("{}", e);
            }

            process::exit(1);
        },
        Ok(()) => {}
    }
}

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

    if args.flag_V {
        human(verify(args.flag_p, args.flag_m, args.flag_x));
    } else if args.flag_G {
        let rounds = if args.flag_n { 0 } else { 42 };
        human(generate(args.flag_p, args.flag_s, args.flag_c, rounds));
    } else if args.flag_S {
        human(sign(args.flag_s, args.flag_m, args.flag_x));
    }
}
<commit_msg>Make input file parsing more robust.<commit_after>extern crate crypto;
extern crate base64;
extern crate byteorder;
extern crate docopt;
extern crate rustc_serialize;
extern crate rpassword;
extern crate ring;
extern crate untrusted;
#[macro_use]
extern crate error_chain;

use std::process;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::{OpenOptions, File};
use std::path::Path;

use ring::rand::SystemRandom;
use ring::signature::Ed25519KeyPair;
use ring::digest;
use crypto::bcrypt_pbkdf::bcrypt_pbkdf;

use docopt::Docopt;

mod structs;
mod errors;

use structs::*;
use errors::*;

const USAGE: &'static str = "
signify-rs

Usage:
  signify -h
  signify -G [-n] [-c <comment>] -p <pubkey> -s <seckey>
  signify -S [-x <sigfile>] -s <seckey> -m <message>
  signify -V [-x <sigfile>] -p <pubkey> -m <message>

Options:
  -h --help     Show this screen.
  -c <comment>  Specify the comment to be added during key generation.
  -m <message>  When signing, the file containing the message to sign.  When verifying, the file containing the
                message to verify.  When verifying with -e, the file to create.
  -n            Do not ask for a passphrase during key generation. Otherwise, signify will prompt the user for a
                passphrase to protect the secret key.
  -p <pubkey>   Public key produced by -G, and used by -V to check a signature.
  -s <seckey>   Secret (private) key produced by -G, and used by -S to sign a message.
  -x <sigfile>  The signature file to create or verify.  The default is <message>.sig.
";

#[allow(non_snake_case)]
#[derive(Debug, RustcDecodable)]
struct Args {
    flag_G: bool,
    flag_S: bool,
    flag_V: bool,

    flag_x: Option<String>,
    flag_c: Option<String>,

    flag_p: String,
    flag_s: String,
    flag_m: String,
    flag_n: bool,
}

fn write_base64_file<P: AsRef<Path>>(file: P, comment: &str, buf: &[u8]) -> Result<()> {
    let mut f = try!(OpenOptions::new().write(true).create_new(true).open(file));

    try!(write!(f, "{}", COMMENTHDR));
    try!(write!(f, "{}\n", comment));
    let out = base64::encode(buf);
    try!(write!(f, "{}\n", out));

    Ok(())
}

fn read_base64_file<P: AsRef<Path>>(file: P) -> Result<Vec<u8>> {
    let file_display = format!("{}", file.as_ref().display());
    let f = try!(File::open(file));
    let mut reader = BufReader::new(f);

    let mut comment_line = String::new();
    let len = try!(reader.read_line(&mut comment_line));

    if len == 0 || len < COMMENTHDRLEN || !comment_line.starts_with(COMMENTHDR) {
        return Err(format!("invalid comment in {}; must start with '{}'", file_display, COMMENTHDR).into());
    }

    if &comment_line[len-1..len] != "\n" {
        return Err(format!("missing new line after comment in {}", file_display).into());
    }

    if len > COMMENTHDRLEN + COMMENTMAXLEN {
        return Err("comment too long".into());
    }

    let mut base64_line = String::new();
    let len = try!(reader.read_line(&mut base64_line));

    if len == 0 {
        return Err(format!("missing line in {}", file_display).into());
    }

    if &base64_line[len-1..len] != "\n" {
        return Err(format!("missing new line after comment in {}", file_display).into());
    }

    let base64_line = &base64_line[0..len-1];

    let data = try!(base64::decode(base64_line)
                    .chain_err(|| format!("invalid base64 encoding in {}", file_display)));

    if &data[0..2] != PKGALG {
        return Err(format!("unsupported file {}", file_display).into());
    }

    Ok(data)
}

fn verify(pubkey_path: String, msg_path: String, signature_path: Option<String>) -> Result<()> {
    // TODO: Better error message?
    let serialized_pkey = try!(read_base64_file(&pubkey_path));
    let pkey = try!(PublicKey::from_buf(&serialized_pkey));

    let signature_path = match signature_path {
        Some(path) => path,
        None => format!("{}.sig", msg_path)
    };

    // TODO: Better error message?
    let serialized_signature = try!(read_base64_file(&signature_path));
    let signature = try!(Signature::from_buf(&serialized_signature));

    let mut msgfile = try!(File::open(&msg_path).chain_err(|| read_error(&msg_path)));
    let mut msg = vec![];
    try!(msgfile.read_to_end(&mut msg).chain_err(|| read_error(&msg_path)));

    if signature.keynum != pkey.keynum {
        return Err("signature verification failed: checked against wrong key".into());
    }

    if signature.verify(&msg, &pkey) {
        println!("Signature Verified");
        Ok(())
    } else {
        Err("signature verification failed".into())
    }
}

fn sign(seckey_path: String, msg_path: String, signature_path: Option<String>) -> Result<()> {
    let serialized_skey = try!(read_base64_file(&seckey_path));
    let mut skey = try!(PrivateKey::from_buf(&serialized_skey));

    let rounds = skey.kdfrounds;
    let xorkey = try!(kdf(&skey.salt, rounds, false, SECRETBYTES));

    for (prv, xor) in skey.seckey.iter_mut().zip(xorkey.iter()) {
        *prv = *prv ^ xor;
    }
    let skey = skey;

    let mut msgfile = try!(File::open(&msg_path)
                           .chain_err(|| read_error(&msg_path)).into());
    let mut msg = vec![];
    try!(msgfile.read_to_end(&mut msg).chain_err(|| read_error(&msg_path)));

    let signature_path = match signature_path {
        Some(path) => path,
        None => format!("{}.sig", msg_path)
    };

    let sig = try!(skey.sign(&msg).chain_err(|| "Failed to sign message"));

    let mut out = vec![];
    try!(sig.write(&mut out).chain_err(|| "Can't write to internal buffer"));

    let sig_comment = "signature from signify secret key";

    write_base64_file(&signature_path, sig_comment, &out)
        .chain_err(|| "Failed to write signature file")
}

fn read_password(prompt: &str) -> Result<String> {
    let mut stdout = std::io::stdout();
    try!(stdout.write_all(prompt.as_bytes()).chain_err(|| "Write to stdout failed"));
    try!(stdout.flush().chain_err(|| "Flushing stdout failed"));

    rpassword::read_password()
        .chain_err(|| "unable to read passphrase")
}

fn kdf(salt: &[u8], rounds: u32, confirm: bool, keylen: usize) -> Result<Vec<u8>> {
    let mut result = vec![0; keylen];
    if rounds == 0 {
        return Ok(result);
    }

    let passphrase = try!(read_password("passphrase: "));

    if confirm {
        let confirm_passphrase = try!(read_password("confirm passphrase: "));

        if passphrase != confirm_passphrase {
            return Err("passwords don't match".into());
        }
    }

    bcrypt_pbkdf(passphrase.as_bytes(), salt, rounds, &mut result);
    Ok(result)
}

fn generate(pubkey_path: String, privkey_path: String, comment: Option<String>, kdfrounds: u32) -> Result<()> {
    let comment = match comment {
        Some(s) => s,
        None    => "signify".into()
    };

    let mut keynum = [0; KEYNUMLEN];
    try!(SystemRandom.fill(&mut keynum).chain_err(|| "Can't fill keynum randomly"));

    let (_, keypair_bytes) = try!(Ed25519KeyPair::generate_serializable(&SystemRandom));
    let mut skey = keypair_bytes.private_key;
    let pkey = keypair_bytes.public_key;

    let mut salt = [0; 16];
    try!(SystemRandom.fill(&mut salt).chain_err(|| "Can't fill salt randomly"));

    let xorkey = try!(kdf(&salt, kdfrounds, true, SECRETBYTES));

    for (prv, xor) in skey.iter_mut().zip(xorkey.iter()) {
        *prv = *prv ^ xor;
    }

    // signify stores the extended key as the private key,
    // that is the 32 byte of the secret key, followed by the 32 byte of the public key,
    // summing up to 64 byte.
    //
    //  *ring* separates them, so we need to stick them together again.
    let mut complete_key = [0; 64];
    complete_key[0..32].copy_from_slice(&skey[0..32]);
    complete_key[32..].copy_from_slice(&pkey);

    // Store private key
    let digest = digest::digest(&digest::SHA512, &complete_key);
    let mut checksum = [0; 8];
    checksum.copy_from_slice(&digest.as_ref()[0..8]);

    let private_key = PrivateKey {
        pkgalg: PKGALG,
        kdfalg: KDFALG,
        kdfrounds: kdfrounds,
        salt: salt,
        checksum: checksum,
        keynum: keynum,
        seckey: complete_key,
    };

    let mut out = vec![];
    try!(private_key.write(&mut out).chain_err(|| "Can't write to internal buffer"));

    let priv_comment = format!("{} secret key", comment);
    try!(write_base64_file(&privkey_path, &priv_comment, &out)
        .chain_err(|| write_error(&privkey_path))
    );

    // Store public key
    let public_key = PublicKey::with_key_and_keynum(pkey, keynum);

    let mut out = vec![];
    try!(public_key.write(&mut out).chain_err(|| "Can't write to internal buffer"));

    let pub_comment = format!("{} public key", comment);
    write_base64_file(&pubkey_path, &pub_comment, &out)
        .chain_err(|| write_error(&pubkey_path))
}

fn human(res: Result<()>) {
    match res {
        Err(e) => {
            let mut it = e.iter();
            let e = it.next().unwrap(); // We have an error, so we can definitely unwrap it.
            let next_err = it.next();
            if let Some(next_err) = next_err {
                println!("{}: {}", e, next_err);
            } else {
                println!("{}", e);
            }

            process::exit(1);
        },
        Ok(()) => {}
    }
}

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

    if args.flag_V {
        human(verify(args.flag_p, args.flag_m, args.flag_x));
    } else if args.flag_G {
        let rounds = if args.flag_n { 0 } else { 42 };
        human(generate(args.flag_p, args.flag_s, args.flag_c, rounds));
    } else if args.flag_S {
        human(sign(args.flag_s, args.flag_m, args.flag_x));
    }
}
<|endoftext|>


<commit_before>#[derive(Clone, Copy, Debug)]
enum Const {
  Data,
  Codata,
}

impl ToString for Const {
  fn to_string(&self) -> String {
    use Const::*;
    match *self {
      Data => "data".to_string(),
      Codata => "codata".to_string(),
    }
  }
}

#[derive(Clone, Debug)]
struct Var {
  name: String,
  idx: i32,
}

impl Var {
  pub fn new(name: &str, idx: i32) -> Var {
    Var {
      name: name.to_string(),
      idx: idx,
    }
  }
}

impl ToString for Var {
  fn to_string(&self) -> String {
    self.name.clone()
    // + "@" + &self.idx.to_string()
  }
}

#[derive(Clone, Debug)]
enum Expr {
  // Type system constants
  Const(Const),
  // Bound variables
  Var(Var),
  // Lambda
  Lam(Var, Box<Expr>, Box<Expr>),
  // "forall"
  Pi(Var, Box<Expr>, Box<Expr>),
  // Function application
  App(Box<Expr>, Box<Expr>),
}

impl Expr {
  pub fn constant(constant: Const) -> Expr {
    Expr::Const(constant)
  }
  pub fn var(v: &Var) -> Expr {
    Expr::Var(v.clone())
  }
  pub fn lam(var: Var, ty: Expr, body: Expr) -> Expr {
    Expr::Lam(var, Box::new(ty), Box::new(body))
  }
  pub fn pi(var: Var, ty: Expr, body: Expr) -> Expr {
    Expr::Pi(var, Box::new(ty), Box::new(body))
  }
  pub fn app(f: Expr, arg: Expr) -> Expr {
    Expr::App(Box::new(f), Box::new(arg))
  }

  pub fn is_constant(&self) -> bool {
    use Expr::*;
    match *self {
      Const(_) => true,
      _ => false,
    }
  }
  pub fn is_var(&self) -> bool {
    use Expr::*;
    match *self {
      Var(_) => true,
      _ => false,
    }
  }
  pub fn is_lam(&self) -> bool {
    use Expr::*;
    match *self {
      Lam(_, _, _) => true,
      _ => false,
    }
  }
  pub fn is_pi(&self) -> bool {
    use Expr::*;
    match *self {
      Pi(_, _, _) => true,
      _ => false,
    }
  }
  pub fn is_app(&self) -> bool {
    use Expr::*;
    match *self {
      App(_, _) => true,
      _ => false,
    }
  }
}

impl ToString for Expr {
  fn to_string(&self) -> String {
    use Expr::*;
    match *self {
      Const(ref constant) => constant.to_string(),
      Var(ref var) => var.to_string(),
      Lam(ref var, ref ty, ref body) => {
        var.to_string() + ":" + &ty.to_string() + " -> " + &body.to_string()
      }
      Pi(ref var, ref ty, ref body) => {
        "forall (".to_string() + &var.to_string() + ":" + &ty.to_string() +
        ") -> " + &body.to_string()
      }
      App(ref f, ref arg) => {
        if f.is_lam() || f.is_pi() {
          "(".to_string() + &f.to_string() + ") " + &arg.to_string()
        } else {
          f.to_string() + " " + &arg.to_string()
        }
      }
    }
  }
}

fn main() {
  println!("{}", Const::Data.to_string());
  let a = Var::new("a", 0);
  let x = Var::new("x", 0);
  let expra = Expr::var(&a);
  let exprx = Expr::var(&x);
  println!("{}", x.to_string());
  let id = Expr::pi(a.clone(),
                    Expr::constant(Const::Data),
                    Expr::lam(x, expra, exprx));
  println!("{}", id.to_string());
  let apply_id = Expr::app(Expr::app(id, Expr::var(&Var::new("int", 0))),
                           Expr::var(&Var::new("1", 0)));
  println!("{}", apply_id.to_string());
}
<commit_msg>Add shorter functions for creating Var and Expr.<commit_after>#[derive(Clone, Copy, Debug)]
enum Const {
  Data,
  Codata,
}

impl ToString for Const {
  fn to_string(&self) -> String {
    use Const::*;
    match *self {
      Data => "data".to_string(),
      Codata => "codata".to_string(),
    }
  }
}

#[derive(Clone, Debug)]
struct Var {
  name: String,
  idx: i32,
}

impl Var {
  pub fn new(name: &str, idx: i32) -> Var {
    Var {
      name: name.to_string(),
      idx: idx,
    }
  }
}

fn v(name: &str, idx: i32) -> Var {
  Var::new(name, idx)
}

fn v0(name: &str) -> Var {
  v(name, 0)
}

impl ToString for Var {
  fn to_string(&self) -> String {
    self.name.clone()
    // + "@" + &self.idx.to_string()
  }
}

#[derive(Clone, Debug)]
enum Expr {
  // Type system constants
  Const(Const),
  // Bound variables
  Var(Var),
  // Lambda
  Lam(Var, Box<Expr>, Box<Expr>),
  // "forall"
  Pi(Var, Box<Expr>, Box<Expr>),
  // Function application
  App(Box<Expr>, Box<Expr>),
}

impl Expr {
  pub fn constant(constant: Const) -> Expr {
    Expr::Const(constant)
  }
  pub fn var(v: &Var) -> Expr {
    Expr::Var(v.clone())
  }
  pub fn lam(var: Var, ty: Expr, body: Expr) -> Expr {
    Expr::Lam(var, Box::new(ty), Box::new(body))
  }
  pub fn pi(var: Var, ty: Expr, body: Expr) -> Expr {
    Expr::Pi(var, Box::new(ty), Box::new(body))
  }
  pub fn app(f: Expr, arg: Expr) -> Expr {
    Expr::App(Box::new(f), Box::new(arg))
  }

  pub fn is_constant(&self) -> bool {
    use Expr::*;
    match *self {
      Const(_) => true,
      _ => false,
    }
  }
  pub fn is_var(&self) -> bool {
    use Expr::*;
    match *self {
      Var(_) => true,
      _ => false,
    }
  }
  pub fn is_lam(&self) -> bool {
    use Expr::*;
    match *self {
      Lam(_, _, _) => true,
      _ => false,
    }
  }
  pub fn is_pi(&self) -> bool {
    use Expr::*;
    match *self {
      Pi(_, _, _) => true,
      _ => false,
    }
  }
  pub fn is_app(&self) -> bool {
    use Expr::*;
    match *self {
      App(_, _) => true,
      _ => false,
    }
  }
}

fn constant(c: Const) -> Expr {
  Expr::constant(c)
}
fn var(v: &Var) -> Expr {
  Expr::var(v)
}
fn lam(var: Var, ty: Expr, body: Expr) -> Expr {
  Expr::lam(var, ty, body)
}
fn pi(var: Var, ty: Expr, body: Expr) -> Expr {
  Expr::pi(var, ty, body)
}
fn app(f: Expr, arg: Expr) -> Expr {
  Expr::app(f, arg)
}

impl ToString for Expr {
  fn to_string(&self) -> String {
    use Expr::*;
    match *self {
      Const(ref constant) => constant.to_string(),
      Var(ref var) => var.to_string(),
      Lam(ref var, ref ty, ref body) => {
        var.to_string() + ":" + &ty.to_string() + " -> " + &body.to_string()
      }
      Pi(ref var, ref ty, ref body) => {
        "forall (".to_string() + &var.to_string() + ":" + &ty.to_string() +
        ") -> " + &body.to_string()
      }
      App(ref f, ref arg) => {
        if f.is_lam() || f.is_pi() {
          "(".to_string() + &f.to_string() + ") " + &arg.to_string()
        } else {
          f.to_string() + " " + &arg.to_string()
        }
      }
    }
  }
}

fn main() {
  println!("{}", Const::Data.to_string());
  let a = v("a", 0);
  let x = v("x", 0);
  let expra = var(&a);
  let exprx = var(&x);
  println!("{}", x.to_string());
  let id = pi(a.clone(), constant(Const::Data), lam(x, expra, exprx));
  println!("{}", id.to_string());
  let apply_id = app(app(id, var(&v("int", 0))), var(&v("1", 0)));
  println!("{}", apply_id.to_string());
}
<|endoftext|>


<commit_before>extern crate toml;

use std::{env, process};
use std::io::prelude::*;
use std::io::{BufReader, ErrorKind};
use std::collections::BTreeMap;
use std::fs::File;

static OVERRIDES_PATH : &'static str = ".multirust/overrides";
static SETTINGS_PATH : &'static str = ".multirust/settings.toml";

enum OverridesDatabase {
    Plain(BTreeMap<String, String>),
    Toml(BTreeMap<String, toml::Value>),
}

impl OverridesDatabase {
    pub fn get(&self, key: &str) -> Option<&str> {
        use OverridesDatabase::*;

        match *self {
            Plain(ref db) => db.get(key).map(|s| &s[..]),
            Toml(ref db) => {
                db.get(key).map(|v| v.as_str().expect("Expected value is not a string."))
            }
        }
    }
}

fn with_date<'a>(short: &'a str, toolchain: &'a str) -> Option<&'a str> {
    let date_start = short.len() + 1;
    let date_end   = short.len() + 3 + 4 + 2 + 2;
    let char_range = toolchain.chars()
        .skip(date_start)
        .take(4)
        .all(char::is_numeric);

    if toolchain.len() > date_start && char_range {
        Some(&toolchain[0..date_end])
    } else {
        None
    }
}

fn clean_toolchain_name(toolchain: &str) -> &str {
    static SHORTNAMES : &'static [&'static str] = &["stable", "nightly", "beta"];

    for short in SHORTNAMES {
        if toolchain.starts_with(short) {
            return match with_date(short, toolchain) {
                Some(s) => s,
                None => short
            }
        }
    }

    toolchain
}

fn plain_overrides_file(f: File) {
    let overrides = BufReader::new(f);

    let mut overrides_map = BTreeMap::new();

    for line in overrides.lines() {
        let line = line.expect("No valid line found");
        let mut s = line.split(';');
        let path = s.next().expect("No path in line");
        let toolchain = s.next().expect("No toolchain in line");

        overrides_map.insert(path.into(), toolchain.into());
    }

    let database = OverridesDatabase::Plain(overrides_map);
    toolchain(database);
}

fn settings_toml(mut settings: File) {
    let mut content = String::new();
    settings.read_to_string(&mut content).expect("Can't read settings file");

    let toml = match toml::Parser::new(&content).parse() {
        Some(table) => table,
        None => {
            println!("default");
            process::exit(0);
        }
    };

    let overrides = match toml.get("overrides") {
        Some(overrides) => overrides,
        None => {
            println!("default");
            process::exit(0);
        }
    };

    let overrides = match overrides.as_table() {
        Some(overrides) => overrides,
        None => {
            println!("default");
            process::exit(0);
        }
    };

    let database = OverridesDatabase::Toml(overrides.clone());
    toolchain(database);
}

fn toolchain(database: OverridesDatabase) {
    let mut cwd = env::current_dir().expect("No valid working directory");

    loop {
        let path = format!("{}", cwd.display());

        if let Some(toolchain) =  database.get(&path) {
            println!("{}", clean_toolchain_name(toolchain));
            return;
        }

        if !cwd.pop() {
            break;
        }
    }
    println!("default");
}

fn main() {
    let home = env::home_dir().expect("Impossible to get your home dir!");

    let mut overrides_path = home.clone();
    overrides_path.push(OVERRIDES_PATH);

    let mut settings_path = home.clone();
    settings_path.push(SETTINGS_PATH);

    match File::open(&overrides_path) {
        Ok(f) => {
            plain_overrides_file(f);
            process::exit(0);
        },
        Err(ref e) if e.kind() == ErrorKind::NotFound => { /* ignored */ },
        Err(_) => {
            println!("default");
            process::exit(0);
        }
    }

    if let Ok(f) = File::open(&settings_path) {
        settings_toml(f);
        process::exit(0);
    }

    println!("default");
}

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

    #[test]
    fn simple_name() {
        assert_eq!("nightly", clean_toolchain_name("nightly-x86_64-unknown-linux-gnu"));
        assert_eq!("nightly", clean_toolchain_name("nightly"));
    }

    #[test]
    fn name_with_date() {
        assert_eq!("nightly-2016-06-05", clean_toolchain_name("nightly-2016-06-05-x86_64-unknown-linux-gnu"));
    }
}
<commit_msg>refactor: Handle error case in outer function<commit_after>extern crate toml;

use std::{env, process};
use std::io::prelude::*;
use std::io::{BufReader, ErrorKind};
use std::collections::BTreeMap;
use std::fs::File;

static OVERRIDES_PATH : &'static str = ".multirust/overrides";
static SETTINGS_PATH : &'static str = ".multirust/settings.toml";

enum OverridesDatabase {
    Plain(BTreeMap<String, String>),
    Toml(BTreeMap<String, toml::Value>),
}

impl OverridesDatabase {
    pub fn get(&self, key: &str) -> Option<&str> {
        use OverridesDatabase::*;

        match *self {
            Plain(ref db) => db.get(key).map(|s| &s[..]),
            Toml(ref db) => {
                db.get(key).map(|v| v.as_str().expect("Expected value is not a string."))
            }
        }
    }
}

fn with_date<'a>(short: &'a str, toolchain: &'a str) -> Option<&'a str> {
    let date_start = short.len() + 1;
    let date_end   = short.len() + 3 + 4 + 2 + 2;
    let char_range = toolchain.chars()
        .skip(date_start)
        .take(4)
        .all(char::is_numeric);

    if toolchain.len() > date_start && char_range {
        Some(&toolchain[0..date_end])
    } else {
        None
    }
}

fn clean_toolchain_name(toolchain: &str) -> &str {
    static SHORTNAMES : &'static [&'static str] = &["stable", "nightly", "beta"];

    for short in SHORTNAMES {
        if toolchain.starts_with(short) {
            return match with_date(short, toolchain) {
                Some(s) => s,
                None => short
            }
        }
    }

    toolchain
}

fn plain_overrides_file(f: File) {
    let overrides = BufReader::new(f);

    let mut overrides_map = BTreeMap::new();

    for line in overrides.lines() {
        let line = line.expect("No valid line found");
        let mut s = line.split(';');
        let path = s.next().expect("No path in line");
        let toolchain = s.next().expect("No toolchain in line");

        overrides_map.insert(path.into(), toolchain.into());
    }

    let database = OverridesDatabase::Plain(overrides_map);
    toolchain(database);
}

fn settings_toml(mut settings: File) -> Result<(), ()> {
    let mut content = String::new();
    settings.read_to_string(&mut content).expect("Can't read settings file");

    let database = try!(toml::Parser::new(&content).parse()
        .and_then(|toml| toml.get("overrides").cloned())
        .and_then(|overrides| overrides.as_table().cloned())
        .and_then(|database| Some(OverridesDatabase::Toml(database)))
        .ok_or(()));

    toolchain(database);
    Ok(())
}

fn toolchain(database: OverridesDatabase) {
    let mut cwd = env::current_dir().expect("No valid working directory");

    loop {
        let path = format!("{}", cwd.display());

        if let Some(toolchain) =  database.get(&path) {
            println!("{}", clean_toolchain_name(toolchain));
            return;
        }

        if !cwd.pop() {
            break;
        }
    }
    println!("default");
}

fn main() {
    let home = env::home_dir().expect("Impossible to get your home dir!");

    let mut overrides_path = home.clone();
    overrides_path.push(OVERRIDES_PATH);

    let mut settings_path = home.clone();
    settings_path.push(SETTINGS_PATH);

    match File::open(&overrides_path) {
        Ok(f) => {
            plain_overrides_file(f);
            process::exit(0);
        },
        Err(ref e) if e.kind() == ErrorKind::NotFound => { /* ignored */ },
        Err(_) => {
            println!("default");
            process::exit(0);
        }
    }

    if let Ok(f) = File::open(&settings_path) {
        settings_toml(f).unwrap_or_else(|_| println!("default"));
        process::exit(0);
    }

    println!("default");
}

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

    #[test]
    fn simple_name() {
        assert_eq!("nightly", clean_toolchain_name("nightly-x86_64-unknown-linux-gnu"));
        assert_eq!("nightly", clean_toolchain_name("nightly"));
    }

    #[test]
    fn name_with_date() {
        assert_eq!("nightly-2016-06-05", clean_toolchain_name("nightly-2016-06-05-x86_64-unknown-linux-gnu"));
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 Jan Likar.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern crate cargo;
extern crate docopt;
#[macro_use]
extern crate failure;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate cargo_clone;

use cargo::core::{SourceId, GitReference};
use cargo::util::{Config, ToUrl};

use docopt::Docopt;
type Result<T> = std::result::Result<T, failure::Error>;

#[derive(Deserialize, Debug)]
pub struct Options {
    flag_verbose: Option<bool>,
    flag_quiet: Option<bool>,
    flag_color: Option<String>,
    flag_version: Option<bool>,

    flag_prefix: Option<String>,

    arg_crate: Option<String>,
    flag_vers: Option<String>,
    flag_git: Option<String>,
    flag_branch: Option<String>,
    flag_tag: Option<String>,
    flag_rev: Option<String>,

    flag_path: Option<String>,
}

pub const USAGE: &'static str = "
Clone source code of a Rust crate

Usage:
    cargo clone [options] [<crate>]

Options:
    --prefix DIR              Directory to clone the package into

    --vers VERS               Specify a version to clone from crates.io

    --git URL                 Git URL to clone the specified crate from
    --branch BRANCH           Branch to use when cloning from git
    --tag TAG                 Tag to use when cloning from git
    --rev SHA                 Specific commit to use when cloning from git

    --path PATH               Filesystem path to local crate to clone

    -h, --help                Print this message
    -V, --version             Print version information
    -v, --verbose             Use verbose output
    -q, --quiet               Less output printed to stdout
    --color WHEN              Coloring: auto, always, never
";

fn main() {
    let options: Options = Docopt::new(USAGE)
                                  .and_then(|d|
                                            d.version(Some(version())).deserialize())
                                  .unwrap_or_else(|e| e.exit());

    let mut config = Config::default().expect("Unable to get config.");

    if let Err(e) = execute(options, &mut config) {
        config.shell().error(e).unwrap();
        std::process::exit(101);
    }
}

fn version() -> String {
    format!("cargo-clone {}.{}.{}{}",
            option_env!("CARGO_PKG_VERSION_MAJOR").unwrap_or("X"),
            option_env!("CARGO_PKG_VERSION_MINOR").unwrap_or("X"),
            option_env!("CARGO_PKG_VERSION_PATCH").unwrap_or("X"),
            option_env!("CARGO_PKG_VERSION_PRE").unwrap_or(""))
}

pub fn execute(options: Options, config: &mut Config) -> Result<Option<()>> {
    let verbose = match options.flag_verbose {
        Some(v) => if v {1} else {0},
        None => 0,
    };
    try!(config.configure(
        verbose,
        options.flag_quiet,
        &options.flag_color,
        false,
        false,
        &None,
        &[]
    ));

    let source_id = if let Some(url) = options.flag_git {
        let url = url.to_url()?;
        let gitref = if let Some(rev) = options.flag_rev {
            GitReference::Rev(rev)
        } else if let Some(tag) = options.flag_tag {
            GitReference::Tag(tag)
        } else if let Some(branch) = options.flag_branch {
            GitReference::Branch(branch)
        } else {
            GitReference::Branch("master".to_string())
        };
        SourceId::for_git(&url, gitref)?
    } else if let Some(path) = options.flag_path {
        SourceId::for_path(&config.cwd().join(path))?
    } else if options.arg_crate == None {
        bail!("must specify a crate to clone from \
                   crates.io, or use --path or --git to \
                   specify alternate source");
    } else {
        SourceId::crates_io(config)?
    };

    let krate = options.arg_crate.as_ref().map(|s| &s[..]);
    let prefix = options.flag_prefix.as_ref().map(|s| &s[..]);
    let vers = options.flag_vers.as_ref().map(|s| &s[..]);

    try!(cargo_clone::ops::clone(krate,
                                 &source_id,
                                 prefix,
                                 vers,
                                 config));

    Ok(None)
}
<commit_msg>add multiple cloning support this solves JanLikar/cargo-clone#23<commit_after>// Copyright 2015 Jan Likar.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern crate cargo;
extern crate docopt;
#[macro_use]
extern crate failure;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate cargo_clone;

use cargo::core::{SourceId, GitReference};
use cargo::util::{Config, ToUrl};

use docopt::Docopt;

type Result<T> = std::result::Result<T, failure::Error>;

#[derive(Deserialize, Debug)]
pub struct Options {
    flag_verbose: Option<bool>,
    flag_quiet: Option<bool>,
    flag_color: Option<String>,
    flag_version: Option<bool>,

    flag_prefix: Option<String>,

    arg_crate: Vec<String>,
    flag_vers: Option<String>,
    flag_git: Option<String>,
    flag_branch: Option<String>,
    flag_tag: Option<String>,
    flag_rev: Option<String>,

    flag_path: Option<String>,
}

pub const USAGE: &'static str = "
Clone source code of a Rust crate

Usage:
    cargo clone [options] [<crate>]...

Options:
    --prefix DIR              Directory to clone the package into

    --vers VERS               Specify a version to clone from crates.io

    --git URL                 Git URL to clone the specified crate from
    --branch BRANCH           Branch to use when cloning from git
    --tag TAG                 Tag to use when cloning from git
    --rev SHA                 Specific commit to use when cloning from git

    --path PATH               Filesystem path to local crate to clone

    -h, --help                Print this message
    -V, --version             Print version information
    -v, --verbose             Use verbose output
    -q, --quiet               Less output printed to stdout
    --color WHEN              Coloring: auto, always, never
";

fn main() {
    let options: Options = Docopt::new(USAGE)
        .and_then(|d|
            d.version(Some(version())).deserialize())
        .unwrap_or_else(|e| e.exit());

    let mut config = Config::default().expect("Unable to get config.");

    if let Err(e) = execute(options, &mut config) {
        config.shell().error(e).unwrap();
        std::process::exit(101);
    }
}

fn version() -> String {
    format!("cargo-clone {}.{}.{}{}",
            option_env!("CARGO_PKG_VERSION_MAJOR").unwrap_or("X"),
            option_env!("CARGO_PKG_VERSION_MINOR").unwrap_or("X"),
            option_env!("CARGO_PKG_VERSION_PATCH").unwrap_or("X"),
            option_env!("CARGO_PKG_VERSION_PRE").unwrap_or(""))
}

pub fn execute(options: Options, config: &mut Config) -> Result<Option<()>> {
    let verbose = match options.flag_verbose {
        Some(v) => if v { 1 } else { 0 },
        None => 0,
    };
    config.configure(
        verbose,
        options.flag_quiet,
        &options.flag_color,
        false,
        false,
        &None,
        &[],
    )?;

    let source_id = if let Some(url) = options.flag_git {
        let url = url.to_url()?;
        let gitref = if let Some(rev) = options.flag_rev {
            GitReference::Rev(rev)
        } else if let Some(tag) = options.flag_tag {
            GitReference::Tag(tag)
        } else if let Some(branch) = options.flag_branch {
            GitReference::Branch(branch)
        } else {
            GitReference::Branch("master".to_string())
        };
        SourceId::for_git(&url, gitref)?
    } else if let Some(path) = options.flag_path {
        SourceId::for_path(&config.cwd().join(path))?
    } else if options.arg_crate.len() == 0 {
        bail!("must specify a crate to clone from \
                   crates.io, or use --path or --git to \
                   specify alternate source");
    } else {
        SourceId::crates_io(config)?
    };

    let prefix = options.flag_prefix.as_ref().map(|s| &s[..]);
    let vers = options.flag_vers.as_ref().map(|s| &s[..]);
    if options.arg_crate.len() != 0 {
        for item in options.arg_crate.iter() {
            cargo_clone::ops::clone(Some(&item[..]),
                                         &source_id,
                                         prefix,
                                         vers,
                                         config)?;
        }
    } else {
        cargo_clone::ops::clone(None,
                                     &source_id,
                                     prefix,
                                     vers,
                                     config)?;
    }
    Ok(None)
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! # Cap'n Proto Schema Compiler Plugin Executable
//!
//! [See this.](https://capnproto.org/otherlang.html#how-to-write-compiler-plugins)
//!
//!

#![crate_type = "bin"]

extern crate capnp;
extern crate capnpc;

pub fn main() {
    //! Generate Rust code according to a `schema_capnp::code_generator_request` read from stdin.

    ::capnpc::codegen::main(::std::io::stdin(), ::std::path::Path::new(".")).unwrap();
}
<commit_msg>remove unused 'extern crate' statement<commit_after>// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! # Cap'n Proto Schema Compiler Plugin Executable
//!
//! [See this.](https://capnproto.org/otherlang.html#how-to-write-compiler-plugins)
//!
//!

#![crate_type = "bin"]

extern crate capnpc;

pub fn main() {
    //! Generate Rust code according to a `schema_capnp::code_generator_request` read from stdin.

    ::capnpc::codegen::main(::std::io::stdin(), ::std::path::Path::new(".")).unwrap();
}
<|endoftext|>


<commit_before>#![feature(macro_rules, slicing_syntax, while_let, if_let, phase, globs)]

//! Lispy-rs

#[phase(plugin, link)] extern crate log;
extern crate term;

extern crate readline;

// FIXME(#18822): Remove `pub`
pub mod parser;
pub mod lval;
pub mod eval;
pub mod builtin;
pub mod util;

#[cfg(not(test))]
mod main {
    use readline;

    use util::print_error;
    use eval::eval;
    use lval::LVal;
    use parser::Parser;

    pub fn main() {
        println!("MLisp Version 0.0.0.1");
        println!("Enter 'quit' to exit");
        println!("");

        loop {
            let input = if let Some(i) = readline::readline("> ") { i }
                        else { println!(""); break };
            readline::add_history(input[]);

            if input[] == "quit" { break }

            let ast = match Parser::parse(input[], "<input>") {
                Ok(lval) => lval,
                Err(err) => { print_error(format!("{}\n", err)[]); continue }
            };
            let lval = LVal::from_ast(ast);

            println!("{}", eval(lval));
        }

        println!("Exiting...")
    }
}

#[cfg(not(test))]
fn main() {
    main::main()
}<commit_msg>Experiments to improve testing performance<commit_after>#![feature(macro_rules, slicing_syntax, while_let, if_let, phase, globs)]

//! Lispy-rs

#[phase(plugin, link)] extern crate log;
extern crate term;

//extern crate readline;

// FIXME(#18822): Remove `pub`
pub mod parser;
pub mod lval;
pub mod eval;
pub mod builtin;
pub mod util;

extern {
    pub fn getch() -> i32;
    pub fn kbhit() -> i32;
}

#[cfg(not(test))]
mod main {
    //use readline;
    use std;

    use util::print_error;
    use eval::eval;
    use lval::LVal;
    use parser::Parser;

    pub fn main() {
        println!("MLisp Version 0.0.0.1");
        println!("Enter 'exit' to exit");
        println!("");

        let mut stdin = std::io::stdin();

        loop {
            print!("> ");

            // TODO: Use getch instead?
            let input = match stdin.read_line() {
                Ok(s) => s,
                Err(e) => {
                    println!("Error reading stdin: {}", e);
                    break
                }
            };

            //let input = if let Some(i) = readline::readline("> ") { i }
            //            else { println!(""); break };
            //readline::add_history(&*input);

            if &*input.trim() == "exit" { break }

            let ast = match Parser::parse(&*input, "<input>") {
                Ok(lval) => lval,
                Err(err) => { print_error(&*format!("{}\n", err)); continue }
            };
            let lval = LVal::from_ast(ast);

            println!("{}", eval(lval));
        }

        println!("Exiting...")
    }
}

#[cfg(not(test))]
fn main() {
    main::main()
}<|endoftext|>


<commit_before>
#![feature(slice_patterns)]

extern crate piston;
extern crate graphics;
extern crate sdl2_window;
extern crate opengl_graphics;
extern crate sprite;
extern crate vecmath;
extern crate uuid;

pub mod entity;

use entity::{Drawable, MobileUnit};

use std::cell::RefCell;
use std::rc::Rc;

use opengl_graphics::{
    GlGraphics,
    OpenGL,
};
use sdl2_window::Sdl2Window;
use piston::input::Button;
use piston::input::keyboard::Key;

fn main() {
    let win_size = piston::window::Size{width: 1280, height: 720};
    let window_settings = piston::window::WindowSettings::new(
        "Space Game".to_string(),
        win_size
        ).fullscreen(false).exit_on_esc(true).samples(0);
    let opengl = OpenGL::_3_2;
    let window = Sdl2Window::new(
        opengl,
        window_settings,
    );

    let ref mut gl = GlGraphics::new(opengl);
    let window = Rc::new(RefCell::new(window));
    let mut scene = sprite::Scene::new();

    let mut player = entity::Player::new(&mut scene);

    // left, up, right, down
    let mut moving = [false; 4];

    for e in piston::events(window) {
        use piston::event::*;

        scene.event(&e);
        if let Some(Button::Keyboard(key)) = e.press_args() {
            match key {
                Key::Left  => {moving[0] = true;},
                Key::Up    => {moving[1] = true;},
                Key::Right => {moving[2] = true;},
                Key::Down  => {moving[3] = true;},
                _ => {},
            }
        }
        if let Some(Button::Keyboard(key)) = e.release_args() {
            match key {
                Key::Left  => {moving[0] = false;},
                Key::Up    => {moving[1] = false;},
                Key::Right => {moving[2] = false;},
                Key::Down  => {moving[3] = false;},
                _ => {},

            }
        }
        if let Some(args) = e.update_args() {
            player.update(args.dt);
            // update horizontal movement
            match moving {
                [true , _, false, _] => {player.set_vel_x(-500.0);},
                [false, _, true , _] => {player.set_vel_x(500.0);},
                [_    , _, _    , _] => {player.set_vel_x(0.0);},
            }
            // update vertical movement
            match moving {
                [_, true , _, false] => {player.set_vel_y(500.0);},
                [_, false, _, true ] => {player.set_vel_y(-500.0);},
                [_, _    , _, _    ] => {player.set_vel_y(0.0);},
            }
        }
        if let Some(args) = e.render_args() {
            use graphics::*;
            player.draw(&mut scene, args);

            gl.draw([0, 0, args.width as i32, args.height as i32], |c, gl| {
                graphics::clear([0.0, 0.0, 0.0, 1.0], gl);
                scene.draw(c.transform, gl);
            });
        }
    }
}
<commit_msg>Fixed piston-up<commit_after>
#![feature(slice_patterns)]

extern crate piston;
extern crate graphics;
extern crate sdl2_window;
extern crate opengl_graphics;
extern crate sprite;
extern crate vecmath;
extern crate uuid;

pub mod entity;

use entity::{Drawable, MobileUnit};

use std::cell::RefCell;
use std::rc::Rc;

use piston::event::*;
use opengl_graphics::{
    GlGraphics,
    OpenGL,
};
use sdl2_window::Sdl2Window;
use piston::input::Button;
use piston::input::keyboard::Key;

fn main() {
    let win_size = piston::window::Size{width: 1280, height: 720};
    let window_settings = piston::window::WindowSettings::new(
        "Space Game".to_string(),
        win_size
        ).fullscreen(false).exit_on_esc(true).samples(0);
    let opengl = OpenGL::_3_2;
    let window = Sdl2Window::new(
        opengl,
        window_settings,
    );

    let ref mut gl = GlGraphics::new(opengl);
    let window = Rc::new(RefCell::new(window));
    let mut scene = sprite::Scene::new();

    let mut player = entity::Player::new(&mut scene);

    // left, up, right, down
    let mut moving = [false; 4];

    for e in window.events() {
        use piston::event::*;

        scene.event(&e);
        if let Some(Button::Keyboard(key)) = e.press_args() {
            match key {
                Key::Left  => {moving[0] = true;},
                Key::Up    => {moving[1] = true;},
                Key::Right => {moving[2] = true;},
                Key::Down  => {moving[3] = true;},
                _ => {},
            }
        }
        if let Some(Button::Keyboard(key)) = e.release_args() {
            match key {
                Key::Left  => {moving[0] = false;},
                Key::Up    => {moving[1] = false;},
                Key::Right => {moving[2] = false;},
                Key::Down  => {moving[3] = false;},
                _ => {},

            }
        }
        if let Some(args) = e.update_args() {
            player.update(args.dt);
            // update horizontal movement
            match moving {
                [true , _, false, _] => {player.set_vel_x(-500.0);},
                [false, _, true , _] => {player.set_vel_x(500.0);},
                [_    , _, _    , _] => {player.set_vel_x(0.0);},
            }
            // update vertical movement
            match moving {
                [_, true , _, false] => {player.set_vel_y(500.0);},
                [_, false, _, true ] => {player.set_vel_y(-500.0);},
                [_, _    , _, _    ] => {player.set_vel_y(0.0);},
            }
        }
        if let Some(args) = e.render_args() {
            use graphics::*;
            player.draw(&mut scene, args);

            gl.draw(args.viewport(), |c, gl| {
                graphics::clear([0.0, 0.0, 0.0, 1.0], gl);
                scene.draw(c.transform, gl);
            });
        }
    }
}
<|endoftext|>


<commit_before>#![deny(warnings)]

extern crate docopt;
extern crate plist;
extern crate rustc_serialize;
extern crate tera;
extern crate urlencoding;
extern crate urlparse;

mod applescript;
mod cli;
mod safari;
mod urls;

const NAME: &str = env!("CARGO_PKG_NAME");
const VERSION: &str = env!("CARGO_PKG_VERSION");

fn main() {
  let args = cli::parse_args(NAME);

  if args.flag_version {
    println!("{} v{}", NAME, VERSION);
  }

  if args.cmd_url {
    safari::assert_safari_is_running();
    print!("{}", safari::get_url(args.flag_window, args.flag_tab));
  }

  if args.cmd_urls_all {
    safari::assert_safari_is_running();
    for url in safari::get_all_urls() {
      println!("{}", url);
    }
  }

  if args.cmd_close_tabs {
    safari::assert_safari_is_running();
    let patterns = args.arg_urls_to_close.split(",").collect();
    safari::close_tabs(patterns);
  }

  if args.cmd_reading_list {
    for url in safari::get_reading_list_urls() {
      println!("{}", url);
    }
  }

  if args.cmd_icloud_tabs {
    if args.flag_list_devices {
      for device in safari::list_icloud_tabs_devices() {
        println!("{}", device);
      }
    } else {
      let tab_data = safari::get_icloud_tabs_urls();
      match args.flag_device {
        Some(d) => {
          match tab_data.get(&d) {
            Some(urls) => {
              for url in urls {
                println!("{}", url);
              }
            },
            None => (),
          }
        },
        None => {
          for urls in tab_data.values() {
            for url in urls {
              println!("{}", url);
            }
          }
        }
      }
    }
  }
}
<commit_msg>Include .rs in the version string<commit_after>#![deny(warnings)]

extern crate docopt;
extern crate plist;
extern crate rustc_serialize;
extern crate tera;
extern crate urlencoding;
extern crate urlparse;

mod applescript;
mod cli;
mod safari;
mod urls;

const NAME: &str = env!("CARGO_PKG_NAME");
const VERSION: &str = env!("CARGO_PKG_VERSION");

fn main() {
  let args = cli::parse_args(NAME);

  if args.flag_version {
    println!("{}.rs v{}", NAME, VERSION);
  }

  if args.cmd_url {
    safari::assert_safari_is_running();
    print!("{}", safari::get_url(args.flag_window, args.flag_tab));
  }

  if args.cmd_urls_all {
    safari::assert_safari_is_running();
    for url in safari::get_all_urls() {
      println!("{}", url);
    }
  }

  if args.cmd_close_tabs {
    safari::assert_safari_is_running();
    let patterns = args.arg_urls_to_close.split(",").collect();
    safari::close_tabs(patterns);
  }

  if args.cmd_reading_list {
    for url in safari::get_reading_list_urls() {
      println!("{}", url);
    }
  }

  if args.cmd_icloud_tabs {
    if args.flag_list_devices {
      for device in safari::list_icloud_tabs_devices() {
        println!("{}", device);
      }
    } else {
      let tab_data = safari::get_icloud_tabs_urls();
      match args.flag_device {
        Some(d) => {
          match tab_data.get(&d) {
            Some(urls) => {
              for url in urls {
                println!("{}", url);
              }
            },
            None => (),
          }
        },
        None => {
          for urls in tab_data.values() {
            for url in urls {
              println!("{}", url);
            }
          }
        }
      }
    }
  }
}
<|endoftext|>