1
use ron::{
2
    extensions::Extensions,
3
    from_str,
4
    ser::{to_string_pretty, PrettyConfig},
5
    Error, Options,
6
};
7
use serde_derive::{Deserialize, Serialize};
8

            
9
24
#[derive(Debug, PartialEq, Serialize, Deserialize)]
10
struct Id(u32);
11

            
12
16
#[derive(Debug, PartialEq, Serialize, Deserialize)]
13
struct Position(f32, f32);
14

            
15
32
#[derive(Debug, PartialEq, Serialize, Deserialize)]
16
enum Query {
17
    None,
18
    Creature(Id),
19
    Location(Position),
20
}
21

            
22
88
#[derive(Debug, PartialEq, Serialize, Deserialize)]
23
struct Foo {
24
    #[allow(unused)]
25
    pub id: Id,
26
    #[allow(unused)]
27
    pub position: Position,
28
    #[allow(unused)]
29
    pub query: Query,
30
}
31

            
32
const EXPECT_ERROR_MESSAGE: &'static str =
33
    "expected `Err(Error::ExpectedStructName)`, deserializer returned `Ok`";
34

            
35
#[test]
36
4
fn explicit_struct_names() {
37
4
    let options = Options::default().with_default_extension(Extensions::EXPLICIT_STRUCT_NAMES);
38
4
    let foo_ser = Foo {
39
4
        id: Id(3),
40
4
        position: Position(0.0, 8.72),
41
4
        query: Query::Creature(Id(4)),
42
4
    };
43
4

            
44
4
    // phase 1 (regular structs)
45
4
    let content_regular = r#"(
46
4
        id: Id(3),
47
4
        position: Position(0.0, 8.72),
48
4
        query: None,
49
4
    )"#;
50
4
    let foo = options.from_str::<Foo>(content_regular);
51
4
    assert_eq!(
52
4
        foo.expect_err(EXPECT_ERROR_MESSAGE).code,
53
4
        Error::ExpectedStructName("Foo".to_string())
54
4
    );
55

            
56
    // phase 2 (newtype structs)
57
4
    let content_newtype = r#"Foo(
58
4
        id: (3),
59
4
        position: Position(0.0, 8.72),
60
4
        query: None,
61
4
    )"#;
62
4
    let foo = options.from_str::<Foo>(content_newtype);
63
4
    assert_eq!(
64
4
        foo.expect_err(EXPECT_ERROR_MESSAGE).code,
65
4
        Error::ExpectedStructName("Id".to_string())
66
4
    );
67

            
68
    // phase 3 (tuple structs)
69
4
    let content_tuple = r#"Foo(
70
4
        id: Id(3),
71
4
        position: (0.0, 8.72),
72
4
        query: None,
73
4
    )"#;
74
4
    let foo = options.from_str::<Foo>(content_tuple);
75
4
    assert_eq!(
76
4
        foo.expect_err(EXPECT_ERROR_MESSAGE).code,
77
4
        Error::ExpectedStructName("Position".to_string())
78
4
    );
79

            
80
    // phase 4 (test without this extension)
81
4
    let _foo1 = from_str::<Foo>(content_regular).unwrap();
82
4
    let _foo2 = from_str::<Foo>(content_newtype).unwrap();
83
4
    let _foo3 = from_str::<Foo>(content_tuple).unwrap();
84
4

            
85
4
    // phase 5 (test serialization)
86
4
    let pretty_config = PrettyConfig::new()
87
4
        .extensions(Extensions::EXPLICIT_STRUCT_NAMES | Extensions::UNWRAP_VARIANT_NEWTYPES);
88
4
    let content = to_string_pretty(&foo_ser, pretty_config).unwrap();
89
4
    assert_eq!(
90
4
        content,
91
4
        r#"#![enable(unwrap_variant_newtypes)]
92
4
#![enable(explicit_struct_names)]
93
4
Foo(
94
4
    id: Id(3),
95
4
    position: Position(0.0, 8.72),
96
4
    query: Creature(4),
97
4
)"#
98
4
    );
99
4
    let foo_de = from_str::<Foo>(&content);
100
4
    match foo_de {
101
        // GRCOV_EXCL_START
102
        Err(err) => panic!(
103
            "failed to deserialize with `explicit_struct_names` and `unwrap_variant_newtypes`: {}",
104
            err
105
        ),
106
        // GRCOV_EXCL_STOP
107
4
        Ok(foo_de) => assert_eq!(foo_de, foo_ser),
108
    }
109
4
}