Skip to content

Commit

Permalink
Fix time_repr bounds
Browse files Browse the repository at this point in the history
  • Loading branch information
RReverser committed Sep 19, 2024
1 parent c42f5cb commit d0e5b70
Showing 1 changed file with 21 additions and 9 deletions.
30 changes: 21 additions & 9 deletions src/api/time_repr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ use crate::response::ValueResponse;
use serde::{Deserialize, Serialize};
use std::marker::PhantomData;
use std::time::SystemTime;
use time::formatting::Formattable;
use time::macros::format_description;
use time::parsing::Parsable;
use time::{format_description, OffsetDateTime};

pub(crate) trait FormatWrapper: std::fmt::Debug {
type Format: 'static + ?Sized + Parsable + Formattable;
type Format: 'static + ?Sized;

const FORMAT: &'static Self::Format;
}
Expand Down Expand Up @@ -48,28 +46,39 @@ impl<F> From<TimeParam<F>> for SystemTime {
}
}

impl<F: FormatWrapper> Serialize for TimeParam<F> {
#[cfg(feature = "server")]
impl<F: FormatWrapper> Serialize for TimeParam<F>
where
F::Format: time::formatting::Formattable,
{
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.0
.format(&F::FORMAT)
.format(F::FORMAT)
.map_err(serde::ser::Error::custom)?
.serialize(serializer)
}
}

impl<'de, F: FormatWrapper> Deserialize<'de> for TimeParam<F> {
#[cfg(feature = "client")]
impl<'de, F: FormatWrapper> Deserialize<'de> for TimeParam<F>
where
F::Format: time::parsing::Parsable,
{
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
struct Visitor<F>(PhantomData<F>);

impl<F: FormatWrapper> serde::de::Visitor<'_> for Visitor<F> {
impl<F: FormatWrapper> serde::de::Visitor<'_> for Visitor<F>
where
F::Format: time::parsing::Parsable,
{
type Value = TimeParam<F>;

fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str("a date string")
}

fn visit_str<E: serde::de::Error>(self, value: &str) -> Result<Self::Value, E> {
match time::PrimitiveDateTime::parse(value, &F::FORMAT) {
match time::PrimitiveDateTime::parse(value, F::FORMAT) {
Ok(value) => Ok(TimeParam(value.assume_utc(), PhantomData)),
Err(err) => Err(serde::de::Error::custom(err)),
}
Expand All @@ -81,7 +90,10 @@ impl<'de, F: FormatWrapper> Deserialize<'de> for TimeParam<F> {
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(bound = "F: FormatWrapper")]
#[serde(bound(
serialize = "TimeParam<F>: Serialize",
deserialize = "TimeParam<F>: Deserialize<'de>"
))]
#[serde(transparent)]
pub(crate) struct TimeResponse<F>(ValueResponse<TimeParam<F>>);

Expand Down

0 comments on commit d0e5b70

Please sign in to comment.