Skip to content

Commit d94872a

Browse files
Add DynStorageAlloc using FnOnce
Our DynStorage trait uses a &mut dyn FnMut as a callback for implementing mount_and_then (instead of a FnOnce like Filesystem). This is because there is no no-std way to pass a FnOnce in an dyn compatible trait method. If alloc is available, this limitation can be avoided by using a Box<dyn FnOnce>. This patch adds an alloc feature to the crate and a DynStorageAlloc trait behind that feature that provides mount_and_then functions using a boxed FnOnce instead of a reference to an FnMut.
1 parent bc4b454 commit d94872a

File tree

4 files changed

+34
-1
lines changed

4 files changed

+34
-1
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## Unreleased
99

10-
-
10+
### Added
11+
12+
- Added `DynStorageAlloc` trait behind the `alloc` feature.
1113

1214
## [v0.6.0](https://github.com/trussed-dev/littlefs2/releases/tag/0.6.0) - 2025-02-28
1315

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ serde = { version = "1.0", default-features = false, features = ["derive"] }
3333

3434
[features]
3535
default = ["serde"]
36+
alloc = []
3637
serde = ["littlefs2-core/serde"]
3738
# enable assertions in backend C code
3839
ll-assertions = ["littlefs2-sys/assertions"]

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ assert_eq!(&buf, b"black smoke");
125125
```
126126
*/
127127

128+
#[cfg(feature = "alloc")]
129+
extern crate alloc;
130+
128131
/// Low-level bindings
129132
pub use littlefs2_sys as ll;
130133

src/object_safe.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ pub use littlefs2_core::{DirEntriesCallback, DynFile, DynFilesystem, FileCallbac
1515
const _: Option<&dyn DynStorage> = None;
1616

1717
pub type FilesystemCallback<'a, R = ()> = &'a mut dyn FnMut(&dyn DynFilesystem) -> Result<R>;
18+
#[cfg(feature = "alloc")]
19+
pub type BoxedFilesystemCallback<'a, R = ()> =
20+
alloc::boxed::Box<dyn FnOnce(&dyn DynFilesystem) -> Result<R> + 'a>;
1821

1922
impl<S: Storage> DynFile for File<'_, '_, S> {
2023
fn sync(&self) -> Result<()> {
@@ -238,3 +241,27 @@ impl dyn DynStorage + '_ {
238241
result
239242
}
240243
}
244+
245+
#[cfg(feature = "alloc")]
246+
pub trait DynStorageAlloc: DynStorage {
247+
fn mount_and_then_unit_boxed(&mut self, f: BoxedFilesystemCallback<'_>) -> Result<()>;
248+
}
249+
250+
#[cfg(feature = "alloc")]
251+
impl<T: Storage> DynStorageAlloc for T {
252+
fn mount_and_then_unit_boxed(&mut self, f: BoxedFilesystemCallback<'_>) -> Result<()> {
253+
Filesystem::mount_and_then(self, |fs| f(fs))
254+
}
255+
}
256+
257+
#[cfg(feature = "alloc")]
258+
impl dyn DynStorageAlloc + '_ {
259+
pub fn mount_and_then_boxed<R>(&mut self, f: BoxedFilesystemCallback<'_, R>) -> Result<R> {
260+
let mut result = Err(Error::IO);
261+
self.mount_and_then_unit_boxed(alloc::boxed::Box::new(|fs| {
262+
result = Ok(f(fs)?);
263+
Ok(())
264+
}))?;
265+
result
266+
}
267+
}

0 commit comments

Comments
 (0)