Add 'allow_extra_keys' parameter to dict_of() and dict_of_opt()

This commit is contained in:
Alex 2022-11-17 15:06:42 +01:00
parent e1b6514f24
commit c6e7a42b7e
Signed by: lx
GPG Key ID: 0E496D15096376BE
1 changed files with 22 additions and 12 deletions

View File

@ -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<const N: usize>(
&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<const N: usize>(
&self,
keys: [&'static [u8]; N],
allow_extra_keys: bool,
) -> Result<[Option<Term<'a, '_>>; 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()))))