Skip to content

Commit

Permalink
xml: Differentiate between ValueSerialize and ValueDeserialize to pre…
Browse files Browse the repository at this point in the history
…vent unwraps
  • Loading branch information
lennart-k committed Jan 15, 2025
1 parent 4da975c commit 807335d
Show file tree
Hide file tree
Showing 9 changed files with 35 additions and 27 deletions.
7 changes: 5 additions & 2 deletions crates/caldav/src/calendar/methods/report/sync_collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rustical_store::{
synctoken::{format_synctoken, parse_synctoken},
CalendarStore,
};
use rustical_xml::{Value, XmlDeserialize};
use rustical_xml::{ValueDeserialize, ValueSerialize, XmlDeserialize};

use crate::{
calendar_object::resource::{CalendarObjectProp, CalendarObjectResource},
Expand All @@ -22,7 +22,7 @@ pub(crate) enum SyncLevel {
Infinity,
}

impl Value for SyncLevel {
impl ValueDeserialize for SyncLevel {
fn deserialize(val: &str) -> Result<Self, rustical_xml::XmlDeError> {
Ok(match val {
"1" => Self::One,
Expand All @@ -34,6 +34,9 @@ impl Value for SyncLevel {
}
})
}
}

impl ValueSerialize for SyncLevel {
fn serialize(&self) -> String {
match self {
SyncLevel::One => "1",
Expand Down
6 changes: 3 additions & 3 deletions crates/caldav/src/calendar/prop.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use derive_more::derive::From;
use rustical_xml::{XmlDeserialize, XmlSerialize};
use rustical_xml::XmlSerialize;

#[derive(Debug, Clone, XmlDeserialize, XmlSerialize, PartialEq, From)]
#[derive(Debug, Clone, XmlSerialize, PartialEq, From)]
pub struct SupportedCalendarComponent {
#[xml(ty = "attr")]
pub name: &'static str,
}

#[derive(Debug, Clone, XmlDeserialize, XmlSerialize, PartialEq)]
#[derive(Debug, Clone, XmlSerialize, PartialEq)]
pub struct SupportedCalendarComponentSet {
#[xml(ns = "rustical_dav::namespace::NS_CALDAV", flatten)]
pub comp: Vec<SupportedCalendarComponent>,
Expand Down
2 changes: 1 addition & 1 deletion crates/caldav/src/principal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub enum PrincipalProp {
Displayname(String),

// Scheduling Extensions to CalDAV (RFC 6638)
#[xml(ns = "rustical_dav::namespace::NS_CALDAV")]
#[xml(ns = "rustical_dav::namespace::NS_CALDAV", skip_deserializing)]
CalendarUserType(&'static str),
#[xml(ns = "rustical_dav::namespace::NS_CALDAV")]
CalendarUserAddressSet(HrefElement),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ use rustical_store::{
synctoken::{format_synctoken, parse_synctoken},
AddressbookStore,
};
use rustical_xml::{Value, XmlDeserialize};
use rustical_xml::{ValueDeserialize, ValueSerialize, XmlDeserialize};

#[derive(Clone, Debug, PartialEq)]
pub(crate) enum SyncLevel {
One,
Infinity,
}

impl Value for SyncLevel {
impl ValueDeserialize for SyncLevel {
fn deserialize(val: &str) -> Result<Self, rustical_xml::XmlDeError> {
Ok(match val {
"1" => Self::One,
Expand All @@ -33,6 +33,8 @@ impl Value for SyncLevel {
}
})
}
}
impl ValueSerialize for SyncLevel {
fn serialize(&self) -> String {
match self {
SyncLevel::One => "1",
Expand Down
8 changes: 5 additions & 3 deletions crates/store/src/calendar/timestamp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use ical::{
property::Property,
};
use lazy_static::lazy_static;
use rustical_xml::Value;
use rustical_xml::{ValueDeserialize, ValueSerialize};
use std::{collections::HashMap, ops::Add};

lazy_static! {
Expand All @@ -21,9 +21,9 @@ pub const LOCAL_DATE: &str = "%Y%m%d";
#[derive(Debug, Clone, Deref, PartialEq)]
pub struct UtcDateTime(DateTime<Utc>);

impl Value for UtcDateTime {
impl ValueDeserialize for UtcDateTime {
fn deserialize(val: &str) -> Result<Self, rustical_xml::XmlDeError> {
let input = <String as Value>::deserialize(val)?;
let input = <String as ValueDeserialize>::deserialize(val)?;
Ok(Self(
NaiveDateTime::parse_from_str(&input, UTC_DATE_TIME)
.map_err(|_| {
Expand All @@ -32,6 +32,8 @@ impl Value for UtcDateTime {
.and_utc(),
))
}
}
impl ValueSerialize for UtcDateTime {
fn serialize(&self) -> String {
format!("{}", self.0.format(UTC_DATE_TIME))
}
Expand Down
8 changes: 4 additions & 4 deletions crates/xml/derive/src/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ impl Field {
let builder_field_ident = self.builder_field_ident();
let value = wrap_option_if_no_default(
quote! {
rustical_xml::Value::deserialize(text.as_ref())?
::rustical_xml::ValueDeserialize::deserialize(text.as_ref())?
},
self.attrs.default.is_some(),
);
Expand All @@ -250,8 +250,8 @@ impl Field {

let value = wrap_option_if_no_default(
quote! {
rustical_xml::Value::deserialize(attr.unescape_value()?.as_ref())?
},
::rustical_xml::ValueDeserialize::deserialize(attr.unescape_value()?.as_ref())?
},
self.attrs.default.is_some(),
);

Expand All @@ -270,7 +270,7 @@ impl Field {

let value = wrap_option_if_no_default(
quote! {
rustical_xml::Value::deserialize(&String::from_utf8_lossy(name.as_ref()))?
rustical_xml::ValueDeserialize::deserialize(&String::from_utf8_lossy(name.as_ref()))?
},
self.attrs.default.is_some(),
);
Expand Down
2 changes: 1 addition & 1 deletion crates/xml/derive/src/xml_struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ impl NamedStruct {
quote! {
::quick_xml::events::attributes::Attribute {
key: ::quick_xml::name::QName(#field_name),
value: ::std::borrow::Cow::from(::rustical_xml::Value::serialize(&self.#field_index).into_bytes())
value: ::std::borrow::Cow::from(::rustical_xml::ValueSerialize::serialize(&self.#field_index).into_bytes())
}
}
});
Expand Down
2 changes: 1 addition & 1 deletion crates/xml/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub use de::XmlDocument;
pub use error::XmlDeError;
pub use se::XmlSerialize;
pub use se::XmlSerializeRoot;
pub use value::Value;
pub use value::{ParseValueError, ValueDeserialize, ValueSerialize};
pub use xml_derive::XmlRootTag;

impl XmlDeserialize for () {
Expand Down
21 changes: 11 additions & 10 deletions crates/xml/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,23 @@ pub enum ParseValueError {
ParseFloatError(#[from] ParseFloatError),
}

pub trait Value: Sized {
pub trait ValueSerialize: Sized {
fn serialize(&self) -> String;
}

pub trait ValueDeserialize: Sized {
fn deserialize(val: &str) -> Result<Self, XmlDeError>;
}

macro_rules! impl_value_parse {
($t:ty) => {
impl Value for $t {
impl ValueSerialize for $t {
fn serialize(&self) -> String {
self.to_string()
}
}

impl ValueDeserialize for $t {
fn deserialize(val: &str) -> Result<Self, XmlDeError> {
val.parse()
.map_err(ParseValueError::from)
Expand All @@ -52,17 +57,13 @@ impl_value_parse!(u64);
impl_value_parse!(isize);
impl_value_parse!(usize);

impl Value for &str {
impl ValueSerialize for &str {
fn serialize(&self) -> String {
self.to_string()
}

fn deserialize(_val: &str) -> Result<Self, XmlDeError> {
Err(XmlDeError::Other("TODO: Handle this error".to_owned()))
}
}

impl<T: Value> XmlDeserialize for T {
impl<T: ValueDeserialize> XmlDeserialize for T {
fn deserialize<R: BufRead>(
reader: &mut quick_xml::NsReader<R>,
_start: &BytesStart,
Expand All @@ -88,11 +89,11 @@ impl<T: Value> XmlDeserialize for T {
}
}

Value::deserialize(&string)
ValueDeserialize::deserialize(&string)
}
}

impl<T: Value> XmlSerialize for T {
impl<T: ValueSerialize> XmlSerialize for T {
fn serialize<W: std::io::Write>(
&self,
ns: Option<Namespace>,
Expand Down

0 comments on commit 807335d

Please sign in to comment.