use bson::{Bson, DateTime, Document};
use prost::Message;
use regex::Regex;
use serde::Serialize;
use tonic::Status;
pub fn pb_to_bson<T: Message + Serialize>(message: &T) -> Result<Document, Status> {
let bson_value = bson::to_bson(message).map_err(|e| Status::invalid_argument(e.to_string()))?;
let mut doc = match bson_value.as_document() {
Some(doc) => doc.clone(),
None => {
return Err(Status::invalid_argument(
"Protobuf message must be able to parse into a BSON Document",
));
}
};
if let Ok(id) = doc.get_str("id") {
if id.is_empty() {
doc.remove("id");
}
}
let re =
Regex::new(r#"^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T"#).map_err(|e| Status::internal(e.to_string()))?;
for (k, v) in doc.clone().iter() {
if let Bson::String(s) = v {
if re.is_match(s) {
if let Ok(dt) = DateTime::parse_rfc3339_str(s) {
doc.insert(k, dt);
}
}
}
}
Ok(doc)
}