1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//! Specify the format and how lenient the deserialization is

#[cfg(feature = "alloc")]
use alloc::string::String;

/// Specify how to serialize/deserialize a type
///
/// The format specifier allows to configure how a value is serialized/deserialized.
/// For example, you can serialize a timestamp as an integer using the UNIX epoch, as a string containing an integer, or as a string using ISO 8601.
/// This [`Format`] traits allows more flexibility in configuring the format without the need to create a new type for each case.
pub trait Format {}

macro_rules! impl_format {
    ($(#[$attr:meta] $t:ty)*) => {
        $(
            #[$attr]
            impl Format for $t {}
        )*
    };
}
macro_rules! create_format {
    ($(#[$attr:meta] $t:ident)*) => {
        $(
            #[$attr]
                        pub struct $t;
            impl_format!(#[$attr] $t);
        )*
    };
}
impl_format!(
    /// Serialize into an i8
    i8
    /// Serialize into a u8
    u8
    /// Serialize into an i16
    i16
    /// Serialize into a u16
    u16
    /// Serialize into an i32
    i32
    /// Serialize into a u32
    u32
    /// Serialize into an i64
    i64
    /// Serialize into a u64
    u64
    /// Serialize into an i128
    i128
    /// Serialize into a u128
    u128

    /// Serialize into a f32
    f32
    /// Serialize into a f64
    f64

    /// Serialize into a bool
    bool
);
#[cfg(feature = "alloc")]
impl_format!(
    /// Serialize into a String
    String
);

create_format!(
    /// Use uppercase characters
    Uppercase
    /// Use lowercase characters
    Lowercase

    /// Use in combination with [`OneOrMany`](crate::OneOrMany). Emit single element for lists of size 1.
    PreferOne
    /// Use in combination with [`OneOrMany`](crate::OneOrMany). Always emit the list form.
    PreferMany

    /// Emit padding during serialization.
    Padded
    /// Do not emit padding during serialization.
    Unpadded
);

/// Specify how lenient the deserialization process should be
///
/// Formats which make use of this trait should specify how it affects the deserialization behavior.
pub trait Strictness {}

/// Use strict deserialization behavior, see [`Strictness`].
pub struct Strict;
impl Strictness for Strict {}

/// Use a flexible deserialization behavior, see [`Strictness`].
pub struct Flexible;
impl Strictness for Flexible {}

/// Separator for string-based collection de/serialization
pub trait Separator {
    /// Return the string delimiting two elements in the string-based collection
    fn separator() -> &'static str;
}

/// Predefined separator using a single space
pub struct SpaceSeparator;

impl Separator for SpaceSeparator {
    #[inline]
    fn separator() -> &'static str {
        " "
    }
}

/// Predefined separator using a single comma
pub struct CommaSeparator;

impl Separator for CommaSeparator {
    #[inline]
    fn separator() -> &'static str {
        ","
    }
}

/// Predefined separator using a single semicolon
pub struct SemicolonSeparator;

impl Separator for SemicolonSeparator {
    #[inline]
    fn separator() -> &'static str {
        ";"
    }
}

/// Predefined separator using a single semicolon
pub struct ColonSeparator;

impl Separator for ColonSeparator {
    #[inline]
    fn separator() -> &'static str {
        ":"
    }
}