diff --git a/src/error.rs b/src/error.rs index a993b93..35d54ba 100644 --- a/src/error.rs +++ b/src/error.rs @@ -8,3 +8,10 @@ pub fn to_net_error(_err: EspError) -> Error { // TODO: Capture the backtrace and the original error ErrorCode::NoNetworkInterface.into() } + +/// Converts an ESP persistence error to an `rs-matter` error +pub fn to_persist_error(_err: EspError) -> Error { + // TODO: The `rs-matter` error code is too generic + // TODO: Capture the backtrace and the original error + ErrorCode::StdIoError.into() +} diff --git a/src/eth.rs b/src/eth.rs index bf9b698..8825e66 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -1,4 +1,8 @@ use rs_matter_stack::{persist::KvBlobBuf, Eth, MatterStack}; +/// A type alias for an ESP-IDF Matter stack running over an Ethernet network (or any other network not managed by Matter). pub type EspEthMatterStack<'a, E> = MatterStack<'a, EspEth>; + +/// A type alias for an ESP-IDF implementation of the `Network` trait for a Matter stack running over +/// an Ethernet network (or any other network not managed by Matter). pub type EspEth = Eth>; diff --git a/src/persist.rs b/src/persist.rs index a2d1b58..d5cb882 100644 --- a/src/persist.rs +++ b/src/persist.rs @@ -3,10 +3,13 @@ use esp_idf_svc::sys::EspError; use log::info; -use rs_matter::error::{Error, ErrorCode}; +use rs_matter::error::Error; use rs_matter_stack::persist::{Key, KvBlobStore, KvPersist}; +use crate::error::to_persist_error; + +/// A type alias for a `KvPersist` instance that uses the ESP IDF NVS API pub type EspMatterPersist<'a, T, C> = KvPersist<'a, EspKvBlobStore, C>; /// A `KvBlobStore`` implementation that uses the ESP IDF NVS API @@ -21,42 +24,57 @@ impl EspKvBlobStore where T: NvsPartitionId, { - /// Create a new PSM instance that would persist in namespace `esp-idf-matter`. + /// Create a new KV BLOB store instance that would persist in namespace `esp-idf-matter`. pub fn new_default(nvs: EspNvsPartition) -> Result { Self::new(nvs, "esp-idf-matter") } - /// Create a new PSM instance. + /// Create a new KV BLOB store instance. pub fn new(nvs: EspNvsPartition, namespace: &str) -> Result { Ok(Self(EspNvs::new(nvs, namespace, true)?)) } - fn load_blob<'b>(&self, key: Key, buf: &'b mut [u8]) -> Result, EspError> { + fn load(&self, key: Key, buf: &mut [u8], cb: F) -> Result<(), Error> + where + F: FnOnce(Option<&[u8]>) -> Result<(), Error>, + { // TODO: Not really async - let data = self.0.get_blob(key.as_ref(), buf)?; + let data = self + .0 + .get_blob(key.as_ref(), buf) + .map_err(to_persist_error)?; + info!( "Blob {key}: loaded {:?} bytes {data:?}", data.map(|data| data.len()) ); - Ok(data) + cb(data) } - fn store_blob(&mut self, key: Key, data: &[u8]) -> Result<(), EspError> { + fn store(&mut self, key: Key, buf: &mut [u8], cb: F) -> Result<(), Error> + where + F: FnOnce(&mut [u8]) -> Result, + { // TODO: Not really async - self.0.set_blob(key.as_ref(), data)?; + let len = cb(buf)?; + let data = &buf[..len]; + + self.0 + .set_blob(key.as_ref(), data) + .map_err(to_persist_error)?; info!("Blob {key}: stored {} bytes {data:?}", data.len()); Ok(()) } - fn remove_blob(&mut self, key: Key) -> Result<(), EspError> { + fn remove(&mut self, key: Key, _buf: &mut [u8]) -> Result<(), Error> { // TODO: Not really async - self.0.remove(key.as_ref())?; + self.0.remove(key.as_ref()).map_err(to_persist_error)?; info!("Blob {key}: removed"); @@ -68,22 +86,21 @@ impl KvBlobStore for EspKvBlobStore where T: NvsPartitionId, { - async fn load<'a>(&mut self, key: Key, buf: &'a mut [u8]) -> Result, Error> { - Ok(self - .load_blob(key, buf) - .map_err(|_| ErrorCode::StdIoError)?) // TODO: We need a dedicated PersistError code here + async fn load(&mut self, key: Key, buf: &mut [u8], cb: F) -> Result<(), Error> + where + F: FnOnce(Option<&[u8]>) -> Result<(), Error>, + { + EspKvBlobStore::load(self, key, buf, cb) } - async fn store(&mut self, key: Key, value: &[u8]) -> Result<(), Error> { - self.store_blob(key, value) - .map_err(|_| ErrorCode::StdIoError)?; - - Ok(()) + async fn store(&mut self, key: Key, buf: &mut [u8], cb: F) -> Result<(), Error> + where + F: FnOnce(&mut [u8]) -> Result, + { + EspKvBlobStore::store(self, key, buf, cb) } - async fn remove(&mut self, key: Key) -> Result<(), Error> { - self.remove_blob(key).map_err(|_| ErrorCode::StdIoError)?; - - Ok(()) + async fn remove(&mut self, key: Key, buf: &mut [u8]) -> Result<(), Error> { + EspKvBlobStore::remove(self, key, buf) } }