<commit_before>// Copyright 2016 Serde YAML 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.

#[macro_use]
extern crate serde_derive;

extern crate serde;
extern crate serde_yaml;

extern crate unindent;
use unindent::unindent;

use std::fmt::Debug;
use std::collections::BTreeMap;

fn test_serde<T>(thing: &T, yaml: &str)
    where T: serde::Serialize + serde::de::DeserializeOwned + PartialEq + Debug
{
    let serialized = serde_yaml::to_string(&thing).unwrap();
    assert_eq!(yaml, serialized);

    let deserialized: T = serde_yaml::from_str(yaml).unwrap();
    assert_eq!(*thing, deserialized);
}

#[test]
fn test_int() {
    let thing = 256;
    let yaml = unindent("
        ---
        256");
    test_serde(&thing, &yaml);
}

#[test]
fn test_int_max_u64() {
    let thing = ::std::u64::MAX;
    let yaml = unindent("
        ---
        18446744073709551615");
    test_serde(&thing, &yaml);
}

#[test]
fn test_int_min_i64() {
    let thing = ::std::i64::MIN;
    let yaml = unindent("
        ---
        -9223372036854775808");
    test_serde(&thing, &yaml);
}

#[test]
fn test_int_max_i64() {
    let thing = ::std::i64::MAX;
    let yaml = unindent("
        ---
        9223372036854775807");
    test_serde(&thing, &yaml);
}

#[test]
fn test_float() {
    let thing = 25.6;
    let yaml = unindent("
        ---
        25.6");
    test_serde(&thing, &yaml);
}

#[test]
fn test_vec() {
    let thing = vec![1, 2, 3];
    let yaml = unindent("
        ---
        - 1
        - 2
        - 3");
    test_serde(&thing, &yaml);
}

#[test]
fn test_map() {
    let mut thing = BTreeMap::new();
    thing.insert(String::from("x"), 1);
    thing.insert(String::from("y"), 2);
    let yaml = unindent(r#"
        ---
        x: 1
        y: 2"#);
    test_serde(&thing, &yaml);
}

#[test]
fn test_basic_struct() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct Basic {
        x: isize,
        y: String,
        z: bool,
    }
    let thing = Basic {
        x: -4,
        y: String::from("hi\tquoted"),
        z: true,
    };
    let yaml = unindent(r#"
        ---
        x: -4
        y: "hi\tquoted"
        z: true"#);
    test_serde(&thing, &yaml);
}

#[test]
fn test_nested_vec() {
    let thing = vec![vec![1, 2, 3], vec![4, 5, 6]];
    let yaml = unindent("
        ---
        -
          - 1
          - 2
          - 3
        -
          - 4
          - 5
          - 6");
    test_serde(&thing, &yaml);
}

#[test]
fn test_nested_struct() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct Outer {
        inner: Inner,
    }
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct Inner {
        v: u16,
    }
    let thing = Outer { inner: Inner { v: 512 } };
    let yaml = unindent(r#"
        ---
        inner:
          v: 512"#);
    test_serde(&thing, &yaml);
}

#[test]
fn test_option() {
    let thing = vec![Some(1), None, Some(3)];
    let yaml = unindent("
        ---
        - 1
        - ~
        - 3");
    test_serde(&thing, &yaml);
}

#[test]
fn test_unit() {
    let thing = vec![(), ()];
    let yaml = unindent("
        ---
        - ~
        - ~");
    test_serde(&thing, &yaml);
}

#[test]
fn test_unit_variant() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    enum Variant {
        First,
        Second,
    }
    let thing = Variant::First;
    let yaml = unindent(r#"
        ---
        First"#);
    test_serde(&thing, &yaml);
}

#[test]
fn test_newtype_struct() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct OriginalType {
        v: u16,
    }
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct NewType(OriginalType);
    let thing = NewType(OriginalType { v: 1 });
    let yaml = unindent(r#"
        ---
        v: 1"#);
    test_serde(&thing, &yaml);
}

#[test]
fn test_newtype_variant() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    enum Variant {
        Size(usize),
    }
    let thing = Variant::Size(127);
    let yaml = unindent(r#"
        ---
        Size: 127"#);
    test_serde(&thing, &yaml);
}

#[test]
fn test_tuple_variant() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    enum Variant {
        Rgb(u8, u8, u8),
    }
    let thing = Variant::Rgb(32, 64, 96);
    let yaml = unindent(r#"
        ---
        Rgb:
          - 32
          - 64
          - 96"#);
    test_serde(&thing, &yaml);
}

#[test]
fn test_struct_variant() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    enum Variant {
        Color { r: u8, g: u8, b: u8 },
    }
    let thing = Variant::Color {
        r: 32,
        g: 64,
        b: 96,
    };
    let yaml = unindent(r#"
        ---
        Color:
          r: 32
          g: 64
          b: 96"#);
    test_serde(&thing, &yaml);
}

#[test]
fn test_value() {
    use serde_yaml::{Mapping, Value, Number};

    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    pub struct GenericInstructions {
        #[serde(rename="type")]
        pub typ: String,
        pub config: Value,
    }
    let thing = GenericInstructions {
        typ: "primary".to_string(),
        config: Value::Sequence(vec![Value::Null,
                                     Value::Bool(true),
                                     Value::Number(Number::from(65535)),
                                     Value::Number(Number::from(0.54321)),
                                     Value::String("s".into()),
                                     Value::Mapping(Mapping::new())]),
    };
    let yaml = unindent(r#"
        ---
        type: primary
        config:
          - ~
          - true
          - 65535
          - 0.54321
          - s
          - {}"#);
    test_serde(&thing, &yaml);
}

#[test]
fn test_mapping() {
    use serde_yaml::{Mapping, Value};
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct Data {
        pub substructure: Mapping,
    }

    let mut thing = Data { substructure: Mapping::new() };
    thing.substructure.insert(Value::String("a".to_owned()),
                              Value::String("foo".to_owned()));
    thing.substructure.insert(Value::String("b".to_owned()),
                              Value::String("bar".to_owned()));

    let yaml = unindent("
        ---
        substructure:
          a: foo
          b: bar");

    test_serde(&thing, &yaml);
}
<commit_msg>Disagree that 65535 is unreadable<commit_after>// Copyright 2016 Serde YAML 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.

#![cfg_attr(feature = "cargo-clippy", allow(unreadable_literal))]

#[macro_use]
extern crate serde_derive;

extern crate serde;
extern crate serde_yaml;

extern crate unindent;
use unindent::unindent;

use std::fmt::Debug;
use std::collections::BTreeMap;

fn test_serde<T>(thing: &T, yaml: &str)
    where T: serde::Serialize + serde::de::DeserializeOwned + PartialEq + Debug
{
    let serialized = serde_yaml::to_string(&thing).unwrap();
    assert_eq!(yaml, serialized);

    let deserialized: T = serde_yaml::from_str(yaml).unwrap();
    assert_eq!(*thing, deserialized);
}

#[test]
fn test_int() {
    let thing = 256;
    let yaml = unindent("
        ---
        256");
    test_serde(&thing, &yaml);
}

#[test]
fn test_int_max_u64() {
    let thing = ::std::u64::MAX;
    let yaml = unindent("
        ---
        18446744073709551615");
    test_serde(&thing, &yaml);
}

#[test]
fn test_int_min_i64() {
    let thing = ::std::i64::MIN;
    let yaml = unindent("
        ---
        -9223372036854775808");
    test_serde(&thing, &yaml);
}

#[test]
fn test_int_max_i64() {
    let thing = ::std::i64::MAX;
    let yaml = unindent("
        ---
        9223372036854775807");
    test_serde(&thing, &yaml);
}

#[test]
fn test_float() {
    let thing = 25.6;
    let yaml = unindent("
        ---
        25.6");
    test_serde(&thing, &yaml);
}

#[test]
fn test_vec() {
    let thing = vec![1, 2, 3];
    let yaml = unindent("
        ---
        - 1
        - 2
        - 3");
    test_serde(&thing, &yaml);
}

#[test]
fn test_map() {
    let mut thing = BTreeMap::new();
    thing.insert(String::from("x"), 1);
    thing.insert(String::from("y"), 2);
    let yaml = unindent(r#"
        ---
        x: 1
        y: 2"#);
    test_serde(&thing, &yaml);
}

#[test]
fn test_basic_struct() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct Basic {
        x: isize,
        y: String,
        z: bool,
    }
    let thing = Basic {
        x: -4,
        y: String::from("hi\tquoted"),
        z: true,
    };
    let yaml = unindent(r#"
        ---
        x: -4
        y: "hi\tquoted"
        z: true"#);
    test_serde(&thing, &yaml);
}

#[test]
fn test_nested_vec() {
    let thing = vec![vec![1, 2, 3], vec![4, 5, 6]];
    let yaml = unindent("
        ---
        -
          - 1
          - 2
          - 3
        -
          - 4
          - 5
          - 6");
    test_serde(&thing, &yaml);
}

#[test]
fn test_nested_struct() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct Outer {
        inner: Inner,
    }
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct Inner {
        v: u16,
    }
    let thing = Outer { inner: Inner { v: 512 } };
    let yaml = unindent(r#"
        ---
        inner:
          v: 512"#);
    test_serde(&thing, &yaml);
}

#[test]
fn test_option() {
    let thing = vec![Some(1), None, Some(3)];
    let yaml = unindent("
        ---
        - 1
        - ~
        - 3");
    test_serde(&thing, &yaml);
}

#[test]
fn test_unit() {
    let thing = vec![(), ()];
    let yaml = unindent("
        ---
        - ~
        - ~");
    test_serde(&thing, &yaml);
}

#[test]
fn test_unit_variant() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    enum Variant {
        First,
        Second,
    }
    let thing = Variant::First;
    let yaml = unindent(r#"
        ---
        First"#);
    test_serde(&thing, &yaml);
}

#[test]
fn test_newtype_struct() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct OriginalType {
        v: u16,
    }
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct NewType(OriginalType);
    let thing = NewType(OriginalType { v: 1 });
    let yaml = unindent(r#"
        ---
        v: 1"#);
    test_serde(&thing, &yaml);
}

#[test]
fn test_newtype_variant() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    enum Variant {
        Size(usize),
    }
    let thing = Variant::Size(127);
    let yaml = unindent(r#"
        ---
        Size: 127"#);
    test_serde(&thing, &yaml);
}

#[test]
fn test_tuple_variant() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    enum Variant {
        Rgb(u8, u8, u8),
    }
    let thing = Variant::Rgb(32, 64, 96);
    let yaml = unindent(r#"
        ---
        Rgb:
          - 32
          - 64
          - 96"#);
    test_serde(&thing, &yaml);
}

#[test]
fn test_struct_variant() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    enum Variant {
        Color { r: u8, g: u8, b: u8 },
    }
    let thing = Variant::Color {
        r: 32,
        g: 64,
        b: 96,
    };
    let yaml = unindent(r#"
        ---
        Color:
          r: 32
          g: 64
          b: 96"#);
    test_serde(&thing, &yaml);
}

#[test]
fn test_value() {
    use serde_yaml::{Mapping, Value, Number};

    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    pub struct GenericInstructions {
        #[serde(rename="type")]
        pub typ: String,
        pub config: Value,
    }
    let thing = GenericInstructions {
        typ: "primary".to_string(),
        config: Value::Sequence(vec![Value::Null,
                                     Value::Bool(true),
                                     Value::Number(Number::from(65535)),
                                     Value::Number(Number::from(0.54321)),
                                     Value::String("s".into()),
                                     Value::Mapping(Mapping::new())]),
    };
    let yaml = unindent(r#"
        ---
        type: primary
        config:
          - ~
          - true
          - 65535
          - 0.54321
          - s
          - {}"#);
    test_serde(&thing, &yaml);
}

#[test]
fn test_mapping() {
    use serde_yaml::{Mapping, Value};
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct Data {
        pub substructure: Mapping,
    }

    let mut thing = Data { substructure: Mapping::new() };
    thing.substructure.insert(Value::String("a".to_owned()),
                              Value::String("foo".to_owned()));
    thing.substructure.insert(Value::String("b".to_owned()),
                              Value::String("bar".to_owned()));

    let yaml = unindent("
        ---
        substructure:
          a: foo
          b: bar");

    test_serde(&thing, &yaml);
}
<|endoftext|>


<commit_before>use redox::*;

// TODO: Structure using loops

use super::Mode;
use super::Mode::*;
use super::Editor;

pub fn exec(editor: &mut Editor, mode: &mut Mode, multiplier: &mut Option<u32>, last_change: &mut String, key_event: KeyEvent, window: &mut Window, swap: &mut usize, period: &mut String, is_recording: &mut bool) {
    match (*mode, key_event.scancode) {
        (Insert, K_ESC) => {
            *mode = Normal;
        },
        (Insert, K_BKSP) => editor.backspace(window),
        (Insert, K_DEL) => editor.delete(window),
        (_, K_F5) => editor.reload(window),
        (_, K_F6) => editor.save(window),
        (_, K_HOME) => editor.offset = 0,
        (_, K_UP) => editor.up(),
        (_, K_LEFT) => editor.left(),
        (_, K_RIGHT) => editor.right(),
        (_, K_END) => editor.offset = editor.string.len(),
        (_, K_DOWN) => editor.down(),
        (m, _) => {
            let (no_mult, mut times) = match *multiplier {
                Some(n) => (false, n),
                None => (true, 1),
            };
            let mut is_none = false;

            match (*mode, key_event.character) {
                (Normal, '0') if !no_mult => times *= 10,

                (Normal, '1') if no_mult => times = 1,
                (Normal, '1') => times = times * 10 + 1,

                (Normal, '2') if no_mult => times = 2,
                (Normal, '2') => times = times * 10 + 2,

                (Normal, '3') if no_mult => times = 3,
                (Normal, '3') => times = times * 10 + 3,

                (Normal, '4') if no_mult => times = 4,
                (Normal, '4') => times = times * 10 + 4,

                (Normal, '5') if no_mult => times = 5,
                (Normal, '5') => times = times * 10 + 5,

                (Normal, '6') if no_mult => times = 6,
                (Normal, '6') => times = times * 10 + 6,

                (Normal, '7') if no_mult => times = 7,
                (Normal, '7') => times = times * 10 + 7,

                (Normal, '8') if no_mult => times = 8,
                (Normal, '8') => times = times * 10 + 8,

                (Normal, '9') if no_mult => times = 9,
                (Normal, '9') => times = times * 10 + 9,
                (_, _) => {
                    if *is_recording {
                        if key_event.character == ',' {
                            *is_recording = false;
                        } else {
                            period.push(key_event.character);
                        }
                    } else {
                        for _ in 0 .. times {
                            match (m, key_event.character) {
                                (Normal, 'i') => {
                                    *mode = Insert;
                                    *last_change = editor.string.clone();
                                },
                                (Normal, 'h') => editor.left(),
                                (Normal, 'l') => editor.right(),
                                (Normal, 'k') => editor.up(),
                                (Normal, 'j') => editor.down(),
                                (Normal, 'K') => {
                                    for _ in 1..15 {
                                        editor.up();
                                    }
                                },
                                (Normal, 'J') => {
                                    for _ in 1..15 {
                                        editor.down();
                                    }
                                },
                                (Normal, 'g') => editor.offset = 0,
                                (Normal, 'G') => editor.offset = editor.string.len(),
                                (Normal, 'a') => {
                                    editor.right();
                                    *mode = Insert;
                                    *last_change = editor.string.clone();
                                },
                                (Normal, 'x') => editor.delete(window),
                                (Normal, 'X') => editor.backspace(window),
                                (Normal, 'u') => {
                                    editor.offset = 0;
                                    ::core::mem::swap(last_change, &mut editor.string);
                                },
                                (Normal, 'c') => {
                                    ::core::mem::swap(&mut editor.offset, swap);
                                },
                                (Normal, 's') => {
                                    editor.delete(window);
                                    *mode = Insert;
                                },
                                (Normal, 'o') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                    editor.insert('\n', window);
                                    *mode = Insert;
                                },
                                (Normal, 'O') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                    editor.insert('\n', window);
                                    editor.left();
                                    *mode = Insert;
                                },
                                (Normal, '^') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset <= 0 {
                                        editor.left();
                                    }
                                    editor.right();
                                    while (editor.cur() == ' ' ||
                                          editor.cur() == '\t') &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, '$') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, '0') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 'd') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.delete(window);
                                    }
                                },
                                (Normal, 'w') => {
                                    editor.save(window);
                                },
                                (Normal, 'e') => {
                                    editor.right();
                                    while editor.cur() != '.' &&
                                          editor.cur() != '{' &&
                                          editor.cur() != ',' &&
                                          editor.cur() != ' ' &&
                                          editor.cur() != '}' &&
                                          editor.cur() != '(' &&
                                          editor.cur() != ')' &&
                                          editor.cur() != '[' &&
                                          editor.cur() != ']' &&
                                          editor.cur() != ';' &&
                                          editor.cur() != '"' &&
                                          editor.cur() != '\'' &&
                                          editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'b') => {
                                    editor.left();
                                    while editor.cur() != '.' &&
                                          editor.cur() != '{' &&
                                          editor.cur() != ',' &&
                                          editor.cur() != ' ' &&
                                          editor.cur() != '}' &&
                                          editor.cur() != '(' &&
                                          editor.cur() != ')' &&
                                          editor.cur() != '[' &&
                                          editor.cur() != ']' &&
                                          editor.cur() != ';' &&
                                          editor.cur() != '"' &&
                                          editor.cur() != '\'' &&
                                          editor.cur() != '\n' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                },
                                (Normal, 'E') => {
                                    editor.right();
                                    while editor.cur() != ' ' && editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'B') => {
                                    editor.left();
                                    while editor.cur() != ' ' && editor.offset >= 1 {
                                        editor.left();
                                    }
                                },
                                (Normal, ',') => {
                                    *is_recording = true;
                                    *period = String::new();
                                },
                                (Normal, '%') => {
                                    match editor.cur() {
                                        '(' | '[' | '{' => {
                                            let mut i = 1;
                                            while i != 0 {
                                                editor.right();
                                                i += match editor.cur() {
                                                    '(' | '[' | '{' => 1,
                                                    ')' | ']' | '}' => -1,
                                                    _ => 0,
                                                };
                                                if editor.offset < editor.string.len() {
                                                    break;
                                                }
                                            }
                                        },
                                        ')' | ']' | '}' => {
                                            let mut i = 1;
                                            while i != 0 {
                                                editor.left();
                                                i += match editor.cur() {
                                                    '(' | '[' | '{' => -1,
                                                    ')' | ']' | '}' => 1,
                                                    _ => 0,
                                                };
                                                if editor.offset >= 0 {
                                                    break;
                                                }
                                            }
                                        },
                                        _ => {},

                                    }
                                },
                                (Normal, '!') => {
                                    for c in period.clone().chars() {
                                        exec(editor, mode, multiplier, last_change, KeyEvent {
                                            character: c,
                                            scancode: 0,
                                            pressed: true,
                                        }, window, swap, period, is_recording);
                                    }
                                },
                                (Insert, '\0') => (),
                                (Insert, c) => {
                                    editor.insert(c, window);
                                },
                                _ => {},
                            }
                        }
                    }
                    is_none = true;
                }
            }

            if !is_none {
                *multiplier = Some(times);
            } else {
                *multiplier = None;
            }
        }
    }
}
<commit_msg>Fix 0 command<commit_after>use redox::*;

// TODO: Structure using loops

use super::Mode;
use super::Mode::*;
use super::Editor;

pub fn exec(editor: &mut Editor, mode: &mut Mode, multiplier: &mut Option<u32>, last_change: &mut String, key_event: KeyEvent, window: &mut Window, swap: &mut usize, period: &mut String, is_recording: &mut bool) {
    match (*mode, key_event.scancode) {
        (Insert, K_ESC) => {
            *mode = Normal;
        },
        (Insert, K_BKSP) => editor.backspace(window),
        (Insert, K_DEL) => editor.delete(window),
        (_, K_F5) => editor.reload(window),
        (_, K_F6) => editor.save(window),
        (_, K_HOME) => editor.offset = 0,
        (_, K_UP) => editor.up(),
        (_, K_LEFT) => editor.left(),
        (_, K_RIGHT) => editor.right(),
        (_, K_END) => editor.offset = editor.string.len(),
        (_, K_DOWN) => editor.down(),
        (m, _) => {
            let (no_mult, mut times) = match *multiplier {
                Some(n) => (false, n),
                None => (true, 1),
            };
            let mut is_none = false;

            match (*mode, key_event.character) {
                (Normal, '0') if !no_mult => times *= 10,

                (Normal, '1') if no_mult => times = 1,
                (Normal, '1') => times = times * 10 + 1,

                (Normal, '2') if no_mult => times = 2,
                (Normal, '2') => times = times * 10 + 2,

                (Normal, '3') if no_mult => times = 3,
                (Normal, '3') => times = times * 10 + 3,

                (Normal, '4') if no_mult => times = 4,
                (Normal, '4') => times = times * 10 + 4,

                (Normal, '5') if no_mult => times = 5,
                (Normal, '5') => times = times * 10 + 5,

                (Normal, '6') if no_mult => times = 6,
                (Normal, '6') => times = times * 10 + 6,

                (Normal, '7') if no_mult => times = 7,
                (Normal, '7') => times = times * 10 + 7,

                (Normal, '8') if no_mult => times = 8,
                (Normal, '8') => times = times * 10 + 8,

                (Normal, '9') if no_mult => times = 9,
                (Normal, '9') => times = times * 10 + 9,
                (_, _) => {
                    if *is_recording {
                        if key_event.character == ',' {
                            *is_recording = false;
                        } else {
                            period.push(key_event.character);
                        }
                    } else {
                        for _ in 0 .. times {
                            match (m, key_event.character) {
                                (Normal, 'i') => {
                                    *mode = Insert;
                                    *last_change = editor.string.clone();
                                },
                                (Normal, 'h') => editor.left(),
                                (Normal, 'l') => editor.right(),
                                (Normal, 'k') => editor.up(),
                                (Normal, 'j') => editor.down(),
                                (Normal, 'K') => {
                                    for _ in 1..15 {
                                        editor.up();
                                    }
                                },
                                (Normal, 'J') => {
                                    for _ in 1..15 {
                                        editor.down();
                                    }
                                },
                                (Normal, 'g') => editor.offset = 0,
                                (Normal, 'G') => editor.offset = editor.string.len(),
                                (Normal, 'a') => {
                                    editor.right();
                                    *mode = Insert;
                                    *last_change = editor.string.clone();
                                },
                                (Normal, 'x') => editor.delete(window),
                                (Normal, 'X') => editor.backspace(window),
                                (Normal, 'u') => {
                                    editor.offset = 0;
                                    ::core::mem::swap(last_change, &mut editor.string);
                                },
                                (Normal, 'c') => {
                                    ::core::mem::swap(&mut editor.offset, swap);
                                },
                                (Normal, 's') => {
                                    editor.delete(window);
                                    *mode = Insert;
                                },
                                (Normal, 'o') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                    editor.insert('\n', window);
                                    *mode = Insert;
                                },
                                (Normal, 'O') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                    editor.insert('\n', window);
                                    editor.left();
                                    *mode = Insert;
                                },
                                (Normal, '^') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset <= 0 {
                                        editor.left();
                                    }
                                    editor.right();
                                    while (editor.cur() == ' ' ||
                                          editor.cur() == '\t') &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, '$') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal,  '0') => {
                                    editor.left();
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 'd') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.delete(window);
                                    }
                                },
                                (Normal, 'w') => {
                                    editor.save(window);
                                },
                                (Normal, 'e') => {
                                    editor.right();
                                    while editor.cur() != '.' &&
                                          editor.cur() != '{' &&
                                          editor.cur() != ',' &&
                                          editor.cur() != ' ' &&
                                          editor.cur() != '}' &&
                                          editor.cur() != '(' &&
                                          editor.cur() != ')' &&
                                          editor.cur() != '[' &&
                                          editor.cur() != ']' &&
                                          editor.cur() != ';' &&
                                          editor.cur() != '"' &&
                                          editor.cur() != '\'' &&
                                          editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'b') => {
                                    editor.left();
                                    while editor.cur() != '.' &&
                                          editor.cur() != '{' &&
                                          editor.cur() != ',' &&
                                          editor.cur() != ' ' &&
                                          editor.cur() != '}' &&
                                          editor.cur() != '(' &&
                                          editor.cur() != ')' &&
                                          editor.cur() != '[' &&
                                          editor.cur() != ']' &&
                                          editor.cur() != ';' &&
                                          editor.cur() != '"' &&
                                          editor.cur() != '\'' &&
                                          editor.cur() != '\n' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                },
                                (Normal, 'E') => {
                                    editor.right();
                                    while editor.cur() != ' ' && editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'B') => {
                                    editor.left();
                                    while editor.cur() != ' ' && editor.offset >= 1 {
                                        editor.left();
                                    }
                                },
                                (Normal, ',') => {
                                    *is_recording = true;
                                    *period = String::new();
                                },
                                (Normal, '%') => {
                                    match editor.cur() {
                                        '(' | '[' | '{' => {
                                            let mut i = 1;
                                            while i != 0 {
                                                editor.right();
                                                i += match editor.cur() {
                                                    '(' | '[' | '{' => 1,
                                                    ')' | ']' | '}' => -1,
                                                    _ => 0,
                                                };
                                                if editor.offset < editor.string.len() {
                                                    break;
                                                }
                                            }
                                        },
                                        ')' | ']' | '}' => {
                                            let mut i = 1;
                                            while i != 0 {
                                                editor.left();
                                                i += match editor.cur() {
                                                    '(' | '[' | '{' => -1,
                                                    ')' | ']' | '}' => 1,
                                                    _ => 0,
                                                };
                                                if editor.offset >= 0 {
                                                    break;
                                                }
                                            }
                                        },
                                        _ => {},

                                    }
                                },
                                (Normal, '!') => {
                                    for c in period.clone().chars() {
                                        exec(editor, mode, multiplier, last_change, KeyEvent {
                                            character: c,
                                            scancode: 0,
                                            pressed: true,
                                        }, window, swap, period, is_recording);
                                    }
                                },
                                (Insert, '\0') => (),
                                (Insert, c) => {
                                    editor.insert(c, window);
                                },
                                _ => {},
                            }
                        }
                    }
                    is_none = true;
                }
            }

            if !is_none {
                *multiplier = Some(times);
            } else {
                *multiplier = None;
            }
        }
    }
}
<|endoftext|>


<commit_before>#![stable(feature = "", since = "1.30.0")]

#![allow(non_camel_case_types)]

//! Utilities related to FFI bindings.

use ::fmt;

/// Equivalent to C's `void` type when used as a [pointer].
///
/// In essence, `*const c_void` is equivalent to C's `const void*`
/// and `*mut c_void` is equivalent to C's `void*`. That said, this is
/// *not* the same as C's `void` return type, which is Rust's `()` type.
///
/// Ideally, this type would be equivalent to [`!`], but currently it may
/// be more ideal to use `c_void` for FFI purposes.
///
/// [`!`]: ../../std/primitive.never.html
/// [pointer]: ../../std/primitive.pointer.html
// N.B., for LLVM to recognize the void pointer type and by extension
//     functions like malloc(), we need to have it represented as i8* in
//     LLVM bitcode. The enum used here ensures this and prevents misuse
//     of the "raw" type by only having private variants.. We need two
//     variants, because the compiler complains about the repr attribute
//     otherwise.
#[repr(u8)]
#[stable(feature = "raw_os", since = "1.1.0")]
pub enum c_void {
    #[unstable(feature = "c_void_variant", reason = "should not have to exist",
               issue = "0")]
    #[doc(hidden)] __variant1,
    #[unstable(feature = "c_void_variant", reason = "should not have to exist",
               issue = "0")]
    #[doc(hidden)] __variant2,
}

#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for c_void {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("c_void")
    }
}

/// Basic implementation of a `va_list`.
#[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
              not(target_arch = "x86_64")),
          all(target_arch = "aarch4", target_os = "ios"),
          windows))]
#[unstable(feature = "c_variadic",
           reason = "the `c_variadic` feature has not been properly tested on \
                     all supported platforms",
           issue = "27745")]
extern {
    type VaListImpl;
}

#[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
              not(target_arch = "x86_64")),
          windows))]
impl fmt::Debug for VaListImpl {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "va_list* {:p}", self)
    }
}

/// AArch64 ABI implementation of a `va_list`. See the
/// [Aarch64 Procedure Call Standard] for more details.
///
/// [AArch64 Procedure Call Standard]:
/// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
#[cfg(all(target_arch = "aarch64", not(windows)))]
#[repr(C)]
#[derive(Debug)]
#[unstable(feature = "c_variadic",
           reason = "the `c_variadic` feature has not been properly tested on \
                     all supported platforms",
           issue = "27745")]
struct VaListImpl {
    stack: *mut (),
    gr_top: *mut (),
    vr_top: *mut (),
    gr_offs: i32,
    vr_offs: i32,
}

/// PowerPC ABI implementation of a `va_list`.
#[cfg(all(target_arch = "powerpc", not(windows)))]
#[repr(C)]
#[derive(Debug)]
#[unstable(feature = "c_variadic",
           reason = "the `c_variadic` feature has not been properly tested on \
                     all supported platforms",
           issue = "27745")]
struct VaListImpl {
    gpr: u8,
    fpr: u8,
    reserved: u16,
    overflow_arg_area: *mut (),
    reg_save_area: *mut (),
}

/// x86_64 ABI implementation of a `va_list`.
#[cfg(all(target_arch = "x86_64", not(windows)))]
#[repr(C)]
#[derive(Debug)]
#[unstable(feature = "c_variadic",
           reason = "the `c_variadic` feature has not been properly tested on \
                     all supported platforms",
           issue = "27745")]
struct VaListImpl {
    gp_offset: i32,
    fp_offset: i32,
    overflow_arg_area: *mut (),
    reg_save_area: *mut (),
}

/// A wrapper for a `va_list`
#[lang = "va_list"]
#[derive(Debug)]
#[unstable(feature = "c_variadic",
           reason = "the `c_variadic` feature has not been properly tested on \
                     all supported platforms",
           issue = "27745")]
#[repr(transparent)]
pub struct VaList<'a>(&'a mut VaListImpl);

// The VaArgSafe trait needs to be used in public interfaces, however, the trait
// itself must not be allowed to be used outside this module. Allowing users to
// implement the trait for a new type (thereby allowing the va_arg intrinsic to
// be used on a new type) is likely to cause undefined behavior.
//
// FIXME(dlrobertson): In order to use the VaArgSafe trait in a public interface
// but also ensure it cannot be used elsewhere, the trait needs to be public
// within a private module. Once RFC 2145 has been implemented look into
// improving this.
mod sealed_trait {
    /// Trait which whitelists the allowed types to be used with [VaList::arg]
    ///
    /// [VaList::va_arg]: struct.VaList.html#method.arg
    #[unstable(feature = "c_variadic",
               reason = "the `c_variadic` feature has not been properly tested on \
                         all supported platforms",
               issue = "27745")]
    pub trait VaArgSafe {}
}

macro_rules! impl_va_arg_safe {
    ($($t:ty),+) => {
        $(
            #[unstable(feature = "c_variadic",
                       reason = "the `c_variadic` feature has not been properly tested on \
                                 all supported platforms",
                       issue = "27745")]
            impl sealed_trait::VaArgSafe for $t {}
        )+
    }
}

impl_va_arg_safe!{i8, i16, i32, i64, usize}
impl_va_arg_safe!{u8, u16, u32, u64, isize}
impl_va_arg_safe!{f64}

#[unstable(feature = "c_variadic",
           reason = "the `c_variadic` feature has not been properly tested on \
                     all supported platforms",
           issue = "27745")]
impl<T> sealed_trait::VaArgSafe for *mut T {}
#[unstable(feature = "c_variadic",
           reason = "the `c_variadic` feature has not been properly tested on \
                     all supported platforms",
           issue = "27745")]
impl<T> sealed_trait::VaArgSafe for *const T {}

impl<'a> VaList<'a> {
    /// Advance to the next arg.
    #[unstable(feature = "c_variadic",
               reason = "the `c_variadic` feature has not been properly tested on \
                         all supported platforms",
               issue = "27745")]
    pub unsafe fn arg<T: sealed_trait::VaArgSafe>(&mut self) -> T {
        va_arg(self)
    }

    /// Copy the `va_list` at the current location.
    #[unstable(feature = "c_variadic",
               reason = "the `c_variadic` feature has not been properly tested on \
                         all supported platforms",
               issue = "27745")]
    pub unsafe fn copy<F, R>(&mut self, f: F) -> R
            where F: for<'copy> FnOnce(VaList<'copy>) -> R {
        #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
                      not(target_arch = "x86_64")),
                  all(target_arch = "aarch4", target_os = "ios"),
                  windows))]
        let mut ap = va_copy(self);
        #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
                  not(windows)))]
        let mut ap_inner = va_copy(self);
        #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
                  not(windows)))]
        let mut ap = VaList(&mut ap_inner);
        let ret = f(VaList(ap.0));
        va_end(&mut ap);
        ret
    }
}

extern "rust-intrinsic" {
    /// Destroy the arglist `ap` after initialization with `va_start` or
    /// `va_copy`.
    fn va_end(ap: &mut VaList);

    /// Copy the current location of arglist `src` to the arglist `dst`.
    #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
                  not(target_arch = "x86_64")),
              windows))]
    fn va_copy<'a>(src: &VaList<'a>) -> VaList<'a>;
    #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
              not(windows)))]
    fn va_copy(src: &VaList) -> VaListImpl;

    /// Loads an argument of type `T` from the `va_list` `ap` and increment the
    /// argument `ap` points to.
    fn va_arg<T: sealed_trait::VaArgSafe>(ap: &mut VaList) -> T;
}
<commit_msg>VaList::copy should not require a mutable ref<commit_after>#![stable(feature = "", since = "1.30.0")]

#![allow(non_camel_case_types)]

//! Utilities related to FFI bindings.

use ::fmt;

/// Equivalent to C's `void` type when used as a [pointer].
///
/// In essence, `*const c_void` is equivalent to C's `const void*`
/// and `*mut c_void` is equivalent to C's `void*`. That said, this is
/// *not* the same as C's `void` return type, which is Rust's `()` type.
///
/// Ideally, this type would be equivalent to [`!`], but currently it may
/// be more ideal to use `c_void` for FFI purposes.
///
/// [`!`]: ../../std/primitive.never.html
/// [pointer]: ../../std/primitive.pointer.html
// N.B., for LLVM to recognize the void pointer type and by extension
//     functions like malloc(), we need to have it represented as i8* in
//     LLVM bitcode. The enum used here ensures this and prevents misuse
//     of the "raw" type by only having private variants.. We need two
//     variants, because the compiler complains about the repr attribute
//     otherwise.
#[repr(u8)]
#[stable(feature = "raw_os", since = "1.1.0")]
pub enum c_void {
    #[unstable(feature = "c_void_variant", reason = "should not have to exist",
               issue = "0")]
    #[doc(hidden)] __variant1,
    #[unstable(feature = "c_void_variant", reason = "should not have to exist",
               issue = "0")]
    #[doc(hidden)] __variant2,
}

#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for c_void {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("c_void")
    }
}

/// Basic implementation of a `va_list`.
#[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
              not(target_arch = "x86_64")),
          all(target_arch = "aarch4", target_os = "ios"),
          windows))]
#[unstable(feature = "c_variadic",
           reason = "the `c_variadic` feature has not been properly tested on \
                     all supported platforms",
           issue = "27745")]
extern {
    type VaListImpl;
}

#[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
              not(target_arch = "x86_64")),
          windows))]
impl fmt::Debug for VaListImpl {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "va_list* {:p}", self)
    }
}

/// AArch64 ABI implementation of a `va_list`. See the
/// [Aarch64 Procedure Call Standard] for more details.
///
/// [AArch64 Procedure Call Standard]:
/// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
#[cfg(all(target_arch = "aarch64", not(windows)))]
#[repr(C)]
#[derive(Debug)]
#[unstable(feature = "c_variadic",
           reason = "the `c_variadic` feature has not been properly tested on \
                     all supported platforms",
           issue = "27745")]
struct VaListImpl {
    stack: *mut (),
    gr_top: *mut (),
    vr_top: *mut (),
    gr_offs: i32,
    vr_offs: i32,
}

/// PowerPC ABI implementation of a `va_list`.
#[cfg(all(target_arch = "powerpc", not(windows)))]
#[repr(C)]
#[derive(Debug)]
#[unstable(feature = "c_variadic",
           reason = "the `c_variadic` feature has not been properly tested on \
                     all supported platforms",
           issue = "27745")]
struct VaListImpl {
    gpr: u8,
    fpr: u8,
    reserved: u16,
    overflow_arg_area: *mut (),
    reg_save_area: *mut (),
}

/// x86_64 ABI implementation of a `va_list`.
#[cfg(all(target_arch = "x86_64", not(windows)))]
#[repr(C)]
#[derive(Debug)]
#[unstable(feature = "c_variadic",
           reason = "the `c_variadic` feature has not been properly tested on \
                     all supported platforms",
           issue = "27745")]
struct VaListImpl {
    gp_offset: i32,
    fp_offset: i32,
    overflow_arg_area: *mut (),
    reg_save_area: *mut (),
}

/// A wrapper for a `va_list`
#[lang = "va_list"]
#[derive(Debug)]
#[unstable(feature = "c_variadic",
           reason = "the `c_variadic` feature has not been properly tested on \
                     all supported platforms",
           issue = "27745")]
#[repr(transparent)]
pub struct VaList<'a>(&'a mut VaListImpl);

// The VaArgSafe trait needs to be used in public interfaces, however, the trait
// itself must not be allowed to be used outside this module. Allowing users to
// implement the trait for a new type (thereby allowing the va_arg intrinsic to
// be used on a new type) is likely to cause undefined behavior.
//
// FIXME(dlrobertson): In order to use the VaArgSafe trait in a public interface
// but also ensure it cannot be used elsewhere, the trait needs to be public
// within a private module. Once RFC 2145 has been implemented look into
// improving this.
mod sealed_trait {
    /// Trait which whitelists the allowed types to be used with [VaList::arg]
    ///
    /// [VaList::va_arg]: struct.VaList.html#method.arg
    #[unstable(feature = "c_variadic",
               reason = "the `c_variadic` feature has not been properly tested on \
                         all supported platforms",
               issue = "27745")]
    pub trait VaArgSafe {}
}

macro_rules! impl_va_arg_safe {
    ($($t:ty),+) => {
        $(
            #[unstable(feature = "c_variadic",
                       reason = "the `c_variadic` feature has not been properly tested on \
                                 all supported platforms",
                       issue = "27745")]
            impl sealed_trait::VaArgSafe for $t {}
        )+
    }
}

impl_va_arg_safe!{i8, i16, i32, i64, usize}
impl_va_arg_safe!{u8, u16, u32, u64, isize}
impl_va_arg_safe!{f64}

#[unstable(feature = "c_variadic",
           reason = "the `c_variadic` feature has not been properly tested on \
                     all supported platforms",
           issue = "27745")]
impl<T> sealed_trait::VaArgSafe for *mut T {}
#[unstable(feature = "c_variadic",
           reason = "the `c_variadic` feature has not been properly tested on \
                     all supported platforms",
           issue = "27745")]
impl<T> sealed_trait::VaArgSafe for *const T {}

impl<'a> VaList<'a> {
    /// Advance to the next arg.
    #[unstable(feature = "c_variadic",
               reason = "the `c_variadic` feature has not been properly tested on \
                         all supported platforms",
               issue = "27745")]
    pub unsafe fn arg<T: sealed_trait::VaArgSafe>(&mut self) -> T {
        va_arg(self)
    }

    /// Copy the `va_list` at the current location.
    #[unstable(feature = "c_variadic",
               reason = "the `c_variadic` feature has not been properly tested on \
                         all supported platforms",
               issue = "27745")]
    pub unsafe fn copy<F, R>(&self, f: F) -> R
            where F: for<'copy> FnOnce(VaList<'copy>) -> R {
        #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
                      not(target_arch = "x86_64")),
                  all(target_arch = "aarch4", target_os = "ios"),
                  windows))]
        let mut ap = va_copy(self);
        #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
                  not(windows)))]
        let mut ap_inner = va_copy(self);
        #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
                  not(windows)))]
        let mut ap = VaList(&mut ap_inner);
        let ret = f(VaList(ap.0));
        va_end(&mut ap);
        ret
    }
}

extern "rust-intrinsic" {
    /// Destroy the arglist `ap` after initialization with `va_start` or
    /// `va_copy`.
    fn va_end(ap: &mut VaList);

    /// Copy the current location of arglist `src` to the arglist `dst`.
    #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
                  not(target_arch = "x86_64")),
              windows))]
    fn va_copy<'a>(src: &VaList<'a>) -> VaList<'a>;
    #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
              not(windows)))]
    fn va_copy(src: &VaList) -> VaListImpl;

    /// Loads an argument of type `T` from the `va_list` `ap` and increment the
    /// argument `ap` points to.
    fn va_arg<T: sealed_trait::VaArgSafe>(ap: &mut VaList) -> T;
}
<|endoftext|>


<commit_before>#![feature(test)]

extern crate test;
extern crate futures;
#[macro_use]
extern crate tokio_core;

use std::io;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::net::SocketAddr;

use futures::{Future, Poll};
use tokio_core::net::UdpSocket;
use tokio_core::reactor::Core;

use test::Bencher;
use std::thread;
use std::time::Duration;

/// UDP echo server
struct Server {
    socket : UdpSocket,
    buf : Vec<u8>,
    to_send : Option<(usize, SocketAddr)>,
    stop : Arc<AtomicBool>,
}

impl Server {
    fn new(s : UdpSocket, stop : Arc<AtomicBool>) -> Self {
        Server {
            socket: s,
            to_send: None,
            buf: vec![0u8; 1600],
            stop: stop,
        }
    }
}

impl Future for Server {
    type Item = ();
    type Error = io::Error;

    fn poll(&mut self) -> Poll<(), io::Error> {
        loop {
            if self.stop.load(Ordering::SeqCst) {
                return Ok(futures::Async::Ready(()))
            }

            if let Some((size, peer)) = self.to_send.take() {
                match self.socket.send_to(&self.buf[..size], &peer) {
                    Err(e) => {
                        self.to_send = Some((size, peer));
                        return try_nb!(Err(e));
                    },
                    Ok(_) => { }
                }
            }

            self.to_send = Some(
                try_nb!(self.socket.recv_from(&mut self.buf))
                );
        }
    }
}
#[bench]
fn udp_echo_latency(b: &mut Bencher) {
    let server_addr= "127.0.0.1:7398".to_string();
    let server_addr = server_addr.parse::<SocketAddr>().unwrap();
    let client_addr= "127.0.0.1:7399".to_string();
    let client_addr = client_addr.parse::<SocketAddr>().unwrap();

    let stop = Arc::new(AtomicBool::new(false));
    let stop2 = stop.clone();

    let child = thread::spawn(move || {
        let mut l = Core::new().unwrap();
        let handle = l.handle();

        let socket = tokio_core::net::UdpSocket::bind(&server_addr, &handle).unwrap();

        let server = Server::new(socket, stop);

        l.run(server).unwrap();
    });

    // TODO: More reliable way to bind server socket and start server
    // first
    thread::sleep(Duration::from_millis(100));

    let client = std::net::UdpSocket::bind(client_addr).unwrap();

    let mut buf = [0u8; 1000];
    b.iter(|| {
        client.send_to(&buf, &server_addr).unwrap();
        let _ = client.recv_from(&mut buf).unwrap();
    });

    // Stop the server; TODO: Use better method
    stop2.store(true, Ordering::SeqCst);
    thread::sleep(Duration::from_millis(1));
    client.send_to(&buf, &server_addr).unwrap();

    child.join().unwrap();
}
<commit_msg>Add `channel_lantency` and fix previous issues.<commit_after>#![feature(test)]

extern crate test;
extern crate futures;
#[macro_use]
extern crate tokio_core;

use std::io;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::net::SocketAddr;

use futures::{Future, Poll};
use tokio_core::net::UdpSocket;
use tokio_core::reactor::Core;

use test::Bencher;
use std::thread;
use std::time::Duration;

use futures::stream::Stream;

/// UDP echo server
struct EchoServer {
    socket : UdpSocket,
    buf : Vec<u8>,
    to_send : Option<(usize, SocketAddr)>,
    stop : Arc<AtomicBool>,
}

impl EchoServer {
    fn new(s : UdpSocket, stop : Arc<AtomicBool>) -> Self {
        EchoServer {
            socket: s,
            to_send: None,
            buf: vec![0u8; 1600],
            stop: stop,
        }
    }
}

impl Future for EchoServer {
    type Item = ();
    type Error = io::Error;

    fn poll(&mut self) -> Poll<(), io::Error> {
        loop {
            if self.stop.load(Ordering::SeqCst) {
                return Ok(futures::Async::Ready(()))
            }

            if let Some((size, peer)) = self.to_send.take() {
                match self.socket.send_to(&self.buf[..size], &peer) {
                    Err(e) => {
                        self.to_send = Some((size, peer));
                        return try_nb!(Err(e));
                    },
                    Ok(_) => { }
                }
            }

            self.to_send = Some(
                try_nb!(self.socket.recv_from(&mut self.buf))
                );
        }
    }
}

/// UDP echo server
struct ChanServer {
    rx : tokio_core::channel::Receiver<usize>,
    tx : tokio_core::channel::Sender<usize>,
    buf : Option<usize>,
    stop : Arc<AtomicBool>,
}

impl ChanServer {
    fn new(tx : tokio_core::channel::Sender<usize>, rx : tokio_core::channel::Receiver<usize>, stop : Arc<AtomicBool>) -> Self {
        ChanServer {
            rx: rx,
            tx: tx,
            buf: None,
            stop: stop,
        }
    }
}

impl Future for ChanServer {
    type Item = ();
    type Error = io::Error;

    fn poll(&mut self) -> Poll<(), io::Error> {
        loop {
            if self.stop.load(Ordering::SeqCst) {
                return Ok(futures::Async::Ready(()))
            }

            if let Some(u) = self.buf.take() {
                match self.tx.send(u) {
                    Err(e) => {
                        self.buf = Some(u);
                        return try_nb!(Err(e));
                    },
                    Ok(_) => { }
                }
            }

            match self.rx.poll() {
                Ok(futures::Async::Ready(None)) => return Ok(futures::Async::Ready(())),
                Ok(futures::Async::Ready(Some(t))) => { self.buf = Some(t) },
                Ok(futures::Async::NotReady) => return Ok(futures::Async::NotReady),
                Err(e) => return try_nb!(Err(e)),
            }
        }
    }
}
#[bench]
fn udp_echo_latency(b: &mut Bencher) {
    let server_addr= "127.0.0.1:7398".to_string();
    let server_addr = server_addr.parse::<SocketAddr>().unwrap();
    let client_addr= "127.0.0.1:7399".to_string();
    let client_addr = client_addr.parse::<SocketAddr>().unwrap();

    let stop = Arc::new(AtomicBool::new(false));
    let stop2 = stop.clone();

    let child = thread::spawn(move || {
        let mut l = Core::new().unwrap();
        let handle = l.handle();

        let socket = tokio_core::net::UdpSocket::bind(&server_addr, &handle).unwrap();

        let server = EchoServer::new(socket, stop);

        l.run(server).unwrap();
    });

    // TODO: More reliable way to bind server socket and start server
    // first
    thread::sleep(Duration::from_millis(100));

    let client = std::net::UdpSocket::bind(client_addr).unwrap();

    let mut buf = [0u8; 1000];

    // warmup phase; for some reason initial couple of
    // rounds is much slower
    //
    // TODO: Describe the exact reasons; caching? branch predictor? lazy closures?
    for _ in 0..1000 {
        client.send_to(&buf, &server_addr).unwrap();
        let _ = client.recv_from(&mut buf).unwrap();
    }

    b.iter(|| {
        client.send_to(&buf, &server_addr).unwrap();
        let _ = client.recv_from(&mut buf).unwrap();
    });

    // Stop the server; TODO: Use better method
    stop2.store(true, Ordering::SeqCst);
    thread::sleep(Duration::from_millis(1));
    client.send_to(&buf, &server_addr).unwrap();

    child.join().unwrap();
}

#[bench]
fn channel_latency(b: &mut Bencher) {
    let stop = Arc::new(AtomicBool::new(false));
    let stop2 = stop.clone();

    // TODO: Any way to start Loop on a separate thread and yet get
    // a tokio_core::channel to it?
    let (tx, rx) = std::sync::mpsc::channel();

    let child = thread::spawn(move || {
        let mut l = Core::new().unwrap();
        let handle = l.handle();

        let (in_tx, in_rx) = tokio_core::channel::channel(&handle).unwrap();
        let (out_tx, out_rx) = tokio_core::channel::channel(&handle).unwrap();

        let server = ChanServer::new(out_tx, in_rx, stop);

        tx.send((in_tx, out_rx)).unwrap();
        l.run(server).unwrap();
    });

    let (in_tx, out_rx) = rx.recv().unwrap();

    // TODO: More reliable way to bind server socket and start server
    // first
    thread::sleep(Duration::from_millis(100));

    let mut rx_iter = out_rx.wait();

    // warmup phase; for some reason initial couple of
    // rounds is much slower
    //
    // TODO: Describe the exact reasons; caching? branch predictor? lazy closures?
    for _ in 0..1000 {
        in_tx.send(1usize).unwrap();
        let _ = rx_iter.next();
    }

    b.iter(|| {
        in_tx.send(1usize).unwrap();
        let _ = rx_iter.next();
    });

    // Stop the server; TODO: Use better method
    stop2.store(true, Ordering::SeqCst);
    thread::sleep(Duration::from_millis(1));
    in_tx.send(1usize).unwrap();

    child.join().unwrap();
}
<|endoftext|>


<commit_before>use std::ops::{Add, Mul};

/// A pair of coordinates
#[derive(Clone, Copy)]
pub struct Vec2(pub usize, pub usize);

/// A structure of values
pub struct Matrix<T> {
    /// 2 dimensional array of rows and columns
    dim: Vec2,
    /// `Vector` of values in the `Matrix`
    buffer: Vec<T>,
}

impl <T> Matrix<T> {
    /// Returns a new `Matrix`
    ///
    /// # Arguments
    ///
    /// - `dimensions` - 2 dimensional array of rows and columns
    /// - `buffer` - `Vector` of values
    ///
    /// # Example
    ///
    /// ```
    /// let matrix = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0, 1, 2, 3, 4, 5]);
    /// ```
    pub fn new(dimensions: Vec2, buffer: Vec<T>) -> Matrix<T> {
        Matrix {
            dim: dimensions,
            buffer: buffer,
        }
    }

    pub fn len(&self) -> usize {
        self.buffer.len()
    }
}

impl <T> Matrix<T> where T: Copy {
    /// Returns reference to value at `Vec2`
    ///
    /// # Arguments
    ///
    /// - `Vec2` - coordinates of the value in the `Matrix`
    ///
    /// # Example
    ///
    /// ```
    /// let matrix = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0, 1, 2, 3, 4, 5]);
    /// assert_eq!(matrix.get(ktensor::math::Vec2(1, 2)), 5);
    /// assert_eq!(matrix.get(ktensor::math::Vec2(1, 2)), 5);
    /// ```
    pub fn get(&self, Vec2(x, y): Vec2) -> T {
        self.buffer[x * self.dim.1 + y]
    }
}

//////////////
// Addition //
//////////////

impl<T> Add<Matrix<T>> for Matrix<T> where T: Add<Output=T> + Copy {
    type Output = Matrix<T>;

    /// Add Matricies
    ///
    /// # Arguments
    ///
    /// - `self` - this matrix
    /// - `rhs` - another matrix
    ///
    /// # Example
    ///
    /// ```
    /// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
    /// let matrix2 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![5.0, 4.0, 3.0, 2.0, 1.0, 0.0]);
    /// let matrix3 = matrix1 + matrix2;
    /// assert_eq!(matrix3.get(ktensor::math::Vec2(0, 0)), 5.0);
    /// ```
    fn add(self, rhs: Matrix<T>) -> Matrix<T> {
        let mut buffer = Vec::with_capacity(self.len());
        for (&i, &j) in self.buffer.iter().zip(rhs.buffer.iter()) {
            buffer.push(i + j);
        }
        Matrix::new(self.dim, buffer)
    }
}

impl<'a, 'b, T> Add<&'b Matrix<T>> for &'a Matrix<T> where T: Add<Output=T> + Copy {
    type Output = Matrix<T>;

    /// Add Matricies by reference
    ///
    /// # Arguments
    ///
    /// - `self` - this matrix reference
    /// - `rhs` - another matrix reference
    ///
    /// # Example
    ///
    /// ```
    /// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
    /// let matrix2 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![5.0, 4.0, 3.0, 2.0, 1.0, 0.0]);
    /// let matrix3 = &matrix1 + &matrix2;
    /// assert_eq!(matrix1.get(ktensor::math::Vec2(0, 0)), 0.0);
    /// assert_eq!(matrix2.get(ktensor::math::Vec2(0, 0)), 5.0);
    /// assert_eq!(matrix3.get(ktensor::math::Vec2(0, 0)), 5.0);
    /// ```
    fn add(self, rhs: &'b Matrix<T>) -> Matrix<T> {
        let mut buffer = Vec::with_capacity(self.len());
        for (&i, &j) in self.buffer.iter().zip(rhs.buffer.iter()) {
            buffer.push(i + j);
        }
        Matrix::new(self.dim, buffer)
    }
}

impl<T> Add<T> for Matrix<T> where T: Add<Output=T> + Copy {
    type Output = Matrix<T>;

    /// Add Matrix and a constant
    ///
    /// # Arguments
    ///
    /// - `self` - this matrix
    /// - `rhs` - a constant
    ///
    /// # Example
    ///
    /// ```
    /// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
    /// let float = 1.0;
    /// let matrix2 = matrix1 + float;
    /// assert_eq!(matrix2.get(ktensor::math::Vec2(0, 0)), 1.0);
    /// ```
    fn add(self, rhs: T) -> Matrix<T> {
        let mut buffer = Vec::with_capacity(self.len());
        for &i in self.buffer.iter() {
            buffer.push(i + rhs);
        }
        Matrix::new(self.dim, buffer)
    }
}

impl<'a, 'b, T> Add<&'b T> for &'a Matrix<T> where T: Add<Output=T> + Copy {
    type Output = Matrix<T>;

    /// Add Matrix and a constant
    ///
    /// # Arguments
    ///
    /// - `self` - this matrix reference
    /// - `rhs` - a constant reference
    ///
    /// # Example
    ///
    /// ```
    /// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
    /// let float = 1.0;
    /// let matrix2 = &matrix1 + &float;
    /// assert_eq!(matrix1.get(ktensor::math::Vec2(0, 0)), 0.0);
    /// assert_eq!(matrix2.get(ktensor::math::Vec2(0, 0)), 1.0);
    /// assert_eq!(float, 1.0);
    /// ```
    fn add(self, &rhs: &'b T) -> Matrix<T> {
        let mut buffer = Vec::with_capacity(self.len());
        for &i in self.buffer.iter() {
            buffer.push(i + rhs);
        }
        Matrix::new(self.dim, buffer)
    }
}

/////////////////////
// Multiplication  //
/////////////////////

impl<T> Mul<Matrix<T>> for Matrix<T> where T: Mul<Output=T> + Add<Output=T> + Copy {
    type Output = Matrix<T>;

    /// Multiply Matricies
    ///
    /// # Arguments
    ///
    /// - `self` - this matrix
    /// - `rhs` - another matrix
    ///
    /// # Example
    ///
    /// ```
    /// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
    /// let matrix2 = ktensor::math::Matrix::new(ktensor::math::Vec2(3, 2), vec![5.0, 4.0, 3.0, 2.0, 1.0, 0.0]);
    /// let matrix3 = matrix1 * matrix2;
    /// assert_eq!(matrix3.len(), 4);
    /// assert_eq!(matrix3.get(ktensor::math::Vec2(0, 0)), 5.0);
    /// ```
    fn mul(self, rhs: Matrix<T>) -> Matrix<T> {
        let Vec2(x, y) = self.dim;
        let Vec2(x2, y2) = rhs.dim;
        assert_eq!(y, x2);
        let mut buffer = Vec::with_capacity(x * y2);
        for i in 0..x {
            for j in 0..y2 {
                let mut sum = self.get(Vec2(i, 0)) * rhs.get(Vec2(0, j));
                for k in 1..y {
                    sum = sum + self.get(Vec2(i, k)) * rhs.get(Vec2(k, j));
                }
                buffer.push(sum);
            }
        }
        Matrix::new(Vec2(x, y2), buffer)
    }
}

impl<'a, 'b, T> Mul<&'b Matrix<T>> for &'a Matrix<T> where T: Mul<Output=T> + Add<Output=T> + Copy {
    type Output = Matrix<T>;

    /// Multiply Matricies by reference
    ///
    /// # Arguments
    ///
    /// - `self` - this matrix reference
    /// - `rhs` - another matrix reference
    ///
    /// # Example
    ///
    /// ```
    /// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
    /// let matrix2 = ktensor::math::Matrix::new(ktensor::math::Vec2(3, 2), vec![5.0, 4.0, 3.0, 2.0, 1.0, 0.0]);
    /// let matrix3 = &matrix1 * &matrix2;
    /// assert_eq!(matrix3.len(), 4);
    /// assert_eq!(matrix1.get(ktensor::math::Vec2(0, 0)), 0.0);
    /// assert_eq!(matrix2.get(ktensor::math::Vec2(0, 0)), 5.0);
    /// assert_eq!(matrix3.get(ktensor::math::Vec2(0, 0)), 5.0);
    /// ```
    fn mul(self, rhs: &'b Matrix<T>) -> Matrix<T> {
        let Vec2(x, y) = self.dim;
        let Vec2(x2, y2) = rhs.dim;
        assert_eq!(y, x2);
        let mut buffer = Vec::with_capacity(x * y2);
        for i in 0..x {
            for j in 0..y2 {
                let mut sum = self.get(Vec2(i, 0)) * rhs.get(Vec2(0, j));
                for k in 1..y {
                    sum = sum + self.get(Vec2(i, k)) * rhs.get(Vec2(k, j));
                }
                buffer.push(sum);
            }
        }
        Matrix::new(Vec2(x, y2), buffer)
    }
}

// impl<T> Add<T> for Matrix<T> where T: Add + Copy {
//     type Output = Matrix<<T as Add>::Output>;
//
//     /// Add Matrix and a constant
//     ///
//     /// # Arguments
//     ///
//     /// - `self` - this matrix
//     /// - `rhs` - a constant
//     ///
//     /// # Example
//     ///
//     /// ```
//     /// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
//     /// let float = 1.0;
//     /// let matrix2 = matrix1 + float;
//     /// assert_eq!(matrix2.get(ktensor::math::Vec2(0, 0)), 1.0);
//     /// ```
//     fn add(self, rhs: T) -> Matrix<<T as Add>::Output> {
//         let mut buffer = Vec::new();
//         for &i in self.buffer.iter() {
//             buffer.push(i + rhs);
//         }
//         Matrix::new(self.dim, buffer)
//     }
// }
//
// impl<'a, 'b, T> Add<&'b T> for &'a Matrix<T> where T: Add + Copy {
//     type Output = Matrix<<T as Add>::Output>;
//
//     /// Add Matrix and a constant
//     ///
//     /// # Arguments
//     ///
//     /// - `self` - this matrix reference
//     /// - `rhs` - a constant reference
//     ///
//     /// # Example
//     ///
//     /// ```
//     /// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
//     /// let float = 1.0;
//     /// let matrix2 = &matrix1 + &float;
//     /// assert_eq!(matrix1.get(ktensor::math::Vec2(0, 0)), 0.0);
//     /// assert_eq!(matrix2.get(ktensor::math::Vec2(0, 0)), 1.0);
//     /// assert_eq!(float, 1.0);
//     /// ```
//     fn add(self, &rhs: &'b T) -> Matrix<<T as Add>::Output> {
//         let mut buffer = Vec::new();
//         for &i in self.buffer.iter() {
//             buffer.push(i + rhs);
//         }
//         Matrix::new(self.dim, buffer)
//     }
// }
<commit_msg>matrix math finished<commit_after>use std::ops::{Add, Mul};

/// A pair of coordinates
#[derive(Clone, Copy)]
pub struct Vec2(pub usize, pub usize);

/// A structure of values
pub struct Matrix<T> {
    /// 2 dimensional array of rows and columns
    dim: Vec2,
    /// `Vector` of values in the `Matrix`
    buffer: Vec<T>,
}

impl <T> Matrix<T> {
    /// Returns a new `Matrix`
    ///
    /// # Arguments
    ///
    /// - `dimensions` - 2 dimensional array of rows and columns
    /// - `buffer` - `Vector` of values
    ///
    /// # Example
    ///
    /// ```
    /// let matrix = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0, 1, 2, 3, 4, 5]);
    /// ```
    pub fn new(dimensions: Vec2, buffer: Vec<T>) -> Matrix<T> {
        Matrix {
            dim: dimensions,
            buffer: buffer,
        }
    }

    pub fn len(&self) -> usize {
        self.buffer.len()
    }
}

impl <T> Matrix<T> where T: Copy {
    /// Returns reference to value at `Vec2`
    ///
    /// # Arguments
    ///
    /// - `Vec2` - coordinates of the value in the `Matrix`
    ///
    /// # Example
    ///
    /// ```
    /// let matrix = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0, 1, 2, 3, 4, 5]);
    /// assert_eq!(matrix.get(ktensor::math::Vec2(1, 2)), 5);
    /// assert_eq!(matrix.get(ktensor::math::Vec2(1, 2)), 5);
    /// ```
    pub fn get(&self, Vec2(x, y): Vec2) -> T {
        self.buffer[x * self.dim.1 + y]
    }
}

//////////////
// Addition //
//////////////

impl<T> Add<Matrix<T>> for Matrix<T> where T: Add<Output=T> + Copy {
    type Output = Matrix<T>;

    /// Add Matricies
    ///
    /// # Arguments
    ///
    /// - `self` - this matrix
    /// - `rhs` - another matrix
    ///
    /// # Example
    ///
    /// ```
    /// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
    /// let matrix2 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![5.0, 4.0, 3.0, 2.0, 1.0, 0.0]);
    /// let matrix3 = matrix1 + matrix2;
    /// assert_eq!(matrix3.get(ktensor::math::Vec2(0, 0)), 5.0);
    /// ```
    fn add(self, rhs: Matrix<T>) -> Matrix<T> {
        let mut buffer = Vec::with_capacity(self.len());
        for (&i, &j) in self.buffer.iter().zip(rhs.buffer.iter()) {
            buffer.push(i + j);
        }
        Matrix::new(self.dim, buffer)
    }
}

impl<'a, 'b, T> Add<&'b Matrix<T>> for &'a Matrix<T> where T: Add<Output=T> + Copy {
    type Output = Matrix<T>;

    /// Add Matricies by reference
    ///
    /// # Arguments
    ///
    /// - `self` - this matrix reference
    /// - `rhs` - another matrix reference
    ///
    /// # Example
    ///
    /// ```
    /// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
    /// let matrix2 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![5.0, 4.0, 3.0, 2.0, 1.0, 0.0]);
    /// let matrix3 = &matrix1 + &matrix2;
    /// assert_eq!(matrix1.get(ktensor::math::Vec2(0, 0)), 0.0);
    /// assert_eq!(matrix2.get(ktensor::math::Vec2(0, 0)), 5.0);
    /// assert_eq!(matrix3.get(ktensor::math::Vec2(0, 0)), 5.0);
    /// ```
    fn add(self, rhs: &'b Matrix<T>) -> Matrix<T> {
        let mut buffer = Vec::with_capacity(self.len());
        for (&i, &j) in self.buffer.iter().zip(rhs.buffer.iter()) {
            buffer.push(i + j);
        }
        Matrix::new(self.dim, buffer)
    }
}

impl<T> Add<T> for Matrix<T> where T: Add<Output=T> + Copy {
    type Output = Matrix<T>;

    /// Add Matrix and a constant
    ///
    /// # Arguments
    ///
    /// - `self` - this matrix
    /// - `rhs` - a constant
    ///
    /// # Example
    ///
    /// ```
    /// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
    /// let float = 1.0;
    /// let matrix2 = matrix1 + float;
    /// assert_eq!(matrix2.get(ktensor::math::Vec2(0, 0)), 1.0);
    /// ```
    fn add(self, rhs: T) -> Matrix<T> {
        let mut buffer = Vec::with_capacity(self.len());
        for &i in self.buffer.iter() {
            buffer.push(i + rhs);
        }
        Matrix::new(self.dim, buffer)
    }
}

impl<'a, 'b, T> Add<&'b T> for &'a Matrix<T> where T: Add<Output=T> + Copy {
    type Output = Matrix<T>;

    /// Add Matrix and a constant
    ///
    /// # Arguments
    ///
    /// - `self` - this matrix reference
    /// - `rhs` - a constant reference
    ///
    /// # Example
    ///
    /// ```
    /// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
    /// let float = 1.0;
    /// let matrix2 = &matrix1 + &float;
    /// assert_eq!(matrix1.get(ktensor::math::Vec2(0, 0)), 0.0);
    /// assert_eq!(matrix2.get(ktensor::math::Vec2(0, 0)), 1.0);
    /// assert_eq!(float, 1.0);
    /// ```
    fn add(self, &rhs: &'b T) -> Matrix<T> {
        let mut buffer = Vec::with_capacity(self.len());
        for &i in self.buffer.iter() {
            buffer.push(i + rhs);
        }
        Matrix::new(self.dim, buffer)
    }
}

/////////////////////
// Multiplication  //
/////////////////////

impl<T> Mul<Matrix<T>> for Matrix<T> where T: Mul<Output=T> + Add<Output=T> + Copy {
    type Output = Matrix<T>;

    /// Multiply Matricies
    ///
    /// # Arguments
    ///
    /// - `self` - this matrix
    /// - `rhs` - another matrix
    ///
    /// # Example
    ///
    /// ```
    /// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
    /// let matrix2 = ktensor::math::Matrix::new(ktensor::math::Vec2(3, 2), vec![5.0, 4.0, 3.0, 2.0, 1.0, 0.0]);
    /// let matrix3 = matrix1 * matrix2;
    /// assert_eq!(matrix3.len(), 4);
    /// assert_eq!(matrix3.get(ktensor::math::Vec2(0, 0)), 5.0);
    /// ```
    fn mul(self, rhs: Matrix<T>) -> Matrix<T> {
        let Vec2(x, y) = self.dim;
        let Vec2(x2, y2) = rhs.dim;
        assert_eq!(y, x2);
        let mut buffer = Vec::with_capacity(x * y2);
        for i in 0..x {
            for j in 0..y2 {
                let mut sum = self.get(Vec2(i, 0)) * rhs.get(Vec2(0, j));
                for k in 1..y {
                    sum = sum + self.get(Vec2(i, k)) * rhs.get(Vec2(k, j));
                }
                buffer.push(sum);
            }
        }
        Matrix::new(Vec2(x, y2), buffer)
    }
}

impl<'a, 'b, T> Mul<&'b Matrix<T>> for &'a Matrix<T> where T: Mul<Output=T> + Add<Output=T> + Copy {
    type Output = Matrix<T>;

    /// Multiply Matricies by reference
    ///
    /// # Arguments
    ///
    /// - `self` - this matrix reference
    /// - `rhs` - another matrix reference
    ///
    /// # Example
    ///
    /// ```
    /// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
    /// let matrix2 = ktensor::math::Matrix::new(ktensor::math::Vec2(3, 2), vec![5.0, 4.0, 3.0, 2.0, 1.0, 0.0]);
    /// let matrix3 = &matrix1 * &matrix2;
    /// assert_eq!(matrix3.len(), 4);
    /// assert_eq!(matrix1.get(ktensor::math::Vec2(0, 0)), 0.0);
    /// assert_eq!(matrix2.get(ktensor::math::Vec2(0, 0)), 5.0);
    /// assert_eq!(matrix3.get(ktensor::math::Vec2(0, 0)), 5.0);
    /// ```
    fn mul(self, rhs: &'b Matrix<T>) -> Matrix<T> {
        let Vec2(x, y) = self.dim;
        let Vec2(x2, y2) = rhs.dim;
        assert_eq!(y, x2);
        let mut buffer = Vec::with_capacity(x * y2);
        for i in 0..x {
            for j in 0..y2 {
                let mut sum = self.get(Vec2(i, 0)) * rhs.get(Vec2(0, j));
                for k in 1..y {
                    sum = sum + self.get(Vec2(i, k)) * rhs.get(Vec2(k, j));
                }
                buffer.push(sum);
            }
        }
        Matrix::new(Vec2(x, y2), buffer)
    }
}

impl<T> Mul<T> for Matrix<T> where T: Mul<Output=T> + Copy {
    type Output = Matrix<T>;

    /// Multiply Matrix and a constant
    ///
    /// # Arguments
    ///
    /// - `self` - this matrix
    /// - `rhs` - a constant
    ///
    /// # Example
    ///
    /// ```
    /// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
    /// let float = 2.0;
    /// let matrix2 = matrix1 * float;
    /// assert_eq!(matrix2.get(ktensor::math::Vec2(0, 2)), 4.0);
    /// ```
    fn mul(self, rhs: T) -> Matrix<T> {
        let mut buffer = Vec::with_capacity(self.len());
        for &i in self.buffer.iter() {
            buffer.push(i * rhs);
        }
        Matrix::new(self.dim, buffer)
    }
}

impl<'a, 'b, T> Mul<&'b T> for &'a Matrix<T> where T: Mul<Output=T> + Copy {
    type Output = Matrix<T>;

    /// Multiply Matrix and a constant
    ///
    /// # Arguments
    ///
    /// - `self` - this matrix reference
    /// - `rhs` - a constant reference
    ///
    /// # Example
    ///
    /// ```
    /// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
    /// let float = 2.0;
    /// let matrix2 = &matrix1 * &float;
    /// assert_eq!(matrix1.get(ktensor::math::Vec2(0, 2)), 2.0);
    /// assert_eq!(matrix2.get(ktensor::math::Vec2(0, 2)), 4.0);
    /// assert_eq!(float, 2.0);
    /// ```
    fn mul(self, &rhs: &'b T) -> Matrix<T> {
        let mut buffer = Vec::with_capacity(self.len());
        for &i in self.buffer.iter() {
            buffer.push(i * rhs);
        }
        Matrix::new(self.dim, buffer)
    }
}
<|endoftext|>


<commit_before>use futures_core::task::{Context, Poll};
#[cfg(feature = "read_initializer")]
use futures_io::Initializer;
use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, IoSliceMut, SeekFrom};
use std::io;
use std::pin::Pin;

/// A `Cursor` wraps an in-memory buffer and provides it with a
/// [`AsyncSeek`] implementation.
///
/// `Cursor`s are used with in-memory buffers, anything implementing
/// `AsRef<[u8]>`, to allow them to implement [`AsyncRead`] and/or [`AsyncWrite`],
/// allowing these buffers to be used anywhere you might use a reader or writer
/// that does actual I/O.
///
/// The standard library implements some I/O traits on various types which
/// are commonly used as a buffer, like `Cursor<`[`Vec`]`<u8>>` and
/// `Cursor<`[`&[u8]`][bytes]`>`.
///
/// [`AsyncSeek`]: trait.AsyncSeek.html
/// [`AsyncRead`]: trait.AsyncRead.html
/// [`AsyncWrite`]: trait.AsyncWrite.html
/// [bytes]: https://doc.rust-lang.org/std/primitive.slice.html
#[derive(Clone, Debug, Default)]
pub struct Cursor<T> {
    inner: io::Cursor<T>,
}

impl<T> Cursor<T> {
    /// Creates a new cursor wrapping the provided underlying in-memory buffer.
    ///
    /// Cursor initial position is `0` even if underlying buffer (e.g., `Vec`)
    /// is not empty. So writing to cursor starts with overwriting `Vec`
    /// content, not with appending to it.
    ///
    /// # Examples
    ///
    /// ```
    /// use futures::io::Cursor;
    ///
    /// let buff = Cursor::new(Vec::new());
    /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
    /// # force_inference(&buff);
    /// ```
    pub fn new(inner: T) -> Self {
        Self {
            inner: io::Cursor::new(inner),
        }
    }

    /// Consumes this cursor, returning the underlying value.
    ///
    /// # Examples
    ///
    /// ```
    /// use futures::io::Cursor;
    ///
    /// let buff = Cursor::new(Vec::new());
    /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
    /// # force_inference(&buff);
    ///
    /// let vec = buff.into_inner();
    /// ```
    pub fn into_inner(self) -> T {
        self.inner.into_inner()
    }

    /// Gets a reference to the underlying value in this cursor.
    ///
    /// # Examples
    ///
    /// ```
    /// use futures::io::Cursor;
    ///
    /// let buff = Cursor::new(Vec::new());
    /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
    /// # force_inference(&buff);
    ///
    /// let reference = buff.get_ref();
    /// ```
    pub fn get_ref(&self) -> &T {
        self.inner.get_ref()
    }

    /// Gets a mutable reference to the underlying value in this cursor.
    ///
    /// Care should be taken to avoid modifying the internal I/O state of the
    /// underlying value as it may corrupt this cursor's position.
    ///
    /// # Examples
    ///
    /// ```
    /// use futures::io::Cursor;
    ///
    /// let mut buff = Cursor::new(Vec::new());
    /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
    /// # force_inference(&buff);
    ///
    /// let reference = buff.get_mut();
    /// ```
    pub fn get_mut(&mut self) -> &mut T {
        self.inner.get_mut()
    }

    /// Returns the current position of this cursor.
    ///
    /// # Examples
    ///
    /// ```
    /// # futures::executor::block_on(async {
    /// use futures::io::{AsyncSeekExt, Cursor, SeekFrom};
    ///
    /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
    ///
    /// assert_eq!(buff.position(), 0);
    ///
    /// buff.seek(SeekFrom::Current(2)).await?;
    /// assert_eq!(buff.position(), 2);
    ///
    /// buff.seek(SeekFrom::Current(-1)).await?;
    /// assert_eq!(buff.position(), 1);
    /// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
    /// ```
    pub fn position(&self) -> u64 {
        self.inner.position()
    }

    /// Sets the position of this cursor.
    ///
    /// # Examples
    ///
    /// ```
    /// use futures::io::Cursor;
    ///
    /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
    ///
    /// assert_eq!(buff.position(), 0);
    ///
    /// buff.set_position(2);
    /// assert_eq!(buff.position(), 2);
    ///
    /// buff.set_position(4);
    /// assert_eq!(buff.position(), 4);
    /// ```
    pub fn set_position(&mut self, pos: u64) {
        self.inner.set_position(pos)
    }
}

impl<T> AsyncSeek for Cursor<T>
where
    T: AsRef<[u8]> + Unpin,
{
    fn poll_seek(
        mut self: Pin<&mut Self>,
        _: &mut Context<'_>,
        pos: SeekFrom,
    ) -> Poll<io::Result<u64>> {
        Poll::Ready(io::Seek::seek(&mut self.inner, pos))
    }
}

impl<T: AsRef<[u8]> + Unpin> AsyncRead for Cursor<T> {
    #[cfg(feature = "read_initializer")]
    #[inline]
    unsafe fn initializer(&self) -> Initializer {
        io::Read::initializer(&self.inner)
    }

    fn poll_read(
        mut self: Pin<&mut Self>,
        _cx: &mut Context<'_>,
        buf: &mut [u8],
    ) -> Poll<io::Result<usize>> {
        Poll::Ready(io::Read::read(&mut self.inner, buf))
    }

    fn poll_read_vectored(
        mut self: Pin<&mut Self>,
        _: &mut Context<'_>,
        bufs: &mut [IoSliceMut<'_>],
    ) -> Poll<io::Result<usize>> {
        Poll::Ready(io::Read::read_vectored(&mut self.inner, bufs))
    }
}

impl<T> AsyncBufRead for Cursor<T>
where
    T: AsRef<[u8]> + Unpin,
{
    fn poll_fill_buf(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
        Poll::Ready(io::BufRead::fill_buf(&mut self.get_mut().inner))
    }

    fn consume(mut self: Pin<&mut Self>, amt: usize) {
        io::BufRead::consume(&mut self.inner, amt)
    }
}

macro_rules! delegate_async_write_to_stdio {
    () => {
        fn poll_write(mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &[u8])
            -> Poll<io::Result<usize>>
        {
            Poll::Ready(io::Write::write(&mut self.inner, buf))
        }

        fn poll_write_vectored(mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &[IoSlice<'_>])
            -> Poll<io::Result<usize>>
        {
            Poll::Ready(io::Write::write_vectored(&mut self.inner, bufs))
        }

        fn poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
            Poll::Ready(io::Write::flush(&mut self.inner))
        }

        fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
            self.poll_flush(cx)
        }
    }
}

impl AsyncWrite for Cursor<&mut [u8]> {
    delegate_async_write_to_stdio!();
}

impl AsyncWrite for Cursor<&mut Vec<u8>> {
    delegate_async_write_to_stdio!();
}

impl AsyncWrite for Cursor<Vec<u8>> {
    delegate_async_write_to_stdio!();
}

impl AsyncWrite for Cursor<Box<[u8]>> {
    delegate_async_write_to_stdio!();
}
<commit_msg>Fix typo in io/cursor.rs (#2336)<commit_after>use futures_core::task::{Context, Poll};
#[cfg(feature = "read_initializer")]
use futures_io::Initializer;
use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, IoSliceMut, SeekFrom};
use std::io;
use std::pin::Pin;

/// A `Cursor` wraps an in-memory buffer and provides it with a
/// [`AsyncSeek`] implementation.
///
/// `Cursor`s are used with in-memory buffers, anything implementing
/// `AsRef<[u8]>`, to allow them to implement [`AsyncRead`] and/or [`AsyncWrite`],
/// allowing these buffers to be used anywhere you might use a reader or writer
/// that does actual I/O.
///
/// This library implements some I/O traits on various types which
/// are commonly used as a buffer, like `Cursor<`[`Vec`]`<u8>>` and
/// `Cursor<`[`&[u8]`][bytes]`>`.
///
/// [`AsyncSeek`]: trait.AsyncSeek.html
/// [`AsyncRead`]: trait.AsyncRead.html
/// [`AsyncWrite`]: trait.AsyncWrite.html
/// [bytes]: https://doc.rust-lang.org/std/primitive.slice.html
#[derive(Clone, Debug, Default)]
pub struct Cursor<T> {
    inner: io::Cursor<T>,
}

impl<T> Cursor<T> {
    /// Creates a new cursor wrapping the provided underlying in-memory buffer.
    ///
    /// Cursor initial position is `0` even if underlying buffer (e.g., `Vec`)
    /// is not empty. So writing to cursor starts with overwriting `Vec`
    /// content, not with appending to it.
    ///
    /// # Examples
    ///
    /// ```
    /// use futures::io::Cursor;
    ///
    /// let buff = Cursor::new(Vec::new());
    /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
    /// # force_inference(&buff);
    /// ```
    pub fn new(inner: T) -> Self {
        Self {
            inner: io::Cursor::new(inner),
        }
    }

    /// Consumes this cursor, returning the underlying value.
    ///
    /// # Examples
    ///
    /// ```
    /// use futures::io::Cursor;
    ///
    /// let buff = Cursor::new(Vec::new());
    /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
    /// # force_inference(&buff);
    ///
    /// let vec = buff.into_inner();
    /// ```
    pub fn into_inner(self) -> T {
        self.inner.into_inner()
    }

    /// Gets a reference to the underlying value in this cursor.
    ///
    /// # Examples
    ///
    /// ```
    /// use futures::io::Cursor;
    ///
    /// let buff = Cursor::new(Vec::new());
    /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
    /// # force_inference(&buff);
    ///
    /// let reference = buff.get_ref();
    /// ```
    pub fn get_ref(&self) -> &T {
        self.inner.get_ref()
    }

    /// Gets a mutable reference to the underlying value in this cursor.
    ///
    /// Care should be taken to avoid modifying the internal I/O state of the
    /// underlying value as it may corrupt this cursor's position.
    ///
    /// # Examples
    ///
    /// ```
    /// use futures::io::Cursor;
    ///
    /// let mut buff = Cursor::new(Vec::new());
    /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
    /// # force_inference(&buff);
    ///
    /// let reference = buff.get_mut();
    /// ```
    pub fn get_mut(&mut self) -> &mut T {
        self.inner.get_mut()
    }

    /// Returns the current position of this cursor.
    ///
    /// # Examples
    ///
    /// ```
    /// # futures::executor::block_on(async {
    /// use futures::io::{AsyncSeekExt, Cursor, SeekFrom};
    ///
    /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
    ///
    /// assert_eq!(buff.position(), 0);
    ///
    /// buff.seek(SeekFrom::Current(2)).await?;
    /// assert_eq!(buff.position(), 2);
    ///
    /// buff.seek(SeekFrom::Current(-1)).await?;
    /// assert_eq!(buff.position(), 1);
    /// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
    /// ```
    pub fn position(&self) -> u64 {
        self.inner.position()
    }

    /// Sets the position of this cursor.
    ///
    /// # Examples
    ///
    /// ```
    /// use futures::io::Cursor;
    ///
    /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
    ///
    /// assert_eq!(buff.position(), 0);
    ///
    /// buff.set_position(2);
    /// assert_eq!(buff.position(), 2);
    ///
    /// buff.set_position(4);
    /// assert_eq!(buff.position(), 4);
    /// ```
    pub fn set_position(&mut self, pos: u64) {
        self.inner.set_position(pos)
    }
}

impl<T> AsyncSeek for Cursor<T>
where
    T: AsRef<[u8]> + Unpin,
{
    fn poll_seek(
        mut self: Pin<&mut Self>,
        _: &mut Context<'_>,
        pos: SeekFrom,
    ) -> Poll<io::Result<u64>> {
        Poll::Ready(io::Seek::seek(&mut self.inner, pos))
    }
}

impl<T: AsRef<[u8]> + Unpin> AsyncRead for Cursor<T> {
    #[cfg(feature = "read_initializer")]
    #[inline]
    unsafe fn initializer(&self) -> Initializer {
        io::Read::initializer(&self.inner)
    }

    fn poll_read(
        mut self: Pin<&mut Self>,
        _cx: &mut Context<'_>,
        buf: &mut [u8],
    ) -> Poll<io::Result<usize>> {
        Poll::Ready(io::Read::read(&mut self.inner, buf))
    }

    fn poll_read_vectored(
        mut self: Pin<&mut Self>,
        _: &mut Context<'_>,
        bufs: &mut [IoSliceMut<'_>],
    ) -> Poll<io::Result<usize>> {
        Poll::Ready(io::Read::read_vectored(&mut self.inner, bufs))
    }
}

impl<T> AsyncBufRead for Cursor<T>
where
    T: AsRef<[u8]> + Unpin,
{
    fn poll_fill_buf(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
        Poll::Ready(io::BufRead::fill_buf(&mut self.get_mut().inner))
    }

    fn consume(mut self: Pin<&mut Self>, amt: usize) {
        io::BufRead::consume(&mut self.inner, amt)
    }
}

macro_rules! delegate_async_write_to_stdio {
    () => {
        fn poll_write(mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &[u8])
            -> Poll<io::Result<usize>>
        {
            Poll::Ready(io::Write::write(&mut self.inner, buf))
        }

        fn poll_write_vectored(mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &[IoSlice<'_>])
            -> Poll<io::Result<usize>>
        {
            Poll::Ready(io::Write::write_vectored(&mut self.inner, bufs))
        }

        fn poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
            Poll::Ready(io::Write::flush(&mut self.inner))
        }

        fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
            self.poll_flush(cx)
        }
    }
}

impl AsyncWrite for Cursor<&mut [u8]> {
    delegate_async_write_to_stdio!();
}

impl AsyncWrite for Cursor<&mut Vec<u8>> {
    delegate_async_write_to_stdio!();
}

impl AsyncWrite for Cursor<Vec<u8>> {
    delegate_async_write_to_stdio!();
}

impl AsyncWrite for Cursor<Box<[u8]>> {
    delegate_async_write_to_stdio!();
}
<|endoftext|>