<commit_before>#[macro_use]
extern crate rswm;
extern crate x11;

use std::io;
use std::io::{Read, Write};
use std::os::raw::{c_uchar, c_uint};
use std::process;
use x11::{keysym, xlib};

use rswm::client::ClientW;
use rswm::config::*;
use rswm::core;
use rswm::loggers;
use rswm::layout::{Tile, FullScreen, Overview, Layout};
use rswm::util::spawn;

const KEYS: &'static [(c_uint, c_uint, &'static Fn(&mut core::WindowManager))] =
    &[(MOD_MASK, keysym::XK_r, &|_| spawn("dmenu_run", &[])),
      (MOD_MASK, keysym::XK_t, &|_| spawn("urxvt", &[])),
      (MOD_MASK, keysym::XK_Print, &|_| spawn("scrot", &["-e", "mv $f ~/"])),
      (MOD_MASK | xlib::Mod1Mask,
       keysym::XK_Print,
       &|_| spawn("scrot", &["-s", "-e", "mv $f ~/"])),
      (MOD_MASK, keysym::XK_f, &|_| spawn("pcmanfm", &[])),
      (MOD_MASK, keysym::XK_l, &|_| spawn("i3lock", &["-c", "000000", "-n"])),
      (0, keysym::XF86XK_MonBrightnessUp, &|_| spawn("xbrightness", &["+10000"])),
      (0, keysym::XF86XK_MonBrightnessDown, &|_| spawn("xbrightness", &["-10000"])),
      (0, keysym::XF86XK_AudioRaiseVolume, &|_| spawn("amixer", &["set", "Master", "5000+"])),
      (0, keysym::XF86XK_AudioLowerVolume, &|_| spawn("amixer", &["set", "Master", "5000-"])),
      (0, keysym::XF86XK_AudioMute, &|_| spawn("amixer", &["set", "Master", "toggle"])),
      (0, keysym::XF86XK_AudioMicMute, &|_| spawn("amixer", &["set", "Capture", "toggle"])),
      (MOD_MASK,
       keysym::XK_w,
       &|w| {
        let clients = w.all_clients();
        let contents: Vec<String> =
            clients.iter().map(|c| format!("[{}] {}", c.get_class(), c.get_title())).collect();
        match dmenu_helper(contents.iter(),
                           &["-p", "window", "-i", "-l", "7", "-sb", "#000000", "-sf",
                             "#00ff00", "-nb", "#000000", "-nf", "#dddddd"]) {
            Ok(result) => {
                if let Some(position) = contents.iter().position(|s| (*s).trim() == result.trim()) {
                    let c = clients[position].clone();
                    w.select_tag(c.tag());
                    w.set_focus(c);
                }
            }
            Err(_) => return,
        }
    })];

const START_PROGRAMS: &'static [&'static Fn()] =
    &[&|| spawn("wmname", &["LG3D"]),
      &|| spawn("xcompmgr", &[]),
      &|| spawn("fcitx", &[]),
      &|| spawn("tilda", &["--hidden"]),
      &|| spawn("/usr/lib/polkit-kde/polkit-kde-authentication-agent-1", &[])];

const TAG_LAYOUT: &'static [(c_uchar, &'static str)] = &[('9' as c_uchar, "fullscreen"),
                                                         (TAG_OVERVIEW as c_uchar, "overview")];

const RULES: &'static [(&'static Fn(&ClientW) -> bool, &'static Fn(&mut ClientW))] =
    &[(&|c| c.get_class() == "Gimp", &|c| c.set_floating(true)),
      (&|c| c.is_dialog(), &|c| c.set_floating(true)),
      (&|c| c.get_class() == "VirtualBox", &|c| c.set_floating(true)),
      (&|c| c.get_class() == "Tilda",
       &|c| {
           c.set_floating(true);
           c.set_sticky(true);
       })];

const TAG_KEYS: &'static (&'static [(c_uint, c_uint, &'static Fn(&mut core::WindowManager))],
          &'static [c_uchar]) = &define_tags!(MOD_MASK,
                                              xlib::ShiftMask,
                                              ['1', '2', '3', '4', '5', '6', '7', '8', '9']);

const TAG_DESCRIPTION: &'static [(c_uchar, &'static str)] = &[('1' as c_uchar, "网页"),
                                                              ('2' as c_uchar, "代码")];

fn main() {
    let config = Config::default()
        .border_width(2)
        .bar_height(19)
        .addtional_keys(KEYS)
        .start_programs(START_PROGRAMS)
        .tag_keys(TAG_KEYS)
        .tag_default('1' as c_uchar)
        .rules(RULES)
        .tag_description(TAG_DESCRIPTION)
        .tag_layout(vec![('9' as c_uchar, Box::new(FullScreen)),
                         (TAG_OVERVIEW as c_uchar, Box::new(Overview))]);
    let xmobar_logger = loggers::XMobarLogger::new(loggers::LoggerConfig::default(), &[]);
    let mut window_manager = core::WindowManager::new(config);
    window_manager.set_logger(Box::new(xmobar_logger));
    window_manager.run();
}

fn dmenu_helper<'a, I>(strings: I, args: &[&str]) -> Result<String, io::Error>
    where I: Iterator<Item = &'a String>
{
    let mut child = try!(process::Command::new("dmenu")
        .args(args)
        .stdin(process::Stdio::piped())
        .stdout(process::Stdio::piped())
        .spawn());
    for c in strings {
        try!(writeln!(child.stdin.as_mut().unwrap(), "{}", c));
    }
    try!(child.wait());
    let mut result = String::new();
    try!(child.stdout.unwrap().read_to_string(&mut result));
    Ok(result)
}<commit_msg>update config for dmenu and remove wmname<commit_after>#[macro_use]
extern crate rswm;
extern crate x11;

use std::io;
use std::io::{Read, Write};
use std::os::raw::{c_uchar, c_uint};
use std::process;
use x11::{keysym, xlib};

use rswm::client::ClientW;
use rswm::config::*;
use rswm::core;
use rswm::loggers;
use rswm::layout::{Tile, FullScreen, Overview, Layout};
use rswm::util::spawn;

const KEYS: &'static [(c_uint, c_uint, &'static Fn(&mut core::WindowManager))] =
    &[(MOD_MASK, keysym::XK_r, &|_| spawn("dmenu_run", &[])),
      (MOD_MASK, keysym::XK_t, &|_| spawn("urxvt", &[])),
      (MOD_MASK, keysym::XK_Print, &|_| spawn("scrot", &["-e", "mv $f ~/"])),
      (MOD_MASK | xlib::Mod1Mask,
       keysym::XK_Print,
       &|_| spawn("scrot", &["-s", "-e", "mv $f ~/"])),
      (MOD_MASK, keysym::XK_f, &|_| spawn("pcmanfm", &[])),
      (MOD_MASK, keysym::XK_l, &|_| spawn("i3lock", &["-c", "000000", "-n"])),
      (0, keysym::XF86XK_MonBrightnessUp, &|_| spawn("xbrightness", &["+10000"])),
      (0, keysym::XF86XK_MonBrightnessDown, &|_| spawn("xbrightness", &["-10000"])),
      (0, keysym::XF86XK_AudioRaiseVolume, &|_| spawn("amixer", &["set", "Master", "5000+"])),
      (0, keysym::XF86XK_AudioLowerVolume, &|_| spawn("amixer", &["set", "Master", "5000-"])),
      (0, keysym::XF86XK_AudioMute, &|_| spawn("amixer", &["set", "Master", "toggle"])),
      (0, keysym::XF86XK_AudioMicMute, &|_| spawn("amixer", &["set", "Capture", "toggle"])),
      (MOD_MASK,
       keysym::XK_w,
       &|w| {
        let clients = w.all_clients();
        let contents: Vec<String> =
            clients.iter().map(|c| format!("[{}] {}", c.get_class(), c.get_title())).collect();
        match dmenu_helper(contents.iter(),
                           &["-p",
                             "window",
                             "-i",
                             "-l",
                             "7",
                             "-sb",
                             "#000000",
                             "-sf",
                             "#00ff00",
                             "-nb",
                             "#000000",
                             "-nf",
                             "#dddddd",
                             "-fn",
                             "WenQuanYi Micro Hei Mono-12"]) {
            Ok(result) => {
                if let Some(position) = contents.iter().position(|s| (*s).trim() == result.trim()) {
                    let c = clients[position].clone();
                    w.select_tag(c.tag());
                    w.set_focus(c);
                }
            }
            Err(_) => return,
        }
    })];

const START_PROGRAMS: &'static [&'static Fn()] =
    &[&|| spawn("xcompmgr", &[]),
      &|| spawn("fcitx", &[]),
      &|| spawn("tilda", &["--hidden"]),
      &|| spawn("/usr/lib/polkit-kde/polkit-kde-authentication-agent-1", &[])];

const TAG_LAYOUT: &'static [(c_uchar, &'static str)] = &[('9' as c_uchar, "fullscreen"),
                                                         (TAG_OVERVIEW as c_uchar, "overview")];

const RULES: &'static [(&'static Fn(&ClientW) -> bool, &'static Fn(&mut ClientW))] =
    &[(&|c| c.get_class() == "Gimp", &|c| c.set_floating(true)),
      (&|c| c.is_dialog(), &|c| c.set_floating(true)),
      (&|c| c.get_class() == "VirtualBox", &|c| c.set_floating(true)),
      (&|c| c.get_class() == "Tilda",
       &|c| {
           c.set_floating(true);
           c.set_sticky(true);
       })];

const TAG_KEYS: &'static (&'static [(c_uint, c_uint, &'static Fn(&mut core::WindowManager))],
          &'static [c_uchar]) = &define_tags!(MOD_MASK,
                                              xlib::ShiftMask,
                                              ['1', '2', '3', '4', '5', '6', '7', '8', '9']);

const TAG_DESCRIPTION: &'static [(c_uchar, &'static str)] = &[('1' as c_uchar, "网页"),
                                                              ('2' as c_uchar, "代码")];

fn main() {
    let config = Config::default()
        .border_width(2)
        .bar_height(19)
        .addtional_keys(KEYS)
        .start_programs(START_PROGRAMS)
        .tag_keys(TAG_KEYS)
        .tag_default('1' as c_uchar)
        .rules(RULES)
        .tag_description(TAG_DESCRIPTION)
        .tag_layout(vec![('9' as c_uchar, Box::new(FullScreen)),
                         (TAG_OVERVIEW as c_uchar, Box::new(Overview))]);
    let xmobar_logger = loggers::XMobarLogger::new(loggers::LoggerConfig::default(), &[]);
    let mut window_manager = core::WindowManager::new(config);
    window_manager.set_logger(Box::new(xmobar_logger));
    window_manager.run();
}

fn dmenu_helper<'a, I>(strings: I, args: &[&str]) -> Result<String, io::Error>
    where I: Iterator<Item = &'a String>
{
    let mut child = try!(process::Command::new("dmenu")
        .args(args)
        .stdin(process::Stdio::piped())
        .stdout(process::Stdio::piped())
        .spawn());
    for c in strings {
        try!(writeln!(child.stdin.as_mut().unwrap(), "{}", c));
    }
    try!(child.wait());
    let mut result = String::new();
    try!(child.stdout.unwrap().read_to_string(&mut result));
    Ok(result)
}<|endoftext|>


<commit_before>use parser::ParseError;
use std::collections::HashSet;
use text_range::TextRange;

pub struct InputError {
    /// The error message
    pub msg: String,
    /// The columns in which the error occurred
    pub pos: TextRange,
}

impl InputError {
    pub fn from_parser_error(err: ParseError) -> InputError {
        InputError {
            msg: generate_expected_string(&err.expected),
            pos: TextRange {
                start: err.offset,
                end: err.column,
            },
        }
    }
}

fn generate_expected_string(expected: &HashSet<&str>) -> String {
    let mut expected = expected.iter().map(|s| *s).collect::<Vec<&str>>();

    expected.sort();

    format!("expected {}", or_list(&expected))
}

#[test]
fn ident_generate_expected_string() {
    {
        let mut expected = HashSet::new();
        expected.insert("a");
        expected.insert("(");
        expected.insert("0");
        expected.insert("number");
        assert_eq!(generate_expected_string(&expected), "expected (, 0, a or number");
    }
}

fn or_list(items: &[&str]) -> String {
    let len = items.len();
    match len {
        0 => String::new(),
        1 => String::from(items[0]),
        _ => {
            let last = len - 1;
            format!("{} or {}", items[0..last].join(", "), items[last])
        }
    }
}

#[test]
fn test_or_list() {
    assert_eq!(or_list(&vec!["foo"]), String::from("foo"));

    assert_eq!(or_list(&vec!["foo", "bar"]), String::from("foo or bar"));

    assert_eq!(
        or_list(&vec!["foo", "bar", "baz"]),
        String::from("foo, bar or baz")
    );

    assert_eq!(
        or_list(&vec!["a", "b", "c", "d", "e"]),
        String::from("a, b, c, d or e")
    );
}
<commit_msg>Disjoint tests<commit_after>use parser::ParseError;
use std::collections::HashSet;
use text_range::TextRange;

pub struct InputError {
    /// The error message
    pub msg: String,
    /// The columns in which the error occurred
    pub pos: TextRange,
}

impl InputError {
    pub fn from_parser_error(err: ParseError) -> InputError {
        InputError {
            msg: generate_expected_string(&err.expected),
            pos: TextRange {
                start: err.offset,
                end: err.column,
            },
        }
    }
}

fn generate_expected_string(expected: &HashSet<&str>) -> String {
    let mut expected = expected.iter().map(|s| *s).collect::<Vec<&str>>();

    expected.sort();

    format!("expected {}", or_list(&expected))
}

#[test]
fn test_generate_expected_string() {
    let mut expected = HashSet::new();
    expected.insert("abc");
    expected.insert("number");
    assert_eq!(generate_expected_string(&expected), "expected abc or number");
}

#[test]
fn test_generate_expected_string_with_special_characters() {
    let mut expected = HashSet::new();
    expected.insert("a");
    expected.insert("(");
    expected.insert("0");
    expected.insert("number");
    assert_eq!(generate_expected_string(&expected), "expected (, 0, a or number");
}

fn or_list(items: &[&str]) -> String {
    let len = items.len();
    match len {
        0 => String::new(),
        1 => String::from(items[0]),
        _ => {
            let last = len - 1;
            format!("{} or {}", items[0..last].join(", "), items[last])
        }
    }
}

#[test]
fn test_or_list_with_one_entry() {
    assert_eq!(or_list(&vec!["foo"]), String::from("foo"));
}

#[test]
fn test_or_list_with_two_entries() {
    assert_eq!(or_list(&vec!["foo", "bar"]), String::from("foo or bar"));
}

#[test]
fn test_or_list_with_three_entries() {
    assert_eq!(
        or_list(&vec!["foo", "bar", "baz"]),
        String::from("foo, bar or baz")
    );
}

#[test]
fn test_or_list_with_five_entries() {
    assert_eq!(
        or_list(&vec!["a", "b", "c", "d", "e"]),
        String::from("a, b, c, d or e")
    );
}
<|endoftext|>


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

use lib::*;

macro_rules! int_to_int {
    ($dst:ident, $n:ident) => (
        if $dst::MIN as i64 <= $n as i64 && $n as i64 <= $dst::MAX as i64 {
            Some($n as $dst)
        } else {
            None
        }
    )
}

macro_rules! int_to_uint {
    ($dst:ident, $n:ident) => (
        if 0 <= $n && $n as u64 <= $dst::MAX as u64 {
            Some($n as $dst)
        } else {
            None
        }
    )
}

macro_rules! uint_to {
    ($dst:ident, $n:ident) => (
        if $n as u64 <= $dst::MAX as u64 {
            Some($n as $dst)
        } else {
            None
        }
    )
}

pub trait FromPrimitive: Sized {
    fn from_isize(n: isize) -> Option<Self>;
    fn from_i8(n: i8) -> Option<Self>;
    fn from_i16(n: i16) -> Option<Self>;
    fn from_i32(n: i32) -> Option<Self>;
    fn from_i64(n: i64) -> Option<Self>;
    fn from_usize(n: usize) -> Option<Self>;
    fn from_u8(n: u8) -> Option<Self>;
    fn from_u16(n: u16) -> Option<Self>;
    fn from_u32(n: u32) -> Option<Self>;
    fn from_u64(n: u64) -> Option<Self>;
}

macro_rules! impl_from_primitive_for_int {
    ($t:ident) => (
        impl FromPrimitive for $t {
            #[inline] fn from_isize(n: isize) -> Option<Self> { int_to_int!($t, n) }
            #[inline] fn from_i8(n: i8) -> Option<Self> { int_to_int!($t, n) }
            #[inline] fn from_i16(n: i16) -> Option<Self> { int_to_int!($t, n) }
            #[inline] fn from_i32(n: i32) -> Option<Self> { int_to_int!($t, n) }
            #[inline] fn from_i64(n: i64) -> Option<Self> { int_to_int!($t, n) }
            #[inline] fn from_usize(n: usize) -> Option<Self> { uint_to!($t, n) }
            #[inline] fn from_u8(n: u8) -> Option<Self> { uint_to!($t, n) }
            #[inline] fn from_u16(n: u16) -> Option<Self> { uint_to!($t, n) }
            #[inline] fn from_u32(n: u32) -> Option<Self> { uint_to!($t, n) }
            #[inline] fn from_u64(n: u64) -> Option<Self> { uint_to!($t, n) }
        }
    )
}

macro_rules! impl_from_primitive_for_uint {
    ($t:ident) => (
        impl FromPrimitive for $t {
            #[inline] fn from_isize(n: isize) -> Option<Self> { int_to_uint!($t, n) }
            #[inline] fn from_i8(n: i8) -> Option<Self> { int_to_uint!($t, n) }
            #[inline] fn from_i16(n: i16) -> Option<Self> { int_to_uint!($t, n) }
            #[inline] fn from_i32(n: i32) -> Option<Self> { int_to_uint!($t, n) }
            #[inline] fn from_i64(n: i64) -> Option<Self> { int_to_uint!($t, n) }
            #[inline] fn from_usize(n: usize) -> Option<Self> { uint_to!($t, n) }
            #[inline] fn from_u8(n: u8) -> Option<Self> { uint_to!($t, n) }
            #[inline] fn from_u16(n: u16) -> Option<Self> { uint_to!($t, n) }
            #[inline] fn from_u32(n: u32) -> Option<Self> { uint_to!($t, n) }
            #[inline] fn from_u64(n: u64) -> Option<Self> { uint_to!($t, n) }
        }
    )
}

macro_rules! impl_from_primitive_for_float {
    ($t:ident) => (
        impl FromPrimitive for $t {
            #[inline] fn from_isize(n: isize) -> Option<Self> { Some(n as Self) }
            #[inline] fn from_i8(n: i8) -> Option<Self> { Some(n as Self) }
            #[inline] fn from_i16(n: i16) -> Option<Self> { Some(n as Self) }
            #[inline] fn from_i32(n: i32) -> Option<Self> { Some(n as Self) }
            #[inline] fn from_i64(n: i64) -> Option<Self> { Some(n as Self) }
            #[inline] fn from_usize(n: usize) -> Option<Self> { Some(n as Self) }
            #[inline] fn from_u8(n: u8) -> Option<Self> { Some(n as Self) }
            #[inline] fn from_u16(n: u16) -> Option<Self> { Some(n as Self) }
            #[inline] fn from_u32(n: u32) -> Option<Self> { Some(n as Self) }
            #[inline] fn from_u64(n: u64) -> Option<Self> { Some(n as Self) }
        }
    )
}

impl_from_primitive_for_int!(isize);
impl_from_primitive_for_int!(i8);
impl_from_primitive_for_int!(i16);
impl_from_primitive_for_int!(i32);
impl_from_primitive_for_int!(i64);
impl_from_primitive_for_uint!(usize);
impl_from_primitive_for_uint!(u8);
impl_from_primitive_for_uint!(u16);
impl_from_primitive_for_uint!(u32);
impl_from_primitive_for_uint!(u64);
impl_from_primitive_for_float!(f32);
impl_from_primitive_for_float!(f64);
<commit_msg>Follow clippy's replace_consts lint<commit_after>// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use lib::*;

macro_rules! int_to_int {
    ($dst:ident, $n:ident) => (
        if $dst::min_value() as i64 <= $n as i64 && $n as i64 <= $dst::max_value() as i64 {
            Some($n as $dst)
        } else {
            None
        }
    )
}

macro_rules! int_to_uint {
    ($dst:ident, $n:ident) => (
        if 0 <= $n && $n as u64 <= $dst::max_value() as u64 {
            Some($n as $dst)
        } else {
            None
        }
    )
}

macro_rules! uint_to {
    ($dst:ident, $n:ident) => (
        if $n as u64 <= $dst::max_value() as u64 {
            Some($n as $dst)
        } else {
            None
        }
    )
}

pub trait FromPrimitive: Sized {
    fn from_isize(n: isize) -> Option<Self>;
    fn from_i8(n: i8) -> Option<Self>;
    fn from_i16(n: i16) -> Option<Self>;
    fn from_i32(n: i32) -> Option<Self>;
    fn from_i64(n: i64) -> Option<Self>;
    fn from_usize(n: usize) -> Option<Self>;
    fn from_u8(n: u8) -> Option<Self>;
    fn from_u16(n: u16) -> Option<Self>;
    fn from_u32(n: u32) -> Option<Self>;
    fn from_u64(n: u64) -> Option<Self>;
}

macro_rules! impl_from_primitive_for_int {
    ($t:ident) => (
        impl FromPrimitive for $t {
            #[inline] fn from_isize(n: isize) -> Option<Self> { int_to_int!($t, n) }
            #[inline] fn from_i8(n: i8) -> Option<Self> { int_to_int!($t, n) }
            #[inline] fn from_i16(n: i16) -> Option<Self> { int_to_int!($t, n) }
            #[inline] fn from_i32(n: i32) -> Option<Self> { int_to_int!($t, n) }
            #[inline] fn from_i64(n: i64) -> Option<Self> { int_to_int!($t, n) }
            #[inline] fn from_usize(n: usize) -> Option<Self> { uint_to!($t, n) }
            #[inline] fn from_u8(n: u8) -> Option<Self> { uint_to!($t, n) }
            #[inline] fn from_u16(n: u16) -> Option<Self> { uint_to!($t, n) }
            #[inline] fn from_u32(n: u32) -> Option<Self> { uint_to!($t, n) }
            #[inline] fn from_u64(n: u64) -> Option<Self> { uint_to!($t, n) }
        }
    )
}

macro_rules! impl_from_primitive_for_uint {
    ($t:ident) => (
        impl FromPrimitive for $t {
            #[inline] fn from_isize(n: isize) -> Option<Self> { int_to_uint!($t, n) }
            #[inline] fn from_i8(n: i8) -> Option<Self> { int_to_uint!($t, n) }
            #[inline] fn from_i16(n: i16) -> Option<Self> { int_to_uint!($t, n) }
            #[inline] fn from_i32(n: i32) -> Option<Self> { int_to_uint!($t, n) }
            #[inline] fn from_i64(n: i64) -> Option<Self> { int_to_uint!($t, n) }
            #[inline] fn from_usize(n: usize) -> Option<Self> { uint_to!($t, n) }
            #[inline] fn from_u8(n: u8) -> Option<Self> { uint_to!($t, n) }
            #[inline] fn from_u16(n: u16) -> Option<Self> { uint_to!($t, n) }
            #[inline] fn from_u32(n: u32) -> Option<Self> { uint_to!($t, n) }
            #[inline] fn from_u64(n: u64) -> Option<Self> { uint_to!($t, n) }
        }
    )
}

macro_rules! impl_from_primitive_for_float {
    ($t:ident) => (
        impl FromPrimitive for $t {
            #[inline] fn from_isize(n: isize) -> Option<Self> { Some(n as Self) }
            #[inline] fn from_i8(n: i8) -> Option<Self> { Some(n as Self) }
            #[inline] fn from_i16(n: i16) -> Option<Self> { Some(n as Self) }
            #[inline] fn from_i32(n: i32) -> Option<Self> { Some(n as Self) }
            #[inline] fn from_i64(n: i64) -> Option<Self> { Some(n as Self) }
            #[inline] fn from_usize(n: usize) -> Option<Self> { Some(n as Self) }
            #[inline] fn from_u8(n: u8) -> Option<Self> { Some(n as Self) }
            #[inline] fn from_u16(n: u16) -> Option<Self> { Some(n as Self) }
            #[inline] fn from_u32(n: u32) -> Option<Self> { Some(n as Self) }
            #[inline] fn from_u64(n: u64) -> Option<Self> { Some(n as Self) }
        }
    )
}

impl_from_primitive_for_int!(isize);
impl_from_primitive_for_int!(i8);
impl_from_primitive_for_int!(i16);
impl_from_primitive_for_int!(i32);
impl_from_primitive_for_int!(i64);
impl_from_primitive_for_uint!(usize);
impl_from_primitive_for_uint!(u8);
impl_from_primitive_for_uint!(u16);
impl_from_primitive_for_uint!(u32);
impl_from_primitive_for_uint!(u64);
impl_from_primitive_for_float!(f32);
impl_from_primitive_for_float!(f64);
<|endoftext|>


<commit_before>//! Main module to handle the layout.
//! This is where the i3-specific code is.

use std::sync::{Mutex, MutexGuard, TryLockError};
use std::ptr;

use super::container::{Container, Handle, ContainerType};
use super::node::{Node};
use super::super::rustwlc::handle::{WlcView, WlcOutput};

pub type TreeResult = Result<(), TryLockError<MutexGuard<'static, Tree>>>;

const ERR_BAD_TREE: &'static str = "Layout tree was in an invalid configuration";

pub struct Tree {
    root: Node,
    active_container: *const Node,
}

impl Tree {
    fn get_active_container(&self) -> Option<&Node> {
        if self.active_container.is_null() {
            None
        } else {
            unsafe {
                Some(&*self.active_container)
            }
        }
    }

    fn get_active_output(&self) -> Option<&Node> {
        if let Some(node) = self.get_active_container() {
            node.get_ancestor_of_type(ContainerType::Output)
        } else {
            None
        }
    }

    fn get_current_workspace(&self) -> Option<&mut Node> {
        if let Some(container) = self.get_active_container() {
            //if let Some(child) = container.get_ancestor_of_type(ContainerType::Workspace) {
            //return child.get_children()[0].get_parent()

            //}
            // NOTE hack here, remove commented code above to make this work properly
            let parent = container.get_parent().expect(ERR_BAD_TREE);
            for child in parent.get_children_mut() {
                if child == container {
                    return Some(child);
                }
            }
        }
        return None
    }

    fn get_workspace_by_name(&self, name: &str) -> Option<&Node> {
        for child in self.root.get_children()[0].get_children() {
            if child.get_val().get_name().expect(ERR_BAD_TREE) != name {
                continue
            }
            return Some(child);
        }
        return None
    }

    fn get_workspace_by_name_mut(&mut self, name: &str) -> Option<&mut Node> {
        for child in self.root.get_children_mut()[0].get_children_mut() {
            if child.get_val().get_name().expect(ERR_BAD_TREE) != name {
                continue
            }
            return Some(child);
        }
        return None
    }

    fn add_output(&mut self, wlc_output: WlcOutput) {
        self.root.new_child(Container::new_output(wlc_output));
    }

    fn add_workspace(&mut self, name: String) {
        let workspace = Container::new_workspace(name.to_string());
        let mut index = 0;
        if let Some(output) = self.get_active_output() {
            for (cur_index, child) in self.root.get_children().iter().enumerate() {
                if child == output {
                    index = cur_index;
                    break;
                }
            }
        }
        self.root.get_children_mut()[index].new_child(workspace);
    }

    fn add_view(&self, wlc_view: WlcView) {
        if let Some(current_workspace) = self.get_current_workspace() {
            trace!("Adding view {:?} to {:?}", wlc_view, current_workspace);
            current_workspace.new_child(Container::new_view(wlc_view));
        }
    }

    fn remove_view(&self, wlc_view: &WlcView) {
        if let Some(view) = self.root.find_view_by_handle(&wlc_view) {
            let parent = view.get_parent().expect(ERR_BAD_TREE);
            parent.remove_child(view);
        }
    }
}

unsafe impl Send for Tree {}

lazy_static! {
    static ref TREE: Mutex<Tree> = {
        Mutex::new(Tree{
            root: Node::new(Container::new_root()),
            active_container: ptr::null(),
        })
    };
}

pub fn add_output(wlc_output: WlcOutput) -> TreeResult {
    {
        let mut tree = try!(TREE.try_lock());
        tree.add_output(wlc_output);
    }
    try!(add_workspace("1".to_string()));
    try!(switch_workspace(&"1"));
    Ok(())
}

pub fn add_workspace(name: String) -> TreeResult {
    trace!("Adding new workspace to root");
    let mut tree = try!(TREE.lock());
    tree.add_workspace(name);
    Ok(())
}

pub fn add_view(wlc_view: WlcView) -> TreeResult {
    let tree = try!(TREE.lock());
    tree.add_view(wlc_view);
    Ok(())
}

pub fn remove_view(wlc_view: &WlcView) -> TreeResult {
    let tree = try!(TREE.lock());
    tree.remove_view(wlc_view);
    Ok(())
}

pub fn switch_workspace(name: &str) -> TreeResult {
    trace!("Switching to workspace {}", name);
    let mut tree = try!(TREE.lock());
    if let Some(old_workspace) = tree.get_current_workspace() {
        // Make all the views in the original workspace to be invisible
        for view in old_workspace.get_children_mut() {
            trace!("Setting {:?} invisible", view);
            match view.get_val().get_handle().expect(ERR_BAD_TREE) {
                Handle::View(view) => view.set_mask(0),
                _ => {},
            }
        }
    }
    let current_workspace: *const Node;
    {
        if let Some(_) = tree.get_workspace_by_name(name) {
            trace!("Found workspace {}", name);
        } else {
            trace!("Adding workspace {}", name);
            try!(add_workspace(name.to_string()));
        }
        let new_current_workspace = tree.get_workspace_by_name_mut(name).expect(ERR_BAD_TREE);
        for view in new_current_workspace.get_children_mut() {
            trace!("Setting {:?} visible", view);
            match view.get_val().get_handle().expect(ERR_BAD_TREE) {
                Handle::View(view) => view.set_mask(1),
                _ => {},
            }
        }
        // Set the first view to be focused, so that the view is updated to this new workspace
        if new_current_workspace.get_children().len() > 0 {
            trace!("Focusing view");
            match new_current_workspace.get_children_mut()[0]
                .get_val().get_handle().expect(ERR_BAD_TREE) {
                Handle::View(view) => view.focus(),
                _ => {},
            }
        } else {
            WlcView::root().focus();
        }
        current_workspace = new_current_workspace as *const Node;
    }
    tree.active_container = current_workspace;
    Ok(())
}
<commit_msg>Workspace hotfix, should no longer lock up when switching workspaces<commit_after>//! Main module to handle the layout.
//! This is where the i3-specific code is.

use std::sync::{Mutex, MutexGuard, TryLockError};
use std::ptr;

use super::container::{Container, Handle, ContainerType};
use super::node::{Node};
use super::super::rustwlc::handle::{WlcView, WlcOutput};

pub type TreeResult = Result<(), TryLockError<MutexGuard<'static, Tree>>>;

const ERR_BAD_TREE: &'static str = "Layout tree was in an invalid configuration";

pub struct Tree {
    root: Node,
    active_container: *const Node,
}

impl Tree {
    fn get_active_container(&self) -> Option<&Node> {
        if self.active_container.is_null() {
            None
        } else {
            unsafe {
                Some(&*self.active_container)
            }
        }
    }

    fn get_active_output(&self) -> Option<&Node> {
        if let Some(node) = self.get_active_container() {
            node.get_ancestor_of_type(ContainerType::Output)
        } else {
            None
        }
    }

    fn get_current_workspace(&self) -> Option<&mut Node> {
        if let Some(container) = self.get_active_container() {
            //if let Some(child) = container.get_ancestor_of_type(ContainerType::Workspace) {
            //return child.get_children()[0].get_parent()

            //}
            // NOTE hack here, remove commented code above to make this work properly
            let parent = container.get_parent().expect(ERR_BAD_TREE);
            for child in parent.get_children_mut() {
                if child == container {
                    return Some(child);
                }
            }
        }
        return None
    }

    fn get_workspace_by_name(&self, name: &str) -> Option<&Node> {
        for child in self.root.get_children()[0].get_children() {
            if child.get_val().get_name().expect(ERR_BAD_TREE) != name {
                continue
            }
            return Some(child);
        }
        return None
    }

    fn get_workspace_by_name_mut(&mut self, name: &str) -> Option<&mut Node> {
        for child in self.root.get_children_mut()[0].get_children_mut() {
            if child.get_val().get_name().expect(ERR_BAD_TREE) != name {
                continue
            }
            return Some(child);
        }
        return None
    }

    fn add_output(&mut self, wlc_output: WlcOutput) {
        self.root.new_child(Container::new_output(wlc_output));
    }

    fn add_workspace(&mut self, name: String) {
        let workspace = Container::new_workspace(name.to_string());
        let mut index = 0;
        if let Some(output) = self.get_active_output() {
            for (cur_index, child) in self.root.get_children().iter().enumerate() {
                if child == output {
                    index = cur_index;
                    break;
                }
            }
        }
        self.root.get_children_mut()[index].new_child(workspace);
    }

    fn add_view(&self, wlc_view: WlcView) {
        if let Some(current_workspace) = self.get_current_workspace() {
            trace!("Adding view {:?} to {:?}", wlc_view, current_workspace);
            current_workspace.new_child(Container::new_view(wlc_view));
        }
    }

    fn remove_view(&self, wlc_view: &WlcView) {
        if let Some(view) = self.root.find_view_by_handle(&wlc_view) {
            let parent = view.get_parent().expect(ERR_BAD_TREE);
            parent.remove_child(view);
        }
    }
}

unsafe impl Send for Tree {}

lazy_static! {
    static ref TREE: Mutex<Tree> = {
        Mutex::new(Tree{
            root: Node::new(Container::new_root()),
            active_container: ptr::null(),
        })
    };
}

pub fn add_output(wlc_output: WlcOutput) -> TreeResult {
    {
        let mut tree = try!(TREE.try_lock());
        tree.add_output(wlc_output);
    }
    try!(add_workspace("1".to_string()));
    try!(switch_workspace(&"1"));
    Ok(())
}

pub fn add_workspace(name: String) -> TreeResult {
    trace!("Adding new workspace to root");
    let mut tree = try!(TREE.lock());
    tree.add_workspace(name);
    Ok(())
}

pub fn add_view(wlc_view: WlcView) -> TreeResult {
    let tree = try!(TREE.lock());
    tree.add_view(wlc_view);
    Ok(())
}

pub fn remove_view(wlc_view: &WlcView) -> TreeResult {
    let tree = try!(TREE.lock());
    tree.remove_view(wlc_view);
    Ok(())
}

pub fn switch_workspace(name: &str) -> TreeResult {
    trace!("Switching to workspace {}", name);
    let mut tree = try!(TREE.lock());
    if let Some(old_workspace) = tree.get_current_workspace() {
        // Make all the views in the original workspace to be invisible
        for view in old_workspace.get_children_mut() {
            trace!("Setting {:?} invisible", view);
            match view.get_val().get_handle().expect(ERR_BAD_TREE) {
                Handle::View(view) => view.set_mask(0),
                _ => {},
            }
        }
    }
    let current_workspace: *const Node;
    {
        if let Some(_) = tree.get_workspace_by_name(name) {
            trace!("Found workspace {}", name);
        } else {
            trace!("Adding workspace {}", name);
            tree.add_workspace(name.to_string());
        }
        let new_current_workspace = tree.get_workspace_by_name_mut(name).expect(ERR_BAD_TREE);
        for view in new_current_workspace.get_children_mut() {
            trace!("Setting {:?} visible", view);
            match view.get_val().get_handle().expect(ERR_BAD_TREE) {
                Handle::View(view) => view.set_mask(1),
                _ => {},
            }
        }
        // Set the first view to be focused, so that the view is updated to this new workspace
        if new_current_workspace.get_children().len() > 0 {
            trace!("Focusing view");
            match new_current_workspace.get_children_mut()[0]
                .get_val().get_handle().expect(ERR_BAD_TREE) {
                Handle::View(view) => view.focus(),
                _ => {},
            }
        } else {
            WlcView::root().focus();
        }
        current_workspace = new_current_workspace as *const Node;
    }
    tree.active_container = current_workspace;
    Ok(())
}
<|endoftext|>


<commit_before>/*!
A macro for declaring lazily evaluated statics.

Using this macro, it is possible to have `static`s that require code to be
executed at runtime in order to be initialized.
This includes anything requiring heap allocations, like vectors or hash maps,
as well as anything that requires function calls to be computed.

# Syntax

```rust
lazy_static! {
    static ref NAME_1: TYPE_1 = EXPR_1;
    static ref NAME_2: TYPE_2 = EXPR_2;
    ...
    static ref NAME_N: TYPE_N = EXPR_N;
}
```

# Semantic

For a given `static ref NAME: TYPE = EXPR;`, the macro generates a
unique type that implements `Deref<TYPE>` and stores it in a static with name `NAME`.

On first deref, `EXPR` gets evaluated and stored internally, such that all further derefs
can return a reference to the same object.

Like regular `static mut`s, this macro only works for types that fulfill the `Share`
trait.

# Example

Using the macro:

```rust
#![feature(phase)]

#[phase(plugin)]
extern crate lazy_static;

use std::collections::HashMap;

lazy_static! {
    static ref HASHMAP: HashMap<uint, &'static str> = {
        let mut m = HashMap::new();
        m.insert(0u, "foo");
        m.insert(1u, "bar");
        m.insert(2u, "baz");
        m
    };
    static ref COUNT: uint = HASHMAP.len();
    static ref NUMBER: uint = times_two(21);
}

fn times_two(n: uint) -> uint { n * 2 }

fn main() {
    println!("The map has {} entries.", *COUNT);
    println!("The entry for `0` is \"{}\".", HASHMAP.get(&0));
    println!("A expensive calculation on a static results in: {}.", *NUMBER);
}
```

# Implementation details

The `Deref` implementation uses a hidden `static mut` that is guarded by a atomic check
using the `sync::Once` abstraction. All lazily evaluated values are currently
put in a heap allocated box, due to the Rust language currently not providing any way to
define uninitialized `static mut` values.

*/

#![crate_id = "lazy_static"]
#![crate_type = "dylib"]
#![license = "MIT"]

#![feature(macro_rules)]

#[macro_export]
macro_rules! lazy_static {
    ($(static ref $N:ident : $T:ty = $e:expr;)*) => {
        $(
            #[allow(non_camel_case_types)]
            #[allow(dead_code)]
            struct $N {__unit__: ()}
            static $N: $N = $N {__unit__: ()};
            impl Deref<$T> for $N {
                fn deref<'a>(&'a self) -> &'a $T {
                    use std::sync::{Once, ONCE_INIT};
                    use std::mem::transmute;

                    #[inline(always)]
                    fn require_share<T: Share>(_: &T) { }

                    unsafe {
                        static mut s: *$T = 0 as *$T;
                        static mut ONCE: Once = ONCE_INIT;
                        ONCE.doit(|| {
                            s = transmute::<Box<$T>, *$T>(box() ($e));
                        });
                        let static_ref = &*s;
                        require_share(static_ref);
                        static_ref
                    }
                }
            }

        )*
    }
}

#[cfg(test)]
mod test {
    use std::collections::HashMap;

    lazy_static! {
        static ref NUMBER: uint = times_two(3);
        static ref VEC: [Box<uint>, ..3] = [box 1, box 2, box 3];
        static ref OWNED_STRING: String = "hello".to_string();
        static ref HASHMAP: HashMap<uint, &'static str> = {
            let mut m = HashMap::new();
            m.insert(0u, "abc");
            m.insert(1, "def");
            m.insert(2, "ghi");
            m
        };
        static ref UNUSED: () = ();
    }

    fn times_two(n: uint) -> uint {
        n * 2
    }

    #[test]
    fn test_basic() {
        assert_eq!(OWNED_STRING.as_slice(), "hello");
        assert_eq!(*NUMBER, 6);
        assert!(HASHMAP.find(&1).is_some());
        assert!(HASHMAP.find(&3).is_none());
        assert_eq!(VEC.as_slice(), &[box 1, box 2, box 3]);
    }

    #[test]
    fn test_repeat() {
        assert_eq!(*NUMBER, 6);
        assert_eq!(*NUMBER, 6);
        assert_eq!(*NUMBER, 6);
    }
}
<commit_msg>Fix *T -> *const breakage<commit_after>/*!
A macro for declaring lazily evaluated statics.

Using this macro, it is possible to have `static`s that require code to be
executed at runtime in order to be initialized.
This includes anything requiring heap allocations, like vectors or hash maps,
as well as anything that requires function calls to be computed.

# Syntax

```rust
lazy_static! {
    static ref NAME_1: TYPE_1 = EXPR_1;
    static ref NAME_2: TYPE_2 = EXPR_2;
    ...
    static ref NAME_N: TYPE_N = EXPR_N;
}
```

# Semantic

For a given `static ref NAME: TYPE = EXPR;`, the macro generates a
unique type that implements `Deref<TYPE>` and stores it in a static with name `NAME`.

On first deref, `EXPR` gets evaluated and stored internally, such that all further derefs
can return a reference to the same object.

Like regular `static mut`s, this macro only works for types that fulfill the `Share`
trait.

# Example

Using the macro:

```rust
#![feature(phase)]

#[phase(plugin)]
extern crate lazy_static;

use std::collections::HashMap;

lazy_static! {
    static ref HASHMAP: HashMap<uint, &'static str> = {
        let mut m = HashMap::new();
        m.insert(0u, "foo");
        m.insert(1u, "bar");
        m.insert(2u, "baz");
        m
    };
    static ref COUNT: uint = HASHMAP.len();
    static ref NUMBER: uint = times_two(21);
}

fn times_two(n: uint) -> uint { n * 2 }

fn main() {
    println!("The map has {} entries.", *COUNT);
    println!("The entry for `0` is \"{}\".", HASHMAP.get(&0));
    println!("A expensive calculation on a static results in: {}.", *NUMBER);
}
```

# Implementation details

The `Deref` implementation uses a hidden `static mut` that is guarded by a atomic check
using the `sync::Once` abstraction. All lazily evaluated values are currently
put in a heap allocated box, due to the Rust language currently not providing any way to
define uninitialized `static mut` values.

*/

#![crate_id = "lazy_static"]
#![crate_type = "dylib"]
#![license = "MIT"]

#![feature(macro_rules)]

#[macro_export]
macro_rules! lazy_static {
    ($(static ref $N:ident : $T:ty = $e:expr;)*) => {
        $(
            #[allow(non_camel_case_types)]
            #[allow(dead_code)]
            struct $N {__unit__: ()}
            static $N: $N = $N {__unit__: ()};
            impl Deref<$T> for $N {
                fn deref<'a>(&'a self) -> &'a $T {
                    use std::sync::{Once, ONCE_INIT};
                    use std::mem::transmute;

                    #[inline(always)]
                    fn require_share<T: Share>(_: &T) { }

                    unsafe {
                        static mut s: *const $T = 0 as *const $T;
                        static mut ONCE: Once = ONCE_INIT;
                        ONCE.doit(|| {
                            s = transmute::<Box<$T>, *const $T>(box() ($e));
                        });
                        let static_ref = &*s;
                        require_share(static_ref);
                        static_ref
                    }
                }
            }

        )*
    }
}

#[cfg(test)]
mod test {
    use std::collections::HashMap;

    lazy_static! {
        static ref NUMBER: uint = times_two(3);
        static ref VEC: [Box<uint>, ..3] = [box 1, box 2, box 3];
        static ref OWNED_STRING: String = "hello".to_string();
        static ref HASHMAP: HashMap<uint, &'static str> = {
            let mut m = HashMap::new();
            m.insert(0u, "abc");
            m.insert(1, "def");
            m.insert(2, "ghi");
            m
        };
        static ref UNUSED: () = ();
    }

    fn times_two(n: uint) -> uint {
        n * 2
    }

    #[test]
    fn test_basic() {
        assert_eq!(OWNED_STRING.as_slice(), "hello");
        assert_eq!(*NUMBER, 6);
        assert!(HASHMAP.find(&1).is_some());
        assert!(HASHMAP.find(&3).is_none());
        assert_eq!(VEC.as_slice(), &[box 1, box 2, box 3]);
    }

    #[test]
    fn test_repeat() {
        assert_eq!(*NUMBER, 6);
        assert_eq!(*NUMBER, 6);
        assert_eq!(*NUMBER, 6);
    }
}
<|endoftext|>


<commit_before>#[doc = "Operations and constants for `u64`"];

/*
Module: u64
*/

/*
Const: min_value

Return the minimal value for a u64
*/
const min_value: u64 = 0u64;

/*
Const: max_value

Return the maximal value for a u64
*/
const max_value: u64 = 0u64 - 1u64;

pure fn min(x: u64, y: u64) -> u64 { if x < y { x } else { y } }
pure fn max(x: u64, y: u64) -> u64 { if x > y { x } else { y } }

/* Function: add */
pure fn add(x: u64, y: u64) -> u64 { ret x + y; }

/* Function: sub */
pure fn sub(x: u64, y: u64) -> u64 { ret x - y; }

/* Function: mul */
pure fn mul(x: u64, y: u64) -> u64 { ret x * y; }

/* Function: div */
pure fn div(x: u64, y: u64) -> u64 { ret x / y; }

/* Function: rem */
pure fn rem(x: u64, y: u64) -> u64 { ret x % y; }

/* Predicate: lt */
pure fn lt(x: u64, y: u64) -> bool { ret x < y; }

/* Predicate: le */
pure fn le(x: u64, y: u64) -> bool { ret x <= y; }

/* Predicate: eq */
pure fn eq(x: u64, y: u64) -> bool { ret x == y; }

/* Predicate: ne */
pure fn ne(x: u64, y: u64) -> bool { ret x != y; }

/* Predicate: ge */
pure fn ge(x: u64, y: u64) -> bool { ret x >= y; }

/* Predicate: gt */
pure fn gt(x: u64, y: u64) -> bool { ret x > y; }

/*
Function: range

Iterate over the range [`lo`..`hi`)
*/
fn range(lo: u64, hi: u64, it: fn(u64)) {
    let i = lo;
    while i < hi { it(i); i += 1u64; }
}

/*
Function: to_str

Convert to a string in a given base
*/
fn to_str(n: u64, radix: uint) -> str {
    assert (0u < radix && radix <= 16u);

    let r64 = radix as u64;

    fn digit(n: u64) -> str {
        ret alt n {
              0u64 { "0" }
              1u64 { "1" }
              2u64 { "2" }
              3u64 { "3" }
              4u64 { "4" }
              5u64 { "5" }
              6u64 { "6" }
              7u64 { "7" }
              8u64 { "8" }
              9u64 { "9" }
              10u64 { "a" }
              11u64 { "b" }
              12u64 { "c" }
              13u64 { "d" }
              14u64 { "e" }
              15u64 { "f" }
              _ { fail }
            };
    }

    if n == 0u64 { ret "0"; }

    let s = "";

    let n = n;
    while n > 0u64 { s = digit(n % r64) + s; n /= r64; }
    ret s;
}

/*
Function: str

Convert to a string
*/
fn str(n: u64) -> str { ret to_str(n, 10u); }

/*
Function: from_str

Parse a string as an unsigned integer.
*/
fn from_str(buf: str, radix: u64) -> option<u64> {
    if str::len_bytes(buf) == 0u { ret none; }
    let i = str::len_bytes(buf) - 1u;
    let power = 1u64, n = 0u64;
    while true {
        alt char::to_digit(buf[i] as char, radix) {
          some(d) { n += d as u64 * power; }
          none { ret none; }
        }
        power *= radix;
        if i == 0u { ret some(n); }
        i -= 1u;
    }
    fail;
}

#[doc = "Computes the bitwise complement"]
fn compl(i: u64) -> u64 {
    max_value ^ i
}
<commit_msg>Fix uint/u64 confusion<commit_after>#[doc = "Operations and constants for `u64`"];

/*
Module: u64
*/

/*
Const: min_value

Return the minimal value for a u64
*/
const min_value: u64 = 0u64;

/*
Const: max_value

Return the maximal value for a u64
*/
const max_value: u64 = 0u64 - 1u64;

pure fn min(x: u64, y: u64) -> u64 { if x < y { x } else { y } }
pure fn max(x: u64, y: u64) -> u64 { if x > y { x } else { y } }

/* Function: add */
pure fn add(x: u64, y: u64) -> u64 { ret x + y; }

/* Function: sub */
pure fn sub(x: u64, y: u64) -> u64 { ret x - y; }

/* Function: mul */
pure fn mul(x: u64, y: u64) -> u64 { ret x * y; }

/* Function: div */
pure fn div(x: u64, y: u64) -> u64 { ret x / y; }

/* Function: rem */
pure fn rem(x: u64, y: u64) -> u64 { ret x % y; }

/* Predicate: lt */
pure fn lt(x: u64, y: u64) -> bool { ret x < y; }

/* Predicate: le */
pure fn le(x: u64, y: u64) -> bool { ret x <= y; }

/* Predicate: eq */
pure fn eq(x: u64, y: u64) -> bool { ret x == y; }

/* Predicate: ne */
pure fn ne(x: u64, y: u64) -> bool { ret x != y; }

/* Predicate: ge */
pure fn ge(x: u64, y: u64) -> bool { ret x >= y; }

/* Predicate: gt */
pure fn gt(x: u64, y: u64) -> bool { ret x > y; }

/*
Function: range

Iterate over the range [`lo`..`hi`)
*/
fn range(lo: u64, hi: u64, it: fn(u64)) {
    let i = lo;
    while i < hi { it(i); i += 1u64; }
}

/*
Function: to_str

Convert to a string in a given base
*/
fn to_str(n: u64, radix: uint) -> str {
    assert (0u < radix && radix <= 16u);

    let r64 = radix as u64;

    fn digit(n: u64) -> str {
        ret alt n {
              0u64 { "0" }
              1u64 { "1" }
              2u64 { "2" }
              3u64 { "3" }
              4u64 { "4" }
              5u64 { "5" }
              6u64 { "6" }
              7u64 { "7" }
              8u64 { "8" }
              9u64 { "9" }
              10u64 { "a" }
              11u64 { "b" }
              12u64 { "c" }
              13u64 { "d" }
              14u64 { "e" }
              15u64 { "f" }
              _ { fail }
            };
    }

    if n == 0u64 { ret "0"; }

    let s = "";

    let n = n;
    while n > 0u64 { s = digit(n % r64) + s; n /= r64; }
    ret s;
}

/*
Function: str

Convert to a string
*/
fn str(n: u64) -> str { ret to_str(n, 10u); }

/*
Function: from_str

Parse a string as an unsigned integer.
*/
fn from_str(buf: str, radix: u64) -> option<u64> {
    if str::len_bytes(buf) == 0u { ret none; }
    let i = str::len_bytes(buf) - 1u;
    let power = 1u64, n = 0u64;
    while true {
        alt char::to_digit(buf[i] as char, radix as uint) {
          some(d) { n += d as u64 * power; }
          none { ret none; }
        }
        power *= radix;
        if i == 0u { ret some(n); }
        i -= 1u;
    }
    fail;
}

#[doc = "Computes the bitwise complement"]
fn compl(i: u64) -> u64 {
    max_value ^ i
}
<|endoftext|>


<commit_before>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Miscellaneous helpers for common patterns.

use cast;
use ptr;
use prelude::*;
use unstable::intrinsics;

/// The identity function.
#[inline]
pub fn id<T>(x: T) -> T { x }

/// Ignores a value.
#[inline]
pub fn ignore<T>(_x: T) { }

/// Sets `*ptr` to `new_value`, invokes `op()`, and then restores the
/// original value of `*ptr`.
///
/// NB: This function accepts `@mut T` and not `&mut T` to avoid
/// an obvious borrowck hazard. Typically passing in `&mut T` will
/// cause borrow check errors because it freezes whatever location
/// that `&mut T` is stored in (either statically or dynamically).
#[inline]
pub fn with<T,R>(
    ptr: @mut T,
    value: T,
    op: &fn() -> R) -> R
{
    let prev = replace(ptr, value);
    let result = op();
    *ptr = prev;
    return result;
}

/**
 * Swap the values at two mutable locations of the same type, without
 * deinitialising or copying either one.
 */
#[inline]
pub fn swap<T>(x: &mut T, y: &mut T) {
    unsafe {
        // Give ourselves some scratch space to work with
        let mut tmp: T = intrinsics::uninit();
        let t: *mut T = &mut tmp;

        // Perform the swap, `&mut` pointers never alias
        ptr::copy_nonoverlapping_memory(t, x, 1);
        ptr::copy_nonoverlapping_memory(x, y, 1);
        ptr::copy_nonoverlapping_memory(y, t, 1);

        // y and t now point to the same thing, but we need to completely forget `tmp`
        // because it's no longer relevant.
        cast::forget(tmp);
    }
}

/**
 * Replace the value at a mutable location with a new one, returning the old
 * value, without deinitialising or copying either one.
 */
#[inline]
pub fn replace<T>(dest: &mut T, mut src: T) -> T {
    swap(dest, &mut src);
    src
}

/// A non-copyable dummy type.
#[deriving(Eq, TotalEq, Ord, TotalOrd)]
#[unsafe_no_drop_flag]
pub struct NonCopyable;

impl Drop for NonCopyable {
    fn drop(&self) { }
}

/// A type with no inhabitants
pub enum Void { }

impl Void {
    /// A utility function for ignoring this uninhabited type
    pub fn uninhabited(self) -> ! {
        match self {
            // Nothing to match on
        }
    }
}

/**
A utility function for indicating unreachable code. It will fail if
executed. This is occasionally useful to put after loops that never
terminate normally, but instead directly return from a function.

# Example

~~~ {.rust}
fn choose_weighted_item(v: &[Item]) -> Item {
    assert!(!v.is_empty());
    let mut so_far = 0u;
    for v.each |item| {
        so_far += item.weight;
        if so_far > 100 {
            return item;
        }
    }
    // The above loop always returns, so we must hint to the
    // type checker that it isn't possible to get down here
    util::unreachable();
}
~~~

*/
pub fn unreachable() -> ! {
    fail!("internal error: entered unreachable code");
}

#[cfg(test)]
mod tests {
    use super::*;
    use option::{None, Some};
    use either::{Either, Left, Right};
    use sys::size_of;
    use kinds::Drop;

    #[test]
    fn identity_crisis() {
        // Writing a test for the identity function. How did it come to this?
        let x = ~[(5, false)];
        //FIXME #3387 assert!(x.eq(id(copy x)));
        let y = copy x;
        assert!(x.eq(&id(y)));
    }

    #[test]
    fn test_swap() {
        let mut x = 31337;
        let mut y = 42;
        swap(&mut x, &mut y);
        assert_eq!(x, 42);
        assert_eq!(y, 31337);
    }

    #[test]
    fn test_replace() {
        let mut x = Some(NonCopyable);
        let y = replace(&mut x, None);
        assert!(x.is_none());
        assert!(y.is_some());
    }

    #[test]
    fn test_uninhabited() {
        let could_only_be_coin : Either <Void, ()> = Right (());
        match could_only_be_coin {
            Right (coin) => coin,
            Left (is_void) => is_void.uninhabited ()
        }
    }

    #[test]
    fn test_noncopyable() {
        assert_eq!(size_of::<NonCopyable>(), 0);

        // verify that `#[unsafe_no_drop_flag]` works as intended on a zero-size struct

        static mut did_run: bool = false;

        struct Foo { five: int }

        impl Drop for Foo {
            fn drop(&self) {
                assert_eq!(self.five, 5);
                unsafe {
                    did_run = true;
                }
            }
        }

        {
            let _a = (NonCopyable, Foo { five: 5 }, NonCopyable);
        }

        unsafe { assert_eq!(did_run, true); }
    }
}
<commit_msg>fix stage0 build<commit_after>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Miscellaneous helpers for common patterns.

use cast;
use ptr;
use prelude::*;
use unstable::intrinsics;

/// The identity function.
#[inline]
pub fn id<T>(x: T) -> T { x }

/// Ignores a value.
#[inline]
pub fn ignore<T>(_x: T) { }

/// Sets `*ptr` to `new_value`, invokes `op()`, and then restores the
/// original value of `*ptr`.
///
/// NB: This function accepts `@mut T` and not `&mut T` to avoid
/// an obvious borrowck hazard. Typically passing in `&mut T` will
/// cause borrow check errors because it freezes whatever location
/// that `&mut T` is stored in (either statically or dynamically).
#[inline]
pub fn with<T,R>(
    ptr: @mut T,
    value: T,
    op: &fn() -> R) -> R
{
    let prev = replace(ptr, value);
    let result = op();
    *ptr = prev;
    return result;
}

/**
 * Swap the values at two mutable locations of the same type, without
 * deinitialising or copying either one.
 */
#[inline]
pub fn swap<T>(x: &mut T, y: &mut T) {
    unsafe {
        // Give ourselves some scratch space to work with
        let mut tmp: T = intrinsics::uninit();
        let t: *mut T = &mut tmp;

        // Perform the swap, `&mut` pointers never alias
        ptr::copy_nonoverlapping_memory(t, x, 1);
        ptr::copy_nonoverlapping_memory(x, y, 1);
        ptr::copy_nonoverlapping_memory(y, t, 1);

        // y and t now point to the same thing, but we need to completely forget `tmp`
        // because it's no longer relevant.
        cast::forget(tmp);
    }
}

/**
 * Replace the value at a mutable location with a new one, returning the old
 * value, without deinitialising or copying either one.
 */
#[inline]
pub fn replace<T>(dest: &mut T, mut src: T) -> T {
    swap(dest, &mut src);
    src
}

/// A non-copyable dummy type.
#[deriving(Eq, TotalEq, Ord, TotalOrd)]
#[unsafe_no_drop_flag]
pub struct NonCopyable;

impl Drop for NonCopyable {
    fn drop(&self) { }
}

/// A type with no inhabitants
pub enum Void { }

impl Void {
    /// A utility function for ignoring this uninhabited type
    pub fn uninhabited(self) -> ! {
        match self {
            // Nothing to match on
        }
    }
}

/**
A utility function for indicating unreachable code. It will fail if
executed. This is occasionally useful to put after loops that never
terminate normally, but instead directly return from a function.

# Example

~~~ {.rust}
fn choose_weighted_item(v: &[Item]) -> Item {
    assert!(!v.is_empty());
    let mut so_far = 0u;
    for v.each |item| {
        so_far += item.weight;
        if so_far > 100 {
            return item;
        }
    }
    // The above loop always returns, so we must hint to the
    // type checker that it isn't possible to get down here
    util::unreachable();
}
~~~

*/
pub fn unreachable() -> ! {
    fail!("internal error: entered unreachable code");
}

#[cfg(test)]
mod tests {
    use super::*;
    use option::{None, Some};
    use either::{Either, Left, Right};
    use sys::size_of;
    use kinds::Drop;

    #[test]
    fn identity_crisis() {
        // Writing a test for the identity function. How did it come to this?
        let x = ~[(5, false)];
        //FIXME #3387 assert!(x.eq(id(copy x)));
        let y = copy x;
        assert!(x.eq(&id(y)));
    }

    #[test]
    fn test_swap() {
        let mut x = 31337;
        let mut y = 42;
        swap(&mut x, &mut y);
        assert_eq!(x, 42);
        assert_eq!(y, 31337);
    }

    #[test]
    fn test_replace() {
        let mut x = Some(NonCopyable);
        let y = replace(&mut x, None);
        assert!(x.is_none());
        assert!(y.is_some());
    }

    #[test]
    fn test_uninhabited() {
        let could_only_be_coin : Either <Void, ()> = Right (());
        match could_only_be_coin {
            Right (coin) => coin,
            Left (is_void) => is_void.uninhabited ()
        }
    }

    #[test]
    fn test_noncopyable() {
        assert_eq!(size_of::<NonCopyable>(), 0);

        // verify that `#[unsafe_no_drop_flag]` works as intended on a zero-size struct

        // NOTE: uncomment after snapshot, will not parse yet
        //static mut did_run: bool = false;

        struct Foo { five: int }

        impl Drop for Foo {
            fn drop(&self) {
                assert_eq!(self.five, 5);
                // NOTE: uncomment after snapshot, will not parse yet
                //unsafe {
                    //did_run = true;
                //}
            }
        }

        {
            let _a = (NonCopyable, Foo { five: 5 }, NonCopyable);
        }

        // NOTE: uncomment after snapshot, will not parse yet
        //unsafe { assert_eq!(did_run, true); }
    }
}
<|endoftext|>


<commit_before>use crate::model::{read_uint, write_uint};
use serde::Serialize;
use shakmaty::{Color, Outcome};
use std::{
    io::{self, Read, Write},
    ops::AddAssign,
};

#[derive(Debug, Default, Clone, Serialize)]
pub struct Stats {
    white: u64,
    draws: u64,
    black: u64,
}

impl From<Outcome> for Stats {
    fn from(outcome: Outcome) -> Stats {
        Stats {
            white: if outcome.winner() == Some(Color::White) {
                1
            } else {
                0
            },
            black: if outcome.winner() == Some(Color::Black) {
                1
            } else {
                0
            },
            draws: if outcome.winner().is_none() { 1 } else { 0 },
        }
    }
}

impl AddAssign for Stats {
    fn add_assign(&mut self, rhs: Stats) {
        self.white += rhs.white;
        self.draws += rhs.draws;
        self.black += rhs.black;
    }
}

impl Stats {
    pub fn total(&self) -> u64 {
        self.white + self.draws + self.black
    }

    pub fn read<R: Read>(reader: &mut R) -> io::Result<Stats> {
        Ok(Stats {
            white: read_uint(reader)?,
            draws: read_uint(reader)?,
            black: read_uint(reader)?,
        })
    }

    pub fn write<W: Write>(&self, writer: &mut W) -> io::Result<()> {
        write_uint(writer, self.white)?;
        write_uint(writer, self.draws)?;
        write_uint(writer, self.black)
    }
}
<commit_msg>make Stats fields public<commit_after>use crate::model::{read_uint, write_uint};
use serde::Serialize;
use shakmaty::{Color, Outcome};
use std::{
    io::{self, Read, Write},
    ops::AddAssign,
};

#[derive(Debug, Default, Clone, Serialize)]
pub struct Stats {
    pub white: u64,
    pub draws: u64,
    pub black: u64,
}

impl From<Outcome> for Stats {
    fn from(outcome: Outcome) -> Stats {
        Stats {
            white: if outcome.winner() == Some(Color::White) {
                1
            } else {
                0
            },
            black: if outcome.winner() == Some(Color::Black) {
                1
            } else {
                0
            },
            draws: if outcome.winner().is_none() { 1 } else { 0 },
        }
    }
}

impl AddAssign for Stats {
    fn add_assign(&mut self, rhs: Stats) {
        self.white += rhs.white;
        self.draws += rhs.draws;
        self.black += rhs.black;
    }
}

impl Stats {
    pub fn total(&self) -> u64 {
        self.white + self.draws + self.black
    }

    pub fn read<R: Read>(reader: &mut R) -> io::Result<Stats> {
        Ok(Stats {
            white: read_uint(reader)?,
            draws: read_uint(reader)?,
            black: read_uint(reader)?,
        })
    }

    pub fn write<W: Write>(&self, writer: &mut W) -> io::Result<()> {
        write_uint(writer, self.white)?;
        write_uint(writer, self.draws)?;
        write_uint(writer, self.black)
    }
}
<|endoftext|>


<commit_before>use structs::Data;
use nn::Network;
use nalgebra::{DVector, DMatrix};

pub fn sgd(mut nn: &mut Network,
           mut training_data: Vec<Data>,
           epochs: u8, mini_batch_size: u8,
           eta: f32) {
    use rand::{ self, Rng};
    let mut rng = rand::thread_rng();

    for j in 0..epochs {
        rng.shuffle(&mut training_data);
        for mut mini_batch in training_data.chunks_mut(mini_batch_size as usize) {
            update_mini_batch(&mut nn, &mut mini_batch, eta);
        }
        println!("Epoch {} complete!", j);
    }
}

fn update_mini_batch(mut nn: &mut Network, mut mini_batch: &mut [Data], eta: f32) {
    // holds all biases of the network
    let mut nabla_b: Vec<DVector<f32>> = Vec::with_capacity(nn.get_biases().len());
    for biases in nn.get_biases() {
        nabla_b.push(DVector::from_element(biases.len(), 0.0f32));
    }
    // holds all weights of the network
    let mut nabla_w: Vec<DMatrix<f32>> = Vec::with_capacity(nn.get_weights().len());
    for weights in nn.get_weights() {
        nabla_w.push(DMatrix::from_element(weights.nrows(), weights.ncols(), 0.0f32));
    }

    let mini_batch_len = mini_batch.len();

    // for each dataset in mini_batch: calculate gradients, add to nablas
    for data in mini_batch {
        let (delta_nabla_b, delta_nabla_w) = backprop(&mut nn,
                                                      data.get_input(),
                                                      data.get_class_vector());
        for (mut nb, dnb) in nabla_b.iter_mut().zip(delta_nabla_b.iter()) {
            // TODO: This is really not good. Someone needs to fix this.
            *nb += dnb.clone();
        }
        for (mut nw, dnw) in nabla_w.iter_mut().zip(delta_nabla_w.iter()) {
            // TODO: Same as above.
            *nw += dnw.clone();
        }
    }

    for (mut w, nw) in nn.get_weights_mut().iter_mut().zip( nabla_w.iter() ) {
        *w -= eta / (mini_batch_len as f32) * nw.clone();
    }

    for (mut b, nb) in nn.get_biases_mut().iter_mut().zip( nabla_b.iter() ) {
        *b -= eta / (mini_batch_len as f32) * nb.clone();
    }
}

fn backprop(nn: &mut Network, data: &DVector<f32>, desired_output: &DVector<f32>)
            -> (Vec<DVector<f32>>, Vec<DMatrix<f32>>) {
    use nalgebra::{self, dot};
    use nn;

    // holds all biases of the network
    let mut nabla_b: Vec<DVector<f32>> = Vec::with_capacity(nn.get_biases().len());
    for biases in nn.get_biases() {
        nabla_b.push(DVector::from_element(biases.len(), 0.0f32));
    }
    // holds all weights of the network
    let mut nabla_w: Vec<DMatrix<f32>> = Vec::with_capacity(nn.get_weights().len());
    for weights in nn.get_weights() {
        nabla_w.push(DMatrix::from_element(weights.nrows(), weights.ncols(), 0.0f32));
    }

    // feedforward
    // current activation layer, at the beginning this is the input
    // Note: Clone here because in later iterations activation will actually hold the
    // ownership of the Vector (or rather the activations vector will). However this might
    // still be a performance issue since we call this once per training data.
    let mut activation = data.clone();

    // hold all activation layers (including output)
    let mut activations: Vec<DVector<f32>> = Vec::with_capacity(nn.get_layers().len());
    // hold z where z is the input of the sigmoid function for each layer
    let mut zs: Vec<DVector<f32>> = Vec::with_capacity(nn.get_layers().len());

    activations.push(activation);
    // execute feedforward
    for (biases, weights) in nn.get_biases().iter().zip(nn.get_weights().iter()) {
        // TODO: Remove Clone
        let z = weights * &activations[activations.len()-1] + biases.clone();
        zs.push(z);
        activation = nn::sigmoid(&zs[zs.len()-1]);
        activations.push(activation)
    }

    // backward pass
    let delta = cost_derivative(&activations[activations.len()], desired_output)
        * sigmoid_prime(&zs[zs.len()-1]);
    let nabla_b_len = nabla_b.len() -1;
    let nabla_w_len = nabla_w.len() -1;
    nabla_b[nabla_b_len] = delta;
    //let mut act_transp = DMatrix::from_column_iter(
    //nabla_w[nabla_w_len] = &nabla_b[nabla_b_len] * activations[activations.len()-2]

    unimplemented!();
}

fn transpose_vec(vec: &Vec<DVector<f32>>) -> DMatrix<&f32> {
    use nalgebra::Iterable;
    let iter = vec.iter().flat_map(|x| x.iter());

    let mut m = DMatrix::from_column_iter(vec[0].len(), vec.len(), iter);
    m = m.transpose()
}

/// Derivative of the cost function
fn cost_derivative(output_activations: &DVector<f32>, desired_output: &DVector<f32>)
                   -> DVector<f32> {
    // easy, derivative of quadratic cost function is:
    //TODO: Get rid of clone
    output_activations.clone()-desired_output.clone()
}

/// Derivative of the sigmoid function
fn sigmoid_prime(z: &DVector<f32>) -> DVector<f32>{
    use nn;
    // Derivative of sigmoid function, ask wolfram alpha if you don't believe me
    nn::sigmoid(z) * (1.0f32 - nn::sigmoid(z))
}

/*

        # backward pass
        delta = self.cost_derivative(activations[-1], y) * \
            sigmoid_prime(zs[-1])
        nabla_b[-1] = delta
        nabla_w[-1] = np.dot(delta, activations[-2].transpose())
        # Note that the variable l in the loop below is used a little
        # differently to the notation in Chapter 2 of the book.  Here,
        # l = 1 means the last layer of neurons, l = 2 is the
        # second-last layer, and so on.  It's a renumbering of the
        # scheme in the book, used here to take advantage of the fact
        # that Python can use negative indices in lists.
        for l in xrange(2, self.num_layers):
            z = zs[-l]
            sp = sigmoid_prime(z)
            delta = np.dot(self.weights[-l+1].transpose(), delta) * sp
            nabla_b[-l] = delta
            nabla_w[-l] = np.dot(delta, activations[-l-1].transpose())
        return (nabla_b, nabla_w)

   def backprop(self, x, y):
        """Return a tuple "(nabla_b, nabla_w)" representing the
        gradient for the cost function C_x.  "nabla_b" and
        "nabla_w" are layer-by-layer lists of numpy arrays, similar
        to "self.biases" and "self.weights"."""
        nabla_b = [np.zeros(b.shape) for b in self.biases]
        nabla_w = [np.zeros(w.shape) for w in self.weights]
        # feedforward
        activation = x
        activations = [x] # list to store all the activations, layer by layer
        zs = [] # list to store all the z vectors, layer by layer
        for b, w in zip(self.biases, self.weights):
            z = np.dot(w, activation)+b
            zs.append(z)
            activation = sigmoid(z)
            activations.append(activation)
*/
<commit_msg>Still wip, some progress, need to try recovering a file<commit_after>use structs::Data;
use nn::Network;
use nalgebra::{DVector, DMatrix};

pub fn sgd(mut nn: &mut Network,
           mut training_data: Vec<Data>,
           epochs: u8, mini_batch_size: u8,
           eta: f32) {
    use rand::{ self, Rng};
    let mut rng = rand::thread_rng();

    for j in 0..epochs {
        rng.shuffle(&mut training_data);
        for mut mini_batch in training_data.chunks_mut(mini_batch_size as usize) {
            update_mini_batch(&mut nn, &mut mini_batch, eta);
        }
        println!("Epoch {} complete!", j);
    }
}

fn update_mini_batch(mut nn: &mut Network, mut mini_batch: &mut [Data], eta: f32) {
    // holds all biases of the network
    let mut nabla_b: Vec<DVector<f32>> = Vec::with_capacity(nn.get_biases().len());
    for biases in nn.get_biases() {
        nabla_b.push(DVector::from_element(biases.len(), 0.0f32));
    }
    // holds all weights of the network
    let mut nabla_w: Vec<DMatrix<f32>> = Vec::with_capacity(nn.get_weights().len());
    for weights in nn.get_weights() {
        nabla_w.push(DMatrix::from_element(weights.nrows(), weights.ncols(), 0.0f32));
    }

    let mini_batch_len = mini_batch.len();

    // for each dataset in mini_batch: calculate gradients, add to nablas
    for data in mini_batch {
        let (delta_nabla_b, delta_nabla_w) = backprop(&mut nn,
                                                      data.get_input(),
                                                      data.get_class_vector());
        for (mut nb, dnb) in nabla_b.iter_mut().zip(delta_nabla_b.iter()) {
            // TODO: This is really not good. Someone needs to fix this.
            *nb += dnb.clone();
        }
        for (mut nw, dnw) in nabla_w.iter_mut().zip(delta_nabla_w.iter()) {
            // TODO: Same as above.
            *nw += dnw.clone();
        }
    }

    for (mut w, nw) in nn.get_weights_mut().iter_mut().zip( nabla_w.iter() ) {
        *w -= eta / (mini_batch_len as f32) * nw.clone();
    }

    for (mut b, nb) in nn.get_biases_mut().iter_mut().zip( nabla_b.iter() ) {
        *b -= eta / (mini_batch_len as f32) * nb.clone();
    }
}

fn backprop(nn: &mut Network, data: &DVector<f32>, desired_output: &DVector<f32>)
            -> (Vec<DVector<f32>>, Vec<DMatrix<f32>>) {
    use nalgebra::{self, Dot};
    //use nalgebra::Dot;
    use nn;

    // holds all biases of the network
    let mut nabla_b: Vec<DVector<f32>> = Vec::with_capacity(nn.get_biases().len());
    for biases in nn.get_biases() {
        nabla_b.push(DVector::from_element(biases.len(), 0.0f32));
    }
    // holds all weights of the network
    let mut nabla_w: Vec<DMatrix<f32>> = Vec::with_capacity(nn.get_weights().len());
    for weights in nn.get_weights() {
        nabla_w.push(DMatrix::from_element(weights.nrows(), weights.ncols(), 0.0f32));
    }

    // feedforward
    // current activation layer, at the beginning this is the input
    // Note: Clone here because in later iterations activation will actually hold the
    // ownership of the Vector (or rather the activations vector will). However this might
    // still be a performance issue since we call this once per training data.
    let mut activation = data.clone();

    // hold all activation layers (including output)
    let mut activations: Vec<DVector<f32>> = Vec::with_capacity(nn.get_layers().len());
    // hold z where z is the input of the sigmoid function for each layer
    let mut zs: Vec<DVector<f32>> = Vec::with_capacity(nn.get_layers().len());

    activations.push(activation);
    // execute feedforward
    for (biases, weights) in nn.get_biases().iter().zip(nn.get_weights().iter()) {
        // TODO: Remove Clone
        let z = weights * &activations[activations.len()-1] + biases.clone();
        zs.push(z);
        activation = nn::sigmoid(&zs[zs.len()-1]);
        activations.push(activation)
    }

    // backward pass
    let delta = cost_derivative(&activations[activations.len()], desired_output)
        * sigmoid_prime(&zs[zs.len()-1]);
    let nabla_b_len = nabla_b.len() -1;
    let nabla_w_len = nabla_w.len() -1;
    nabla_b[nabla_b_len] = delta;
    //let mut act_transp = DMatrix::from_column_iter(
    nabla_w[nabla_w_len] = (&nabla_b[nabla_b_len]).clone().dot(&activations[activations.len()-2]).clone();

    unimplemented!();
}
/*

        # backward pass
        delta = self.cost_derivative(activations[-1], y) * \
            sigmoid_prime(zs[-1])
        nabla_b[-1] = delta
        nabla_w[-1] = np.dot(delta, activations[-2].transpose())
        # Note that the variable l in the loop below is used a little
        # differently to the notation in Chapter 2 of the book.  Here,
        # l = 1 means the last layer of neurons, l = 2 is the
        # second-last layer, and so on.  It's a renumbering of the
        # scheme in the book, used here to take advantage of the fact
        # that Python can use negative indices in lists.
        for l in xrange(2, self.num_layers):
            z = zs[-l]
            sp = sigmoid_prime(z)
            delta = np.dot(self.weights[-l+1].transpose(), delta) * sp
            nabla_b[-l] = delta
            nabla_w[-l] = np.dot(delta, activations[-l-1].transpose())
        return (nabla_b, nabla_w)

   def backprop(self, x, y):
        """Return a tuple "(nabla_b, nabla_w)" representing the
        gradient for the cost function C_x.  "nabla_b" and
        "nabla_w" are layer-by-layer lists of numpy arrays, similar
        to "self.biases" and "self.weights"."""
        nabla_b = [np.zeros(b.shape) for b in self.biases]
        nabla_w = [np.zeros(w.shape) for w in self.weights]
        # feedforward
        activation = x
        activations = [x] # list to store all the activations, layer by layer
        zs = [] # list to store all the z vectors, layer by layer
        for b, w in zip(self.biases, self.weights):
            z = np.dot(w, activation)+b
            zs.append(z)
            activation = sigmoid(z)
            activations.append(activation)
*/

fn transpose_vec(vec: &Vec<DVector<f32>>) -> DMatrix<&f32> {
    // this eventually has to go. If we need this for any vector of DVectors we should probably
    // think of storing it all in a DMatrix instead.
    use nalgebra::Iterable;
    let iter = vec.iter().flat_map(|x| x.iter());

    let mut m = DMatrix::from_column_iter(vec[0].len(), vec.len(), iter);
    m = m.transpose()
}

/// Derivative of the cost function
fn cost_derivative(output_activations: &DVector<f32>, desired_output: &DVector<f32>)
                   -> DVector<f32> {
    // easy, derivative of quadratic cost function is:
    //TODO: Get rid of clone
    output_activations.clone()-desired_output.clone()
}

/// Derivative of the sigmoid function
fn sigmoid_prime(z: &DVector<f32>) -> DVector<f32>{
    use nn;
    // Derivative of sigmoid function, ask wolfram alpha if you don't believe me
    nn::sigmoid(z) * (1.0f32 - nn::sigmoid(z))
}
<|endoftext|>