Skip to content

Commit cdcb99f

Browse files
committed
Updates
- rely on new resolver - remove driver parameters which can't actually be used - bump heapless Keeps generic-array, as associated constants still can't be used as constants.
1 parent 8dee660 commit cdcb99f

File tree

7 files changed

+69
-78
lines changed

7 files changed

+69
-78
lines changed

Cargo.toml

+5-24
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,25 @@
11
[package]
22
name = "littlefs2"
33
description = "Idiomatic Rust API for littlefs"
4-
version = "0.2.2"
4+
version = "0.3.0"
55
authors = ["Nicolas Stalder <n@stalder.io>", "Brandon Edens <brandonedens@gmail.com>"]
66
edition = "2018"
77
license = "Apache-2.0 OR MIT"
88
readme = "README.md"
99
categories = ["embedded", "filesystem", "no-std"]
1010
repository = "https://github.com/nickray/littlefs2"
11+
resolver = "2"
1112

1213
[dependencies]
1314
bitflags = "1"
1415
cty = "0.2.1"
1516
delog = "0.1.0"
16-
generic-array = "0.14.2"
17-
heapless = "0.6"
17+
generic-array = "0.14"
18+
heapless = "0.7"
1819

1920
[dependencies.cstr_core]
2021
default-features = false
21-
# Update: we are just waiting for stabilization of
22-
# https://doc.rust-lang.org/beta/cargo/reference/unstable.html#resolver
23-
24-
# HACK TL;DR :sadface: we are using an older version here to avoid
25-
# rust-lang/cargo#4361 which has been fixed in nightly but lives behind a
26-
# unstable flag as of Rust 1.42.0
27-
#
28-
# longer explanation: this crate depends on bindgen (build dependency) and
29-
# bindgen depends on `memchr` "2" with default features enabled, which include a
30-
# "std" feature that makes the crate depend on `std`. `cstr_core` ">0.1.1" and
31-
# "0.2" also depend on "memchr" but with default features disabled. As this
32-
# crate depends on both it ends up enabling the "std" of the `memchr` crate
33-
# (that's the bug because that shouldn't happen).
34-
#
35-
# To avoid `bindgen` enabling the "std" dependency of `memchr` "2" we use an
36-
# older version of `cstr_core` that depends on version of "1" of `memchr`. This
37-
# way the bug won't enable the "std" of `memchr` "1" (because `memchr` "1" and
38-
# `memchr` "2" are considered different crates)
39-
#
40-
# NB: It really has to be 0.1.0, both 0.1.1 and 0.1.2 don't work
41-
version = "=0.1.0"
22+
version = "0.2"
4223

4324
[dependencies.littlefs2-sys]
4425
version = "0.1.6"

src/consts.rs

+1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ pub const PATH_MAX: usize = 255;
1010
pub const PATH_MAX_PLUS_ONE: usize = PATH_MAX + 1;
1111
pub const FILEBYTES_MAX: u32 = crate::ll::LFS_FILE_MAX as _;
1212
pub const ATTRBYTES_MAX: u32 = 1_022;
13+
pub type ATTRBYTES_MAX_TYPE = U1022;
1314
pub const LOOKAHEADWORDS_SIZE: u32 = 16;
1415

src/driver.rs

+22-22
Original file line numberDiff line numberDiff line change
@@ -59,35 +59,35 @@ pub trait Storage {
5959
type LOOKAHEADWORDS_SIZE: ArrayLength<u32>;
6060
// type LOOKAHEAD_SIZE: ArrayLength<u8>;
6161

62-
/// Maximum length of a filename plus one. Stored in superblock.
63-
/// Should default to 255+1, but associated type defaults don't exist currently.
64-
/// At most 1_022+1.
65-
///
66-
/// TODO: We can't actually change this - need to pass on as compile flag
67-
/// to the C backend.
68-
type FILENAME_MAX_PLUS_ONE: ArrayLength<u8>;
62+
///// Maximum length of a filename plus one. Stored in superblock.
63+
///// Should default to 255+1, but associated type defaults don't exist currently.
64+
///// At most 1_022+1.
65+
/////
66+
///// TODO: We can't actually change this - need to pass on as compile flag
67+
///// to the C backend.
68+
//type FILENAME_MAX_PLUS_ONE: ArrayLength<u8>;
6969

7070
/// Maximum length of a path plus one. Necessary to convert Rust string slices
7171
/// to C strings, which requires an allocation for the terminating
7272
/// zero-byte. If in doubt, set to `FILENAME_MAX_PLUS_ONE`.
7373
/// Must be larger than `FILENAME_MAX_PLUS_ONE`.
7474
type PATH_MAX_PLUS_ONE: ArrayLength<u8>;
7575

76-
/// Maximum size of file. Stored in superblock.
77-
/// Defaults to 2_147_483_647 (or u31, to avoid sign issues in the C code).
78-
/// At most 2_147_483_647.
79-
///
80-
/// TODO: We can't actually change this - need to pass on as compile flag
81-
/// to the C backend.
82-
const FILEBYTES_MAX: usize = ll::LFS_FILE_MAX as _;
83-
84-
/// Maximum size of custom attributes.
85-
/// Should default to 1_022, but associated type defaults don't exists currently.
86-
/// At most 1_022.
87-
///
88-
/// TODO: We can't actually change this - need to pass on as compile flag
89-
/// to the C backend.
90-
type ATTRBYTES_MAX: ArrayLength<u8>;
76+
///// Maximum size of file. Stored in superblock.
77+
///// Defaults to 2_147_483_647 (or u31, to avoid sign issues in the C code).
78+
///// At most 2_147_483_647.
79+
/////
80+
///// TODO: We can't actually change this - need to pass on as compile flag
81+
///// to the C backend.
82+
//const FILEBYTES_MAX: usize = ll::LFS_FILE_MAX as _;
83+
84+
///// Maximum size of custom attributes.
85+
///// Should default to 1_022, but associated type defaults don't exists currently.
86+
///// At most 1_022.
87+
/////
88+
///// TODO: We can't actually change this - need to pass on as compile flag
89+
///// to the C backend.
90+
//type ATTRBYTES_MAX: ArrayLength<u8>;
9191

9292
/// Read data from the storage device.
9393
/// Guaranteed to be called only with bufs of length a multiple of READ_SIZE.

src/fs.rs

+34-21
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ pub struct Allocation<Storage: driver::Storage> {
4848

4949
// pub fn check_storage_requirements(
5050

51+
impl<Storage: driver::Storage> Default for Allocation<Storage> {
52+
fn default() -> Self {
53+
Self::new()
54+
}
55+
}
5156
impl<Storage: driver::Storage> Allocation<Storage> {
5257

5358
pub fn new() -> Allocation<Storage> {
@@ -86,21 +91,20 @@ impl<Storage: driver::Storage> Allocation<Storage> {
8691

8792
let cache = Cache::new();
8893

89-
let filename_max_plus_one: u32 =
90-
<Storage as driver::Storage>::FILENAME_MAX_PLUS_ONE::to_u32();
94+
let filename_max_plus_one: u32 = crate::consts::FILENAME_MAX_PLUS_ONE;
9195
debug_assert!(filename_max_plus_one > 1);
9296
debug_assert!(filename_max_plus_one <= 1_022+1);
9397
// limitation of ll-bindings
9498
debug_assert!(filename_max_plus_one == 255+1);
9599
let path_max_plus_one: u32 = <Storage as driver::Storage>::PATH_MAX_PLUS_ONE::to_u32();
96100
// TODO: any upper limit?
97101
debug_assert!(path_max_plus_one >= filename_max_plus_one);
98-
let file_max = Storage::FILEBYTES_MAX as u32;
102+
let file_max = crate::consts::FILEBYTES_MAX;
99103
assert!(file_max > 0);
100104
assert!(file_max <= 2_147_483_647);
101105
// limitation of ll-bindings
102106
assert!(file_max == 2_147_483_647);
103-
let attr_max: u32 = <Storage as driver::Storage>::ATTRBYTES_MAX::to_u32();
107+
let attr_max: u32 = crate::consts::ATTRBYTES_MAX;
104108
assert!(attr_max > 0);
105109
assert!(attr_max <= 1_022);
106110
// limitation of ll-bindings
@@ -130,7 +134,7 @@ impl<Storage: driver::Storage> Allocation<Storage> {
130134

131135
name_max: filename_max_plus_one.wrapping_sub(1),
132136
file_max,
133-
attr_max: attr_max,
137+
attr_max,
134138
};
135139

136140
Self {
@@ -237,10 +241,7 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {
237241
// TODO: check if this is equivalent to `is_formatted`.
238242
pub fn is_mountable(storage: &mut Storage) -> bool {
239243
let alloc = &mut Allocation::new();
240-
match Filesystem::mount(alloc, storage) {
241-
Ok(_) => true,
242-
_ => false,
243-
}
244+
matches!(Filesystem::mount(alloc, storage), Ok(_))
244245
}
245246

246247
// Can BorrowMut be implemented "unsafely" instead?
@@ -434,10 +435,10 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {
434435
path: &Path,
435436
id: u8,
436437
) ->
437-
Result<Option<Attribute<Storage>>>
438+
Result<Option<Attribute>>
438439
{
439440
let mut attribute = Attribute::new(id);
440-
let attr_max = <Storage as driver::Storage>::ATTRBYTES_MAX::to_u32();
441+
let attr_max = crate::consts::ATTRBYTES_MAX;
441442

442443
let return_code = unsafe { ll::lfs_getattr(
443444
&mut self.alloc.borrow_mut().state,
@@ -478,7 +479,7 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {
478479
pub fn set_attribute(
479480
&self,
480481
path: &Path,
481-
attribute: &Attribute<Storage>
482+
attribute: &Attribute,
482483
) ->
483484
Result<()>
484485
{
@@ -571,13 +572,13 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {
571572
/// Use [`Filesystem::attribute`](struct.Filesystem.html#method.attribute),
572573
/// [`Filesystem::set_attribute`](struct.Filesystem.html#method.set_attribute), and
573574
/// [`Filesystem::clear_attribute`](struct.Filesystem.html#method.clear_attribute).
574-
pub struct Attribute<S: driver::Storage> {
575+
pub struct Attribute {
575576
id: u8,
576-
data: Bytes<S::ATTRBYTES_MAX>,
577+
data: Bytes<crate::consts::ATTRBYTES_MAX_TYPE>,
577578
size: usize,
578579
}
579580

580-
impl<S: driver::Storage> Attribute<S> {
581+
impl Attribute {
581582
pub fn new(id: u8) -> Self {
582583
Attribute {
583584
id,
@@ -591,13 +592,13 @@ impl<S: driver::Storage> Attribute<S> {
591592
}
592593

593594
pub fn data(&self) -> &[u8] {
594-
let attr_max = <S as driver::Storage>::ATTRBYTES_MAX::to_usize();
595+
let attr_max = crate::consts::ATTRBYTES_MAX as _;
595596
let len = cmp::min(attr_max, self.size);
596597
&self.data[..len]
597598
}
598599

599600
pub fn set_data(&mut self, data: &[u8]) -> &mut Self {
600-
let attr_max = <S as driver::Storage>::ATTRBYTES_MAX::to_usize();
601+
let attr_max = crate::consts::ATTRBYTES_MAX as _;
601602
let len = cmp::min(attr_max, data.len());
602603
self.data[..len].copy_from_slice(&data[..len]);
603604
self.size = len;
@@ -638,6 +639,12 @@ pub struct FileAllocation<S: driver::Storage>
638639
config: ll::lfs_file_config,
639640
}
640641

642+
impl<S: driver::Storage> Default for FileAllocation<S> {
643+
fn default() -> Self {
644+
Self::new()
645+
}
646+
}
647+
641648
impl<S: driver::Storage> FileAllocation<S> {
642649
pub fn new() -> Self {
643650
let cache_size: u32 = <S as driver::Storage>::CACHE_SIZE::to_u32();
@@ -782,7 +789,7 @@ impl<'a, 'b, Storage: driver::Storage> File<'a, 'b, Storage>
782789
}
783790

784791
// This belongs in `io::Read` but really don't want that to have a generic parameter
785-
pub fn read_to_end<N: heapless::ArrayLength<u8>>(&self, buf: &mut heapless::Vec<u8, N>) -> Result<usize> {
792+
pub fn read_to_end<const N: usize>(&self, buf: &mut heapless::Vec<u8, N>) -> Result<usize> {
786793
// My understanding of
787794
// https://github.com/ARMmbed/littlefs/blob/4c9146ea539f72749d6cc3ea076372a81b12cb11/lfs.c#L2816
788795
// is that littlefs keeps reading until either the buffer is full, or the file is exhausted
@@ -1032,6 +1039,12 @@ pub struct ReadDirAllocation {
10321039
state: ll::lfs_dir_t,
10331040
}
10341041

1042+
impl Default for ReadDirAllocation {
1043+
fn default() -> Self {
1044+
Self::new()
1045+
}
1046+
}
1047+
10351048
impl ReadDirAllocation {
10361049
pub fn new() -> Self {
10371050
unsafe { mem::MaybeUninit::zeroed().assume_init() }
@@ -1258,7 +1271,7 @@ impl<'a, Storage: driver::Storage> Filesystem<'a, Storage> {
12581271
}
12591272

12601273
/// Read the entire contents of a file into a bytes vector.
1261-
pub fn read<N: generic_array::ArrayLength<u8>>(
1274+
pub fn read<const N: usize>(
12621275
&self,
12631276
path: &Path,
12641277
)
@@ -1375,7 +1388,7 @@ mod tests {
13751388
println!("\nfile {}: {:?}", i, entry.file_name());
13761389

13771390
if entry.file_type().is_file() {
1378-
let content: heapless::Vec::<u8, heapless::consts::U256> = fs.read(entry.path())?;
1391+
let content: heapless::Vec::<u8, 256> = fs.read(entry.path())?;
13791392
println!("content:\n{:?}", core::str::from_utf8(&content).unwrap());
13801393
// println!("and now the removal");
13811394
// fs.remove(entry.path())?;
@@ -1476,7 +1489,7 @@ mod tests {
14761489
}
14771490
)?;
14781491

1479-
let content: heapless::Vec<_, consts::U256> = fs.read(filename)?;
1492+
let content: heapless::Vec<_, 256> = fs.read(filename)?;
14801493
assert_eq!(content, b"first part - second part");
14811494
// println!("content: {:?}", core::str::from_utf8(&content).unwrap());
14821495
Ok(())

src/macros.rs

-4
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,7 @@ macro_rules! ram_storage { (
5050
const BLOCK_SIZE: usize = $block_size;
5151
const BLOCK_COUNT: usize = $block_count;
5252
type LOOKAHEADWORDS_SIZE = $lookaheadwords_size;
53-
type FILENAME_MAX_PLUS_ONE = $filename_max_plus_one;
5453
type PATH_MAX_PLUS_ONE = $path_max_plus_one;
55-
type ATTRBYTES_MAX = consts::U1022;
5654

5755
fn read(&self, offset: usize, buf: &mut [u8]) -> $Result<usize> {
5856
let read_size: usize = Self::READ_SIZE;
@@ -182,9 +180,7 @@ macro_rules! const_ram_storage { (
182180
const BLOCK_SIZE: usize = $block_size;
183181
const BLOCK_COUNT: usize = $block_count;
184182
type LOOKAHEADWORDS_SIZE = $lookaheadwords_size;
185-
type FILENAME_MAX_PLUS_ONE = $filename_max_plus_one;
186183
type PATH_MAX_PLUS_ONE = $path_max_plus_one;
187-
type ATTRBYTES_MAX = consts::U1022;
188184

189185
fn read(&self, offset: usize, buf: &mut [u8]) -> $Result<usize> {
190186
let read_size: usize = Self::READ_SIZE;

src/path.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ impl Path {
2323
///
2424
/// The buffer will be first interpreted as a `CStr` and then checked to be comprised only of
2525
/// ASCII characters.
26-
pub fn from_bytes_with_nul<'b>(bytes: &'b [u8]) -> Result<&'b Self> {
26+
pub fn from_bytes_with_nul(bytes: &[u8]) -> Result<&Self> {
2727
let cstr = CStr::from_bytes_with_nul(bytes).map_err(|_| Error::NotCStr)?;
2828
Self::from_cstr(cstr)
2929
}
@@ -40,7 +40,7 @@ impl Path {
4040
///
4141
/// The string will be checked to be comprised only of ASCII characters
4242
// XXX should we reject empty paths (`""`) here?
43-
pub fn from_cstr<'s>(cstr: &'s CStr) -> Result<&'s Self> {
43+
pub fn from_cstr(cstr: &CStr) -> Result<&Self> {
4444
let bytes = cstr.to_bytes();
4545
let n = cstr.to_bytes().len();
4646
if n > consts::PATH_MAX {
@@ -277,7 +277,7 @@ impl From<&[u8]> for PathBuf {
277277
fn from(bytes: &[u8]) -> Self {
278278
// NB: This needs to set the final NUL byte, unless it already has one
279279
// It also checks that there are no inner NUL bytes
280-
let bytes = if bytes.len() > 0 && bytes[bytes.len() - 1] == b'\0' {
280+
let bytes = if !bytes.is_empty() && bytes[bytes.len() - 1] == b'\0' {
281281
&bytes[..bytes.len() - 1]
282282
} else {
283283
bytes
@@ -347,7 +347,7 @@ impl<'de> serde::Deserialize<'de> for PathBuf
347347
E: serde::de::Error,
348348
{
349349
if v.len() > consts::PATH_MAX {
350-
return Err(E::invalid_length(v.len(), &self))?;
350+
return Err(E::invalid_length(v.len(), &self));
351351
}
352352
Ok(PathBuf::from(v))
353353
}

src/tests.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ fn test_create() {
245245

246246
// alternative approach
247247
file.seek(SeekFrom::Start(0))?;
248-
let mut contents_vec = heapless::Vec::<u8, consts::U3>::new();
248+
let mut contents_vec = heapless::Vec::<u8, 3>::new();
249249
assert!(file.read_to_end(&mut contents_vec).unwrap() == 3);
250250
Ok(())
251251
})?;
@@ -273,7 +273,7 @@ fn test_unbind() {
273273

274274
let mut storage = RamStorage::new(&mut backend);
275275
Filesystem::mount_and_then(&mut storage, |fs| {
276-
let contents: heapless::Vec<_, consts::U37> = fs.read(b"test_unbind.txt\0".try_into().unwrap())?;
276+
let contents: heapless::Vec<_, 37> = fs.read(b"test_unbind.txt\0".try_into().unwrap())?;
277277
assert_eq!(contents, b"hello world");
278278
Ok(())
279279
}).unwrap();
@@ -358,7 +358,7 @@ fn attributes() {
358358
fs.write(filename, &[])?;
359359
assert!(fs.attribute(filename, 37)?.is_none());
360360

361-
let mut attribute = Attribute::<RamStorage>::new(37);
361+
let mut attribute = Attribute::new(37);
362362
attribute.set_data(b"top secret");
363363

364364
fs.set_attribute(filename, &attribute).unwrap();

0 commit comments

Comments
 (0)