compris/ser/normal/
integer.rs

1use super::super::{
2    super::{annotate::*, normal::*},
3    modal::*,
4    mode::*,
5};
6
7use {num_traits::cast, serde::ser::*};
8
9impl<AnnotatedT> Serialize for Integer<AnnotatedT> {
10    fn serialize<SerializerT>(&self, serializer: SerializerT) -> Result<SerializerT::Ok, SerializerT::Error>
11    where
12        SerializerT: Serializer,
13    {
14        serializer.serialize_i64(self.inner)
15    }
16}
17
18impl<AnnotatedT> SerializeModal for Integer<AnnotatedT>
19where
20    AnnotatedT: Annotated + Clone + Default,
21{
22    fn serialize_modal<SerializerT>(
23        &self,
24        serializer: SerializerT,
25        mode: &SerializationMode,
26    ) -> Result<SerializerT::Ok, SerializerT::Error>
27    where
28        SerializerT: Serializer,
29    {
30        // See: https://docs.rs/num-traits/latest/num_traits/cast/trait.NumCast.html#tymethod.from
31        match &mode.integer {
32            IntegerSerializationMode::AsI64 => serializer.serialize_i64(self.inner),
33
34            IntegerSerializationMode::AsU64IfNonNegative => {
35                if self.inner < 0 {
36                    serializer.serialize_i64(self.inner)
37                } else {
38                    let unsigned_integer = self.inner as u64; // should always succeed
39                    if mode.unsigned_integer.might_be_integer() {
40                        // Avoid endless recursion!
41                        serializer.serialize_u64(unsigned_integer)
42                    } else {
43                        UnsignedInteger::<AnnotatedT>::from(unsigned_integer)
44                            .with_annotations_from(self)
45                            .serialize_modal(serializer, mode)
46                    }
47                }
48            }
49
50            IntegerSerializationMode::AsF64 => {
51                let float =
52                    cast(self.inner).ok_or_else(|| Error::custom(format!("cannot cast to f64: {}", self.inner)))?;
53                if mode.float.might_be_integer() {
54                    // Avoid endless recursion!
55                    serializer.serialize_f64(float)
56                } else {
57                    Float::<AnnotatedT>::from(float).with_annotations_from(self).serialize_modal(serializer, mode)
58                }
59            }
60
61            IntegerSerializationMode::Stringify(hint) => {
62                let string = self.inner.to_string();
63                match hint {
64                    None => serializer.serialize_str(&string),
65
66                    Some(hint) => {
67                        let mut map = serializer.serialize_map(Some(1))?;
68                        map.serialize_entry(&hint, &string)?;
69                        map.end()
70                    }
71                }
72            }
73        }
74    }
75}