Skip to content

Commit 5003249

Browse files
Simplify Store trait
This patch simplifies the Store trait by removing the Fs wrapper struct, the Storage types, the static lifetime and the Copy requirement and replaces it with a reference to a DynFilesystem. This gives runners more options on how to implement the store. As the Store trait can now easily be implemented in a safe way, this patch also removes the unsafe keyword from the trait definition.
1 parent ede9fc0 commit 5003249

File tree

7 files changed

+80
-100
lines changed

7 files changed

+80
-100
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5757
- Added support for non-static channels:
5858
- Added lifetimes to `ClientImplementation` and `ServiceEndpoints`.
5959
- Added the `pipe::TrussedChannel` type.
60+
- Refactored the `Store` trait:
61+
- Removed the requirement for a static lifetime.
62+
- Removed the `Fs` wrapper type.
63+
- Removed the storage types to return `&dyn DynFilesystem` instead.
64+
- Removed the `Copy` requirement.
65+
- Removed the `unsafe` keyword for the `Store` trait.
6066

6167
### Fixed
6268

src/store.rs

Lines changed: 48 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
//! - Alternative: subdirectory <==> RP hash, everything else in flat files
7373
//! - In any case need to "list dirs excluding . and .." or similar
7474
75-
use littlefs2::{driver::Storage, fs::Filesystem, path};
75+
use littlefs2::path;
7676

7777
use crate::error::Error;
7878
use crate::types::{Bytes, Location};
@@ -127,39 +127,19 @@ pub mod keystore;
127127
// LfsStorage-bound types) to remove lifetimes and generic parameters from Store.
128128
//
129129
// This makes everything using it *much* more ergonomic.
130-
pub unsafe trait Store: Copy {
131-
type I: 'static + Storage;
132-
type E: 'static + Storage;
133-
type V: 'static + Storage;
134-
fn ifs(self) -> &'static Fs<Self::I>;
135-
fn efs(self) -> &'static Fs<Self::E>;
136-
fn vfs(self) -> &'static Fs<Self::V>;
130+
pub trait Store {
131+
fn ifs(&self) -> &dyn DynFilesystem;
132+
fn efs(&self) -> &dyn DynFilesystem;
133+
fn vfs(&self) -> &dyn DynFilesystem;
137134
fn fs(&self, location: Location) -> &dyn DynFilesystem {
138135
match location {
139-
Location::Internal => self.ifs().fs,
140-
Location::External => self.efs().fs,
141-
Location::Volatile => self.vfs().fs,
136+
Location::Internal => self.ifs(),
137+
Location::External => self.efs(),
138+
Location::Volatile => self.vfs(),
142139
}
143140
}
144141
}
145142

146-
pub struct Fs<S: 'static + Storage> {
147-
fs: &'static Filesystem<'static, S>,
148-
}
149-
150-
impl<S: 'static + Storage> core::ops::Deref for Fs<S> {
151-
type Target = Filesystem<'static, S>;
152-
fn deref(&self) -> &Self::Target {
153-
self.fs
154-
}
155-
}
156-
157-
impl<S: 'static + Storage> Fs<S> {
158-
pub fn new(fs: &'static Filesystem<'static, S>) -> Self {
159-
Self { fs }
160-
}
161-
}
162-
163143
#[macro_export]
164144
macro_rules! store {
165145
(
@@ -174,19 +154,15 @@ macro_rules! store {
174154
__: core::marker::PhantomData<*mut ()>,
175155
}
176156

177-
unsafe impl $crate::store::Store for $store {
178-
type I = $Ifs;
179-
type E = $Efs;
180-
type V = $Vfs;
181-
182-
fn ifs(self) -> &'static $crate::store::Fs<$Ifs> {
183-
unsafe { &*Self::ifs_ptr() }
157+
impl $crate::store::Store for $store {
158+
fn ifs(&self) -> &dyn littlefs2::object_safe::DynFilesystem {
159+
unsafe { Self::ifs_ptr().assume_init() }
184160
}
185-
fn efs(self) -> &'static $crate::store::Fs<$Efs> {
186-
unsafe { &*Self::efs_ptr() }
161+
fn efs(&self) -> &dyn littlefs2::object_safe::DynFilesystem {
162+
unsafe { Self::efs_ptr().assume_init() }
187163
}
188-
fn vfs(self) -> &'static $crate::store::Fs<$Vfs> {
189-
unsafe { &*Self::vfs_ptr() }
164+
fn vfs(&self) -> &dyn littlefs2::object_safe::DynFilesystem {
165+
unsafe { Self::vfs_ptr().assume_init() }
190166
}
191167
}
192168

@@ -277,14 +253,9 @@ macro_rules! store {
277253
efs: &'static littlefs2::fs::Filesystem<$Efs>,
278254
vfs: &'static littlefs2::fs::Filesystem<$Vfs>,
279255
) -> Self {
280-
let store_ifs = $crate::store::Fs::new(ifs);
281-
let store_efs = $crate::store::Fs::new(efs);
282-
let store_vfs = $crate::store::Fs::new(vfs);
283-
unsafe {
284-
Self::ifs_ptr().write(store_ifs);
285-
Self::efs_ptr().write(store_efs);
286-
Self::vfs_ptr().write(store_vfs);
287-
}
256+
Self::ifs_ptr().write(ifs);
257+
Self::efs_ptr().write(efs);
258+
Self::vfs_ptr().write(vfs);
288259
Self::claim().unwrap()
289260
}
290261

@@ -317,28 +288,31 @@ macro_rules! store {
317288
}
318289
}
319290

320-
fn ifs_ptr() -> *mut $crate::store::Fs<$Ifs> {
291+
fn ifs_ptr() -> &'static mut core::mem::MaybeUninit<
292+
&'static dyn littlefs2::object_safe::DynFilesystem,
293+
> {
321294
use core::mem::MaybeUninit;
322-
use core::ptr::addr_of_mut;
323-
use $crate::store::Fs;
324-
static mut IFS: MaybeUninit<Fs<$Ifs>> = MaybeUninit::uninit();
325-
unsafe { (*addr_of_mut!(IFS)).as_mut_ptr() }
295+
static mut IFS: MaybeUninit<&'static dyn littlefs2::object_safe::DynFilesystem> =
296+
MaybeUninit::uninit();
297+
unsafe { (&raw mut IFS).as_mut().unwrap() }
326298
}
327299

328-
fn efs_ptr() -> *mut $crate::store::Fs<$Efs> {
300+
fn efs_ptr() -> &'static mut core::mem::MaybeUninit<
301+
&'static dyn littlefs2::object_safe::DynFilesystem,
302+
> {
329303
use core::mem::MaybeUninit;
330-
use core::ptr::addr_of_mut;
331-
use $crate::store::Fs;
332-
static mut EFS: MaybeUninit<Fs<$Efs>> = MaybeUninit::uninit();
333-
unsafe { (*addr_of_mut!(EFS)).as_mut_ptr() }
304+
static mut EFS: MaybeUninit<&'static dyn littlefs2::object_safe::DynFilesystem> =
305+
MaybeUninit::uninit();
306+
unsafe { (&raw mut EFS).as_mut().unwrap() }
334307
}
335308

336-
fn vfs_ptr() -> *mut $crate::store::Fs<$Vfs> {
309+
fn vfs_ptr() -> &'static mut core::mem::MaybeUninit<
310+
&'static dyn littlefs2::object_safe::DynFilesystem,
311+
> {
337312
use core::mem::MaybeUninit;
338-
use core::ptr::addr_of_mut;
339-
use $crate::store::Fs;
340-
static mut VFS: MaybeUninit<Fs<$Vfs>> = MaybeUninit::uninit();
341-
unsafe { (*addr_of_mut!(VFS)).as_mut_ptr() }
313+
static mut VFS: MaybeUninit<&'static dyn littlefs2::object_safe::DynFilesystem> =
314+
MaybeUninit::uninit();
315+
unsafe { (&raw mut VFS).as_mut().unwrap() }
342316
}
343317

344318
// Ignore lint for compatibility
@@ -401,26 +375,23 @@ macro_rules! store {
401375
&mut *(*addr_of_mut!(IFS_ALLOC)).as_mut_ptr(),
402376
&mut *(*addr_of_mut!(IFS_STORAGE)).as_mut_ptr(),
403377
)?);
404-
let ifs = $crate::store::Fs::new((*addr_of!(IFS)).as_ref().unwrap());
405-
Self::ifs_ptr().write(ifs);
378+
Self::ifs_ptr().write(addr_of!(IFS).as_ref().unwrap().as_ref().unwrap());
406379

407380
(*addr_of_mut!(EFS_ALLOC)).as_mut_ptr().write(efs_alloc);
408381
(*addr_of_mut!(EFS_STORAGE)).as_mut_ptr().write(efs_storage);
409382
EFS = Some(Filesystem::mount(
410383
&mut *(*addr_of_mut!(EFS_ALLOC)).as_mut_ptr(),
411384
&mut *(*addr_of_mut!(EFS_STORAGE)).as_mut_ptr(),
412385
)?);
413-
let efs = $crate::store::Fs::new((*addr_of_mut!(EFS)).as_ref().unwrap());
414-
Self::efs_ptr().write(efs);
386+
Self::efs_ptr().write(addr_of!(EFS).as_ref().unwrap().as_ref().unwrap());
415387

416388
(*addr_of_mut!(VFS_ALLOC)).as_mut_ptr().write(vfs_alloc);
417389
(*addr_of_mut!(VFS_STORAGE)).as_mut_ptr().write(vfs_storage);
418390
VFS = Some(Filesystem::mount(
419391
&mut *(*addr_of_mut!(VFS_ALLOC)).as_mut_ptr(),
420392
&mut *(*addr_of_mut!(VFS_STORAGE)).as_mut_ptr(),
421393
)?);
422-
let vfs = $crate::store::Fs::new((*addr_of!(VFS)).as_ref().unwrap());
423-
Self::vfs_ptr().write(vfs);
394+
Self::vfs_ptr().write(addr_of!(VFS).as_ref().unwrap().as_ref().unwrap());
424395

425396
Ok(())
426397
}
@@ -509,7 +480,7 @@ pub fn create_directories(fs: &dyn DynFilesystem, path: &Path) -> Result<(), Err
509480
/// Reads contents from path in location of store.
510481
#[inline(never)]
511482
pub fn read<const N: usize>(
512-
store: impl Store,
483+
store: &impl Store,
513484
location: Location,
514485
path: &Path,
515486
) -> Result<Bytes<N>, Error> {
@@ -523,7 +494,7 @@ pub fn read<const N: usize>(
523494
/// Writes contents to path in location of store.
524495
#[inline(never)]
525496
pub fn write(
526-
store: impl Store,
497+
store: &impl Store,
527498
location: Location,
528499
path: &Path,
529500
contents: &[u8],
@@ -538,7 +509,7 @@ pub fn write(
538509
/// Creates parent directory if necessary, then writes.
539510
#[inline(never)]
540511
pub fn store(
541-
store: impl Store,
512+
store: &impl Store,
542513
location: Location,
543514
path: &Path,
544515
contents: &[u8],
@@ -552,7 +523,7 @@ pub fn store(
552523
}
553524

554525
#[inline(never)]
555-
pub fn delete(store: impl Store, location: Location, path: &Path) -> bool {
526+
pub fn delete(store: &impl Store, location: Location, path: &Path) -> bool {
556527
debug_now!("deleting {}", &path);
557528
let fs = store.fs(location);
558529
if fs.remove(path).is_err() {
@@ -583,14 +554,14 @@ pub fn delete(store: impl Store, location: Location, path: &Path) -> bool {
583554
}
584555

585556
#[inline(never)]
586-
pub fn exists(store: impl Store, location: Location, path: &Path) -> bool {
557+
pub fn exists(store: &impl Store, location: Location, path: &Path) -> bool {
587558
debug_now!("checking existence of {}", &path);
588559
store.fs(location).exists(path)
589560
}
590561

591562
#[inline(never)]
592563
pub fn metadata(
593-
store: impl Store,
564+
store: &impl Store,
594565
location: Location,
595566
path: &Path,
596567
) -> Result<Option<Metadata>, Error> {
@@ -603,7 +574,7 @@ pub fn metadata(
603574
}
604575

605576
#[inline(never)]
606-
pub fn rename(store: impl Store, location: Location, from: &Path, to: &Path) -> Result<(), Error> {
577+
pub fn rename(store: &impl Store, location: Location, from: &Path, to: &Path) -> Result<(), Error> {
607578
debug_now!("renaming {} to {}", &from, &to);
608579
store
609580
.fs(location)
@@ -612,14 +583,14 @@ pub fn rename(store: impl Store, location: Location, from: &Path, to: &Path) ->
612583
}
613584

614585
#[inline(never)]
615-
pub fn remove_dir(store: impl Store, location: Location, path: &Path) -> bool {
586+
pub fn remove_dir(store: &impl Store, location: Location, path: &Path) -> bool {
616587
debug_now!("remove_dir'ing {}", &path);
617588
store.fs(location).remove_dir(path).is_ok()
618589
}
619590

620591
#[inline(never)]
621592
pub fn remove_dir_all_where(
622-
store: impl Store,
593+
store: &impl Store,
623594
location: Location,
624595
path: &Path,
625596
predicate: &dyn Fn(&DirEntry) -> bool,

src/store/certstore.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ impl<S: Store> Certstore for ClientCertstore<S> {
3131
let locations = [Location::Internal, Location::External, Location::Volatile];
3232
locations
3333
.iter()
34-
.any(|&location| store::delete(self.store, location, &path))
34+
.any(|&location| store::delete(&self.store, location, &path))
3535
.then_some(())
3636
.ok_or(Error::NoSuchKey)
3737
}
@@ -41,14 +41,14 @@ impl<S: Store> Certstore for ClientCertstore<S> {
4141
let locations = [Location::Internal, Location::External, Location::Volatile];
4242
locations
4343
.iter()
44-
.find_map(|&location| store::read(self.store, location, &path).ok())
44+
.find_map(|&location| store::read(&self.store, location, &path).ok())
4545
.ok_or(Error::NoSuchCertificate)
4646
}
4747

4848
fn write_certificate(&mut self, location: Location, der: &Message) -> Result<CertId> {
4949
let id = CertId::new(&mut self.rng);
5050
let path = self.cert_path(id);
51-
store::store(self.store, location, &path, der.as_slice())?;
51+
store::store(&self.store, location, &path, der.as_slice())?;
5252
Ok(id)
5353
}
5454
}

src/store/counterstore.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@ impl<S: Store> ClientCounterstore<S> {
3737

3838
fn read_counter(&mut self, location: Location, id: CounterId) -> Result<Counter> {
3939
let path = self.counter_path(id);
40-
let mut bytes: crate::Bytes<16> = store::read(self.store, location, &path)?;
40+
let mut bytes: crate::Bytes<16> = store::read(&self.store, location, &path)?;
4141
bytes.resize_default(16).ok();
4242
Ok(u128::from_le_bytes(bytes.as_slice().try_into().unwrap()))
4343
}
4444

4545
fn write_counter(&mut self, location: Location, id: CounterId, value: u128) -> Result<()> {
4646
let path = self.counter_path(id);
47-
store::store(self.store, location, &path, &value.to_le_bytes())
47+
store::store(&self.store, location, &path, &value.to_le_bytes())
4848
}
4949

5050
fn increment_location(&mut self, location: Location, id: CounterId) -> Result<Counter> {

0 commit comments

Comments
 (0)