Skip to content

Instantly share code, notes, and snippets.

@Gricha
Created December 11, 2017 02:39
Show Gist options
  • Save Gricha/21d58b59fb65fb4eeb5f0af8640ca4a2 to your computer and use it in GitHub Desktop.
Save Gricha/21d58b59fb65fb4eeb5f0af8640ca4a2 to your computer and use it in GitHub Desktop.
Timestamp from String
use std::fmt;
use serde::de;
use chrono::{DateTime, Utc, FixedOffset};
use chrono::offset::{LocalResult, TimeZone};
pub fn deserialize<'de, D>(d: D) -> Result<DateTime<Utc>, D::Error>
where D: de::Deserializer<'de>
{
Ok(try!(d.deserialize_i64(SecondsTimestampVisitor).map(|dt| dt.with_timezone(&Utc))))
}
struct SecondsTimestampVisitor;
impl<'de> de::Visitor<'de> for SecondsTimestampVisitor {
type Value = DateTime<FixedOffset>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result
{
write!(formatter, "a unix timestamp in seconds")
}
/// Deserialize a timestamp in seconds since the epoch
fn visit_i64<E>(self, value: i64) -> Result<DateTime<FixedOffset>, E>
where E: de::Error
{
from(FixedOffset::east(0).timestamp_opt(value, 0), &value)
}
/// Deserialize a timestamp in seconds since the epoch
fn visit_u64<E>(self, value: u64) -> Result<DateTime<FixedOffset>, E>
where E: de::Error
{
from(FixedOffset::east(0).timestamp_opt(value as i64, 0), &value)
}
fn visit_str<E>(self, value: &str) -> Result<DateTime<FixedOffset>, E>
where E: de::Error
{
let ts: i64 = value.parse()
.map_err(|e| E::custom(format!("Unable to parse timestamp as int: {}", e)))?;
self.visit_i64(ts)
}
}
// try!-like function to convert a LocalResult into a serde-ish Result
fn from<T, E, V>(me: LocalResult<T>, ts: &V) -> Result<T, E>
where E: de::Error,
V: fmt::Display,
T: fmt::Display,
{
match me {
LocalResult::None => Err(E::custom(
format!("value is not a legal timestamp: {}", ts))),
LocalResult::Ambiguous(min, max) => Err(E::custom(
format!("value is an ambiguous timestamp: {}, could be either of {}, {}",
ts, min, max))),
LocalResult::Single(val) => Ok(val)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment