<commit_before>#[macro_use]
extern crate serde_derive;

use rmp_serde as rmps;
use std::borrow::Cow;
use std::io::Cursor;
use serde::{Deserialize, Serialize};
use rmps::{Deserializer, Serializer};

#[test]
fn round_trip_option() {
    #[derive(Debug, PartialEq, Serialize, Deserialize)]
    struct Foo {
        v: Option<Vec<u8>>,
    }

    let expected = Foo { v: None };

    let mut buf = Vec::new();
    expected.serialize(&mut Serializer::new(&mut buf)).unwrap();

    let mut de = Deserializer::new(Cursor::new(&buf[..]));

    assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}

#[test]
fn round_trip_optional_enum() {
    #[derive(Serialize, Deserialize, Debug, PartialEq)]
    pub enum SimpleEnum {
        Variant,
    }
    let expected = Some(SimpleEnum::Variant);

    let mut buf = Vec::new();
    expected.serialize(&mut Serializer::new(&mut buf)).unwrap();

    let mut de = Deserializer::new(Cursor::new(&buf[..]));
    assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}

#[test]
fn round_trip_cow() {
    #[derive(Serialize, Deserialize, Debug, PartialEq)]
    struct Foo<'a> {
        v: Cow<'a, [u8]>,
    }

    let expected = Foo { v : Cow::Borrowed(&[]) };

    let mut buf = Vec::new();
    expected.serialize(&mut Serializer::new(&mut buf)).unwrap();

    let mut de = Deserializer::new(Cursor::new(&buf[..]));

    assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}

#[test]
fn round_trip_option_cow() {
    use std::borrow::Cow;
    use std::io::Cursor;
    use serde::Serialize;

    #[derive(Serialize, Deserialize, Debug, PartialEq)]
    struct Foo<'a> {
        v: Option<Cow<'a, [u8]>>,
    }

    let expected = Foo { v : None };

    let mut buf = Vec::new();
    expected.serialize(&mut Serializer::new(&mut buf)).unwrap();

    let mut de = Deserializer::new(Cursor::new(&buf[..]));

    assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}

#[test]
fn round_struct_like_enum() {
    use serde::Serialize;

    #[derive(Serialize, Deserialize, Debug, PartialEq)]
    enum Enum {
        A { data: u32 },
    }

    let expected = Enum::A { data: 42 };
    let mut buf = Vec::new();
    expected.serialize(&mut Serializer::new(&mut buf)).unwrap();

    let mut de = Deserializer::new(&buf[..]);

    assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}

#[test]
fn round_struct_like_enum_with_struct_map() {
    use serde::Serialize;

    #[derive(Serialize, Deserialize, Debug, PartialEq)]
    enum Enum {
        A { data: u32 },
    }

    let expected = Enum::A { data: 42 };
    let mut buf = Vec::new();
    expected
        .serialize(&mut Serializer::new(&mut buf).with_struct_map())
        .unwrap();

    let mut de = Deserializer::new(&buf[..]);

    assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}

#[test]
fn round_struct_like_enum_with_struct_tuple() {
    use serde::Serialize;

    #[derive(Serialize, Deserialize, Debug, PartialEq)]
    enum Enum {
        A { data: u32 },
    }

    let expected = Enum::A { data: 42 };
    let mut buf = Vec::new();
    expected
        .serialize(&mut Serializer::new(&mut buf).with_struct_tuple())
        .unwrap();

    let mut de = Deserializer::new(&buf[..]);

    assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}

#[test]
fn round_enum_with_newtype_struct() {
    use serde::Serialize;

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

    #[derive(Serialize, Deserialize, Debug, PartialEq)]
    enum Enum {
        A(Newtype),
    }

    let expected = Enum::A(Newtype("le message".into()));
    let mut buf = Vec::new();
    expected.serialize(&mut Serializer::new(&mut buf)).unwrap();

    let mut de = Deserializer::new(&buf[..]);

    assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}

#[test]
fn round_trip_untagged_enum_with_enum_associated_data() {
    #[derive(Serialize, Deserialize, Debug, PartialEq)]
    #[serde(untagged)]
    enum Foo {
        A(Bar),
    }

    #[derive(Serialize, Deserialize, Debug, PartialEq)]
    enum Bar {
        B,
        C(String),
        D(u64, u64, u64),
        E{f1: String},
    }

    let data1_1 = Foo::A(Bar::B);
    let bytes_1 = rmps::to_vec(&data1_1).unwrap();
    let data1_2 = rmps::from_slice(&bytes_1).unwrap();
    assert_eq!(data1_1, data1_2);

    let data2_1 = Foo::A(Bar::C("Hello".into()));
    let bytes_2 = rmps::to_vec(&data2_1).unwrap();
    let data2_2 = rmps::from_slice(&bytes_2).unwrap();
    assert_eq!(data2_1, data2_2);

    let data3_1 = Foo::A(Bar::D(1,2,3));
    let bytes_3 = rmps::to_vec(&data3_1).unwrap();
    let data3_2 = rmps::from_slice(&bytes_3).unwrap();
    assert_eq!(data3_1, data3_2);

    let data4_1 = Foo::A(Bar::E{f1: "Hello".into()});
    let bytes_4 = rmps::to_vec(&data4_1).unwrap();
    let data4_2 = rmps::from_slice(&bytes_4).unwrap();
    assert_eq!(data4_1, data4_2);
}

// Checks whether deserialization and serialization can both work with structs as maps
#[test]
fn round_struct_as_map() {
    use crate::rmps::to_vec_named;
    use crate::rmps::decode::from_slice;

    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    struct Dog1 {
        name: String,
        age: u16,
    }
    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    struct Dog2 {
        age: u16,
        name: String,
    }

    let dog1 = Dog1 {
        name: "Frankie".into(),
        age: 42,
    };

    let serialized: Vec<u8> = to_vec_named(&dog1).unwrap();
    let deserialized: Dog2 = from_slice(&serialized).unwrap();

    let check = Dog1 {
        age: deserialized.age,
        name: deserialized.name,
    };

    assert_eq!(dog1, check);
}

#[test]
fn round_struct_as_map_in_vec() {
    // See: issue #205
    use crate::rmps::decode::from_slice;
    use crate::rmps::to_vec_named;

    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    struct Dog1 {
        name: String,
        age: u16,
    }
    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    struct Dog2 {
        age: u16,
        name: String,
    }

    let dog1 = Dog1 {
        name: "Frankie".into(),
        age: 42,
    };

    let data = vec![dog1];

    let serialized: Vec<u8> = to_vec_named(&data).unwrap();
    let deserialized: Vec<Dog2> = from_slice(&serialized).unwrap();

    let dog2 = &deserialized[0];

    assert_eq!(dog2.name, "Frankie");
    assert_eq!(dog2.age, 42);
}

#[test]
fn round_trip_unit_struct() {
    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    struct Message1 {
        data: u8,
    }

    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    struct Message2;

    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    enum Messages {
        Message1(Message1),
        Message2(Message2),
    }

    let msg2 = Messages::Message2(Message2);

    // struct-as-tuple
    {
        let serialized: Vec<u8> = rmps::to_vec(&msg2).unwrap();
        let deserialized: Messages = rmps::from_slice(&serialized).unwrap();
        assert_eq!(deserialized, msg2);
    }

    // struct-as-map
    {
        let serialized: Vec<u8> = rmps::to_vec_named(&msg2).unwrap();
        let deserialized: Messages = rmps::from_slice(&serialized).unwrap();
        assert_eq!(deserialized, msg2);
    }
}

#[test]
#[ignore]
fn round_trip_unit_struct_untagged_enum() {
    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    struct UnitStruct;

    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    struct MessageA {
        some_int: i32,
        unit: UnitStruct,
    }

    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    #[serde(untagged)]
    enum Messages {
        MessageA(MessageA),
    }

    let msga = Messages::MessageA(MessageA {
        some_int: 32,
        unit: UnitStruct,
    });

    // struct-as-tuple
    {
        let serialized: Vec<u8> = rmps::to_vec(&msga).unwrap();
        let deserialized: Messages = rmps::from_slice(&serialized).unwrap();
        assert_eq!(deserialized, msga);
    }

    // struct-as-map
    {
        let serialized: Vec<u8> = rmps::to_vec_named(&msga).unwrap();
        let deserialized: Messages = rmps::from_slice(&serialized).unwrap();
        assert_eq!(deserialized, msga);
    }
}

// Checks whether deserialization and serialization can both work with enum variants as strings
#[test]
fn round_variant_string() {
    use crate::rmps::decode::from_slice;

    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    enum Animal1 {
        Dog { breed: String },
        Cat,
        Emu,
    }

    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    enum Animal2 {
        Emu,
        Dog { breed: String },
        Cat,
    }

    // use helper macro so that we can test many combinations at once. Needs to be a macro to deal
    // with the serializer owning a reference to the Vec.
    macro_rules! do_test {
        ($ser:expr) => {
            {
                let animal1 = Animal1::Dog { breed: "Pitbull".to_owned() };
                let expected = Animal2::Dog { breed: "Pitbull".to_owned() };
                let mut buf = Vec::new();
                animal1.serialize(&mut $ser(&mut buf)).unwrap();

                let deserialized: Animal2 = from_slice(&buf).unwrap();
                assert_eq!(deserialized, expected);
            }
        }
    }

    do_test!(|b| Serializer::new(b).with_string_variants());
    do_test!(|b| Serializer::new(b).with_struct_map().with_string_variants());
    do_test!(|b| Serializer::new(b).with_struct_tuple().with_string_variants());
    do_test!(|b| Serializer::new(b).with_string_variants().with_struct_map());
    do_test!(|b| Serializer::new(b).with_string_variants().with_struct_tuple());
    do_test!(|b| {
        Serializer::new(b)
            .with_string_variants()
            .with_struct_tuple()
            .with_struct_map()
            .with_struct_tuple()
            .with_struct_map()
    });
    do_test!(|b| Serializer::new(b).with_integer_variants().with_string_variants());
}

use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};

#[test]
fn roundtrip_ipv4addr() {
    assert_roundtrips(Ipv4Addr::new(127, 0, 0, 1));
}

#[test]
fn roundtrip_ipv6addr() {
    assert_roundtrips(Ipv6Addr::new(1, 2, 3, 4, 5, 6, 7, 8));
}

#[test]
fn roundtrip_ipaddr_ipv4addr() {
    assert_roundtrips(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
}

#[test]
fn roundtrip_ipaddr_ipv6addr() {
    assert_roundtrips(IpAddr::V6(Ipv6Addr::new(1, 2, 3, 4, 5, 6, 7, 8)));
}

#[test]
fn roundtrip_result_ipv4addr() {
    let val: Result<Ipv4Addr, ()> = Ok(Ipv4Addr::new(127, 0, 0, 1));
    assert_roundtrips(val);
}

#[test]
fn roundtrip_result_num() {
    assert_roundtrips(Ok::<u32, u32>(42));
    assert_roundtrips(Err::<(),_>(222));
}

#[test]
fn roundtrip_simple_enum() {
    #[derive(PartialEq, Debug, Serialize, Deserialize)]
    enum SimpleEnum {
        V1(u32),
        V2(String),
    }

    assert_roundtrips(SimpleEnum::V1(42));
    assert_roundtrips(SimpleEnum::V2("hello".into()));
}

#[test]
fn roundtrip_some() {
    #[derive(PartialEq, Debug, Serialize, Deserialize)]
    struct Wrapper<T>(T);

    assert_roundtrips(Some(99));
    assert_roundtrips(Wrapper(Some(99)));
    assert_roundtrips(Some(Wrapper(99)));
    assert_roundtrips(Some("hi".to_string()));
}

#[ignore]
#[test]
fn roundtrip_some_failures() {
    // FIXME
    assert_roundtrips(Some(None::<()>));
}

#[cfg(test)]
fn assert_roundtrips<T: PartialEq + std::fmt::Debug + Serialize + for<'a> Deserialize<'a>>(val: T) {
    let serialized = rmp_serde::to_vec(&val).unwrap();
    let val2: T = match rmp_serde::from_slice(&serialized) {
        Ok(t) => t,
        Err(e) => {
            panic!("Does not deserialize: {}\nSerialized {:?}\nGot {:?}\n", e, val, rmpv::decode::value::read_value(&mut serialized.as_slice()).expect("rmp didn't serialize correctly at all"));
        },
    };
    assert_eq!(val2, val);
}
<commit_msg>Test roundtrips for all serializer configurations<commit_after>#[macro_use]
extern crate serde_derive;

use rmp_serde as rmps;
use std::borrow::Cow;
use std::io::Cursor;
use serde::{Deserialize, Serialize};
use rmps::{Deserializer, Serializer};
use rmps::config::{DefaultConfig, SerializerConfig};

#[test]
fn round_trip_option() {
    #[derive(Debug, PartialEq, Serialize, Deserialize)]
    struct Foo {
        v: Option<Vec<u8>>,
    }

    let expected = Foo { v: None };

    let mut buf = Vec::new();
    expected.serialize(&mut Serializer::new(&mut buf)).unwrap();

    let mut de = Deserializer::new(Cursor::new(&buf[..]));

    assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}

#[test]
fn round_trip_optional_enum() {
    #[derive(Serialize, Deserialize, Debug, PartialEq)]
    pub enum SimpleEnum {
        Variant,
    }
    let expected = Some(SimpleEnum::Variant);

    let mut buf = Vec::new();
    expected.serialize(&mut Serializer::new(&mut buf)).unwrap();

    let mut de = Deserializer::new(Cursor::new(&buf[..]));
    assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}

#[test]
fn round_trip_cow() {
    #[derive(Serialize, Deserialize, Debug, PartialEq)]
    struct Foo<'a> {
        v: Cow<'a, [u8]>,
    }

    let expected = Foo { v : Cow::Borrowed(&[]) };

    let mut buf = Vec::new();
    expected.serialize(&mut Serializer::new(&mut buf)).unwrap();

    let mut de = Deserializer::new(Cursor::new(&buf[..]));

    assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}

#[test]
fn round_trip_option_cow() {
    use std::borrow::Cow;
    use std::io::Cursor;
    use serde::Serialize;

    #[derive(Serialize, Deserialize, Debug, PartialEq)]
    struct Foo<'a> {
        v: Option<Cow<'a, [u8]>>,
    }

    let expected = Foo { v : None };

    let mut buf = Vec::new();
    expected.serialize(&mut Serializer::new(&mut buf)).unwrap();

    let mut de = Deserializer::new(Cursor::new(&buf[..]));

    assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}

#[test]
fn round_struct_like_enum() {
    use serde::Serialize;

    #[derive(Serialize, Deserialize, Debug, PartialEq)]
    enum Enum {
        A { data: u32 },
    }

    let expected = Enum::A { data: 42 };
    let mut buf = Vec::new();
    expected.serialize(&mut Serializer::new(&mut buf)).unwrap();

    let mut de = Deserializer::new(&buf[..]);

    assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}

#[test]
fn round_struct_like_enum_with_struct_map() {
    use serde::Serialize;

    #[derive(Serialize, Deserialize, Debug, PartialEq)]
    enum Enum {
        A { data: u32 },
    }

    let expected = Enum::A { data: 42 };
    let mut buf = Vec::new();
    expected
        .serialize(&mut Serializer::new(&mut buf).with_struct_map())
        .unwrap();

    let mut de = Deserializer::new(&buf[..]);

    assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}

#[test]
fn round_struct_like_enum_with_struct_tuple() {
    use serde::Serialize;

    #[derive(Serialize, Deserialize, Debug, PartialEq)]
    enum Enum {
        A { data: u32 },
    }

    let expected = Enum::A { data: 42 };
    let mut buf = Vec::new();
    expected
        .serialize(&mut Serializer::new(&mut buf).with_struct_tuple())
        .unwrap();

    let mut de = Deserializer::new(&buf[..]);

    assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}

#[test]
fn round_enum_with_newtype_struct() {
    use serde::Serialize;

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

    #[derive(Serialize, Deserialize, Debug, PartialEq)]
    enum Enum {
        A(Newtype),
    }

    let expected = Enum::A(Newtype("le message".into()));
    let mut buf = Vec::new();
    expected.serialize(&mut Serializer::new(&mut buf)).unwrap();

    let mut de = Deserializer::new(&buf[..]);

    assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}

#[test]
fn round_trip_untagged_enum_with_enum_associated_data() {
    #[derive(Serialize, Deserialize, Debug, PartialEq)]
    #[serde(untagged)]
    enum Foo {
        A(Bar),
    }

    #[derive(Serialize, Deserialize, Debug, PartialEq)]
    enum Bar {
        B,
        C(String),
        D(u64, u64, u64),
        E{f1: String},
    }

    let data1_1 = Foo::A(Bar::B);
    let bytes_1 = rmps::to_vec(&data1_1).unwrap();
    let data1_2 = rmps::from_slice(&bytes_1).unwrap();
    assert_eq!(data1_1, data1_2);

    let data2_1 = Foo::A(Bar::C("Hello".into()));
    let bytes_2 = rmps::to_vec(&data2_1).unwrap();
    let data2_2 = rmps::from_slice(&bytes_2).unwrap();
    assert_eq!(data2_1, data2_2);

    let data3_1 = Foo::A(Bar::D(1,2,3));
    let bytes_3 = rmps::to_vec(&data3_1).unwrap();
    let data3_2 = rmps::from_slice(&bytes_3).unwrap();
    assert_eq!(data3_1, data3_2);

    let data4_1 = Foo::A(Bar::E{f1: "Hello".into()});
    let bytes_4 = rmps::to_vec(&data4_1).unwrap();
    let data4_2 = rmps::from_slice(&bytes_4).unwrap();
    assert_eq!(data4_1, data4_2);
}

// Checks whether deserialization and serialization can both work with structs as maps
#[test]
fn round_struct_as_map() {
    use crate::rmps::to_vec_named;
    use crate::rmps::decode::from_slice;

    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    struct Dog1 {
        name: String,
        age: u16,
    }
    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    struct Dog2 {
        age: u16,
        name: String,
    }

    let dog1 = Dog1 {
        name: "Frankie".into(),
        age: 42,
    };

    let serialized: Vec<u8> = to_vec_named(&dog1).unwrap();
    let deserialized: Dog2 = from_slice(&serialized).unwrap();

    let check = Dog1 {
        age: deserialized.age,
        name: deserialized.name,
    };

    assert_eq!(dog1, check);
}

#[test]
fn round_struct_as_map_in_vec() {
    // See: issue #205
    use crate::rmps::decode::from_slice;
    use crate::rmps::to_vec_named;

    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    struct Dog1 {
        name: String,
        age: u16,
    }
    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    struct Dog2 {
        age: u16,
        name: String,
    }

    let dog1 = Dog1 {
        name: "Frankie".into(),
        age: 42,
    };

    let data = vec![dog1];

    let serialized: Vec<u8> = to_vec_named(&data).unwrap();
    let deserialized: Vec<Dog2> = from_slice(&serialized).unwrap();

    let dog2 = &deserialized[0];

    assert_eq!(dog2.name, "Frankie");
    assert_eq!(dog2.age, 42);
}

#[test]
fn round_trip_unit_struct() {
    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    struct Message1 {
        data: u8,
    }

    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    struct Message2;

    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    enum Messages {
        Message1(Message1),
        Message2(Message2),
    }

    let msg2 = Messages::Message2(Message2);

    // struct-as-tuple
    {
        let serialized: Vec<u8> = rmps::to_vec(&msg2).unwrap();
        let deserialized: Messages = rmps::from_slice(&serialized).unwrap();
        assert_eq!(deserialized, msg2);
    }

    // struct-as-map
    {
        let serialized: Vec<u8> = rmps::to_vec_named(&msg2).unwrap();
        let deserialized: Messages = rmps::from_slice(&serialized).unwrap();
        assert_eq!(deserialized, msg2);
    }
}

#[test]
#[ignore]
fn round_trip_unit_struct_untagged_enum() {
    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    struct UnitStruct;

    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    struct MessageA {
        some_int: i32,
        unit: UnitStruct,
    }

    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    #[serde(untagged)]
    enum Messages {
        MessageA(MessageA),
    }

    let msga = Messages::MessageA(MessageA {
        some_int: 32,
        unit: UnitStruct,
    });

    // struct-as-tuple
    {
        let serialized: Vec<u8> = rmps::to_vec(&msga).unwrap();
        let deserialized: Messages = rmps::from_slice(&serialized).unwrap();
        assert_eq!(deserialized, msga);
    }

    // struct-as-map
    {
        let serialized: Vec<u8> = rmps::to_vec_named(&msga).unwrap();
        let deserialized: Messages = rmps::from_slice(&serialized).unwrap();
        assert_eq!(deserialized, msga);
    }
}

// Checks whether deserialization and serialization can both work with enum variants as strings
#[test]
fn round_variant_string() {
    use crate::rmps::decode::from_slice;

    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    enum Animal1 {
        Dog { breed: String },
        Cat,
        Emu,
    }

    #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
    enum Animal2 {
        Emu,
        Dog { breed: String },
        Cat,
    }

    // use helper macro so that we can test many combinations at once. Needs to be a macro to deal
    // with the serializer owning a reference to the Vec.
    macro_rules! do_test {
        ($ser:expr) => {
            {
                let animal1 = Animal1::Dog { breed: "Pitbull".to_owned() };
                let expected = Animal2::Dog { breed: "Pitbull".to_owned() };
                let mut buf = Vec::new();
                animal1.serialize(&mut $ser(&mut buf)).unwrap();

                let deserialized: Animal2 = from_slice(&buf).unwrap();
                assert_eq!(deserialized, expected);
            }
        }
    }

    do_test!(|b| Serializer::new(b).with_string_variants());
    do_test!(|b| Serializer::new(b).with_struct_map().with_string_variants());
    do_test!(|b| Serializer::new(b).with_struct_tuple().with_string_variants());
    do_test!(|b| Serializer::new(b).with_string_variants().with_struct_map());
    do_test!(|b| Serializer::new(b).with_string_variants().with_struct_tuple());
    do_test!(|b| {
        Serializer::new(b)
            .with_string_variants()
            .with_struct_tuple()
            .with_struct_map()
            .with_struct_tuple()
            .with_struct_map()
    });
    do_test!(|b| Serializer::new(b).with_integer_variants().with_string_variants());
}

use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};

#[test]
fn roundtrip_ipv4addr() {
    assert_roundtrips(Ipv4Addr::new(127, 0, 0, 1));
}

#[test]
fn roundtrip_ipv6addr() {
    assert_roundtrips(Ipv6Addr::new(1, 2, 3, 4, 5, 6, 7, 8));
}

#[test]
fn roundtrip_ipaddr_ipv4addr() {
    assert_roundtrips(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
}

#[test]
fn roundtrip_ipaddr_ipv6addr() {
    assert_roundtrips(IpAddr::V6(Ipv6Addr::new(1, 2, 3, 4, 5, 6, 7, 8)));
}

#[test]
fn roundtrip_result_ipv4addr() {
    let val: Result<Ipv4Addr, ()> = Ok(Ipv4Addr::new(127, 0, 0, 1));
    assert_roundtrips(val);
}

#[test]
fn roundtrip_result_num() {
    assert_roundtrips(Ok::<u32, u32>(42));
    assert_roundtrips(Err::<(),_>(222));
}

#[test]
fn roundtrip_simple_enum() {
    #[derive(PartialEq, Debug, Serialize, Deserialize)]
    enum SimpleEnum {
        V1(u32),
        V2(String),
    }

    assert_roundtrips(SimpleEnum::V1(42));
    assert_roundtrips(SimpleEnum::V2("hello".into()));
}

#[test]
fn roundtrip_some() {
    #[derive(PartialEq, Debug, Serialize, Deserialize)]
    struct Wrapper<T>(T);

    assert_roundtrips(Some(99));
    assert_roundtrips(Wrapper(Some(99)));
    assert_roundtrips(Some(Wrapper(99)));
    assert_roundtrips(Some("hi".to_string()));
}

#[ignore]
#[test]
fn roundtrip_some_failures() {
    // FIXME
    assert_roundtrips(Some(None::<()>));
}

#[cfg(test)]
fn assert_roundtrips<T: PartialEq + std::fmt::Debug + Serialize + for<'a> Deserialize<'a>>(val: T) {
    assert_roundtrips_config(&val, "default", |s| s);
    assert_roundtrips_config(&val, ".with_struct_map()", |s| s.with_struct_map());
    assert_roundtrips_config(&val, ".with_string_variants()", |s| {
        s.with_string_variants()
    });
    assert_roundtrips_config(&val, ".with_struct_map().with_string_variants()", |s| {
        s.with_struct_map().with_string_variants()
    });
}

#[cfg(test)]
fn assert_roundtrips_config<T, CSF, C>(val: &T, desc: &str, config_serializer: CSF)
where
    T: PartialEq + std::fmt::Debug + Serialize + for<'a> Deserialize<'a>,
    CSF: FnOnce(Serializer<Vec<u8>, DefaultConfig>) -> Serializer<Vec<u8>, C>,
    C: SerializerConfig,
{
    let mut serializer = config_serializer(Serializer::new(Vec::new()));
    if let Err(e) = val.serialize(&mut serializer) {
        panic!(
            "Failed to serialize: {}\nConfig: {}\nValue: {:?}\n",
            e, desc, val
        );
    }
    let serialized = serializer.into_inner();

    let mut deserializer = Deserializer::new(serialized.as_slice());
    let val2: T = match T::deserialize(&mut deserializer) {
        Ok(t) => t,
        Err(e) => {
            panic!(
                "Does not deserialize: {}\nConfig: {}\nSerialized {:?}\nGot {:?}\n",
                e,
                desc,
                val,
                rmpv::decode::value::read_value(&mut serialized.as_slice())
                    .expect("rmp didn't serialize correctly at all")
            );
        }
    };

    assert_eq!(val, &val2, "Config: {}", desc);
}
<|endoftext|>


<commit_before>pub fn write_leb_i32(buf: &mut Vec<u8>, v: i32) { write_leb_i64(buf, v as i64); }

pub fn write_leb_i64(buf: &mut Vec<u8>, mut v: i64) {
    // https://en.wikipedia.org/wiki/LEB128#Encode_signed_integer
    // http://llvm.org/doxygen/LEB128_8h_source.html#l00048

    let mut more = true;
    let negative = v < 0;
    let size = 32;
    while more {
        let mut byte = (v & 0b1111111) as u8; // get last 7 bits
        v >>= 7; // shift them away from the value
        if negative {
            v |= (!0 as i64) << (size - 7); // extend sign
        }
        let sign_bit = byte & (1 << 6);
        if (v == 0 && sign_bit == 0) || (v == -1 && sign_bit != 0) {
            more = false;
        }
        else {
            byte |= 0b10000000; // turn on MSB
        }
        buf.push(byte);
    }
}

pub fn write_leb_u32(buf: &mut Vec<u8>, mut v: u32) {
    loop {
        let mut byte = v as u8 & 0b01111111; // get last 7 bits
        v >>= 7; // shift them away from the value
        if v != 0 {
            byte |= 0b10000000; // turn on MSB
        }
        buf.push(byte);
        if v == 0 {
            break;
        }
    }
}

pub fn write_fixed_leb16_at_idx(vec: &mut Vec<u8>, idx: usize, x: u16) {
    dbg_assert!(x < (1 << 14)); // we have 14 bits of available space in 2 bytes for leb
    vec[idx] = ((x & 0b1111111) | 0b10000000) as u8;
    vec[idx + 1] = (x >> 7) as u8;
}

pub fn write_fixed_leb32_at_idx(vec: &mut Vec<u8>, idx: usize, x: u32) {
    dbg_assert!(x < (1 << 28)); // we have 28 bits of available space in 4 bytes for leb
    vec[idx] = (x & 0b1111111) as u8 | 0b10000000;
    vec[idx + 1] = (x >> 7 & 0b1111111) as u8 | 0b10000000;
    vec[idx + 2] = (x >> 14 & 0b1111111) as u8 | 0b10000000;
    vec[idx + 3] = (x >> 21 & 0b1111111) as u8;
}
<commit_msg>Rewrite write_leb_i64 (fixes bug with upper bits of constant)<commit_after>pub fn write_leb_i32(buf: &mut Vec<u8>, v: i32) { write_leb_i64(buf, v as i64); }

pub fn write_leb_i64(buf: &mut Vec<u8>, mut v: i64) {
    // https://en.wikipedia.org/wiki/LEB128#Encode_signed_integer
    loop {
        let mut byte = v as u8 & 0b0111_1111;
        v >>= 7;
        let sign = byte & (1 << 6);
        let done = v == 0 && sign == 0 || v == -1 && sign != 0;
        if !done {
            byte |= 0b1000_0000;
        }
        buf.push(byte);
        if done {
            break;
        }
    }
}

pub fn write_leb_u32(buf: &mut Vec<u8>, mut v: u32) {
    loop {
        let mut byte = v as u8 & 0b0111_1111;
        v >>= 7;
        if v != 0 {
            byte |= 0b1000_0000;
        }
        buf.push(byte);
        if v == 0 {
            break;
        }
    }
}

pub fn write_fixed_leb16_at_idx(vec: &mut Vec<u8>, idx: usize, x: u16) {
    dbg_assert!(x < (1 << 14)); // we have 14 bits of available space in 2 bytes for leb
    vec[idx] = ((x & 0b1111111) | 0b10000000) as u8;
    vec[idx + 1] = (x >> 7) as u8;
}

pub fn write_fixed_leb32_at_idx(vec: &mut Vec<u8>, idx: usize, x: u32) {
    dbg_assert!(x < (1 << 28)); // we have 28 bits of available space in 4 bytes for leb
    vec[idx] = (x & 0b1111111) as u8 | 0b10000000;
    vec[idx + 1] = (x >> 7 & 0b1111111) as u8 | 0b10000000;
    vec[idx + 2] = (x >> 14 & 0b1111111) as u8 | 0b10000000;
    vec[idx + 3] = (x >> 21 & 0b1111111) as u8;
}
<|endoftext|>


<commit_before>/*
Copyright 2014 Google Inc. All rights reserved.
Copyright 2017 Jihyun Yu. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

use std;
use std::f64::consts::PI;

/// Angle represents a 1D angle. The internal representation is a double precision
/// value in radians, so conversion to and from radians is exact.
/// Conversions between E5, E6, E7, and Degrees are not always
/// exact. For example, Deg(3.1) is different from E6(3100000) or E7(310000000).
///
///     use s2::s1::angle::*;
///     use std::f64::consts::PI;
///
///     // The following conversions between degrees and radians are exact:
///     assert_eq!(Deg(180.), Deg::from(Rad(PI)));
///     for n in 0..9 {
///         // for n == 0..8
///         assert_eq!(Rad(PI/(n as f64)), Deg(180./(n as f64)).into());
///     }
///
///     // These identities hold when the arguments are scaled up or down by any power
///     // of 2. Some similar identities are also true, for example,
///     assert_eq!(Rad(PI/3.), Deg(60.).into());
///
///     // But be aware that this type of identity does not hold in general. For example,
///     assert_ne!(Rad(PI/60.), Deg(3.).into());
///
///     // Similarly, the conversion to radians means that Deg::from(Angle::from(Deg(x)))
///     // does not always equal x. For example,
///
///     // for n == 0..8
///     for n in 0..9 {
///         let x = 45. * (n as f64);
///         assert_eq!(Deg(x), Deg::from(Angle::from(Deg(x))));
///     }
///
///     // but
///     assert_ne!(Deg(60.), Deg::from(Angle::from(Deg(60.))));
///
/// When testing for equality, you should allow for numerical errors (float64Eq)
/// or convert to discrete E5/E6/E7 values first.
#[derive(Clone, Copy, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Angle(f64);
#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Rad(pub f64);
#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Deg(pub f64);

#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct E5(pub i32);
#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct E6(pub i32);
#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct E7(pub i32);

impl Angle {
    /// rad returns the angle in radians.
    pub fn rad(&self) -> f64 {
        self.0
    }

    /// deg returns the angle in degrees.
    pub fn deg(&self) -> f64 {
        Deg::from(self).0
    }

    /// inf returns an angle larger than any finite angle.
    pub fn inf() -> Self {
        Angle(std::f64::INFINITY)
    }

    /// is_infinite reports whether this Angle is infinite.
    pub fn is_infinite(&self) -> bool {
        self.0.is_infinite()
    }

    /// abs returns the absolute value of the angle.
    pub fn abs(&self) -> Self {
        Angle(self.0.abs())
    }

    /// normalized returns an equivalent angle in [0, 2π).
    pub fn normalized(&self) -> Self {
        let rem = self.0 % (2f64 * PI);
        if rem < 0. {
            Angle(rem + 2f64 * PI)
        } else {
            Angle(rem)
        }
    }

    pub fn max(self, other: Angle) -> Self {
        if self.0 < other.0 {
            return other;
        } else {
            return self;
        }
    }
}

impl std::ops::Mul<f64> for Angle {
    type Output = Self;
    fn mul(self, other: f64) -> Self {
        Angle(self.0 * other)
    }
}
impl std::ops::Add<f64> for Angle {
    type Output = Self;
    fn add(self, other: f64) -> Self {
        Angle(self.0 + other)
    }
}

impl std::ops::Sub<f64> for Angle {
    type Output = Self;
    fn sub(self, other: f64) -> Self {
        Angle(self.0 - other)
    }
}

impl std::ops::Sub<Angle> for f64 {
    type Output = Angle;
    fn sub(self, other: Angle) -> Angle {
        Angle(self - other.0)
    }
}

impl std::fmt::Debug for Angle {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{:.7}", Deg::from(self).0)
    }
}

macro_rules! convert {
    ($tyname1:ident, $tyname2:ident, $mul:expr) => {
        impl From<$tyname1> for $tyname2 {
            fn from(a: $tyname1) -> Self {
                $tyname2(a.0 * $mul)
            }
        }
        impl<'a> From<&'a $tyname1> for $tyname2 {
            fn from(a: &$tyname1) -> Self {
                $tyname2(a.0 * $mul)
            }
        }
        impl From<$tyname2> for $tyname1 {
            fn from(a: $tyname2) -> Self {
                $tyname1(a.0 / $mul)
            }
        }
        impl<'a> From<&'a $tyname2> for $tyname1 {
            fn from(a: &$tyname2) -> Self {
                $tyname1(a.0 / $mul)
            }
        }
    };
}

macro_rules! convert_i32 {
    ($tyname1:ident, $tyname2:ident, $mul:expr) => {
        impl From<$tyname1> for $tyname2 {
            fn from(a: $tyname1) -> Self {
                $tyname2(f64::from(a.0) * $mul)
            }
        }
        impl<'a> From<&'a $tyname1> for $tyname2 {
            fn from(a: &$tyname1) -> Self {
                $tyname2(f64::from(a.0) * $mul)
            }
        }
        impl From<$tyname2> for $tyname1 {
            fn from(a: $tyname2) -> Self {
                $tyname1((a.0 / $mul).round() as i32)
            }
        }
        impl<'a> From<&'a $tyname2> for $tyname1 {
            fn from(a: &$tyname2) -> Self {
                $tyname1((a.0 / $mul).round() as i32)
            }
        }
    };
}

convert!(Rad, Angle, 1.);
convert!(Deg, Rad, PI / 180.);
convert!(Deg, Angle, PI / 180.);

convert_i32!(E5, Angle, PI / 180. / 1e5);
convert_i32!(E6, Angle, PI / 180. / 1e6);
convert_i32!(E7, Angle, PI / 180. / 1e7);

convert_i32!(E5, Deg, 1. / 1e5);
convert_i32!(E6, Deg, 1. / 1e6);
convert_i32!(E7, Deg, 1. / 1e7);

#[cfg(test)]
mod tests {
    use super::*;
    use crate::consts::*;

    #[test]
    fn test_deg_rad() {
        let deg = Deg(180.);
        let rad = Angle(PI);
        assert_eq!(rad, deg.clone().into());
        assert_eq!(deg, rad.clone().into());
    }

    #[test]
    fn test_empty_value() {
        assert_eq!(Deg::from(Angle(0.)).0, 0.);
    }

    #[test]
    fn test_pi_radians_exactly_180_degrees() {
        assert_eq!(Angle(PI).rad(), PI);
        assert_eq!(Angle(PI).deg(), 180.);

        assert_eq!(Angle::from(Deg(180.)).rad(), PI);
        assert_eq!(Angle::from(Deg(180.)).deg(), 180.);

        assert_eq!(Angle(PI / 2.).deg(), 90.);

        assert_eq!(Angle(PI / -2.).deg(), -90.);
        assert_eq!(Angle::from(Deg(-45.)).rad(), PI / -4.);
    }

    fn test_rounding(have: f64, want: i32) {
        assert_eq!(E5::from(Deg(have * 1e-5)).0, want);
        assert_eq!(E6::from(Deg(have * 1e-6)).0, want);
        assert_eq!(E7::from(Deg(have * 1e-7)).0, want);
    }

    #[test]
    fn test_e5e6e7_representation() {
        // NOTE(dsymonds): This first test gives a variance in the 16th decimal place. I should track that down.
        assert_f64_eq!(Angle::from(Deg(-45.)).0, Angle::from(E5(-4500000)).0);

        assert_eq!(Angle::from(Deg(-60.)), Angle::from(E6(-60000000)));
        assert_eq!(Angle::from(Deg(-75.)), Angle::from(E7(-750000000)));

        assert_eq!(-17256123, E5::from(Angle::from(Deg(-172.56123))).0);
        assert_eq!(12345678, E6::from(Angle::from(Deg(12.345678))).0);
        assert_eq!(-123456789, E7::from(Angle::from(Deg(-12.3456789))).0);

        test_rounding(0.500000001, 1);
        test_rounding(-0.500000001, -1);
        test_rounding(0.499999999, 0);
        test_rounding(-0.499999999, 0);
    }

    #[test]
    fn test_normalize_correctly_canonicalize_angles() {
        assert_eq!(Angle::from(Deg(0.)), Angle::from(Deg(360.)).normalized());
        assert_eq!(Angle::from(Deg(180.)), Angle::from(Deg(-180.)).normalized());
        assert_eq!(Angle::from(Deg(180.)), Angle::from(Deg(180.)).normalized());
        assert_eq!(Angle::from(Deg(180.)), Angle::from(Deg(540.)).normalized());
        assert_eq!(Angle::from(Deg(90.)), Angle::from(Deg(-270.)).normalized());
    }

    #[test]
    fn test_degrees_vs_radians() {
        // This test tests the exactness of specific values between degrees and radians.
        let mut k = -8.;
        while k <= 8. {
            assert_eq!(Deg(45. * k), Deg::from(Angle(k * PI / 4.)));
            assert_eq!(Angle::from(Deg(45. * k)), Angle(k * PI / 4.));
            k += 1.;
        }

        for k in 0..30 {
            let n = (1i32 << k) as f64;
            assert_eq!(Angle::from(Deg(180. / n)), Angle(PI / (1. * n)));
            assert_eq!(Angle::from(Deg(60. / n)), Angle(PI / (3. * n)));
            assert_eq!(Angle::from(Deg(36. / n)), Angle(PI / (5. * n)));
            assert_eq!(Angle::from(Deg(20. / n)), Angle(PI / (9. * n)));
            assert_eq!(Angle::from(Deg(4. / n)), Angle(PI / (45. * n)));
        }

        // We also spot check a non-identity.
        assert_f64_eq!(Deg::from(Angle::from(Deg(60.))).0, Deg(60.).0);
    }
}

// BUG(dsymonds): The major differences from the C++ version are:
//   - no unsigned E5/E6/E7 methods
//   - no S2Point or S2LatLng constructors
//   - no comparison or arithmetic operators
<commit_msg>Add Angle::min<commit_after>/*
Copyright 2014 Google Inc. All rights reserved.
Copyright 2017 Jihyun Yu. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

use std;
use std::f64::consts::PI;

/// Angle represents a 1D angle. The internal representation is a double precision
/// value in radians, so conversion to and from radians is exact.
/// Conversions between E5, E6, E7, and Degrees are not always
/// exact. For example, Deg(3.1) is different from E6(3100000) or E7(310000000).
///
///     use s2::s1::angle::*;
///     use std::f64::consts::PI;
///
///     // The following conversions between degrees and radians are exact:
///     assert_eq!(Deg(180.), Deg::from(Rad(PI)));
///     for n in 0..9 {
///         // for n == 0..8
///         assert_eq!(Rad(PI/(n as f64)), Deg(180./(n as f64)).into());
///     }
///
///     // These identities hold when the arguments are scaled up or down by any power
///     // of 2. Some similar identities are also true, for example,
///     assert_eq!(Rad(PI/3.), Deg(60.).into());
///
///     // But be aware that this type of identity does not hold in general. For example,
///     assert_ne!(Rad(PI/60.), Deg(3.).into());
///
///     // Similarly, the conversion to radians means that Deg::from(Angle::from(Deg(x)))
///     // does not always equal x. For example,
///
///     // for n == 0..8
///     for n in 0..9 {
///         let x = 45. * (n as f64);
///         assert_eq!(Deg(x), Deg::from(Angle::from(Deg(x))));
///     }
///
///     // but
///     assert_ne!(Deg(60.), Deg::from(Angle::from(Deg(60.))));
///
/// When testing for equality, you should allow for numerical errors (float64Eq)
/// or convert to discrete E5/E6/E7 values first.
#[derive(Clone, Copy, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Angle(f64);
#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Rad(pub f64);
#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Deg(pub f64);

#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct E5(pub i32);
#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct E6(pub i32);
#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct E7(pub i32);

impl Angle {
    /// rad returns the angle in radians.
    pub fn rad(&self) -> f64 {
        self.0
    }

    /// deg returns the angle in degrees.
    pub fn deg(&self) -> f64 {
        Deg::from(self).0
    }

    /// inf returns an angle larger than any finite angle.
    pub fn inf() -> Self {
        Angle(std::f64::INFINITY)
    }

    /// is_infinite reports whether this Angle is infinite.
    pub fn is_infinite(&self) -> bool {
        self.0.is_infinite()
    }

    /// abs returns the absolute value of the angle.
    pub fn abs(&self) -> Self {
        Angle(self.0.abs())
    }

    /// normalized returns an equivalent angle in [0, 2π).
    pub fn normalized(&self) -> Self {
        let rem = self.0 % (2f64 * PI);
        if rem < 0. {
            Angle(rem + 2f64 * PI)
        } else {
            Angle(rem)
        }
    }

    pub fn max(self, other: Angle) -> Self {
        if self.0 < other.0 {
            return other;
        } else {
            return self;
        }
    }

    pub fn min(self, other: Angle) -> Self {
        if self.0 > other.0 {
            return other;
        } else {
            return self;
        }
    }
}

impl std::ops::Mul<f64> for Angle {
    type Output = Self;
    fn mul(self, other: f64) -> Self {
        Angle(self.0 * other)
    }
}
impl std::ops::Add<f64> for Angle {
    type Output = Self;
    fn add(self, other: f64) -> Self {
        Angle(self.0 + other)
    }
}

impl std::ops::Sub<f64> for Angle {
    type Output = Self;
    fn sub(self, other: f64) -> Self {
        Angle(self.0 - other)
    }
}

impl std::ops::Sub<Angle> for f64 {
    type Output = Angle;
    fn sub(self, other: Angle) -> Angle {
        Angle(self - other.0)
    }
}

impl std::fmt::Debug for Angle {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{:.7}", Deg::from(self).0)
    }
}

macro_rules! convert {
    ($tyname1:ident, $tyname2:ident, $mul:expr) => {
        impl From<$tyname1> for $tyname2 {
            fn from(a: $tyname1) -> Self {
                $tyname2(a.0 * $mul)
            }
        }
        impl<'a> From<&'a $tyname1> for $tyname2 {
            fn from(a: &$tyname1) -> Self {
                $tyname2(a.0 * $mul)
            }
        }
        impl From<$tyname2> for $tyname1 {
            fn from(a: $tyname2) -> Self {
                $tyname1(a.0 / $mul)
            }
        }
        impl<'a> From<&'a $tyname2> for $tyname1 {
            fn from(a: &$tyname2) -> Self {
                $tyname1(a.0 / $mul)
            }
        }
    };
}

macro_rules! convert_i32 {
    ($tyname1:ident, $tyname2:ident, $mul:expr) => {
        impl From<$tyname1> for $tyname2 {
            fn from(a: $tyname1) -> Self {
                $tyname2(f64::from(a.0) * $mul)
            }
        }
        impl<'a> From<&'a $tyname1> for $tyname2 {
            fn from(a: &$tyname1) -> Self {
                $tyname2(f64::from(a.0) * $mul)
            }
        }
        impl From<$tyname2> for $tyname1 {
            fn from(a: $tyname2) -> Self {
                $tyname1((a.0 / $mul).round() as i32)
            }
        }
        impl<'a> From<&'a $tyname2> for $tyname1 {
            fn from(a: &$tyname2) -> Self {
                $tyname1((a.0 / $mul).round() as i32)
            }
        }
    };
}

convert!(Rad, Angle, 1.);
convert!(Deg, Rad, PI / 180.);
convert!(Deg, Angle, PI / 180.);

convert_i32!(E5, Angle, PI / 180. / 1e5);
convert_i32!(E6, Angle, PI / 180. / 1e6);
convert_i32!(E7, Angle, PI / 180. / 1e7);

convert_i32!(E5, Deg, 1. / 1e5);
convert_i32!(E6, Deg, 1. / 1e6);
convert_i32!(E7, Deg, 1. / 1e7);

#[cfg(test)]
mod tests {
    use super::*;
    use crate::consts::*;

    #[test]
    fn test_deg_rad() {
        let deg = Deg(180.);
        let rad = Angle(PI);
        assert_eq!(rad, deg.clone().into());
        assert_eq!(deg, rad.clone().into());
    }

    #[test]
    fn test_empty_value() {
        assert_eq!(Deg::from(Angle(0.)).0, 0.);
    }

    #[test]
    fn test_pi_radians_exactly_180_degrees() {
        assert_eq!(Angle(PI).rad(), PI);
        assert_eq!(Angle(PI).deg(), 180.);

        assert_eq!(Angle::from(Deg(180.)).rad(), PI);
        assert_eq!(Angle::from(Deg(180.)).deg(), 180.);

        assert_eq!(Angle(PI / 2.).deg(), 90.);

        assert_eq!(Angle(PI / -2.).deg(), -90.);
        assert_eq!(Angle::from(Deg(-45.)).rad(), PI / -4.);
    }

    fn test_rounding(have: f64, want: i32) {
        assert_eq!(E5::from(Deg(have * 1e-5)).0, want);
        assert_eq!(E6::from(Deg(have * 1e-6)).0, want);
        assert_eq!(E7::from(Deg(have * 1e-7)).0, want);
    }

    #[test]
    fn test_e5e6e7_representation() {
        // NOTE(dsymonds): This first test gives a variance in the 16th decimal place. I should track that down.
        assert_f64_eq!(Angle::from(Deg(-45.)).0, Angle::from(E5(-4500000)).0);

        assert_eq!(Angle::from(Deg(-60.)), Angle::from(E6(-60000000)));
        assert_eq!(Angle::from(Deg(-75.)), Angle::from(E7(-750000000)));

        assert_eq!(-17256123, E5::from(Angle::from(Deg(-172.56123))).0);
        assert_eq!(12345678, E6::from(Angle::from(Deg(12.345678))).0);
        assert_eq!(-123456789, E7::from(Angle::from(Deg(-12.3456789))).0);

        test_rounding(0.500000001, 1);
        test_rounding(-0.500000001, -1);
        test_rounding(0.499999999, 0);
        test_rounding(-0.499999999, 0);
    }

    #[test]
    fn test_normalize_correctly_canonicalize_angles() {
        assert_eq!(Angle::from(Deg(0.)), Angle::from(Deg(360.)).normalized());
        assert_eq!(Angle::from(Deg(180.)), Angle::from(Deg(-180.)).normalized());
        assert_eq!(Angle::from(Deg(180.)), Angle::from(Deg(180.)).normalized());
        assert_eq!(Angle::from(Deg(180.)), Angle::from(Deg(540.)).normalized());
        assert_eq!(Angle::from(Deg(90.)), Angle::from(Deg(-270.)).normalized());
    }

    #[test]
    fn test_degrees_vs_radians() {
        // This test tests the exactness of specific values between degrees and radians.
        let mut k = -8.;
        while k <= 8. {
            assert_eq!(Deg(45. * k), Deg::from(Angle(k * PI / 4.)));
            assert_eq!(Angle::from(Deg(45. * k)), Angle(k * PI / 4.));
            k += 1.;
        }

        for k in 0..30 {
            let n = (1i32 << k) as f64;
            assert_eq!(Angle::from(Deg(180. / n)), Angle(PI / (1. * n)));
            assert_eq!(Angle::from(Deg(60. / n)), Angle(PI / (3. * n)));
            assert_eq!(Angle::from(Deg(36. / n)), Angle(PI / (5. * n)));
            assert_eq!(Angle::from(Deg(20. / n)), Angle(PI / (9. * n)));
            assert_eq!(Angle::from(Deg(4. / n)), Angle(PI / (45. * n)));
        }

        // We also spot check a non-identity.
        assert_f64_eq!(Deg::from(Angle::from(Deg(60.))).0, Deg(60.).0);
    }
}

// BUG(dsymonds): The major differences from the C++ version are:
//   - no unsigned E5/E6/E7 methods
//   - no S2Point or S2LatLng constructors
//   - no comparison or arithmetic operators
<|endoftext|>


<commit_before>//! A type that represents the union of a set of regular expressions.

use regex::RegexSet as RxSet;

// Yeah, I'm aware this is sorta crappy, should be cheaper to compile a regex
// ORing all the patterns, I guess...

/// A dynamic set of regular expressions.
#[derive(Debug)]
pub struct RegexSet {
    items: Vec<String>,
    set: Option<RxSet>,
}

impl RegexSet {
    /// Is this set empty?
    pub fn is_empty(&self) -> bool {
        self.items.is_empty()
    }

    /// Insert a new regex into this set.
    pub fn insert<S>(&mut self, string: S)
    where
        S: AsRef<str>,
    {
        self.items.push(format!("^{}$", string.as_ref()));
        self.set = None;
    }

    /// Returns slice of String from its field 'items'
    pub fn get_items(&self) -> &[String] {
        &self.items[..]
    }

    /// Construct a RegexSet from the set of entries we've accumulated.
    ///
    /// Must be called before calling `matches()`, or it will always return
    /// false.
    pub fn build(&mut self) {
        self.set = match RxSet::new(&self.items) {
            Ok(x) => Some(x),
            Err(e) => {
                error!("Invalid regex in {:?}: {:?}", self.items, e);
                None
            }
        }
    }

    /// Does the given `string` match any of the regexes in this set?
    pub fn matches<S>(&self, string: S) -> bool
    where
        S: AsRef<str>,
    {
        let s = string.as_ref();
        self.set.as_ref().map(|set| set.is_match(s)).unwrap_or(
            false,
        )
    }
}

impl Default for RegexSet {
    fn default() -> Self {
        RegexSet {
            items: vec![],
            set: None,
        }
    }
}
<commit_msg>Remove an out-of-date comment in RegexSet.<commit_after>//! A type that represents the union of a set of regular expressions.

use regex::RegexSet as RxSet;

/// A dynamic set of regular expressions.
#[derive(Debug)]
pub struct RegexSet {
    items: Vec<String>,
    set: Option<RxSet>,
}

impl RegexSet {
    /// Is this set empty?
    pub fn is_empty(&self) -> bool {
        self.items.is_empty()
    }

    /// Insert a new regex into this set.
    pub fn insert<S>(&mut self, string: S)
    where
        S: AsRef<str>,
    {
        self.items.push(format!("^{}$", string.as_ref()));
        self.set = None;
    }

    /// Returns slice of String from its field 'items'
    pub fn get_items(&self) -> &[String] {
        &self.items[..]
    }

    /// Construct a RegexSet from the set of entries we've accumulated.
    ///
    /// Must be called before calling `matches()`, or it will always return
    /// false.
    pub fn build(&mut self) {
        self.set = match RxSet::new(&self.items) {
            Ok(x) => Some(x),
            Err(e) => {
                error!("Invalid regex in {:?}: {:?}", self.items, e);
                None
            }
        }
    }

    /// Does the given `string` match any of the regexes in this set?
    pub fn matches<S>(&self, string: S) -> bool
    where
        S: AsRef<str>,
    {
        let s = string.as_ref();
        self.set.as_ref().map(|set| set.is_match(s)).unwrap_or(
            false,
        )
    }
}

impl Default for RegexSet {
    fn default() -> Self {
        RegexSet {
            items: vec![],
            set: None,
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>remove opt-in of feature that I removed uses of in previous commit.<commit_after><|endoftext|>


<commit_before>extern crate rsoundio;

use std::os::raw::c_int;

#[test]
fn test_outstream() {
    println!("test: OutStream");
    let sio = rsoundio::SoundIo::new();
    assert!(sio.connect().is_none());
    // assert!(sio.connect_backend(rsoundio::ffi::SioBackend::Alsa).is_none());
    println!("current backend: {}", sio.current_backend().unwrap());
    sio.flush_events();
    let fmt;
    let dev_idx = sio.default_output_device_index().unwrap();
    let dev = sio.get_output_device(dev_idx).unwrap();
    println!("device: {}, ref_count: {}", dev, dev.ref_count());
    let mut stream = dev.create_outstream().unwrap();
    assert!(stream.open().is_none());
    fmt = stream.current_format().unwrap();
    println!("current format: {}", fmt);
    let cb = |out: rsoundio::OutStream, min: i32, max: i32| {
        println!("Closure: {}, {} using format: {}", min, max, fmt);
    };
    stream.register_write_callback(Box::new(cb));
    let ucb = | out: rsoundio::OutStream | {
        println!("Underflow!")
    };
    stream.register_underflow_callback(Box::new(ucb));
    let ecb = | out: rsoundio::OutStream, err: rsoundio::ffi::SioError| {
        println!("Error: {}", err)
    };
    stream.register_error_callback(Box::new(ecb));
    assert!(stream.start().is_none());
    loop {
        sio.wait_events();
    }
    assert!(stream.clear_buffer().is_none());
    assert!(stream.pause(true).is_none());
    assert!(stream.pause(false).is_none());
    println!("latency: {}", stream.get_latency().unwrap());
    stream.destroy();
}

unsafe extern "C" fn write_callback(raw_out: *mut rsoundio::ffi::SoundIoOutStream,
                                    min_frame_count: c_int,
                                    max_frame_count: c_int) {
    let out = rsoundio::OutStream::new(raw_out);
    let sr = out.get_sample_rate();
    let layout = out.get_layout();
    let channels = layout.channel_count();
    // osc stuff:
    let mut f = 8_000.0f32;
    // let phi = 2.0 * f * ::std::f32::consts::PI / (sr as f32);
    let mut sample = 0.0f32;

    let mut raw_areas: *mut rsoundio::ffi::SoundIoChannelArea = ::std::ptr::null_mut();
    let mut frames_left = max_frame_count;
    let mut block_size = frames_left;
    while frames_left > 0 {
        if let Some(err) = out.begin_write(&mut raw_areas, &mut block_size) {
            panic!("{}", err);
        }
        if block_size <= 0 {
            break;
        }

        let areas = unsafe { ::std::slice::from_raw_parts_mut(raw_areas, channels as usize) };
        let mut dir = 1.0;
        for idx in 0..block_size {
            if f >= 8_000.0 || f <= 60.0 {
                dir *= -1.0
            };
            f += dir * 1.0;
            let phi = 2.0 * f * ::std::f32::consts::PI / (sr as f32);
            sample = (phi * (idx as f32)).sin();
            assert!(sample.abs() < 1.001);
            for ch_idx in 0..channels {
                let addr = (areas[ch_idx as usize].ptr as usize +
                            areas[ch_idx as usize].step as usize *
                            idx as usize) as *mut f32;
                unsafe { *addr = sample };
            }
        }
        assert!(out.end_write().is_none());
        frames_left -= block_size;
    }
}
<commit_msg>Remove unnecessary `unsafe`<commit_after>extern crate rsoundio;

use std::os::raw::c_int;

#[test]
fn test_outstream() {
    println!("test: OutStream");
    let sio = rsoundio::SoundIo::new();
    assert!(sio.connect().is_none());
    // assert!(sio.connect_backend(rsoundio::ffi::SioBackend::Alsa).is_none());
    println!("current backend: {}", sio.current_backend().unwrap());
    sio.flush_events();
    let fmt;
    let dev_idx = sio.default_output_device_index().unwrap();
    let dev = sio.get_output_device(dev_idx).unwrap();
    println!("device: {}, ref_count: {}", dev, dev.ref_count());
    let mut stream = dev.create_outstream().unwrap();
    assert!(stream.open().is_none());
    fmt = stream.current_format().unwrap();
    println!("current format: {}", fmt);
    let cb = |out: rsoundio::OutStream, min: i32, max: i32| {
        println!("Closure: {}, {} using format: {}", min, max, fmt);
    };
    stream.register_write_callback(Box::new(cb));
    let ucb = | out: rsoundio::OutStream | {
        println!("Underflow!")
    };
    stream.register_underflow_callback(Box::new(ucb));
    let ecb = | out: rsoundio::OutStream, err: rsoundio::ffi::SioError| {
        println!("Error: {}", err)
    };
    stream.register_error_callback(Box::new(ecb));
    assert!(stream.start().is_none());
    loop {
        sio.wait_events();
    }
    assert!(stream.clear_buffer().is_none());
    assert!(stream.pause(true).is_none());
    assert!(stream.pause(false).is_none());
    println!("latency: {}", stream.get_latency().unwrap());
    stream.destroy();
}

unsafe extern "C" fn write_callback(raw_out: *mut rsoundio::ffi::SoundIoOutStream,
                                    min_frame_count: c_int,
                                    max_frame_count: c_int) {
    let out = rsoundio::OutStream::new(raw_out);
    let sr = out.get_sample_rate();
    let layout = out.get_layout();
    let channels = layout.channel_count();
    // osc stuff:
    let mut f = 8_000.0f32;
    // let phi = 2.0 * f * ::std::f32::consts::PI / (sr as f32);
    let mut sample = 0.0f32;

    let mut raw_areas: *mut rsoundio::ffi::SoundIoChannelArea = ::std::ptr::null_mut();
    let mut frames_left = max_frame_count;
    let mut block_size = frames_left;
    while frames_left > 0 {
        if let Some(err) = out.begin_write(&mut raw_areas, &mut block_size) {
            panic!("{}", err);
        }
        if block_size <= 0 {
            break;
        }

        let areas = ::std::slice::from_raw_parts_mut(raw_areas, channels as usize);
        let mut dir = 1.0;
        for idx in 0..block_size {
            if f >= 8_000.0 || f <= 60.0 {
                dir *= -1.0
            };
            f += dir * 1.0;
            let phi = 2.0 * f * ::std::f32::consts::PI / (sr as f32);
            sample = (phi * (idx as f32)).sin();
            assert!(sample.abs() < 1.001);
            for ch_idx in 0..channels {
                let addr = (areas[ch_idx as usize].ptr as usize +
                            areas[ch_idx as usize].step as usize *
                            idx as usize) as *mut f32;
                *addr = sample ;
            }
        }
        assert!(out.end_write().is_none());
        frames_left -= block_size;
    }
}
<|endoftext|>


<commit_before>use crate::time::{Duration, Time};
use crate::util::FAILED_TO_LOCK;
use crossbeam::channel::{unbounded, Sender};
use log::warn;
use std::cmp;
use std::collections::BinaryHeap;
use std::sync::{Arc, Mutex};
use std::thread::sleep;
use std::time::{Duration as StdDuration, SystemTime, UNIX_EPOCH};

static BEFORE_EPOCH: &'static str = "Requested time is before UNIX epoch.";

pub struct Delay {
    clock: Arc<Clock>,
    delay: Duration,
}

impl Delay {
    pub fn new(clock: Arc<Clock>, delay: Duration) -> Self {
        Self { clock, delay }
    }

    pub fn sleep(self) {
        self.clock.sleep(self.delay);
    }
}

pub struct Rate {
    clock: Arc<Clock>,
    next: Time,
    delay: Duration,
}

impl Rate {
    pub fn new(clock: Arc<Clock>, delay: Duration) -> Rate {
        let start = clock.now();
        Rate {
            clock,
            next: start,
            delay,
        }
    }

    pub fn sleep(&mut self) {
        self.next = self.next.clone() + self.delay.clone();
        self.clock.wait_until(self.next.clone());
    }
}

pub trait Clock: Send + Sync {
    fn now(&self) -> Time;
    fn sleep(&self, d: Duration);
    fn wait_until(&self, t: Time);
    fn await_init(&self) {}
}

#[derive(Clone, Default)]
pub struct RealClock {}

impl Clock for RealClock {
    #[inline]
    fn now(&self) -> Time {
        let time = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .expect(BEFORE_EPOCH);
        Time {
            sec: time.as_secs() as u32,
            nsec: time.subsec_nanos() as u32,
        }
    }

    #[inline]
    fn sleep(&self, d: Duration) {
        if d < Duration::default() {
            return;
        }
        sleep(StdDuration::new(d.sec as u64, d.nsec as u32));
    }

    #[inline]
    fn wait_until(&self, t: Time) {
        self.sleep(t - self.now());
    }
}

struct Timeout {
    timestamp: Time,
    tx: Sender<()>,
}

impl cmp::PartialEq for Timeout {
    fn eq(&self, other: &Self) -> bool {
        self.timestamp == other.timestamp
    }
}

impl cmp::PartialOrd for Timeout {
    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
        self.timestamp
            .partial_cmp(&other.timestamp)
            .map(cmp::Ordering::reverse)
    }
}

impl cmp::Eq for Timeout {}

impl cmp::Ord for Timeout {
    fn cmp(&self, other: &Self) -> cmp::Ordering {
        self.timestamp.cmp(&other.timestamp).reverse()
    }
}

#[derive(Default)]
pub struct SimData {
    current: Time,
    timeouts: BinaryHeap<Timeout>,
}

#[derive(Default)]
pub struct SimulatedClock {
    pub data: Mutex<SimData>,
}

impl SimulatedClock {
    pub fn trigger(&self, time: Time) {
        let mut data = self.data.lock().expect(FAILED_TO_LOCK);
        data.current = time;
        loop {
            match data.timeouts.peek() {
                None => break,
                Some(next) if next.timestamp > data.current => break,
                _ => {}
            }
            if let Some(next) = data.timeouts.pop() {
                next.tx.send(()).expect(SLEEPING_THREAD_MISSING);
            }
        }
    }
}

impl Clock for SimulatedClock {
    #[inline]
    fn now(&self) -> Time {
        self.data.lock().expect(FAILED_TO_LOCK).current.clone()
    }

    #[inline]
    fn sleep(&self, d: Duration) {
        if d.sec < 0 || d.nsec < 0 {
            return;
        }
        let current = { self.data.lock().expect(FAILED_TO_LOCK).current.clone() };
        self.wait_until(current + d);
    }

    #[inline]
    fn wait_until(&self, timestamp: Time) {
        let (tx, rx) = unbounded();
        {
            self.data
                .lock()
                .expect(FAILED_TO_LOCK)
                .timeouts
                .push(Timeout { timestamp, tx });
        }
        if rx.recv().is_err() {
            warn!("Sleep beyond simulated clock");
        }
    }

    fn await_init(&self) {
        if self.data.lock().expect(FAILED_TO_LOCK).current == Time::default() {
            self.wait_until(Time::from_nanos(1));
        }
    }
}

static SLEEPING_THREAD_MISSING: &'static str = "Failed to find sleeping thread";
<commit_msg>Use parker for simulated clock<commit_after>use crate::time::{Duration, Time};
use crate::util::FAILED_TO_LOCK;
use crossbeam::sync::{Parker, Unparker};
use std::cmp;
use std::collections::BinaryHeap;
use std::sync::{Arc, Mutex};
use std::thread::sleep;
use std::time::{Duration as StdDuration, SystemTime, UNIX_EPOCH};

static BEFORE_EPOCH: &'static str = "Requested time is before UNIX epoch.";

pub struct Delay {
    clock: Arc<Clock>,
    delay: Duration,
}

impl Delay {
    pub fn new(clock: Arc<Clock>, delay: Duration) -> Self {
        Self { clock, delay }
    }

    pub fn sleep(self) {
        self.clock.sleep(self.delay);
    }
}

pub struct Rate {
    clock: Arc<Clock>,
    next: Time,
    delay: Duration,
}

impl Rate {
    pub fn new(clock: Arc<Clock>, delay: Duration) -> Rate {
        let start = clock.now();
        Rate {
            clock,
            next: start,
            delay,
        }
    }

    pub fn sleep(&mut self) {
        self.next = self.next.clone() + self.delay.clone();
        self.clock.wait_until(self.next.clone());
    }
}

pub trait Clock: Send + Sync {
    fn now(&self) -> Time;
    fn sleep(&self, d: Duration);
    fn wait_until(&self, t: Time);
    fn await_init(&self) {}
}

#[derive(Clone, Default)]
pub struct RealClock {}

impl Clock for RealClock {
    #[inline]
    fn now(&self) -> Time {
        let time = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .expect(BEFORE_EPOCH);
        Time {
            sec: time.as_secs() as u32,
            nsec: time.subsec_nanos() as u32,
        }
    }

    #[inline]
    fn sleep(&self, d: Duration) {
        if d < Duration::default() {
            return;
        }
        sleep(StdDuration::new(d.sec as u64, d.nsec as u32));
    }

    #[inline]
    fn wait_until(&self, t: Time) {
        self.sleep(t - self.now());
    }
}

struct Timeout {
    timestamp: Time,
    unparker: Unparker,
}

impl Drop for Timeout {
    fn drop(&mut self) {
        self.unparker.unpark();
    }
}

impl cmp::PartialEq for Timeout {
    fn eq(&self, other: &Self) -> bool {
        self.timestamp == other.timestamp
    }
}

impl cmp::PartialOrd for Timeout {
    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
        self.timestamp
            .partial_cmp(&other.timestamp)
            .map(cmp::Ordering::reverse)
    }
}

impl cmp::Eq for Timeout {}

impl cmp::Ord for Timeout {
    fn cmp(&self, other: &Self) -> cmp::Ordering {
        self.timestamp.cmp(&other.timestamp).reverse()
    }
}

#[derive(Default)]
pub struct SimData {
    current: Time,
    timeouts: BinaryHeap<Timeout>,
}

#[derive(Default)]
pub struct SimulatedClock {
    pub data: Mutex<SimData>,
}

impl SimulatedClock {
    pub fn trigger(&self, time: Time) {
        let mut data = self.data.lock().expect(FAILED_TO_LOCK);
        data.current = time;
        loop {
            match data.timeouts.peek() {
                None => break,
                Some(next) if next.timestamp > data.current => break,
                _ => {}
            }
            data.timeouts.pop();
        }
    }
}

impl Clock for SimulatedClock {
    #[inline]
    fn now(&self) -> Time {
        self.data.lock().expect(FAILED_TO_LOCK).current.clone()
    }

    #[inline]
    fn sleep(&self, d: Duration) {
        if d.sec < 0 || d.nsec < 0 {
            return;
        }
        let current = { self.data.lock().expect(FAILED_TO_LOCK).current.clone() };
        self.wait_until(current + d);
    }

    #[inline]
    fn wait_until(&self, timestamp: Time) {
        let parker = Parker::new();
        let unparker = parker.unparker().clone();
        {
            self.data
                .lock()
                .expect(FAILED_TO_LOCK)
                .timeouts
                .push(Timeout {
                    timestamp,
                    unparker,
                });
        }
        parker.park()
    }

    fn await_init(&self) {
        if self.data.lock().expect(FAILED_TO_LOCK).current == Time::default() {
            self.wait_until(Time::from_nanos(1));
        }
    }
}
<|endoftext|>


<commit_before>extern crate draw;
extern crate gfx;
extern crate cgmath;

use cgmath::{BaseFloat, Zero, Matrix3, Matrix4, Transform3};

//TODO
pub struct Camera<S>(S);

#[derive(Debug)]
pub enum DrawError {
    Batch(gfx::batch::BatchError),
    Flush(draw::FlushError),
}

pub trait AbstractScene<D: gfx::Device> {
    type Scalar;
    type Entity;
    type SpaceData;

    fn draw<P: draw::AbstractPhase<D, Self::SpaceData, Self::Entity> + ?Sized>(
            &mut self, &mut P, &Camera<Self::Scalar>, &gfx::Frame<D::Resources>,
            &mut gfx::Renderer<D::CommandBuffer>) -> Result<(), DrawError>;
}

pub struct Entity<R: gfx::Resources, M> {
    material: M,
    mesh: gfx::Mesh<R>,
    slice: gfx::Slice<R>,
}

impl<R: gfx::Resources, M> draw::Entity<R, M> for Entity<R, M> {
    fn get_material(&self) -> &M {
        &self.material
    }
    fn get_mesh(&self) -> (&gfx::Mesh<R>, gfx::Slice<R>) {
        (&self.mesh, self.slice)
    }
}

/// A class that manages spatial relations between objects
pub trait World {
    type Scalar: cgmath::BaseFloat;
    type Transform: cgmath::Transform3<Self::Scalar>;
    type NodePtr;
    type SkeletonPtr;
    type Iter: Iterator<Item = Self::Transform>;

    fn get_transform(&self, Self::NodePtr) -> &Self::Transform;
    fn iter_bones(&self, Self::SkeletonPtr) -> Self::Iter;
}

pub struct Scene<R: gfx::Resources, M, W> {
    pub entities: Vec<Entity<R, M>>,
    pub world: W,
    context: gfx::batch::Context<R>,
}

pub struct SpaceData<S> {
    depth: S,
    _vertex_mx: Matrix4<S>,
    _normal_mx: Matrix3<S>,
}

impl<S: Copy + PartialOrd> draw::ToDepth for SpaceData<S> {
    type Depth = S;
    fn to_depth(&self) -> S {
        self.depth
    }
}

impl<
    D: gfx::Device,
    M: draw::Material,
    W: World,
> AbstractScene<D> for Scene<D::Resources, M, W> {
    type Scalar = W::Scalar;
    type Entity = Entity<D::Resources, M>;
    type SpaceData = SpaceData<W::Scalar>;

    fn draw<P: draw::AbstractPhase<D, SpaceData<W::Scalar>, Entity<D::Resources, M>> + ?Sized>(
            &mut self, phase: &mut P, _camera: &Camera<W::Scalar>,
            frame: &gfx::Frame<D::Resources>,
            renderer: &mut gfx::Renderer<D::CommandBuffer>)
            -> Result<(), DrawError> {
        for entity in self.entities.iter_mut() {
            if !phase.does_apply(entity) {
                 continue
            }
            //TODO: cull `ent.bounds` here
            //TODO: compute depth here
            let data = SpaceData {
                depth: Zero::zero(),
                _vertex_mx: Matrix4::identity(),
                _normal_mx: Matrix3::identity(),
            };
            match phase.enqueue(entity, data, &mut self.context) {
                Ok(()) => (),
                Err(e) => return Err(DrawError::Batch(e)),
            }
        }
        phase.flush(frame, &self.context, renderer)
             .map_err(|e| DrawError::Flush(e))
    }
}

/// Wrapper around a scene that carries a list of phases as well as the
/// `Renderer`, allowing to isolate a command buffer completely.
pub struct PhaseHarness<D: gfx::Device, C, P> {
    pub scene: C,
    pub phases: Vec<P>,
    pub renderer: gfx::Renderer<D::CommandBuffer>,
}

impl<
    D: gfx::Device,
    C: AbstractScene<D>,
    P: draw::AbstractPhase<D, C::SpaceData, C::Entity>
> PhaseHarness<D, C, P> {
    pub fn draw(&mut self, camera: &Camera<C::Scalar>,
                frame: &gfx::Frame<D::Resources>) -> Result<(), DrawError> {
        self.renderer.reset();
        for phase in self.phases.iter_mut() {
            match self.scene.draw(phase, camera, frame, &mut self.renderer) {
                Ok(_) => (),
                Err(e) => return Err(e),
            }
        }
        Ok(())
    }
}

/// A typical scene to be used in demoes. Has a heterogeneous vector of phases.
pub type StandardScene<
    D: gfx::Device,
    M: draw::Material,
    W: World,
> = PhaseHarness<
    D, Scene<D::Resources, M, W>,
    Box<draw::AbstractPhase<D, SpaceData<W::Scalar>, Entity<D::Resources, M>>>
>;
<commit_msg>Implemented the Camera<commit_after>extern crate draw;
extern crate gfx;
extern crate cgmath;

use cgmath::{BaseFloat, Zero, Matrix3, Matrix4, Transform3};

#[derive(Debug)]
pub enum DrawError {
    Batch(gfx::batch::BatchError),
    Flush(draw::FlushError),
}

pub trait AbstractScene<D: gfx::Device> {
    type SpaceData;
    type Entity;
    type Camera;

    fn draw<P: draw::AbstractPhase<D, Self::SpaceData, Self::Entity> + ?Sized>(
            &mut self, &mut P, &Self::Camera, &gfx::Frame<D::Resources>,
            &mut gfx::Renderer<D::CommandBuffer>) -> Result<(), DrawError>;
}

/// A class that manages spatial relations between objects
pub trait World {
    type Scalar: cgmath::BaseFloat;
    type Transform: cgmath::Transform3<Self::Scalar>;
    type NodePtr;
    type SkeletonPtr;
    type Iter: Iterator<Item = Self::Transform>;

    fn get_transform(&self, Self::NodePtr) -> &Self::Transform;
    fn iter_bones(&self, Self::SkeletonPtr) -> Self::Iter;
}

pub struct Entity<R: gfx::Resources, M, W: World> {
    pub name: String,
    pub material: M,
    mesh: gfx::Mesh<R>,
    slice: gfx::Slice<R>,
    node: W::NodePtr,
    skeleton: Option<W::SkeletonPtr>,
}

impl<R: gfx::Resources, M, W: World> draw::Entity<R, M> for Entity<R, M, W> {
    fn get_material(&self) -> &M {
        &self.material
    }
    fn get_mesh(&self) -> (&gfx::Mesh<R>, gfx::Slice<R>) {
        (&self.mesh, self.slice)
    }
}

pub struct Camera<P, N> {
    pub name: String,
    pub projection: P,
    pub node: N,
}

pub struct Scene<R: gfx::Resources, M, W: World, P> {
    pub entities: Vec<Entity<R, M, W>>,
    pub cameras: Vec<Camera<P, W::NodePtr>>,
    pub world: W,
    context: gfx::batch::Context<R>,
}

pub struct SpaceData<S> {
    depth: S,
    vertex_mx: Matrix4<S>,
    normal_mx: Matrix3<S>,
}

impl<S: Copy + PartialOrd> draw::ToDepth for SpaceData<S> {
    type Depth = S;
    fn to_depth(&self) -> S {
        self.depth
    }
}

impl<
    D: gfx::Device,
    M: draw::Material,
    W: World,
    P: cgmath::Projection<W::Scalar>,
> AbstractScene<D> for Scene<D::Resources, M, W, P> {
    type SpaceData = SpaceData<W::Scalar>;
    type Entity = Entity<D::Resources, M, W>;
    type Camera = Camera<P, W::NodePtr>;

    fn draw<H: draw::AbstractPhase<D, SpaceData<W::Scalar>, Entity<D::Resources, M, W>> + ?Sized>(
            &mut self, phase: &mut H, _camera: &Camera<P, W::NodePtr>,
            frame: &gfx::Frame<D::Resources>,
            renderer: &mut gfx::Renderer<D::CommandBuffer>)
            -> Result<(), DrawError> {
        for entity in self.entities.iter_mut() {
            if !phase.does_apply(entity) {
                 continue
            }
            //TODO: cull `ent.bounds` here
            //TODO: compute depth here
            let data = SpaceData {
                depth: Zero::zero(),
                vertex_mx: Matrix4::identity(),
                normal_mx: Matrix3::identity(),
            };
            match phase.enqueue(entity, data, &mut self.context) {
                Ok(()) => (),
                Err(e) => return Err(DrawError::Batch(e)),
            }
        }
        phase.flush(frame, &self.context, renderer)
             .map_err(|e| DrawError::Flush(e))
    }
}

/// Wrapper around a scene that carries a list of phases as well as the
/// `Renderer`, allowing to isolate a command buffer completely.
pub struct PhaseHarness<D: gfx::Device, C, P> {
    pub scene: C,
    pub phases: Vec<P>,
    pub renderer: gfx::Renderer<D::CommandBuffer>,
}

impl<
    D: gfx::Device,
    C: AbstractScene<D>,
    H: draw::AbstractPhase<D, C::SpaceData, C::Entity>
> PhaseHarness<D, C, H> {
    pub fn draw(&mut self, camera: &C::Camera, frame: &gfx::Frame<D::Resources>)
                -> Result<(), DrawError> {
        self.renderer.reset();
        for phase in self.phases.iter_mut() {
            match self.scene.draw(phase, camera, frame, &mut self.renderer) {
                Ok(_) => (),
                Err(e) => return Err(e),
            }
        }
        Ok(())
    }
}

pub type PerspectiveCam<W: World> = Camera<
    cgmath::PerspectiveFov<W::Scalar, cgmath::Rad<W::Scalar>>,
    W::NodePtr
>;

/// A typical scene to be used in demoes. Has a heterogeneous vector of phases
/// and a perspective fov-based camera.
pub type StandardScene<
    D: gfx::Device,
    M: draw::Material,
    W: World,
    P: cgmath::Projection<W::Scalar>,
> = PhaseHarness<D,
    Scene<D::Resources, M, W, P>,
    Box<draw::AbstractPhase<D, SpaceData<W::Scalar>, Entity<D::Resources, M, W>>>
>;
<|endoftext|>


<commit_before>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

use private::units::*;
use private::endian::WireValue;
use message::*;
use private::arena;
use io::{InputStream, OutputStream};
use {Error, Result, Word};

pub struct OwnedSpaceMessageReader {
    options : ReaderOptions,
    arena : Box<arena::ReaderArena>,
    segment_slices : Vec<(usize, usize)>,
    owned_space : Vec<Word>,
}

impl MessageReader for OwnedSpaceMessageReader {
    fn get_segment(&self, id : usize) -> &[Word] {
        let (a,b) = self.segment_slices[id];
        &self.owned_space[a .. b]
    }

    fn arena(&self) -> &arena::ReaderArena { &*self.arena }
    fn arena_mut(&mut self) -> &mut arena::ReaderArena { &mut *self.arena }

    fn get_options(&self) -> &ReaderOptions {
        return &self.options;
    }
}

pub fn new_reader<U : InputStream>(
    input_stream : &mut U,
    options : ReaderOptions) -> Result<OwnedSpaceMessageReader> {

    let mut first_word : [WireValue<u32>; 2] = unsafe {::std::mem::uninitialized()};
    unsafe {
        let ptr : *mut u8 = ::std::mem::transmute(first_word.as_mut_ptr());
        let buf = ::std::slice::from_raw_parts_mut::<u8>(ptr, 8);
        try!(input_stream.read_exact(buf));
    }

    let segment_count : u32 = first_word[0].get() + 1;

    let segment0_size = if segment_count == 0 { 0 } else { first_word[1].get() };

    let mut total_words = segment0_size;

    if segment_count >= 512 {
        return Err(Error::new_decode_error("Too many segments.", Some(format!("{}", segment_count))));
    }

    let more_sizes_len = (segment_count & !1) as usize;
    let mut more_sizes : Vec<WireValue<u32>> = Vec::with_capacity(more_sizes_len);
    unsafe { more_sizes.set_len(more_sizes_len); }

    if segment_count > 1 {
        unsafe {
            let ptr : *mut u8 = ::std::mem::transmute(more_sizes.as_mut_ptr());
            let buf = ::std::slice::from_raw_parts_mut::<u8>(ptr, more_sizes_len * 4);
            try!(input_stream.read_exact(buf));
        }
        for ii in 0..(segment_count as usize - 1) {
            total_words += more_sizes[ii].get();
        }
    }

    // Don't accept a message which the receiver couldn't possibly traverse without hitting the
    // traversal limit. Without this check, a malicious client could transmit a very large segment
    // size to make the receiver allocate excessive space and possibly crash.
    if ! (total_words as u64 <= options.traversal_limit_in_words)  {
        return Err(Error::new_decode_error(
            "Message is too large. To increase the limit on the \
             receiving end, see capnp::ReaderOptions.", None));
    }

    let mut owned_space : Vec<Word> = Word::allocate_zeroed_vec(total_words as usize);
    let buf_len = total_words as usize * BYTES_PER_WORD;

    unsafe {
        let ptr : *mut u8 = ::std::mem::transmute(owned_space.as_mut_ptr());
        let buf = ::std::slice::from_raw_parts_mut::<u8>(ptr, buf_len);
        try!(input_stream.read_exact(buf));
    }

    // TODO(maybe someday) lazy reading like in capnproto-c++?

    let mut segment_slices : Vec<(usize, usize)> = vec!((0, segment0_size as usize));

    let arena = {
        let segment0 : &[Word] = &owned_space[0 .. segment0_size as usize];
        let mut segments : Vec<&[Word]> = vec!(segment0);

        if segment_count > 1 {
            let mut offset = segment0_size;

            for ii in 0..(segment_count as usize - 1) {
                segments.push(&owned_space[offset as usize ..
                                           (offset + more_sizes[ii].get()) as usize]);
                segment_slices.push((offset as usize,
                                     (offset + more_sizes[ii].get()) as usize));
                offset += more_sizes[ii].get();
            }
        }
        arena::ReaderArena::new(&segments, options)
    };

    Ok(OwnedSpaceMessageReader {
        segment_slices : segment_slices,
        owned_space : owned_space,
        arena : arena,
        options : options,
    })
}

pub fn write_message<T : OutputStream, U : MessageBuilder>(
    output_stream : &mut T,
    message : &mut U) -> ::std::io::Result<()> {

    let segments = message.get_segments_for_output();
    let table_size : usize = (segments.len() + 2) & (!1);

    let mut table : Vec<WireValue<u32>> = Vec::with_capacity(table_size);
    unsafe { table.set_len(table_size) }

    table[0].set((segments.len() - 1) as u32);

    for i in 0..segments.len() {
        table[i + 1].set(segments[i].len() as u32);
    }
    if segments.len() % 2 == 0 {
        // Set padding.
        table[segments.len() + 1].set( 0 );
    }

    unsafe {
        let ptr : *const u8 = ::std::mem::transmute(table.as_ptr());
        let buf = ::std::slice::from_raw_parts::<u8>(ptr, table.len() * 4);
        try!(output_stream.write(buf));
    }

    for i in 0..segments.len() {
        unsafe {
            let ptr : *const u8 = ::std::mem::transmute(segments[i].as_ptr());
            let buf = ::std::slice::from_raw_parts::<u8>(ptr, segments[i].len() * BYTES_PER_WORD);
            try!(output_stream.write(buf));
        }
    }
    output_stream.flush()
}
<commit_msg>Implement a function to compute the serialized size of a message<commit_after>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

use private::units::*;
use private::endian::WireValue;
use message::*;
use private::arena;
use io::{InputStream, OutputStream};
use {Error, Result, Word};

pub struct OwnedSpaceMessageReader {
    options : ReaderOptions,
    arena : Box<arena::ReaderArena>,
    segment_slices : Vec<(usize, usize)>,
    owned_space : Vec<Word>,
}

impl MessageReader for OwnedSpaceMessageReader {
    fn get_segment(&self, id : usize) -> &[Word] {
        let (a,b) = self.segment_slices[id];
        &self.owned_space[a .. b]
    }

    fn arena(&self) -> &arena::ReaderArena { &*self.arena }
    fn arena_mut(&mut self) -> &mut arena::ReaderArena { &mut *self.arena }

    fn get_options(&self) -> &ReaderOptions {
        return &self.options;
    }
}

pub fn new_reader<U : InputStream>(
    input_stream : &mut U,
    options : ReaderOptions) -> Result<OwnedSpaceMessageReader> {

    let mut first_word : [WireValue<u32>; 2] = unsafe {::std::mem::uninitialized()};
    unsafe {
        let ptr : *mut u8 = ::std::mem::transmute(first_word.as_mut_ptr());
        let buf = ::std::slice::from_raw_parts_mut::<u8>(ptr, 8);
        try!(input_stream.read_exact(buf));
    }

    let segment_count : u32 = first_word[0].get() + 1;

    let segment0_size = if segment_count == 0 { 0 } else { first_word[1].get() };

    let mut total_words = segment0_size;

    if segment_count >= 512 {
        return Err(Error::new_decode_error("Too many segments.", Some(format!("{}", segment_count))));
    }

    let more_sizes_len = (segment_count & !1) as usize;
    let mut more_sizes : Vec<WireValue<u32>> = Vec::with_capacity(more_sizes_len);
    unsafe { more_sizes.set_len(more_sizes_len); }

    if segment_count > 1 {
        unsafe {
            let ptr : *mut u8 = ::std::mem::transmute(more_sizes.as_mut_ptr());
            let buf = ::std::slice::from_raw_parts_mut::<u8>(ptr, more_sizes_len * 4);
            try!(input_stream.read_exact(buf));
        }
        for ii in 0..(segment_count as usize - 1) {
            total_words += more_sizes[ii].get();
        }
    }

    // Don't accept a message which the receiver couldn't possibly traverse without hitting the
    // traversal limit. Without this check, a malicious client could transmit a very large segment
    // size to make the receiver allocate excessive space and possibly crash.
    if ! (total_words as u64 <= options.traversal_limit_in_words)  {
        return Err(Error::new_decode_error(
            "Message is too large. To increase the limit on the \
             receiving end, see capnp::ReaderOptions.", None));
    }

    let mut owned_space : Vec<Word> = Word::allocate_zeroed_vec(total_words as usize);
    let buf_len = total_words as usize * BYTES_PER_WORD;

    unsafe {
        let ptr : *mut u8 = ::std::mem::transmute(owned_space.as_mut_ptr());
        let buf = ::std::slice::from_raw_parts_mut::<u8>(ptr, buf_len);
        try!(input_stream.read_exact(buf));
    }

    // TODO(maybe someday) lazy reading like in capnproto-c++?

    let mut segment_slices : Vec<(usize, usize)> = vec!((0, segment0_size as usize));

    let arena = {
        let segment0 : &[Word] = &owned_space[0 .. segment0_size as usize];
        let mut segments : Vec<&[Word]> = vec!(segment0);

        if segment_count > 1 {
            let mut offset = segment0_size;

            for ii in 0..(segment_count as usize - 1) {
                segments.push(&owned_space[offset as usize ..
                                           (offset + more_sizes[ii].get()) as usize]);
                segment_slices.push((offset as usize,
                                     (offset + more_sizes[ii].get()) as usize));
                offset += more_sizes[ii].get();
            }
        }
        arena::ReaderArena::new(&segments, options)
    };

    Ok(OwnedSpaceMessageReader {
        segment_slices : segment_slices,
        owned_space : owned_space,
        arena : arena,
        options : options,
    })
}

pub fn write_message<T : OutputStream, U : MessageBuilder>(
    output_stream : &mut T,
    message : &mut U) -> ::std::io::Result<()> {

    let segments = message.get_segments_for_output();
    let table_size : usize = (segments.len() + 2) & (!1);

    let mut table : Vec<WireValue<u32>> = Vec::with_capacity(table_size);
    unsafe { table.set_len(table_size) }

    table[0].set((segments.len() - 1) as u32);

    for i in 0..segments.len() {
        table[i + 1].set(segments[i].len() as u32);
    }
    if segments.len() % 2 == 0 {
        // Set padding.
        table[segments.len() + 1].set( 0 );
    }

    unsafe {
        let ptr : *const u8 = ::std::mem::transmute(table.as_ptr());
        let buf = ::std::slice::from_raw_parts::<u8>(ptr, table.len() * 4);
        try!(output_stream.write(buf));
    }

    for i in 0..segments.len() {
        unsafe {
            let ptr : *const u8 = ::std::mem::transmute(segments[i].as_ptr());
            let buf = ::std::slice::from_raw_parts::<u8>(ptr, segments[i].len() * BYTES_PER_WORD);
            try!(output_stream.write(buf));
        }
    }
    output_stream.flush()
}

pub fn compute_serialized_size_in_words<U : MessageBuilder>(message: &mut U) -> usize {
    let segments = message.get_segments_for_output();

    // Table size
    let mut size = (segments.len() / 2) + 1;

    for segment in segments {
        size += segment.len();
    }

    size
}
<|endoftext|>