diff --git a/packages/storey/src/containers/column.rs b/packages/storey/src/containers/column.rs index 64b06ed..0ed7f1b 100644 --- a/packages/storey/src/containers/column.rs +++ b/packages/storey/src/containers/column.rs @@ -7,6 +7,7 @@ use crate::encoding::{DecodableWith, EncodableWith}; use crate::storage::{IterableStorage, StorageBranch}; use crate::storage::{Storage, StorageMut}; +use super::common::TryGetError; use super::{BoundFor, BoundedIterableAccessor, IterableAccessor, NonTerminal, Storable}; const META_LAST_IX: &[u8] = &[0]; @@ -158,6 +159,8 @@ where { /// Get the value associated with the given key. /// + /// Returns `Ok(None)` if the entry doesn't exist (has not been set yet). + /// /// # Example /// ``` /// # use mocks::encoding::TestEncoding; @@ -179,6 +182,33 @@ where .transpose() } + /// Get the value associated with the given key. + /// + /// Returns [`TryGetError::Empty`] if the entry doesn't exist (has not been + /// set yet). + /// + /// This is similar to [`get`](Self::get), but removes one level of nesting + /// so that you can get to your data faster, without having to unpack the + /// [`Option`]. + /// + /// # Example + /// ``` + /// # use mocks::encoding::TestEncoding; + /// # use mocks::backend::TestStorage; + /// use storey::containers::Column; + /// + /// let mut storage = TestStorage::new(); + /// let column = Column::::new(0); + /// let mut access = column.access(&mut storage); + /// + /// access.push(&1337).unwrap(); + /// assert_eq!(access.try_get(0).unwrap(), 1337); + /// assert!(access.try_get(1).is_err()); + /// ``` + pub fn try_get(&self, key: u32) -> Result> { + self.get(key)?.ok_or(TryGetError::Empty) + } + /// Get the length of the column. This is the number of elements actually stored, /// taking the possibility of removed elements into account. /// diff --git a/packages/storey/src/containers/common.rs b/packages/storey/src/containers/common.rs new file mode 100644 index 0000000..0125ea0 --- /dev/null +++ b/packages/storey/src/containers/common.rs @@ -0,0 +1,7 @@ +#[derive(Debug, PartialEq, Eq, Clone, Copy, thiserror::Error)] +pub enum TryGetError { + #[error("item is empty")] + Empty, + #[error(transparent)] + DecodeError(#[from] E), +} diff --git a/packages/storey/src/containers/item.rs b/packages/storey/src/containers/item.rs index 25d63e9..4593753 100644 --- a/packages/storey/src/containers/item.rs +++ b/packages/storey/src/containers/item.rs @@ -4,6 +4,7 @@ use crate::encoding::{DecodableWith, EncodableWith, Encoding}; use crate::storage::StorageBranch; use crate::storage::{Storage, StorageMut}; +use super::common::TryGetError; use super::{Storable, Terminal}; /// A single item in the storage. @@ -117,7 +118,7 @@ where { /// Get the value of the item. /// - /// Returns `None` if the item doesn't exist (has not been set yet). + /// Returns `Ok(None)` if the item doesn't exist (has not been set yet). /// /// # Examples /// ``` @@ -149,6 +150,43 @@ where .map(|bytes| T::decode(&bytes)) .transpose() } + + /// Get the value of the item. + /// + /// Returns [`TryGetError::Empty`] if the item doesn't exist (has not been + /// set yet). + /// + /// This is similar to [`get`](Self::get), but removes one level of nesting + /// so that you can get to your data faster, without having to unpack the + /// [`Option`]. + /// + /// # Examples + /// ``` + /// # use mocks::encoding::TestEncoding; + /// # use mocks::backend::TestStorage; + /// use storey::containers::Item; + /// + /// let mut storage = TestStorage::new(); + /// let item = Item::::new(0); + /// + /// item.access(&mut storage).set(&42).unwrap(); + /// assert_eq!(item.access(&storage).try_get().unwrap(), 42); + /// ``` + /// + /// ``` + /// # use mocks::encoding::TestEncoding; + /// # use mocks::backend::TestStorage; + /// use storey::containers::Item; + /// + /// let storage = TestStorage::new(); + /// let item = Item::::new(0); + /// let access = item.access(&storage); + /// + /// assert!(access.try_get().is_err()); + /// ``` + pub fn try_get(&self) -> Result> { + self.get()?.ok_or_else(|| TryGetError::Empty) + } } impl ItemAccess diff --git a/packages/storey/src/containers/mod.rs b/packages/storey/src/containers/mod.rs index 12b655f..a24bc98 100644 --- a/packages/storey/src/containers/mod.rs +++ b/packages/storey/src/containers/mod.rs @@ -2,6 +2,7 @@ //! few fundamental collections/containers themselves. mod column; +pub mod common; mod item; pub mod map;