1
use ron::error::{Error, Position, SpannedError};
2

            
3
104
#[derive(Debug, serde::Deserialize, PartialEq)]
4
#[serde(deny_unknown_fields)]
5
enum TestEnum {
6
    StructVariant { a: bool, b: char, c: i32 },
7
    NewtypeVariant(TestStruct),
8
}
9

            
10
8
#[derive(Debug, serde::Deserialize, PartialEq)]
11
#[serde(tag = "type")]
12
enum TestEnumInternal {
13
    StructVariant { a: bool },
14
}
15

            
16
20
#[derive(Debug, serde::Deserialize, PartialEq)]
17
#[serde(tag = "type", content = "content")]
18
enum TestEnumAdjacent {
19
    StructVariant { a: bool },
20
}
21

            
22
12
#[derive(Debug, serde::Deserialize, PartialEq)]
23
#[serde(untagged)]
24
enum TestEnumUntagged {
25
    StructVariant { a: bool },
26
}
27

            
28
96
#[derive(Debug, serde::Deserialize, PartialEq)]
29
#[serde(deny_unknown_fields)]
30
struct TestStruct {
31
    a: bool,
32
    b: char,
33
    c: i32,
34
}
35

            
36
#[test]
37
4
fn test_unknown_enum_variant() {
38
4
    assert_eq!(
39
4
        ron::from_str::<TestEnum>("NotAVariant"),
40
4
        Err(SpannedError {
41
4
            code: Error::NoSuchEnumVariant {
42
4
                expected: &["StructVariant", "NewtypeVariant"],
43
4
                found: String::from("NotAVariant"),
44
4
                outer: Some(String::from("TestEnum")),
45
4
            },
46
4
            position: Position { line: 1, col: 12 },
47
4
        })
48
4
    );
49
4
}
50

            
51
#[test]
52
4
fn test_struct_enum_fields() {
53
4
    assert_eq!(
54
4
        ron::from_str::<TestEnum>("StructVariant(a: true, b: 'b', c: -42, d: \"gotcha\")"),
55
4
        Err(SpannedError {
56
4
            code: Error::NoSuchStructField {
57
4
                expected: &["a", "b", "c"],
58
4
                found: String::from("d"),
59
4
                outer: Some(String::from("StructVariant")),
60
4
            },
61
4
            position: Position { line: 1, col: 41 },
62
4
        })
63
4
    );
64

            
65
4
    assert_eq!(
66
4
        ron::from_str::<TestEnum>("StructVariant(a: true, c: -42)"),
67
4
        Err(SpannedError {
68
4
            code: Error::MissingStructField {
69
4
                field: "b",
70
4
                outer: Some(String::from("StructVariant")),
71
4
            },
72
4
            position: Position { line: 1, col: 30 },
73
4
        })
74
4
    );
75

            
76
4
    assert_eq!(
77
4
        ron::from_str::<TestEnum>("StructVariant(a: true, b: 'b', a: false, c: -42)"),
78
4
        Err(SpannedError {
79
4
            code: Error::DuplicateStructField {
80
4
                field: "a",
81
4
                outer: Some(String::from("StructVariant")),
82
4
            },
83
4
            position: Position { line: 1, col: 33 },
84
4
        })
85
4
    );
86
4
}
87

            
88
#[test]
89
4
fn test_newtype_enum_fields() {
90
4
    assert_eq!(
91
4
        ron::from_str::<TestEnum>("#![enable(unwrap_variant_newtypes)] NewtypeVariant(a: true, b: 'b', c: -42, d: \"gotcha\")"),
92
4
        Err(SpannedError {
93
4
            code: Error::NoSuchStructField {
94
4
                expected: &["a", "b", "c"],
95
4
                found: String::from("d"),
96
4
                outer: Some(String::from("NewtypeVariant")),
97
4
            },
98
4
            position: Position { line: 1, col: 78 },
99
4
        })
100
4
    );
101

            
102
4
    assert_eq!(
103
4
        ron::from_str::<TestEnum>(
104
4
            "#![enable(unwrap_variant_newtypes)] NewtypeVariant(a: true, c: -42)"
105
4
        ),
106
4
        Err(SpannedError {
107
4
            code: Error::MissingStructField {
108
4
                field: "b",
109
4
                outer: Some(String::from("NewtypeVariant")),
110
4
            },
111
4
            position: Position { line: 1, col: 67 },
112
4
        })
113
4
    );
114

            
115
4
    assert_eq!(
116
4
        ron::from_str::<TestEnum>(
117
4
            "#![enable(unwrap_variant_newtypes)] NewtypeVariant(a: true, b: 'b', a: false, c: -42)"
118
4
        ),
119
4
        Err(SpannedError {
120
4
            code: Error::DuplicateStructField {
121
4
                field: "a",
122
4
                outer: Some(String::from("NewtypeVariant")),
123
4
            },
124
4
            position: Position { line: 1, col: 70 },
125
4
        })
126
4
    );
127
4
}
128

            
129
#[test]
130
4
fn test_struct_fields() {
131
4
    assert_eq!(
132
4
        ron::from_str::<TestStruct>("TestStruct(a: true, b: 'b', c: -42, d: \"gotcha\")"),
133
4
        Err(SpannedError {
134
4
            code: Error::NoSuchStructField {
135
4
                expected: &["a", "b", "c"],
136
4
                found: String::from("d"),
137
4
                outer: Some(String::from("TestStruct")),
138
4
            },
139
4
            position: Position { line: 1, col: 38 },
140
4
        })
141
4
    );
142

            
143
4
    assert_eq!(
144
4
        ron::from_str::<TestStruct>("TestStruct(a: true, c: -42)"),
145
4
        Err(SpannedError {
146
4
            code: Error::MissingStructField {
147
4
                field: "b",
148
4
                outer: Some(String::from("TestStruct")),
149
4
            },
150
4
            position: Position { line: 1, col: 27 },
151
4
        })
152
4
    );
153

            
154
4
    assert_eq!(
155
4
        ron::from_str::<TestStruct>("TestStruct(a: true, b: 'b', a: false, c: -42)"),
156
4
        Err(SpannedError {
157
4
            code: Error::DuplicateStructField {
158
4
                field: "a",
159
4
                outer: Some(String::from("TestStruct")),
160
4
            },
161
4
            position: Position { line: 1, col: 30 },
162
4
        })
163
4
    );
164
4
}
165

            
166
#[test]
167
4
fn test_internally_tagged_enum() {
168
4
    // Note: Not extracting the variant type is not great,
169
4
    //        but at least not wrong either
170
4
    //       Since the error occurs in serde-generated user code,
171
4
    //        after successfully deserialising, we cannot annotate
172
4

            
173
4
    assert_eq!(
174
4
        ron::from_str::<TestEnumInternal>("(type: \"StructVariant\")"),
175
4
        Err(SpannedError {
176
4
            code: Error::MissingStructField {
177
4
                field: "a",
178
4
                outer: None,
179
4
            },
180
4
            position: Position { line: 1, col: 24 },
181
4
        })
182
4
    );
183
4
}
184

            
185
#[test]
186
4
fn test_adjacently_tagged_enum() {
187
4
    // Note: TestEnumAdjacent makes sense here since we are now treating
188
4
    //        the enum as a struct
189
4

            
190
4
    assert_eq!(
191
4
        ron::from_str::<TestEnumAdjacent>("(type: StructVariant, content: (d: 4))"),
192
4
        Err(SpannedError {
193
4
            code: Error::MissingStructField {
194
4
                field: "a",
195
4
                outer: Some(String::from("TestEnumAdjacent")),
196
4
            },
197
4
            position: Position { line: 1, col: 37 },
198
4
        })
199
4
    );
200
4
}
201

            
202
#[test]
203
4
fn test_untagged_enum() {
204
4
    // Note: Errors inside untagged enums are not bubbled up
205
4

            
206
4
    assert_eq!(
207
4
        ron::from_str::<TestEnumUntagged>("(a: true, a: false)"),
208
4
        Err(SpannedError {
209
4
            code: Error::Message(String::from(
210
4
                "data did not match any variant of untagged enum TestEnumUntagged"
211
4
            )),
212
4
            position: Position { line: 1, col: 20 },
213
4
        })
214
4
    );
215
4
}