Skip to content

Instantly share code, notes, and snippets.

@SimonSapin
Created August 18, 2022 22:47
Show Gist options
  • Save SimonSapin/282d3a354fa34b33123fe38b9def3ac8 to your computer and use it in GitHub Desktop.
Save SimonSapin/282d3a354fa34b33123fe38b9def3ac8 to your computer and use it in GitHub Desktop.
impl embedded_svc::storage::Storage for esp_idf_svc::nvs_storage::EspNvsStorage
use embedded_svc::storage::RawStorage;
use embedded_svc::storage::Storage;
use embedded_svc::storage::StorageBase;
use esp_idf_svc::nvs::EspDefaultNvs;
use esp_idf_svc::nvs_storage::EspNvsStorage;
use esp_idf_sys::EspError;
use std::sync::Arc;
pub fn default(namespace: &str) -> Result<PostcardStorage<EspNvsStorage>, EspError> {
let read_write = true;
Ok(PostcardStorage {
inner: EspNvsStorage::new_default(Arc::new(EspDefaultNvs::new()?), namespace, read_write)?,
})
}
#[derive(Debug, thiserror::Error)]
pub enum PostcardStorageError<Inner> {
#[error("{0}")]
InnerError(Inner),
#[error("{0}")]
PostcardError(#[from] postcard::Error),
}
pub struct PostcardStorage<S>
where
S: RawStorage,
{
inner: S,
}
impl<S> Storage for PostcardStorage<S>
where
S: RawStorage,
{
fn get<T>(&self, name: &str) -> Result<Option<T>, Self::Error>
where
T: serde::de::DeserializeOwned,
{
if let Some(buffer) = self
.inner
.get_raw_vec(name)
.map_err(PostcardStorageError::InnerError)?
{
Ok(Some(postcard::from_bytes(&buffer)?))
} else {
Ok(None)
}
}
fn set<T>(&mut self, name: &str, value: &T) -> Result<bool, Self::Error>
where
T: serde::Serialize,
{
self.inner
.put_raw(name, &postcard::to_stdvec(value)?)
.map_err(PostcardStorageError::InnerError)
}
}
impl<S> StorageBase for PostcardStorage<S>
where
S: RawStorage,
{
type Error = PostcardStorageError<S::Error>;
fn contains(&self, name: &str) -> Result<bool, Self::Error> {
self.inner
.contains(name)
.map_err(PostcardStorageError::InnerError)
}
fn remove(&mut self, name: &str) -> Result<bool, Self::Error> {
self.inner
.remove(name)
.map_err(PostcardStorageError::InnerError)
}
}
trait RawStorageExt: RawStorage {
fn get_raw_vec(&self, name: &str) -> Result<Option<Vec<u8>>, Self::Error> {
if let Some(len) = self.len(name)? {
let mut buffer = vec![0; len];
if let Some((_, len)) = self.get_raw(name, &mut buffer)? {
buffer.truncate(len);
return Ok(Some(buffer));
}
}
Ok(None)
}
}
impl<T> RawStorageExt for T where T: RawStorage {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment