-
-
Notifications
You must be signed in to change notification settings - Fork 794
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
Support for std::time::Instant #1375
Comments
If there is no way to obtain some form of serializable underlying data from a type, then there is no way it can be serialized. Or in the reverse situation if there is no way to instantiate a type from some deserializable underlying data, it isn't possible to deserialize the type. In this case it looks like |
As a hacky approximate workaround you could serialize an approximation of an (The real fix is still to use a different type.) #[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
use std::time::Instant;
#[derive(Serialize, Deserialize, Debug)]
struct S {
#[serde(with = "approx_instant")]
time: Instant,
}
mod approx_instant {
use std::time::{Instant, SystemTime};
use serde::{Serialize, Serializer, Deserialize, Deserializer, de::Error};
pub fn serialize<S>(instant: &Instant, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let system_now = SystemTime::now();
let instant_now = Instant::now();
let approx = system_now - (instant_now - *instant);
approx.serialize(serializer)
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<Instant, D::Error>
where
D: Deserializer<'de>,
{
let de = SystemTime::deserialize(deserializer)?;
let system_now = SystemTime::now();
let instant_now = Instant::now();
let duration = system_now.duration_since(de).map_err(Error::custom)?;
let approx = instant_now - duration;
Ok(approx)
}
}
fn main() {
let s = S { time: Instant::now() };
println!("before: {:?}\n", s);
let j = serde_json::to_string(&s).unwrap();
println!("json: {}\n", j);
let s: S = serde_json::from_str(&j).unwrap();
println!("after: {:?}\n", s);
} |
If you are only interested by elapsed time, you can serialize and deserialize like this : use std::time::{Duration, Instant};
use serde::{Serialize, Serializer, Deserialize, Deserializer};
use serde::de::Error;
pub fn serialize<S>(instant: &Instant, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let duration = instant.elapsed();
duration.serialize(serializer)
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<Instant, D::Error>
where
D: Deserializer<'de>,
{
let duration = Duration::deserialize(deserializer)?;
let now = Instant::now();
let instant = now.checked_sub(duration).ok_or_else(|| Error::custom("Erreur checked_add"))?;
Ok(instant)
} |
I ran into a case where I was looking to serialize a struct that contained a field of type std::time::Instant.
This is currently not supported by
serde
so I thought I would take the opportunity and try to add an implementation for it. I looked at #476 and #949 as starting points.I think the main issue with an
Instant
implementation stems from the following:Duration
is composed of a whole number of seconds and a fractional part represented in nanoseconds.SystemTime
is able to anchor off of UNIX_EPOCH. Therefore, there are ways to obtain the underlying data representing these structs.Since there is nothing similar for
Instant
, and it can only be compared with otherInstant
s, is an implementation for this currently a dead end? I would love to be able to tackle this, but I am not sure if serialization is possible since there is no way to obtain the underlying data representation.The text was updated successfully, but these errors were encountered: