pub trait StorageOptionExt {
// Required methods
fn write_option<T: Serialize>(
&self,
key: &[u8],
value: Option<&T>,
) -> Result<u64>;
fn read_option<T: DeserializeOwned>(
&self,
key: &[u8],
) -> Result<Option<T>, Error>;
}
Expand description
§Storage Utilities for Handling Option<T>
This trait provides methods to store and retrieve Option<T>
values
in a DataStore
, ensuring that None
values are explicitly handled.
§Purpose
- Prevents ambiguity: Ensures
None
is stored and retrieved correctly. - Efficient storage: Uses a compact representation.
- Binary-safe: Avoids unintended interpretation of missing values.
§Implementation Details
Some(value)
: Serialized usingbincode
.None
: Explicitly stored using a dedicated tombstone marker ([0xFF, 0xFE]
).
§Example Usage
use simd_r_drive::DataStore;
use simd_r_drive_extensions::StorageOptionExt;
use std::path::PathBuf;
use tempfile::tempdir;
let temp_dir = tempdir().expect("Failed to create temp dir");
let temp_path = temp_dir.path().join("test_store.bin");
let storage = DataStore::open(&PathBuf::from(temp_path)).unwrap();
// Store `Some(value)`
storage.write_option(b"key1", Some(&42)).unwrap();
// Store `None` (tombstone)
storage.write_option::<i32>(b"key2", None).unwrap();
// Read values
assert_eq!(storage.read_option::<i32>(b"key1").unwrap(), Some(42));
assert_eq!(storage.read_option::<i32>(b"key2").unwrap(), None);
Required Methods§
Sourcefn write_option<T: Serialize>(
&self,
key: &[u8],
value: Option<&T>,
) -> Result<u64>
fn write_option<T: Serialize>( &self, key: &[u8], value: Option<&T>, ) -> Result<u64>
Writes an Option<T>
into the DataStore
, ensuring None
values are preserved.
Some(value)
: Serialized usingbincode
.None
: Stored in a way that allows correct retrieval.
§Arguments
key
: The binary key under which the value is stored.value
: An optional reference toT
, whereNone
is handled appropriately.
§Returns
Ok(offset)
: The file offset where the data was written.Err(std::io::Error)
: If the write operation fails.
§Example
use simd_r_drive::DataStore;
use simd_r_drive_extensions::StorageOptionExt;
use std::path::PathBuf;
use tempfile::tempdir;
let temp_dir = tempdir().expect("Failed to create temp dir");
let temp_path = temp_dir.path().join("test_store.bin");
let storage = DataStore::open(&PathBuf::from(temp_path)).unwrap();
// Write `Some(value)`
storage.write_option(b"key_with_some_value", Some(&123)).unwrap();
// Write `None` (tombstone)
storage.write_option::<i32>(b"key_with_none_value", None).unwrap();
Sourcefn read_option<T: DeserializeOwned>(
&self,
key: &[u8],
) -> Result<Option<T>, Error>
fn read_option<T: DeserializeOwned>( &self, key: &[u8], ) -> Result<Option<T>, Error>
Reads an Option<T>
from storage.
- ⚠️ Non Zero-Copy Warning: Requires deserialization.
- Returns
Ok(None)
if the key exists and explicitly stores the tombstone marker ([0xFF, 0xFE]
). - Returns
Err(ErrorKind::NotFound)
if the key does not exist. - Returns
Err(ErrorKind::InvalidData)
if deserialization fails.
§Arguments
key
: The binary key to retrieve.
§Returns
Ok(Some(T))
: If deserialization succeeds and isSome
.Ok(None)
: If the key representsNone
.Err(std::io::Error)
: If the key does not exist or if deserialization fails.
§Example
use simd_r_drive::DataStore;
use simd_r_drive_extensions::StorageOptionExt;
use std::path::PathBuf;
use tempfile::tempdir;
let temp_dir = tempdir().expect("Failed to create temp dir");
let temp_path = temp_dir.path().join("test_store.bin");
let storage = DataStore::open(&PathBuf::from(temp_path)).unwrap();
storage.write_option(b"key_with_some_value", Some(&789)).unwrap();
storage.write_option::<i32>(b"key_with_none_value", None).unwrap();
assert_eq!(storage.read_option::<i32>(b"key_with_some_value").unwrap(), Some(789));
assert_eq!(storage.read_option::<i32>(b"key_with_none_value").unwrap(), None);
if let Ok(none_option) = storage.read_option::<i32>(b"key_with_none_value") {
assert!(none_option.is_some() || none_option.is_none()); // Explicitly checking Option type
}
// Alternative, concise check
let none_option = storage.read_option::<i32>(b"key_with_none_value").unwrap();
assert!(none_option.is_none() || none_option.is_some()); // Ensures `Option<T>` exists
// Errors on non-existent keys
assert!(storage.read_option::<i32>(b"non_existent_key").is_err());
§Safety
- This function allocates memory for deserialization.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
Implementations on Foreign Types§
Source§impl StorageOptionExt for DataStore
Implements StorageOptionExt
for DataStore
impl StorageOptionExt for DataStore
Implements StorageOptionExt
for DataStore