1
use serde_derive::Serialize;
2

            
3
use crate::Number;
4

            
5
#[derive(Serialize)]
6
struct EmptyStruct1;
7

            
8
#[derive(Serialize)]
9
struct EmptyStruct2 {}
10

            
11
#[derive(Serialize)]
12
struct NewType(i32);
13

            
14
#[derive(Serialize)]
15
struct TupleStruct(f32, f32);
16

            
17
#[derive(Serialize)]
18
struct MyStruct {
19
    x: f32,
20
    y: f32,
21
}
22

            
23
#[derive(Serialize)]
24
enum MyEnum {
25
    A,
26
    B(bool),
27
    C(bool, f32),
28
    D { a: i32, b: i32 },
29
}
30

            
31
#[test]
32
4
fn test_empty_struct() {
33
4
    check_to_string_writer(&EmptyStruct1, "()", "EmptyStruct1");
34
4
    check_to_string_writer(&EmptyStruct2 {}, "()", "EmptyStruct2()");
35
4
}
36

            
37
#[test]
38
4
fn test_struct() {
39
4
    let my_struct = MyStruct { x: 4.0, y: 7.0 };
40
4

            
41
4
    check_to_string_writer(&my_struct, "(x:4.0,y:7.0)", "MyStruct(x: 4.0, y: 7.0)");
42
4

            
43
4
    check_to_string_writer(&NewType(42), "(42)", "NewType(42)");
44
4

            
45
4
    check_to_string_writer(&TupleStruct(2.0, 5.0), "(2.0,5.0)", "TupleStruct(2.0, 5.0)");
46
4
}
47

            
48
#[test]
49
4
fn test_option() {
50
4
    check_to_string_writer(&Some(1u8), "Some(1)", "Some(1)");
51
4
    check_to_string_writer(&None::<u8>, "None", "None");
52
4
}
53

            
54
#[test]
55
4
fn test_enum() {
56
4
    check_to_string_writer(&MyEnum::A, "A", "A");
57
4
    check_to_string_writer(&MyEnum::B(true), "B(true)", "B(true)");
58
4
    check_to_string_writer(&MyEnum::C(true, 3.5), "C(true,3.5)", "C(true, 3.5)");
59
4
    check_to_string_writer(&MyEnum::D { a: 2, b: 3 }, "D(a:2,b:3)", "D(a: 2, b: 3)");
60
4
}
61

            
62
#[test]
63
4
fn test_array() {
64
4
    let empty: [i32; 0] = [];
65
4
    check_to_string_writer(&empty, "()", "()");
66
4
    let empty_ref: &[i32] = &empty;
67
4
    check_to_string_writer(&empty_ref, "[]", "[]");
68
4

            
69
4
    check_to_string_writer(&[2, 3, 4i32], "(2,3,4)", "(2, 3, 4)");
70
4
    check_to_string_writer(
71
4
        &(&[2, 3, 4i32] as &[i32]),
72
4
        "[2,3,4]",
73
4
        "[\n    2,\n    3,\n    4,\n]",
74
4
    );
75
4
}
76

            
77
#[test]
78
4
fn test_slice() {
79
4
    check_to_string_writer(
80
4
        &[0, 1, 2, 3, 4, 5][..],
81
4
        "[0,1,2,3,4,5]",
82
4
        "[\n    0,\n    1,\n    2,\n    3,\n    4,\n    5,\n]",
83
4
    );
84
4
    check_to_string_writer(
85
4
        &[0, 1, 2, 3, 4, 5][1..4],
86
4
        "[1,2,3]",
87
4
        "[\n    1,\n    2,\n    3,\n]",
88
4
    );
89
4
}
90

            
91
#[test]
92
4
fn test_vec() {
93
4
    check_to_string_writer(
94
4
        &vec![0, 1, 2, 3, 4, 5],
95
4
        "[0,1,2,3,4,5]",
96
4
        "[\n    0,\n    1,\n    2,\n    3,\n    4,\n    5,\n]",
97
4
    );
98
4
}
99

            
100
#[test]
101
4
fn test_map() {
102
    use std::collections::BTreeMap;
103

            
104
4
    let mut map = BTreeMap::new();
105
4
    map.insert((true, false), 4);
106
4
    map.insert((false, false), 123);
107
4

            
108
4
    check_to_string_writer(
109
4
        &map,
110
4
        "{(false,false):123,(true,false):4}",
111
4
        "{\n    (false, false): 123,\n    (true, false): 4,\n}",
112
4
    );
113
4
}
114

            
115
#[test]
116
4
fn test_string() {
117
4
    check_to_string_writer(&"Some string", "\"Some string\"", "\"Some string\"");
118
4
}
119

            
120
#[test]
121
4
fn test_char() {
122
4
    check_to_string_writer(&'c', "'c'", "'c'");
123
4
}
124

            
125
#[test]
126
4
fn test_escape() {
127
4
    check_to_string_writer(&r#""Quoted""#, r#""\"Quoted\"""#, r#""\"Quoted\"""#);
128
4
}
129

            
130
#[test]
131
4
fn test_byte_stream() {
132
    use serde_bytes;
133

            
134
4
    let small: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
135
4
    check_to_string_writer(
136
4
        &small,
137
4
        "(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)",
138
4
        "(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)",
139
4
    );
140
4

            
141
4
    let large = vec![0x01, 0x02, 0x03, 0x04];
142
4
    let large = serde_bytes::Bytes::new(&large);
143
4
    check_to_string_writer(
144
4
        &large,
145
4
        "b\"\\x01\\x02\\x03\\x04\"",
146
4
        "b\"\\x01\\x02\\x03\\x04\"",
147
4
    );
148
4

            
149
4
    let large = vec![0x01, 0x02, 0x03, 0x04, 0x05, 0x06];
150
4
    let large = serde_bytes::Bytes::new(&large);
151
4
    check_to_string_writer(
152
4
        &large,
153
4
        "b\"\\x01\\x02\\x03\\x04\\x05\\x06\"",
154
4
        "b\"\\x01\\x02\\x03\\x04\\x05\\x06\"",
155
4
    );
156
4

            
157
4
    let large = vec![255u8; 64];
158
4
    let large = serde_bytes::Bytes::new(&large);
159
4
    check_to_string_writer(
160
4
        &large,
161
4
        concat!(
162
4
            "b\"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff",
163
4
            "\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff",
164
4
            "\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff",
165
4
            "\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff",
166
4
            "\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\""
167
4
        ),
168
4
        concat!(
169
4
            "b\"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff",
170
4
            "\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff",
171
4
            "\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff",
172
4
            "\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff",
173
4
            "\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\""
174
4
        ),
175
4
    );
176
4
}
177

            
178
#[test]
179
4
fn rename() {
180
    #[derive(Serialize, Debug, PartialEq)]
181
    enum Foo {
182
        #[serde(rename = "2d")]
183
        D2,
184
        #[serde(rename = "triangle-list")]
185
        TriangleList,
186
    }
187

            
188
4
    check_to_string_writer(&Foo::D2, "r#2d", "r#2d");
189
4
    check_to_string_writer(&Foo::TriangleList, "r#triangle-list", "r#triangle-list");
190
4
}
191

            
192
#[test]
193
4
fn test_any_number_precision() {
194
4
    check_ser_any_number(1_u8);
195
4
    check_ser_any_number(-1_i8);
196
4
    check_ser_any_number(1_f32);
197
4
    check_ser_any_number(-1_f32);
198
4
    check_ser_any_number(0.3_f64);
199
4

            
200
4
    check_to_string_writer(&Number::new(f32::NAN), "NaN", "NaN");
201
4
    check_to_string_writer(&f32::NAN, "NaN", "NaN");
202
4
    check_to_string_writer(&Number::new(-f32::NAN), "-NaN", "-NaN");
203
4
    check_to_string_writer(&(-f32::NAN), "-NaN", "-NaN");
204
4
    check_to_string_writer(&Number::new(f32::INFINITY), "inf", "inf");
205
4
    check_to_string_writer(&f32::INFINITY, "inf", "inf");
206
4
    check_to_string_writer(&Number::new(f32::NEG_INFINITY), "-inf", "-inf");
207
4
    check_to_string_writer(&f32::NEG_INFINITY, "-inf", "-inf");
208

            
209
    macro_rules! test_min_max {
210
        ($ty:ty) => {
211
            check_ser_any_number(<$ty>::MIN);
212
            check_ser_any_number(<$ty>::MAX);
213
        };
214
        ($($ty:ty),*) => {
215
            $(test_min_max! { $ty })*
216
        };
217
    }
218

            
219
4
    test_min_max! { i8, i16, i32, i64, u8, u16, u32, u64, f32, f64 }
220
4
    #[cfg(feature = "integer128")]
221
4
    test_min_max! { i128, u128 }
222
4
}
223

            
224
108
fn check_ser_any_number<T: Copy + Into<Number> + std::fmt::Display + serde::Serialize>(n: T) {
225
108
    let mut fmt = format!("{}", n);
226
108
    if !fmt.contains('.') && std::any::type_name::<T>().contains('f') {
227
24
        fmt.push_str(".0");
228
84
    }
229

            
230
108
    check_to_string_writer(&n.into(), &fmt, &fmt);
231
108
    check_to_string_writer(&n, &fmt, &fmt);
232
108
}
233

            
234
#[test]
235
4
fn recursion_limit() {
236
4
    assert_eq!(
237
4
        crate::Options::default()
238
4
            .with_recursion_limit(0)
239
4
            .to_string(&[42]),
240
4
        Err(crate::Error::ExceededRecursionLimit),
241
4
    );
242
4
    assert_eq!(
243
4
        crate::Options::default()
244
4
            .with_recursion_limit(1)
245
4
            .to_string(&[42])
246
4
            .as_deref(),
247
4
        Ok("(42)"),
248
4
    );
249
4
    assert_eq!(
250
4
        crate::Options::default()
251
4
            .without_recursion_limit()
252
4
            .to_string(&[42])
253
4
            .as_deref(),
254
4
        Ok("(42)"),
255
4
    );
256

            
257
4
    assert_eq!(
258
4
        crate::Options::default()
259
4
            .with_recursion_limit(1)
260
4
            .to_string(&[[42]]),
261
4
        Err(crate::Error::ExceededRecursionLimit),
262
4
    );
263
4
    assert_eq!(
264
4
        crate::Options::default()
265
4
            .with_recursion_limit(2)
266
4
            .to_string(&[[42]])
267
4
            .as_deref(),
268
4
        Ok("((42))"),
269
4
    );
270
4
    assert_eq!(
271
4
        crate::Options::default()
272
4
            .without_recursion_limit()
273
4
            .to_string(&[[42]])
274
4
            .as_deref(),
275
4
        Ok("((42))"),
276
4
    );
277
4
}
278

            
279
360
fn check_to_string_writer<T: ?Sized + serde::Serialize>(val: &T, check: &str, check_pretty: &str) {
280
360
    let ron_str = super::to_string(val).unwrap();
281
360
    assert_eq!(ron_str, check);
282

            
283
360
    let ron_str_pretty = super::to_string_pretty(
284
360
        val,
285
360
        super::PrettyConfig::default()
286
360
            .struct_names(true)
287
360
            .compact_structs(true),
288
360
    )
289
360
    .unwrap();
290
360
    assert_eq!(ron_str_pretty, check_pretty);
291

            
292
360
    let mut ron_writer = std::ffi::OsString::new();
293
360
    super::to_writer(&mut ron_writer, val).unwrap();
294
360
    assert_eq!(ron_writer, check);
295

            
296
360
    let mut ron_writer_pretty = std::ffi::OsString::new();
297
360
    super::to_writer_pretty(
298
360
        &mut ron_writer_pretty,
299
360
        val,
300
360
        super::PrettyConfig::default()
301
360
            .struct_names(true)
302
360
            .compact_structs(true),
303
360
    )
304
360
    .unwrap();
305
360
    assert_eq!(ron_writer_pretty, check_pretty);
306
360
}