1mod firestore_array_value_serializer;
2mod firestore_geo_point_value_serializer;
3mod firestore_map_value_serializer;
4mod firestore_reference_value_serializer;
5mod firestore_timestamp_value_serializer;
6mod firestore_value_serializer;
7mod firestore_value_struct_serializer;
8mod name_map_value_serializer;
9pub(crate) mod with;
10
11use serde::Serialize;
12
13use crate::google::firestore::v1::Value;
14use crate::{ser::firestore_value_serializer::FirestoreValueSerializer, Error};
15
16pub use firestore_value_serializer::FirestoreValueSerializer as Serializer;
17
18pub fn to_value<T>(value: &T) -> Result<Value, Error>
100where
101 T: Serialize,
102{
103 value.serialize(FirestoreValueSerializer)
104}
105
106#[cfg(test)]
107mod tests {
108 use std::collections::{BTreeMap, HashMap};
109
110 const MAX_BYTE_LEN: usize = 1_048_487;
111
112 use crate::value_ext::ValueExt;
113
114 use super::*;
115
116 #[test]
117 fn test_bool() -> anyhow::Result<()> {
118 assert_eq!(to_value(&false)?, Value::from_bool(false));
119 assert_eq!(to_value(&true)?, Value::from_bool(true));
120 Ok(())
121 }
122
123 #[test]
124 fn test_i8() -> anyhow::Result<()> {
125 assert_eq!(to_value(&i8::MAX)?, Value::from_i64(i64::from(i8::MAX)));
126 assert_eq!(to_value(&i8::MIN)?, Value::from_i64(i64::from(i8::MIN)));
127 Ok(())
128 }
129
130 #[test]
131 fn test_i16() -> anyhow::Result<()> {
132 assert_eq!(to_value(&i16::MAX)?, Value::from_i64(i64::from(i16::MAX)));
133 assert_eq!(to_value(&i16::MIN)?, Value::from_i64(i64::from(i16::MIN)));
134 Ok(())
135 }
136
137 #[test]
138 fn test_i32() -> anyhow::Result<()> {
139 assert_eq!(to_value(&i32::MAX)?, Value::from_i64(i64::from(i32::MAX)));
140 assert_eq!(to_value(&i32::MIN)?, Value::from_i64(i64::from(i32::MIN)));
141 Ok(())
142 }
143
144 #[test]
145 fn test_i64() -> anyhow::Result<()> {
146 assert_eq!(to_value(&i64::MAX)?, Value::from_i64(i64::MAX));
147 assert_eq!(to_value(&i64::MIN)?, Value::from_i64(i64::MIN));
148 Ok(())
149 }
150
151 #[test]
152 fn test_u8() -> anyhow::Result<()> {
153 assert_eq!(to_value(&u8::MAX)?, Value::from_i64(i64::from(u8::MAX)));
154 assert_eq!(to_value(&u8::MIN)?, Value::from_i64(i64::from(u8::MIN)));
155 Ok(())
156 }
157
158 #[test]
159 fn test_u16() -> anyhow::Result<()> {
160 assert_eq!(to_value(&u16::MAX)?, Value::from_i64(i64::from(u16::MAX)));
161 assert_eq!(to_value(&u16::MIN)?, Value::from_i64(i64::from(u16::MIN)));
162 Ok(())
163 }
164
165 #[test]
166 fn test_u32() -> anyhow::Result<()> {
167 assert_eq!(to_value(&u32::MAX)?, Value::from_i64(i64::from(u32::MAX)));
168 assert_eq!(to_value(&u32::MIN)?, Value::from_i64(i64::from(u32::MIN)));
169 Ok(())
170 }
171
172 #[test]
173 fn test_u64() -> anyhow::Result<()> {
174 assert_eq!(
175 to_value(&u64::MAX).unwrap_err().to_string(),
176 "u64 is not supported"
177 );
178 assert_eq!(
179 to_value(&u64::MIN).unwrap_err().to_string(),
180 "u64 is not supported"
181 );
182 Ok(())
183 }
184
185 #[test]
186 fn test_f32() -> anyhow::Result<()> {
187 assert_eq!(to_value(&f32::MAX)?, Value::from_f64(f64::from(f32::MAX)));
188 assert_eq!(to_value(&f32::MIN)?, Value::from_f64(f64::from(f32::MIN)));
189 Ok(())
190 }
191
192 #[test]
193 fn test_f64() -> anyhow::Result<()> {
194 assert_eq!(to_value(&f64::MAX)?, Value::from_f64(f64::MAX));
195 assert_eq!(to_value(&f64::MIN)?, Value::from_f64(f64::MIN));
196 Ok(())
197 }
198
199 #[test]
200 fn test_char() -> anyhow::Result<()> {
201 assert_eq!(to_value(&'a')?, Value::from_string("a".to_string()));
202 Ok(())
203 }
204
205 #[test]
206 fn test_str() -> anyhow::Result<()> {
207 assert_eq!(to_value(&"abc")?, Value::from_string("abc".to_string()));
208 assert_eq!(
209 to_value(&"a".repeat(MAX_BYTE_LEN))?,
210 Value::from_string("a".repeat(MAX_BYTE_LEN))
211 );
212 assert_eq!(
213 to_value(&"a".repeat(MAX_BYTE_LEN + 1))
214 .unwrap_err()
215 .to_string(),
216 "maximum byte length (1,048,487 bytes = 1MiB - 89 bytes) exceeded"
217 );
218
219 Ok(())
220 }
221
222 #[test]
223 fn test_bytes() -> anyhow::Result<()> {
224 assert_eq!(
225 to_value(&[0_u8, 1_u8])?,
226 Value::from_values(vec![Value::from_i64(0_i64), Value::from_i64(1_i64)])
229 );
230 Ok(())
239 }
240
241 #[test]
242 fn test_none() -> anyhow::Result<()> {
243 assert_eq!(to_value(&None::<Option<i64>>)?, Value::null());
244 Ok(())
245 }
246
247 #[test]
248 fn test_some() -> anyhow::Result<()> {
249 assert_eq!(to_value(&Some(true))?, Value::from_bool(true));
250 assert_eq!(to_value(&Some(1_i64))?, Value::from_i64(1_i64));
251 Ok(())
252 }
253
254 #[test]
255 fn test_unit() -> anyhow::Result<()> {
256 assert_eq!(to_value(&())?, Value::null());
257 Ok(())
258 }
259
260 #[test]
261 fn test_unit_struct() -> anyhow::Result<()> {
262 #[derive(serde::Serialize)]
263 struct Unit;
264 assert_eq!(to_value(&Unit)?, Value::null());
265 Ok(())
266 }
267
268 #[test]
269 fn test_unit_variant() -> anyhow::Result<()> {
270 #[derive(serde::Serialize)]
271 enum E {
272 A,
273 B,
274 }
275 assert_eq!(to_value(&E::A)?, Value::from_string("A".to_string()));
276 assert_eq!(to_value(&E::B)?, Value::from_string("B".to_string()));
277 Ok(())
278 }
279
280 #[test]
281 fn test_newtype_struct() -> anyhow::Result<()> {
282 #[derive(serde::Serialize)]
283 struct Millimeters(u8);
284 assert_eq!(
285 to_value(&Millimeters(u8::MAX))?,
286 Value::from_i64(i64::from(u8::MAX))
287 );
288 Ok(())
289 }
290
291 #[test]
292 fn test_newtype_variant() -> anyhow::Result<()> {
293 #[derive(serde::Serialize)]
294 enum E {
295 N(u8),
296 }
297 assert_eq!(
298 to_value(&E::N(u8::MAX))?,
299 Value::from_fields([("N", Value::from_i64(i64::from(u8::MAX)))])
300 );
301 Ok(())
302 }
303
304 #[test]
305 fn test_seq() -> anyhow::Result<()> {
306 assert_eq!(
307 to_value(&vec![1_i64, 2_i64, 3_i64])?,
308 Value::from_values(vec![
309 Value::from_i64(1_i64),
310 Value::from_i64(2_i64),
311 Value::from_i64(3_i64)
312 ])
313 );
314 assert_eq!(
315 to_value(&vec![vec![1_i64]])?,
316 Value::from_values(vec![Value::from_values(vec![Value::from_i64(1_i64)])])
317 );
318 Ok(())
319 }
320
321 #[test]
322 fn test_tuple() -> anyhow::Result<()> {
323 assert_eq!(
324 to_value(&(true, 1, "abc"))?,
325 Value::from_values(vec![
326 Value::from_bool(true),
327 Value::from_i64(1),
328 Value::from_string("abc".to_string())
329 ])
330 );
331 Ok(())
332 }
333
334 #[test]
335 fn test_tuple_struct() -> anyhow::Result<()> {
336 #[derive(serde::Serialize)]
337 struct Rgb(u8, u8, u8);
338 assert_eq!(
339 to_value(&Rgb(1, 2, 3))?,
340 Value::from_values(vec![
341 Value::from_i64(1),
342 Value::from_i64(2),
343 Value::from_i64(3)
344 ])
345 );
346 Ok(())
347 }
348
349 #[test]
350 fn test_tuple_variant() -> anyhow::Result<()> {
351 #[derive(serde::Serialize)]
352 enum E {
353 T(u8, u8),
354 }
355 assert_eq!(
356 to_value(&E::T(1, 2))?,
357 Value::from_fields([(
358 "T",
359 Value::from_values(vec![Value::from_i64(1), Value::from_i64(2)]),
360 )])
361 );
362 Ok(())
363 }
364
365 #[test]
366 fn test_map() -> anyhow::Result<()> {
367 assert_eq!(
368 to_value(&{
369 let mut map = std::collections::HashMap::new();
370 map.insert("k1", 1_i64);
371 map.insert("k2", 2_i64);
372 map
373 })?,
374 Value::from_fields([("k1", Value::from_i64(1)), ("k2", Value::from_i64(2))])
375 );
376 Ok(())
377 }
378
379 #[test]
380 fn test_struct() -> anyhow::Result<()> {
381 #[derive(serde::Serialize)]
382 struct S {
383 r: u8,
384 g: u8,
385 b: u8,
386 }
387 assert_eq!(
388 to_value(&S { r: 1, g: 2, b: 3 })?,
389 Value::from_fields([
390 ("r", Value::from_i64(1)),
391 ("g", Value::from_i64(2)),
392 ("b", Value::from_i64(3)),
393 ])
394 );
395 Ok(())
396 }
397
398 #[test]
399 fn test_struct_variant() -> anyhow::Result<()> {
400 #[derive(serde::Serialize)]
401 enum E {
402 S { r: u8, g: u8, b: u8 },
403 }
404 assert_eq!(
405 to_value(&E::S { r: 1, g: 2, b: 3 })?,
406 Value::from_fields([(
407 "S",
408 Value::from_fields([
409 ("r", Value::from_i64(1)),
410 ("g", Value::from_i64(2)),
411 ("b", Value::from_i64(3)),
412 ]),
413 )])
414 );
415 Ok(())
416 }
417
418 #[test]
419 fn test_error_key_must_be_a_string() -> anyhow::Result<()> {
420 assert_eq!(
421 to_value(&{
422 let mut map = HashMap::new();
423 map.insert((), 1_u8);
424 map
425 })
426 .unwrap_err()
427 .to_string(),
428 "key must be a string"
429 );
430 assert_eq!(
431 to_value(&{
432 let mut map = BTreeMap::new();
433 map.insert('a', 1_u8);
434 map
435 })?,
436 Value::from_fields([("a", Value::from_i64(1))])
437 );
438 Ok(())
439 }
440
441 #[test]
442 fn test_impl_serde_ser_error() {
443 fn assert_impl<T: serde::ser::Error>() {}
444 assert_impl::<Error>();
445 assert_eq!(
446 <Error as serde::ser::Error>::custom("custom error").to_string(),
447 "custom error"
448 );
449 }
450}