<commit_before>use std::str;
use std::io;
use std::thread;
use std::io::Write;
use std::io::Read;

pub const ENCODER_DATA: u8 = 0x61;
pub const ANALOG_MAPPING_QUERY: u8 = 0x69;
pub const ANALOG_MAPPING_RESPONSE: u8 = 0x6A;
pub const CAPABILITY_QUERY: u8 = 0x6B;
pub const CAPABILITY_RESPONSE: u8 = 0x6C;
pub const PIN_STATE_QUERY: u8 = 0x6D;
pub const PIN_STATE_RESPONSE: u8 = 0x6E;
pub const EXTENDED_ANALOG: u8 = 0x6F;
pub const SERVO_CONFIG: u8 = 0x70;
pub const STRING_DATA: u8 = 0x71;
pub const STEPPER_DATA: u8 = 0x72;
pub const ONEWIRE_DATA: u8 = 0x73;
pub const SHIFT_DATA: u8 = 0x75;
pub const I2C_REQUEST: u8 = 0x76;
pub const I2C_REPLY: u8 = 0x77;
pub const I2C_CONFIG: u8 = 0x78;
pub const I2C_MODE_WRITE: u8 = 0x00;
pub const I2C_MODE_READ: u8 = 0x01;
pub const REPORT_FIRMWARE: u8 = 0x79;
pub const PROTOCOL_VERSION: u8 = 0xF9;
pub const SAMPLEING_INTERVAL: u8 = 0x7A;
pub const SCHEDULER_DATA: u8 = 0x7B;
pub const SYSEX_NON_REALTIME: u8 = 0x7E;
pub const SYSEX_REALTIME: u8 = 0x7F;
pub const START_SYSEX: u8 = 0xF0;
pub const END_SYSEX: u8 = 0xF7;
pub const PIN_MODE: u8 = 0xF4;
pub const REPORT_DIGITAL: u8 = 0xD0;
pub const REPORT_ANALOG: u8 = 0xC0;
pub const DIGITAL_MESSAGE: u8 = 0x90;
pub const ANALOG_MESSAGE: u8 = 0xE0;

pub const INPUT: u8 = 0;
pub const OUTPUT: u8 = 1;
pub const ANALOG: u8 = 2;
pub const PWM: u8 = 3;
pub const SERVO: u8 = 4;
pub const I2C: u8 = 6;
pub const ONEWIRE: u8 = 7;
pub const STEPPER: u8 = 8;
pub const ENCODER: u8 = 9;

fn read<T: io::Read>(port: &mut T, len: i32) -> io::Result<(Vec<u8>)> {
    use std::io::ErrorKind;
    let mut vec: Vec<u8> = vec![];
    let mut len = len;

    loop {
        let buf: &mut [u8; 1] = &mut [0u8];

        match port.read(buf) {
            Ok(_) => {
                vec.push(buf[0]);
                len = len - 1;
                if len == 0 {
                   break;
                }
            }
            Err(e) => {
                 if e.kind() == ErrorKind::TimedOut {
                    thread::sleep_ms(1);
                    continue
                }
            }
        }
    }

    return Ok(vec);
}

#[derive(Debug)]
pub struct I2CReply {
    pub address: i32,
    pub register: i32,
    pub data: Vec<u8>,
}

#[derive(Debug)]
pub struct Mode {
    pub mode: u8,
    pub resolution: u8
}

#[derive(Debug)]
pub struct Pin {
    pub modes: Vec<Mode>,
    pub analog: bool,
    pub value: i32,
    pub mode: u8,
}

pub trait Firmata {
    fn i2c_data(&mut self) -> &mut Vec<I2CReply>;
    fn pins(&mut self) -> &Vec<Pin>;
    fn protocol_version(&mut self) -> &String;
    fn firmware_name(&mut self) -> &String;
    fn firmware_version(&mut self) -> &String;
    fn query_analog_mapping(&mut self);
    fn query_capabilities(&mut self);
    fn query_firmware(&mut self);
    fn i2c_config(&mut self, delay: i32);
    fn i2c_read(&mut self, address: i32, size: i32);
    fn i2c_write(&mut self, address: i32, data: &[u8]);
    fn report_digital(&mut self, pin: i32, state: i32);
    fn report_analog(&mut self, pin: i32, state: i32);
    fn analog_write(&mut self, pin: i32, level: i32);
    fn digital_write(&mut self, pin: i32, level: i32);
    fn set_pin_mode(&mut self, pin: i32, mode: u8);
    fn read_and_decode(&mut self);
}

pub struct Board<T: io::Read+io::Write> {
    pub connection: Box<T>,
    pub pins: Vec<Pin>,
    pub i2c_data: Vec<I2CReply>,
    pub protocol_version: String,
    pub firmware_name: String,
    pub firmware_version: String,
}

impl<T: io::Read+io::Write> Board<T> {
    pub fn new(connection: Box<T>) -> Board<T> {
        let mut b = Board {
            connection: connection,
            firmware_name: String::new(),
            firmware_version: String::new(),
            protocol_version: String::new(),
            pins: vec![],
            i2c_data: vec![],
        };

        b.query_firmware();
        b.read_and_decode();
        b.read_and_decode();
        b.query_capabilities();
        b.read_and_decode();
        b.query_analog_mapping();
        b.read_and_decode();

        b.report_digital(0, 1);
        b.report_digital(1, 1);

        return b;
    }
}

impl<T:io::Read+io::Write> Firmata for Board<T> {
    fn pins(&mut self) -> &Vec<Pin> {
        &self.pins
    }
    fn protocol_version(&mut self) -> &String {
        &self.protocol_version
    }
    fn firmware_name(&mut self) -> &String {
        &self.firmware_name
    }
    fn firmware_version(&mut self) -> &String {
        &self.firmware_version
    }
    fn i2c_data(&mut self) -> &mut Vec<I2CReply> {
        &mut self.i2c_data
    }
    fn query_analog_mapping(&mut self) {
        self.connection.write(&mut [START_SYSEX, ANALOG_MAPPING_QUERY, END_SYSEX]).unwrap();
    }

    fn query_capabilities(&mut self) {
        self.connection.write(&mut [START_SYSEX, CAPABILITY_QUERY, END_SYSEX]).unwrap();
    }

    fn query_firmware(&mut self) {
        self.connection.write(&mut [START_SYSEX, REPORT_FIRMWARE, END_SYSEX]).unwrap();
    }

    fn i2c_config(&mut self, delay: i32) {
        self.connection.write(
            &mut [
                START_SYSEX,
                I2C_CONFIG,
                (delay & 0xFF) as u8,
                (delay >> 8 & 0xFF) as u8,
                END_SYSEX
            ]
        ).unwrap();
    }

    fn i2c_read(&mut self, address: i32, size: i32) {
        self.connection.write(
            &mut [
                START_SYSEX,
                I2C_REQUEST,
                address as u8,
                (I2C_MODE_READ << 3),
                ((size as u8) & 0x7F),
                (((size) >> 7) & 0x7F) as u8,
                END_SYSEX
            ]
        ).unwrap();
    }

    fn i2c_write(&mut self, address: i32, data: &[u8]) {
        let mut buf = vec![];

        buf.push(START_SYSEX);
        buf.push(I2C_REQUEST);
        buf.push(address as u8);
        buf.push(I2C_MODE_WRITE << 3);

        for i in data.iter() {
            buf.push(i & 0x7F);
            buf.push((((*i as i32) >> 7) & 0x7F) as u8);
        }

        buf.push(END_SYSEX);

        self.connection.write(&mut buf[..]).unwrap();
    }

    fn report_digital(&mut self, pin: i32, state: i32) {
        self.connection.write(
            &mut [
                REPORT_DIGITAL | pin as u8,
                state as u8
            ]
        ).unwrap();
    }

    fn report_analog(&mut self, pin: i32, state: i32) {
        self.connection.write(
            &mut [
                REPORT_ANALOG | pin as u8,
                state as u8
            ]
        ).unwrap();
    }

    fn analog_write(&mut self, pin: i32, level: i32) {
        self.pins[pin as usize].value = level;

        self.connection.write(
            &mut [
                ANALOG_MESSAGE | pin as u8,
                (level & 0x7f) as u8,
                ((level >> 7) & 0x7f) as u8
            ]
        ).unwrap();
    }

    fn digital_write(&mut self, pin: i32, level: i32) {
        let port = (pin as f64 / 8f64).floor() as usize;
        let mut value = 0i32;
        let mut i = 0;

        self.pins[pin as usize].value = level;

        while i < 8 {
            if self.pins[8*port+i].value != 0 {
                value = value | (1 << i)
            }
            i += 1;
        }

        self.connection.write(
            &mut [
                DIGITAL_MESSAGE | port as u8,
                (value & 0x7f) as u8,
                ((value >> 7) & 0x7f) as u8
            ]
        ).unwrap();
    }

    fn set_pin_mode(&mut self, pin: i32, mode: u8) {
        self.pins[pin as usize].mode = mode;
        self.connection.write(&mut [PIN_MODE, pin as u8, mode as u8]).unwrap();
    }

    fn read_and_decode(&mut self) {
        let mut buf = read(&mut self.connection, 3).unwrap();
        match buf[0] {
            PROTOCOL_VERSION => {
                self.protocol_version = format!("{:o}.{:o}", buf[1], buf[2]);
            },
            ANALOG_MESSAGE...0xEF => {
                let value = (buf[1] as i32) | ((buf[2] as i32) << 7);
                let pin = ((buf[0] as i32) & 0x0F) + 14;

                if self.pins.len() as i32 > pin {
                    self.pins[pin as usize].value = value;
                }
            },
            DIGITAL_MESSAGE...0x9F => {
                let port = (buf[0] as i32) & 0x0F;
                let value = (buf[1] as i32) | ((buf[2] as i32) << 7);

                for i in 0..8 {
                    let pin = (8 * port) + i;

                    if self.pins.len() as i32 > pin {
                        if self.pins[pin as usize].mode == INPUT {
                            self.pins[pin as usize].value = (value >> (i & 0x07)) & 0x01;
                        }
                    }
                }
            },
            START_SYSEX => {
                loop {
                    let message = read(&mut *self.connection, 1).unwrap();
                    buf.push(message[0]);
                    if message[0] == END_SYSEX {
                        break;
                    }
                }
                match buf[1] {
                    ANALOG_MAPPING_RESPONSE => {
                        if self.pins.len() > 0 {
                           let mut i = 2;
                           while i < buf.len()-1 {
                               if buf[i] != 127u8 {
                                   self.pins[i-2].analog = true;
                               }
                               i += 1;
                           }
                        }
                    },
                    CAPABILITY_RESPONSE => {
                        let mut pin = 0;
                        let mut i = 2;
                        self.pins = vec![];
                        self.pins.push(Pin{
                            modes: vec![],
                            analog: false,
                            value: 0,
                            mode: 0,
                        });
                        while i < buf.len()-1 {
                            if buf[i] == 127u8 {
                                pin += 1;
                                i += 1;
                                self.pins.push(Pin{
                                    modes: vec![],
                                    analog: false,
                                    value: 0,
                                    mode: 0,
                                });
                                continue;
                            }
                            self.pins[pin].modes.push(Mode {
                                mode: buf[i],
                                resolution: buf[i+1]
                            });
                            i += 2;
                        }
                    },
                    REPORT_FIRMWARE => {
                        self.firmware_version = format!("{:o}.{:o}", buf[2], buf[3]);
                        self.firmware_name = str::from_utf8(&buf[4..buf.len()-1]).unwrap().to_string();
                    },
                    I2C_REPLY => {
                        let len = buf.len();
                        let mut reply = I2CReply{
                            address:  (buf[2] as i32) | ((buf[3] as i32) << 7),
                            register: (buf[4] as i32) | ((buf[5] as i32) << 7),
                            data:     vec![buf[6] | buf[7]<<7],
                        };
                        let mut i = 8;

                        while i < len-1 {
                            if buf[i] == 0xF7 {
                                break
                            }
                            if i+2 > len {
                                break
                            }
                            reply.data.push(buf[i] | buf[i+1] << 7);
                            i += 2;
                        }
                        self.i2c_data.push(reply);
                    },
                    _ => println!("unknown sysex code"),
                }
            },
            _ => println!("bad byte"),
        }
    }

}
<commit_msg>First pass at docs<commit_after>//! This module contains a client implementation of the
//! [Firmata Protocol](https://github.com/firmata/protocol)
use std::str;
use std::io;
use std::thread;
use std::io::Write;
use std::io::Read;

pub const ENCODER_DATA: u8 = 0x61;
pub const ANALOG_MAPPING_QUERY: u8 = 0x69;
pub const ANALOG_MAPPING_RESPONSE: u8 = 0x6A;
pub const CAPABILITY_QUERY: u8 = 0x6B;
pub const CAPABILITY_RESPONSE: u8 = 0x6C;
pub const PIN_STATE_QUERY: u8 = 0x6D;
pub const PIN_STATE_RESPONSE: u8 = 0x6E;
pub const EXTENDED_ANALOG: u8 = 0x6F;
pub const SERVO_CONFIG: u8 = 0x70;
pub const STRING_DATA: u8 = 0x71;
pub const STEPPER_DATA: u8 = 0x72;
pub const ONEWIRE_DATA: u8 = 0x73;
pub const SHIFT_DATA: u8 = 0x75;
pub const I2C_REQUEST: u8 = 0x76;
pub const I2C_REPLY: u8 = 0x77;
pub const I2C_CONFIG: u8 = 0x78;
pub const I2C_MODE_WRITE: u8 = 0x00;
pub const I2C_MODE_READ: u8 = 0x01;
pub const REPORT_FIRMWARE: u8 = 0x79;
pub const PROTOCOL_VERSION: u8 = 0xF9;
pub const SAMPLEING_INTERVAL: u8 = 0x7A;
pub const SCHEDULER_DATA: u8 = 0x7B;
pub const SYSEX_NON_REALTIME: u8 = 0x7E;
pub const SYSEX_REALTIME: u8 = 0x7F;
pub const START_SYSEX: u8 = 0xF0;
pub const END_SYSEX: u8 = 0xF7;
pub const PIN_MODE: u8 = 0xF4;
pub const REPORT_DIGITAL: u8 = 0xD0;
pub const REPORT_ANALOG: u8 = 0xC0;
pub const DIGITAL_MESSAGE: u8 = 0x90;
pub const ANALOG_MESSAGE: u8 = 0xE0;

pub const INPUT: u8 = 0;
pub const OUTPUT: u8 = 1;
pub const ANALOG: u8 = 2;
pub const PWM: u8 = 3;
pub const SERVO: u8 = 4;
pub const I2C: u8 = 6;
pub const ONEWIRE: u8 = 7;
pub const STEPPER: u8 = 8;
pub const ENCODER: u8 = 9;

fn read<T: io::Read>(port: &mut T, len: i32) -> io::Result<(Vec<u8>)> {
    use std::io::ErrorKind;
    let mut vec: Vec<u8> = vec![];
    let mut len = len;

    loop {
        let buf: &mut [u8; 1] = &mut [0u8];

        match port.read(buf) {
            Ok(_) => {
                vec.push(buf[0]);
                len = len - 1;
                if len == 0 {
                   break;
                }
            }
            Err(e) => {
                 if e.kind() == ErrorKind::TimedOut {
                    thread::sleep_ms(1);
                    continue
                }
            }
        }
    }

    return Ok(vec);
}

/// A structure representing an I2C reply.
#[derive(Debug)]
pub struct I2CReply {
    pub address: i32,
    pub register: i32,
    pub data: Vec<u8>,
}

/// A structure representing an available pin mode.
#[derive(Debug)]
pub struct Mode {
    pub mode: u8,
    pub resolution: u8
}

/// A structure representing the current state and configuration of a pin.
#[derive(Debug)]
pub struct Pin {
    pub modes: Vec<Mode>,
    pub analog: bool,
    pub value: i32,
    pub mode: u8,
}

/// A trait for implementing firmata boards.
pub trait Firmata {
    /// This function returns the raw I2C replies that have been read from
    /// the board.
    fn i2c_data(&mut self) -> &mut Vec<I2CReply>;
    /// This function returns the pins that the board has access to.
    fn pins(&mut self) -> &Vec<Pin>;
    /// This function returns the current firmata protocol version.
    fn protocol_version(&mut self) -> &String;
    /// This function returns the firmware name.
    fn firmware_name(&mut self) -> &String;
    /// This function returns the firmware version.
    fn firmware_version(&mut self) -> &String;
    /// This function queries the board for available analog pins.
    fn query_analog_mapping(&mut self);
    /// This function queries the board for all available capabilities.
    fn query_capabilities(&mut self);
    /// This function queries the board for current firmware and protocol
    /// information.
    fn query_firmware(&mut self);
    /// This function configures the `delay` in microseconds for I2C devices
    /// that require a delay between when the register is written to and the
    /// data in that register can be read.
    fn i2c_config(&mut self, delay: i32);
    /// This function reads `size` bytes from I2C device at the specified
    /// `address`.
    fn i2c_read(&mut self, address: i32, size: i32);
    /// This function writes `data` to the I2C device at
    /// the specified `address`.
    fn i2c_write(&mut self, address: i32, data: &[u8]);
    /// This function sets the digital reporting `state`
    /// of the specified `pin`.
    fn report_digital(&mut self, pin: i32, state: i32);
    /// This function sets the analog reporting `state` of the specified `pin`.
    fn report_analog(&mut self, pin: i32, state: i32);
    /// This function writes `level` to the analog `pin`.
    fn analog_write(&mut self, pin: i32, level: i32);
    /// This function writes `level` to the digital `pin`.
    fn digital_write(&mut self, pin: i32, level: i32);
    /// This function sets the `mode` of the specified `pin`.
    fn set_pin_mode(&mut self, pin: i32, mode: u8);
    /// This function reads from the firmata device and parses one firmata
    /// message.
    fn read_and_decode(&mut self);
}

/// A structure representing a firmata board.
pub struct Board<T: io::Read+io::Write> {
    pub connection: Box<T>,
    pub pins: Vec<Pin>,
    pub i2c_data: Vec<I2CReply>,
    pub protocol_version: String,
    pub firmware_name: String,
    pub firmware_version: String,
}

impl<T: io::Read+io::Write> Board<T> {
    /// Creates a new `Board` given an `io::Read+io::Write`.
    pub fn new(connection: Box<T>) -> Board<T> {
        let mut b = Board {
            connection: connection,
            firmware_name: String::new(),
            firmware_version: String::new(),
            protocol_version: String::new(),
            pins: vec![],
            i2c_data: vec![],
        };

        b.query_firmware();
        b.read_and_decode();
        b.read_and_decode();
        b.query_capabilities();
        b.read_and_decode();
        b.query_analog_mapping();
        b.read_and_decode();

        b.report_digital(0, 1);
        b.report_digital(1, 1);

        return b;
    }
}

impl<T:io::Read+io::Write> Firmata for Board<T> {
    fn pins(&mut self) -> &Vec<Pin> {
        &self.pins
    }
    fn protocol_version(&mut self) -> &String {
        &self.protocol_version
    }
    fn firmware_name(&mut self) -> &String {
        &self.firmware_name
    }
    fn firmware_version(&mut self) -> &String {
        &self.firmware_version
    }
    fn i2c_data(&mut self) -> &mut Vec<I2CReply> {
        &mut self.i2c_data
    }
    fn query_analog_mapping(&mut self) {
        self.connection.write(&mut [START_SYSEX, ANALOG_MAPPING_QUERY, END_SYSEX]).unwrap();
    }

    fn query_capabilities(&mut self) {
        self.connection.write(&mut [START_SYSEX, CAPABILITY_QUERY, END_SYSEX]).unwrap();
    }

    fn query_firmware(&mut self) {
        self.connection.write(&mut [START_SYSEX, REPORT_FIRMWARE, END_SYSEX]).unwrap();
    }

    fn i2c_config(&mut self, delay: i32) {
        self.connection.write(
            &mut [
                START_SYSEX,
                I2C_CONFIG,
                (delay & 0xFF) as u8,
                (delay >> 8 & 0xFF) as u8,
                END_SYSEX
            ]
        ).unwrap();
    }

    fn i2c_read(&mut self, address: i32, size: i32) {
        self.connection.write(
            &mut [
                START_SYSEX,
                I2C_REQUEST,
                address as u8,
                (I2C_MODE_READ << 3),
                ((size as u8) & 0x7F),
                (((size) >> 7) & 0x7F) as u8,
                END_SYSEX
            ]
        ).unwrap();
    }

    fn i2c_write(&mut self, address: i32, data: &[u8]) {
        let mut buf = vec![];

        buf.push(START_SYSEX);
        buf.push(I2C_REQUEST);
        buf.push(address as u8);
        buf.push(I2C_MODE_WRITE << 3);

        for i in data.iter() {
            buf.push(i & 0x7F);
            buf.push((((*i as i32) >> 7) & 0x7F) as u8);
        }

        buf.push(END_SYSEX);

        self.connection.write(&mut buf[..]).unwrap();
    }

    fn report_digital(&mut self, pin: i32, state: i32) {
        self.connection.write(
            &mut [
                REPORT_DIGITAL | pin as u8,
                state as u8
            ]
        ).unwrap();
    }

    fn report_analog(&mut self, pin: i32, state: i32) {
        self.connection.write(
            &mut [
                REPORT_ANALOG | pin as u8,
                state as u8
            ]
        ).unwrap();
    }

    fn analog_write(&mut self, pin: i32, level: i32) {
        self.pins[pin as usize].value = level;

        self.connection.write(
            &mut [
                ANALOG_MESSAGE | pin as u8,
                (level & 0x7f) as u8,
                ((level >> 7) & 0x7f) as u8
            ]
        ).unwrap();
    }

    fn digital_write(&mut self, pin: i32, level: i32) {
        let port = (pin as f64 / 8f64).floor() as usize;
        let mut value = 0i32;
        let mut i = 0;

        self.pins[pin as usize].value = level;

        while i < 8 {
            if self.pins[8*port+i].value != 0 {
                value = value | (1 << i)
            }
            i += 1;
        }

        self.connection.write(
            &mut [
                DIGITAL_MESSAGE | port as u8,
                (value & 0x7f) as u8,
                ((value >> 7) & 0x7f) as u8
            ]
        ).unwrap();
    }

    fn set_pin_mode(&mut self, pin: i32, mode: u8) {
        self.pins[pin as usize].mode = mode;
        self.connection.write(&mut [PIN_MODE, pin as u8, mode as u8]).unwrap();
    }

    fn read_and_decode(&mut self) {
        let mut buf = read(&mut self.connection, 3).unwrap();
        match buf[0] {
            PROTOCOL_VERSION => {
                self.protocol_version = format!("{:o}.{:o}", buf[1], buf[2]);
            },
            ANALOG_MESSAGE...0xEF => {
                let value = (buf[1] as i32) | ((buf[2] as i32) << 7);
                let pin = ((buf[0] as i32) & 0x0F) + 14;

                if self.pins.len() as i32 > pin {
                    self.pins[pin as usize].value = value;
                }
            },
            DIGITAL_MESSAGE...0x9F => {
                let port = (buf[0] as i32) & 0x0F;
                let value = (buf[1] as i32) | ((buf[2] as i32) << 7);

                for i in 0..8 {
                    let pin = (8 * port) + i;

                    if self.pins.len() as i32 > pin {
                        if self.pins[pin as usize].mode == INPUT {
                            self.pins[pin as usize].value = (value >> (i & 0x07)) & 0x01;
                        }
                    }
                }
            },
            START_SYSEX => {
                loop {
                    let message = read(&mut *self.connection, 1).unwrap();
                    buf.push(message[0]);
                    if message[0] == END_SYSEX {
                        break;
                    }
                }
                match buf[1] {
                    ANALOG_MAPPING_RESPONSE => {
                        if self.pins.len() > 0 {
                           let mut i = 2;
                           while i < buf.len()-1 {
                               if buf[i] != 127u8 {
                                   self.pins[i-2].analog = true;
                               }
                               i += 1;
                           }
                        }
                    },
                    CAPABILITY_RESPONSE => {
                        let mut pin = 0;
                        let mut i = 2;
                        self.pins = vec![];
                        self.pins.push(Pin{
                            modes: vec![],
                            analog: false,
                            value: 0,
                            mode: 0,
                        });
                        while i < buf.len()-1 {
                            if buf[i] == 127u8 {
                                pin += 1;
                                i += 1;
                                self.pins.push(Pin{
                                    modes: vec![],
                                    analog: false,
                                    value: 0,
                                    mode: 0,
                                });
                                continue;
                            }
                            self.pins[pin].modes.push(Mode {
                                mode: buf[i],
                                resolution: buf[i+1]
                            });
                            i += 2;
                        }
                    },
                    REPORT_FIRMWARE => {
                        self.firmware_version = format!("{:o}.{:o}", buf[2], buf[3]);
                        self.firmware_name = str::from_utf8(&buf[4..buf.len()-1]).unwrap().to_string();
                    },
                    I2C_REPLY => {
                        let len = buf.len();
                        let mut reply = I2CReply{
                            address:  (buf[2] as i32) | ((buf[3] as i32) << 7),
                            register: (buf[4] as i32) | ((buf[5] as i32) << 7),
                            data:     vec![buf[6] | buf[7]<<7],
                        };
                        let mut i = 8;

                        while i < len-1 {
                            if buf[i] == 0xF7 {
                                break
                            }
                            if i+2 > len {
                                break
                            }
                            reply.data.push(buf[i] | buf[i+1] << 7);
                            i += 2;
                        }
                        self.i2c_data.push(reply);
                    },
                    _ => println!("unknown sysex code"),
                }
            },
            _ => println!("bad byte"),
        }
    }

}
<|endoftext|>


<commit_before>extern crate proc_macro;
extern crate syn;
#[macro_use]
extern crate quote;

use proc_macro::TokenStream;

#[proc_macro_derive(OptionalStruct)]
pub fn optional_struct(input: TokenStream) -> TokenStream {
    let s = input.to_string();
    let ast = syn::parse_derive_input(&s).unwrap();
    let gen = create_optional_struct(&ast);
    gen.parse().unwrap()
}

fn create_optional_struct(ast: &syn::DeriveInput) -> quote::Tokens {
    let name = &ast.ident;

    if let syn::Body::Struct(ref variant_data) = ast.body {
        if let &syn::VariantData::Struct(ref fields) = variant_data {

            let mut attributes = quote! {};
            for field in fields {
                let ref type_name = &field.ty;
                let ref field_name = &field.ident.clone().unwrap();
                let next_attribute = quote! { pub Option<#type_name> #field_name, };
                attributes = quote!{ #attributes #next_attribute };
            }

            return quote!{
                struct Optional#name {
                    #attributes
                }
            }
        }
    }

    panic!("OptionalStruct only supports non-tuple structs for now");
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}
<commit_msg>add apply_options<commit_after>extern crate proc_macro;
extern crate syn;
#[macro_use]
extern crate quote;

use proc_macro::TokenStream;

#[proc_macro_derive(OptionalStruct)]
pub fn optional_struct(input: TokenStream) -> TokenStream {
    let s = input.to_string();
    let ast = syn::parse_derive_input(&s).unwrap();
    let gen = create_optional_struct(&ast);
    gen.parse().unwrap()
}

fn create_optional_struct(ast: &syn::DeriveInput) -> quote::Tokens {
    let name = &ast.ident;

    if let syn::Body::Struct(ref variant_data) = ast.body {
        if let &syn::VariantData::Struct(ref fields) = variant_data {

            let mut attributes = quote!{};
            let mut assigners = quote!{};
            for field in fields {
                let ref type_name = &field.ty;
                let ref field_name = &field.ident.clone().unwrap();
                let next_attribute = quote! { pub Option<#type_name> #field_name, };
                attributes = quote!{ #attributes #next_attribute };
                let next_assigner = quote!{
                    if let Some(attribute) = optional_struct.#field_name {
                        self.#field_name = attribute;
                    }
                };
                assigners = quote!{ #assigners #next_assigner };

                return quote!{
                    struct Optional#name {
                        #attributes
                    }

                    impl #name {
                        pub fn apply_options(&mut self, optional_struct: &Optional#name) {
                            #assigners
                        }
                    }
                };
            }
        }
    }

    panic!("OptionalStruct only supports non-tuple structs for now");
}

#[cfg(test)]
mod tests {

    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}
<|endoftext|>


<commit_before>//! Struct and methods for union-find operation.

#![warn(bad_style, missing_docs,
        unused, unused_extern_crates, unused_import_braces,
        unused_qualifications, unused_results)]

#![cfg_attr(all(test, feature = "nightly"), feature(test))]

use std::{mem, usize};
use std::default::Default;
use std::iter::{IntoIterator, FromIterator};

#[derive(Clone, Debug)]
enum UFNode<T> {
    Key(usize),
    Value(T)
}

impl<T> UFNode<T> {
    fn get(&self) -> &T {
        match self {
            &UFNode::Value(ref val) => val,
            &UFNode::Key(_) => panic!()
        }
    }
    fn get_mut(&mut self) -> &mut T {
        match self {
            &mut UFNode::Value(ref mut val) => val,
            &mut UFNode::Key(_) => panic!()
        }
    }
    fn unwrap(self) -> T {
        match self {
            UFNode::Value(val) => val,
            UFNode::Key(_) => panic!()
        }
    }
}

/// The value that can be contained with `UFValue`.
pub trait UFValue: Sized {
    /// Merge two value into one.
    ///
    /// This is used by `UnionFind::union` operation.
    fn merge(lval: Self, rval: Self) -> Merge<Self>;
}

/// Return value of the `UFValue::merege`
#[allow(missing_docs)]
pub enum Merge<T> {
    Left(T), Right(T)
}

/// Reperesents the size of the group.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct Size(usize);

impl UFValue for Size {
    fn merge(Size(lval): Size, Size(rval): Size) -> Merge<Size> {
        if lval >= rval {
            Merge::Left(Size(lval + rval))
        } else {
            Merge::Right(Size(lval + rval))
        }
    }
}

impl Default for Size {
    fn default() -> Size { Size(1) }
}

/// Struct for union-find operation.
#[derive(Clone, Debug)]
pub struct UnionFind<V = Size> {
    data: Vec<UFNode<V>>
}

impl<T: UFValue = Size> UnionFind<T> {
    /// Creates empty `UnionFind` struct.
    #[inline]
    pub fn new(len: usize) -> UnionFind<T>
        where T: Default
    {
        UnionFind {
            data: (0 .. len)
                .map(|_| UFNode::Value(Default::default()))
                .collect()
        }
    }

    /// Returns the size of `self`.
    #[inline]
    pub fn size(&self) -> usize { self.data.len() }

    /// Join two sets that contains given keys (Union operation).
    ///
    /// Returns `true` if these keys are belonged to different sets.
    #[inline]
    pub fn union(&mut self, key0: usize, key1: usize) -> bool {
        let k0 = self.get_key(key0);
        let k1 = self.get_key(key1);
        if k0 == k1 { return false; }

        // Temporary replace with dummy to move out the elements of the vector.
        let v0 = mem::replace(&mut self.data[k0], UFNode::Key(usize::MAX)).unwrap();
        let v1 = mem::replace(&mut self.data[k1], UFNode::Key(usize::MAX)).unwrap();

        match UFValue::merge(v0, v1) {
            Merge::Left(val) => {
                self.data[k0] = UFNode::Value(val);
                self.data[k1] = UFNode::Key(k0);
            }
            Merge::Right(val) => {
                self.data[k1] = UFNode::Value(val);
                self.data[k0] = UFNode::Key(k1);
            }
        }

        true
    }

    /// Returns `true` if two keys contained by the same set (find operation).
    #[inline]
    pub fn find(&mut self, key0: usize, key1: usize) -> bool {
         self.get_key(key0) == self.get_key(key1)
    }

    /// Returns the reference to the value of the set that the key belongs to.
    #[inline]
    pub fn get(&mut self, key: usize) -> &T {
        let root_key = self.get_key(key);
        self.data[root_key].get()
    }

    /// Returns the mutable reference to the value of the set that the key belongs to.
    #[inline]
    pub fn get_mut(&mut self, key: usize) -> &mut T {
        let root_key = self.get_key(key);
        self.data[root_key].get_mut()
    }

    fn get_key(&mut self, key: usize) -> usize {
        let root_key = match self.data[key] {
            UFNode::Value(_) => return key,
            UFNode::Key(key) => self.get_key(key)
        };

        self.data[key] = UFNode::Key(root_key);
        root_key
    }
}

impl<A: UFValue> FromIterator<A> for UnionFind<A> {
    #[inline]
    fn from_iter<T: IntoIterator<Item=A>>(iterator: T) -> UnionFind<A> {
        UnionFind { data: iterator.into_iter().map(UFNode::Value).collect() }
    }
}

#[cfg(test)]
mod tests {
    use super::{UnionFind, Size};

    #[test]
    fn test_union_find() {
        let mut uf = UnionFind::new(100);
        assert_eq!(&Size(1), uf.get(0));
        assert_eq!(&Size(1), uf.get(1));
        assert!(!uf.find(0, 1));
        assert!(!uf.find(1, 2));
        assert!(uf.union(0, 1));
        assert!(uf.find(0, 1));
        assert_eq!(&Size(2), uf.get(0));
        assert_eq!(&Size(2), uf.get(1));
        assert_eq!(&Size(1), uf.get(2));
        assert!(!uf.union(0, 1));
        assert_eq!(&Size(2), uf.get(0));
        assert_eq!(&Size(2), uf.get(1));
        assert_eq!(&Size(1), uf.get(2));
        assert!(uf.union(1, 2));
        assert_eq!(&Size(3), uf.get(0));
        assert_eq!(&Size(3), uf.get(1));
        assert_eq!(&Size(3), uf.get(2));
        assert!(uf.find(0, 1));
        assert!(uf.find(2, 1));
    }
}

#[cfg(all(test, feature = "nightly"))]
mod bench {
    extern crate test;
    extern crate rand;

    use self::test::Bencher;
    use self::rand::distributions::{IndependentSample, Range};
    use super::{UnionFind, Size};

    fn union_short_trail(uf: &mut UnionFind<Size>) {
        for i in 1 .. uf.size() {
            uf.union(0, i);
        }
    }

    fn union_long_trail(uf: &mut UnionFind<Size>) {
        let mut rng = rand::thread_rng();
        let between = Range::new(0, uf.size());

        for _ in 0..uf.size() {
            let a = between.ind_sample(&mut rng);
            let b = between.ind_sample(&mut rng);
            uf.union(a, b);
       }
    }

    #[bench]
    fn bench_union_short_trail(bencher: &mut Bencher) {
        bencher.iter(|| {
            let mut uf = UnionFind::<Size>::new(1024);
            union_short_trail(&mut uf);
        })
    }

    #[bench]
    fn bench_union_long_trail(bencher: &mut Bencher) {
        bencher.iter(|| {
            let mut uf = UnionFind::<Size>::new(1024);
            union_long_trail(&mut uf);
        })
    }

    fn find_interleave(uf: &UnionFind<Size>, n: usize) -> UnionFind<Size> {
        let mut uf = uf.clone();
        for _ in 0..n {
            for i in 1 .. uf.size() {
                uf.find(0, i);
            }
        }
        uf
    }

    fn find_repeat(uf: &UnionFind<Size>, n: usize) -> UnionFind<Size> {
        let mut uf = uf.clone();
        for i in 1 .. uf.size() {
            for _ in 0..n {
                uf.find(0, i);
            }
        }
        uf
    }

    #[bench]
    fn bench_find_short_trail_1_interleave(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_short_trail(&mut uf);
        bencher.iter(|| find_interleave(&uf, 1));
    }
    #[bench]
    fn bench_find_long_trail_1_interleave(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_long_trail(&mut uf);
        bencher.iter(|| find_interleave(&uf, 1));
    }
    #[bench]
    fn bench_find_short_trail_1_repeat(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_short_trail(&mut uf);
        bencher.iter(|| find_repeat(&uf, 1));
    }
    #[bench]
    fn bench_find_long_trail_1_repeat(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_long_trail(&mut uf);
        bencher.iter(|| find_repeat(&uf, 1));
    }

    #[bench]
    fn bench_find_short_trail_10_interleave(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_short_trail(&mut uf);
        bencher.iter(|| find_interleave(&uf, 10));
    }
    #[bench]
    fn bench_find_long_trail_10_interleave(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_long_trail(&mut uf);
        bencher.iter(|| find_interleave(&uf, 10));
    }
    #[bench]
    fn bench_find_short_trail_10_repeat(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_short_trail(&mut uf);
        bencher.iter(|| find_repeat(&uf, 10));
    }
    #[bench]
    fn bench_find_long_trail_10_repeat(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_long_trail(&mut uf);
        bencher.iter(|| find_repeat(&uf, 10));
    }

    #[bench]
    fn bench_find_short_trail_100_interleave(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_short_trail(&mut uf);
        bencher.iter(|| find_interleave(&uf, 100));
    }
    #[bench]
    fn bench_find_long_trail_100_interleave(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_long_trail(&mut uf);
        bencher.iter(|| find_interleave(&uf, 100));
    }
    #[bench]
    fn bench_find_short_trail_100_repeat(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_short_trail(&mut uf);
        bencher.iter(|| find_repeat(&uf, 100));
    }
    #[bench]
    fn bench_find_long_trail_100_repeat(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_long_trail(&mut uf);
        bencher.iter(|| find_repeat(&uf, 100));
    }

    #[bench]
    fn bench_find_short_trail_1000_interleave(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_short_trail(&mut uf);
        bencher.iter(|| find_interleave(&uf, 1000));
    }
    #[bench]
    fn bench_find_long_trail_1000_interleave(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_long_trail(&mut uf);
        bencher.iter(|| find_interleave(&uf, 1000));
    }
    #[bench]
    fn bench_find_short_trail_1000_repeat(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_short_trail(&mut uf);
        bencher.iter(|| find_repeat(&uf, 1000));
    }
    #[bench]
    fn bench_find_long_trail_1000_repeat(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_long_trail(&mut uf);
        bencher.iter(|| find_repeat(&uf, 1000));
    }
}
<commit_msg>some performance improvement<commit_after>//! Struct and methods for union-find operation.

#![warn(bad_style, missing_docs,
        unused, unused_extern_crates, unused_import_braces,
        unused_qualifications, unused_results)]

#![cfg_attr(all(test, feature = "nightly"), feature(test))]

use std::{mem, usize};
use std::default::Default;
use std::iter::{IntoIterator, FromIterator};

#[derive(Clone, Debug)]
enum UFNode<T> {
    Key(usize),
    Value(T)
}

impl<T> UFNode<T> {
    fn get(&self) -> &T {
        match self {
            &UFNode::Value(ref val) => val,
            &UFNode::Key(_) => panic!()
        }
    }
    fn get_mut(&mut self) -> &mut T {
        match self {
            &mut UFNode::Value(ref mut val) => val,
            &mut UFNode::Key(_) => panic!()
        }
    }
    fn unwrap(self) -> T {
        match self {
            UFNode::Value(val) => val,
            UFNode::Key(_) => panic!()
        }
    }
}

/// The value that can be contained with `UFValue`.
pub trait UFValue: Sized {
    /// Merge two value into one.
    ///
    /// This is used by `UnionFind::union` operation.
    fn merge(lval: Self, rval: Self) -> Merge<Self>;
}

/// Return value of the `UFValue::merege`
#[allow(missing_docs)]
pub enum Merge<T> {
    Left(T), Right(T)
}

/// Reperesents the size of the group.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct Size(usize);

impl UFValue for Size {
    fn merge(Size(lval): Size, Size(rval): Size) -> Merge<Size> {
        if lval >= rval {
            Merge::Left(Size(lval + rval))
        } else {
            Merge::Right(Size(lval + rval))
        }
    }
}

impl Default for Size {
    fn default() -> Size { Size(1) }
}

/// Struct for union-find operation.
#[derive(Clone, Debug)]
pub struct UnionFind<V = Size> {
    data: Vec<UFNode<V>>
}

impl<T: UFValue = Size> UnionFind<T> {
    /// Creates empty `UnionFind` struct.
    #[inline]
    pub fn new(len: usize) -> UnionFind<T>
        where T: Default
    {
        UnionFind {
            data: (0 .. len)
                .map(|_| UFNode::Value(Default::default()))
                .collect()
        }
    }

    /// Returns the size of `self`.
    #[inline]
    pub fn size(&self) -> usize { self.data.len() }

    /// Join two sets that contains given keys (Union operation).
    ///
    /// Returns `true` if these keys are belonged to different sets.
    #[inline]
    pub fn union(&mut self, key0: usize, key1: usize) -> bool {
        let k0 = self.get_key(key0);
        let k1 = self.get_key(key1);
        if k0 == k1 { return false; }

        // Temporary replace with dummy to move out the elements of the vector.
        let v0 = mem::replace(&mut self.data[k0], UFNode::Key(usize::MAX)).unwrap();
        let v1 = mem::replace(&mut self.data[k1], UFNode::Key(usize::MAX)).unwrap();

        match UFValue::merge(v0, v1) {
            Merge::Left(val) => {
                self.data[k0] = UFNode::Value(val);
                self.data[k1] = UFNode::Key(k0);
            }
            Merge::Right(val) => {
                self.data[k1] = UFNode::Value(val);
                self.data[k0] = UFNode::Key(k1);
            }
        }

        true
    }

    /// Returns `true` if two keys contained by the same set (find operation).
    #[inline]
    pub fn find(&mut self, key0: usize, key1: usize) -> bool {
         self.get_key(key0) == self.get_key(key1)
    }

    /// Returns the reference to the value of the set that the key belongs to.
    #[inline]
    pub fn get(&mut self, key: usize) -> &T {
        let root_key = self.get_key(key);
        self.data[root_key].get()
    }

    /// Returns the mutable reference to the value of the set that the key belongs to.
    #[inline]
    pub fn get_mut(&mut self, key: usize) -> &mut T {
        let root_key = self.get_key(key);
        self.data[root_key].get_mut()
    }

    fn get_key(&mut self, key: usize) -> usize {
        let mut cur_key = key;
        loop {
            match self.data[cur_key] {
                UFNode::Value(_) => {
                    if key != cur_key {
                        self.data[key] = UFNode::Key(cur_key);
                    }
                    return cur_key;
                }
                UFNode::Key(k) => {
                    cur_key = k;
                }
            }
        }
    }
}

impl<A: UFValue> FromIterator<A> for UnionFind<A> {
    #[inline]
    fn from_iter<T: IntoIterator<Item=A>>(iterator: T) -> UnionFind<A> {
        UnionFind { data: iterator.into_iter().map(UFNode::Value).collect() }
    }
}

#[cfg(test)]
mod tests {
    use super::{UnionFind, Size};

    #[test]
    fn test_union_find() {
        let mut uf = UnionFind::new(100);
        assert_eq!(&Size(1), uf.get(0));
        assert_eq!(&Size(1), uf.get(1));
        assert!(!uf.find(0, 1));
        assert!(!uf.find(1, 2));
        assert!(uf.union(0, 1));
        assert!(uf.find(0, 1));
        assert_eq!(&Size(2), uf.get(0));
        assert_eq!(&Size(2), uf.get(1));
        assert_eq!(&Size(1), uf.get(2));
        assert!(!uf.union(0, 1));
        assert_eq!(&Size(2), uf.get(0));
        assert_eq!(&Size(2), uf.get(1));
        assert_eq!(&Size(1), uf.get(2));
        assert!(uf.union(1, 2));
        assert_eq!(&Size(3), uf.get(0));
        assert_eq!(&Size(3), uf.get(1));
        assert_eq!(&Size(3), uf.get(2));
        assert!(uf.find(0, 1));
        assert!(uf.find(2, 1));
    }
}

#[cfg(all(test, feature = "nightly"))]
mod bench {
    extern crate test;
    extern crate rand;

    use self::test::Bencher;
    use self::rand::distributions::{IndependentSample, Range};
    use super::{UnionFind, Size};

    fn union_short_trail(uf: &mut UnionFind<Size>) {
        for i in 1 .. uf.size() {
            uf.union(0, i);
        }
    }

    fn union_long_trail(uf: &mut UnionFind<Size>) {
        let mut rng = rand::thread_rng();
        let between = Range::new(0, uf.size());

        for _ in 0..uf.size() {
            let a = between.ind_sample(&mut rng);
            let b = between.ind_sample(&mut rng);
            uf.union(a, b);
       }
    }

    #[bench]
    fn bench_union_short_trail(bencher: &mut Bencher) {
        bencher.iter(|| {
            let mut uf = UnionFind::<Size>::new(1024);
            union_short_trail(&mut uf);
        })
    }

    #[bench]
    fn bench_union_long_trail(bencher: &mut Bencher) {
        bencher.iter(|| {
            let mut uf = UnionFind::<Size>::new(1024);
            union_long_trail(&mut uf);
        })
    }

    fn find_interleave(uf: &UnionFind<Size>, n: usize) -> UnionFind<Size> {
        let mut uf = uf.clone();
        for _ in 0..n {
            for i in 1 .. uf.size() {
                uf.find(0, i);
            }
        }
        uf
    }

    fn find_repeat(uf: &UnionFind<Size>, n: usize) -> UnionFind<Size> {
        let mut uf = uf.clone();
        for i in 1 .. uf.size() {
            for _ in 0..n {
                uf.find(0, i);
            }
        }
        uf
    }

    #[bench]
    fn bench_find_short_trail_1_interleave(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_short_trail(&mut uf);
        bencher.iter(|| find_interleave(&uf, 1));
    }
    #[bench]
    fn bench_find_long_trail_1_interleave(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_long_trail(&mut uf);
        bencher.iter(|| find_interleave(&uf, 1));
    }
    #[bench]
    fn bench_find_short_trail_1_repeat(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_short_trail(&mut uf);
        bencher.iter(|| find_repeat(&uf, 1));
    }
    #[bench]
    fn bench_find_long_trail_1_repeat(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_long_trail(&mut uf);
        bencher.iter(|| find_repeat(&uf, 1));
    }

    #[bench]
    fn bench_find_short_trail_10_interleave(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_short_trail(&mut uf);
        bencher.iter(|| find_interleave(&uf, 10));
    }
    #[bench]
    fn bench_find_long_trail_10_interleave(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_long_trail(&mut uf);
        bencher.iter(|| find_interleave(&uf, 10));
    }
    #[bench]
    fn bench_find_short_trail_10_repeat(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_short_trail(&mut uf);
        bencher.iter(|| find_repeat(&uf, 10));
    }
    #[bench]
    fn bench_find_long_trail_10_repeat(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_long_trail(&mut uf);
        bencher.iter(|| find_repeat(&uf, 10));
    }

    #[bench]
    fn bench_find_short_trail_100_interleave(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_short_trail(&mut uf);
        bencher.iter(|| find_interleave(&uf, 100));
    }
    #[bench]
    fn bench_find_long_trail_100_interleave(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_long_trail(&mut uf);
        bencher.iter(|| find_interleave(&uf, 100));
    }
    #[bench]
    fn bench_find_short_trail_100_repeat(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_short_trail(&mut uf);
        bencher.iter(|| find_repeat(&uf, 100));
    }
    #[bench]
    fn bench_find_long_trail_100_repeat(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_long_trail(&mut uf);
        bencher.iter(|| find_repeat(&uf, 100));
    }

    #[bench]
    fn bench_find_short_trail_1000_interleave(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_short_trail(&mut uf);
        bencher.iter(|| find_interleave(&uf, 1000));
    }
    #[bench]
    fn bench_find_long_trail_1000_interleave(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_long_trail(&mut uf);
        bencher.iter(|| find_interleave(&uf, 1000));
    }
    #[bench]
    fn bench_find_short_trail_1000_repeat(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_short_trail(&mut uf);
        bencher.iter(|| find_repeat(&uf, 1000));
    }
    #[bench]
    fn bench_find_long_trail_1000_repeat(bencher: &mut Bencher) {
        let mut uf = UnionFind::<Size>::new(1024);
        union_long_trail(&mut uf);
        bencher.iter(|| find_repeat(&uf, 1000));
    }
}
<|endoftext|>


<commit_before>//! [![github]](https://github.com/dtolnay/serde-yaml) [![crates-io]](https://crates.io/crates/serde-yaml) [![docs-rs]](https://docs.rs/serde-yaml)
//!
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K
//!
//!

//!
//! This crate is a Rust library for using the [Serde] serialization framework
//! with data in [YAML] file format.
//!
//! This library does not reimplement a YAML parser; it uses [yaml-rust] which
//! is a pure Rust YAML 1.2 implementation.
//!
//! [Serde]: https://github.com/serde-rs/serde
//! [YAML]: https://yaml.org/
//! [yaml-rust]: https://github.com/chyh1990/yaml-rust
//!
//! # Examples
//!
//! ```
//! use std::collections::BTreeMap;
//!
//! fn main() -> Result<(), serde_yaml::Error> {
//!     // You have some type.
//!     let mut map = BTreeMap::new();
//!     map.insert("x".to_string(), 1.0);
//!     map.insert("y".to_string(), 2.0);
//!
//!     // Serialize it to a YAML string.
//!     let s = serde_yaml::to_string(&map)?;
//!     assert_eq!(s, "---\nx: 1.0\ny: 2.0\n");
//!
//!     // Deserialize it back to a Rust type.
//!     let deserialized_map: BTreeMap<String, f64> = serde_yaml::from_str(&s)?;
//!     assert_eq!(map, deserialized_map);
//!     Ok(())
//! }
//! ```
//!
//! ## Using Serde derive
//!
//! It can also be used with Serde's serialization code generator `serde_derive` to
//! handle structs and enums defined in your own program.
//!
//! ```
//! # use serde_derive::{Serialize, Deserialize};
//! use serde::{Serialize, Deserialize};
//!
//! #[derive(Debug, PartialEq, Serialize, Deserialize)]
//! struct Point {
//!     x: f64,
//!     y: f64,
//! }
//!
//! fn main() -> Result<(), serde_yaml::Error> {
//!     let point = Point { x: 1.0, y: 2.0 };
//!
//!     let s = serde_yaml::to_string(&point)?;
//!     assert_eq!(s, "---\nx: 1.0\ny: 2.0\n");
//!
//!     let deserialized_point: Point = serde_yaml::from_str(&s)?;
//!     assert_eq!(point, deserialized_point);
//!     Ok(())
//! }
//! ```

#![doc(html_root_url = "https://docs.rs/serde_yaml/0.8.18")]
#![deny(missing_docs)]
// Suppressed clippy_pedantic lints
#![allow(
    // private Deserializer::next
    clippy::should_implement_trait,
    // things are often more readable this way
    clippy::cast_lossless,
    clippy::if_not_else,
    clippy::match_same_arms,
    clippy::module_name_repetitions,
    clippy::needless_pass_by_value,
    clippy::option_if_let_else,
    clippy::redundant_else,
    clippy::single_match_else,
    // code is acceptable
    clippy::cast_possible_wrap,
    clippy::cast_precision_loss,
    // noisy
    clippy::missing_errors_doc,
    clippy::must_use_candidate,
)]

pub use crate::de::{from_reader, from_slice, from_str, Deserializer};
pub use crate::error::{Error, Location, Result};
pub use crate::ser::{to_string, to_vec, to_writer, Serializer};
pub use crate::value::{from_value, to_value, Index, Number, Sequence, Value};

#[doc(inline)]
pub use crate::mapping::Mapping;

/// Entry points for deserializing with pre-existing state.
///
/// These functions are only exposed this way because we don't yet expose a
/// Deserializer type. Data formats that have a public Deserializer should not
/// copy these signatures.
pub mod seed {
    pub use super::de::{from_reader_seed, from_slice_seed, from_str_seed};
}

mod de;
mod error;
pub mod mapping;
mod number;
mod path;
mod ser;
mod value;
<commit_msg>Ignore items_after_statements Clippy pedantic lint<commit_after>//! [![github]](https://github.com/dtolnay/serde-yaml) [![crates-io]](https://crates.io/crates/serde-yaml) [![docs-rs]](https://docs.rs/serde-yaml)
//!
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K
//!
//!

//!
//! This crate is a Rust library for using the [Serde] serialization framework
//! with data in [YAML] file format.
//!
//! This library does not reimplement a YAML parser; it uses [yaml-rust] which
//! is a pure Rust YAML 1.2 implementation.
//!
//! [Serde]: https://github.com/serde-rs/serde
//! [YAML]: https://yaml.org/
//! [yaml-rust]: https://github.com/chyh1990/yaml-rust
//!
//! # Examples
//!
//! ```
//! use std::collections::BTreeMap;
//!
//! fn main() -> Result<(), serde_yaml::Error> {
//!     // You have some type.
//!     let mut map = BTreeMap::new();
//!     map.insert("x".to_string(), 1.0);
//!     map.insert("y".to_string(), 2.0);
//!
//!     // Serialize it to a YAML string.
//!     let s = serde_yaml::to_string(&map)?;
//!     assert_eq!(s, "---\nx: 1.0\ny: 2.0\n");
//!
//!     // Deserialize it back to a Rust type.
//!     let deserialized_map: BTreeMap<String, f64> = serde_yaml::from_str(&s)?;
//!     assert_eq!(map, deserialized_map);
//!     Ok(())
//! }
//! ```
//!
//! ## Using Serde derive
//!
//! It can also be used with Serde's serialization code generator `serde_derive` to
//! handle structs and enums defined in your own program.
//!
//! ```
//! # use serde_derive::{Serialize, Deserialize};
//! use serde::{Serialize, Deserialize};
//!
//! #[derive(Debug, PartialEq, Serialize, Deserialize)]
//! struct Point {
//!     x: f64,
//!     y: f64,
//! }
//!
//! fn main() -> Result<(), serde_yaml::Error> {
//!     let point = Point { x: 1.0, y: 2.0 };
//!
//!     let s = serde_yaml::to_string(&point)?;
//!     assert_eq!(s, "---\nx: 1.0\ny: 2.0\n");
//!
//!     let deserialized_point: Point = serde_yaml::from_str(&s)?;
//!     assert_eq!(point, deserialized_point);
//!     Ok(())
//! }
//! ```

#![doc(html_root_url = "https://docs.rs/serde_yaml/0.8.18")]
#![deny(missing_docs)]
// Suppressed clippy_pedantic lints
#![allow(
    // private Deserializer::next
    clippy::should_implement_trait,
    // things are often more readable this way
    clippy::cast_lossless,
    clippy::if_not_else,
    clippy::match_same_arms,
    clippy::module_name_repetitions,
    clippy::needless_pass_by_value,
    clippy::option_if_let_else,
    clippy::redundant_else,
    clippy::single_match_else,
    // code is acceptable
    clippy::cast_possible_wrap,
    clippy::cast_precision_loss,
    clippy::items_after_statements,
    // noisy
    clippy::missing_errors_doc,
    clippy::must_use_candidate,
)]

pub use crate::de::{from_reader, from_slice, from_str, Deserializer};
pub use crate::error::{Error, Location, Result};
pub use crate::ser::{to_string, to_vec, to_writer, Serializer};
pub use crate::value::{from_value, to_value, Index, Number, Sequence, Value};

#[doc(inline)]
pub use crate::mapping::Mapping;

/// Entry points for deserializing with pre-existing state.
///
/// These functions are only exposed this way because we don't yet expose a
/// Deserializer type. Data formats that have a public Deserializer should not
/// copy these signatures.
pub mod seed {
    pub use super::de::{from_reader_seed, from_slice_seed, from_str_seed};
}

mod de;
mod error;
pub mod mapping;
mod number;
mod path;
mod ser;
mod value;
<|endoftext|>


<commit_before>#![crate_name = "amethyst"]
#![crate_type = "lib"]
#![doc(html_logo_url = "http://tinyurl.com/hgsb45k")]

//! Amethyst is a free and open source game engine written in idiomatic
//! [Rust][rs] for building video games and interactive multimedia applications.
//! The source code is available for download on [GitHub][gh]. See the
//! [online book][bk] for a complete guide to using Amethyst.
//!
//! [rs]: https://www.rust-lang.org/
//! [gh]: https://github.com/ebkalderon/amethyst
//! [bk]: http://ebkalderon.github.io/amethyst/
//!
//! This project is a work in progress and is very incomplete. Pardon the dust!
//!
//! # Example
//!
//! ```ignore
//! extern crate amethyst;
//!
//! use amethyst::*;
//!
//! struct GameState;
//!
//! impl State for GameState {
//!     fn handle_events(&mut self, events: &Vec<Event>) -> Trans {
//!         for e in events {
//!             match e {
//!                 Event::Closed => Trans::Quit,
//!                 Event::Resized(x, y) => println!("x: {}, y: {}", x, y),
//!                 Event::KeyPressed(k) => if k == Key::Esc { Trans::Quit },
//!             }
//!         }
//!         Trans::None
//!     }
//!
//!     fn update(&mut self, _delta: Duration) -> Trans {
//!         println!("Computing some more whoop-ass...");
//!         Trans::None
//!     }
//! }
//!
//! fn main() {
//!     let mut game = Application::new(GameState);
//!     game.run();
//! }
//! ```

extern crate amethyst_engine;
extern crate amethyst_renderer;

pub use amethyst_engine as engine;
pub use amethyst_renderer as renderer;
<commit_msg>use idiomatic &[T] in doc comments<commit_after>#![crate_name = "amethyst"]
#![crate_type = "lib"]
#![doc(html_logo_url = "http://tinyurl.com/hgsb45k")]

//! Amethyst is a free and open source game engine written in idiomatic
//! [Rust][rs] for building video games and interactive multimedia applications.
//! The source code is available for download on [GitHub][gh]. See the
//! [online book][bk] for a complete guide to using Amethyst.
//!
//! [rs]: https://www.rust-lang.org/
//! [gh]: https://github.com/ebkalderon/amethyst
//! [bk]: http://ebkalderon.github.io/amethyst/
//!
//! This project is a work in progress and is very incomplete. Pardon the dust!
//!
//! # Example
//!
//! ```ignore
//! extern crate amethyst;
//!
//! use amethyst::*;
//!
//! struct GameState;
//!
//! impl State for GameState {
//!     fn handle_events(&mut self, events: &[Event]) -> Trans {
//!         for e in events {
//!             match e {
//!                 Event::Closed => Trans::Quit,
//!                 Event::Resized(x, y) => println!("x: {}, y: {}", x, y),
//!                 Event::KeyPressed(k) => if k == Key::Esc { Trans::Quit },
//!             }
//!         }
//!         Trans::None
//!     }
//!
//!     fn update(&mut self, _delta: Duration) -> Trans {
//!         println!("Computing some more whoop-ass...");
//!         Trans::None
//!     }
//! }
//!
//! fn main() {
//!     let mut game = Application::new(GameState);
//!     game.run();
//! }
//! ```

extern crate amethyst_engine;
extern crate amethyst_renderer;

pub use amethyst_engine as engine;
pub use amethyst_renderer as renderer;
<|endoftext|>


<commit_before>#![deny(missing_docs)]

//! A Glutin window back-end for the Piston game engine.

extern crate glutin;
extern crate gl;
extern crate window;
extern crate shader_version;
extern crate input;
#[macro_use]
extern crate quack;

// External crates.
use input::{
    keyboard,
    MouseButton,
    Button,
    Input,
    Motion,
};
use window::{
    WindowSettings,
    ShouldClose, Size, PollEvent, SwapBuffers,
    //CaptureCursor,
    DrawSize, Title,
    ExitOnEsc
};
use shader_version::opengl::OpenGL;
use quack::Associative;

/// Contains stuff for game window.
pub struct GlutinWindow {
    /// The window.
    pub window: glutin::Window,
    // Used to compute relative mouse movement.
    last_mouse_pos: Option<(f64, f64)>,
    // The back-end does not remember the title.
    title: String,
    exit_on_esc: bool,
    should_close: bool,
}

impl GlutinWindow {
    /// Creates a new game window for GLFW.
    pub fn new(opengl: OpenGL, settings: WindowSettings) -> GlutinWindow {
        let (major, minor) = opengl.get_major_minor();
        let mut builder = glutin::WindowBuilder::new()
            .with_dimensions(settings.size[0], settings.size[1])
            .with_gl_version((major as u32, minor as u32))
            .with_title(settings.title.clone());
        if settings.samples != 0 {
            builder = builder.with_multisampling(settings.samples as u16);
        }
        if settings.fullscreen {
            builder = builder.with_fullscreen(glutin::get_primary_monitor());
        }
        let window = builder
            .build().unwrap();
        unsafe { window.make_current(); }

        // Load the OpenGL function pointers
        gl::load_with(|s| window.get_proc_address(s));

        GlutinWindow {
            window: window,
            last_mouse_pos: None,
            title: settings.title,
            exit_on_esc: settings.exit_on_esc,
            should_close: false,
        }
    }

    fn poll_event(&mut self) -> Option<Input> {
        use glutin::Event as E;
        use input::Input;

        if let Some((x, y)) = self.last_mouse_pos {
            self.last_mouse_pos = None;
            return Some(Input::Move(input::Motion::MouseRelative(x, y)));
        }

        match self.window.poll_events().next() {
            None => None,
            Some(E::Resized(w, h)) =>
                Some(Input::Resize(w, h)),
            Some(E::ReceivedCharacter(ch)) => {
                let string = match ch {
                    // Ignore control characters and return ascii for Text event (like sdl2).
                    '\u{7f}' | // Delete
                    '\u{1b}' | // Escape
                    '\u{8}'  | // Backspace
                    '\r' | '\n' | '\t' => "".to_string(),
                    _ => ch.to_string()
                };
                Some(Input::Text(string))
            },
            Some(E::Focused(focused)) =>
                Some(Input::Focus(focused)),
            Some(E::KeyboardInput(glutin::ElementState::Pressed, _, Some(key))) => {
                let piston_key = map_key(key);
                if let (true, input::keyboard::Key::Escape) = (self.exit_on_esc, piston_key) {
                    self.should_close = true;
                }
                Some(Input::Press(Button::Keyboard(piston_key)))
            },
            Some(E::KeyboardInput(glutin::ElementState::Released, _, Some(key))) =>
                Some(Input::Release(Button::Keyboard(map_key(key)))),
            Some(E::MouseMoved((x, y))) => {
                self.last_mouse_pos = Some((x as f64, y as f64));
                Some(Input::Move(
                    Motion::MouseCursor(x as f64, y as f64)))
            }
            Some(E::MouseWheel(y)) =>
                Some(Input::Move(
                    Motion::MouseScroll(0.0, y as f64))),
            Some(E::MouseInput(glutin::ElementState::Pressed, button)) =>
                Some(Input::Press(Button::Mouse(map_mouse(button)))),
            Some(E::MouseInput(glutin::ElementState::Released, button)) =>
                Some(Input::Release(Button::Mouse(map_mouse(button)))),
            _ => None,
        }
    }

    /*
    fn capture_cursor(&mut self, enabled: bool) {

    }
    */
}

quack! {
obj: GlutinWindow[]
get:
    fn () -> Size [] {
        if let Some((w, h)) = obj.window.get_outer_size() {
            Size([w, h])
        } else {
            Size([0, 0])
        }
    }
    fn () -> ShouldClose [] { ShouldClose(obj.window.should_close() || obj.should_close) }
    fn () -> DrawSize [] {
        if let Some((w, h)) = obj.window.get_inner_size() {
            DrawSize([w, h])
        } else {
            DrawSize([0, 0])
        }
    }
    fn () -> Title [] { Title(obj.title.clone()) }
    fn () -> ExitOnEsc [] { ExitOnEsc(obj.exit_on_esc) }
set:
    // fn (val: CaptureCursor) [] {}
    // fn (val: ShouldClose) [] {}
    fn (val: Title) [] {
        obj.title = val.0;
        obj.window.set_title(&obj.title);
    }
    fn (val: ExitOnEsc) [] { obj.exit_on_esc = val.0; }
action:
    fn (__: PollEvent) -> Option<Input> [] { obj.poll_event() }
    fn (__: SwapBuffers) -> () [] { obj.window.swap_buffers(); }
}

impl Associative for (PollEvent, GlutinWindow) {
    type Type = Input;
}

/// Maps Glutin's key to Piston's key.
pub fn map_key(keycode: glutin::VirtualKeyCode) -> keyboard::Key {
    use input::keyboard::Key;
    use glutin::VirtualKeyCode as K;

    match keycode {
        K::Key0 => Key::D0,
        K::Key1 => Key::D1,
        K::Key2 => Key::D2,
        K::Key3 => Key::D3,
        K::Key4 => Key::D4,
        K::Key5 => Key::D5,
        K::Key6 => Key::D6,
        K::Key7 => Key::D7,
        K::Key8 => Key::D8,
        K::Key9 => Key::D9,
        K::A => Key::A,
        K::B => Key::B,
        K::C => Key::C,
        K::D => Key::D,
        K::E => Key::E,
        K::F => Key::F,
        K::G => Key::G,
        K::H => Key::H,
        K::I => Key::I,
        K::J => Key::J,
        K::K => Key::K,
        K::L => Key::L,
        K::M => Key::M,
        K::N => Key::N,
        K::O => Key::O,
        K::P => Key::P,
        K::Q => Key::Q,
        K::R => Key::R,
        K::S => Key::S,
        K::T => Key::T,
        K::U => Key::U,
        K::V => Key::V,
        K::W => Key::W,
        K::X => Key::X,
        K::Y => Key::Y,
        K::Z => Key::Z,
        K::Apostrophe => Key::Unknown,
        K::Backslash => Key::Backslash,
        K::Back => Key::Backspace,
        // K::CapsLock => Key::CapsLock,
        K::Delete => Key::Delete,
        K::Comma => Key::Comma,
        K::Down => Key::Down,
        K::End => Key::End,
        K::Return => Key::Return,
        K::Equals => Key::Equals,
        K::Escape => Key::Escape,
        K::F1 => Key::F1,
        K::F2 => Key::F2,
        K::F3 => Key::F3,
        K::F4 => Key::F4,
        K::F5 => Key::F5,
        K::F6 => Key::F6,
        K::F7 => Key::F7,
        K::F8 => Key::F8,
        K::F9 => Key::F9,
        K::F10 => Key::F10,
        K::F11 => Key::F11,
        K::F12 => Key::F12,
        K::F13 => Key::F13,
        K::F14 => Key::F14,
        K::F15 => Key::F15,
        // K::F16 => Key::F16,
        // K::F17 => Key::F17,
        // K::F18 => Key::F18,
        // K::F19 => Key::F19,
        // K::F20 => Key::F20,
        // K::F21 => Key::F21,
        // K::F22 => Key::F22,
        // K::F23 => Key::F23,
        // K::F24 => Key::F24,
        // Possibly next code.
        // K::F25 => Key::Unknown,
        K::Numpad0 => Key::NumPad0,
        K::Numpad1 => Key::NumPad1,
        K::Numpad2 => Key::NumPad2,
        K::Numpad3 => Key::NumPad3,
        K::Numpad4 => Key::NumPad4,
        K::Numpad5 => Key::NumPad5,
        K::Numpad6 => Key::NumPad6,
        K::Numpad7 => Key::NumPad7,
        K::Numpad8 => Key::NumPad8,
        K::Numpad9 => Key::NumPad9,
        K::NumpadComma => Key::NumPadDecimal,
        K::Divide => Key::NumPadDivide,
        K::Multiply => Key::NumPadMultiply,
        K::Subtract => Key::NumPadMinus,
        K::Add => Key::NumPadPlus,
        K::NumpadEnter => Key::NumPadEnter,
        K::NumpadEquals => Key::NumPadEquals,
        K::LShift => Key::LShift,
        K::LControl => Key::LCtrl,
        K::LAlt => Key::LAlt,
        K::LMenu => Key::LGui,
        K::RShift => Key::RShift,
        K::RControl => Key::RCtrl,
        K::RAlt => Key::RAlt,
        K::RMenu => Key::RGui,
        // Map to backslash?
        // K::GraveAccent => Key::Unknown,
        K::Home => Key::Home,
        K::Insert => Key::Insert,
        K::Left => Key::Left,
        K::LBracket => Key::LeftBracket,
        // K::Menu => Key::Menu,
        K::Minus => Key::Minus,
        K::Numlock => Key::NumLockClear,
        K::PageDown => Key::PageDown,
        K::PageUp => Key::PageUp,
        K::Pause => Key::Pause,
        K::Period => Key::Period,
        // K::PrintScreen => Key::PrintScreen,
        K::Right => Key::Right,
        K::RBracket => Key::RightBracket,
        // K::ScrollLock => Key::ScrollLock,
        K::Semicolon => Key::Semicolon,
        K::Slash => Key::Slash,
        K::Space => Key::Space,
        K::Tab => Key::Tab,
        K::Up => Key::Up,
        // K::World1 => Key::Unknown,
        // K::World2 => Key::Unknown,
        _ => Key::Unknown,
    }
}

/// Maps Glutin's mouse button to Piston's mouse button.
pub fn map_mouse(mouse_button: glutin::MouseButton) -> MouseButton {
    use glutin::MouseButton as M;

    match mouse_button {
        M::Left => MouseButton::Left,
        M::Right => MouseButton::Right,
        M::Middle => MouseButton::Middle,
        M::Other(0) => MouseButton::X1,
        M::Other(1) => MouseButton::X2,
        M::Other(2) => MouseButton::Button6,
        M::Other(3) => MouseButton::Button7,
        M::Other(4) => MouseButton::Button8,
        _ => MouseButton::Unknown
    }
}
<commit_msg>Fixed `Size`<commit_after>#![deny(missing_docs)]

//! A Glutin window back-end for the Piston game engine.

extern crate glutin;
extern crate gl;
extern crate window;
extern crate shader_version;
extern crate input;
#[macro_use]
extern crate quack;

// External crates.
use input::{
    keyboard,
    MouseButton,
    Button,
    Input,
    Motion,
};
use window::{
    WindowSettings,
    ShouldClose, Size, PollEvent, SwapBuffers,
    //CaptureCursor,
    DrawSize, Title,
    ExitOnEsc
};
use shader_version::opengl::OpenGL;
use quack::Associative;

/// Contains stuff for game window.
pub struct GlutinWindow {
    /// The window.
    pub window: glutin::Window,
    // Used to compute relative mouse movement.
    last_mouse_pos: Option<(f64, f64)>,
    // The back-end does not remember the title.
    title: String,
    exit_on_esc: bool,
    should_close: bool,
}

impl GlutinWindow {
    /// Creates a new game window for GLFW.
    pub fn new(opengl: OpenGL, settings: WindowSettings) -> GlutinWindow {
        let (major, minor) = opengl.get_major_minor();
        let mut builder = glutin::WindowBuilder::new()
            .with_dimensions(settings.size[0], settings.size[1])
            .with_gl_version((major as u32, minor as u32))
            .with_title(settings.title.clone());
        if settings.samples != 0 {
            builder = builder.with_multisampling(settings.samples as u16);
        }
        if settings.fullscreen {
            builder = builder.with_fullscreen(glutin::get_primary_monitor());
        }
        let window = builder
            .build().unwrap();
        unsafe { window.make_current(); }

        // Load the OpenGL function pointers
        gl::load_with(|s| window.get_proc_address(s));

        GlutinWindow {
            window: window,
            last_mouse_pos: None,
            title: settings.title,
            exit_on_esc: settings.exit_on_esc,
            should_close: false,
        }
    }

    fn poll_event(&mut self) -> Option<Input> {
        use glutin::Event as E;
        use input::Input;

        if let Some((x, y)) = self.last_mouse_pos {
            self.last_mouse_pos = None;
            return Some(Input::Move(input::Motion::MouseRelative(x, y)));
        }

        match self.window.poll_events().next() {
            None => None,
            Some(E::Resized(w, h)) =>
                Some(Input::Resize(w, h)),
            Some(E::ReceivedCharacter(ch)) => {
                let string = match ch {
                    // Ignore control characters and return ascii for Text event (like sdl2).
                    '\u{7f}' | // Delete
                    '\u{1b}' | // Escape
                    '\u{8}'  | // Backspace
                    '\r' | '\n' | '\t' => "".to_string(),
                    _ => ch.to_string()
                };
                Some(Input::Text(string))
            },
            Some(E::Focused(focused)) =>
                Some(Input::Focus(focused)),
            Some(E::KeyboardInput(glutin::ElementState::Pressed, _, Some(key))) => {
                let piston_key = map_key(key);
                if let (true, input::keyboard::Key::Escape) = (self.exit_on_esc, piston_key) {
                    self.should_close = true;
                }
                Some(Input::Press(Button::Keyboard(piston_key)))
            },
            Some(E::KeyboardInput(glutin::ElementState::Released, _, Some(key))) =>
                Some(Input::Release(Button::Keyboard(map_key(key)))),
            Some(E::MouseMoved((x, y))) => {
                self.last_mouse_pos = Some((x as f64, y as f64));
                Some(Input::Move(
                    Motion::MouseCursor(x as f64, y as f64)))
            }
            Some(E::MouseWheel(y)) =>
                Some(Input::Move(
                    Motion::MouseScroll(0.0, y as f64))),
            Some(E::MouseInput(glutin::ElementState::Pressed, button)) =>
                Some(Input::Press(Button::Mouse(map_mouse(button)))),
            Some(E::MouseInput(glutin::ElementState::Released, button)) =>
                Some(Input::Release(Button::Mouse(map_mouse(button)))),
            _ => None,
        }
    }

    /*
    fn capture_cursor(&mut self, enabled: bool) {

    }
    */
}

quack! {
obj: GlutinWindow[]
get:
    fn () -> Size [] {
        let f = obj.window.hidpi_factor();
        if let Some((w, h)) = obj.window.get_inner_size() {
            Size([(w as f32 / f) as u32, (h as f32 / f) as u32])
        } else {
            Size([0, 0])
        }
    }
    fn () -> ShouldClose [] { ShouldClose(obj.window.should_close() || obj.should_close) }
    fn () -> DrawSize [] {
        if let Some((w, h)) = obj.window.get_inner_size() {
            DrawSize([w, h])
        } else {
            DrawSize([0, 0])
        }
    }
    fn () -> Title [] { Title(obj.title.clone()) }
    fn () -> ExitOnEsc [] { ExitOnEsc(obj.exit_on_esc) }
set:
    // fn (val: CaptureCursor) [] {}
    // fn (val: ShouldClose) [] {}
    fn (val: Title) [] {
        obj.title = val.0;
        obj.window.set_title(&obj.title);
    }
    fn (val: ExitOnEsc) [] { obj.exit_on_esc = val.0; }
action:
    fn (__: PollEvent) -> Option<Input> [] { obj.poll_event() }
    fn (__: SwapBuffers) -> () [] { obj.window.swap_buffers(); }
}

impl Associative for (PollEvent, GlutinWindow) {
    type Type = Input;
}

/// Maps Glutin's key to Piston's key.
pub fn map_key(keycode: glutin::VirtualKeyCode) -> keyboard::Key {
    use input::keyboard::Key;
    use glutin::VirtualKeyCode as K;

    match keycode {
        K::Key0 => Key::D0,
        K::Key1 => Key::D1,
        K::Key2 => Key::D2,
        K::Key3 => Key::D3,
        K::Key4 => Key::D4,
        K::Key5 => Key::D5,
        K::Key6 => Key::D6,
        K::Key7 => Key::D7,
        K::Key8 => Key::D8,
        K::Key9 => Key::D9,
        K::A => Key::A,
        K::B => Key::B,
        K::C => Key::C,
        K::D => Key::D,
        K::E => Key::E,
        K::F => Key::F,
        K::G => Key::G,
        K::H => Key::H,
        K::I => Key::I,
        K::J => Key::J,
        K::K => Key::K,
        K::L => Key::L,
        K::M => Key::M,
        K::N => Key::N,
        K::O => Key::O,
        K::P => Key::P,
        K::Q => Key::Q,
        K::R => Key::R,
        K::S => Key::S,
        K::T => Key::T,
        K::U => Key::U,
        K::V => Key::V,
        K::W => Key::W,
        K::X => Key::X,
        K::Y => Key::Y,
        K::Z => Key::Z,
        K::Apostrophe => Key::Unknown,
        K::Backslash => Key::Backslash,
        K::Back => Key::Backspace,
        // K::CapsLock => Key::CapsLock,
        K::Delete => Key::Delete,
        K::Comma => Key::Comma,
        K::Down => Key::Down,
        K::End => Key::End,
        K::Return => Key::Return,
        K::Equals => Key::Equals,
        K::Escape => Key::Escape,
        K::F1 => Key::F1,
        K::F2 => Key::F2,
        K::F3 => Key::F3,
        K::F4 => Key::F4,
        K::F5 => Key::F5,
        K::F6 => Key::F6,
        K::F7 => Key::F7,
        K::F8 => Key::F8,
        K::F9 => Key::F9,
        K::F10 => Key::F10,
        K::F11 => Key::F11,
        K::F12 => Key::F12,
        K::F13 => Key::F13,
        K::F14 => Key::F14,
        K::F15 => Key::F15,
        // K::F16 => Key::F16,
        // K::F17 => Key::F17,
        // K::F18 => Key::F18,
        // K::F19 => Key::F19,
        // K::F20 => Key::F20,
        // K::F21 => Key::F21,
        // K::F22 => Key::F22,
        // K::F23 => Key::F23,
        // K::F24 => Key::F24,
        // Possibly next code.
        // K::F25 => Key::Unknown,
        K::Numpad0 => Key::NumPad0,
        K::Numpad1 => Key::NumPad1,
        K::Numpad2 => Key::NumPad2,
        K::Numpad3 => Key::NumPad3,
        K::Numpad4 => Key::NumPad4,
        K::Numpad5 => Key::NumPad5,
        K::Numpad6 => Key::NumPad6,
        K::Numpad7 => Key::NumPad7,
        K::Numpad8 => Key::NumPad8,
        K::Numpad9 => Key::NumPad9,
        K::NumpadComma => Key::NumPadDecimal,
        K::Divide => Key::NumPadDivide,
        K::Multiply => Key::NumPadMultiply,
        K::Subtract => Key::NumPadMinus,
        K::Add => Key::NumPadPlus,
        K::NumpadEnter => Key::NumPadEnter,
        K::NumpadEquals => Key::NumPadEquals,
        K::LShift => Key::LShift,
        K::LControl => Key::LCtrl,
        K::LAlt => Key::LAlt,
        K::LMenu => Key::LGui,
        K::RShift => Key::RShift,
        K::RControl => Key::RCtrl,
        K::RAlt => Key::RAlt,
        K::RMenu => Key::RGui,
        // Map to backslash?
        // K::GraveAccent => Key::Unknown,
        K::Home => Key::Home,
        K::Insert => Key::Insert,
        K::Left => Key::Left,
        K::LBracket => Key::LeftBracket,
        // K::Menu => Key::Menu,
        K::Minus => Key::Minus,
        K::Numlock => Key::NumLockClear,
        K::PageDown => Key::PageDown,
        K::PageUp => Key::PageUp,
        K::Pause => Key::Pause,
        K::Period => Key::Period,
        // K::PrintScreen => Key::PrintScreen,
        K::Right => Key::Right,
        K::RBracket => Key::RightBracket,
        // K::ScrollLock => Key::ScrollLock,
        K::Semicolon => Key::Semicolon,
        K::Slash => Key::Slash,
        K::Space => Key::Space,
        K::Tab => Key::Tab,
        K::Up => Key::Up,
        // K::World1 => Key::Unknown,
        // K::World2 => Key::Unknown,
        _ => Key::Unknown,
    }
}

/// Maps Glutin's mouse button to Piston's mouse button.
pub fn map_mouse(mouse_button: glutin::MouseButton) -> MouseButton {
    use glutin::MouseButton as M;

    match mouse_button {
        M::Left => MouseButton::Left,
        M::Right => MouseButton::Right,
        M::Middle => MouseButton::Middle,
        M::Other(0) => MouseButton::X1,
        M::Other(1) => MouseButton::X2,
        M::Other(2) => MouseButton::Button6,
        M::Other(3) => MouseButton::Button7,
        M::Other(4) => MouseButton::Button8,
        _ => MouseButton::Unknown
    }
}
<|endoftext|>