From 380f916bd60e65b25845cfe728b99e9a2c9e300b Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 26 Apr 2022 15:05:34 -0500 Subject: [PATCH] feat: Add `Table*::get_key_value*` This is inspired by `indexmap` --- src/inline_table.rs | 28 ++++++++++++++++++++++++++++ src/table.rs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/src/inline_table.rs b/src/inline_table.rs index dd028f64..00c0cf2d 100644 --- a/src/inline_table.rs +++ b/src/inline_table.rs @@ -259,6 +259,28 @@ impl InlineTable { .and_then(|kv| kv.value.as_value_mut()) } + /// Return references to the key-value pair stored for key, if it is present, else None. + pub fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> { + self.items.get(key).and_then(|kv| { + if !kv.value.is_none() { + Some((&kv.key, &kv.value)) + } else { + None + } + }) + } + + /// Return mutable references to the key-value pair stored for key, if it is present, else None. + pub fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> { + self.items.get_mut(key).and_then(|kv| { + if !kv.value.is_none() { + Some((kv.key.as_mut(), &mut kv.value)) + } else { + None + } + }) + } + /// Returns true iff the table contains given key. pub fn contains_key(&self, key: &str) -> bool { if let Some(kv) = self.items.get(key) { @@ -427,6 +449,12 @@ impl TableLike for InlineTable { fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item> { self.items.get_mut(key).map(|kv| &mut kv.value) } + fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> { + self.get_key_value(key) + } + fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> { + self.get_key_value_mut(key) + } fn contains_key(&self, key: &str) -> bool { self.contains_key(key) } diff --git a/src/table.rs b/src/table.rs index bd7f26e6..f6515156 100644 --- a/src/table.rs +++ b/src/table.rs @@ -303,6 +303,28 @@ impl Table { }) } + /// Return references to the key-value pair stored for key, if it is present, else None. + pub fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> { + self.items.get(key).and_then(|kv| { + if !kv.value.is_none() { + Some((&kv.key, &kv.value)) + } else { + None + } + }) + } + + /// Return mutable references to the key-value pair stored for key, if it is present, else None. + pub fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> { + self.items.get_mut(key).and_then(|kv| { + if !kv.value.is_none() { + Some((kv.key.as_mut(), &mut kv.value)) + } else { + None + } + }) + } + /// Returns true iff the table contains an item with the given key. pub fn contains_key(&self, key: &str) -> bool { if let Some(kv) = self.items.get(key) { @@ -479,6 +501,10 @@ pub trait TableLike: crate::private::Sealed { fn get<'s>(&'s self, key: &str) -> Option<&'s Item>; /// Returns an optional mutable reference to an item given the key. fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item>; + /// Return references to the key-value pair stored for key, if it is present, else None. + fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)>; + /// Return mutable references to the key-value pair stored for key, if it is present, else None. + fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)>; /// Returns true iff the table contains an item with the given key. fn contains_key(&self, key: &str) -> bool; /// Inserts a key-value pair into the map. @@ -530,6 +556,12 @@ impl TableLike for Table { fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item> { self.get_mut(key) } + fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> { + self.get_key_value(key) + } + fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> { + self.get_key_value_mut(key) + } fn contains_key(&self, key: &str) -> bool { self.contains_key(key) }