diff --git a/CHANGELOG.md b/CHANGELOG.md index 800ed71..f5247d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Fixed - Add missing `query` property for `sqlserver`, `postgres` and `mysql`, see [#36](https://github.com/BigBoot/AutoKuma/issues/36) +- Fix parsing of recurring maintenance with no effective date range, see [#43](https://github.com/BigBoot/AutoKuma/issues/43) ## [0.6.0] - 2024-04-28 ### Changed diff --git a/kuma-client/src/deserialize.rs b/kuma-client/src/deserialize.rs index cc7f57d..b259551 100644 --- a/kuma-client/src/deserialize.rs +++ b/kuma-client/src/deserialize.rs @@ -237,49 +237,65 @@ impl SerializeAs for SerializeDateTime { } pub(crate) struct SerializeDateRange; -impl<'de> DeserializeAs<'de, Range> for SerializeDateRange { - fn deserialize_as(deserializer: D) -> Result, D::Error> +impl<'de> DeserializeAs<'de, Option>> for SerializeDateRange { + fn deserialize_as(deserializer: D) -> Result>, D::Error> where D: Deserializer<'de>, { - let value = Vec::::deserialize(deserializer) - .map_err(serde::de::Error::custom)? - .into_iter() - .map(|s| PrimitiveDateTime::parse(&s, &Iso8601::DATE_TIME)) - .collect::, _>>() - .map_err(serde::de::Error::custom)?; - - if value.len() != 2 { - return Err(serde::de::Error::custom(format!( - "Expected array of length 2 but got array of length {}", + if let Some(source) = Option::>>::deserialize(deserializer)? { + let value = source + .into_iter() + .map(|o| { + o.map(|s| PrimitiveDateTime::parse(&s, &Iso8601::DATE_TIME)) + .transpose() + }) + .collect::, _>>() + .map_err(serde::de::Error::custom)?; + + match value.len() { + 1 if value[0].is_none() => Ok(None), + 2 => { + let mut iter = value.into_iter(); + Ok(Some(Range { + start: iter.next().unwrap().unwrap(), + end: iter.next().unwrap().unwrap(), + })) + } + _ => Err(serde::de::Error::custom(format!( + "Expected DateRange to be [Null] or array of length 2 but got array of length {}", value.len() - ))); - }; - - let mut iter = value.into_iter(); - Ok(Range { - start: iter.next().unwrap(), - end: iter.next().unwrap(), - }) + ))), + } + } else { + Ok(None) + } } } -impl SerializeAs> for SerializeDateRange { - fn serialize_as(source: &Range, serializer: S) -> Result +impl SerializeAs>> for SerializeDateRange { + fn serialize_as( + source: &Option>, + serializer: S, + ) -> Result where S: serde::Serializer, { - vec![ - &source - .start - .format(&Iso8601::DATE_TIME) - .map_err(serde::ser::Error::custom)?, - &source - .end - .format(&Iso8601::DATE_TIME) - .map_err(serde::ser::Error::custom)?, - ] - .serialize(serializer) + let values = match &source { + None => vec![None], + Some(Range { start, end }) => vec![ + Some( + start + .format(&Iso8601::DATE_TIME) + .map_err(serde::ser::Error::custom)?, + ), + Some( + end.format(&Iso8601::DATE_TIME) + .map_err(serde::ser::Error::custom)?, + ), + ], + }; + + values.serialize(serializer) } } diff --git a/kuma-client/src/models/maintenance.rs b/kuma-client/src/models/maintenance.rs index ae01bc1..b54092c 100644 --- a/kuma-client/src/models/maintenance.rs +++ b/kuma-client/src/models/maintenance.rs @@ -287,7 +287,8 @@ pub struct MaintenanceCommon { #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct MaintenanceSchedule { #[serde(rename = "dateRange")] - #[serde_as(as = "Option")] + #[serde_as(as = "SerializeDateRange")] + #[serialize_always] pub date_range: Option>, #[serde(rename = "timeRange")]