1
use alloc::{format, vec};
2

            
3
use serde_derive::Serialize;
4

            
5
use crate::Number;
6

            
7
#[derive(Serialize)]
8
struct EmptyStruct1;
9

            
10
#[derive(Serialize)]
11
struct EmptyStruct2 {}
12

            
13
#[derive(Serialize)]
14
struct NewType(i32);
15

            
16
#[derive(Serialize)]
17
struct TupleStruct(f32, f32);
18

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

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

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

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

            
43
4
    check_to_string_writer(&my_struct, "(x:4.0,y:7.0)", "MyStruct(x: 4.0, y: 7.0)");
44
4

            
45
4
    check_to_string_writer(&NewType(42), "(42)", "NewType(42)");
46
4

            
47
4
    check_to_string_writer(&TupleStruct(2.0, 5.0), "(2.0,5.0)", "TupleStruct(2.0, 5.0)");
48
4
}
49

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

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

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

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

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

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

            
102
#[test]
103
4
fn test_map() {
104
    use alloc::collections::BTreeMap;
105

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

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

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

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

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

            
132
#[test]
133
4
fn test_byte_stream() {
134
    use serde_bytes;
135

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

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

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

            
159
4
    let large = vec![255u8; 64];
160
4
    let large = serde_bytes::Bytes::new(&large);
161
4
    check_to_string_writer(
162
4
        &large,
163
4
        concat!(
164
4
            "b\"\\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
            "\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff",
168
4
            "\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\""
169
4
        ),
170
4
        concat!(
171
4
            "b\"\\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
            "\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff",
175
4
            "\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\""
176
4
        ),
177
4
    );
178
4
}
179

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

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

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

            
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::NAN), "-NaN", "-NaN");
205
4
    check_to_string_writer(&(-f32::NAN), "-NaN", "-NaN");
206
4
    check_to_string_writer(&Number::new(f32::INFINITY), "inf", "inf");
207
4
    check_to_string_writer(&f32::INFINITY, "inf", "inf");
208
4
    check_to_string_writer(&Number::new(f32::NEG_INFINITY), "-inf", "-inf");
209
4
    check_to_string_writer(&f32::NEG_INFINITY, "-inf", "-inf");
210

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

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

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

            
232
108
    check_to_string_writer(&n.into(), &fmt, &fmt);
233
108
    check_to_string_writer(&n, &fmt, &fmt);
234
108
}
235

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

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

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

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

            
294
    #[cfg(feature = "std")]
295
    {
296
360
        let mut ron_writer = std::ffi::OsString::new();
297
360
        super::to_writer(&mut ron_writer, val).unwrap();
298
360
        assert_eq!(ron_writer, check);
299

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