diff --git a/src/db/options.rs b/src/db/options.rs index ee987ce28..03848e841 100644 --- a/src/db/options.rs +++ b/src/db/options.rs @@ -44,7 +44,11 @@ pub struct CreateCollectionOptions { /// The maximum size (in bytes) for a capped collection. This option is ignored if `capped` is /// not set to true. - #[serde(serialize_with = "serde_util::serialize_u64_option_as_i64")] + #[serde( + serialize_with = "serde_util::serialize_u64_option_as_i64", + deserialize_with = "serde_util::deserialize_option_u64_from_bson_number", + default + )] pub size: Option, /// The maximum number of documents in a capped collection. The `size` limit takes precedence diff --git a/src/serde_util.rs b/src/serde_util.rs index d3dcda433..b8046bd37 100644 --- a/src/serde_util.rs +++ b/src/serde_util.rs @@ -118,6 +118,21 @@ where .ok_or_else(|| serde::de::Error::custom(format!("could not deserialize u64 from {bson:?}"))) } +pub(crate) fn deserialize_option_u64_from_bson_number<'de, D>( + deserializer: D, +) -> std::result::Result, D::Error> +where + D: Deserializer<'de>, +{ + Option::::deserialize(deserializer)? + .map(|bson| { + get_u64(&bson).ok_or_else(|| { + serde::de::Error::custom(format!("could not deserialize u64 from {bson:?}")) + }) + }) + .transpose() +} + pub(crate) fn serialize_error_as_string( val: &Error, serializer: S, diff --git a/src/test/db.rs b/src/test/db.rs index b13df1abc..3b4a25213 100644 --- a/src/test/db.rs +++ b/src/test/db.rs @@ -468,3 +468,18 @@ async fn test_run_command() { assert_eq!(v[0].as_ref().unwrap().get_str("foo").unwrap(), "bar"); } } + +#[test] +fn create_collection_options_deserialize() { + let source = doc! { + "capped": true, + "size": 5253511168.0, + "autoIndexId": false, + }; + let _: CreateCollectionOptions = crate::bson_compat::deserialize_from_document(source).unwrap(); + let source = doc! { + "capped": true, + "autoIndexId": false, + }; + let _: CreateCollectionOptions = crate::bson_compat::deserialize_from_document(source).unwrap(); +}