xso: Allow any T: FromXmlText + AsXmlText in EmptyAsNone
This text codec was previously implemented only for Option<String>, this extends it to all types implementing those two traits, such as numbers or JIDs.
This commit is contained in:
parent
2b346c4e87
commit
7f5b6fec7f
1 changed files with 19 additions and 10 deletions
|
|
@ -123,7 +123,7 @@ convert_via_fromstr_and_display! {
|
||||||
|
|
||||||
/// Represent a way to encode/decode text data into a Rust type.
|
/// Represent a way to encode/decode text data into a Rust type.
|
||||||
///
|
///
|
||||||
/// This trait can be used in scenarios where implementing [`FromXmlText`]
|
/// This trait can be used in scenarios where implementing [`FromXmlText`]
|
||||||
/// and/or [`AsXmlText`] on a type is not feasible or sensible, such as the
|
/// and/or [`AsXmlText`] on a type is not feasible or sensible, such as the
|
||||||
/// following:
|
/// following:
|
||||||
///
|
///
|
||||||
|
|
@ -202,23 +202,32 @@ impl TextCodec<String> for Plain {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Text codec which returns None instead of the empty string.
|
/// Text codec which returns `None` if the input to decode is the empty string, instead of
|
||||||
|
/// attempting to decode it.
|
||||||
|
///
|
||||||
|
/// Particularly useful when parsing `Option<T>` on `#[xml(text)]`, which does not support
|
||||||
|
/// `Option<_>` otherwise.
|
||||||
pub struct EmptyAsNone;
|
pub struct EmptyAsNone;
|
||||||
|
|
||||||
impl TextCodec<Option<String>> for EmptyAsNone {
|
impl<T> TextCodec<Option<T>> for EmptyAsNone
|
||||||
fn decode(&self, s: String) -> Result<Option<String>, Error> {
|
where
|
||||||
|
T: FromXmlText + AsXmlText,
|
||||||
|
{
|
||||||
|
fn decode(&self, s: String) -> Result<Option<T>, Error> {
|
||||||
if s.is_empty() {
|
if s.is_empty() {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
} else {
|
} else {
|
||||||
Ok(Some(s))
|
Some(T::from_xml_text(s)).transpose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode<'x>(&self, value: &'x Option<String>) -> Result<Option<Cow<'x, str>>, Error> {
|
fn encode<'x>(&self, value: &'x Option<T>) -> Result<Option<Cow<'x, str>>, Error> {
|
||||||
Ok(match value.as_ref() {
|
Ok(value
|
||||||
Some(v) if !v.is_empty() => Some(Cow::Borrowed(v.as_str())),
|
.as_ref()
|
||||||
Some(_) | None => None,
|
.map(AsXmlText::as_xml_text)
|
||||||
})
|
.transpose()?
|
||||||
|
.map(|v| (!v.is_empty()).then_some(v))
|
||||||
|
.flatten())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue