Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RUST-1178 The ability to custom tag DateTime<Utc> for automatic conversion. #191

Open
ruseinov opened this issue Jun 9, 2020 · 9 comments
Labels
tracked-in-jira Ticket filed in Mongo's Jira system

Comments

@ruseinov
Copy link

ruseinov commented Jun 9, 2020

Here's an example of a collection with records expiring by expires_at:

#[collection = "subscriptions"]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Subscription {
    #[serde(rename = "_id")]
    pub id: Option<ObjectId>,
    pub expires_at: DateTime<Utc>,
}

In order for that to work I need to use the Bson::UtcDateTime helper (now DateTime), but in that case when I deliver this model to the frontend I end up with

    "expires_at": {
        "$date": {
            "$numberLong": 1591700287095
        }
    },

instead of proper date. The approach with duplicating the object just for the sake date serialization is not the most convenient one.

What would be nice to have is some sort of annotation that would tell Bson Encoder/Decoder that this DateTime field has to be de/serialized as Bson date, while serde_json will serialize it as usual.

The same applies to ObjectId, currently if one wants a readable hex string instead of a json object there's a lot of duplication involved.

@ruseinov
Copy link
Author

ruseinov commented Jun 9, 2020

Here's my temp fix, which is verbose, but it does the job.

pub struct SubscriptionDTO {
    pub data: Subscription,
}

impl Serialize for SubscriptionDTO {
    fn serialize<S>(
        &self,
        serializer: S,
    ) -> result::Result<<S as Serializer>::Ok, <S as Serializer>::Error>
    where
        S: Serializer,
    {
        let mut state = serializer.serialize_struct("SubscriptionDTO", 5)?;
       ... other fields
        state.serialize_field("expires_at", &self.data.expires_at.0)?;
        state.end()
    }
}

@patrickfreed
Copy link
Contributor

To reduce the amount of code required to achieve this, you could use #[serde(serialize_with)] on the date field.

I filed RUST-506 to track the status of work on this. Thank you for filing the issue!

@Alexander-L-G Alexander-L-G added the tracked-in-jira Ticket filed in Mongo's Jira system label Nov 30, 2020
@Cosmiiko
Copy link

Cosmiiko commented Jan 31, 2022

Any updates on this?
The $numberLong format really isn't convenient for front-end, and using a custom serializer (or a helper like #[serde(serialize_with = "bson_datetime_as_rfc3339_string::serialize")] causes the field to be inserted as a string in Mongo.

Also why is the jira issue closed?

@patrickfreed patrickfreed changed the title The ability to custom tag DateTime<Utc> for automatic conversion. RUST-1178 The ability to custom tag DateTime<Utc> for automatic conversion. Feb 8, 2022
@patrickfreed
Copy link
Contributor

In RUST-506 we introduced some more general purpose helpers, but as you point out they didn't quite solve the initial problem of automatic serialization changes on a per-format basis. For that, I've filed RUST-1178. Thanks for bringing this to our attention!

Until that ticket gets completed, you can use separate structs for communicating with the DB and with the frontend which have different serialization implementations.

@max-block
Copy link

@ruseinov , have you found any other solutions to this problem except an extra wrapper struct?

@ruseinov
Copy link
Author

ruseinov commented Jun 3, 2022

@max-block TBH I don't remember anymore, but I think not. Haven't been interfacing with MongoDB lately, therefore I have got no recent experience with BSON.

@clarkmcc
Copy link

clarkmcc commented Jan 23, 2023

Any updates on this?

I ended up with this. When I pass this into my database create function, the create function converts it into a Foobar<bson::DateTime>. This requires all sorts of unnecessary cloning, so a real solution would still be better.

struct Foobar<T = DateTime<Utc>> {
    created_date: T,
}

impl From<Foobar<DateTime<Utc>>> for Foobar<bson::DateTime> {
    fn from(value: Foobar<DateTime<Utc>>) -> Self {
        Foobar {
            created_date: value.created_date.into(),
        }
    }
}

@bajanam
Copy link
Contributor

bajanam commented Jan 24, 2023

Hi @clarkmcc, while our current development plan is at capacity, this remains in our backlog for future prioritization. Thank you for the suggestion!

@danielsan
Copy link

Any news here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tracked-in-jira Ticket filed in Mongo's Jira system
Projects
None yet
Development

No branches or pull requests

8 participants