1
use ron::error::{Position, Span, SpannedError};
2
use serde::{Deserialize, Serialize};
3

            
4
#[derive(Serialize, Deserialize, Debug)]
5
#[serde(rename = "Hello World")]
6
struct InvalidStruct;
7

            
8
#[derive(Serialize, Deserialize, Debug)]
9
#[serde(rename = "")]
10
struct EmptyStruct;
11

            
12
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
13
#[serde(rename = "Hello+World")]
14
#[serde(deny_unknown_fields)]
15
struct RawStruct {
16
    #[serde(rename = "ab.cd-ef")]
17
    field: bool,
18
    really_not_raw: i32,
19
}
20

            
21
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
22
enum RawEnum {
23
    #[serde(rename = "Hello-World")]
24
    RawVariant,
25
}
26

            
27
#[test]
28
4
fn test_invalid_identifiers() {
29
4
    let ser = ron::ser::to_string_pretty(
30
4
        &InvalidStruct,
31
4
        ron::ser::PrettyConfig::default().struct_names(true),
32
    );
33
4
    assert_eq!(
34
        ser,
35
4
        Err(ron::Error::InvalidIdentifier(String::from("Hello World")))
36
    );
37

            
38
4
    let ser = ron::ser::to_string_pretty(
39
4
        &EmptyStruct,
40
4
        ron::ser::PrettyConfig::default().struct_names(true),
41
    );
42
4
    assert_eq!(ser, Err(ron::Error::InvalidIdentifier(String::from(""))));
43

            
44
4
    let de = ron::from_str::<InvalidStruct>("Hello World").unwrap_err();
45
4
    assert_eq!(
46
        de,
47
4
        SpannedError {
48
4
            code: ron::Error::ExpectedDifferentStructName {
49
4
                expected: "Hello World",
50
4
                found: String::from("Hello"),
51
4
            },
52
4
            span: Span {
53
4
                start: Position { line: 1, col: 1 },
54
4
                end: Position { line: 1, col: 6 },
55
4
            }
56
4
        }
57
    );
58

            
59
4
    let de = ron::from_str::<EmptyStruct>("").unwrap_err();
60
4
    assert_eq!(
61
        de,
62
        SpannedError {
63
            code: ron::Error::ExpectedUnit,
64
            span: Span {
65
                start: Position { line: 1, col: 1 },
66
                end: Position { line: 1, col: 1 },
67
            }
68
        }
69
    );
70

            
71
4
    let de = ron::from_str::<EmptyStruct>("r#").unwrap_err();
72
4
    assert_eq!(
73
4
        format!("{}", de),
74
        "1:1: Expected only opening `(`, no name, for un-nameable struct"
75
    );
76

            
77
4
    let de = ron::from_str::<RawStruct>("").unwrap_err();
78
4
    assert_eq!(
79
        de,
80
        SpannedError {
81
            code: ron::Error::ExpectedNamedStructLike("Hello+World"),
82
            span: Span {
83
                start: Position { line: 1, col: 1 },
84
                end: Position { line: 1, col: 1 },
85
            }
86
        },
87
    );
88

            
89
4
    let de = ron::from_str::<RawStruct>("r#").unwrap_err();
90
4
    assert_eq!(
91
        de,
92
        SpannedError {
93
            code: ron::Error::ExpectedNamedStructLike("Hello+World"),
94
            span: Span {
95
                start: Position { line: 1, col: 1 },
96
                end: Position { line: 1, col: 1 },
97
            }
98
        },
99
    );
100

            
101
4
    let de = ron::from_str::<RawStruct>("Hello+World").unwrap_err();
102
4
    assert_eq!(
103
        de,
104
4
        SpannedError {
105
4
            code: ron::Error::SuggestRawIdentifier(String::from("Hello+World")),
106
4
            span: Span {
107
4
                start: Position { line: 1, col: 1 },
108
4
                end: Position { line: 1, col: 1 },
109
4
            }
110
4
        }
111
    );
112

            
113
4
    let de = ron::from_str::<RawStruct>(
114
4
        "r#Hello+World(
115
4
        ab.cd-ef: true,
116
4
    )",
117
    )
118
4
    .unwrap_err();
119
4
    assert_eq!(
120
        de,
121
4
        SpannedError {
122
4
            code: ron::Error::SuggestRawIdentifier(String::from("ab.cd-ef")),
123
4
            span: Span {
124
4
                start: Position { line: 1, col: 15 },
125
4
                end: Position { line: 2, col: 9 },
126
4
            }
127
4
        }
128
    );
129

            
130
4
    let de = ron::from_str::<RawStruct>(
131
4
        "r#Hello+World(
132
4
        rab.cd-ef: true,
133
4
    )",
134
    )
135
4
    .unwrap_err();
136
4
    assert_eq!(
137
        de,
138
4
        SpannedError {
139
4
            code: ron::Error::SuggestRawIdentifier(String::from("rab.cd-ef")),
140
4
            span: Span {
141
4
                start: Position { line: 1, col: 15 },
142
4
                end: Position { line: 2, col: 9 },
143
4
            }
144
4
        }
145
    );
146

            
147
4
    let de = ron::from_str::<RawStruct>(
148
4
        "r#Hello+World(
149
4
        r#ab.cd+ef: true,
150
4
    )",
151
    )
152
4
    .unwrap_err();
153
4
    assert_eq!(
154
        de,
155
4
        SpannedError {
156
4
            code: ron::Error::NoSuchStructField {
157
4
                expected: &["ab.cd-ef", "really_not_raw"],
158
4
                found: String::from("ab.cd+ef"),
159
4
                outer: Some(String::from("Hello+World")),
160
4
            },
161
4
            span: Span {
162
4
                start: Position { line: 2, col: 11 },
163
4
                end: Position { line: 2, col: 19 },
164
4
            }
165
4
        }
166
    );
167

            
168
4
    let de = ron::from_str::<RawEnum>("Hello-World").unwrap_err();
169
4
    assert_eq!(
170
        de,
171
4
        SpannedError {
172
4
            code: ron::Error::SuggestRawIdentifier(String::from("Hello-World")),
173
4
            span: Span {
174
4
                start: Position { line: 1, col: 1 },
175
4
                end: Position { line: 1, col: 1 },
176
4
            }
177
4
        }
178
    );
179

            
180
4
    let de = ron::from_str::<RawEnum>("r#Hello+World").unwrap_err();
181
4
    assert_eq!(
182
        de,
183
4
        SpannedError {
184
4
            code: ron::Error::NoSuchEnumVariant {
185
4
                expected: &["Hello-World"],
186
4
                found: String::from("Hello+World"),
187
4
                outer: Some(String::from("RawEnum")),
188
4
            },
189
4
            span: Span {
190
4
                start: Position { line: 1, col: 3 },
191
4
                end: Position { line: 1, col: 14 },
192
4
            }
193
4
        }
194
    );
195

            
196
4
    let de = ron::from_str::<EmptyStruct>("r#+").unwrap_err();
197
4
    assert_eq!(
198
4
        format!("{}", de),
199
        r#"1:3-1:4: Expected only opening `(`, no name, for un-nameable struct"#,
200
    );
201
4
}
202

            
203
#[test]
204
4
fn test_raw_identifier_roundtrip() {
205
4
    let val = RawStruct {
206
4
        field: true,
207
4
        really_not_raw: 42,
208
4
    };
209

            
210
4
    let ser =
211
4
        ron::ser::to_string_pretty(&val, ron::ser::PrettyConfig::default().struct_names(true))
212
4
            .unwrap();
213
4
    assert_eq!(
214
        ser,
215
        "r#Hello+World(\n    r#ab.cd-ef: true,\n    really_not_raw: 42,\n)"
216
    );
217

            
218
4
    let de: RawStruct = ron::from_str(&ser).unwrap();
219
4
    assert_eq!(de, val);
220

            
221
4
    let val = RawEnum::RawVariant;
222

            
223
4
    let ser = ron::ser::to_string(&val).unwrap();
224
4
    assert_eq!(ser, "r#Hello-World");
225

            
226
4
    let de: RawEnum = ron::from_str(&ser).unwrap();
227
4
    assert_eq!(de, val);
228
4
}