diff --git a/satrs-core/src/pool.rs b/satrs-core/src/pool.rs index 67a8a22..137abee 100644 --- a/satrs-core/src/pool.rs +++ b/satrs-core/src/pool.rs @@ -71,6 +71,7 @@ use core::fmt::{Display, Formatter}; use serde::{Deserialize, Serialize}; #[cfg(feature = "std")] use std::error::Error; +use delegate::delegate; type NumBlocks = u16; pub type StoreAddr = u64; @@ -217,7 +218,9 @@ pub trait PoolProviderMemInPlace { } Ok(self.read(addr)?.len()) } +} +pub trait PoolProviderMemInPlaceWithGuards: PoolProviderMemInPlace { /// This function behaves like [PoolProvider::read], but consumes the provided address /// and returns a RAII conformant guard object. /// @@ -239,13 +242,76 @@ pub trait PoolProviderMemInPlace { fn modify_with_guard(&mut self, addr: StoreAddr) -> PoolRwGuard; } +pub struct PoolGuard<'a, MemProvider: PoolProviderMemInPlace + ?Sized> { + pool: &'a mut MemProvider, + pub addr: StoreAddr, + no_deletion: bool, + deletion_failed_error: Option, +} + +/// This helper object +impl<'a, MemProvider: PoolProviderMemInPlace> PoolGuard<'a, MemProvider> { + pub fn new(pool: &'a mut MemProvider, addr: StoreAddr) -> Self { + Self { + pool, + addr, + no_deletion: false, + deletion_failed_error: None, + } + } + + pub fn read(&self) -> Result<&[u8], StoreError> { + self.pool.read(&self.addr) + } + + /// Releasing the pool guard will disable the automatic deletion of the data when the guard + /// is dropped. + pub fn release(&mut self) { + self.no_deletion = true; + } +} + +impl Drop for PoolGuard<'_, MemProvider> { + fn drop(&mut self) { + if !self.no_deletion { + if let Err(e) = self.pool.delete(self.addr) { + self.deletion_failed_error = Some(e); + } + } + } +} + +pub struct PoolRwGuard<'a, MemProvider: PoolProviderMemInPlace + ?Sized> { + guard: PoolGuard<'a, MemProvider>, +} + +impl<'a, MemProvider: PoolProviderMemInPlace> PoolRwGuard<'a, MemProvider> { + pub fn new(pool: &'a mut MemProvider, addr: StoreAddr) -> Self { + Self { + guard: PoolGuard::new(pool, addr), + } + } + + pub fn modify(&mut self) -> Result<&mut [u8], StoreError> { + self.guard.pool.modify(&self.guard.addr) + } + + delegate!( + to self.guard { + pub fn read(&self) -> Result<&[u8], StoreError>; + /// Releasing the pool guard will disable the automatic deletion of the data when the guard + /// is dropped. + pub fn release(&mut self); + } + ); +} + #[cfg(feature = "alloc")] mod alloc_mod { - use super::{PoolProviderMemInPlace, StaticPoolAddr}; + use super::{PoolProviderMemInPlace, StaticPoolAddr, PoolProviderMemInPlaceWithGuards, PoolRwGuard, PoolGuard}; use crate::pool::{NumBlocks, StoreAddr, StoreError, StoreIdError}; use alloc::vec; use alloc::vec::Vec; - use delegate::delegate; #[cfg(feature = "std")] use std::sync::{Arc, RwLock}; @@ -285,70 +351,6 @@ mod alloc_mod { } } - pub struct PoolGuard<'a, MemProvider: PoolProviderMemInPlace + ?Sized> { - pool: &'a mut MemProvider, - pub addr: StoreAddr, - no_deletion: bool, - deletion_failed_error: Option, - } - - /// This helper object - impl<'a, MemProvider: PoolProviderMemInPlace> PoolGuard<'a, MemProvider> { - pub fn new(pool: &'a mut MemProvider, addr: StoreAddr) -> Self { - Self { - pool, - addr, - no_deletion: false, - deletion_failed_error: None, - } - } - - pub fn read(&self) -> Result<&[u8], StoreError> { - self.pool.read(&self.addr) - } - - /// Releasing the pool guard will disable the automatic deletion of the data when the guard - /// is dropped. - pub fn release(&mut self) { - self.no_deletion = true; - } - } - - impl Drop for PoolGuard<'_, MemProvider> { - fn drop(&mut self) { - if !self.no_deletion { - if let Err(e) = self.pool.delete(self.addr) { - self.deletion_failed_error = Some(e); - } - } - } - } - - pub struct PoolRwGuard<'a, MemProvider: PoolProviderMemInPlace + ?Sized> { - guard: PoolGuard<'a, MemProvider>, - } - - impl<'a, MemProvider: PoolProviderMemInPlace> PoolRwGuard<'a, MemProvider> { - pub fn new(pool: &'a mut MemProvider, addr: StoreAddr) -> Self { - Self { - guard: PoolGuard::new(pool, addr), - } - } - - pub fn modify(&mut self) -> Result<&mut [u8], StoreError> { - self.guard.pool.modify(&self.guard.addr) - } - - delegate!( - to self.guard { - pub fn read(&self) -> Result<&[u8], StoreError>; - /// Releasing the pool guard will disable the automatic deletion of the data when the guard - /// is dropped. - pub fn release(&mut self); - } - ); - } - /// Pool implementation providing sub-pools with fixed size memory blocks. /// /// This is a simple memory pool implementation which pre-allocates all sub-pools using a given pool @@ -535,6 +537,9 @@ mod alloc_mod { } Ok(true) } + } + + impl PoolProviderMemInPlaceWithGuards for StaticMemoryPool { fn modify_with_guard(&mut self, addr: StoreAddr) -> PoolRwGuard { PoolRwGuard::new(self, addr) } @@ -549,7 +554,7 @@ mod alloc_mod { mod tests { use crate::pool::{ PoolGuard, PoolProviderMemInPlace, PoolRwGuard, StaticMemoryPool, StaticPoolAddr, - StaticPoolConfig, StoreError, StoreIdError, POOL_MAX_SIZE, + StaticPoolConfig, StoreError, StoreIdError, POOL_MAX_SIZE, PoolProviderMemInPlaceWithGuards, }; use std::vec;