xso: implement TextCodec<_> on all T: base64::engine::Engine
The `xso::text::Base64` struct remains as a shorthand (because frankly, I find the const names in the base64 crate very unwieldly), but you can now use any of the base64 engines as codec.
This commit is contained in:
parent
95773505e4
commit
69787569c9
2 changed files with 53 additions and 8 deletions
|
|
@ -27,6 +27,8 @@ Version NEXT:
|
||||||
jid::DomainPart, and jid::ResourcePart (!485)
|
jid::DomainPart, and jid::ResourcePart (!485)
|
||||||
- Support for optional child elements, the presence of which are
|
- Support for optional child elements, the presence of which are
|
||||||
translated into a boolean (`#[xml(flag)]`).
|
translated into a boolean (`#[xml(flag)]`).
|
||||||
|
- Generic TextCodec implementation for all base64 engines provided by
|
||||||
|
the base64 crate (if the `base64` feature is enabled).
|
||||||
|
|
||||||
Version 0.1.2:
|
Version 0.1.2:
|
||||||
2024-07-26 Jonas Schäfer <jonas@zombofant.net>
|
2024-07-26 Jonas Schäfer <jonas@zombofant.net>
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ use alloc::{
|
||||||
use crate::{error::Error, AsXmlText, FromXmlText};
|
use crate::{error::Error, AsXmlText, FromXmlText};
|
||||||
|
|
||||||
#[cfg(feature = "base64")]
|
#[cfg(feature = "base64")]
|
||||||
use base64::engine::{general_purpose::STANDARD as StandardBase64Engine, Engine as _};
|
use base64::engine::general_purpose::STANDARD as StandardBase64Engine;
|
||||||
|
|
||||||
macro_rules! convert_via_fromstr_and_display {
|
macro_rules! convert_via_fromstr_and_display {
|
||||||
($($(#[cfg $cfg:tt])?$t:ty,)+) => {
|
($($(#[cfg $cfg:tt])?$t:ty,)+) => {
|
||||||
|
|
@ -291,38 +291,47 @@ impl TextFilter for StripWhitespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Text codec transforming text to binary using standard base64.
|
/// Text codec transforming text to binary using standard `base64`.
|
||||||
///
|
///
|
||||||
/// The `Filter` type argument can be used to employ additional preprocessing
|
/// The `Filter` type argument can be used to employ additional preprocessing
|
||||||
/// of incoming text data. Most interestingly, passing [`StripWhitespace`]
|
/// of incoming text data. Most interestingly, passing [`StripWhitespace`]
|
||||||
/// will make the implementation ignore any whitespace within the text.
|
/// will make the implementation ignore any whitespace within the text.
|
||||||
|
///
|
||||||
|
/// `Base64` uses the [`base64::engine::general_purpose::STANDARD`] engine.
|
||||||
|
/// [`TextCodec`] is also automatically implemented for any value which
|
||||||
|
/// implements [`base64::engine::Engine`], allowing you to choose different
|
||||||
|
/// alphabets easily.
|
||||||
#[cfg(feature = "base64")]
|
#[cfg(feature = "base64")]
|
||||||
pub struct Base64;
|
pub struct Base64;
|
||||||
|
|
||||||
#[cfg(feature = "base64")]
|
#[cfg(feature = "base64")]
|
||||||
impl TextCodec<Vec<u8>> for Base64 {
|
impl TextCodec<Vec<u8>> for Base64 {
|
||||||
fn decode(&self, s: String) -> Result<Vec<u8>, Error> {
|
fn decode(&self, s: String) -> Result<Vec<u8>, Error> {
|
||||||
StandardBase64Engine
|
base64::engine::Engine::decode(&StandardBase64Engine, s.as_bytes())
|
||||||
.decode(s.as_bytes())
|
|
||||||
.map_err(Error::text_parse_error)
|
.map_err(Error::text_parse_error)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode<'x>(&self, value: &'x Vec<u8>) -> Result<Option<Cow<'x, str>>, Error> {
|
fn encode<'x>(&self, value: &'x Vec<u8>) -> Result<Option<Cow<'x, str>>, Error> {
|
||||||
Ok(Some(Cow::Owned(StandardBase64Engine.encode(&value))))
|
Ok(Some(Cow::Owned(base64::engine::Engine::encode(
|
||||||
|
&StandardBase64Engine,
|
||||||
|
&value,
|
||||||
|
))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "base64")]
|
#[cfg(feature = "base64")]
|
||||||
impl<'x> TextCodec<Cow<'x, [u8]>> for Base64 {
|
impl<'x> TextCodec<Cow<'x, [u8]>> for Base64 {
|
||||||
fn decode(&self, s: String) -> Result<Cow<'x, [u8]>, Error> {
|
fn decode(&self, s: String) -> Result<Cow<'x, [u8]>, Error> {
|
||||||
StandardBase64Engine
|
base64::engine::Engine::decode(&StandardBase64Engine, s.as_bytes())
|
||||||
.decode(s.as_bytes())
|
|
||||||
.map_err(Error::text_parse_error)
|
.map_err(Error::text_parse_error)
|
||||||
.map(Cow::Owned)
|
.map(Cow::Owned)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode<'a>(&self, value: &'a Cow<'x, [u8]>) -> Result<Option<Cow<'a, str>>, Error> {
|
fn encode<'a>(&self, value: &'a Cow<'x, [u8]>) -> Result<Option<Cow<'a, str>>, Error> {
|
||||||
Ok(Some(Cow::Owned(StandardBase64Engine.encode(&value))))
|
Ok(Some(Cow::Owned(base64::engine::Engine::encode(
|
||||||
|
&StandardBase64Engine,
|
||||||
|
&value,
|
||||||
|
))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -347,6 +356,40 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "base64")]
|
||||||
|
impl<T: base64::engine::Engine> TextCodec<Vec<u8>> for T {
|
||||||
|
fn decode(&self, s: String) -> Result<Vec<u8>, Error> {
|
||||||
|
base64::engine::Engine::decode(self, s.as_bytes()).map_err(Error::text_parse_error)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn encode<'x>(&self, value: &'x Vec<u8>) -> Result<Option<Cow<'x, str>>, Error> {
|
||||||
|
Ok(Some(Cow::Owned(base64::engine::Engine::encode(
|
||||||
|
self, &value,
|
||||||
|
))))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "base64")]
|
||||||
|
impl<'a, T: base64::engine::Engine, U> TextCodec<Option<U>> for T
|
||||||
|
where
|
||||||
|
T: TextCodec<U>,
|
||||||
|
{
|
||||||
|
fn decode(&self, s: String) -> Result<Option<U>, Error> {
|
||||||
|
if s.is_empty() {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
Ok(Some(TextCodec::decode(self, s)?))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn encode<'x>(&self, decoded: &'x Option<U>) -> Result<Option<Cow<'x, str>>, Error> {
|
||||||
|
decoded
|
||||||
|
.as_ref()
|
||||||
|
.map(|x| TextCodec::encode(self, x))
|
||||||
|
.transpose()
|
||||||
|
.map(Option::flatten)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Text codec transforming text to binary using hexadecimal nibbles.
|
/// Text codec transforming text to binary using hexadecimal nibbles.
|
||||||
///
|
///
|
||||||
/// The length must be known at compile-time.
|
/// The length must be known at compile-time.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue