use std::fmt::Display;
use s_macro::s;
use wildland_corex::{LocalSecureStorage, LssError, LssResult};
#[derive(Debug, Clone)]
pub struct SledLss {
db: sled::Db,
}
impl SledLss {
pub fn new(path: String) -> Self {
SledLss {
db: sled::open(path).unwrap(),
}
}
pub fn boxed(&self) -> Box<Self> {
Box::new(self.clone())
}
}
fn to_lsserror<T: Display>(error: T) -> LssError {
LssError::Error(s!(error))
}
impl LocalSecureStorage for SledLss {
#[tracing::instrument(level = "trace", err(Debug), skip(self))]
fn insert(&self, key: String, value: String) -> LssResult<Option<String>> {
let value = self.db.insert(key, value.as_bytes()).map_err(to_lsserror)?;
match value {
Some(value) => Ok(Some(
String::from_utf8(value.to_vec()).map_err(to_lsserror)?,
)),
None => Ok(None),
}
}
#[tracing::instrument(level = "trace", err(Debug), err(Debug), skip(self))]
fn get(&self, key: String) -> LssResult<Option<String>> {
let value = self.db.get(key).map_err(to_lsserror)?;
match value {
Some(value) => Ok(Some(
String::from_utf8(value.to_vec()).map_err(to_lsserror)?,
)),
None => Ok(None),
}
}
#[tracing::instrument(level = "trace", err(Debug), skip(self))]
fn contains_key(&self, key: String) -> LssResult<bool> {
self.db.contains_key(key).map_err(to_lsserror)
}
#[tracing::instrument(level = "trace", skip(self))]
fn is_empty(&self) -> LssResult<bool> {
Ok(self.db.is_empty())
}
#[tracing::instrument(level = "trace", err(Debug), skip(self))]
fn keys(&self) -> LssResult<Vec<String>> {
let keys = self
.db
.iter()
.map(|item| String::from_utf8(item.unwrap().0.to_vec()).unwrap())
.collect();
Ok(keys)
}
#[tracing::instrument(level = "trace", err(Debug), skip(self))]
fn remove(&self, key: String) -> LssResult<Option<String>> {
let value = self.db.remove(key).map_err(to_lsserror)?;
match value {
Some(value) => Ok(Some(
String::from_utf8(value.to_vec()).map_err(to_lsserror)?,
)),
None => Ok(None),
}
}
#[tracing::instrument(level = "trace", err(Debug), skip(self))]
fn len(&self) -> LssResult<usize> {
Ok(self.db.len())
}
#[tracing::instrument(level = "trace", err(Debug), skip(self))]
fn keys_starting_with(&self, prefix: String) -> LssResult<Vec<String>> {
let keys = self
.db
.iter()
.map(|item| String::from_utf8(item.unwrap().0.to_vec()).unwrap())
.filter(|x| x.starts_with(&prefix))
.collect();
Ok(keys)
}
}