The In-Memory Version
Define the API against a HashMap first, so the interface is settled.
Get the interface right before you touch the disk.
pub trait KvStore {
fn set(&mut self, key: String, value: String) -> Result<()>;
fn get(&self, key: &str) -> Result<Option<String>>;
fn remove(&mut self, key: &str) -> Result<()>;
}
Every method returns Result even though a HashMap can’t fail. That’s deliberate: the
disk-backed version will fail, and changing the signature later means changing every call
site. Design the trait for the implementation you’re heading toward.
get returns Result<Option<String>> — the two failure modes are genuinely different. “The
key isn’t there” is Ok(None); “the disk is on fire” is Err.