xmpp-parsers: Remove util::text_node_codecs

Emmanuel Gil Peyrot created

This codec system was useful for the previous parser style, but we have
converted them all to xso now!

Change summary

parsers/src/util/macros.rs           |  34 ----
parsers/src/util/mod.rs              |   3 
parsers/src/util/text_node_codecs.rs | 217 ------------------------------
3 files changed, 1 insertion(+), 253 deletions(-)

Detailed changes

parsers/src/util/macros.rs πŸ”—

@@ -693,13 +693,7 @@ macro_rules! generate_element {
     ($(#[$meta:meta])* $elem:ident, $name:tt, $ns:ident, children: [$($(#[$child_meta:meta])* $child_ident:ident: $coucou:tt<$child_type:ty> = ($child_name:tt, $child_ns:tt) => $child_constructor:ident),+$(,)?]) => (
         generate_element!($(#[$meta])* $elem, $name, $ns, attributes: [], children: [$($(#[$child_meta])* $child_ident: $coucou<$child_type> = ($child_name, $child_ns) => $child_constructor),*]);
     );
-    ($(#[$meta:meta])* $elem:ident, $name:tt, $ns:ident, text: ($(#[$text_meta:meta])* $text_ident:ident: $codec:ty )) => (
-        generate_element!($(#[$meta])* $elem, $name, $ns, attributes: [], children: [], text: ($(#[$text_meta])* $text_ident: $codec));
-    );
-    ($(#[$meta:meta])* $elem:ident, $name:tt, $ns:ident, attributes: [$($(#[$attr_meta:meta])* $attr:ident: $attr_action:tt<$attr_type:ty> = $attr_name:tt),+$(,)?], text: ($(#[$text_meta:meta])* $text_ident:ident: $codec:ty )) => (
-        generate_element!($(#[$meta])* $elem, $name, $ns, attributes: [$($(#[$attr_meta])* $attr: $attr_action<$attr_type> = $attr_name),*], children: [], text: ($(#[$text_meta])* $text_ident: $codec));
-    );
-    ($(#[$meta:meta])* $elem:ident, $name:tt, $ns:ident, attributes: [$($(#[$attr_meta:meta])* $attr:ident: $attr_action:tt<$attr_type:ty> = $attr_name:tt),*$(,)?], children: [$($(#[$child_meta:meta])* $child_ident:ident: $coucou:tt<$child_type:ty> = ($child_name:tt, $child_ns:tt) => $child_constructor:ident),*$(,)?] $(, text: ($(#[$text_meta:meta])* $text_ident:ident: $codec:ty ))*) => (
+    ($(#[$meta:meta])* $elem:ident, $name:tt, $ns:ident, attributes: [$($(#[$attr_meta:meta])* $attr:ident: $attr_action:tt<$attr_type:ty> = $attr_name:tt),*$(,)?], children: [$($(#[$child_meta:meta])* $child_ident:ident: $coucou:tt<$child_type:ty> = ($child_name:tt, $child_ns:tt) => $child_constructor:ident),*$(,)?]) => (
         $(#[$meta])*
         #[derive(Debug, Clone, PartialEq)]
         pub struct $elem {
@@ -711,10 +705,6 @@ macro_rules! generate_element {
                 $(#[$child_meta])*
                 pub $child_ident: start_decl!($coucou, $child_type),
             )*
-            $(
-                $(#[$text_meta])*
-                pub $text_ident: <$codec as Codec>::Decoded,
-            )*
         }
 
         impl ::xso::FromXml for $elem {
@@ -743,22 +733,6 @@ macro_rules! generate_element {
                 $(
                     start_parse_elem!($child_ident: $coucou);
                 )*
-                // We must pull the texts out of the Element before we pull
-                // the children, because take_elements_as_children drains
-                // *all* child nodes, including texts.
-                // To deal with the genericity of this macro, we need a local
-                // struct decl to carry the identifier around.
-                struct Texts {
-                    $(
-                        $text_ident: <$codec as Codec>::Decoded,
-                    )*
-                }
-                #[allow(unused_variables)]
-                let texts = Texts {
-                    $(
-                        $text_ident: <$codec>::decode(&elem.text())?,
-                    )*
-                };
                 for _child in elem.take_contents_as_children() {
                     let residual = _child;
                     $(
@@ -783,9 +757,6 @@ macro_rules! generate_element {
                     $(
                         $child_ident: finish_parse_elem!($child_ident: $coucou = $child_name, $name),
                     )*
-                    $(
-                        $text_ident: texts.$text_ident,
-                    )*
                 })
             }
         }
@@ -799,9 +770,6 @@ macro_rules! generate_element {
                 $(
                     builder = generate_serialiser!(builder, elem, $child_ident, $coucou, $child_constructor, ($child_name, $child_ns));
                 )*
-                $(
-                    builder = builder.append_all(<$codec>::encode(&elem.$text_ident).map(::minidom::Node::Text).into_iter());
-                )*
 
                 builder.build()
             }

parsers/src/util/mod.rs πŸ”—

@@ -4,9 +4,6 @@
 // License, v. 2.0. If a copy of the MPL was not distributed with this
 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-/// Various helpers.
-pub(crate) mod text_node_codecs;
-
 /// Helper macros to parse and serialise more easily.
 #[macro_use]
 mod macros;

parsers/src/util/text_node_codecs.rs πŸ”—

@@ -1,217 +0,0 @@
-// Copyright (c) 2017 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-use base64::{engine::general_purpose::STANDARD as Base64Engine, Engine};
-use xso::error::Error;
-
-/// A trait for codecs that can decode and encode text nodes.
-pub trait Codec {
-    type Decoded;
-
-    /// Decode the given string into the codec’s output.
-    fn decode(s: &str) -> Result<Self::Decoded, Error>;
-
-    /// Encode the given value; return None to not produce a text node at all.
-    fn encode(decoded: &Self::Decoded) -> Option<String>;
-}
-
-/// Codec for text content.
-pub struct Text;
-
-impl Codec for Text {
-    type Decoded = String;
-
-    fn decode(s: &str) -> Result<String, Error> {
-        Ok(s.to_owned())
-    }
-
-    fn encode(decoded: &String) -> Option<String> {
-        Some(decoded.to_owned())
-    }
-}
-
-/// Codec transformer that makes the text optional; a "" string is decoded as None.
-pub struct OptionalCodec<T: Codec>(std::marker::PhantomData<T>);
-
-impl<T> Codec for OptionalCodec<T>
-where
-    T: Codec,
-{
-    type Decoded = Option<T::Decoded>;
-
-    fn decode(s: &str) -> Result<Option<T::Decoded>, Error> {
-        if s.is_empty() {
-            return Ok(None);
-        }
-
-        Ok(Some(T::decode(s)?))
-    }
-
-    fn encode(decoded: &Option<T::Decoded>) -> Option<String> {
-        decoded.as_ref().and_then(T::encode)
-    }
-}
-
-/// Codec that trims whitespace around the text.
-pub struct Trimmed<T: Codec>(std::marker::PhantomData<T>);
-
-impl<T> Codec for Trimmed<T>
-where
-    T: Codec,
-{
-    type Decoded = T::Decoded;
-
-    fn decode(s: &str) -> Result<T::Decoded, Error> {
-        match s.trim() {
-            // TODO: This error message can be a bit opaque when used
-            // in-context; ideally it'd be configurable.
-            "" => Err(Error::Other(
-                "The text in the element's text node was empty after trimming.",
-            )),
-            trimmed => T::decode(trimmed),
-        }
-    }
-
-    fn encode(decoded: &T::Decoded) -> Option<String> {
-        T::encode(decoded)
-    }
-}
-
-/// Codec wrapping that encodes/decodes a string as base64.
-pub struct Base64;
-
-impl Codec for Base64 {
-    type Decoded = Vec<u8>;
-
-    fn decode(s: &str) -> Result<Vec<u8>, Error> {
-        Base64Engine.decode(s).map_err(Error::text_parse_error)
-    }
-
-    fn encode(decoded: &Vec<u8>) -> Option<String> {
-        Some(Base64Engine.encode(decoded))
-    }
-}
-
-/// Codec wrapping base64 encode/decode, while ignoring whitespace characters.
-pub struct WhitespaceAwareBase64;
-
-impl Codec for WhitespaceAwareBase64 {
-    type Decoded = Vec<u8>;
-
-    fn decode(s: &str) -> Result<Self::Decoded, Error> {
-        let s: String = s
-            .chars()
-            .filter(|ch| *ch != ' ' && *ch != '\n' && *ch != '\t')
-            .collect();
-
-        Base64Engine.decode(s).map_err(Error::text_parse_error)
-    }
-
-    fn encode(decoded: &Self::Decoded) -> Option<String> {
-        Some(Base64Engine.encode(decoded))
-    }
-}
-
-/// Codec for bytes of lowercase hexadecimal, with a fixed length `N` (in bytes).
-pub struct FixedHex<const N: usize>;
-
-impl<const N: usize> Codec for FixedHex<N> {
-    type Decoded = [u8; N];
-
-    fn decode(s: &str) -> Result<Self::Decoded, Error> {
-        if s.len() != 2 * N {
-            return Err(Error::Other("Invalid length"));
-        }
-
-        let mut bytes = [0u8; N];
-        for i in 0..N {
-            bytes[i] =
-                u8::from_str_radix(&s[2 * i..2 * i + 2], 16).map_err(Error::text_parse_error)?;
-        }
-
-        Ok(bytes)
-    }
-
-    fn encode(decoded: &Self::Decoded) -> Option<String> {
-        let mut bytes = String::with_capacity(N * 2);
-        for byte in decoded {
-            bytes.extend(format!("{:02x}", byte).chars());
-        }
-        Some(bytes)
-    }
-}
-
-/// Codec for colon-separated bytes of uppercase hexadecimal.
-pub struct ColonSeparatedHex;
-
-impl Codec for ColonSeparatedHex {
-    type Decoded = Vec<u8>;
-
-    fn decode(s: &str) -> Result<Self::Decoded, Error> {
-        let mut bytes = vec![];
-        for i in 0..(1 + s.len()) / 3 {
-            let byte =
-                u8::from_str_radix(&s[3 * i..3 * i + 2], 16).map_err(Error::text_parse_error)?;
-            if 3 * i + 2 < s.len() {
-                assert_eq!(&s[3 * i + 2..3 * i + 3], ":");
-            }
-            bytes.push(byte);
-        }
-        Ok(bytes)
-    }
-
-    fn encode(decoded: &Self::Decoded) -> Option<String> {
-        let mut bytes = vec![];
-        for byte in decoded {
-            bytes.push(format!("{:02X}", byte));
-        }
-        Some(bytes.join(":"))
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn fixed_hex() {
-        let value = [0x01, 0xfe, 0xef];
-
-        // Test that we support both lowercase and uppercase as input.
-        let hex = FixedHex::<3>::decode("01feEF").unwrap();
-        assert_eq!(&hex, &value);
-
-        // Test that we do output lowercase.
-        let hex = FixedHex::<3>::encode(&value).unwrap();
-        assert_eq!(hex, "01feef");
-
-        // What if we give it a string that's too long?
-        let err = FixedHex::<3>::decode("01feEF01").unwrap_err();
-        assert_eq!(err.to_string(), "Invalid length");
-
-        // Too short?
-        let err = FixedHex::<3>::decode("01fe").unwrap_err();
-        assert_eq!(err.to_string(), "Invalid length");
-
-        // Not-even numbers?
-        let err = FixedHex::<3>::decode("01feE").unwrap_err();
-        assert_eq!(err.to_string(), "Invalid length");
-
-        // No colon supported.
-        let err = FixedHex::<3>::decode("0:f:EF").unwrap_err();
-        assert_eq!(
-            err.to_string(),
-            "text parse error: invalid digit found in string"
-        );
-
-        // No non-hex character allowed.
-        let err = FixedHex::<3>::decode("01defg").unwrap_err();
-        assert_eq!(
-            err.to_string(),
-            "text parse error: invalid digit found in string"
-        );
-    }
-}