<commit_before>/*******************************************************************************
 *
 * kit/kernel/include/terminal.rs
 * - early text mode 80x25 terminal handler
 *
 * vim:ft=rust:ts=4:sw=4:et:tw=80
 *
 * Copyright (C) 2015, Devyn Cairns
 * Redistribution of this file is permitted under the terms of the simplified
 * BSD license. See LICENSE for more information.
 *
 ******************************************************************************/

use core::prelude::*;

use core::fmt;

#[derive(Copy)]
pub enum Color {
    Black        = 0,
    Blue         = 1,
    Green        = 2,
    Cyan         = 3,
    Red          = 4,
    Magenta      = 5,
    Brown        = 6,
    LightGrey    = 7,
    DarkGrey     = 8,
    LightBlue    = 9,
    LightGreen   = 10,
    LightCyan    = 11,
    LightRed     = 12,
    LightMagenta = 13,
    LightBrown   = 14,
    White        = 15,
}

/// A terminal.
pub trait Terminal: fmt::Write {
    fn reset(&mut self) -> fmt::Result;
    fn clear(&mut self) -> fmt::Result;

    fn get_cursor(&self) -> (usize, usize);
    fn set_cursor(&mut self, row: usize, col: usize) -> fmt::Result;

    fn get_color(&self) -> (Color, Color);
    fn set_color(&mut self, fg: Color, bg: Color) -> fmt::Result;

    fn put_raw_byte(&mut self,
                    byte: u8,
                    fg:   Color,
                    bg:   Color,
                    row:  usize,
                    col:  usize) -> fmt::Result;

    /// Does not flush.
    fn write_raw_byte(&mut self, byte: u8) -> fmt::Result;

    /// Does not flush.
    fn write_raw_bytes(&mut self, bytes: &[u8]) -> fmt::Result {
        for byte in bytes {
            try!(self.write_raw_byte(*byte));
        }

        Ok(())
    }

    fn flush(&mut self) -> fmt::Result;

    fn write_char(&mut self, ch: char) -> fmt::Result {
        let mut buf = [0u8, 4];

        try!(ch.encode_utf8(&mut buf).ok_or(fmt::Error));

        try!(self.write_raw_bytes(&buf));
        try!(self.flush());
        Ok(())
    }
}

/// Controls a VGA text-mode terminal.
pub struct Vga {
    width:  usize,
    height: usize,
    row:    usize,
    col:    usize,
    fg:     Color,
    bg:     Color,
    attr:   u8,
    buffer: *mut u16,
    port:   u16
}

impl Vga {
    pub unsafe fn new(width:  usize,
                      height: usize,
                      buffer: *mut u16,
                      port:   u16)
                      -> Vga {

        let mut vga = Vga {
            width:  width,
            height: height,
            row:    0,
            col:    0,
            fg:     Color::LightGrey,
            bg:     Color::Black,
            attr:   Vga::attr(Color::LightGrey, Color::Black),
            buffer: buffer,
            port:   port
        };

        vga.reset().unwrap();

        vga
    }

    pub fn color(c: Color) -> u8 {
        c as u8
    }

    pub fn attr(fg: Color, bg: Color) -> u8 {
        Vga::color(fg) | (Vga::color(bg) << 4)
    }

    fn update_attr(&mut self) {
        self.attr = Vga::attr(self.fg, self.bg);
    }

    fn update_cursor(&mut self) {
        unsafe fn outb(byte: u8, port: u16) {
            // FIXME: It seems like we have to do this due to a Rust bug where
            // the "a" and "d" constraints cause nothing to be generated. I
            // should file a bug report.
            asm!(concat!("mov $0, %al;\n",
                         "mov $1, %dx;\n",
                         "out %al, %dx")
                :
                : "r" (byte), "r" (port)
                : "rax", "rdx"
                : "volatile");
        }

        let pos: u16 = ((self.row * self.width) + self.col) as u16;

        unsafe {
            outb(0x0F,             self.port);
            outb(pos as u8,        self.port + 1);

            outb(0x0E,             self.port);
            outb((pos >> 8) as u8, self.port + 1);
        }
    }

    pub fn put(&mut self, byte: u8, attr: u8, row: usize, col: usize) {
        unsafe {
            *self.buffer.offset((row * self.width + col) as isize) =
                (byte as u16) | ((attr as u16) << 8);
        }
    }

    pub fn put_here(&mut self, byte: u8) {
        let (attr, row, col) = (self.attr, self.row, self.col);

        self.put(byte, attr, row, col)
    }

    fn new_line(&mut self) {
        // Clear to the end of the line.
        while self.col < self.width {
            self.put_here(' ' as u8);
            self.col += 1;
        }

        // Go to the next line, scrolling if necessary.
        self.col  = 0;
        self.row += 1;

        while self.row >= self.height {
            self.scroll();
            self.row -= 1;
        }

        self.update_cursor();
    }

    fn scroll(&mut self) {
        // Shift everything one line back.
        for row in 1..self.height {
            for col in 0..self.width {
                let index = (row * self.width + col) as isize;

                unsafe {
                    *self.buffer.offset(index - self.width as isize) =
                        *self.buffer.offset(index);
                }
            }
        }

        // Clear last line.
        let (attr, height) = (self.attr, self.height);

        for col in 0..self.width {
            self.put(' ' as u8, attr, height - 1, col);
        }
    }
}

impl Terminal for Vga {
    fn reset(&mut self) -> fmt::Result {
        self.fg = Color::LightGrey;
        self.bg = Color::Black;
        self.update_attr();
        self.clear()
    }

    fn clear(&mut self) -> fmt::Result {
        self.row = 0;
        self.col = 0;

        let attr = self.attr;

        for row in 0..self.height {
            for col in 0..self.width {
                self.put(' ' as u8, attr, row, col);
            }
        }

        Ok(())
    }

    fn get_cursor(&self) -> (usize, usize) {
        (self.row, self.col)
    }

    fn set_cursor(&mut self, row: usize, col: usize) -> fmt::Result {
        self.row = row;
        self.col = col;

        self.update_cursor();
        Ok(())
    }

    fn get_color(&self) -> (Color, Color) {
        (self.fg, self.bg)
    }

    fn set_color(&mut self, fg: Color, bg: Color) -> fmt::Result {
        self.fg = fg;
        self.bg = bg;
        self.update_attr();
        Ok(())
    }

    fn put_raw_byte(&mut self,
                    byte: u8,
                    fg:   Color,
                    bg:   Color,
                    row:  usize,
                    col:  usize) -> fmt::Result {

        self.put(byte, Vga::attr(fg, bg), row, col);
        Ok(())
    }

    fn write_raw_byte(&mut self, byte: u8) -> fmt::Result {
        match byte {
            0x0A /* newline */ => {
                self.new_line();
            },

            0x08 /* backspace */ => {
                if self.col > 0 {
                    self.col -= 1;
                }

                self.put_here(' ' as u8);
            },

            _ => {
                self.put_here(byte);

                if self.col + 1 >= self.width {
                    self.new_line();
                } else {
                    self.col += 1;
                }
            }
        }

        Ok(())
    }

    fn flush(&mut self) -> fmt::Result {
        self.update_cursor();
        Ok(())
    }
}

impl fmt::Write for Vga {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        try!(self.write_raw_bytes(s.as_bytes()));
        try!(self.flush());
        Ok(())
    }
}

static mut CONSOLE: Option<Vga> = None;

/// Get the current global console.
pub fn console() -> &'static mut Terminal {
    unsafe {
        if CONSOLE.is_none() {
            CONSOLE = Some(Vga::new(80, 25,
                                    0xffffffff800b8000 as *mut u16, 0x3d4));
        }

        CONSOLE.as_mut().unwrap()
    }
}

/// C (legacy) interface. See `kit/kernel/include/terminal.h`.
pub mod ffi {
    use super::*;

    use core::mem;
    use core::slice;
    use core::ptr::PtrExt;

    use libc::{c_char, size_t};

    #[no_mangle]
    pub extern fn terminal_initialize() {
        console().reset().unwrap();
    }

    #[no_mangle]
    pub extern fn terminal_clear() {
        console().clear().unwrap();
    }

    #[no_mangle]
    pub extern fn terminal_updatecursor() {
        console().flush().unwrap();
    }

    #[no_mangle]
    pub unsafe extern fn terminal_getcursor(row: *mut size_t, column: *mut size_t) {
        let (row_us, col_us) = console().get_cursor();

        *row    = row_us as size_t;
        *column = col_us as size_t;
    }

    #[no_mangle]
    pub extern fn terminal_setcursor(row: size_t, column: size_t) {
        console().set_cursor(row as usize, column as usize).unwrap();
    }

    #[repr(C)]
    #[derive(Copy)]
    pub enum VgaColor {
        Black        = 0,
        Blue         = 1,
        Green        = 2,
        Cyan         = 3,
        Red          = 4,
        Magenta      = 5,
        Brown        = 6,
        LightGrey    = 7,
        DarkGrey     = 8,
        LightBlue    = 9,
        LightGreen   = 10,
        LightCyan    = 11,
        LightRed     = 12,
        LightMagenta = 13,
        LightBrown   = 14,
        White        = 15,
    }

    impl VgaColor {
        pub fn from_color(color: Color) -> VgaColor {
            unsafe { mem::transmute(color as i32) }
        }

        pub fn to_color(self) -> Color {
            unsafe { mem::transmute(self as u8) }
        }
    }

    #[no_mangle]
    pub unsafe extern fn terminal_getcolor(fg: *mut VgaColor,
                                           bg: *mut VgaColor) {
        let (fg_c, bg_c) = console().get_color();

        *fg = VgaColor::from_color(fg_c);
        *bg = VgaColor::from_color(bg_c);
    }

    #[no_mangle]
    pub extern fn terminal_setcolor(fg: VgaColor, bg: VgaColor) {
        console().set_color(fg.to_color(), bg.to_color()).unwrap();
    }

    #[no_mangle]
    pub unsafe extern fn terminal_putentryat(c: c_char,
                                      color: u8,
                                      x: size_t,
                                      y: size_t) {

        let fg_v: VgaColor = mem::transmute((color & 0x0f) as i32);
        let bg_v: VgaColor = mem::transmute((color >> 4)   as i32);

        console()
            .put_raw_byte(c as u8,
                          fg_v.to_color(),
                          bg_v.to_color(),
                          y as usize,
                          x as usize)
            .unwrap();
    }

    #[no_mangle]
    pub extern fn terminal_newline() {
        console().write_raw_byte('\n' as u8).unwrap();
        console().flush().unwrap();
    }

    #[no_mangle]
    pub extern fn terminal_writechar_internal(c: c_char) {
        console().write_raw_byte(c as u8).unwrap();
    }

    #[no_mangle]
    pub extern fn terminal_writechar(c: c_char) {
        console().write_raw_byte(c as u8).unwrap();
        console().flush().unwrap();
    }

    #[no_mangle]
    pub unsafe extern fn terminal_writebuf(length: u64, buffer: *const u8) {
        let bytes = slice::from_raw_parts(buffer, length as usize);

        console().write_raw_bytes(bytes).unwrap();
        console().flush().unwrap();
    }

    #[no_mangle]
    pub unsafe extern fn terminal_writestring(data: *const u8) {
        let mut data_len = 0usize;
        let mut data_end = data;

        while *data_end != 0 {
            data_len += 1;
            data_end = data_end.offset(1);
        }

        let bytes = slice::from_raw_parts(data, data_len);

        console().write_raw_bytes(bytes).unwrap();
        console().flush().unwrap();
    }
}
<commit_msg>[kernel/terminal] Fix file header<commit_after>/*******************************************************************************
 *
 * kit/kernel/terminal.rs
 * - early text mode 80x25 terminal handler
 *
 * vim:ft=rust:ts=4:sw=4:et:tw=80
 *
 * Copyright (C) 2015, Devyn Cairns
 * Redistribution of this file is permitted under the terms of the simplified
 * BSD license. See LICENSE for more information.
 *
 ******************************************************************************/

use core::prelude::*;

use core::fmt;

#[derive(Copy)]
pub enum Color {
    Black        = 0,
    Blue         = 1,
    Green        = 2,
    Cyan         = 3,
    Red          = 4,
    Magenta      = 5,
    Brown        = 6,
    LightGrey    = 7,
    DarkGrey     = 8,
    LightBlue    = 9,
    LightGreen   = 10,
    LightCyan    = 11,
    LightRed     = 12,
    LightMagenta = 13,
    LightBrown   = 14,
    White        = 15,
}

/// A terminal.
pub trait Terminal: fmt::Write {
    fn reset(&mut self) -> fmt::Result;
    fn clear(&mut self) -> fmt::Result;

    fn get_cursor(&self) -> (usize, usize);
    fn set_cursor(&mut self, row: usize, col: usize) -> fmt::Result;

    fn get_color(&self) -> (Color, Color);
    fn set_color(&mut self, fg: Color, bg: Color) -> fmt::Result;

    fn put_raw_byte(&mut self,
                    byte: u8,
                    fg:   Color,
                    bg:   Color,
                    row:  usize,
                    col:  usize) -> fmt::Result;

    /// Does not flush.
    fn write_raw_byte(&mut self, byte: u8) -> fmt::Result;

    /// Does not flush.
    fn write_raw_bytes(&mut self, bytes: &[u8]) -> fmt::Result {
        for byte in bytes {
            try!(self.write_raw_byte(*byte));
        }

        Ok(())
    }

    fn flush(&mut self) -> fmt::Result;

    fn write_char(&mut self, ch: char) -> fmt::Result {
        let mut buf = [0u8, 4];

        try!(ch.encode_utf8(&mut buf).ok_or(fmt::Error));

        try!(self.write_raw_bytes(&buf));
        try!(self.flush());
        Ok(())
    }
}

/// Controls a VGA text-mode terminal.
pub struct Vga {
    width:  usize,
    height: usize,
    row:    usize,
    col:    usize,
    fg:     Color,
    bg:     Color,
    attr:   u8,
    buffer: *mut u16,
    port:   u16
}

impl Vga {
    pub unsafe fn new(width:  usize,
                      height: usize,
                      buffer: *mut u16,
                      port:   u16)
                      -> Vga {

        let mut vga = Vga {
            width:  width,
            height: height,
            row:    0,
            col:    0,
            fg:     Color::LightGrey,
            bg:     Color::Black,
            attr:   Vga::attr(Color::LightGrey, Color::Black),
            buffer: buffer,
            port:   port
        };

        vga.reset().unwrap();

        vga
    }

    pub fn color(c: Color) -> u8 {
        c as u8
    }

    pub fn attr(fg: Color, bg: Color) -> u8 {
        Vga::color(fg) | (Vga::color(bg) << 4)
    }

    fn update_attr(&mut self) {
        self.attr = Vga::attr(self.fg, self.bg);
    }

    fn update_cursor(&mut self) {
        unsafe fn outb(byte: u8, port: u16) {
            // FIXME: It seems like we have to do this due to a Rust bug where
            // the "a" and "d" constraints cause nothing to be generated. I
            // should file a bug report.
            asm!(concat!("mov $0, %al;\n",
                         "mov $1, %dx;\n",
                         "out %al, %dx")
                :
                : "r" (byte), "r" (port)
                : "rax", "rdx"
                : "volatile");
        }

        let pos: u16 = ((self.row * self.width) + self.col) as u16;

        unsafe {
            outb(0x0F,             self.port);
            outb(pos as u8,        self.port + 1);

            outb(0x0E,             self.port);
            outb((pos >> 8) as u8, self.port + 1);
        }
    }

    pub fn put(&mut self, byte: u8, attr: u8, row: usize, col: usize) {
        unsafe {
            *self.buffer.offset((row * self.width + col) as isize) =
                (byte as u16) | ((attr as u16) << 8);
        }
    }

    pub fn put_here(&mut self, byte: u8) {
        let (attr, row, col) = (self.attr, self.row, self.col);

        self.put(byte, attr, row, col)
    }

    fn new_line(&mut self) {
        // Clear to the end of the line.
        while self.col < self.width {
            self.put_here(' ' as u8);
            self.col += 1;
        }

        // Go to the next line, scrolling if necessary.
        self.col  = 0;
        self.row += 1;

        while self.row >= self.height {
            self.scroll();
            self.row -= 1;
        }

        self.update_cursor();
    }

    fn scroll(&mut self) {
        // Shift everything one line back.
        for row in 1..self.height {
            for col in 0..self.width {
                let index = (row * self.width + col) as isize;

                unsafe {
                    *self.buffer.offset(index - self.width as isize) =
                        *self.buffer.offset(index);
                }
            }
        }

        // Clear last line.
        let (attr, height) = (self.attr, self.height);

        for col in 0..self.width {
            self.put(' ' as u8, attr, height - 1, col);
        }
    }
}

impl Terminal for Vga {
    fn reset(&mut self) -> fmt::Result {
        self.fg = Color::LightGrey;
        self.bg = Color::Black;
        self.update_attr();
        self.clear()
    }

    fn clear(&mut self) -> fmt::Result {
        self.row = 0;
        self.col = 0;

        let attr = self.attr;

        for row in 0..self.height {
            for col in 0..self.width {
                self.put(' ' as u8, attr, row, col);
            }
        }

        Ok(())
    }

    fn get_cursor(&self) -> (usize, usize) {
        (self.row, self.col)
    }

    fn set_cursor(&mut self, row: usize, col: usize) -> fmt::Result {
        self.row = row;
        self.col = col;

        self.update_cursor();
        Ok(())
    }

    fn get_color(&self) -> (Color, Color) {
        (self.fg, self.bg)
    }

    fn set_color(&mut self, fg: Color, bg: Color) -> fmt::Result {
        self.fg = fg;
        self.bg = bg;
        self.update_attr();
        Ok(())
    }

    fn put_raw_byte(&mut self,
                    byte: u8,
                    fg:   Color,
                    bg:   Color,
                    row:  usize,
                    col:  usize) -> fmt::Result {

        self.put(byte, Vga::attr(fg, bg), row, col);
        Ok(())
    }

    fn write_raw_byte(&mut self, byte: u8) -> fmt::Result {
        match byte {
            0x0A /* newline */ => {
                self.new_line();
            },

            0x08 /* backspace */ => {
                if self.col > 0 {
                    self.col -= 1;
                }

                self.put_here(' ' as u8);
            },

            _ => {
                self.put_here(byte);

                if self.col + 1 >= self.width {
                    self.new_line();
                } else {
                    self.col += 1;
                }
            }
        }

        Ok(())
    }

    fn flush(&mut self) -> fmt::Result {
        self.update_cursor();
        Ok(())
    }
}

impl fmt::Write for Vga {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        try!(self.write_raw_bytes(s.as_bytes()));
        try!(self.flush());
        Ok(())
    }
}

static mut CONSOLE: Option<Vga> = None;

/// Get the current global console.
pub fn console() -> &'static mut Terminal {
    unsafe {
        if CONSOLE.is_none() {
            CONSOLE = Some(Vga::new(80, 25,
                                    0xffffffff800b8000 as *mut u16, 0x3d4));
        }

        CONSOLE.as_mut().unwrap()
    }
}

/// C (legacy) interface. See `kit/kernel/include/terminal.h`.
pub mod ffi {
    use super::*;

    use core::mem;
    use core::slice;
    use core::ptr::PtrExt;

    use libc::{c_char, size_t};

    #[no_mangle]
    pub extern fn terminal_initialize() {
        console().reset().unwrap();
    }

    #[no_mangle]
    pub extern fn terminal_clear() {
        console().clear().unwrap();
    }

    #[no_mangle]
    pub extern fn terminal_updatecursor() {
        console().flush().unwrap();
    }

    #[no_mangle]
    pub unsafe extern fn terminal_getcursor(row: *mut size_t, column: *mut size_t) {
        let (row_us, col_us) = console().get_cursor();

        *row    = row_us as size_t;
        *column = col_us as size_t;
    }

    #[no_mangle]
    pub extern fn terminal_setcursor(row: size_t, column: size_t) {
        console().set_cursor(row as usize, column as usize).unwrap();
    }

    #[repr(C)]
    #[derive(Copy)]
    pub enum VgaColor {
        Black        = 0,
        Blue         = 1,
        Green        = 2,
        Cyan         = 3,
        Red          = 4,
        Magenta      = 5,
        Brown        = 6,
        LightGrey    = 7,
        DarkGrey     = 8,
        LightBlue    = 9,
        LightGreen   = 10,
        LightCyan    = 11,
        LightRed     = 12,
        LightMagenta = 13,
        LightBrown   = 14,
        White        = 15,
    }

    impl VgaColor {
        pub fn from_color(color: Color) -> VgaColor {
            unsafe { mem::transmute(color as i32) }
        }

        pub fn to_color(self) -> Color {
            unsafe { mem::transmute(self as u8) }
        }
    }

    #[no_mangle]
    pub unsafe extern fn terminal_getcolor(fg: *mut VgaColor,
                                           bg: *mut VgaColor) {
        let (fg_c, bg_c) = console().get_color();

        *fg = VgaColor::from_color(fg_c);
        *bg = VgaColor::from_color(bg_c);
    }

    #[no_mangle]
    pub extern fn terminal_setcolor(fg: VgaColor, bg: VgaColor) {
        console().set_color(fg.to_color(), bg.to_color()).unwrap();
    }

    #[no_mangle]
    pub unsafe extern fn terminal_putentryat(c: c_char,
                                      color: u8,
                                      x: size_t,
                                      y: size_t) {

        let fg_v: VgaColor = mem::transmute((color & 0x0f) as i32);
        let bg_v: VgaColor = mem::transmute((color >> 4)   as i32);

        console()
            .put_raw_byte(c as u8,
                          fg_v.to_color(),
                          bg_v.to_color(),
                          y as usize,
                          x as usize)
            .unwrap();
    }

    #[no_mangle]
    pub extern fn terminal_newline() {
        console().write_raw_byte('\n' as u8).unwrap();
        console().flush().unwrap();
    }

    #[no_mangle]
    pub extern fn terminal_writechar_internal(c: c_char) {
        console().write_raw_byte(c as u8).unwrap();
    }

    #[no_mangle]
    pub extern fn terminal_writechar(c: c_char) {
        console().write_raw_byte(c as u8).unwrap();
        console().flush().unwrap();
    }

    #[no_mangle]
    pub unsafe extern fn terminal_writebuf(length: u64, buffer: *const u8) {
        let bytes = slice::from_raw_parts(buffer, length as usize);

        console().write_raw_bytes(bytes).unwrap();
        console().flush().unwrap();
    }

    #[no_mangle]
    pub unsafe extern fn terminal_writestring(data: *const u8) {
        let mut data_len = 0usize;
        let mut data_end = data;

        while *data_end != 0 {
            data_len += 1;
            data_end = data_end.offset(1);
        }

        let bytes = slice::from_raw_parts(data, data_len);

        console().write_raw_bytes(bytes).unwrap();
        console().flush().unwrap();
    }
}
<|endoftext|>


<commit_before>extern crate twitter;

fn main() {
    let consumer_key = include_str!("consumer_key").trim();
    let consumer_secret = include_str!("consumer_secret").trim();

    let token = twitter::auth::Token::new(consumer_key, consumer_secret);

    let request_token = twitter::auth::request_token(&token, "oob").unwrap();

    println!("Go to the following URL, sign in, and give me the PIN that comes back:");
    println!("{}", twitter::auth::authorize_url(&request_token));

    let mut pin = String::new();
    std::io::stdin().read_line(&mut pin).unwrap();
    println!("");

    let (access_token, user_id, username) = twitter::auth::access_token(&token, &request_token, pin).unwrap();

    println!("Welcome, {}, let's get this show on the road!", username);
}
<commit_msg>add warning about needing api keys<commit_after>extern crate twitter;

fn main() {
    //IMPORTANT: make an app for yourself at apps.twitter.com and get your
    //key/secret into these files; this example won't work without them
    let consumer_key = include_str!("consumer_key").trim();
    let consumer_secret = include_str!("consumer_secret").trim();

    let token = twitter::auth::Token::new(consumer_key, consumer_secret);

    let request_token = twitter::auth::request_token(&token, "oob").unwrap();

    println!("Go to the following URL, sign in, and give me the PIN that comes back:");
    println!("{}", twitter::auth::authorize_url(&request_token));

    let mut pin = String::new();
    std::io::stdin().read_line(&mut pin).unwrap();
    println!("");

    let (access_token, user_id, username) = twitter::auth::access_token(&token, &request_token, pin).unwrap();

    println!("Welcome, {}, let's get this show on the road!", username);
}
<|endoftext|>


<commit_before>use config::Config;
#[derive(Debug, Default, serde_derive::Deserialize, PartialEq)]
struct AppConfig {
    list: Vec<String>,
}

fn main() {
    std::env::set_var("APP_LIST", "Hello World");

    let config = Config::builder()
        .add_source(
            config::Environment::with_prefix("APP")
                .try_parsing(true)
                .separator("_")
                .list_separator(" "),
        )
        .build()
        .unwrap();

    let app: AppConfig = config.try_deserialize().unwrap();

    assert_eq!(app.list, vec![String::from("Hello"), String::from("World")]);

    std::env::remove_var("APP_LIST");
}
<commit_msg>Fix clippy: Derive Eq as well<commit_after>use config::Config;
#[derive(Debug, Default, serde_derive::Deserialize, PartialEq, Eq)]
struct AppConfig {
    list: Vec<String>,
}

fn main() {
    std::env::set_var("APP_LIST", "Hello World");

    let config = Config::builder()
        .add_source(
            config::Environment::with_prefix("APP")
                .try_parsing(true)
                .separator("_")
                .list_separator(" "),
        )
        .build()
        .unwrap();

    let app: AppConfig = config.try_deserialize().unwrap();

    assert_eq!(app.list, vec![String::from("Hello"), String::from("World")]);

    std::env::remove_var("APP_LIST");
}
<|endoftext|>


<commit_before>// Std
use std::io::Write;

// Internal
use clap::*;
use clap_complete::*;

/// Generate fig completion file
pub struct Fig;

impl Generator for Fig {
    fn file_name(&self, name: &str) -> String {
        format!("{}.ts", name)
    }

    fn generate(&self, cmd: &Command, buf: &mut dyn Write) {
        let command = cmd.get_bin_name().unwrap();
        let mut buffer = String::new();

        buffer.push_str(&format!(
            "const completion: Fig.Spec = {{\n  name: \"{}\",\n",
            command
        ));

        buffer.push_str(&format!(
            "  description: \"{}\",\n",
            cmd.get_about().unwrap_or_default()
        ));

        gen_fig_inner(command, &[], 2, cmd, &mut buffer);

        buffer.push_str("};\n\nexport default completion;\n");

        buf.write_all(buffer.as_bytes())
            .expect("Failed to write to generated file");
    }
}

// Escape string inside double quotes
fn escape_string(string: &str) -> String {
    string.replace('\\', "\\\\").replace('\"', "\\\"")
}

fn gen_fig_inner(
    root_command: &str,
    parent_commands: &[&str],
    indent: usize,
    cmd: &Command,
    buffer: &mut String,
) {
    if cmd.has_subcommands() {
        buffer.push_str(&format!("{:indent$}subcommands: [\n", "", indent = indent));
        // generate subcommands
        for subcommand in cmd.get_subcommands() {
            let mut aliases: Vec<&str> = subcommand.get_all_aliases().collect();
            if !aliases.is_empty() {
                aliases.insert(0, subcommand.get_name());

                buffer.push_str(&format!(
                    "{:indent$}{{\n{:indent$}  name: [",
                    "",
                    "",
                    indent = indent + 2
                ));

                buffer.push_str(
                    &aliases
                        .iter()
                        .map(|name| format!("\"{}\"", name))
                        .collect::<Vec<_>>()
                        .join(", "),
                );

                buffer.push_str("],\n");
            } else {
                buffer.push_str(&format!(
                    "{:indent$}{{\n{:indent$}  name: \"{}\",\n",
                    "",
                    "",
                    subcommand.get_name(),
                    indent = indent + 2
                ));
            }

            if let Some(data) = subcommand.get_about() {
                buffer.push_str(&format!(
                    "{:indent$}description: \"{}\",\n",
                    "",
                    escape_string(data),
                    indent = indent + 4
                ));
            }

            if subcommand.is_hide_set() {
                buffer.push_str(&format!(
                    "{:indent$}hidden: true,\n",
                    "",
                    indent = indent + 4
                ))
            }

            let mut parent_commands: Vec<_> = parent_commands.into();
            parent_commands.push(subcommand.get_name());
            gen_fig_inner(
                root_command,
                &parent_commands,
                indent + 4,
                subcommand,
                buffer,
            );

            buffer.push_str(&format!("{:indent$}}},\n", "", indent = indent + 2));
        }
        buffer.push_str(&format!("{:indent$}],\n", "", indent = indent));
    }

    buffer.push_str(&gen_options(cmd, indent));

    let args = cmd.get_positionals().collect::<Vec<_>>();

    match args.len() {
        0 => {}
        1 => {
            buffer.push_str(&format!("{:indent$}args: ", "", indent = indent));

            buffer.push_str(&gen_args(args[0], indent));
        }
        _ => {
            buffer.push_str(&format!("{:indent$}args: [\n", "", indent = indent));
            for arg in args {
                buffer.push_str(&format!("{:indent$}", "", indent = indent + 2));
                buffer.push_str(&gen_args(arg, indent + 2));
            }
            buffer.push_str(&format!("{:indent$}]\n", "", indent = indent));
        }
    };
}

fn gen_options(cmd: &Command, indent: usize) -> String {
    let mut buffer = String::new();

    let flags = generator::utils::flags(cmd);

    if cmd.get_opts().next().is_some() || !flags.is_empty() {
        buffer.push_str(&format!("{:indent$}options: [\n", "", indent = indent));

        for option in cmd.get_opts() {
            buffer.push_str(&format!("{:indent$}{{\n", "", indent = indent + 2));

            let mut names = vec![];

            if let Some(shorts) = option.get_short_and_visible_aliases() {
                names.extend(shorts.iter().map(|short| format!("-{}", short)));
            }

            if let Some(longs) = option.get_long_and_visible_aliases() {
                names.extend(longs.iter().map(|long| format!("--{}", long)));
            }

            if names.len() > 1 {
                buffer.push_str(&format!("{:indent$}name: [", "", indent = indent + 4));

                buffer.push_str(
                    &names
                        .iter()
                        .map(|name| format!("\"{}\"", name))
                        .collect::<Vec<_>>()
                        .join(", "),
                );

                buffer.push_str("],\n");
            } else {
                buffer.push_str(&format!(
                    "{:indent$}name: \"{}\",\n",
                    "",
                    names[0],
                    indent = indent + 4
                ));
            }

            if let Some(data) = option.get_help() {
                buffer.push_str(&format!(
                    "{:indent$}description: \"{}\",\n",
                    "",
                    escape_string(data),
                    indent = indent + 4
                ));
            }

            if option.is_hide_set() {
                buffer.push_str(&format!(
                    "{:indent$}hidden: true,\n",
                    "",
                    indent = indent + 4
                ))
            }

            let conflicts = arg_conflicts(cmd, option);

            if !conflicts.is_empty() {
                buffer.push_str(&format!(
                    "{:indent$}exclusiveOn: [\n",
                    "",
                    indent = indent + 4
                ));

                for conflict in conflicts {
                    buffer.push_str(&format!(
                        "{:indent$}\"{}\",\n",
                        "",
                        conflict,
                        indent = indent + 6
                    ));
                }

                buffer.push_str(&format!("{:indent$}],\n", "", indent = indent + 4));
            }

            if let ArgAction::Set | ArgAction::Append | ArgAction::Count = option.get_action() {
                buffer.push_str(&format!(
                    "{:indent$}isRepeatable: true,\n",
                    "",
                    indent = indent + 4
                ));
            }

            if option.is_require_equals_set() {
                buffer.push_str(&format!(
                    "{:indent$}requiresEquals: true,\n",
                    "",
                    indent = indent + 4
                ));
            }

            buffer.push_str(&format!("{:indent$}args: ", "", indent = indent + 4));

            buffer.push_str(&gen_args(option, indent + 4));

            buffer.push_str(&format!("{:indent$}}},\n", "", indent = indent + 2));
        }

        for flag in generator::utils::flags(cmd) {
            buffer.push_str(&format!("{:indent$}{{\n", "", indent = indent + 2));

            let mut flags = vec![];

            if let Some(shorts) = flag.get_short_and_visible_aliases() {
                flags.extend(shorts.iter().map(|s| format!("-{}", s)));
            }

            if let Some(longs) = flag.get_long_and_visible_aliases() {
                flags.extend(longs.iter().map(|s| format!("--{}", s)));
            }

            if flags.len() > 1 {
                buffer.push_str(&format!("{:indent$}name: [", "", indent = indent + 4));

                buffer.push_str(
                    &flags
                        .iter()
                        .map(|name| format!("\"{}\"", name))
                        .collect::<Vec<_>>()
                        .join(", "),
                );

                buffer.push_str("],\n");
            } else {
                buffer.push_str(&format!(
                    "{:indent$}name: \"{}\",\n",
                    "",
                    flags[0],
                    indent = indent + 4
                ));
            }

            if let Some(data) = flag.get_help() {
                buffer.push_str(&format!(
                    "{:indent$}description: \"{}\",\n",
                    "",
                    escape_string(data).as_str(),
                    indent = indent + 4
                ));
            }

            let conflicts = arg_conflicts(cmd, &flag);

            if !conflicts.is_empty() {
                buffer.push_str(&format!(
                    "{:indent$}exclusiveOn: [\n",
                    "",
                    indent = indent + 4
                ));

                for conflict in conflicts {
                    buffer.push_str(&format!(
                        "{:indent$}\"{}\",\n",
                        "",
                        conflict,
                        indent = indent + 6
                    ));
                }

                buffer.push_str(&format!("{:indent$}],\n", "", indent = indent + 4));
            }

            if let ArgAction::Set | ArgAction::Append | ArgAction::Count = flag.get_action() {
                buffer.push_str(&format!(
                    "{:indent$}isRepeatable: true,\n",
                    "",
                    indent = indent + 4
                ));
            }

            buffer.push_str(&format!("{:indent$}}},\n", "", indent = indent + 2));
        }

        buffer.push_str(&format!("{:indent$}],\n", "", indent = indent));
    }

    buffer
}

fn gen_args(arg: &Arg, indent: usize) -> String {
    if !arg.is_takes_value_set() {
        return "".to_string();
    }

    let mut buffer = String::new();

    buffer.push_str(&format!(
        "{{\n{:indent$}  name: \"{}\",\n",
        "",
        arg.get_id(),
        indent = indent
    ));

    if arg.is_multiple_values_set() {
        buffer.push_str(&format!(
            "{:indent$}isVariadic: true,\n",
            "",
            indent = indent + 2
        ));
    }

    if !arg.is_required_set() {
        buffer.push_str(&format!(
            "{:indent$}isOptional: true,\n",
            "",
            indent = indent + 2
        ));
    }

    if let Some(data) = generator::utils::possible_values(arg) {
        buffer.push_str(&format!(
            "{:indent$}suggestions: [\n",
            "",
            indent = indent + 2
        ));

        for value in data {
            if let Some(help) = value.get_help() {
                buffer.push_str(&format!(
                    "{:indent$}{{\n{:indent$}  name: \"{}\",\n",
                    "",
                    "",
                    value.get_name(),
                    indent = indent + 4,
                ));

                buffer.push_str(&format!(
                    "{:indent$}description: \"{}\",\n",
                    "",
                    escape_string(help),
                    indent = indent + 6
                ));

                buffer.push_str(&format!("{:indent$}}},\n", "", indent = indent + 4));
            } else {
                buffer.push_str(&format!(
                    "{:indent$}\"{}\",\n",
                    "",
                    value.get_name(),
                    indent = indent + 4,
                ));
            }
        }

        buffer.push_str(&format!("{:indent$}],\n", "", indent = indent + 2));
    } else {
        match arg.get_value_hint() {
            ValueHint::AnyPath | ValueHint::FilePath | ValueHint::ExecutablePath => {
                buffer.push_str(&format!(
                    "{:indent$}template: \"filepaths\",\n",
                    "",
                    indent = indent + 2
                ));
            }
            ValueHint::DirPath => {
                buffer.push_str(&format!(
                    "{:indent$}template: \"folders\",\n",
                    "",
                    indent = indent + 2
                ));
            }
            ValueHint::CommandString | ValueHint::CommandName | ValueHint::CommandWithArguments => {
                buffer.push_str(&format!(
                    "{:indent$}isCommand: true,\n",
                    "",
                    indent = indent + 2
                ));
            }
            // Disable completion for others
            _ => (),
        };
    };

    buffer.push_str(&format!("{:indent$}}},\n", "", indent = indent));

    buffer
}

fn arg_conflicts(cmd: &Command, arg: &Arg) -> Vec<String> {
    let mut res = vec![];

    for conflict in cmd.get_arg_conflicts_with(arg) {
        if let Some(s) = conflict.get_short() {
            res.push(format!("-{}", s));
        }

        if let Some(l) = conflict.get_long() {
            res.push(format!("--{}", l));
        }
    }

    res
}
<commit_msg>fix: Add back depercated `is_multiple_occurrences_set`<commit_after>// Std
use std::io::Write;

// Internal
use clap::*;
use clap_complete::*;

/// Generate fig completion file
pub struct Fig;

impl Generator for Fig {
    fn file_name(&self, name: &str) -> String {
        format!("{}.ts", name)
    }

    fn generate(&self, cmd: &Command, buf: &mut dyn Write) {
        let command = cmd.get_bin_name().unwrap();
        let mut buffer = String::new();

        buffer.push_str(&format!(
            "const completion: Fig.Spec = {{\n  name: \"{}\",\n",
            command
        ));

        buffer.push_str(&format!(
            "  description: \"{}\",\n",
            cmd.get_about().unwrap_or_default()
        ));

        gen_fig_inner(command, &[], 2, cmd, &mut buffer);

        buffer.push_str("};\n\nexport default completion;\n");

        buf.write_all(buffer.as_bytes())
            .expect("Failed to write to generated file");
    }
}

// Escape string inside double quotes
fn escape_string(string: &str) -> String {
    string.replace('\\', "\\\\").replace('\"', "\\\"")
}

fn gen_fig_inner(
    root_command: &str,
    parent_commands: &[&str],
    indent: usize,
    cmd: &Command,
    buffer: &mut String,
) {
    if cmd.has_subcommands() {
        buffer.push_str(&format!("{:indent$}subcommands: [\n", "", indent = indent));
        // generate subcommands
        for subcommand in cmd.get_subcommands() {
            let mut aliases: Vec<&str> = subcommand.get_all_aliases().collect();
            if !aliases.is_empty() {
                aliases.insert(0, subcommand.get_name());

                buffer.push_str(&format!(
                    "{:indent$}{{\n{:indent$}  name: [",
                    "",
                    "",
                    indent = indent + 2
                ));

                buffer.push_str(
                    &aliases
                        .iter()
                        .map(|name| format!("\"{}\"", name))
                        .collect::<Vec<_>>()
                        .join(", "),
                );

                buffer.push_str("],\n");
            } else {
                buffer.push_str(&format!(
                    "{:indent$}{{\n{:indent$}  name: \"{}\",\n",
                    "",
                    "",
                    subcommand.get_name(),
                    indent = indent + 2
                ));
            }

            if let Some(data) = subcommand.get_about() {
                buffer.push_str(&format!(
                    "{:indent$}description: \"{}\",\n",
                    "",
                    escape_string(data),
                    indent = indent + 4
                ));
            }

            if subcommand.is_hide_set() {
                buffer.push_str(&format!(
                    "{:indent$}hidden: true,\n",
                    "",
                    indent = indent + 4
                ))
            }

            let mut parent_commands: Vec<_> = parent_commands.into();
            parent_commands.push(subcommand.get_name());
            gen_fig_inner(
                root_command,
                &parent_commands,
                indent + 4,
                subcommand,
                buffer,
            );

            buffer.push_str(&format!("{:indent$}}},\n", "", indent = indent + 2));
        }
        buffer.push_str(&format!("{:indent$}],\n", "", indent = indent));
    }

    buffer.push_str(&gen_options(cmd, indent));

    let args = cmd.get_positionals().collect::<Vec<_>>();

    match args.len() {
        0 => {}
        1 => {
            buffer.push_str(&format!("{:indent$}args: ", "", indent = indent));

            buffer.push_str(&gen_args(args[0], indent));
        }
        _ => {
            buffer.push_str(&format!("{:indent$}args: [\n", "", indent = indent));
            for arg in args {
                buffer.push_str(&format!("{:indent$}", "", indent = indent + 2));
                buffer.push_str(&gen_args(arg, indent + 2));
            }
            buffer.push_str(&format!("{:indent$}]\n", "", indent = indent));
        }
    };
}

fn gen_options(cmd: &Command, indent: usize) -> String {
    let mut buffer = String::new();

    let flags = generator::utils::flags(cmd);

    if cmd.get_opts().next().is_some() || !flags.is_empty() {
        buffer.push_str(&format!("{:indent$}options: [\n", "", indent = indent));

        for option in cmd.get_opts() {
            buffer.push_str(&format!("{:indent$}{{\n", "", indent = indent + 2));

            let mut names = vec![];

            if let Some(shorts) = option.get_short_and_visible_aliases() {
                names.extend(shorts.iter().map(|short| format!("-{}", short)));
            }

            if let Some(longs) = option.get_long_and_visible_aliases() {
                names.extend(longs.iter().map(|long| format!("--{}", long)));
            }

            if names.len() > 1 {
                buffer.push_str(&format!("{:indent$}name: [", "", indent = indent + 4));

                buffer.push_str(
                    &names
                        .iter()
                        .map(|name| format!("\"{}\"", name))
                        .collect::<Vec<_>>()
                        .join(", "),
                );

                buffer.push_str("],\n");
            } else {
                buffer.push_str(&format!(
                    "{:indent$}name: \"{}\",\n",
                    "",
                    names[0],
                    indent = indent + 4
                ));
            }

            if let Some(data) = option.get_help() {
                buffer.push_str(&format!(
                    "{:indent$}description: \"{}\",\n",
                    "",
                    escape_string(data),
                    indent = indent + 4
                ));
            }

            if option.is_hide_set() {
                buffer.push_str(&format!(
                    "{:indent$}hidden: true,\n",
                    "",
                    indent = indent + 4
                ))
            }

            let conflicts = arg_conflicts(cmd, option);

            if !conflicts.is_empty() {
                buffer.push_str(&format!(
                    "{:indent$}exclusiveOn: [\n",
                    "",
                    indent = indent + 4
                ));

                for conflict in conflicts {
                    buffer.push_str(&format!(
                        "{:indent$}\"{}\",\n",
                        "",
                        conflict,
                        indent = indent + 6
                    ));
                }

                buffer.push_str(&format!("{:indent$}],\n", "", indent = indent + 4));
            }

            #[allow(deprecated)]
            if matches!(
                option.get_action(),
                ArgAction::StoreValue | ArgAction::IncOccurrence
            ) && option.is_multiple_occurrences_set()
            {
                buffer.push_str(&format!(
                    "{:indent$}isRepeatable: true,\n",
                    "",
                    indent = indent + 4
                ));
            }

            if let ArgAction::Set | ArgAction::Append | ArgAction::Count = option.get_action() {
                buffer.push_str(&format!(
                    "{:indent$}isRepeatable: true,\n",
                    "",
                    indent = indent + 4
                ));
            }

            if option.is_require_equals_set() {
                buffer.push_str(&format!(
                    "{:indent$}requiresEquals: true,\n",
                    "",
                    indent = indent + 4
                ));
            }

            buffer.push_str(&format!("{:indent$}args: ", "", indent = indent + 4));

            buffer.push_str(&gen_args(option, indent + 4));

            buffer.push_str(&format!("{:indent$}}},\n", "", indent = indent + 2));
        }

        for flag in generator::utils::flags(cmd) {
            buffer.push_str(&format!("{:indent$}{{\n", "", indent = indent + 2));

            let mut flags = vec![];

            if let Some(shorts) = flag.get_short_and_visible_aliases() {
                flags.extend(shorts.iter().map(|s| format!("-{}", s)));
            }

            if let Some(longs) = flag.get_long_and_visible_aliases() {
                flags.extend(longs.iter().map(|s| format!("--{}", s)));
            }

            if flags.len() > 1 {
                buffer.push_str(&format!("{:indent$}name: [", "", indent = indent + 4));

                buffer.push_str(
                    &flags
                        .iter()
                        .map(|name| format!("\"{}\"", name))
                        .collect::<Vec<_>>()
                        .join(", "),
                );

                buffer.push_str("],\n");
            } else {
                buffer.push_str(&format!(
                    "{:indent$}name: \"{}\",\n",
                    "",
                    flags[0],
                    indent = indent + 4
                ));
            }

            if let Some(data) = flag.get_help() {
                buffer.push_str(&format!(
                    "{:indent$}description: \"{}\",\n",
                    "",
                    escape_string(data).as_str(),
                    indent = indent + 4
                ));
            }

            let conflicts = arg_conflicts(cmd, &flag);

            if !conflicts.is_empty() {
                buffer.push_str(&format!(
                    "{:indent$}exclusiveOn: [\n",
                    "",
                    indent = indent + 4
                ));

                for conflict in conflicts {
                    buffer.push_str(&format!(
                        "{:indent$}\"{}\",\n",
                        "",
                        conflict,
                        indent = indent + 6
                    ));
                }

                buffer.push_str(&format!("{:indent$}],\n", "", indent = indent + 4));
            }

            #[allow(deprecated)]
            if matches!(
                flag.get_action(),
                ArgAction::StoreValue | ArgAction::IncOccurrence
            ) && flag.is_multiple_occurrences_set()
            {
                buffer.push_str(&format!(
                    "{:indent$}isRepeatable: true,\n",
                    "",
                    indent = indent + 4
                ));
            }

            if let ArgAction::Set | ArgAction::Append | ArgAction::Count = flag.get_action() {
                buffer.push_str(&format!(
                    "{:indent$}isRepeatable: true,\n",
                    "",
                    indent = indent + 4
                ));
            }

            buffer.push_str(&format!("{:indent$}}},\n", "", indent = indent + 2));
        }

        buffer.push_str(&format!("{:indent$}],\n", "", indent = indent));
    }

    buffer
}

fn gen_args(arg: &Arg, indent: usize) -> String {
    if !arg.is_takes_value_set() {
        return "".to_string();
    }

    let mut buffer = String::new();

    buffer.push_str(&format!(
        "{{\n{:indent$}  name: \"{}\",\n",
        "",
        arg.get_id(),
        indent = indent
    ));

    if arg.is_multiple_values_set() {
        buffer.push_str(&format!(
            "{:indent$}isVariadic: true,\n",
            "",
            indent = indent + 2
        ));
    }

    if !arg.is_required_set() {
        buffer.push_str(&format!(
            "{:indent$}isOptional: true,\n",
            "",
            indent = indent + 2
        ));
    }

    if let Some(data) = generator::utils::possible_values(arg) {
        buffer.push_str(&format!(
            "{:indent$}suggestions: [\n",
            "",
            indent = indent + 2
        ));

        for value in data {
            if let Some(help) = value.get_help() {
                buffer.push_str(&format!(
                    "{:indent$}{{\n{:indent$}  name: \"{}\",\n",
                    "",
                    "",
                    value.get_name(),
                    indent = indent + 4,
                ));

                buffer.push_str(&format!(
                    "{:indent$}description: \"{}\",\n",
                    "",
                    escape_string(help),
                    indent = indent + 6
                ));

                buffer.push_str(&format!("{:indent$}}},\n", "", indent = indent + 4));
            } else {
                buffer.push_str(&format!(
                    "{:indent$}\"{}\",\n",
                    "",
                    value.get_name(),
                    indent = indent + 4,
                ));
            }
        }

        buffer.push_str(&format!("{:indent$}],\n", "", indent = indent + 2));
    } else {
        match arg.get_value_hint() {
            ValueHint::AnyPath | ValueHint::FilePath | ValueHint::ExecutablePath => {
                buffer.push_str(&format!(
                    "{:indent$}template: \"filepaths\",\n",
                    "",
                    indent = indent + 2
                ));
            }
            ValueHint::DirPath => {
                buffer.push_str(&format!(
                    "{:indent$}template: \"folders\",\n",
                    "",
                    indent = indent + 2
                ));
            }
            ValueHint::CommandString | ValueHint::CommandName | ValueHint::CommandWithArguments => {
                buffer.push_str(&format!(
                    "{:indent$}isCommand: true,\n",
                    "",
                    indent = indent + 2
                ));
            }
            // Disable completion for others
            _ => (),
        };
    };

    buffer.push_str(&format!("{:indent$}}},\n", "", indent = indent));

    buffer
}

fn arg_conflicts(cmd: &Command, arg: &Arg) -> Vec<String> {
    let mut res = vec![];

    for conflict in cmd.get_arg_conflicts_with(arg) {
        if let Some(s) = conflict.get_short() {
            res.push(format!("-{}", s));
        }

        if let Some(l) = conflict.get_long() {
            res.push(format!("--{}", l));
        }
    }

    res
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate glium;
extern crate rand;
use glium::glutin;

fn main() {
    let context = glutin::HeadlessRendererBuilder::new(1024, 1024).build().unwrap();
    let display = glium::HeadlessRenderer::new(context).unwrap();

    let program = glium::program::ComputeShader::from_source(&display, r#"\

            #version 430
            layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

            layout(std140) buffer MyBlock {
                float power;
                float values[256];
            };

            void main() {
                float val = values[gl_GlobalInvocationID.x];
                values[gl_GlobalInvocationID.x] = pow(val, power);
            }

        "#).unwrap();

    struct Data {
        power: f32,
        _padding: [f32; 3],
        values: [f32],
    }

    implement_buffer_content!(Data);
    implement_uniform_block!(Data, power, values);

    const NUM_VALUES: usize = 4096;

    let mut buffer: glium::uniforms::UniformBuffer<Data> =
              glium::uniforms::UniformBuffer::empty_unsized(&display, 4 + 4 * NUM_VALUES).unwrap();

    {
        let mut mapping = buffer.map();
        mapping.power = rand::random();
        for val in mapping.values.iter_mut() {
            *val = rand::random();
        }
    }

    program.execute(uniform! { MyBlock: &*buffer }, 4096, 1, 1);

    {
        let mapping = buffer.map();
        println!("Power is: {:?}", mapping.power);
        for val in mapping.values.iter().take(10) {
            println!("{:?}", *val);
        }
        println!("...");
    }
}
<commit_msg>Fix gpgpu.rs example<commit_after>#[macro_use]
extern crate glium;
extern crate rand;
use glium::glutin;

fn main() {
    let context = glutin::HeadlessRendererBuilder::new(1024, 1024).build().unwrap();
    let display = glium::HeadlessRenderer::new(context).unwrap();

    let program = glium::program::ComputeShader::from_source(&display, r#"\

            #version 430
            layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

            layout(std140) buffer MyBlock {
                float power;
                vec4 values[4096/4];
            };

            void main() {
                vec4 val = values[gl_GlobalInvocationID.x];

                values[gl_GlobalInvocationID.x] = pow(val, vec4(power,power,power,power));
            }

        "#).unwrap();

    struct Data {
        power: f32,
        _padding: [f32; 3],
        values: [[f32;4]],
    }

    implement_buffer_content!(Data);
    implement_uniform_block!(Data, power, values);

    const NUM_VALUES: usize = 4096;

    let mut buffer: glium::uniforms::UniformBuffer<Data> =
              glium::uniforms::UniformBuffer::empty_unsized(&display, 4 + 4*3 + 4 * NUM_VALUES).unwrap();

    {
        let mut mapping = buffer.map();
        mapping.power = rand::random();
        for val in mapping.values.iter_mut() {
            *val = [rand::random::<f32>(),rand::random::<f32>(),rand::random::<f32>(),rand::random::<f32>()];
        }
    }

    program.execute(uniform! { MyBlock: &*buffer }, 4096, 1, 1);

    {
        let mapping = buffer.map();
        println!("Power is: {:?}", mapping.power);
        for val in mapping.values.iter().take(3) {
            println!("{:?}", val[0]);
            println!("{:?}", val[1]);
            println!("{:?}", val[2]);
            println!("{:?}", val[3]);
        }
        println!("...");
    }
}
<|endoftext|>


<commit_before>#![feature(proc_macro)]

extern crate hayaku_http;
extern crate hayaku_path;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

use hayaku_http::{Http, Request, Response};
use hayaku_path::Router;

use std::sync::Arc;

fn main() {
    let addr = "127.0.0.1:3000".parse().unwrap();

    let mut router = Router::new();
    router.get("/", Arc::new(hello_handler)).unwrap();
    router.get("/plaintext", Arc::new(plain_handler)).unwrap();
    router.get("/json", Arc::new(json_handler)).unwrap();

    let mut http = Http::new(router, ());
    http.threads(4);
    http.listen_and_serve(addr);
}

fn hello_handler(_req: &Request, res: &mut Response, _ctx: &()) {
    res.body(b"hello, world!").unwrap();
}

fn plain_handler(_req: &Request, res: &mut Response, _ctx: &()) {
    res.add_header("Content-Type".to_string(), "text/plain".to_string());
    res.body(b"hello, world!").unwrap();
}

#[derive(Serialize, Deserialize)]
struct Message {
    message: String,
}

fn json_handler(_req: &Request, res: &mut Response, _ctx: &()) {
    let msg = Message { message: "Hello, World!".to_string() };
    let data = serde_json::to_vec(&msg).unwrap();

    res.add_header("Content-Type".to_string(), "application/json".to_string());
    res.body(&data).unwrap();
}
<commit_msg>Update example for hayaku_http builder change<commit_after>#![feature(proc_macro)]

extern crate hayaku_http;
extern crate hayaku_path;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

use hayaku_http::{Http, Request, Response};
use hayaku_path::Router;

use std::sync::Arc;

fn main() {
    let addr = "127.0.0.1:3000".parse().unwrap();

    let mut router = Router::new();
    router.get("/", Arc::new(hello_handler)).unwrap();
    router.get("/plaintext", Arc::new(plain_handler)).unwrap();
    router.get("/json", Arc::new(json_handler)).unwrap();

    Http::new(router, ()).threads(4).listen_and_serve(addr);
}

fn hello_handler(_req: &Request, res: &mut Response, _ctx: &()) {
    res.body(b"hello, world!").unwrap();
}

fn plain_handler(_req: &Request, res: &mut Response, _ctx: &()) {
    res.add_header("Content-Type".to_string(), "text/plain".to_string());
    res.body(b"hello, world!").unwrap();
}

#[derive(Serialize, Deserialize)]
struct Message {
    message: String,
}

fn json_handler(_req: &Request, res: &mut Response, _ctx: &()) {
    let msg = Message { message: "Hello, World!".to_string() };
    let data = serde_json::to_vec(&msg).unwrap();

    res.add_header("Content-Type".to_string(), "application/json".to_string());
    res.body(&data).unwrap();
}
<|endoftext|>


<commit_before>#![feature(zero_one)]

extern crate deeplearn;
extern crate matrix;

use std::fs::File;
use std::io::{
    self,
    BufReader,
    Read,
};
use std::num::{Zero, One};
use std::path::Path;
use std::rc::Rc;

use deeplearn::Graph;
use deeplearn::op::{Add, MatMul, Mse, Relu};
use deeplearn::init;
use matrix::Matrix;

fn main() {
    // Training data
    println!("Reading training labels...");
    let train_labels = read_mnist_labels("data/mnist/train-labels-idx1-ubyte", None).unwrap();
    let train_labels_logits: Vec<Matrix<f32>> = train_labels.iter().cloned().map(|x| one_hot(x, 10)).collect();
    println!("Label count: {}", train_labels.len());

    println!("Reading training images...");
    let (rows, columns, train_images) = read_mnist_images("data/mnist/train-images-idx3-ubyte", None).unwrap();

    // Validation data
    println!("Reading validation labels...");
    let val_labels = read_mnist_labels("data/mnist/t10k-labels-idx1-ubyte", Some(1000)).unwrap();
    let val_labels_logits: Vec<Matrix<f32>> = val_labels.iter().cloned().map(|x| one_hot(x, 10)).collect();
    println!("Label count: {}", train_labels.len());

    println!("Reading validation images...");
    let (_, _, val_images) = read_mnist_images("data/mnist/t10k-images-idx3-ubyte", Some(1000)).unwrap();

    let ctx = Rc::new(matrix::Context::new());

    // Setup the graph. It's going to have 2 inputs, 3 hidden nodes in it's 1 hidden layer, and 1
    // output node
    let mut graph = Graph::new(ctx.clone());

    //////////////////////////
    // Layer 1

    // Input.  1 batches of rows*columns inputs each.
    let input = graph.add_variable((1, rows*columns), vec![0.0; rows*columns]);
    // Weights for layer 1: [rows*columns inputs x 1000 nodes]
    let l1_w = graph.add_variable((rows*columns, 1000), init::Normal(0.001, 0.005));
    // Use matrix multiplication to do a fully connected layer
    let l1_mat_mul = graph.add_node(MatMul(input, l1_w));
    // Grab VarIndex for l1_mat_mul's output
    let l1_mat_mul_out = l1_mat_mul.get(&graph).outputs[0];
    // 1000 biases; one for each node in layer 1
    let l1_b = graph.add_variable((1, 1000), init::Normal(0.001, 0.005));
    // Here we add the biases to the matrix multiplication output
    let l1_biased = graph.add_node(Add(l1_mat_mul_out, l1_b, 0));
    // Grab VarIndex for l1_biased's output
    let l1_biased_out = l1_biased.get(&graph).outputs[0];
    // Run the biased input*weight sums through an ReLU activation
    let l1_relu = graph.add_node(Relu(l1_biased_out));
    let l1_relu_out = l1_relu.get(&graph).outputs[0];

    //////////////////////////
    // Layer 2

    // Weights for layer 2: [1000 inputs x 10 nodes]
    let l2_w = graph.add_variable((1000, 10), init::Normal(0.001, 0.005));
    // Fully connected layer 2. Use layer 1's output as layer 2's input
    let l2_mat_mul = graph.add_node(MatMul(l1_relu_out, l2_w));
    // Grab VarIndex for l2_mat_mul's output
    let l2_mat_mul_out = l2_mat_mul.get(&graph).outputs[0];
    // 10 bias for 1 output node
    let l2_b = graph.add_variable((1, 10), init::Normal(0.001, 0.005));
    // Here we add the bias to the matrix multiplication output
    let l2_biased = graph.add_node(Add(l2_mat_mul_out, l2_b, 0));
    // Grab VarIndex for l2_biased's output
    let l2_biased_out = l2_biased.get(&graph).outputs[0];
    // Run the biased input*weight sums through an ReLU activation
    let l2_relu = graph.add_node(Relu(l2_biased_out));
    // Grab VarIndex for l2_relu's output
    let l2_relu_out = l2_relu.get(&graph).outputs[0];

    //////////////////////////
    // Loss

    // Add a variable for the training outputs: [1 batches x 10 output]
    let train_out = graph.add_variable((1, 10), vec![0.0; 10]);
    // Use mean squared error loss function
    let loss = graph.add_node(Mse(l2_relu_out, train_out));
    // Grab the VarIndex for loss's output
    let loss_out = loss.get(&graph).outputs[0];
    // Create a gradient to apply to the loss function
    let loss_d = graph.add_gradient(loss, 0);

    ////////////////////////////////////////////////////////////////////////////////////////////////

    // We apply a gradient of -0.1 to the loss function
    let loss_d_cpu = Matrix::from_vec(1, 10, vec![-0.001; 10]);
    loss_d.get(&graph).set(&ctx, &loss_d_cpu);

    /////////////////////////
    // Train the network
    let mut correct = 0;
    for epoch in 0..60000 {
        // Upload training data
        let train_sample = epoch%train_images.len();
        input.get(&graph).set(&ctx, &train_images[train_sample]);
        train_out.get(&graph).set(&ctx, &train_labels_logits[train_sample]);

        graph.run();
        let out = l2_relu_out.get(&graph).get(&ctx);
        let out_d = l2_relu.get(&graph)
                           .out_grad[0]
                           .gradient()
                           .get(&graph)
                           .get(&ctx);
        let l = loss_out.get(&graph).get(&ctx);
        let l1_w_d = graph.get_input_gradient(l1_w).unwrap().get(&graph);
        let l2_w_d = graph.get_input_gradient(l2_w).unwrap().get(&graph);
        let l1_b_d = graph.get_input_gradient(l1_b).unwrap().get(&graph);
        let l2_b_d = graph.get_input_gradient(l2_b).unwrap().get(&graph);
        l1_w.get(&graph).add(&ctx, -1, &*l1_w_d, &*l1_w.get(&graph));
        l2_w.get(&graph).add(&ctx, -1, &*l2_w_d, &*l2_w.get(&graph));
        l1_b.get(&graph).add(&ctx, -1, &*l1_b_d, &*l1_b.get(&graph));
        l2_b.get(&graph).add(&ctx, -1, &*l2_b_d, &*l2_b.get(&graph));

        let (mut max_index, mut max_value) = (0, out[(0, 0)]);
        for (i, val) in out.buffer().iter().enumerate() {
            if *val > max_value {
                max_index = i;
                max_value = *val;
            }
        }

        if max_index == train_labels[train_sample] as usize {
            correct += 1;
        }

        if epoch % 1000 == 999 {
            println!("===================");
            println!("Epoch: {}", epoch);
            println!("out = {:?}", out);
            println!("out_d = {:?}", out_d);
            println!("loss = {:?}", l);
            println!("Accuracy: {}%", (correct as f32)/(1000 as f32) * 100.0);
            correct = 0;
        }
    }

    /////////////////////////
    // Validate the network
    println!("#######################################");
    println!("Validating");
    let mut correct = 0;
    for epoch in 0..1000 {
        // Upload training data
        let train_sample = epoch%val_images.len();
        input.get(&graph).set(&ctx, &val_images[train_sample]);
        train_out.get(&graph).set(&ctx, &val_labels_logits[train_sample]);

        graph.run();
        let out = l2_relu_out.get(&graph).get(&ctx);
        let out_d = l2_relu.get(&graph)
                           .out_grad[0]
                           .gradient()
                           .get(&graph)
                           .get(&ctx);
        let l = loss_out.get(&graph).get(&ctx);

        let (mut max_index, mut max_value) = (0, out[(0, 0)]);
        for (i, val) in out.buffer().iter().enumerate() {
            if *val > max_value {
                max_index = i;
                max_value = *val;
            }
        }

        if max_index == val_labels[train_sample] as usize {
            correct += 1;
        }

        if epoch % 1000 == 999 {
            println!("===================");
            println!("Epoch: {}", epoch);
            println!("out = {:?}", out);
            println!("out_d = {:?}", out_d);
            println!("loss = {:?}", l);
            println!("Accuracy: {}%", (correct as f32)/(1000 as f32) * 100.0);
            correct = 0;
        }
    }
}

fn read_mnist_labels<P: AsRef<Path>>(path: P, num_samples: Option<usize>) -> io::Result<Vec<u8>> {
    use std::io::{Error, ErrorKind};

    let ref mut file = BufReader::new(File::open(path).unwrap());

    let magic = u32::from_be(try!(read_u32(file)));
    if magic != 2049 {
        return Err(Error::new(ErrorKind::Other,
                              format!("Invalid magic number. Got expect 2049, got {}",
                                      magic).as_ref()))
    }

    let label_count = u32::from_be(try!(read_u32(file)));

    let mut labels = Vec::with_capacity(label_count as usize);
    for i in 0..label_count {
        if let Some(num_samples) = num_samples {
            if i as usize > num_samples {
                break;
            }
        }
        labels.push(try!(read_u8(file)));
    }

    Ok(labels)
}

fn read_mnist_images<P: AsRef<Path>>(path: P, num_samples: Option<usize>) -> io::Result<(usize, usize, Vec<Matrix<f32>>)> {
    use std::io::{Error, ErrorKind};

    let ref mut file = BufReader::new(File::open(path).unwrap());

    let magic = u32::from_be(try!(read_u32(file)));
    if magic != 2051 {
        return Err(Error::new(ErrorKind::Other,
                              format!("Invalid magic number. Got expect 2051, got {}",
                                      magic).as_ref()))
    }

    let image_count = u32::from_be(try!(read_u32(file))) as usize;
    let rows = u32::from_be(try!(read_u32(file))) as usize;
    let columns = u32::from_be(try!(read_u32(file))) as usize;

    let mut images = Vec::with_capacity(image_count);
    for i in 0..image_count {
        if let Some(num_samples) = num_samples {
            if i as usize > num_samples {
                break;
            }
        }
        let mut pixel_buf = vec![0u8; rows*columns];
        try!(file.read_exact(pixel_buf.as_mut()));
        let matrix = Matrix::from_vec(rows, columns,
                                      pixel_buf.into_iter().map(|x| (x as f32)/255.0).collect());
        images.push(matrix);
    }

    Ok((rows, columns, images))
}

fn one_hot<N, M>(label: N, classes: N) -> Matrix<M>
    where usize: From<N>,
          M:     matrix::num::Num+Zero+One,
{
    let classes: usize = From::from(classes); // Cast class count to usize
    let label: usize = From::from(label); // Cast label to usize
    let mut buf: Vec<M> = vec![Zero::zero(); classes]; // Create array of zeroes
    buf[label] = One::one(); // Set the one-hot component
    Matrix::from_vec(1, buf.len(), buf) // Construct the matrix
}

fn read_u8<T: Read>(reader: &mut T) -> io::Result<u8> {
    use std::mem;

    let mut buf: [u8; 1] = [0];
    reader.read_exact(&mut buf).map(|_| {
        let data: u8 = unsafe { mem::transmute(buf) };
        data
    })
}

fn read_u32<T: Read>(reader: &mut T) -> io::Result<u32> {
    use std::mem;

    let mut buf: [u8; 4] = [0, 0, 0, 0];
    reader.read_exact(&mut buf).map(|_| {
        let data: u32 = unsafe { mem::transmute(buf) };
        data
    })
}
<commit_msg>fixed comment in mnist<commit_after>#![feature(zero_one)]

extern crate deeplearn;
extern crate matrix;

use std::fs::File;
use std::io::{
    self,
    BufReader,
    Read,
};
use std::num::{Zero, One};
use std::path::Path;
use std::rc::Rc;

use deeplearn::Graph;
use deeplearn::op::{Add, MatMul, Mse, Relu};
use deeplearn::init;
use matrix::Matrix;

fn main() {
    // Training data
    println!("Reading training labels...");
    let train_labels = read_mnist_labels("data/mnist/train-labels-idx1-ubyte", None).unwrap();
    let train_labels_logits: Vec<Matrix<f32>> = train_labels.iter().cloned().map(|x| one_hot(x, 10)).collect();
    println!("Label count: {}", train_labels.len());

    println!("Reading training images...");
    let (rows, columns, train_images) = read_mnist_images("data/mnist/train-images-idx3-ubyte", None).unwrap();

    // Validation data
    println!("Reading validation labels...");
    let val_labels = read_mnist_labels("data/mnist/t10k-labels-idx1-ubyte", Some(1000)).unwrap();
    let val_labels_logits: Vec<Matrix<f32>> = val_labels.iter().cloned().map(|x| one_hot(x, 10)).collect();
    println!("Label count: {}", train_labels.len());

    println!("Reading validation images...");
    let (_, _, val_images) = read_mnist_images("data/mnist/t10k-images-idx3-ubyte", Some(1000)).unwrap();

    let ctx = Rc::new(matrix::Context::new());

    // Setup the graph. It's going to have 2 inputs, 3 hidden nodes in it's 1 hidden layer, and 1
    // output node
    let mut graph = Graph::new(ctx.clone());

    //////////////////////////
    // Layer 1

    // Input.  1 batches of rows*columns inputs each.
    let input = graph.add_variable((1, rows*columns), vec![0.0; rows*columns]);
    // Weights for layer 1: [rows*columns inputs x 1000 nodes]
    let l1_w = graph.add_variable((rows*columns, 1000), init::Normal(0.001, 0.005));
    // Use matrix multiplication to do a fully connected layer
    let l1_mat_mul = graph.add_node(MatMul(input, l1_w));
    // Grab VarIndex for l1_mat_mul's output
    let l1_mat_mul_out = l1_mat_mul.get(&graph).outputs[0];
    // 1000 biases; one for each node in layer 1
    let l1_b = graph.add_variable((1, 1000), init::Normal(0.001, 0.005));
    // Here we add the biases to the matrix multiplication output
    let l1_biased = graph.add_node(Add(l1_mat_mul_out, l1_b, 0));
    // Grab VarIndex for l1_biased's output
    let l1_biased_out = l1_biased.get(&graph).outputs[0];
    // Run the biased input*weight sums through an ReLU activation
    let l1_relu = graph.add_node(Relu(l1_biased_out));
    let l1_relu_out = l1_relu.get(&graph).outputs[0];

    //////////////////////////
    // Layer 2

    // Weights for layer 2: [1000 inputs x 10 nodes]
    let l2_w = graph.add_variable((1000, 10), init::Normal(0.001, 0.005));
    // Fully connected layer 2. Use layer 1's output as layer 2's input
    let l2_mat_mul = graph.add_node(MatMul(l1_relu_out, l2_w));
    // Grab VarIndex for l2_mat_mul's output
    let l2_mat_mul_out = l2_mat_mul.get(&graph).outputs[0];
    // 10 bias for 1 output node
    let l2_b = graph.add_variable((1, 10), init::Normal(0.001, 0.005));
    // Here we add the bias to the matrix multiplication output
    let l2_biased = graph.add_node(Add(l2_mat_mul_out, l2_b, 0));
    // Grab VarIndex for l2_biased's output
    let l2_biased_out = l2_biased.get(&graph).outputs[0];
    // Run the biased input*weight sums through an ReLU activation
    let l2_relu = graph.add_node(Relu(l2_biased_out));
    // Grab VarIndex for l2_relu's output
    let l2_relu_out = l2_relu.get(&graph).outputs[0];

    //////////////////////////
    // Loss

    // Add a variable for the training outputs: [1 batches x 10 output]
    let train_out = graph.add_variable((1, 10), vec![0.0; 10]);
    // Use mean squared error loss function
    let loss = graph.add_node(Mse(l2_relu_out, train_out));
    // Grab the VarIndex for loss's output
    let loss_out = loss.get(&graph).outputs[0];
    // Create a gradient to apply to the loss function
    let loss_d = graph.add_gradient(loss, 0);

    ////////////////////////////////////////////////////////////////////////////////////////////////

    // We apply a gradient of -0.001 to the loss function
    let loss_d_cpu = Matrix::from_vec(1, 10, vec![-0.001; 10]);
    loss_d.get(&graph).set(&ctx, &loss_d_cpu);

    /////////////////////////
    // Train the network
    let mut correct = 0;
    for epoch in 0..60000 {
        // Upload training data
        let train_sample = epoch%train_images.len();
        input.get(&graph).set(&ctx, &train_images[train_sample]);
        train_out.get(&graph).set(&ctx, &train_labels_logits[train_sample]);

        graph.run();
        let out = l2_relu_out.get(&graph).get(&ctx);
        let out_d = l2_relu.get(&graph)
                           .out_grad[0]
                           .gradient()
                           .get(&graph)
                           .get(&ctx);
        let l = loss_out.get(&graph).get(&ctx);
        let l1_w_d = graph.get_input_gradient(l1_w).unwrap().get(&graph);
        let l2_w_d = graph.get_input_gradient(l2_w).unwrap().get(&graph);
        let l1_b_d = graph.get_input_gradient(l1_b).unwrap().get(&graph);
        let l2_b_d = graph.get_input_gradient(l2_b).unwrap().get(&graph);
        l1_w.get(&graph).add(&ctx, -1, &*l1_w_d, &*l1_w.get(&graph));
        l2_w.get(&graph).add(&ctx, -1, &*l2_w_d, &*l2_w.get(&graph));
        l1_b.get(&graph).add(&ctx, -1, &*l1_b_d, &*l1_b.get(&graph));
        l2_b.get(&graph).add(&ctx, -1, &*l2_b_d, &*l2_b.get(&graph));

        let (mut max_index, mut max_value) = (0, out[(0, 0)]);
        for (i, val) in out.buffer().iter().enumerate() {
            if *val > max_value {
                max_index = i;
                max_value = *val;
            }
        }

        if max_index == train_labels[train_sample] as usize {
            correct += 1;
        }

        if epoch % 1000 == 999 {
            println!("===================");
            println!("Epoch: {}", epoch);
            println!("out = {:?}", out);
            println!("out_d = {:?}", out_d);
            println!("loss = {:?}", l);
            println!("Accuracy: {}%", (correct as f32)/(1000 as f32) * 100.0);
            correct = 0;
        }
    }

    /////////////////////////
    // Validate the network
    println!("#######################################");
    println!("Validating");
    let mut correct = 0;
    for epoch in 0..1000 {
        // Upload training data
        let train_sample = epoch%val_images.len();
        input.get(&graph).set(&ctx, &val_images[train_sample]);
        train_out.get(&graph).set(&ctx, &val_labels_logits[train_sample]);

        graph.run();
        let out = l2_relu_out.get(&graph).get(&ctx);
        let out_d = l2_relu.get(&graph)
                           .out_grad[0]
                           .gradient()
                           .get(&graph)
                           .get(&ctx);
        let l = loss_out.get(&graph).get(&ctx);

        let (mut max_index, mut max_value) = (0, out[(0, 0)]);
        for (i, val) in out.buffer().iter().enumerate() {
            if *val > max_value {
                max_index = i;
                max_value = *val;
            }
        }

        if max_index == val_labels[train_sample] as usize {
            correct += 1;
        }

        if epoch % 1000 == 999 {
            println!("===================");
            println!("Epoch: {}", epoch);
            println!("out = {:?}", out);
            println!("out_d = {:?}", out_d);
            println!("loss = {:?}", l);
            println!("Accuracy: {}%", (correct as f32)/(1000 as f32) * 100.0);
            correct = 0;
        }
    }
}

fn read_mnist_labels<P: AsRef<Path>>(path: P, num_samples: Option<usize>) -> io::Result<Vec<u8>> {
    use std::io::{Error, ErrorKind};

    let ref mut file = BufReader::new(File::open(path).unwrap());

    let magic = u32::from_be(try!(read_u32(file)));
    if magic != 2049 {
        return Err(Error::new(ErrorKind::Other,
                              format!("Invalid magic number. Got expect 2049, got {}",
                                      magic).as_ref()))
    }

    let label_count = u32::from_be(try!(read_u32(file)));

    let mut labels = Vec::with_capacity(label_count as usize);
    for i in 0..label_count {
        if let Some(num_samples) = num_samples {
            if i as usize > num_samples {
                break;
            }
        }
        labels.push(try!(read_u8(file)));
    }

    Ok(labels)
}

fn read_mnist_images<P: AsRef<Path>>(path: P, num_samples: Option<usize>) -> io::Result<(usize, usize, Vec<Matrix<f32>>)> {
    use std::io::{Error, ErrorKind};

    let ref mut file = BufReader::new(File::open(path).unwrap());

    let magic = u32::from_be(try!(read_u32(file)));
    if magic != 2051 {
        return Err(Error::new(ErrorKind::Other,
                              format!("Invalid magic number. Got expect 2051, got {}",
                                      magic).as_ref()))
    }

    let image_count = u32::from_be(try!(read_u32(file))) as usize;
    let rows = u32::from_be(try!(read_u32(file))) as usize;
    let columns = u32::from_be(try!(read_u32(file))) as usize;

    let mut images = Vec::with_capacity(image_count);
    for i in 0..image_count {
        if let Some(num_samples) = num_samples {
            if i as usize > num_samples {
                break;
            }
        }
        let mut pixel_buf = vec![0u8; rows*columns];
        try!(file.read_exact(pixel_buf.as_mut()));
        let matrix = Matrix::from_vec(rows, columns,
                                      pixel_buf.into_iter().map(|x| (x as f32)/255.0).collect());
        images.push(matrix);
    }

    Ok((rows, columns, images))
}

fn one_hot<N, M>(label: N, classes: N) -> Matrix<M>
    where usize: From<N>,
          M:     matrix::num::Num+Zero+One,
{
    let classes: usize = From::from(classes); // Cast class count to usize
    let label: usize = From::from(label); // Cast label to usize
    let mut buf: Vec<M> = vec![Zero::zero(); classes]; // Create array of zeroes
    buf[label] = One::one(); // Set the one-hot component
    Matrix::from_vec(1, buf.len(), buf) // Construct the matrix
}

fn read_u8<T: Read>(reader: &mut T) -> io::Result<u8> {
    use std::mem;

    let mut buf: [u8; 1] = [0];
    reader.read_exact(&mut buf).map(|_| {
        let data: u8 = unsafe { mem::transmute(buf) };
        data
    })
}

fn read_u32<T: Read>(reader: &mut T) -> io::Result<u32> {
    use std::mem;

    let mut buf: [u8; 4] = [0, 0, 0, 0];
    reader.read_exact(&mut buf).map(|_| {
        let data: u32 = unsafe { mem::transmute(buf) };
        data
    })
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2015 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.

extern crate gj;
use std::net::ToSocketAddrs;
use gj::io::{AsyncRead, AsyncWrite};

fn forward<R,W,B>(src: R, dst: W, buf: B) -> gj::Promise<(R,W,B), gj::io::Error<(R,W,B)>>
    where R: AsyncRead, W: AsyncWrite, B: ::std::ops::DerefMut<Target=[u8]> + 'static
{
    src.try_read(buf, 1).then_else(move |r| match r {
        Ok((src, buf, n)) => {
            if n == 0 {
                // EOF
                Ok(gj::Promise::fulfilled((src, dst, buf)))
            } else {
                Ok(dst.write(gj::io::Slice::new(buf, n)).then_else(move |r| match r {
                    Ok((dst, slice)) => Ok(forward(src, dst, slice.buf)),
                    Err(gj::io::Error {state: (dst, slice), error}) =>
                        Err(gj::io::Error::new((src, dst, slice.buf), error))
                }))
            }
        }
        Err(gj::io::Error {state: (src, buf), error}) =>
            Err(gj::io::Error::new((src, dst, buf), error)),
    })
}

fn accept_loop(receiver: gj::io::tcp::Listener,
               outbound_addr: ::std::net::SocketAddr,
               mut task_set: gj::TaskSet<(), ::std::io::Error>) -> gj::Promise<(), ::std::io::Error> {
    receiver.accept().lift().then(move |(receiver, src_stream)| {
        println!("handling connection");

        Ok(gj::io::Timer.timeout_after_ms(3000, ::gj::io::tcp::Stream::connect(outbound_addr))
           .then_else(move |r| match r {
               Ok(dst_stream) =>  {
                   task_set.add(forward(try!(src_stream.try_clone()),
                                        try!(dst_stream.try_clone()),
                                        vec![0; 1024]).lift().map(|_| Ok(())));
                   task_set.add(forward(dst_stream, src_stream, vec![0; 1024]).lift().map(|_| Ok(())));
                   Ok(accept_loop(receiver, outbound_addr, task_set))
               }
               Err(e) => {
                   println!("failed to connect: {}", e);
                   Err(e.into())
               }
           }))
    })
}

pub struct Reporter;

impl gj::TaskReaper<(), ::std::io::Error> for Reporter {
    fn task_failed(&mut self, error: ::std::io::Error) {
        println!("Task failed: {}", error);
    }
}

pub fn main() {
    let args : Vec<String> = ::std::env::args().collect();
    if args.len() != 3 {
        println!("usage: {} <LISTEN_ADDR> <CONNECT_ADDR>", args[0]);
        return;
    }

    gj::EventLoop::top_level(|wait_scope| {
        let addr = try!(args[1].to_socket_addrs()).next().expect("could not parse address");
        let listener = try!(::gj::io::tcp::Listener::bind(addr));

        let outbound_addr = try!(args[2].to_socket_addrs()).next().expect("could not parse address");
        return accept_loop(listener,
                           outbound_addr,
                           gj::TaskSet::new(Box::new(Reporter))).lift().wait(wait_scope);
    }).unwrap();
}
<commit_msg>AsMut and AsRef in proxy example.<commit_after>// Copyright (c) 2013-2015 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.

extern crate gj;
use std::net::ToSocketAddrs;
use gj::io::{AsyncRead, AsyncWrite};

fn forward<R,W,B>(src: R, dst: W, buf: B) -> gj::Promise<(R,W,B), gj::io::Error<(R,W,B)>>
    where R: AsyncRead, W: AsyncWrite, B: AsMut<[u8]> + AsRef<[u8]> + 'static
{
    src.try_read(buf, 1).then_else(move |r| match r {
        Ok((src, buf, n)) => {
            if n == 0 {
                // EOF
                Ok(gj::Promise::fulfilled((src, dst, buf)))
            } else {
                Ok(dst.write(gj::io::Slice::new(buf, n)).then_else(move |r| match r {
                    Ok((dst, slice)) => Ok(forward(src, dst, slice.buf)),
                    Err(gj::io::Error {state: (dst, slice), error}) =>
                        Err(gj::io::Error::new((src, dst, slice.buf), error))
                }))
            }
        }
        Err(gj::io::Error {state: (src, buf), error}) =>
            Err(gj::io::Error::new((src, dst, buf), error)),
    })
}

fn accept_loop(receiver: gj::io::tcp::Listener,
               outbound_addr: ::std::net::SocketAddr,
               mut task_set: gj::TaskSet<(), ::std::io::Error>) -> gj::Promise<(), ::std::io::Error> {
    receiver.accept().lift().then(move |(receiver, src_stream)| {
        println!("handling connection");

        Ok(gj::io::Timer.timeout_after_ms(3000, ::gj::io::tcp::Stream::connect(outbound_addr))
           .then_else(move |r| match r {
               Ok(dst_stream) =>  {
                   task_set.add(forward(try!(src_stream.try_clone()),
                                        try!(dst_stream.try_clone()),
                                        vec![0; 1024]).lift().map(|_| Ok(())));
                   task_set.add(forward(dst_stream, src_stream, vec![0; 1024]).lift().map(|_| Ok(())));
                   Ok(accept_loop(receiver, outbound_addr, task_set))
               }
               Err(e) => {
                   println!("failed to connect: {}", e);
                   Err(e.into())
               }
           }))
    })
}

pub struct Reporter;

impl gj::TaskReaper<(), ::std::io::Error> for Reporter {
    fn task_failed(&mut self, error: ::std::io::Error) {
        println!("Task failed: {}", error);
    }
}

pub fn main() {
    let args : Vec<String> = ::std::env::args().collect();
    if args.len() != 3 {
        println!("usage: {} <LISTEN_ADDR> <CONNECT_ADDR>", args[0]);
        return;
    }

    gj::EventLoop::top_level(|wait_scope| {
        let addr = try!(args[1].to_socket_addrs()).next().expect("could not parse address");
        let listener = try!(::gj::io::tcp::Listener::bind(addr));

        let outbound_addr = try!(args[2].to_socket_addrs()).next().expect("could not parse address");
        return accept_loop(listener,
                           outbound_addr,
                           gj::TaskSet::new(Box::new(Reporter))).lift().wait(wait_scope);
    }).unwrap();
}
<|endoftext|>