mirror of
https://github.com/trussed-dev/littlefs2.git
synced 2026-06-20 04:16:32 -07:00
Store Filesystem's Allocation as RefCell, allowing some nesting
This commit is contained in:
committed by
Nicolas Stalder
parent
3e75276e2d
commit
71b5068404
+80
-75
@@ -1,6 +1,6 @@
|
||||
//! Experimental Filesystem version using closures.
|
||||
|
||||
use core::{cmp, mem, slice};
|
||||
use core::{cell::RefCell, cmp, mem, slice};
|
||||
|
||||
use bitflags::bitflags;
|
||||
use generic_array::typenum::marker_traits::Unsigned;
|
||||
@@ -157,7 +157,7 @@ impl<Storage: driver::Storage> Allocation<Storage> {
|
||||
// one lifetime is simpler than two... hopefully should be enough
|
||||
// also consider "erasing" the lifetime completely
|
||||
pub struct Filesystem<'a, Storage: driver::Storage> {
|
||||
alloc: &'a mut Allocation<Storage>,
|
||||
alloc: RefCell<&'a mut Allocation<Storage>>,
|
||||
storage: &'a mut Storage,
|
||||
}
|
||||
|
||||
@@ -241,7 +241,8 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {
|
||||
|
||||
let alloc = &mut Allocation::new();
|
||||
let fs = Filesystem::new(alloc, storage);
|
||||
let return_code = unsafe { ll::lfs_format(&mut fs.alloc.state, &fs.alloc.config) };
|
||||
let mut alloc = fs.alloc.borrow_mut();
|
||||
let return_code = unsafe { ll::lfs_format(&mut alloc.state, &alloc.config) };
|
||||
Error::result_from(return_code)
|
||||
}
|
||||
|
||||
@@ -254,22 +255,22 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {
|
||||
}
|
||||
}
|
||||
|
||||
// Can BorrowMut be implemented "unsafely" instead?
|
||||
// This is intended to be a second option, besides `into_inner`, to
|
||||
// get access to the Flash peripheral in Storage.
|
||||
pub unsafe fn borrow_storage_mut(&mut self) -> &mut Storage {
|
||||
&mut self.storage
|
||||
}
|
||||
// // Can BorrowMut be implemented "unsafely" instead?
|
||||
// // This is intended to be a second option, besides `into_inner`, to
|
||||
// // get access to the Flash peripheral in Storage.
|
||||
// pub unsafe fn borrow_storage_mut(&mut self) -> &mut Storage {
|
||||
// &mut self.storage.borrow_mut()
|
||||
// }
|
||||
|
||||
/// This API avoids the need for using `Allocation`.
|
||||
pub fn mount_and_then<R>(
|
||||
storage: &mut Storage,
|
||||
f: impl FnOnce(&mut Filesystem<'_, Storage>) -> Result<R>,
|
||||
f: impl FnOnce(&Filesystem<'_, Storage>) -> Result<R>,
|
||||
) -> Result<R> {
|
||||
|
||||
let mut alloc = Allocation::new();
|
||||
let mut fs = Filesystem::mount(&mut alloc, storage)?;
|
||||
f(&mut fs)
|
||||
let fs = Filesystem::mount(&mut alloc, storage)?;
|
||||
f(&fs)
|
||||
}
|
||||
|
||||
/// Total number of blocks in the filesystem
|
||||
@@ -290,8 +291,8 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {
|
||||
///
|
||||
/// So it would seem that there are *at least* the number of blocks returned
|
||||
/// by this method available, at any given time.
|
||||
pub fn available_blocks(&mut self) -> Result<usize> {
|
||||
let return_code = unsafe { ll::lfs_fs_size( &mut self.alloc.state) };
|
||||
pub fn available_blocks(&self) -> Result<usize> {
|
||||
let return_code = unsafe { ll::lfs_fs_size( &mut self.alloc.borrow_mut().state) };
|
||||
Error::usize_result_from(return_code).map(|blocks| self.total_blocks() - blocks)
|
||||
}
|
||||
|
||||
@@ -300,14 +301,14 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {
|
||||
/// This is a lower bound, more may be available. First, more blocks may be available as
|
||||
/// explained in [`available_blocks`](struct.Filesystem.html#method.available_blocks).
|
||||
/// Second, files may be inlined.
|
||||
pub fn available_space(&mut self) -> Result<usize> {
|
||||
pub fn available_space(&self) -> Result<usize> {
|
||||
self.available_blocks().map(|blocks| blocks * Storage::BLOCK_SIZE)
|
||||
}
|
||||
|
||||
/// Remove a file or directory.
|
||||
pub fn remove(&mut self, path: impl Into<Path<Storage>>) -> Result<()> {
|
||||
pub fn remove(&self, path: impl Into<Path<Storage>>) -> Result<()> {
|
||||
let return_code = unsafe { ll::lfs_remove(
|
||||
&mut self.alloc.state,
|
||||
&mut self.alloc.borrow_mut().state,
|
||||
&path.into() as *const _ as *const cty::c_char,
|
||||
) };
|
||||
Error::result_from(return_code)
|
||||
@@ -315,12 +316,12 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {
|
||||
|
||||
/// Rename or move a file or directory.
|
||||
pub fn rename(
|
||||
&mut self,
|
||||
&self,
|
||||
from: impl Into<Path<Storage>>,
|
||||
to: impl Into<Path<Storage>>,
|
||||
) -> Result<()> {
|
||||
let return_code = unsafe { ll::lfs_rename(
|
||||
&mut self.alloc.state,
|
||||
&mut self.alloc.borrow_mut().state,
|
||||
&from.into() as *const _ as *const cty::c_char,
|
||||
&to.into() as *const _ as *const cty::c_char,
|
||||
) };
|
||||
@@ -331,7 +332,7 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {
|
||||
///
|
||||
/// To read user attributes, use
|
||||
/// [`Filesystem::attribute`](struct.Filesystem.html#method.attribute)
|
||||
pub fn metadata(&mut self, path: impl Into<Path<Storage>>) -> Result<Metadata> {
|
||||
pub fn metadata(&self, path: impl Into<Path<Storage>>) -> Result<Metadata> {
|
||||
|
||||
// do *not* not call assume_init here and pass into the unsafe block.
|
||||
// strange things happen ;)
|
||||
@@ -342,7 +343,7 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {
|
||||
let mut info: ll::lfs_info = unsafe { mem::MaybeUninit::zeroed().assume_init() };
|
||||
let return_code = unsafe {
|
||||
ll::lfs_stat(
|
||||
&mut self.alloc.state,
|
||||
&mut self.alloc.borrow_mut().state,
|
||||
&path.into() as *const _ as *const cty::c_char,
|
||||
&mut info,
|
||||
)
|
||||
@@ -353,7 +354,7 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {
|
||||
|
||||
/// Read attribute.
|
||||
pub fn attribute(
|
||||
&mut self,
|
||||
&self,
|
||||
path: impl Into<Path<Storage>>,
|
||||
id: u8,
|
||||
) ->
|
||||
@@ -363,7 +364,7 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {
|
||||
let attr_max = <Storage as driver::Storage>::ATTRBYTES_MAX::to_u32();
|
||||
|
||||
let return_code = unsafe { ll::lfs_getattr(
|
||||
&mut self.alloc.state,
|
||||
&mut self.alloc.borrow_mut().state,
|
||||
&path.into() as *const _ as *const cty::c_char,
|
||||
id,
|
||||
&mut attribute.data as *mut _ as *mut cty::c_void,
|
||||
@@ -385,12 +386,12 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {
|
||||
|
||||
/// Remove attribute.
|
||||
pub fn remove_attribute(
|
||||
&mut self,
|
||||
&self,
|
||||
path: impl Into<Path<Storage>>,
|
||||
id: u8,
|
||||
) -> Result<()> {
|
||||
let return_code = unsafe { ll::lfs_removeattr(
|
||||
&mut self.alloc.state,
|
||||
&mut self.alloc.borrow_mut().state,
|
||||
&path.into() as *const _ as *const cty::c_char,
|
||||
id,
|
||||
) };
|
||||
@@ -399,14 +400,14 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {
|
||||
|
||||
/// Set attribute.
|
||||
pub fn set_attribute(
|
||||
&mut self,
|
||||
&self,
|
||||
path: impl Into<Path<Storage>>,
|
||||
attribute: &Attribute<Storage>
|
||||
) ->
|
||||
Result<()>
|
||||
{
|
||||
let return_code = unsafe { ll::lfs_setattr(
|
||||
&mut self.alloc.state,
|
||||
&mut self.alloc.borrow_mut().state,
|
||||
&path.into() as *const _ as *const cty::c_char,
|
||||
attribute.id,
|
||||
&attribute.data as *const _ as *const cty::c_void,
|
||||
@@ -571,7 +572,7 @@ impl<S: driver::Storage> FileAllocation<S> {
|
||||
pub struct File<'a, 'b, S: driver::Storage>
|
||||
{
|
||||
alloc: &'b mut FileAllocation<S>,
|
||||
fs: &'b mut Filesystem<'a, S>,
|
||||
fs: &'b Filesystem<'a, S>,
|
||||
#[cfg(test)]
|
||||
path: Path<S>,
|
||||
}
|
||||
@@ -583,7 +584,7 @@ impl<'a, 'b, Storage: driver::Storage> File<'a, 'b, Storage>
|
||||
}
|
||||
|
||||
pub unsafe fn open(
|
||||
fs: &'b mut Filesystem<'a, Storage>,
|
||||
fs: &'b Filesystem<'a, Storage>,
|
||||
alloc: &'b mut FileAllocation<Storage>,
|
||||
path: impl Into<Path<Storage>>,
|
||||
) ->
|
||||
@@ -595,7 +596,7 @@ impl<'a, 'b, Storage: driver::Storage> File<'a, 'b, Storage>
|
||||
}
|
||||
|
||||
pub fn open_and_then<R>(
|
||||
fs: &mut Filesystem<'a, Storage>,
|
||||
fs: &Filesystem<'a, Storage>,
|
||||
path: impl Into<Path<Storage>>,
|
||||
f: impl FnOnce(&mut File<'_, '_, Storage>) -> Result<R>,
|
||||
) ->
|
||||
@@ -607,7 +608,7 @@ impl<'a, 'b, Storage: driver::Storage> File<'a, 'b, Storage>
|
||||
}
|
||||
|
||||
pub unsafe fn create(
|
||||
fs: &'b mut Filesystem<'a, Storage>,
|
||||
fs: &'b Filesystem<'a, Storage>,
|
||||
alloc: &'b mut FileAllocation<Storage>,
|
||||
path: impl Into<Path<Storage>>,
|
||||
) ->
|
||||
@@ -621,7 +622,7 @@ impl<'a, 'b, Storage: driver::Storage> File<'a, 'b, Storage>
|
||||
}
|
||||
|
||||
pub fn create_and_then<R>(
|
||||
fs: &mut Filesystem<'a, Storage>,
|
||||
fs: &Filesystem<'a, Storage>,
|
||||
path: impl Into<Path<Storage>>,
|
||||
f: impl FnOnce(&mut File<'_, '_, Storage>) -> Result<R>,
|
||||
) ->
|
||||
@@ -635,8 +636,8 @@ impl<'a, 'b, Storage: driver::Storage> File<'a, 'b, Storage>
|
||||
}
|
||||
|
||||
// Safety-hatch to experiment with missing parts of API
|
||||
pub unsafe fn borrow_filesystem<'c>(&'c mut self) -> &'c mut Filesystem<'a, Storage> {
|
||||
&mut self.fs
|
||||
pub unsafe fn borrow_filesystem<'c>(&'c mut self) -> &'c Filesystem<'a, Storage> {
|
||||
&self.fs
|
||||
}
|
||||
|
||||
/// Sync the file and drop it from the internal linked list.
|
||||
@@ -658,7 +659,7 @@ impl<'a, 'b, Storage: driver::Storage> File<'a, 'b, Storage>
|
||||
println!("closing file {:?}", &self.path);
|
||||
|
||||
let return_code = ll::lfs_file_close(
|
||||
&mut self.fs.alloc.state,
|
||||
&mut self.fs.alloc.borrow_mut().state,
|
||||
&mut self.alloc.state,
|
||||
);
|
||||
Error::result_from(return_code)
|
||||
@@ -667,7 +668,7 @@ impl<'a, 'b, Storage: driver::Storage> File<'a, 'b, Storage>
|
||||
/// Synchronize file contents to storage.
|
||||
pub fn sync(&mut self) -> Result<()> {
|
||||
let return_code = unsafe { ll::lfs_file_sync(
|
||||
&mut self.fs.alloc.state,
|
||||
&mut self.fs.alloc.borrow_mut().state,
|
||||
&mut self.alloc.state,
|
||||
) };
|
||||
Error::result_from(return_code)
|
||||
@@ -676,7 +677,7 @@ impl<'a, 'b, Storage: driver::Storage> File<'a, 'b, Storage>
|
||||
/// Size of the file in bytes.
|
||||
pub fn len(&mut self) -> Result<usize> {
|
||||
let return_code = unsafe { ll::lfs_file_size(
|
||||
&mut self.fs.alloc.state,
|
||||
&mut self.fs.alloc.borrow_mut().state,
|
||||
&mut self.alloc.state
|
||||
) };
|
||||
Error::usize_result_from(return_code)
|
||||
@@ -689,7 +690,7 @@ impl<'a, 'b, Storage: driver::Storage> File<'a, 'b, Storage>
|
||||
/// of the intermediate data filled in with 0s.
|
||||
pub fn set_len(&mut self, size: usize) -> Result<()> {
|
||||
let return_code = unsafe { ll::lfs_file_truncate(
|
||||
&mut self.fs.alloc.state,
|
||||
&mut self.fs.alloc.borrow_mut().state,
|
||||
&mut self.alloc.state,
|
||||
size as u32,
|
||||
) };
|
||||
@@ -730,7 +731,7 @@ impl OpenOptions {
|
||||
/// Drop and panic if something went wrong.
|
||||
pub unsafe fn open<'a, 'b, S: driver::Storage>(
|
||||
&self,
|
||||
fs: &'b mut Filesystem<'a, S>,
|
||||
fs: &'b Filesystem<'a, S>,
|
||||
alloc: &'b mut FileAllocation<S>,
|
||||
path: impl Into<Path<S>>,
|
||||
) ->
|
||||
@@ -740,7 +741,7 @@ impl OpenOptions {
|
||||
let path = path.into();
|
||||
|
||||
let return_code = ll::lfs_file_opencfg(
|
||||
&mut fs.alloc.state,
|
||||
&mut fs.alloc.borrow_mut().state,
|
||||
&mut alloc.state,
|
||||
&path as *const _ as *const cty::c_char,
|
||||
self.0.bits() as i32,
|
||||
@@ -760,7 +761,7 @@ impl OpenOptions {
|
||||
/// (Hopefully) safe abstraction around `open`.
|
||||
pub fn open_and_then<'a, R, S: driver::Storage>(
|
||||
&self,
|
||||
fs: &mut Filesystem<'a, S>,
|
||||
fs: &Filesystem<'a, S>,
|
||||
path: impl Into<Path<S>>,
|
||||
f: impl FnOnce(&mut File<'a, '_, S>) -> Result<R>,
|
||||
)
|
||||
@@ -841,7 +842,7 @@ impl<S: driver::Storage> io::ReadWith for File<'_, '_, S>
|
||||
{
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
||||
let return_code = unsafe { ll::lfs_file_read(
|
||||
&mut self.fs.alloc.state,
|
||||
&mut self.fs.alloc.borrow_mut().state,
|
||||
&mut self.alloc.state,
|
||||
buf.as_mut_ptr() as *mut cty::c_void,
|
||||
buf.len() as u32,
|
||||
@@ -854,7 +855,7 @@ impl<S: driver::Storage> io::SeekWith for File<'_, '_, S>
|
||||
{
|
||||
fn seek(&mut self, pos: SeekFrom) -> Result<usize> {
|
||||
let return_code = unsafe { ll::lfs_file_seek(
|
||||
&mut self.fs.alloc.state,
|
||||
&mut self.fs.alloc.borrow_mut().state,
|
||||
&mut self.alloc.state,
|
||||
pos.off(),
|
||||
pos.whence(),
|
||||
@@ -867,7 +868,7 @@ impl<S: driver::Storage> io::WriteWith for File<'_, '_, S>
|
||||
{
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||
let return_code = unsafe { ll::lfs_file_write(
|
||||
&mut self.fs.alloc.state,
|
||||
&mut self.fs.alloc.borrow_mut().state,
|
||||
&mut self.alloc.state,
|
||||
buf.as_ptr() as *const cty::c_void,
|
||||
buf.len() as u32,
|
||||
@@ -949,7 +950,7 @@ impl ReadDirAllocation {
|
||||
pub struct ReadDir<'a, 'b, S: driver::Storage>
|
||||
{
|
||||
alloc: &'b mut ReadDirAllocation,
|
||||
fs: &'b mut Filesystem<'a, S>,
|
||||
fs: &'b Filesystem<'a, S>,
|
||||
#[cfg(feature = "dir-entry-path")]
|
||||
path: Path<S>,
|
||||
}
|
||||
@@ -967,7 +968,7 @@ impl<'a, 'b, S: driver::Storage> Iterator for ReadDir<'a, 'b, S>
|
||||
|
||||
let return_code = unsafe {
|
||||
ll::lfs_dir_read(
|
||||
&mut self.fs.alloc.state,
|
||||
&mut self.fs.alloc.borrow_mut().state,
|
||||
&mut self.alloc.state,
|
||||
&mut info,
|
||||
)
|
||||
@@ -1004,8 +1005,8 @@ impl<'a, 'b, S: driver::Storage> Iterator for ReadDir<'a, 'b, S>
|
||||
impl<'a, 'b, S: driver::Storage> ReadDir<'a, 'b, S> {
|
||||
|
||||
// Safety-hatch to experiment with missing parts of API
|
||||
pub unsafe fn borrow_filesystem<'c>(&'c mut self) -> &'c mut Filesystem<'a, S> {
|
||||
&mut self.fs
|
||||
pub unsafe fn borrow_filesystem<'c>(&'c mut self) -> &'c Filesystem<'a, S> {
|
||||
&self.fs
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1020,7 +1021,7 @@ impl<S: driver::Storage> ReadDir<'_, '_, S> {
|
||||
pub /* unsafe */ fn close(self) -> Result<()>
|
||||
{
|
||||
let return_code = unsafe { ll::lfs_dir_close(
|
||||
&mut self.fs.alloc.state,
|
||||
&mut self.fs.alloc.borrow_mut().state,
|
||||
&mut self.alloc.state,
|
||||
) };
|
||||
Error::result_from(return_code)
|
||||
@@ -1037,7 +1038,7 @@ impl<'a, Storage: driver::Storage> Filesystem<'a, Storage> {
|
||||
// f: impl FnOnce(&mut File<'_, '_, S>) -> Result<R>,
|
||||
// )
|
||||
pub fn read_dir_and_then<R>(
|
||||
&mut self,
|
||||
&self,
|
||||
path: impl Into<Path<Storage>>,
|
||||
f: impl FnOnce(&mut ReadDir<'_, '_, Storage>) -> Result<R>,
|
||||
) -> Result<R>
|
||||
@@ -1054,7 +1055,7 @@ impl<'a, Storage: driver::Storage> Filesystem<'a, Storage> {
|
||||
///
|
||||
/// This is unsafe since it can induce UB just like File::open.
|
||||
pub unsafe fn read_dir<'b>(
|
||||
&'b mut self,
|
||||
&'b self,
|
||||
alloc: &'b mut ReadDirAllocation,
|
||||
path: impl Into<Path<Storage>>,
|
||||
) ->
|
||||
@@ -1063,7 +1064,7 @@ impl<'a, Storage: driver::Storage> Filesystem<'a, Storage> {
|
||||
let path = path.into();
|
||||
|
||||
let return_code = ll::lfs_dir_open(
|
||||
&mut self.alloc.state,
|
||||
&mut self.alloc.borrow_mut().state,
|
||||
&mut alloc.state,
|
||||
&path as *const _ as *const cty::c_char,
|
||||
);
|
||||
@@ -1089,7 +1090,9 @@ impl<'a, Storage: driver::Storage> Filesystem<'a, Storage> {
|
||||
) -> Result<Self> {
|
||||
|
||||
let fs = Self::new(alloc, storage);
|
||||
let return_code = unsafe { ll::lfs_mount(&mut fs.alloc.state, &fs.alloc.config) };
|
||||
let mut alloc = fs.alloc.borrow_mut();
|
||||
let return_code = unsafe { ll::lfs_mount(&mut alloc.state, &alloc.config) };
|
||||
drop(alloc);
|
||||
Error::result_from(return_code).map(move |_| { fs } )
|
||||
}
|
||||
|
||||
@@ -1102,7 +1105,7 @@ impl<'a, Storage: driver::Storage> Filesystem<'a, Storage> {
|
||||
alloc.config.prog_buffer = &mut alloc.cache.write as *mut _ as *mut cty::c_void;
|
||||
alloc.config.lookahead_buffer = &mut alloc.cache.lookahead as *mut _ as *mut cty::c_void;
|
||||
|
||||
Filesystem { alloc, storage }
|
||||
Filesystem { alloc: RefCell::new(alloc), storage }
|
||||
}
|
||||
|
||||
/// Deconstruct `Filesystem`, intention is to allow access to
|
||||
@@ -1110,21 +1113,21 @@ impl<'a, Storage: driver::Storage> Filesystem<'a, Storage> {
|
||||
///
|
||||
/// See also `borrow_storage_mut`.
|
||||
pub fn into_inner(self) -> (&'a mut Allocation<Storage>, &'a mut Storage) {
|
||||
(self.alloc, self. storage)
|
||||
(self.alloc.into_inner(), self.storage)
|
||||
}
|
||||
|
||||
/// Creates a new, empty directory at the provided path.
|
||||
pub fn create_dir(&mut self, path: impl Into<Path<Storage>>) -> Result<()> {
|
||||
pub fn create_dir(&self, path: impl Into<Path<Storage>>) -> Result<()> {
|
||||
|
||||
let return_code = unsafe { ll::lfs_mkdir(
|
||||
&mut self.alloc.state,
|
||||
&mut self.alloc.borrow_mut().state,
|
||||
&path.into() as *const _ as *const cty::c_char,
|
||||
) };
|
||||
Error::result_from(return_code)
|
||||
}
|
||||
|
||||
/// Recursively create a directory and all of its parent components if they are missing.
|
||||
pub fn create_dir_all(&mut self, path: impl Into<Path<Storage>>) -> Result<()> {
|
||||
pub fn create_dir_all(&self, path: impl Into<Path<Storage>>) -> Result<()> {
|
||||
// Placeholder implementation!
|
||||
// - Path should gain a few methods
|
||||
// - Maybe should pull in `heapless-bytes` (and merge upstream into `heapless`)
|
||||
@@ -1169,7 +1172,7 @@ impl<'a, Storage: driver::Storage> Filesystem<'a, Storage> {
|
||||
/// This function will create a file if it does not exist,
|
||||
/// and will entirely replace its contents if it does.
|
||||
pub fn write(
|
||||
&mut self,
|
||||
&self,
|
||||
path: impl Into<Path<Storage>>,
|
||||
contents: &[u8],
|
||||
) -> Result<()>
|
||||
@@ -1183,20 +1186,20 @@ impl<'a, Storage: driver::Storage> Filesystem<'a, Storage> {
|
||||
|
||||
}
|
||||
|
||||
impl<Storage: driver::Storage> core::ops::Deref for Filesystem<'_, Storage> {
|
||||
type Target = Storage;
|
||||
// impl<Storage: driver::Storage> core::ops::Deref for Filesystem<'_, Storage> {
|
||||
// type Target = Storage;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.storage
|
||||
}
|
||||
}
|
||||
// fn deref(&self) -> &Self::Target {
|
||||
// &self.storage.borrow()
|
||||
// }
|
||||
// }
|
||||
|
||||
impl<Storage: driver::Storage> core::ops::DerefMut for Filesystem<'_, Storage> {
|
||||
// impl<Storage: driver::Storage> core::ops::DerefMut for Filesystem<'_, Storage> {
|
||||
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.storage
|
||||
}
|
||||
}
|
||||
// fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
// &mut self.storage.borrow_mut()
|
||||
// }
|
||||
// }
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
@@ -1258,7 +1261,7 @@ mod tests {
|
||||
}).unwrap();
|
||||
|
||||
let mut alloc = Allocation::new();
|
||||
let mut fs = Filesystem::mount(&mut alloc, &mut test_storage).unwrap();
|
||||
let fs = Filesystem::mount(&mut alloc, &mut test_storage).unwrap();
|
||||
fs.write("/z.txt", &jackson5).unwrap();
|
||||
}
|
||||
|
||||
@@ -1282,10 +1285,12 @@ mod tests {
|
||||
// Do we want a way to borrow_filesystem for DirEntry?
|
||||
// One usecase is to read data from the files iterated over.
|
||||
//
|
||||
// unsafe { read_dir.borrow_filesystem() }.write(
|
||||
// &entry.file_name()[..],
|
||||
// b"wowee zowie"
|
||||
// )?;
|
||||
if entry.metadata.is_file() {
|
||||
fs.write(
|
||||
&entry.file_name()[..],
|
||||
b"wowee zowie"
|
||||
)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
@@ -123,6 +123,31 @@ pub trait WriteWith {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait WriteClosure {
|
||||
/// Write at most data.len() bytes.
|
||||
/// The file will not necessarily be updated unless
|
||||
/// flush is called as there is a cache.
|
||||
/// Upon success, return how many bytes were written.
|
||||
fn write(&self, data: &[u8]) -> Result<usize>;
|
||||
|
||||
/// Write out all pending writes to storage.
|
||||
fn flush(&self) -> Result<()>;
|
||||
|
||||
fn write_all(&self, mut buf: &[u8]) -> Result<()> {
|
||||
while !buf.is_empty() {
|
||||
match self.write(buf) {
|
||||
Ok(0) => {
|
||||
// failed to write whole buffer
|
||||
return Err(Error::Io)
|
||||
}
|
||||
Ok(n) => buf = &buf[n..],
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/** Enumeration of possible methods to seek within an I/O object.
|
||||
|
||||
Use the [`Seek`](../io/trait.Seek.html) trait.
|
||||
|
||||
Reference in New Issue
Block a user