liquid_core/model/scalar/
ser.rs

1use crate::model::KString;
2use serde::ser::Impossible;
3use serde::{self, Serialize};
4
5use crate::model::ser::SerError;
6use crate::model::Scalar;
7
8/// Convert a `T` into `liquid_core::model::Scalar`.
9///
10/// # Examples
11///
12/// ```rust
13/// let s = "foo";
14/// let value = liquid_core::model::to_scalar(&s).unwrap();
15/// assert_eq!(value, liquid_core::model::Scalar::new(s));
16/// ```
17pub fn to_scalar<T>(value: &T) -> Result<Scalar, crate::error::Error>
18where
19    T: Serialize,
20{
21    value.serialize(ScalarSerializer).map_err(|e| e.into())
22}
23
24pub(crate) struct ScalarSerializer;
25
26fn scalar_must_be_a_string() -> SerError {
27    SerError::new(crate::error::Error::with_msg("Scalar must be a string."))
28}
29
30impl serde::Serializer for ScalarSerializer {
31    type Ok = Scalar;
32    type Error = SerError;
33
34    type SerializeSeq = Impossible<Scalar, SerError>;
35    type SerializeTuple = Impossible<Scalar, SerError>;
36    type SerializeTupleStruct = Impossible<Scalar, SerError>;
37    type SerializeTupleVariant = Impossible<Scalar, SerError>;
38    type SerializeMap = Impossible<Scalar, SerError>;
39    type SerializeStruct = Impossible<Scalar, SerError>;
40    type SerializeStructVariant = Impossible<Scalar, SerError>;
41
42    #[inline]
43    fn serialize_bool(self, value: bool) -> Result<Scalar, SerError> {
44        Ok(Scalar::new(value))
45    }
46
47    #[inline]
48    fn serialize_i8(self, value: i8) -> Result<Scalar, SerError> {
49        serialize_as_i64(value)
50    }
51
52    #[inline]
53    fn serialize_i16(self, value: i16) -> Result<Scalar, SerError> {
54        serialize_as_i64(value)
55    }
56
57    #[inline]
58    fn serialize_i32(self, value: i32) -> Result<Scalar, SerError> {
59        serialize_as_i64(value)
60    }
61
62    fn serialize_i64(self, value: i64) -> Result<Scalar, SerError> {
63        Ok(Scalar::new(value))
64    }
65
66    #[inline]
67    fn serialize_u8(self, value: u8) -> Result<Scalar, SerError> {
68        serialize_as_i64(value)
69    }
70
71    #[inline]
72    fn serialize_u16(self, value: u16) -> Result<Scalar, SerError> {
73        serialize_as_i64(value)
74    }
75
76    #[inline]
77    fn serialize_u32(self, value: u32) -> Result<Scalar, SerError> {
78        serialize_as_i64(value)
79    }
80
81    #[inline]
82    fn serialize_u64(self, value: u64) -> Result<Scalar, SerError> {
83        serialize_as_i64(value)
84    }
85
86    #[inline]
87    fn serialize_f32(self, value: f32) -> Result<Scalar, SerError> {
88        self.serialize_f64(f64::from(value))
89    }
90
91    #[inline]
92    fn serialize_f64(self, value: f64) -> Result<Scalar, SerError> {
93        Ok(Scalar::new(value))
94    }
95
96    #[inline]
97    fn serialize_char(self, value: char) -> Result<Scalar, SerError> {
98        let mut s = String::new();
99        s.push(value);
100        self.serialize_str(&s)
101    }
102
103    #[inline]
104    fn serialize_str(self, value: &str) -> Result<Scalar, SerError> {
105        Ok(Scalar::new(KString::from_ref(value)))
106    }
107
108    fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok, Self::Error> {
109        Err(scalar_must_be_a_string())
110    }
111
112    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
113        Err(scalar_must_be_a_string())
114    }
115
116    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
117        Err(scalar_must_be_a_string())
118    }
119
120    fn serialize_unit_variant(
121        self,
122        _name: &'static str,
123        _variant_index: u32,
124        variant: &'static str,
125    ) -> Result<Scalar, SerError> {
126        self.serialize_str(variant)
127    }
128
129    fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<Scalar, SerError>
130    where
131        T: Serialize + ?Sized,
132    {
133        value.serialize(ScalarSerializer)
134    }
135
136    fn serialize_newtype_variant<T>(
137        self,
138        _name: &'static str,
139        _variant_index: u32,
140        _variant: &'static str,
141        _value: &T,
142    ) -> Result<Self::Ok, Self::Error>
143    where
144        T: Serialize + ?Sized,
145    {
146        Err(scalar_must_be_a_string())
147    }
148
149    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
150        Err(scalar_must_be_a_string())
151    }
152
153    fn serialize_some<T>(self, _value: &T) -> Result<Self::Ok, Self::Error>
154    where
155        T: Serialize + ?Sized,
156    {
157        Err(scalar_must_be_a_string())
158    }
159
160    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
161        Err(scalar_must_be_a_string())
162    }
163
164    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
165        Err(scalar_must_be_a_string())
166    }
167
168    fn serialize_tuple_struct(
169        self,
170        _name: &'static str,
171        _len: usize,
172    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
173        Err(scalar_must_be_a_string())
174    }
175
176    fn serialize_tuple_variant(
177        self,
178        _name: &'static str,
179        _variant_index: u32,
180        _variant: &'static str,
181        _len: usize,
182    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
183        Err(scalar_must_be_a_string())
184    }
185
186    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
187        Err(scalar_must_be_a_string())
188    }
189
190    fn serialize_struct(
191        self,
192        _name: &'static str,
193        _len: usize,
194    ) -> Result<Self::SerializeStruct, Self::Error> {
195        Err(scalar_must_be_a_string())
196    }
197
198    fn serialize_struct_variant(
199        self,
200        _name: &'static str,
201        _variant_index: u32,
202        _variant: &'static str,
203        _len: usize,
204    ) -> Result<Self::SerializeStructVariant, Self::Error> {
205        Err(scalar_must_be_a_string())
206    }
207}
208
209#[inline]
210fn serialize_as_i64(value: impl TryInto<i64>) -> Result<Scalar, SerError> {
211    let value = value
212        .try_into()
213        .map_err(|_err| SerError::new(crate::error::Error::with_msg("Cannot fit number")))?;
214    Ok(Scalar::new(value))
215}