Open AlexKovalevych opened 3 years ago
Hi @AlexKovalevych!
So right now, the only format we support for deserializing arbitrary BSON to an arbitrary serialization format is Extended JSON, which is what you're seeing there with the $date
. We think allowing configuration in this area would be a nice addition to our API, so I've filed RUST-677 to track the work for that.
In the meantime, you could define a wrapper struct and implement a custom Serialize
implementation on it, which could possibly make this a little more straightforward.
Here's a pretty inefficient example using a lot of clones:
struct MyWrapper {
wrapped: Bson
}
impl Serialize for MyWrapper {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer
{
match self.wrapped {
Bson::DateTime(ref d) => {
d.serialize(serializer)
}
Bson::Document(ref d) => {
let map: HashMap<String, MyWrapper> = d.iter().map(|(k, v)| {
(k.clone(), MyWrapper { wrapped: v.clone() })
}).collect();
map.serialize(serializer)
},
Bson::Array(ref a) => {
let vec: Vec<MyWrapper> = a.iter().map(|b| { MyWrapper { wrapped: b.clone() } }).collect();
vec.serialize(serializer)
}
ref a @ _ => a.serialize(serializer)
}
}
}
And then you'd use serde_json
's serialization functionality:
let doc = doc! { "date": Bson::DateTime(Utc::now()) };
let json = serde_json::to_value(MyWrapper { wrapped: Bson::Document(doc) }).unwrap();
println!("{}", json); // {"date":"2021-02-20T00:36:46.597117805Z"}
This could be optimized to get rid of the clones, but this was just the simplest way I could think of implementing it for demonstration purposes.
Got it, thank you for detailed response
After retrieving data from database like:
I'm not able to serialize data to json with custom datetime format getting datetime fields like:
I can't use serde helpers, since i don't know the data schema. The only solution i see right now is to manually iterate all fields in
bson_document
recursively and in case ofBson::DateTime
type convert it toBson::String
type with desired datetime format. Is there a better solution?