<commit_before>#![feature(proc_macro)]

#[macro_use]
extern crate serde_derive;

extern crate redis;

extern crate serde;
extern crate serde_redis;

use std::collections::HashMap;

use serde::Deserialize;
use serde_redis::Deserializer;

use redis::Value;

#[test]
fn deserialize_unit_struct_string() {
    let v = Value::Data(b"hello".to_vec());

    #[derive(Deserialize, Debug, PartialEq)]
    struct Unit(String);

    let de = Deserializer::new(v);
    let actual: Unit = Deserialize::deserialize(de).unwrap();

    let expected = Unit("hello".to_owned());
    assert_eq!(expected, actual);
}

#[test]
fn deserialize_unit_struct_u8_redis_int() {
    let num = 5u8;
    let v = Value::Int(num as i64);

    #[derive(Deserialize, Debug, PartialEq)]
    struct IntUnit(u8);

    let de = Deserializer::new(v);
    let actual: IntUnit = Deserialize::deserialize(de).unwrap();

    let expected = IntUnit(num);
    assert_eq!(expected, actual);
}

#[test]
fn deserialize_bool() {
    let v = vec![
        Value::Data(b"0".to_vec()), Value::Data(b"false".to_vec()), Value::Data(b"False".to_vec()),
        Value::Data(b"1".to_vec()), Value::Data(b"true".to_vec()), Value::Data(b"True".to_vec())
    ];

    let de = Deserializer::new(Value::Bulk(v));
    let actual: Vec<bool> = Deserialize::deserialize(de).unwrap();

    let expected = vec![false, false, false, true, true, true];
    assert_eq!(expected, actual);
}

#[test]
fn deserialize_tuple() {
    let v = vec![Value::Int(5), Value::Data(b"hello".to_vec())];

    let de = Deserializer::new(Value::Bulk(v));
    let actual: (u8, String) = Deserialize::deserialize(de).unwrap();

    let expected = (5, "hello".to_owned());
    assert_eq!(expected, actual);
}

#[test]
fn deserialize_struct() {
    let v = vec![
        Value::Data(b"a".to_vec()), Value::Data(b"apple".to_vec()),
        Value::Data(b"b".to_vec()), Value::Data(b"banana".to_vec())
    ];

    #[derive(Debug, Deserialize, PartialEq)]
    struct Simple {
        a: String,
        b: String,
    }

    let de = Deserializer::new(Value::Bulk(v));
    let actual: Simple = Deserialize::deserialize(de).unwrap();

    let expected = Simple {
        a: "apple".to_owned(),
        b: "banana".to_owned(),
    };

    assert_eq!(expected, actual);
}

#[test]
fn deserialize_hash_map_strings() {
    let v = vec![
        Value::Data(b"a".to_vec()), Value::Data(b"apple".to_vec()),
        Value::Data(b"b".to_vec()), Value::Data(b"banana".to_vec())
    ];

    let mut expected = HashMap::new();
    expected.insert("a".to_string(), "apple".to_string());
    expected.insert("b".to_string(), "banana".to_string());

    let de = Deserializer::new(Value::Bulk(v));
    let actual: HashMap<String, String> = Deserialize::deserialize(de).unwrap();

    assert_eq!(expected, actual);
}

#[test]
fn deserialize_float() {
    let v = Value::Data(b"3.14159".to_vec());

    let expected = "3.14159".parse::<f32>().unwrap();

    let de = Deserializer::new(v);
    let actual: f32 = Deserialize::deserialize(de).unwrap();

    assert_eq!(actual, expected);
}

#[test]
fn deserialize_hash_map_string_u8() {
    let v = vec![
        Value::Data(b"a".to_vec()), Value::Data(b"1".to_vec()),
        Value::Data(b"b".to_vec()), Value::Data(b"2".to_vec())
    ];

    let mut expected = HashMap::new();
    expected.insert("a".to_string(), 1);
    expected.insert("b".to_string(), 2);

    let de = Deserializer::new(Value::Bulk(v));
    let actual: HashMap<String, u8> = Deserialize::deserialize(de).unwrap();

    assert_eq!(expected, actual);
}

#[test]
fn deserialize_struct_out_of_order() {
    let v = vec![
        Value::Data(b"b".to_vec()), Value::Data(b"banana".to_vec()),
        Value::Data(b"a".to_vec()), Value::Data(b"apple".to_vec()),
    ];

    #[derive(Debug, Deserialize, PartialEq)]
    struct Simple {
        a: String,
        b: String,
    }

    let de = Deserializer::new(Value::Bulk(v));
    let actual: Simple = Deserialize::deserialize(de).unwrap();

    let expected = Simple {
        a: "apple".to_owned(),
        b: "banana".to_owned(),

    };

    assert_eq!(expected, actual);
}

#[test]
fn deserialize_struct_extra_keys() {
    let v = vec![
        Value::Data(b"c".to_vec()), Value::Data(b"cranberry".to_vec()),
        Value::Data(b"b".to_vec()), Value::Data(b"banana".to_vec()),
        Value::Data(b"a".to_vec()), Value::Data(b"apple".to_vec()),
    ];

    #[derive(Debug, Deserialize, PartialEq)]
    struct Simple {
        a: String,
        b: String,
    }

    let de = Deserializer::new(Value::Bulk(v));
    let actual: Simple = Deserialize::deserialize(de).unwrap();

    let expected = Simple {
        a: "apple".to_owned(),
        b: "banana".to_owned(),
    };

    assert_eq!(expected, actual);
}

#[test]
fn deserialize_enum() {
    let v = Value::Data(b"Orange".to_vec());

    #[derive(Debug, Deserialize, PartialEq)]
    enum Fruit {
        Orange,
        Apple
    }

    let de = Deserializer::new(v);
    let actual: Fruit = Deserialize::deserialize(de).unwrap();

    assert_eq!(Fruit::Orange, actual);
}

#[test]
fn deserialize_option() {
    let de = Deserializer::new(Value::Nil);
    let actual: Option<u8> = Deserialize::deserialize(de).unwrap();

    assert_eq!(None, actual);
}

#[test]
fn deserialize_complex_struct() {
    let v = vec![
        Value::Data(b"num".to_vec()), Value::Data(b"10".to_vec()),
        Value::Data(b"opt".to_vec()), Value::Data(b"yes".to_vec()),
        Value::Data(b"s".to_vec()), Value::Data(b"yarn".to_vec()),
    ];

    #[derive(Debug, Deserialize, PartialEq)]
    struct Complex {
        num: usize,
        opt: Option<String>,
        not_present: Option<String>,
        s: String,
    }

    let expected = Complex {
        num: 10,
        opt: Some("yes".to_owned()),
        not_present: None,
        s: "yarn".to_owned()
    };

    let de = Deserializer::new(Value::Bulk(v));
    let actual: Complex = Deserialize::deserialize(de).unwrap();

    assert_eq!(expected, actual);
}

#[test]
fn deserialize_vec_of_strings() {
    let v = vec![
        Value::Data(b"first".to_vec()),
        Value::Data(b"second".to_vec()),
        Value::Data(b"third".to_vec()),
    ];

    let de = Deserializer::new(Value::Bulk(v));
    let actual: Vec<String> = Deserialize::deserialize(de).unwrap();

    let expected = vec!["first".to_string(), "second".to_string(), "third".to_string()];
    assert_eq!(expected, actual);
}

#[test]
fn deserialize_vec_of_newtype() {
    let v = vec![
        Value::Data(b"first".to_vec()),
        Value::Data(b"second".to_vec()),
        Value::Data(b"third".to_vec()),
    ];

    #[derive(Debug, PartialEq, Deserialize)]
    struct Rank(String);

    let de = Deserializer::new(Value::Bulk(v));
    let actual: Vec<Rank> = Deserialize::deserialize(de).unwrap();

    let expected = vec![
        Rank("first".into()),
        Rank("second".into()),
        Rank("third".into()),
    ];

    assert_eq!(expected, actual);
}

/// Test for deserializing pipelined structs
///
/// In pipeline mode, there is nested bulk items that are returned. The original implementation did
/// not handle this.
#[test]
fn deserialize_pipelined_hmap() {
    let values =
        Value::Bulk(vec![
            Value::Bulk(vec![
                Value::Data(b"a".to_vec()), Value::Data(b"apple".to_vec()),
                Value::Data(b"b".to_vec()), Value::Data(b"banana".to_vec())
            ]),
            Value::Bulk(vec![
                Value::Data(b"a".to_vec()), Value::Data(b"art".to_vec()),
                Value::Data(b"b".to_vec()), Value::Data(b"bold".to_vec())
            ])
        ]);

    #[derive(Debug, Deserialize, PartialEq)]
    struct Simple {
        a: String,
        b: String,
    }

    let de = Deserializer::new(values);
    let actual: Vec<Simple> = Deserialize::deserialize(de).unwrap();

    let expected = vec![Simple {
        a: "apple".to_owned(),
        b: "banana".to_owned(),
    }, Simple {
        a: "art".to_owned(),
        b: "bold".to_owned(),
    }];

    assert_eq!(expected, actual);
}

#[test]
fn deserialize_pipelined_single_hmap() {
    let values =
        Value::Bulk(vec![
            Value::Bulk(vec![
                Value::Data(b"a".to_vec()), Value::Data(b"apple".to_vec()),
                Value::Data(b"b".to_vec()), Value::Data(b"banana".to_vec())
            ]),
        ]);

    #[derive(Debug, Deserialize, PartialEq)]
    struct Simple {
        a: String,
        b: String,
    }

    let de = Deserializer::new(values);
    let actual: Vec<Simple> = Deserialize::deserialize(de).unwrap();

    let expected = vec![Simple {
        a: "apple".to_owned(),
        b: "banana".to_owned(),
    }];

    assert_eq!(expected, actual);
}

#[test]
fn deserialize_struct_with_newtype_field() {
    let v = vec![
        Value::Data(b"b".to_vec()), Value::Data(b"banana".to_vec()),
        Value::Data(b"a".to_vec()), Value::Data(b"apple".to_vec()),
    ];

    #[derive(Debug, Deserialize, PartialEq)]
    struct Fruit(String);

    #[derive(Debug, Deserialize, PartialEq)]
    struct Simple {
        a: Fruit,
        b: Fruit,
    }

    let de = Deserializer::new(Value::Bulk(v));
    let actual: Simple = Deserialize::deserialize(de).unwrap();

    let expected = Simple {
        a: Fruit(String::from("apple")),
        b: Fruit(String::from("banana")),
    };

    assert_eq!(expected, actual);
}

#[test]
fn deserialize_pipelined_single_hmap_newtype_fields() {

    #[derive(Debug, Deserialize, PartialEq)]
    struct Fruit(String);

    let values =
        Value::Bulk(vec![
            Value::Bulk(vec![
                Value::Data(b"a".to_vec()), Value::Data(b"apple".to_vec()),
                Value::Data(b"b".to_vec()), Value::Data(b"banana".to_vec())
            ]),
        ]);

    #[derive(Debug, Deserialize, PartialEq)]
    struct Simple {
        a: Fruit,
        b: Fruit,
    }

    let de = Deserializer::new(values);
    let actual: Vec<Simple> = Deserialize::deserialize(de).unwrap();

    let expected = vec![Simple {
        a: Fruit(String::from("apple")),
        b: Fruit(String::from("banana")),
    }];

    assert_eq!(expected, actual);
}

#[derive(Debug, Deserialize, Serialize)]
pub struct Details {
    pub time: i64,
    pub count: u32,
    pub ids: Vec<String>,
}

type MapMapList = ::std::collections::HashMap<String, Details>;

#[test]
fn deserialize_nested_map_map_list() {
    let value = Value::Bulk(vec![
        Value::Data(b"key".to_vec()), Value::Bulk(vec![
            Value::Data(b"count".to_vec()), Value::Data(b"4".to_vec()),
            Value::Data(b"time".to_vec()), Value::Data(b"1473359995".to_vec()),
            Value::Data(b"ids".to_vec()), Value::Bulk(vec![
                Value::Data(b"00000000-0000-0000-0000-000000000000".to_vec()),
                Value::Data(b"00000000-0000-0000-0000-000000000001".to_vec()),
                Value::Data(b"00000000-0000-0000-0000-000000000002".to_vec()),
            ])
        ])
    ]);

    let de = Deserializer::new(value);
    let map: MapMapList = Deserialize::deserialize(de).unwrap();

    let nest = map.get("key").unwrap();
    assert_eq!(nest.count, 4);
    assert_eq!(nest.time, 1473359995);
    assert_eq!(&nest.ids[..], &[String::from("00000000-0000-0000-0000-000000000000"),
                                String::from("00000000-0000-0000-0000-000000000001"),
                                String::from("00000000-0000-0000-0000-000000000002")]);
}

#[test]
#[should_panic]
fn deserialize_nested_item() {
    let value = Value::Bulk(vec![Value::Bulk(vec![Value::Data(b"hi".to_vec())])]);

    let de = Deserializer::new(value);
    let _hellos: Vec<String> = Deserialize::deserialize(de).unwrap();
}
<commit_msg>Remove extra allocation in bool test<commit_after>#![feature(proc_macro)]

#[macro_use]
extern crate serde_derive;

extern crate redis;

extern crate serde;
extern crate serde_redis;

use std::collections::HashMap;

use serde::Deserialize;
use serde_redis::Deserializer;

use redis::Value;

#[test]
fn deserialize_unit_struct_string() {
    let v = Value::Data(b"hello".to_vec());

    #[derive(Deserialize, Debug, PartialEq)]
    struct Unit(String);

    let de = Deserializer::new(v);
    let actual: Unit = Deserialize::deserialize(de).unwrap();

    let expected = Unit("hello".to_owned());
    assert_eq!(expected, actual);
}

#[test]
fn deserialize_unit_struct_u8_redis_int() {
    let num = 5u8;
    let v = Value::Int(num as i64);

    #[derive(Deserialize, Debug, PartialEq)]
    struct IntUnit(u8);

    let de = Deserializer::new(v);
    let actual: IntUnit = Deserialize::deserialize(de).unwrap();

    let expected = IntUnit(num);
    assert_eq!(expected, actual);
}

#[test]
fn deserialize_bool() {
    let v = vec![
        Value::Data(b"0".to_vec()), Value::Data(b"false".to_vec()), Value::Data(b"False".to_vec()),
        Value::Data(b"1".to_vec()), Value::Data(b"true".to_vec()), Value::Data(b"True".to_vec())
    ];

    let de = Deserializer::new(Value::Bulk(v));
    let actual: Vec<bool> = Deserialize::deserialize(de).unwrap();

    let expected = [false, false, false, true, true, true];
    assert_eq!(&expected, &actual[..]);
}

#[test]
fn deserialize_tuple() {
    let v = vec![Value::Int(5), Value::Data(b"hello".to_vec())];

    let de = Deserializer::new(Value::Bulk(v));
    let actual: (u8, String) = Deserialize::deserialize(de).unwrap();

    let expected = (5, "hello".to_owned());
    assert_eq!(expected, actual);
}

#[test]
fn deserialize_struct() {
    let v = vec![
        Value::Data(b"a".to_vec()), Value::Data(b"apple".to_vec()),
        Value::Data(b"b".to_vec()), Value::Data(b"banana".to_vec())
    ];

    #[derive(Debug, Deserialize, PartialEq)]
    struct Simple {
        a: String,
        b: String,
    }

    let de = Deserializer::new(Value::Bulk(v));
    let actual: Simple = Deserialize::deserialize(de).unwrap();

    let expected = Simple {
        a: "apple".to_owned(),
        b: "banana".to_owned(),
    };

    assert_eq!(expected, actual);
}

#[test]
fn deserialize_hash_map_strings() {
    let v = vec![
        Value::Data(b"a".to_vec()), Value::Data(b"apple".to_vec()),
        Value::Data(b"b".to_vec()), Value::Data(b"banana".to_vec())
    ];

    let mut expected = HashMap::new();
    expected.insert("a".to_string(), "apple".to_string());
    expected.insert("b".to_string(), "banana".to_string());

    let de = Deserializer::new(Value::Bulk(v));
    let actual: HashMap<String, String> = Deserialize::deserialize(de).unwrap();

    assert_eq!(expected, actual);
}

#[test]
fn deserialize_float() {
    let v = Value::Data(b"3.14159".to_vec());

    let expected = "3.14159".parse::<f32>().unwrap();

    let de = Deserializer::new(v);
    let actual: f32 = Deserialize::deserialize(de).unwrap();

    assert_eq!(actual, expected);
}

#[test]
fn deserialize_hash_map_string_u8() {
    let v = vec![
        Value::Data(b"a".to_vec()), Value::Data(b"1".to_vec()),
        Value::Data(b"b".to_vec()), Value::Data(b"2".to_vec())
    ];

    let mut expected = HashMap::new();
    expected.insert("a".to_string(), 1);
    expected.insert("b".to_string(), 2);

    let de = Deserializer::new(Value::Bulk(v));
    let actual: HashMap<String, u8> = Deserialize::deserialize(de).unwrap();

    assert_eq!(expected, actual);
}

#[test]
fn deserialize_struct_out_of_order() {
    let v = vec![
        Value::Data(b"b".to_vec()), Value::Data(b"banana".to_vec()),
        Value::Data(b"a".to_vec()), Value::Data(b"apple".to_vec()),
    ];

    #[derive(Debug, Deserialize, PartialEq)]
    struct Simple {
        a: String,
        b: String,
    }

    let de = Deserializer::new(Value::Bulk(v));
    let actual: Simple = Deserialize::deserialize(de).unwrap();

    let expected = Simple {
        a: "apple".to_owned(),
        b: "banana".to_owned(),

    };

    assert_eq!(expected, actual);
}

#[test]
fn deserialize_struct_extra_keys() {
    let v = vec![
        Value::Data(b"c".to_vec()), Value::Data(b"cranberry".to_vec()),
        Value::Data(b"b".to_vec()), Value::Data(b"banana".to_vec()),
        Value::Data(b"a".to_vec()), Value::Data(b"apple".to_vec()),
    ];

    #[derive(Debug, Deserialize, PartialEq)]
    struct Simple {
        a: String,
        b: String,
    }

    let de = Deserializer::new(Value::Bulk(v));
    let actual: Simple = Deserialize::deserialize(de).unwrap();

    let expected = Simple {
        a: "apple".to_owned(),
        b: "banana".to_owned(),
    };

    assert_eq!(expected, actual);
}

#[test]
fn deserialize_enum() {
    let v = Value::Data(b"Orange".to_vec());

    #[derive(Debug, Deserialize, PartialEq)]
    enum Fruit {
        Orange,
        Apple
    }

    let de = Deserializer::new(v);
    let actual: Fruit = Deserialize::deserialize(de).unwrap();

    assert_eq!(Fruit::Orange, actual);
}

#[test]
fn deserialize_option() {
    let de = Deserializer::new(Value::Nil);
    let actual: Option<u8> = Deserialize::deserialize(de).unwrap();

    assert_eq!(None, actual);
}

#[test]
fn deserialize_complex_struct() {
    let v = vec![
        Value::Data(b"num".to_vec()), Value::Data(b"10".to_vec()),
        Value::Data(b"opt".to_vec()), Value::Data(b"yes".to_vec()),
        Value::Data(b"s".to_vec()), Value::Data(b"yarn".to_vec()),
    ];

    #[derive(Debug, Deserialize, PartialEq)]
    struct Complex {
        num: usize,
        opt: Option<String>,
        not_present: Option<String>,
        s: String,
    }

    let expected = Complex {
        num: 10,
        opt: Some("yes".to_owned()),
        not_present: None,
        s: "yarn".to_owned()
    };

    let de = Deserializer::new(Value::Bulk(v));
    let actual: Complex = Deserialize::deserialize(de).unwrap();

    assert_eq!(expected, actual);
}

#[test]
fn deserialize_vec_of_strings() {
    let v = vec![
        Value::Data(b"first".to_vec()),
        Value::Data(b"second".to_vec()),
        Value::Data(b"third".to_vec()),
    ];

    let de = Deserializer::new(Value::Bulk(v));
    let actual: Vec<String> = Deserialize::deserialize(de).unwrap();

    let expected = vec!["first".to_string(), "second".to_string(), "third".to_string()];
    assert_eq!(expected, actual);
}

#[test]
fn deserialize_vec_of_newtype() {
    let v = vec![
        Value::Data(b"first".to_vec()),
        Value::Data(b"second".to_vec()),
        Value::Data(b"third".to_vec()),
    ];

    #[derive(Debug, PartialEq, Deserialize)]
    struct Rank(String);

    let de = Deserializer::new(Value::Bulk(v));
    let actual: Vec<Rank> = Deserialize::deserialize(de).unwrap();

    let expected = vec![
        Rank("first".into()),
        Rank("second".into()),
        Rank("third".into()),
    ];

    assert_eq!(expected, actual);
}

/// Test for deserializing pipelined structs
///
/// In pipeline mode, there is nested bulk items that are returned. The original implementation did
/// not handle this.
#[test]
fn deserialize_pipelined_hmap() {
    let values =
        Value::Bulk(vec![
            Value::Bulk(vec![
                Value::Data(b"a".to_vec()), Value::Data(b"apple".to_vec()),
                Value::Data(b"b".to_vec()), Value::Data(b"banana".to_vec())
            ]),
            Value::Bulk(vec![
                Value::Data(b"a".to_vec()), Value::Data(b"art".to_vec()),
                Value::Data(b"b".to_vec()), Value::Data(b"bold".to_vec())
            ])
        ]);

    #[derive(Debug, Deserialize, PartialEq)]
    struct Simple {
        a: String,
        b: String,
    }

    let de = Deserializer::new(values);
    let actual: Vec<Simple> = Deserialize::deserialize(de).unwrap();

    let expected = vec![Simple {
        a: "apple".to_owned(),
        b: "banana".to_owned(),
    }, Simple {
        a: "art".to_owned(),
        b: "bold".to_owned(),
    }];

    assert_eq!(expected, actual);
}

#[test]
fn deserialize_pipelined_single_hmap() {
    let values =
        Value::Bulk(vec![
            Value::Bulk(vec![
                Value::Data(b"a".to_vec()), Value::Data(b"apple".to_vec()),
                Value::Data(b"b".to_vec()), Value::Data(b"banana".to_vec())
            ]),
        ]);

    #[derive(Debug, Deserialize, PartialEq)]
    struct Simple {
        a: String,
        b: String,
    }

    let de = Deserializer::new(values);
    let actual: Vec<Simple> = Deserialize::deserialize(de).unwrap();

    let expected = vec![Simple {
        a: "apple".to_owned(),
        b: "banana".to_owned(),
    }];

    assert_eq!(expected, actual);
}

#[test]
fn deserialize_struct_with_newtype_field() {
    let v = vec![
        Value::Data(b"b".to_vec()), Value::Data(b"banana".to_vec()),
        Value::Data(b"a".to_vec()), Value::Data(b"apple".to_vec()),
    ];

    #[derive(Debug, Deserialize, PartialEq)]
    struct Fruit(String);

    #[derive(Debug, Deserialize, PartialEq)]
    struct Simple {
        a: Fruit,
        b: Fruit,
    }

    let de = Deserializer::new(Value::Bulk(v));
    let actual: Simple = Deserialize::deserialize(de).unwrap();

    let expected = Simple {
        a: Fruit(String::from("apple")),
        b: Fruit(String::from("banana")),
    };

    assert_eq!(expected, actual);
}

#[test]
fn deserialize_pipelined_single_hmap_newtype_fields() {

    #[derive(Debug, Deserialize, PartialEq)]
    struct Fruit(String);

    let values =
        Value::Bulk(vec![
            Value::Bulk(vec![
                Value::Data(b"a".to_vec()), Value::Data(b"apple".to_vec()),
                Value::Data(b"b".to_vec()), Value::Data(b"banana".to_vec())
            ]),
        ]);

    #[derive(Debug, Deserialize, PartialEq)]
    struct Simple {
        a: Fruit,
        b: Fruit,
    }

    let de = Deserializer::new(values);
    let actual: Vec<Simple> = Deserialize::deserialize(de).unwrap();

    let expected = vec![Simple {
        a: Fruit(String::from("apple")),
        b: Fruit(String::from("banana")),
    }];

    assert_eq!(expected, actual);
}

#[derive(Debug, Deserialize, Serialize)]
pub struct Details {
    pub time: i64,
    pub count: u32,
    pub ids: Vec<String>,
}

type MapMapList = ::std::collections::HashMap<String, Details>;

#[test]
fn deserialize_nested_map_map_list() {
    let value = Value::Bulk(vec![
        Value::Data(b"key".to_vec()), Value::Bulk(vec![
            Value::Data(b"count".to_vec()), Value::Data(b"4".to_vec()),
            Value::Data(b"time".to_vec()), Value::Data(b"1473359995".to_vec()),
            Value::Data(b"ids".to_vec()), Value::Bulk(vec![
                Value::Data(b"00000000-0000-0000-0000-000000000000".to_vec()),
                Value::Data(b"00000000-0000-0000-0000-000000000001".to_vec()),
                Value::Data(b"00000000-0000-0000-0000-000000000002".to_vec()),
            ])
        ])
    ]);

    let de = Deserializer::new(value);
    let map: MapMapList = Deserialize::deserialize(de).unwrap();

    let nest = map.get("key").unwrap();
    assert_eq!(nest.count, 4);
    assert_eq!(nest.time, 1473359995);
    assert_eq!(&nest.ids[..], &[String::from("00000000-0000-0000-0000-000000000000"),
                                String::from("00000000-0000-0000-0000-000000000001"),
                                String::from("00000000-0000-0000-0000-000000000002")]);
}

#[test]
#[should_panic]
fn deserialize_nested_item() {
    let value = Value::Bulk(vec![Value::Bulk(vec![Value::Data(b"hi".to_vec())])]);

    let de = Deserializer::new(value);
    let _hellos: Vec<String> = Deserialize::deserialize(de).unwrap();
}
<|endoftext|>


<commit_before>use std::net::TcpStream;
use std::io::stdout;
use std::io::Read;
use std::io::Write;
use std::env;
use std::str;
use std::option::Option;
use std::process::Command;
use std::process::Child;
use std::path::PathBuf;
use std::thread::sleep;
use std::time::Duration;
use wait_timeout::ChildExt;
use std::io::Error;

extern crate wait_timeout;

const MAX_RETRIES: usize = 5;

fn main() {
    let args: Vec<String> = env::args().collect();
    let message = create_message(&args);

    send_message_retrying(message.as_bytes());
}

fn create_message(args: &Vec<String>) -> String {
    let args_str = args[1..].join(" ");
    let curr_dir = env::current_dir().unwrap().into_os_string().into_string().unwrap();

    let mut message: String = String::with_capacity(args_str.len() + curr_dir.len() + 12);

    message.push_str(&curr_dir);
    message.push('\n');
    message.push_str(&args_str);
    message.push_str("\nJGRAB_END\n");

    message
}

fn send_message_retrying(message: &[u8]) {
    if let Some(_) = send_message(message, false) {
        // failed to connect, try to start the daemon, then retry
        let mut retries = MAX_RETRIES;

        let mut child = start_daemon();
        check_status(&mut child);

        while retries > 0 {
            if let Some(err) = send_message(message, true) {
                check_status(&mut child);

                log(&format!("unable to connect to JGrab daemon: {}", err));
                log(&format!("will re-try {} more times", &mut retries));
                retries -= 1;
            } else {
                break // success
            }
        }

        if retries == 0 {
            error("unable to start JGrab daemon. \
                   Make sure JGrab's port [5002] is not already bound");
        }
    }
}

fn send_message(socket_message: &[u8],
                is_retry: bool) -> Option<Error> {
    match TcpStream::connect("127.0.0.1:5002") {
        Ok(mut stream) => {
            if is_retry {
                log("Connected!");
            }

            stream.write(socket_message).unwrap();

            let mut client_buffer = [0u8; 1024];

            loop {
                match stream.read(&mut client_buffer) {
                    Ok(n) => {
                        if n == 0 {
                            break;
                        } else {
                            stdout().write(&client_buffer[0..n]).unwrap();
                        }
                    }
                    Err(err) => error(&err.to_string())
                }
            }

            Option::None
        }
        Err(err) => Option::Some(err)
    }
}

fn start_daemon() -> Child {
    log("Starting daemon");

    if let Some(user_home) = env::home_dir() {
        let mut jgrab_jar: PathBuf = user_home;
        jgrab_jar.push(".jgrab");
        jgrab_jar.push("jgrab.jar");

        if jgrab_jar.as_path().is_file() {
            let cmd = Command::new("java")
                .arg("-jar")
                .arg(jgrab_jar.into_os_string().into_string().unwrap())
                .arg("--daemon")
                .spawn();

            match cmd {
                Ok(child) => {
                    log(&format!("Daemon started, pid={}", child.id()));
                    child
                }
                Err(err) => error(&err.to_string())
            }
        } else {
            error("The JGrab jar is not installed! Please install it as explained \
                   in https://github.com/renatoathaydes/jgrab");
        }
    } else {
        error("user.home could not be found, making it impossible to start the JGrab Daemon");
    }
}

fn check_status(child: &mut Child) {
    let timeout = Duration::from_secs(1);

    match child.wait_timeout(timeout) {
        Ok(Some(status)) => error(&format!(
            "The JGrab daemon has died prematurely, exit code was {}", status)),
        Ok(None) => {
            // give time for the socket server to become active
            sleep(Duration::from_secs(1));
        }
        Err(e) => error(&format!(
            "Could not wait for JGrab daemon process status: {}", e)),
    }
}

fn log(message: &str) {
    println!("==== JGrab Client ==== {}", message)
}

fn error(message: &str) -> ! {
    panic!("JGrab Client Error - {}", message)
}
<commit_msg>Reformulated socket communication in jgrab-client.<commit_after>use std::net::{TcpStream, Shutdown};
use std::io::{Stdin, stdin, stdout, Read, Write, Error, Result, Cursor};
use std::fs::File;
use std::env;
use std::str;
use std::option::Option;
use std::process::Command;
use std::process::Child;
use std::path::PathBuf;
use std::thread::sleep;
use std::time::Duration;
use wait_timeout::ChildExt;
use Input::*;

extern crate wait_timeout;

const MAX_RETRIES: usize = 5;

/// All possible sources of input for the JGrab Client
enum Input {
    FileInput(File),
    StdinInput(Stdin),
    TextInput(Cursor<String>)
}

impl Read for Input {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        match *self {
            FileInput(ref mut r) => r.read(buf),
            StdinInput(ref mut r) => r.read(buf),
            TextInput(ref mut r) => r.read(buf),
        }
    }
}

fn main() {
    let args: Vec<String> = env::args().collect();

    let input: Input;

    if args.len() == 1 {
        // no args, pipe stdin
        input = StdinInput(stdin());
    } else if args.len() == 2 && !args[1].starts_with('-') {
        // there's one argument and it is not an option, so it must be a file

        match File::open(&args[1]) {
            Ok(file) => input = FileInput(file),
            Err(err) => error(&format!("unable to read file: {}", err))
        }
    } else if args.len() == 2 && args[1].trim() == "--help" {
        // TODO
        println!("Help");
        return;
    } else {
        // just pass on the arguments to JGrab
        input = TextInput(Cursor::new(create_message(&args)))
    }

    send_message_retrying(input);
}

fn create_message(args: &Vec<String>) -> String {
    args[1..].join(" ")
}

fn send_message_retrying<R: Read>(mut reader: R) {
    if let Some(_) = send_message(&mut reader, false) {
        // failed to connect, try to start the daemon, then retry
        let mut retries = MAX_RETRIES;

        let mut child = start_daemon();
        check_status(&mut child);

        while retries > 0 {
            if let Some(err) = send_message(&mut reader, true) {
                check_status(&mut child);

                log(&format!("unable to connect to JGrab daemon: {}", err));
                log(&format!("will re-try {} more times", &mut retries));
                retries -= 1;
            } else {
                break // success
            }
        }

        if retries == 0 {
            error("unable to start JGrab daemon. \
                   Make sure JGrab's port [5002] is not already bound");
        }
    }
}

fn send_message<R: Read>(reader: &mut R,
                         is_retry: bool) -> Option<Error> {
    match TcpStream::connect("127.0.0.1:5002") {
        Ok(mut stream) => {
            if is_retry {
                log("Connected!");
            }

            let mut socket_message = [0u8; 1024];

            loop {
                match reader.read(&mut socket_message) {
                    Ok(n) => {
                        if n == 0 {
                            break;
                        } else {
                            stream.write(&socket_message[0..n]).unwrap();
                        }
                    }
                    Err(err) => error(&err.to_string())
                }
            }

            stream.shutdown(Shutdown::Write).unwrap();

            let mut client_buffer = socket_message;

            loop {
                match stream.read(&mut client_buffer) {
                    Ok(n) => {
                        if n == 0 {
                            break;
                        } else {
                            stdout().write(&client_buffer[0..n]).unwrap();
                        }
                    }
                    Err(err) => error(&err.to_string())
                }
            }

            Option::None
        }
        Err(err) => Option::Some(err)
    }
}

fn start_daemon() -> Child {
    log("Starting daemon");

    if let Some(user_home) = env::home_dir() {
        let mut jgrab_jar: PathBuf = user_home;
        jgrab_jar.push(".jgrab");
        jgrab_jar.push("jgrab.jar");

        if jgrab_jar.as_path().is_file() {
            let cmd = Command::new("java")
                .arg("-jar")
                .arg(jgrab_jar.into_os_string().into_string().unwrap())
                .arg("--daemon")
                .spawn();

            match cmd {
                Ok(child) => {
                    log(&format!("Daemon started, pid={}", child.id()));
                    child
                }
                Err(err) => error(&err.to_string())
            }
        } else {
            error("The JGrab jar is not installed! Please install it as explained \
                   in https://github.com/renatoathaydes/jgrab");
        }
    } else {
        error("user.home could not be found, making it impossible to start the JGrab Daemon");
    }
}

fn check_status(child: &mut Child) {
    let timeout = Duration::from_secs(1);

    match child.wait_timeout(timeout) {
        Ok(Some(status)) => error(&format!(
            "The JGrab daemon has died prematurely, exit code was {}", status)),
        Ok(None) => {
            // give time for the socket server to become active
            sleep(Duration::from_secs(1));
        }
        Err(e) => error(&format!(
            "Could not wait for JGrab daemon process status: {}", e)),
    }
}

fn log(message: &str) {
    println!("==== JGrab Client ==== {}", message)
}

fn error(message: &str) -> ! {
    panic!("JGrab Client Error - {}", message)
}
<|endoftext|>


<commit_before>//! Task execution related traits and utilities.
//!
//! In the Tokio execution model, futures are lazy. When a future is created, no
//! work is performed. In order for the work defined by the future to happen,
//! the future must be submitted to an executor. A future that is submitted to
//! an executor is called a "task".
//!
//! The executor is responsible for ensuring that [`Future::poll`] is called
//! whenever the task is [notified]. Notification happens when the internal
//! state of a task transitions from "not ready" to ready. For example, a socket
//! might have received data and a call to `read` will now be able to succeed.
//!
//! This crate provides traits and utilities that are necessary for building an
//! executor, including:
//!
//! * The [`Executor`] trait describes the API for spawning a future onto an
//!   executor.
//!
//! * [`enter`] marks that the the current thread is entering an execution
//!   context. This prevents a second executor from accidentally starting from
//!   within the context of one that is already running.
//!
//! * [`DefaultExecutor`] spawns tasks onto the default executor for the current
//!   context.
//!
//! * [`Park`] abstracts over blocking and unblocking the current thread.
//!
//! [`Executor`]: trait.Executor.html
//! [`enter`]: fn.enter.html
//! [`DefaultExecutor`]: struct.DefaultExecutor.html
//! [`Park`]: park/index.html

#![deny(missing_docs, missing_debug_implementations, warnings)]
#![doc(html_root_url = "https://docs.rs/tokio-executor/0.1.2")]

extern crate futures;

#[cfg(feature = "unstable-futures")]
extern crate futures2;

mod enter;
mod global;
pub mod park;

pub use enter::{enter, Enter, EnterError};
pub use global::{spawn, with_default, DefaultExecutor};

#[cfg(feature = "unstable-futures")]
pub use global::spawn2;

use futures::Future;

/// A value that executes futures.
///
/// The [`spawn`] function is used to submit a future to an executor. Once
/// submitted, the executor takes ownership of the future and becomes
/// responsible for driving the future to completion.
///
/// The strategy employed by the executor to handle the future is less defined
/// and is left up to the `Executor` implementation. The `Executor` instance is
/// expected to call [`poll`] on the future once it has been notified, however
/// the "when" and "how" can vary greatly.
///
/// For example, the executor might be a thread pool, in which case a set of
/// threads have already been spawned up and the future is inserted into a
/// queue. A thread will acquire the future and poll it.
///
/// The `Executor` trait is only for futures that **are** `Send`. These are most
/// common. There currently is no trait that describes executors that operate
/// entirely on the current thread (i.e., are able to spawn futures that are not
/// `Send`). Note that single threaded executors can still implement `Executor`,
/// but only futures that are `Send` can be spawned via the trait.
///
/// # Errors
///
/// The [`spawn`] function returns `Result` with an error type of `SpawnError`.
/// This error type represents the reason that the executor was unable to spawn
/// the future. The two current represented scenarios are:
///
/// * An executor being at capacity or full. As such, the executor is not able
///   to accept a new future. This error state is expected to be transient.
/// * An executor has been shutdown and can no longer accept new futures. This
///   error state is expected to be permanent.
///
/// If a caller encounters an at capacity error, the caller should try to shed
/// load. This can be as simple as dropping the future that was spawned.
///
/// If the caller encounters a shutdown error, the caller should attempt to
/// gracefully shutdown.
///
/// # Examples
///
/// ```rust
/// # extern crate futures;
/// # extern crate tokio_executor;
/// # use tokio_executor::Executor;
/// # fn docs(my_executor: &mut Executor) {
/// use futures::future::lazy;
/// my_executor.spawn(Box::new(lazy(|| {
///     println!("running on the executor");
///     Ok(())
/// }))).unwrap();
/// # }
/// # fn main() {}
/// ```
///
/// [`spawn`]: #tymethod.spawn
/// [`poll`]: https://docs.rs/futures/0.1/futures/future/trait.Future.html#tymethod.poll
pub trait Executor {
    /// Spawns a future object to run on this executor.
    ///
    /// `future` is passed to the executor, which will begin running it. The
    /// future may run on the current thread or another thread at the discretion
    /// of the `Executor` implementation.
    ///
    /// # Panics
    ///
    /// Implementors are encouraged to avoid panics. However, a panic is
    /// permitted and the caller should check the implementation specific
    /// documentation for more details on possible panics.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate futures;
    /// # extern crate tokio_executor;
    /// # use tokio_executor::Executor;
    /// # fn docs(my_executor: &mut Executor) {
    /// use futures::future::lazy;
    /// my_executor.spawn(Box::new(lazy(|| {
    ///     println!("running on the executor");
    ///     Ok(())
    /// }))).unwrap();
    /// # }
    /// # fn main() {}
    /// ```
    fn spawn(&mut self, future: Box<Future<Item = (), Error = ()> + Send>)
             -> Result<(), SpawnError>;

    /// Like `spawn`, but compatible with futures 0.2
    #[cfg(feature = "unstable-futures")]
    fn spawn2(&mut self, future: Box<futures2::Future<Item = (), Error = futures2::Never> + Send>)
             -> Result<(), futures2::executor::SpawnError>;

    /// Provides a best effort **hint** to whether or not `spawn` will succeed.
    ///
    /// This function may return both false positives **and** false negatives.
    /// If `status` returns `Ok`, then a call to `spawn` will *probably*
    /// succeed, but may fail. If `status` returns `Err`, a call to `spawn` will
    /// *probably* fail, but may succeed.
    ///
    /// This allows a caller to avoid creating the task if the call to `spawn`
    /// has a high likelihood of failing.
    ///
    /// # Panics
    ///
    /// This function must not panic. Implementors must ensure that panics do
    /// not happen.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate futures;
    /// # extern crate tokio_executor;
    /// # use tokio_executor::Executor;
    /// # fn docs(my_executor: &mut Executor) {
    /// use futures::future::lazy;
    ///
    /// if my_executor.status().is_ok() {
    ///     my_executor.spawn(Box::new(lazy(|| {
    ///         println!("running on the executor");
    ///         Ok(())
    ///     }))).unwrap();
    /// } else {
    ///     println!("the executor is not in a good state");
    /// }
    /// # }
    /// # fn main() {}
    /// ```
    fn status(&self) -> Result<(), SpawnError> {
        Ok(())
    }
}

impl<E: Executor + ?Sized> Executor for Box<E> {
    fn spawn(&mut self, future: Box<Future<Item = (), Error = ()> + Send>)
        -> Result<(), SpawnError>
    {
        (**self).spawn(future)
    }

    #[cfg(feature = "unstable-futures")]
    fn spawn2(&mut self, future: Box<futures2::Future<Item = (), Error = futures2::Never> + Send>)
        -> Result<(), futures2::executor::SpawnError>
    {
        (**self).spawn2(future)
    }

    fn status(&self) -> Result<(), SpawnError> {
        (**self).status()
    }
}

/// Errors returned by `Executor::spawn`.
///
/// Spawn errors should represent relatively rare scenarios. Currently, the two
/// scenarios represented by `SpawnError` are:
///
/// * An executor being at capacity or full. As such, the executor is not able
///   to accept a new future. This error state is expected to be transient.
/// * An executor has been shutdown and can no longer accept new futures. This
///   error state is expected to be permanent.
#[derive(Debug)]
pub struct SpawnError {
    is_shutdown: bool,
}

impl SpawnError {
    /// Return a new `SpawnError` reflecting a shutdown executor failure.
    pub fn shutdown() -> Self {
        SpawnError { is_shutdown: true }
    }

    /// Return a new `SpawnError` reflecting an executor at capacity failure.
    pub fn at_capacity() -> Self {
        SpawnError { is_shutdown: false }
    }

    /// Returns `true` if the error reflects a shutdown executor failure.
    pub fn is_shutdown(&self) -> bool {
        self.is_shutdown
    }

    /// Returns `true` if the error reflects an executor at capacity failure.
    pub fn is_at_capacity(&self) -> bool {
        !self.is_shutdown
    }
}
<commit_msg>Update lib.rs (#471)<commit_after>//! Task execution related traits and utilities.
//!
//! In the Tokio execution model, futures are lazy. When a future is created, no
//! work is performed. In order for the work defined by the future to happen,
//! the future must be submitted to an executor. A future that is submitted to
//! an executor is called a "task".
//!
//! The executor is responsible for ensuring that [`Future::poll`] is called
//! whenever the task is notified. Notification happens when the internal
//! state of a task transitions from "not ready" to ready. For example, a socket
//! might have received data and a call to `read` will now be able to succeed.
//!
//! This crate provides traits and utilities that are necessary for building an
//! executor, including:
//!
//! * The [`Executor`] trait describes the API for spawning a future onto an
//!   executor.
//!
//! * [`enter`] marks that the the current thread is entering an execution
//!   context. This prevents a second executor from accidentally starting from
//!   within the context of one that is already running.
//!
//! * [`DefaultExecutor`] spawns tasks onto the default executor for the current
//!   context.
//!
//! * [`Park`] abstracts over blocking and unblocking the current thread.
//!
//! [`Executor`]: trait.Executor.html
//! [`enter`]: fn.enter.html
//! [`DefaultExecutor`]: struct.DefaultExecutor.html
//! [`Park`]: park/index.html

#![deny(missing_docs, missing_debug_implementations, warnings)]
#![doc(html_root_url = "https://docs.rs/tokio-executor/0.1.2")]

extern crate futures;

#[cfg(feature = "unstable-futures")]
extern crate futures2;

mod enter;
mod global;
pub mod park;

pub use enter::{enter, Enter, EnterError};
pub use global::{spawn, with_default, DefaultExecutor};

#[cfg(feature = "unstable-futures")]
pub use global::spawn2;

use futures::Future;

/// A value that executes futures.
///
/// The [`spawn`] function is used to submit a future to an executor. Once
/// submitted, the executor takes ownership of the future and becomes
/// responsible for driving the future to completion.
///
/// The strategy employed by the executor to handle the future is less defined
/// and is left up to the `Executor` implementation. The `Executor` instance is
/// expected to call [`poll`] on the future once it has been notified, however
/// the "when" and "how" can vary greatly.
///
/// For example, the executor might be a thread pool, in which case a set of
/// threads have already been spawned up and the future is inserted into a
/// queue. A thread will acquire the future and poll it.
///
/// The `Executor` trait is only for futures that **are** `Send`. These are most
/// common. There currently is no trait that describes executors that operate
/// entirely on the current thread (i.e., are able to spawn futures that are not
/// `Send`). Note that single threaded executors can still implement `Executor`,
/// but only futures that are `Send` can be spawned via the trait.
///
/// # Errors
///
/// The [`spawn`] function returns `Result` with an error type of `SpawnError`.
/// This error type represents the reason that the executor was unable to spawn
/// the future. The two current represented scenarios are:
///
/// * An executor being at capacity or full. As such, the executor is not able
///   to accept a new future. This error state is expected to be transient.
/// * An executor has been shutdown and can no longer accept new futures. This
///   error state is expected to be permanent.
///
/// If a caller encounters an at capacity error, the caller should try to shed
/// load. This can be as simple as dropping the future that was spawned.
///
/// If the caller encounters a shutdown error, the caller should attempt to
/// gracefully shutdown.
///
/// # Examples
///
/// ```rust
/// # extern crate futures;
/// # extern crate tokio_executor;
/// # use tokio_executor::Executor;
/// # fn docs(my_executor: &mut Executor) {
/// use futures::future::lazy;
/// my_executor.spawn(Box::new(lazy(|| {
///     println!("running on the executor");
///     Ok(())
/// }))).unwrap();
/// # }
/// # fn main() {}
/// ```
///
/// [`spawn`]: #tymethod.spawn
/// [`poll`]: https://docs.rs/futures/0.1/futures/future/trait.Future.html#tymethod.poll
pub trait Executor {
    /// Spawns a future object to run on this executor.
    ///
    /// `future` is passed to the executor, which will begin running it. The
    /// future may run on the current thread or another thread at the discretion
    /// of the `Executor` implementation.
    ///
    /// # Panics
    ///
    /// Implementors are encouraged to avoid panics. However, a panic is
    /// permitted and the caller should check the implementation specific
    /// documentation for more details on possible panics.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate futures;
    /// # extern crate tokio_executor;
    /// # use tokio_executor::Executor;
    /// # fn docs(my_executor: &mut Executor) {
    /// use futures::future::lazy;
    /// my_executor.spawn(Box::new(lazy(|| {
    ///     println!("running on the executor");
    ///     Ok(())
    /// }))).unwrap();
    /// # }
    /// # fn main() {}
    /// ```
    fn spawn(&mut self, future: Box<Future<Item = (), Error = ()> + Send>)
             -> Result<(), SpawnError>;

    /// Like `spawn`, but compatible with futures 0.2
    #[cfg(feature = "unstable-futures")]
    fn spawn2(&mut self, future: Box<futures2::Future<Item = (), Error = futures2::Never> + Send>)
             -> Result<(), futures2::executor::SpawnError>;

    /// Provides a best effort **hint** to whether or not `spawn` will succeed.
    ///
    /// This function may return both false positives **and** false negatives.
    /// If `status` returns `Ok`, then a call to `spawn` will *probably*
    /// succeed, but may fail. If `status` returns `Err`, a call to `spawn` will
    /// *probably* fail, but may succeed.
    ///
    /// This allows a caller to avoid creating the task if the call to `spawn`
    /// has a high likelihood of failing.
    ///
    /// # Panics
    ///
    /// This function must not panic. Implementors must ensure that panics do
    /// not happen.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate futures;
    /// # extern crate tokio_executor;
    /// # use tokio_executor::Executor;
    /// # fn docs(my_executor: &mut Executor) {
    /// use futures::future::lazy;
    ///
    /// if my_executor.status().is_ok() {
    ///     my_executor.spawn(Box::new(lazy(|| {
    ///         println!("running on the executor");
    ///         Ok(())
    ///     }))).unwrap();
    /// } else {
    ///     println!("the executor is not in a good state");
    /// }
    /// # }
    /// # fn main() {}
    /// ```
    fn status(&self) -> Result<(), SpawnError> {
        Ok(())
    }
}

impl<E: Executor + ?Sized> Executor for Box<E> {
    fn spawn(&mut self, future: Box<Future<Item = (), Error = ()> + Send>)
        -> Result<(), SpawnError>
    {
        (**self).spawn(future)
    }

    #[cfg(feature = "unstable-futures")]
    fn spawn2(&mut self, future: Box<futures2::Future<Item = (), Error = futures2::Never> + Send>)
        -> Result<(), futures2::executor::SpawnError>
    {
        (**self).spawn2(future)
    }

    fn status(&self) -> Result<(), SpawnError> {
        (**self).status()
    }
}

/// Errors returned by `Executor::spawn`.
///
/// Spawn errors should represent relatively rare scenarios. Currently, the two
/// scenarios represented by `SpawnError` are:
///
/// * An executor being at capacity or full. As such, the executor is not able
///   to accept a new future. This error state is expected to be transient.
/// * An executor has been shutdown and can no longer accept new futures. This
///   error state is expected to be permanent.
#[derive(Debug)]
pub struct SpawnError {
    is_shutdown: bool,
}

impl SpawnError {
    /// Return a new `SpawnError` reflecting a shutdown executor failure.
    pub fn shutdown() -> Self {
        SpawnError { is_shutdown: true }
    }

    /// Return a new `SpawnError` reflecting an executor at capacity failure.
    pub fn at_capacity() -> Self {
        SpawnError { is_shutdown: false }
    }

    /// Returns `true` if the error reflects a shutdown executor failure.
    pub fn is_shutdown(&self) -> bool {
        self.is_shutdown
    }

    /// Returns `true` if the error reflects an executor at capacity failure.
    pub fn is_at_capacity(&self) -> bool {
        !self.is_shutdown
    }
}
<|endoftext|>


<commit_before>fn main() {

    // ------------------ print macros start ------------------
    // println -> prints statement to console in a new line
    println!("April has {} days.", 31);
    println!("{month} has {numberOfDays} days.",
        month = "January",
        numberOfDays = "31");
    // Special formating is used here
    // {:b} -> converts 2 to 10 (binary form)
    println!("{} of {:b} people know binary, the other half doesn't", 1, 2);
    let width = 6;
    println!("{number:>width$} {spaces} spaces and {number}", number = 1, width = width, spaces = width - 1);
    println!("{}", format!("{:05}", 12));
    // ------------------ print macros end ------------------

}<commit_msg>add macro definition and a round off example<commit_after>fn main() {

    // ------------------ print macros start ------------------
    // Macros: Macros look like functions, except that their name ends with a bang !,
    // but instead of generating a function call, macros are expanded into source code
    // that gets compiled with the rest of the program. eg. println!
    // println! -> prints statement to console in a new line

    println!("April has {} days.", 31);
    println!("{month} has {numberOfDays} days.",
        month = "January",
        numberOfDays = "31");
    // Special formating is used here
    // {:b} -> converts 2 to 10 (binary form)
    println!("{} of {:b} people know binary, the other half doesn't", 1, 2);
    let width = 6;
    println!("{number:>width$} {spaces} spaces and {number}", number = 1, width = width, spaces = width - 1);
    println!("{}", format!("{:05}", 12));

    // rounds off the number
    let pi = 3.141592;
    println!("Pi is roughly {:.3}", pi);
    // ------------------ print macros end ------------------

}<|endoftext|>


<commit_before>use std::borrow::Borrow;
use std::fmt::Arguments;
use std::io::Read;
use std::io::Write;
use std::io;
use std::net::TcpStream;
use std::os::unix::io::{AsRawFd, RawFd};
use std::str;
use std::time::Duration;

use msg::{Msg, Pfx, Command};
use utils::find_byte;

pub struct Comms {
    /// The TCP connection to the server.
    stream        : TcpStream,

    pub serv_name : String,
    serv_addr     : String,

    /// _Partial_ messages collected here until they make a complete message.
    msg_buf       : Vec<u8>,
}

#[derive(Debug)]
pub enum CommsRet<'a> {
    Disconnected {
        fd        : RawFd,
    },

    Err {
        serv_name : &'a str,
        err_msg   : String,
    },

    IncomingMsg {
        serv_name : &'a str,
        pfx       : Pfx,
        ty        : String,
        msg       : String,
    },

    /// A message without prefix. From RFC 2812:
    /// > If the prefix is missing from the message, it is assumed to have
    /// > originated from the connection from which it was received from.
    SentMsg {
        serv_name   : &'a str,
        ty          : String,
        msg         : String,
    }
}

impl Comms {
    pub fn try_connect(serv_addr : &str, serv_name : &str,
                       nick : &str, hostname : &str, realname : &str)
                       -> io::Result<Comms> {
        let stream = try!(TcpStream::connect(serv_addr));
        try!(stream.set_read_timeout(Some(Duration::from_millis(10))));
        try!(stream.set_write_timeout(None));
        try!(stream.set_nonblocking(true));

        let mut comms = Comms {
            stream:     stream,
            serv_name:  serv_name.to_owned(),
            serv_addr:  serv_addr.to_owned(),
            msg_buf:    Vec::new(),
        };
        try!(comms.introduce(nick, hostname, realname));
        Ok(comms)
    }

    /// Get the RawFd, to be used with select() or other I/O multiplexer.
    pub fn get_raw_fd(&self) -> RawFd {
        self.stream.as_raw_fd()
    }

    ////////////////////////////////////////////////////////////////////////////
    // Sending messages

    fn introduce(&mut self, nick : &str, hostname : &str, realname : &str) -> io::Result<()> {
        try!(Msg::user(hostname, realname, &mut self.stream));
        Msg::nick(nick, &mut self.stream)
    }

    ////////////////////////////////////////////////////////////////////////////
    // Receiving messages

    pub fn read_incoming_msg<'a>(&'a mut self) -> Vec<CommsRet<'a>> {
        let mut read_buf : [u8; 512] = [0; 512];

        // Handle disconnects
        match self.stream.read(&mut read_buf) {
            Err(_) => {
                // TODO: I don't understand why this happens. I'm ``randomly''
                // getting "temporarily unavailable" errors.
                // return vec![CommsRet::ShowErr(format!("error in read(): {:?}", err))];
                return vec![];
            },
            Ok(bytes_read) => {
                if bytes_read == 0 {
                    return vec![CommsRet::Disconnected { fd: self.get_raw_fd() }];
                }
            }
        }

        self.add_to_msg_buf(&read_buf);
        self.handle_msgs()
    }

    #[inline]
    fn add_to_msg_buf(&mut self, slice : &[u8]) {
        // Some invisible ASCII characters causing glitches on some terminals,
        // we filter those out here.
        self.msg_buf.extend(slice.iter().filter(|c| **c != 0x1 /* SOH */ || **c != 0x2 /* STX */));
    }

    fn handle_msgs<'a>(&'a mut self) -> Vec<CommsRet<'a>> {
        let mut ret = Vec::with_capacity(1);

        // Have we read any CRLFs? In that case just process the message and
        // update buffers. Otherwise just leave the partial message in the
        // buffer.
        loop {
            match find_byte(self.msg_buf.borrow(), b'\r') {
                None => { break; },
                Some(cr_idx) => {
                    // We have a CR, however, we don't have any guarantees that
                    // a single read() will read both CR and LF. So if we have a
                    // CR, but that's the last byte, we should just wait until
                    // we read NL too.
                    if cr_idx == self.msg_buf.len() - 1 {
                        break;
                    } else {
                        assert!(self.msg_buf[cr_idx + 1] == b'\n');
                        // Don't include CRLF
                        let msg = Msg::parse(&self.msg_buf[ 0 .. cr_idx ]);
                        Comms::handle_msg(self.serv_name.borrow(), &mut self.stream, msg, &mut ret);
                        // Update the buffer (drop CRLF)
                        self.msg_buf.drain(0 .. cr_idx + 2);
                    }
                }
            }
        }

        ret
    }

    fn handle_msg<'a>(serv_name : &'a str,
                      stream : &mut TcpStream,
                      msg : Result<Msg, String>,
                      ret : &mut Vec<CommsRet<'a>>) {
        match msg {
            Err(err_msg) => {
                ret.push(CommsRet::Err { serv_name: serv_name, err_msg: err_msg });
            },
            Ok(Msg { pfx, command, params }) => {
                match command {
                    Command::Str(str) =>
                        Comms::handle_str_command(serv_name, stream, ret, pfx, str, params),
                    Command::Num(num) =>
                        Comms::handle_num_command(serv_name, stream, ret, pfx, num, params),
                }
            }
        }
    }

    fn handle_str_command<'a>(serv_name : &'a str,
                              stream : &mut TcpStream,
                              ret : &mut Vec<CommsRet<'a>>,
                              pfx : Option<Pfx>, cmd : String, params : Vec<Vec<u8>>) {
        if cmd == "PING" {
            debug_assert!(params.len() == 1);
            Msg::pong(unsafe {
                        str::from_utf8_unchecked(params.into_iter().nth(0).unwrap().as_ref())
                      }, stream).unwrap();
        } else {
            match pfx {
                None => {
                    ret.push(CommsRet::SentMsg {
                        serv_name: serv_name,
                        ty: cmd,
                        msg: params.into_iter().map(|s| unsafe {
                            String::from_utf8_unchecked(s)
                        }).collect::<Vec<_>>().join(" "), // FIXME: intermediate vector
                    });
                },
                Some(pfx) => {
                    ret.push(CommsRet::IncomingMsg {
                        serv_name: serv_name.borrow(),
                        pfx: pfx,
                        ty: cmd,
                        msg: params.into_iter().map(|s| unsafe {
                            String::from_utf8_unchecked(s)
                        }).collect::<Vec<_>>().join(" "), // FIXME: intermediate vector
                    });
                }
            }
        }
    }

    fn handle_num_command<'a>(serv_name : &'a str,
                              stream : &mut TcpStream,
                              ret : &mut Vec<CommsRet<'a>>,
                              prefix : Option<Pfx>, num : u16, params : Vec<Vec<u8>>) {
        // TODO
        Comms::handle_str_command(serv_name, stream, ret, prefix, "UNKNOWN".to_owned(), params)
    }
}

impl Write for Comms {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.stream.write(buf)
    }

    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        self.stream.flush()
    }

    #[inline]
    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        self.stream.write_all(buf)
    }

    #[inline]
    fn write_fmt(&mut self, fmt: Arguments) -> io::Result<()> {
        self.stream.write_fmt(fmt)
    }

    #[inline]
    fn by_ref(&mut self) -> &mut Comms {
        self
    }
}
<commit_msg>comms: don't add null bytes in the socket buffer to the partial msg buffer<commit_after>use std::borrow::Borrow;
use std::fmt::Arguments;
use std::io::Read;
use std::io::Write;
use std::io;
use std::net::TcpStream;
use std::os::unix::io::{AsRawFd, RawFd};
use std::str;
use std::time::Duration;

use msg::{Msg, Pfx, Command};
use utils::find_byte;

pub struct Comms {
    /// The TCP connection to the server.
    stream        : TcpStream,

    pub serv_name : String,
    serv_addr     : String,

    /// _Partial_ messages collected here until they make a complete message.
    msg_buf       : Vec<u8>,
}

#[derive(Debug)]
pub enum CommsRet<'a> {
    Disconnected {
        fd        : RawFd,
    },

    Err {
        serv_name : &'a str,
        err_msg   : String,
    },

    IncomingMsg {
        serv_name : &'a str,
        pfx       : Pfx,
        ty        : String,
        msg       : String,
    },

    /// A message without prefix. From RFC 2812:
    /// > If the prefix is missing from the message, it is assumed to have
    /// > originated from the connection from which it was received from.
    SentMsg {
        serv_name   : &'a str,
        ty          : String,
        msg         : String,
    }
}

impl Comms {
    pub fn try_connect(serv_addr : &str, serv_name : &str,
                       nick : &str, hostname : &str, realname : &str)
                       -> io::Result<Comms> {
        let stream = try!(TcpStream::connect(serv_addr));
        try!(stream.set_read_timeout(Some(Duration::from_millis(10))));
        try!(stream.set_write_timeout(None));
        try!(stream.set_nonblocking(true));

        let mut comms = Comms {
            stream:     stream,
            serv_name:  serv_name.to_owned(),
            serv_addr:  serv_addr.to_owned(),
            msg_buf:    Vec::new(),
        };
        try!(comms.introduce(nick, hostname, realname));
        Ok(comms)
    }

    /// Get the RawFd, to be used with select() or other I/O multiplexer.
    pub fn get_raw_fd(&self) -> RawFd {
        self.stream.as_raw_fd()
    }

    ////////////////////////////////////////////////////////////////////////////
    // Sending messages

    fn introduce(&mut self, nick : &str, hostname : &str, realname : &str) -> io::Result<()> {
        try!(Msg::user(hostname, realname, &mut self.stream));
        Msg::nick(nick, &mut self.stream)
    }

    ////////////////////////////////////////////////////////////////////////////
    // Receiving messages

    pub fn read_incoming_msg<'a>(&'a mut self) -> Vec<CommsRet<'a>> {
        let mut read_buf : [u8; 512] = [0; 512];

        // Handle disconnects
        match self.stream.read(&mut read_buf) {
            Err(_) => {
                // TODO: I don't understand why this happens. I'm ``randomly''
                // getting "temporarily unavailable" errors.
                // return vec![CommsRet::ShowErr(format!("error in read(): {:?}", err))];
                return vec![];
            },
            Ok(bytes_read) => {
                if bytes_read == 0 {
                    vec![CommsRet::Disconnected { fd: self.get_raw_fd() }]
                } else {
                    self.add_to_msg_buf(&read_buf[ 0 .. bytes_read ]);
                    self.handle_msgs()
                }
            }
        }
    }

    #[inline]
    fn add_to_msg_buf(&mut self, slice : &[u8]) {
        // Some invisible ASCII characters causing glitches on some terminals,
        // we filter those out here.
        self.msg_buf.extend(slice.iter().filter(|c| **c != 0x1 /* SOH */ || **c != 0x2 /* STX */));
    }

    fn handle_msgs<'a>(&'a mut self) -> Vec<CommsRet<'a>> {
        let mut ret = Vec::with_capacity(1);

        // Have we read any CRLFs? In that case just process the message and
        // update buffers. Otherwise just leave the partial message in the
        // buffer.
        loop {
            match find_byte(self.msg_buf.borrow(), b'\r') {
                None => { break; },
                Some(cr_idx) => {
                    // We have a CR, however, we don't have any guarantees that
                    // a single read() will read both CR and LF. So if we have a
                    // CR, but that's the last byte, we should just wait until
                    // we read NL too.
                    if cr_idx == self.msg_buf.len() - 1 {
                        break;
                    } else {
                        assert!(self.msg_buf[cr_idx + 1] == b'\n');
                        // Don't include CRLF
                        let msg = Msg::parse(&self.msg_buf[ 0 .. cr_idx ]);
                        Comms::handle_msg(self.serv_name.borrow(), &mut self.stream, msg, &mut ret);
                        // Update the buffer (drop CRLF)
                        self.msg_buf.drain(0 .. cr_idx + 2);
                    }
                }
            }
        }

        ret
    }

    fn handle_msg<'a>(serv_name : &'a str,
                      stream : &mut TcpStream,
                      msg : Result<Msg, String>,
                      ret : &mut Vec<CommsRet<'a>>) {
        match msg {
            Err(err_msg) => {
                ret.push(CommsRet::Err { serv_name: serv_name, err_msg: err_msg });
            },
            Ok(Msg { pfx, command, params }) => {
                match command {
                    Command::Str(str) =>
                        Comms::handle_str_command(serv_name, stream, ret, pfx, str, params),
                    Command::Num(num) =>
                        Comms::handle_num_command(serv_name, stream, ret, pfx, num, params),
                }
            }
        }
    }

    fn handle_str_command<'a>(serv_name : &'a str,
                              stream : &mut TcpStream,
                              ret : &mut Vec<CommsRet<'a>>,
                              pfx : Option<Pfx>, cmd : String, params : Vec<Vec<u8>>) {
        if cmd == "PING" {
            debug_assert!(params.len() == 1);
            Msg::pong(unsafe {
                        str::from_utf8_unchecked(params.into_iter().nth(0).unwrap().as_ref())
                      }, stream).unwrap();
        } else {
            match pfx {
                None => {
                    ret.push(CommsRet::SentMsg {
                        serv_name: serv_name,
                        ty: cmd,
                        msg: params.into_iter().map(|s| unsafe {
                            String::from_utf8_unchecked(s)
                        }).collect::<Vec<_>>().join(" "), // FIXME: intermediate vector
                    });
                },
                Some(pfx) => {
                    ret.push(CommsRet::IncomingMsg {
                        serv_name: serv_name.borrow(),
                        pfx: pfx,
                        ty: cmd,
                        msg: params.into_iter().map(|s| unsafe {
                            String::from_utf8_unchecked(s)
                        }).collect::<Vec<_>>().join(" "), // FIXME: intermediate vector
                    });
                }
            }
        }
    }

    fn handle_num_command<'a>(serv_name : &'a str,
                              stream : &mut TcpStream,
                              ret : &mut Vec<CommsRet<'a>>,
                              prefix : Option<Pfx>, num : u16, params : Vec<Vec<u8>>) {
        // TODO
        Comms::handle_str_command(serv_name, stream, ret, prefix, "UNKNOWN".to_owned(), params)
    }
}

impl Write for Comms {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.stream.write(buf)
    }

    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        self.stream.flush()
    }

    #[inline]
    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        self.stream.write_all(buf)
    }

    #[inline]
    fn write_fmt(&mut self, fmt: Arguments) -> io::Result<()> {
        self.stream.write_fmt(fmt)
    }

    #[inline]
    fn by_ref(&mut self) -> &mut Comms {
        self
    }
}
<|endoftext|>


<commit_before>//! Implement elementary coordinate operations.

use std::error::Error;
use std::fmt;
use std::fmt::{Display, Formatter};
use std::ops::{Add, AddAssign, Sub, SubAssign, Neg};
use std::str::FromStr;

#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
/// A three-dimensional coordinate.
///
/// # Examples
/// ```
/// # use grafen::coord::Coord;
/// let coord1 = Coord::new(1.0, 0.0, 1.0);
/// let coord2 = Coord::new(0.5, 0.5, 0.5);
///
/// assert_eq!(Coord::new(1.5, 0.5, 1.5), coord1 + coord2);
/// assert_eq!(Coord::new(0.5, -0.5, 0.5), coord1 - coord2);
/// ```
pub struct Coord {
    pub x: f64,
    pub y: f64,
    pub z: f64,
}

impl Coord {
    /// A coordinate at origo.
    pub const ORIGO: Self = Coord { x: 0.0, y: 0.0, z: 0.0 };

    /// Construct a new coordinate.
    pub fn new(x: f64, y: f64, z: f64) -> Coord {
        Coord { x: x, y: y, z: z }
    }

    /// Unpack the coordinate into a tuple.
    pub fn to_tuple(&self) -> (f64, f64, f64) {
        (self.x, self.y, self.z)
    }

    /// Calculate the absolute distance between two coordinates.
    pub fn distance(self, other: Coord) -> f64 {
        let dx = self - other;

        (dx.x * dx.x + dx.y * dx.y + dx.z * dx.z).sqrt()
    }

    /// Calculate the cylindrical distance between two coordinates along an input `Direction`.
    /// Returns the 2-tuple (radius, height).
    ///
    /// # Examples:
    /// ```
    /// # use grafen::coord::{Coord, Direction};
    /// let coord1 = Coord::new(0.0, 0.0, 0.0);
    /// let coord2 = Coord::new(3.0, 4.0, 1.0);
    /// let (dr, dh) = coord1.distance_cylindrical(coord2, Direction::Z);
    ///
    /// assert_eq!((5.0, 1.0), (dr, dh));
    pub fn distance_cylindrical(self, other: Coord, dir: Direction) -> (f64, f64) {
        use self::Direction::*;

        // Get the in-plane (radius) generalized coordinate differences a, b
        // and generalized height (directed) difference h
        let (a, b, dh) = match dir {
            X => (self.y - other.y, self.z - other.z, other.x - self.x),
            Y => (self.x - other.x, self.z - other.z, other.y - self.y),
            Z => (self.x - other.x, self.y - other.y, other.z - self.z),
        };

        let dr = (a * a + b * b).sqrt();

        (dr, dh)
    }

    /// Return the coordinate with its position adjusted to lie within the input box.
    ///
    /// If an input box size side is 0.0 (or smaller) the coordinate is not changed.
    pub fn with_pbc(self, box_size: Coord) -> Coord {
        let do_pbc = |mut c: f64, size: f64| {
            if size <= 0.0 {
                c
            } else {
                while c < 0.0 {
                    c += size;
                }

                c % size
            }
        };

        let (x, y, z) = self.to_tuple();
        Coord::new(do_pbc(x, box_size.x), do_pbc(y, box_size.y), do_pbc(z, box_size.z))
    }
}

impl Display for Coord {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "({:.1}, {:.1}, {:.1})", self.x, self.y, self.z)
    }
}

impl Add for Coord {
    type Output = Coord;

    fn add(self, other: Coord) -> Self::Output {
        Coord::new(self.x + other.x, self.y + other.y, self.z + other.z)
    }

}

impl AddAssign for Coord {
    fn add_assign(&mut self, other: Coord) {
        *self = Coord {
            x: self.x + other.x,
            y: self.y + other.y,
            z: self.z + other.z,
        };
    }
}

impl Sub for Coord {
    type Output = Coord;

    fn sub(self, other: Coord) -> Self::Output {
        Coord::new(self.x - other.x, self.y - other.y, self.z - other.z)
    }

}

impl SubAssign for Coord {
    fn sub_assign(&mut self, other: Coord) {
        *self = Coord {
            x: self.x - other.x,
            y: self.y - other.y,
            z: self.z - other.z,
        };
    }
}

impl Neg for Coord {
    type Output = Coord;

    fn neg(self) -> Self::Output {
        Coord { x: -self.x, y: -self.y, z: -self.z }
    }
}

impl PartialEq for Coord {
    fn eq(&self, other: &Coord) -> bool {
        let atol = 1e-9;
        (self.x - other.x).abs() < atol
            && (self.y - other.y).abs() < atol
            && (self.z - other.z).abs() < atol
    }
}

impl FromStr for Coord {
    type Err = String;

    fn from_str(input: &str) -> Result<Coord, Self::Err> {
        let parse_opt_value = |value: Option<&str>| {
            value.ok_or("Not enough values to parse".to_string())
                 .and_then(|v| v.parse::<f64>().map_err(|err| err.description().to_string()))
        };

        let mut split = input.split_whitespace();
        let x = parse_opt_value(split.next())?;
        let y = parse_opt_value(split.next())?;
        let z = parse_opt_value(split.next())?;

        return Ok(Coord { x, y, z})
    }
}

#[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)]
/// Component direction axis. Eg. for `Cylinder`s this is the cylinder axis.
/// For a `Sheet` the normal.
pub enum Direction { X, Y, Z }

impl Direction {
    /// Default alignment of a cylinder.
    pub fn default_cylinder() -> Direction {
        Direction::Z
    }
}

impl Display for Direction {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        match *self {
            Direction::X => write!(f, "X"),
            Direction::Y => write!(f, "Y"),
            Direction::Z => write!(f, "Z"),
        }
    }
}

/// Trait denoting the ability to `Translate` an object with a `Coord`.
pub trait Translate {
    fn translate(self, Coord) -> Self;
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::str::FromStr;

    #[test]
    fn coord_origo_is_correct() {
        assert_eq!(Coord::new(0.0, 0.0, 0.0), Coord::ORIGO);
    }

    #[test]
    fn coord_eq_tolerance_small_deviation_passes() {
        // Allow for some deviation when testing for equality, since floating point
        // numbers are stupid.
        let coord = Coord::new(0.0, 0.0, 0.0);
        assert_eq!(coord, Coord::new(1e-10, 2e-10, 3e-10));
    }

    #[test]
    #[should_panic]
    fn coord_eq_tolerance_larger_deviation_does_not() {
        let coord = Coord::new(0.0, 0.0, 0.0);
        assert_eq!(coord, Coord::new(1e-9, 2e-9, 3e-9));
    }

    #[test]
    fn coord_distance_calc() {
        let coord1 = Coord::new(1.0, 1.0, 1.0);
        let coord2 = Coord::new(3.0, 3.0, 2.0);

        assert_eq!(3.0, Coord::distance(coord1, coord2));
        assert_eq!(3.0, coord1.distance(coord2));
    }

    #[test]
    fn coord_to_tuple() {
        let coord = Coord::new(1.0, 2.0, 3.0);
        assert_eq!((1.0, 2.0, 3.0), coord.to_tuple());
    }

    #[test]
    fn coord_with_set_pbc() {
        let box_size = Coord::new(2.0, 4.0, 6.0);
        assert_eq!(Coord::new(1.0, 1.0, 1.0), Coord::new(1.0, 1.0, 1.0).with_pbc(box_size));
        assert_eq!(Coord::new(1.0, 1.0, 1.0), Coord::new(3.0, 1.0, 1.0).with_pbc(box_size));
        assert_eq!(Coord::new(1.0, 0.5, 1.0), Coord::new(1.0, 4.5, 1.0).with_pbc(box_size));
        assert_eq!(Coord::new(1.0, 1.0, 1.0), Coord::new(1.0, 1.0, 13.0).with_pbc(box_size));
        assert_eq!(Coord::new(1.0, 1.0, 1.0), Coord::new(-1.0, 1.0, 1.0).with_pbc(box_size));
        assert_eq!(Coord::new(1.0, 3.0, 1.0), Coord::new(1.0, -1.0, 1.0).with_pbc(box_size));
    }

    #[test]
    fn coords_adjusted_by_pbc_with_size_0_does_not_change() {
        let box_size = Coord::new(0.0, 0.0, 0.0);
        let coord = Coord::new(1.0, 2.0, 3.0);
        assert_eq!(coord, coord.with_pbc(box_size));
    }

    #[test]
    fn coord_display_format() {
        let coord = Coord::ORIGO;
        assert_eq!("(0.0, 0.0, 0.0)", &format!("{}", coord));
    }

    #[test]
    fn coord_parsed_from_string() {
        assert_eq!(Ok(Coord::new(1.0, -1.0, 2.0)), Coord::from_str("1.0 -1.0 2.0"));
        assert_eq!(Ok(Coord::new(1.0, -1.0, 2.0)), Coord::from_str("1 -1.0 2"));
        assert_eq!(Ok(Coord::new(1.0, -1.0, 2.0)), Coord::from_str("\t1.0 -1.0 2.0"));
        assert!(Coord::from_str("").is_err());
        assert!(Coord::from_str("2.0 1.0").is_err());
    }

    #[test]
    fn coord_operators() {
        let coord1 = Coord::new(0.0, 1.0, 2.0);
        let coord2 = Coord::new(3.0, 4.0, 5.0);

        assert_eq!(Coord::new(3.0, 5.0, 7.0), coord1 + coord2);
        assert_eq!(Coord::new(3.0, 3.0, 3.0), coord2 - coord1);
        assert_eq!(Coord::new(0.0, -1.0, -2.0), -coord1);
    }

    #[test]
    fn coord_assign_operators() {
        let mut coord1 = Coord::ORIGO;
        let coord2 = Coord::new(1.0, 2.0, 3.0);

        coord1 += coord2;
        assert_eq!(coord2, coord1);

        coord1 -= coord2;
        assert_eq!(Coord::ORIGO, coord1);
    }

    #[test]
    fn coord_distance_along_plane() {
        let mut coord1 = Coord::new(0.0, 0.0, 0.0);
        let mut coord2 = Coord::new(1.0, 1.0, 5.0);

        assert_eq!((26.0f64.sqrt(), 1.0), coord1.distance_cylindrical(coord2, Direction::X));
        assert_eq!((26.0f64.sqrt(), 1.0), coord1.distance_cylindrical(coord2, Direction::Y));
        assert_eq!((2.0f64.sqrt(), 5.0), coord1.distance_cylindrical(coord2, Direction::Z));
    }
}
<commit_msg>Add `Periodic` trait for pbc multiples creation<commit_after>//! Implement elementary coordinate operations.

use std::error::Error;
use std::fmt;
use std::fmt::{Display, Formatter};
use std::ops::{Add, AddAssign, Sub, SubAssign, Neg};
use std::str::FromStr;

#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
/// A three-dimensional coordinate.
///
/// # Examples
/// ```
/// # use grafen::coord::Coord;
/// let coord1 = Coord::new(1.0, 0.0, 1.0);
/// let coord2 = Coord::new(0.5, 0.5, 0.5);
///
/// assert_eq!(Coord::new(1.5, 0.5, 1.5), coord1 + coord2);
/// assert_eq!(Coord::new(0.5, -0.5, 0.5), coord1 - coord2);
/// ```
pub struct Coord {
    pub x: f64,
    pub y: f64,
    pub z: f64,
}

impl Coord {
    /// A coordinate at origo.
    pub const ORIGO: Self = Coord { x: 0.0, y: 0.0, z: 0.0 };

    /// Construct a new coordinate.
    pub fn new(x: f64, y: f64, z: f64) -> Coord {
        Coord { x: x, y: y, z: z }
    }

    /// Unpack the coordinate into a tuple.
    pub fn to_tuple(&self) -> (f64, f64, f64) {
        (self.x, self.y, self.z)
    }

    /// Calculate the absolute distance between two coordinates.
    pub fn distance(self, other: Coord) -> f64 {
        let dx = self - other;

        (dx.x * dx.x + dx.y * dx.y + dx.z * dx.z).sqrt()
    }

    /// Calculate the cylindrical distance between two coordinates along an input `Direction`.
    /// Returns the 2-tuple (radius, height).
    ///
    /// # Examples:
    /// ```
    /// # use grafen::coord::{Coord, Direction};
    /// let coord1 = Coord::new(0.0, 0.0, 0.0);
    /// let coord2 = Coord::new(3.0, 4.0, 1.0);
    /// let (dr, dh) = coord1.distance_cylindrical(coord2, Direction::Z);
    ///
    /// assert_eq!((5.0, 1.0), (dr, dh));
    pub fn distance_cylindrical(self, other: Coord, dir: Direction) -> (f64, f64) {
        use self::Direction::*;

        // Get the in-plane (radius) generalized coordinate differences a, b
        // and generalized height (directed) difference h
        let (a, b, dh) = match dir {
            X => (self.y - other.y, self.z - other.z, other.x - self.x),
            Y => (self.x - other.x, self.z - other.z, other.y - self.y),
            Z => (self.x - other.x, self.y - other.y, other.z - self.z),
        };

        let dr = (a * a + b * b).sqrt();

        (dr, dh)
    }

    /// Return the coordinate with its position adjusted to lie within the input box.
    ///
    /// If an input box size side is 0.0 (or smaller) the coordinate is not changed.
    pub fn with_pbc(self, box_size: Coord) -> Coord {
        let do_pbc = |mut c: f64, size: f64| {
            if size <= 0.0 {
                c
            } else {
                while c < 0.0 {
                    c += size;
                }

                c % size
            }
        };

        let (x, y, z) = self.to_tuple();
        Coord::new(do_pbc(x, box_size.x), do_pbc(y, box_size.y), do_pbc(z, box_size.z))
    }
}

impl Display for Coord {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "({:.1}, {:.1}, {:.1})", self.x, self.y, self.z)
    }
}

impl Add for Coord {
    type Output = Coord;

    fn add(self, other: Coord) -> Self::Output {
        Coord::new(self.x + other.x, self.y + other.y, self.z + other.z)
    }

}

impl AddAssign for Coord {
    fn add_assign(&mut self, other: Coord) {
        *self = Coord {
            x: self.x + other.x,
            y: self.y + other.y,
            z: self.z + other.z,
        };
    }
}

impl Sub for Coord {
    type Output = Coord;

    fn sub(self, other: Coord) -> Self::Output {
        Coord::new(self.x - other.x, self.y - other.y, self.z - other.z)
    }

}

impl SubAssign for Coord {
    fn sub_assign(&mut self, other: Coord) {
        *self = Coord {
            x: self.x - other.x,
            y: self.y - other.y,
            z: self.z - other.z,
        };
    }
}

impl Neg for Coord {
    type Output = Coord;

    fn neg(self) -> Self::Output {
        Coord { x: -self.x, y: -self.y, z: -self.z }
    }
}

impl PartialEq for Coord {
    fn eq(&self, other: &Coord) -> bool {
        let atol = 1e-9;
        (self.x - other.x).abs() < atol
            && (self.y - other.y).abs() < atol
            && (self.z - other.z).abs() < atol
    }
}

impl FromStr for Coord {
    type Err = String;

    fn from_str(input: &str) -> Result<Coord, Self::Err> {
        let parse_opt_value = |value: Option<&str>| {
            value.ok_or("Not enough values to parse".to_string())
                 .and_then(|v| v.parse::<f64>().map_err(|err| err.description().to_string()))
        };

        let mut split = input.split_whitespace();
        let x = parse_opt_value(split.next())?;
        let y = parse_opt_value(split.next())?;
        let z = parse_opt_value(split.next())?;

        return Ok(Coord { x, y, z})
    }
}

impl Periodic for Coord {
    fn pbc_multiply(&self, nx: usize, ny: usize, nz: usize) -> Coord {
        Coord { x: self.x * nx as f64, y: self.y * ny as f64, z: self.z * nz as f64 }
    }
}

#[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)]
/// Component direction axis. Eg. for `Cylinder`s this is the cylinder axis.
/// For a `Sheet` the normal.
pub enum Direction { X, Y, Z }

impl Direction {
    /// Default alignment of a cylinder.
    pub fn default_cylinder() -> Direction {
        Direction::Z
    }
}

impl Display for Direction {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        match *self {
            Direction::X => write!(f, "X"),
            Direction::Y => write!(f, "Y"),
            Direction::Z => write!(f, "Z"),
        }
    }
}

/// Trait denoting the ability to `Translate` an object with a `Coord`.
pub trait Translate {
    fn translate(self, Coord) -> Self;
}

/// Trait denoting periodic boundary condition operations on objects.
pub trait Periodic {
    /// Extend an object by some integer amounts.
    fn pbc_multiply(&self, nx: usize, ny: usize, nz: usize) -> Self;
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::str::FromStr;

    #[test]
    fn coord_origo_is_correct() {
        assert_eq!(Coord::new(0.0, 0.0, 0.0), Coord::ORIGO);
    }

    #[test]
    fn coord_eq_tolerance_small_deviation_passes() {
        // Allow for some deviation when testing for equality, since floating point
        // numbers are stupid.
        let coord = Coord::new(0.0, 0.0, 0.0);
        assert_eq!(coord, Coord::new(1e-10, 2e-10, 3e-10));
    }

    #[test]
    #[should_panic]
    fn coord_eq_tolerance_larger_deviation_does_not() {
        let coord = Coord::new(0.0, 0.0, 0.0);
        assert_eq!(coord, Coord::new(1e-9, 2e-9, 3e-9));
    }

    #[test]
    fn coord_distance_calc() {
        let coord1 = Coord::new(1.0, 1.0, 1.0);
        let coord2 = Coord::new(3.0, 3.0, 2.0);

        assert_eq!(3.0, Coord::distance(coord1, coord2));
        assert_eq!(3.0, coord1.distance(coord2));
    }

    #[test]
    fn coord_to_tuple() {
        let coord = Coord::new(1.0, 2.0, 3.0);
        assert_eq!((1.0, 2.0, 3.0), coord.to_tuple());
    }

    #[test]
    fn coord_with_set_pbc() {
        let box_size = Coord::new(2.0, 4.0, 6.0);
        assert_eq!(Coord::new(1.0, 1.0, 1.0), Coord::new(1.0, 1.0, 1.0).with_pbc(box_size));
        assert_eq!(Coord::new(1.0, 1.0, 1.0), Coord::new(3.0, 1.0, 1.0).with_pbc(box_size));
        assert_eq!(Coord::new(1.0, 0.5, 1.0), Coord::new(1.0, 4.5, 1.0).with_pbc(box_size));
        assert_eq!(Coord::new(1.0, 1.0, 1.0), Coord::new(1.0, 1.0, 13.0).with_pbc(box_size));
        assert_eq!(Coord::new(1.0, 1.0, 1.0), Coord::new(-1.0, 1.0, 1.0).with_pbc(box_size));
        assert_eq!(Coord::new(1.0, 3.0, 1.0), Coord::new(1.0, -1.0, 1.0).with_pbc(box_size));
    }

    #[test]
    fn coords_adjusted_by_pbc_with_size_0_does_not_change() {
        let box_size = Coord::new(0.0, 0.0, 0.0);
        let coord = Coord::new(1.0, 2.0, 3.0);
        assert_eq!(coord, coord.with_pbc(box_size));
    }

    #[test]
    fn coord_display_format() {
        let coord = Coord::ORIGO;
        assert_eq!("(0.0, 0.0, 0.0)", &format!("{}", coord));
    }

    #[test]
    fn coord_parsed_from_string() {
        assert_eq!(Ok(Coord::new(1.0, -1.0, 2.0)), Coord::from_str("1.0 -1.0 2.0"));
        assert_eq!(Ok(Coord::new(1.0, -1.0, 2.0)), Coord::from_str("1 -1.0 2"));
        assert_eq!(Ok(Coord::new(1.0, -1.0, 2.0)), Coord::from_str("\t1.0 -1.0 2.0"));
        assert!(Coord::from_str("").is_err());
        assert!(Coord::from_str("2.0 1.0").is_err());
    }

    #[test]
    fn coord_operators() {
        let coord1 = Coord::new(0.0, 1.0, 2.0);
        let coord2 = Coord::new(3.0, 4.0, 5.0);

        assert_eq!(Coord::new(3.0, 5.0, 7.0), coord1 + coord2);
        assert_eq!(Coord::new(3.0, 3.0, 3.0), coord2 - coord1);
        assert_eq!(Coord::new(0.0, -1.0, -2.0), -coord1);
    }

    #[test]
    fn coord_assign_operators() {
        let mut coord1 = Coord::ORIGO;
        let coord2 = Coord::new(1.0, 2.0, 3.0);

        coord1 += coord2;
        assert_eq!(coord2, coord1);

        coord1 -= coord2;
        assert_eq!(Coord::ORIGO, coord1);
    }

    #[test]
    fn coord_distance_along_plane() {
        let mut coord1 = Coord::new(0.0, 0.0, 0.0);
        let mut coord2 = Coord::new(1.0, 1.0, 5.0);

        assert_eq!((26.0f64.sqrt(), 1.0), coord1.distance_cylindrical(coord2, Direction::X));
        assert_eq!((26.0f64.sqrt(), 1.0), coord1.distance_cylindrical(coord2, Direction::Y));
        assert_eq!((2.0f64.sqrt(), 5.0), coord1.distance_cylindrical(coord2, Direction::Z));
    }

    #[test]
    fn periodic_multiple_of_coords() {
        let coord = Coord::new(1.0, 2.0, 3.0);
        assert_eq!(Coord::new(2.0, 6.0, 12.0), coord.pbc_multiply(2, 3, 4));
    }
}
<|endoftext|>


<commit_before>pub struct Crc64 {
    table: [u64; 256],
    value: u64,
    count: u32,
}

fn table_maker(polynomial: u64) -> [u64; 256] {
    let mut table: [u64; 256] = [0; 256];
    for i in 0..256 {
        let mut v = i as u64;
        for _ in 0..8 {
            v = if v & 1 != 0 {
                polynomial ^ (v >> 1)
            } else {
                v >> 1
            }
        }
        table[i] = v;
    }
    table
}

impl Crc64 {
    pub fn new() -> Crc64 {
        let polynomial = 0xC96C5795D7870F42;
        let c64 = Crc64 {
            table: table_maker(polynomial),
            value: 0xffffffffffffffff,
            count: 0,
        };
        c64
    }

    pub fn reset(&mut self) {
        self.value = 0xffffffffffffffff;
        self.value = 0;
    }

    pub fn update(&mut self, buf: &[u8]) {
        for &i in buf {
            self.value = self.table[((self.value as u8) ^ i) as usize] ^ (self.value >> 8);
            self.count += 1;
        }
    }

    pub fn finalize(&mut self){
        self.value = self.value ^ 0xffffffffffffffffu64;
    }

    pub fn checksum(&mut self, buf: &[u8]) -> u64 {
        self.reset();
        self.update(buf);
        self.finalize();
        self.getsum()
    }

    pub fn getsum(&self) -> u64 {
        self.value
    }

    pub fn bytecount(&self) -> u32{
        self.count
    }
}

#[test]
fn crc32_test() {
    let mut crc64 = Crc64::new();
    crc64.checksum(b"0000");
    assert_eq!(crc64.getsum(),0x2006FFA09D5A94F2);
}
<commit_msg>Fix faulty CRC-64 calculation<commit_after>pub struct Crc64 {
    table: [u64; 256],
    value: u64,
    count: u32,
}

fn table_maker(polynomial: u64) -> [u64; 256] {
    let mut table: [u64; 256] = [0; 256];
    for i in 0..256 {
        let mut v = i as u64;
        for _ in 0..8 {
            v = if v & 1 != 0 {
                polynomial ^ (v >> 1)
            } else {
                v >> 1
            }
        }
        table[i] = v;
    }
    table
}

impl Crc64 {
    pub fn new() -> Crc64 {
        let polynomial = 0xC96C5795D7870F42;
        let c64 = Crc64 {
            table: table_maker(polynomial),
            value: 0xffffffffffffffff,
            count: 0,
        };
        c64
    }

    pub fn reset(&mut self) {
        self.value = 0xffffffffffffffff;
    }

    pub fn update(&mut self, buf: &[u8]) {
        for &i in buf {
            self.value = self.table[((self.value as u8) ^ i) as usize] ^ (self.value >> 8);
            self.count += 1;
        }
    }

    pub fn finalize(&mut self){
        self.value = self.value ^ 0xffffffffffffffffu64;
    }

    pub fn checksum(&mut self, buf: &[u8]) -> u64 {
        self.reset();
        self.update(buf);
        self.finalize();
        self.getsum()
    }

    pub fn getsum(&self) -> u64 {
        self.value
    }

    pub fn bytecount(&self) -> u32{
        self.count
    }
}

#[test]
fn crc32_test() {
    let mut crc64 = Crc64::new();
    crc64.checksum(b"0000");
    assert_eq!(crc64.getsum(),0x2B5C866A7CBEF446);
}
<|endoftext|>


<commit_before>//! Different types of delay for retryable operations.

use std::time::Duration;

use rand::distributions::{IndependentSample, Range as RandRange};
use rand::thread_rng;

/// Each retry increases the delay since the last exponentially.
#[derive(Debug)]
pub struct Exponential {
    base: u64,
    current: u64,
}

impl Exponential {
    /// Create a new `Exponential` using the given millisecond duration as the initial delay.
    pub fn from_millis(base: u64) -> Self {
        Exponential {
            base: base,
            current: base,
        }
    }
}

impl Iterator for Exponential {
    type Item = Duration;

    fn next(&mut self) -> Option<Duration> {
        let duration = Duration::from_millis(self.current);

        self.current = self.current * self.base;

        Some(duration)
    }
}

/// Each retry uses a fixed delay.
#[derive(Debug)]
pub struct Fixed {
    duration: Duration,
}

impl Fixed {
    /// Create a new `Fixed` using the given duration in milliseconds.
    pub fn from_millis(millis: u64) -> Self {
        Fixed {
            duration: Duration::from_millis(millis),
        }
    }
}

impl Iterator for Fixed {
    type Item = Duration;

    fn next(&mut self) -> Option<Duration> {
        Some(self.duration)
    }
}

/// Each retry happens immediately without any delay.
#[derive(Debug)]
pub struct NoDelay;

impl Iterator for NoDelay {
    type Item = Duration;

    fn next(&mut self) -> Option<Duration> {
        Some(Duration::default())
    }
}

/// Each retry uses a duration randomly chosen from a range.
#[derive(Debug)]
pub struct Range {
    minimum: u64,
    maximum: u64,
}

impl Range {
    /// Create a new `Range` between the given millisecond durations.
    pub fn from_millis(minimum: u64, maximum: u64) -> Self {
        Range {
            minimum: minimum,
            maximum: maximum,
        }
    }
}

impl Iterator for Range {
    type Item = Duration;

    fn next(&mut self) -> Option<Duration> {
        let range = RandRange::new(self.minimum, self.maximum);

        let mut rng = thread_rng();

        Some(Duration::from_millis(range.ind_sample(&mut rng)))
    }
}
<commit_msg>Move Range's rand values into struct fields.<commit_after>//! Different types of delay for retryable operations.

use std::fmt::{Debug, Formatter, Error as FmtError};
use std::time::Duration;

use rand::distributions::{IndependentSample, Range as RandRange};
use rand::{ThreadRng, thread_rng};

/// Each retry increases the delay since the last exponentially.
#[derive(Debug)]
pub struct Exponential {
    base: u64,
    current: u64,
}

impl Exponential {
    /// Create a new `Exponential` using the given millisecond duration as the initial delay.
    pub fn from_millis(base: u64) -> Self {
        Exponential {
            base: base,
            current: base,
        }
    }
}

impl Iterator for Exponential {
    type Item = Duration;

    fn next(&mut self) -> Option<Duration> {
        let duration = Duration::from_millis(self.current);

        self.current = self.current * self.base;

        Some(duration)
    }
}

/// Each retry uses a fixed delay.
#[derive(Debug)]
pub struct Fixed {
    duration: Duration,
}

impl Fixed {
    /// Create a new `Fixed` using the given duration in milliseconds.
    pub fn from_millis(millis: u64) -> Self {
        Fixed {
            duration: Duration::from_millis(millis),
        }
    }
}

impl Iterator for Fixed {
    type Item = Duration;

    fn next(&mut self) -> Option<Duration> {
        Some(self.duration)
    }
}

/// Each retry happens immediately without any delay.
#[derive(Debug)]
pub struct NoDelay;

impl Iterator for NoDelay {
    type Item = Duration;

    fn next(&mut self) -> Option<Duration> {
        Some(Duration::default())
    }
}

/// Each retry uses a duration randomly chosen from a range.
pub struct Range {
    range: RandRange<u64>,
    rng: ThreadRng,
}

impl Range {
    /// Create a new `Range` between the given millisecond durations.
    pub fn from_millis(minimum: u64, maximum: u64) -> Self {
        Range {
            range: RandRange::new(minimum, maximum),
            rng: thread_rng(),
        }
    }
}

impl Iterator for Range {
    type Item = Duration;

    fn next(&mut self) -> Option<Duration> {
        Some(Duration::from_millis(self.range.ind_sample(&mut self.rng)))
    }
}

impl Debug for Range {
    fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
        write!(f, "Range {{ range: RandRange<u64>, rng: ThreadRng }}")
    }
}
<|endoftext|>