jingle_rtp: Put Channel code into a macro, to generate it automatically.

Emmanuel Gil Peyrot created

Change summary

src/jingle_rtp.rs  | 35 ++++-------------------------------
src/util/macros.rs | 24 ++++++++++++++++++++++++
2 files changed, 28 insertions(+), 31 deletions(-)

Detailed changes

src/jingle_rtp.rs 🔗

@@ -4,10 +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/.
 
-use std::num::ParseIntError;
-use std::str::FromStr;
-use minidom::IntoAttributeValue;
-
 generate_element!(
     /// Wrapper element describing an RTP session.
     Description, "description", JINGLE_RTP,
@@ -28,33 +24,10 @@ generate_element!(
     ]
 );
 
-/// The number of channels.
-#[derive(Debug, Clone)]
-pub struct Channels(pub u8);
-
-impl Default for Channels {
-    fn default() -> Channels {
-        Channels(1)
-    }
-}
-
-impl FromStr for Channels {
-    type Err = ParseIntError;
-
-    fn from_str(s: &str) -> Result<Channels, ParseIntError> {
-        Ok(Channels(u8::from_str(s)?))
-    }
-}
-
-impl IntoAttributeValue for Channels {
-    fn into_attribute_value(self) -> Option<String> {
-        if self.0 == 1 {
-            None
-        } else {
-            Some(format!("{}", self.0))
-        }
-    }
-}
+generate_attribute!(
+    /// The number of channels.
+    Channels, "channels", u8, Default = 1
+);
 
 generate_element!(
     /// An encoding that can be used for an RTP stream.

src/util/macros.rs 🔗

@@ -191,6 +191,30 @@ macro_rules! generate_attribute {
             }
         }
     );
+    ($(#[$meta:meta])* $elem:ident, $name:tt, $type:tt, Default = $default:expr) => (
+        $(#[$meta])*
+        #[derive(Debug, Clone, PartialEq)]
+        pub struct $elem(pub $type);
+        impl ::std::str::FromStr for $elem {
+            type Err = crate::util::error::Error;
+            fn from_str(s: &str) -> Result<Self, crate::util::error::Error> {
+                Ok($elem($type::from_str(s)?))
+            }
+        }
+        impl ::minidom::IntoAttributeValue for $elem {
+            fn into_attribute_value(self) -> Option<String> {
+                match self {
+                    $elem($default) => None,
+                    $elem(value) => Some(format!("{}", value)),
+                }
+            }
+        }
+        impl ::std::default::Default for $elem {
+            fn default() -> $elem {
+                $elem($default)
+            }
+        }
+    );
 }
 
 macro_rules! generate_element_enum {