1use std::{convert::TryFrom, result::Result};
4
5use serde::{ser, Serialize, Serializer};
6
7use crate::oid::ObjectId;
8
9#[doc(inline)]
10pub use bson_datetime_as_rfc3339_string::{
11 deserialize as deserialize_bson_datetime_from_rfc3339_string,
12 serialize as serialize_bson_datetime_as_rfc3339_string,
13};
14#[cfg(feature = "chrono-0_4")]
15#[doc(inline)]
16pub use chrono_datetime_as_bson_datetime::{
17 deserialize as deserialize_chrono_datetime_from_bson_datetime,
18 serialize as serialize_chrono_datetime_as_bson_datetime,
19};
20#[doc(inline)]
21pub use hex_string_as_object_id::{
22 deserialize as deserialize_hex_string_from_object_id,
23 serialize as serialize_hex_string_as_object_id,
24};
25#[doc(inline)]
26pub use rfc3339_string_as_bson_datetime::{
27 deserialize as deserialize_rfc3339_string_from_bson_datetime,
28 serialize as serialize_rfc3339_string_as_bson_datetime,
29};
30#[doc(inline)]
31pub use timestamp_as_u32::{
32 deserialize as deserialize_timestamp_from_u32,
33 serialize as serialize_timestamp_as_u32,
34};
35#[doc(inline)]
36pub use u32_as_f64::{deserialize as deserialize_u32_from_f64, serialize as serialize_u32_as_f64};
37#[doc(inline)]
38pub use u32_as_timestamp::{
39 deserialize as deserialize_u32_from_timestamp,
40 serialize as serialize_u32_as_timestamp,
41};
42#[doc(inline)]
43pub use u64_as_f64::{deserialize as deserialize_u64_from_f64, serialize as serialize_u64_as_f64};
44
45#[cfg(feature = "uuid-0_8")]
46#[doc(inline)]
47pub use uuid_as_binary::{
48 deserialize as deserialize_uuid_from_binary,
49 serialize as serialize_uuid_as_binary,
50};
51#[cfg(feature = "uuid-0_8")]
52#[doc(inline)]
53pub use uuid_as_c_sharp_legacy_binary::{
54 deserialize as deserialize_uuid_from_c_sharp_legacy_binary,
55 serialize as serialize_uuid_as_c_sharp_legacy_binary,
56};
57#[cfg(feature = "uuid-0_8")]
58#[doc(inline)]
59pub use uuid_as_java_legacy_binary::{
60 deserialize as deserialize_uuid_from_java_legacy_binary,
61 serialize as serialize_uuid_as_java_legacy_binary,
62};
63#[cfg(feature = "uuid-0_8")]
64#[doc(inline)]
65pub use uuid_as_python_legacy_binary::{
66 deserialize as deserialize_uuid_from_python_legacy_binary,
67 serialize as serialize_uuid_as_python_legacy_binary,
68};
69
70pub fn serialize_u32_as_i32<S: Serializer>(val: &u32, serializer: S) -> Result<S::Ok, S::Error> {
72 match i32::try_from(*val) {
73 Ok(val) => serializer.serialize_i32(val),
74 Err(_) => Err(ser::Error::custom(format!("cannot convert {} to i32", val))),
75 }
76}
77
78pub fn serialize_u32_as_i64<S: Serializer>(val: &u32, serializer: S) -> Result<S::Ok, S::Error> {
80 serializer.serialize_i64(*val as i64)
81}
82
83pub fn serialize_u64_as_i32<S: Serializer>(val: &u64, serializer: S) -> Result<S::Ok, S::Error> {
85 match i32::try_from(*val) {
86 Ok(val) => serializer.serialize_i32(val),
87 Err(_) => Err(ser::Error::custom(format!("cannot convert {} to i32", val))),
88 }
89}
90
91pub fn serialize_u64_as_i64<S: Serializer>(val: &u64, serializer: S) -> Result<S::Ok, S::Error> {
93 match i64::try_from(*val) {
94 Ok(val) => serializer.serialize_i64(val),
95 Err(_) => Err(ser::Error::custom(format!("cannot convert {} to i64", val))),
96 }
97}
98
99pub fn serialize_object_id_as_hex_string<S: Serializer>(
101 val: &ObjectId,
102 serializer: S,
103) -> Result<S::Ok, S::Error> {
104 val.to_hex().serialize(serializer)
105}
106
107pub mod u32_as_f64 {
120 use serde::{de, Deserialize, Deserializer, Serializer};
121
122 pub fn deserialize<'de, D>(deserializer: D) -> Result<u32, D::Error>
124 where
125 D: Deserializer<'de>,
126 {
127 let f = f64::deserialize(deserializer)?;
128 if (f - f as u32 as f64).abs() <= f64::EPSILON {
129 Ok(f as u32)
130 } else {
131 Err(de::Error::custom(format!(
132 "cannot convert f64 (BSON double) {} to u32",
133 f
134 )))
135 }
136 }
137
138 pub fn serialize<S: Serializer>(val: &u32, serializer: S) -> Result<S::Ok, S::Error> {
140 serializer.serialize_f64(*val as f64)
141 }
142}
143
144pub mod u64_as_f64 {
157 use serde::{de, ser, Deserialize, Deserializer, Serializer};
158
159 pub fn deserialize<'de, D>(deserializer: D) -> Result<u64, D::Error>
161 where
162 D: Deserializer<'de>,
163 {
164 let f = f64::deserialize(deserializer)?;
165 if (f - f as u64 as f64).abs() <= f64::EPSILON {
166 Ok(f as u64)
167 } else {
168 Err(de::Error::custom(format!(
169 "cannot convert f64 (BSON double) {} to u64",
170 f
171 )))
172 }
173 }
174
175 pub fn serialize<S: Serializer>(val: &u64, serializer: S) -> Result<S::Ok, S::Error> {
177 if val < &u64::MAX && *val == *val as f64 as u64 {
178 serializer.serialize_f64(*val as f64)
179 } else {
180 Err(ser::Error::custom(format!(
181 "cannot convert u64 {} to f64 (BSON double)",
182 val
183 )))
184 }
185 }
186}
187
188#[cfg(feature = "chrono-0_4")]
204#[cfg_attr(docsrs, doc(cfg(feature = "chrono-0_4")))]
205pub mod chrono_datetime_as_bson_datetime {
206 use crate::DateTime;
207 use chrono::Utc;
208 use serde::{Deserialize, Deserializer, Serialize, Serializer};
209 use std::result::Result;
210
211 #[cfg_attr(docsrs, doc(cfg(feature = "chrono-0_4")))]
213 pub fn deserialize<'de, D>(deserializer: D) -> Result<chrono::DateTime<Utc>, D::Error>
214 where
215 D: Deserializer<'de>,
216 {
217 let datetime = DateTime::deserialize(deserializer)?;
218 Ok(datetime.to_chrono())
219 }
220
221 #[cfg_attr(docsrs, doc(cfg(feature = "chrono-0_4")))]
223 pub fn serialize<S: Serializer>(
224 val: &chrono::DateTime<Utc>,
225 serializer: S,
226 ) -> Result<S::Ok, S::Error> {
227 let datetime = DateTime::from_chrono(val.to_owned());
228 datetime.serialize(serializer)
229 }
230}
231
232pub mod rfc3339_string_as_bson_datetime {
245 use crate::{Bson, DateTime};
246 use serde::{ser, Deserialize, Deserializer, Serialize, Serializer};
247 use std::result::Result;
248
249 pub fn deserialize<'de, D>(deserializer: D) -> Result<String, D::Error>
251 where
252 D: Deserializer<'de>,
253 {
254 let date = DateTime::deserialize(deserializer)?;
255 Ok(date.to_rfc3339_string())
256 }
257
258 pub fn serialize<S: Serializer>(val: &str, serializer: S) -> Result<S::Ok, S::Error> {
260 let date =
261 chrono::DateTime::<chrono::FixedOffset>::parse_from_rfc3339(val).map_err(|_| {
262 ser::Error::custom(format!("cannot convert {} to chrono::DateTime", val))
263 })?;
264 Bson::DateTime(crate::DateTime::from_chrono(date)).serialize(serializer)
265 }
266}
267
268pub mod bson_datetime_as_rfc3339_string {
281 use crate::DateTime;
282 use serde::{de, Deserialize, Deserializer, Serializer};
283 use std::result::Result;
284
285 pub fn deserialize<'de, D>(deserializer: D) -> Result<DateTime, D::Error>
287 where
288 D: Deserializer<'de>,
289 {
290 let iso = String::deserialize(deserializer)?;
291 let date =
292 chrono::DateTime::<chrono::FixedOffset>::parse_from_rfc3339(&iso).map_err(|_| {
293 de::Error::custom(format!("cannot parse RFC 3339 datetime from \"{}\"", iso))
294 })?;
295 Ok(DateTime::from_chrono(date))
296 }
297
298 pub fn serialize<S: Serializer>(val: &DateTime, serializer: S) -> Result<S::Ok, S::Error> {
300 serializer.serialize_str(&val.to_rfc3339_string())
301 }
302}
303
304pub mod hex_string_as_object_id {
317 use crate::oid::ObjectId;
318 use serde::{ser, Deserialize, Deserializer, Serialize, Serializer};
319
320 pub fn deserialize<'de, D>(deserializer: D) -> Result<String, D::Error>
322 where
323 D: Deserializer<'de>,
324 {
325 let object_id = ObjectId::deserialize(deserializer)?;
326 Ok(object_id.to_hex())
327 }
328
329 pub fn serialize<S: Serializer>(val: &str, serializer: S) -> Result<S::Ok, S::Error> {
331 match ObjectId::parse_str(val) {
332 Ok(oid) => oid.serialize(serializer),
333 Err(_) => Err(ser::Error::custom(format!(
334 "cannot convert {} to ObjectId",
335 val
336 ))),
337 }
338 }
339}
340
341#[cfg(feature = "uuid-0_8")]
356#[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
357pub mod uuid_as_binary {
358 use serde::{Deserialize, Deserializer, Serialize, Serializer};
359 use std::result::Result;
360 use uuid::Uuid;
361
362 #[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
364 pub fn serialize<S: Serializer>(val: &Uuid, serializer: S) -> Result<S::Ok, S::Error> {
365 crate::uuid::Uuid::from_external_uuid(*val).serialize(serializer)
366 }
367
368 #[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
370 pub fn deserialize<'de, D>(deserializer: D) -> Result<Uuid, D::Error>
371 where
372 D: Deserializer<'de>,
373 {
374 let bson_uuid = crate::uuid::Uuid::deserialize(deserializer)?;
375 Ok(bson_uuid.into())
376 }
377}
378
379#[cfg(feature = "uuid-0_8")]
397#[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
398pub mod uuid_as_java_legacy_binary {
399 use crate::{uuid::UuidRepresentation, Binary};
400 use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
401 use std::result::Result;
402 use uuid::Uuid;
403
404 #[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
406 pub fn serialize<S: Serializer>(val: &Uuid, serializer: S) -> Result<S::Ok, S::Error> {
407 let binary = Binary::from_uuid_with_representation(
408 crate::uuid::Uuid::from_external_uuid(*val),
409 UuidRepresentation::JavaLegacy,
410 );
411 binary.serialize(serializer)
412 }
413
414 #[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
416 pub fn deserialize<'de, D>(deserializer: D) -> Result<Uuid, D::Error>
417 where
418 D: Deserializer<'de>,
419 {
420 let binary = Binary::deserialize(deserializer)?;
421 let uuid = binary
422 .to_uuid_with_representation(UuidRepresentation::JavaLegacy)
423 .map_err(de::Error::custom)?;
424 Ok(uuid.to_uuid_0_8())
425 }
426}
427
428#[cfg(feature = "uuid-0_8")]
446#[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
447pub mod uuid_as_python_legacy_binary {
448 use crate::{uuid::UuidRepresentation, Binary};
449 use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
450 use std::result::Result;
451 use uuid::Uuid;
452
453 #[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
455 pub fn serialize<S: Serializer>(val: &Uuid, serializer: S) -> Result<S::Ok, S::Error> {
456 let binary = Binary::from_uuid_with_representation(
457 crate::uuid::Uuid::from_external_uuid(*val),
458 UuidRepresentation::PythonLegacy,
459 );
460 binary.serialize(serializer)
461 }
462
463 #[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
465 pub fn deserialize<'de, D>(deserializer: D) -> Result<Uuid, D::Error>
466 where
467 D: Deserializer<'de>,
468 {
469 let binary = Binary::deserialize(deserializer)?;
470 let uuid = binary
471 .to_uuid_with_representation(UuidRepresentation::PythonLegacy)
472 .map_err(de::Error::custom)?;
473 Ok(uuid.into())
474 }
475}
476
477#[cfg(feature = "uuid-0_8")]
495#[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
496pub mod uuid_as_c_sharp_legacy_binary {
497 use crate::{uuid::UuidRepresentation, Binary};
498 use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
499 use std::result::Result;
500 use uuid::Uuid;
501
502 #[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
504 pub fn serialize<S: Serializer>(val: &Uuid, serializer: S) -> Result<S::Ok, S::Error> {
505 let binary = Binary::from_uuid_with_representation(
506 crate::uuid::Uuid::from_external_uuid(*val),
507 UuidRepresentation::CSharpLegacy,
508 );
509 binary.serialize(serializer)
510 }
511
512 #[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
514 pub fn deserialize<'de, D>(deserializer: D) -> Result<Uuid, D::Error>
515 where
516 D: Deserializer<'de>,
517 {
518 let binary = Binary::deserialize(deserializer)?;
519 let uuid = binary
520 .to_uuid_with_representation(UuidRepresentation::CSharpLegacy)
521 .map_err(de::Error::custom)?;
522 Ok(uuid.into())
523 }
524}
525
526pub mod u32_as_timestamp {
539 use crate::{Bson, Timestamp};
540 use serde::{Deserialize, Deserializer, Serialize, Serializer};
541 use std::result::Result;
542
543 pub fn serialize<S: Serializer>(val: &u32, serializer: S) -> Result<S::Ok, S::Error> {
545 let timestamp = Bson::Timestamp(Timestamp {
546 time: *val,
547 increment: 0,
548 });
549 timestamp.serialize(serializer)
550 }
551
552 pub fn deserialize<'de, D>(deserializer: D) -> Result<u32, D::Error>
554 where
555 D: Deserializer<'de>,
556 {
557 let timestamp = Timestamp::deserialize(deserializer)?;
558 Ok(timestamp.time)
559 }
560}
561
562pub mod timestamp_as_u32 {
576 use crate::Timestamp;
577 use serde::{ser, Deserialize, Deserializer, Serializer};
578 use std::result::Result;
579
580 pub fn serialize<S: Serializer>(val: &Timestamp, serializer: S) -> Result<S::Ok, S::Error> {
583 if val.increment != 0 {
584 return Err(ser::Error::custom(
585 "Cannot convert Timestamp with a non-zero increment to u32",
586 ));
587 }
588 serializer.serialize_u32(val.time)
589 }
590
591 pub fn deserialize<'de, D>(deserializer: D) -> Result<Timestamp, D::Error>
593 where
594 D: Deserializer<'de>,
595 {
596 let time = u32::deserialize(deserializer)?;
597 Ok(Timestamp { time, increment: 0 })
598 }
599}