Skip to main content

deser_core/adapters/bytes/
mod.rs

1//! The adapters and encodings for bytes (see [`adapters`](super#bytes)).
2use alloc::string::String;
3use alloc::vec::Vec;
4
5use crate::BytesFormat;
6use crate::State;
7use crate::error::Error;
8
9mod encodings;
10mod impls;
11
12pub use self::encodings::{Base64, Base64NoPad, Base64Url, Base64UrlNoPad};
13pub use self::impls::{BytesBuf, BytesFallback, BytesFallbackFormat, IntSeq};
14
15#[allow(unused_imports)]
16pub(crate) use self::impls::{BytesBufImpl, encoded_expecting, encoded_handle, encoding_adapter};
17
18pub(crate) use self::encodings::decode_base64;
19
20/// An encoding of bytes as string.
21///
22/// Encodings are types which are not instantiated.  They are used with
23/// [`BytesFormat::encoded`] and every encoding is an adapter which
24/// represents bytes as strings in the encoding (see the
25/// [adapters documentation](super#bytes)).  With [`BytesFallback`] the encoding is
26/// only used in formats without native bytes.
27///
28/// ```
29/// use deser::adapters::BytesEncoding;
30/// use deser::{Error, ErrorKind};
31///
32/// /// Writes bytes as decimal numbers separated by dots.
33/// pub struct Dotted;
34///
35/// impl BytesEncoding for Dotted {
36///     const NAME: &'static str = "dotted";
37///
38///     fn encode(bytes: &[u8], out: &mut String) {
39///         for (idx, byte) in bytes.iter().enumerate() {
40///             if idx > 0 {
41///                 out.push('.');
42///             }
43///             out.push_str(&byte.to_string());
44///         }
45///     }
46///
47///     fn decode(s: &str) -> Result<Vec<u8>, Error> {
48///         if s.is_empty() {
49///             return Ok(Vec::new());
50///         }
51///         s.split('.')
52///             .map(|x| {
53///                 x.parse().map_err(|_| {
54///                     Error::new(ErrorKind::InvalidValue, "invalid byte")
55///                 })
56///             })
57///             .collect()
58///     }
59/// }
60/// ```
61pub trait BytesEncoding: Send + Sync + 'static {
62    /// The name of the encoding.
63    ///
64    /// The name is used in error messages and to compare [`BytesFormat`]s.
65    const NAME: &'static str;
66
67    /// Encodes bytes and appends them to the string.
68    fn encode(bytes: &[u8], out: &mut String);
69
70    /// Decodes a string.
71    fn decode(s: &str) -> Result<Vec<u8>, Error>;
72}
73
74/// Decodes a string into bytes with the format in the state.
75pub(crate) fn decode_str(s: &str, state: &State) -> Result<Vec<u8>, Error> {
76    BytesFormat::of(state).decode(s)
77}