From c6e7a42b7e455b6e779aa3556a294bfcb2c52f3e Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Thu, 17 Nov 2022 15:06:42 +0100 Subject: [PATCH] Add 'allow_extra_keys' parameter to dict_of() and dict_of_opt() --- src/dec/mod.rs | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/dec/mod.rs b/src/dec/mod.rs index 9c1e7d7..2d86e1a 100644 --- a/src/dec/mod.rs +++ b/src/dec/mod.rs @@ -262,14 +262,17 @@ impl<'a, 'b> Term<'a, 'b> { /// ``` /// use nettext::dec::decode; /// - /// let term = decode(b"{ k1 = v1, k2 = v2 }").unwrap(); - /// let [s1, s2] = term.dict_of([b"k1", b"k2"]).unwrap(); + /// let term = decode(b"{ k1 = v1, k2 = v2, k3 = v3 }").unwrap(); + /// let [s1, s2] = term.dict_of([b"k1", b"k2"], true).unwrap(); /// assert_eq!(s1.str().unwrap(), b"v1"); /// assert_eq!(s2.str().unwrap(), b"v2"); + /// + /// assert!(term.dict_of([b"k1", b"k2"], false).is_err()); /// ``` pub fn dict_of( &self, keys: [&'static [u8]; N], + allow_extra_keys: bool, ) -> Result<[Term<'a, '_>; N], TypeError> { match self.0.mkref() { AnyTerm::DictRef(_, dict) => { @@ -279,10 +282,12 @@ impl<'a, 'b> Term<'a, 'b> { return Err(TypeError::MissingKey(debug(k).to_string())); } } - // Check that dictionnary contains no extraneous keys - for k in dict.keys() { - if !keys.contains(k) { - return Err(TypeError::UnexpectedKey(debug(k).to_string())); + if !allow_extra_keys { + // Check that dictionnary contains no extraneous keys + for k in dict.keys() { + if !keys.contains(k) { + return Err(TypeError::UnexpectedKey(debug(k).to_string())); + } } } Ok(keys.map(|k| Term(dict.get(k).unwrap().mkref()))) @@ -299,22 +304,27 @@ impl<'a, 'b> Term<'a, 'b> { /// ``` /// use nettext::dec::decode; /// - /// let term = decode(b"{ k1 = v1, k2 = v2 }").unwrap(); - /// let [s1, s2, s3] = term.dict_of_opt([b"k1", b"k2", b"k3"]).unwrap(); + /// let term = decode(b"{ k1 = v1, k2 = v2, k4 = v4 }").unwrap(); + /// let [s1, s2, s3] = term.dict_of_opt([b"k1", b"k2", b"k3"], true).unwrap(); /// assert_eq!(s1.unwrap().str().unwrap(), b"v1"); /// assert_eq!(s2.unwrap().str().unwrap(), b"v2"); /// assert!(s3.is_none()); + /// + /// assert!(term.dict_of_opt([b"k1", b"k2", b"k3"], false).is_err()); /// ``` pub fn dict_of_opt( &self, keys: [&'static [u8]; N], + allow_extra_keys: bool, ) -> Result<[Option>; N], TypeError> { match self.0.mkref() { AnyTerm::DictRef(_, dict) => { - // Check that dictionnary contains no extraneous keys - for k in dict.keys() { - if !keys.contains(k) { - return Err(TypeError::UnexpectedKey(debug(k).to_string())); + if !allow_extra_keys { + // Check that dictionnary contains no extraneous keys + for k in dict.keys() { + if !keys.contains(k) { + return Err(TypeError::UnexpectedKey(debug(k).to_string())); + } } } Ok(keys.map(|k| dict.get(k).map(|x| Term(x.mkref()))))