Skip to content

Commit 9fd5937

Browse files
authored
Merge pull request #223 from robamu/bump-embedded-io
bump embedded-io to v0.7 and introduce thiserror
2 parents 69e1754 + c77385f commit 9fd5937

6 files changed

Lines changed: 56 additions & 90 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@ The format is based on [Keep a Changelog] and this project adheres to [Semantic
1717
- Added `open_long_name_file_in_dir` API, to open files using their Long File Name
1818
- Updated directory iterator callback, to allow bailing out early (breaking change)
1919
- `crc7` function now returns the actual CRC7 value without left-shifting by and XOR-ing by/with 1.
20+
- Bumped `embedded-io` to 0.7
2021

2122
### Added
2223

2324
- Added `CsdV3` data structure.
2425
- `Csd::new` constructor which creates the CSD from a raw `&[u8; 16]` and also performs a CRC7
2526
check.
2627
- Added `verify_crc7` function on CSD structures.
28+
- Added `core::error::Error` bounds to device driver error type
2729

2830
## [Version 0.9.0] - 2025-06-08
2931

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ rust-version = "1.87"
1717
byteorder = {version = "1", default-features = false}
1818
defmt = {version = "1.0.1", optional = true}
1919
embedded-hal = "1.0.0"
20-
embedded-io = "0.6.1"
20+
embedded-io = "0.7"
2121
bitbybit = "2"
2222
arbitrary-int = "2"
2323
bitflags = "2"

src/blockdevice.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ impl Default for Block {
7777
/// sectors). Only supports devices which are <= 2 TiB in size.
7878
pub trait BlockDevice {
7979
/// The errors that the `BlockDevice` can return. Must be debug formattable.
80-
type Error: core::fmt::Debug;
80+
type Error: core::error::Error + 'static;
8181
/// Read one or more blocks, starting at the given block index.
8282
fn read(&self, blocks: &mut [Block], start_block_idx: BlockIdx) -> Result<(), Self::Error>;
8383
/// Write one or more blocks, starting at the given block index.

src/lib.rs

Lines changed: 34 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -158,77 +158,107 @@ macro_rules! warn {
158158

159159
/// All the ways the functions in this crate can fail.
160160
#[cfg_attr(feature = "defmt-log", derive(defmt::Format))]
161-
#[derive(Debug, Clone)]
161+
#[derive(Debug, Clone, thiserror::Error)]
162162
pub enum Error<E>
163163
where
164-
E: core::fmt::Debug,
164+
E: core::error::Error,
165165
{
166166
/// The underlying block device threw an error.
167-
DeviceError(E),
167+
#[error("error from underlying block device: {0}")]
168+
DeviceError(#[from] E),
168169
/// The filesystem is badly formatted (or this code is buggy).
170+
#[error("filesystem is badly formatted: {0}")]
169171
FormatError(&'static str),
170172
/// The given `VolumeIdx` was bad,
173+
#[error("no such volume")]
171174
NoSuchVolume,
172175
/// The given filename was bad
176+
#[error("bad filename")]
173177
FilenameError(FilenameError),
174178
/// Out of memory opening volumes
179+
#[error("too many open volumes")]
175180
TooManyOpenVolumes,
176181
/// Out of memory opening directories
182+
#[error("too many open directories")]
177183
TooManyOpenDirs,
178184
/// Out of memory opening files
185+
#[error("too many open files")]
179186
TooManyOpenFiles,
180187
/// Bad handle given
188+
#[error("bad handle")]
181189
BadHandle,
182190
/// That file or directory doesn't exist
191+
#[error("file or directory does not exist")]
183192
NotFound,
184193
/// You can't open a file twice or delete an open file
194+
#[error("file already open")]
185195
FileAlreadyOpen,
186196
/// You can't open a directory twice
197+
#[error("directory already open")]
187198
DirAlreadyOpen,
188199
/// You can't open a directory as a file
200+
#[error("cannot open directory as file")]
189201
OpenedDirAsFile,
190202
/// You can't open a file as a directory
203+
#[error("cannot open file as directory")]
191204
OpenedFileAsDir,
192205
/// You can't delete a non-empty directory
206+
#[error("cannot delete a non-empty directory")]
193207
DeleteNonEmptyDir,
194208
/// You can't close a volume with open files or directories
209+
#[error("volume is still in use")]
195210
VolumeStillInUse,
196211
/// You can't open a volume twice
212+
#[error("cannot open volume twice")]
197213
VolumeAlreadyOpen,
198214
/// We can't do that yet
215+
#[error("unsupported operation")]
199216
Unsupported,
200217
/// Tried to read beyond end of file
218+
#[error("end of file")]
201219
EndOfFile,
202220
/// Found a bad cluster
221+
#[error("bad cluster")]
203222
BadCluster,
204223
/// Error while converting types
224+
#[error("type conversion failed")]
205225
ConversionError,
206226
/// The device does not have enough space for the operation
227+
#[error("not enough space on device")]
207228
NotEnoughSpace,
208229
/// Cluster was not properly allocated by the library
230+
#[error("cluster not properly allocated")]
209231
AllocationError,
210232
/// Jumped to free space during FAT traversing
233+
#[error("FAT chain unterminated")]
211234
UnterminatedFatChain,
212235
/// Tried to open Read-Only file with write mode
236+
#[error("file is read-only")]
213237
ReadOnly,
214238
/// Tried to create an existing file
239+
#[error("file already exists")]
215240
FileAlreadyExists,
216241
/// Bad block size - only 512 byte blocks supported
242+
#[error("bad block size: {0} (only 512 byte blocks supported)")]
217243
BadBlockSize(u16),
218244
/// Bad offset given when seeking
245+
#[error("invalid seek offset")]
219246
InvalidOffset,
220247
/// Disk is full
248+
#[error("disk full")]
221249
DiskFull,
222250
/// A directory with that name already exists
251+
#[error("directory already exists")]
223252
DirAlreadyExists,
224253
/// The filesystem tried to gain a lock whilst already locked.
225254
///
226255
/// This is either a bug in the filesystem, or you tried to access the
227256
/// filesystem API from inside a directory iterator (that isn't allowed).
257+
#[error("already locked")]
228258
LockError,
229259
}
230260

231-
impl<E: Debug> embedded_io::Error for Error<E> {
261+
impl<E: core::error::Error + 'static> embedded_io::Error for Error<E> {
232262
fn kind(&self) -> ErrorKind {
233263
match self {
234264
Error::DeviceError(_)
@@ -263,59 +293,6 @@ impl<E: Debug> embedded_io::Error for Error<E> {
263293
}
264294
}
265295

266-
impl<E> From<E> for Error<E>
267-
where
268-
E: core::fmt::Debug,
269-
{
270-
fn from(value: E) -> Error<E> {
271-
Error::DeviceError(value)
272-
}
273-
}
274-
275-
impl<E> core::fmt::Display for Error<E>
276-
where
277-
E: core::fmt::Debug + core::fmt::Display,
278-
{
279-
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
280-
match self {
281-
Error::DeviceError(e) => write!(f, "error from underlying block device: {e}"),
282-
Error::FormatError(s) => write!(f, "filesystem is badly formatted: {s}"),
283-
Error::NoSuchVolume => write!(f, "no such volume"),
284-
Error::FilenameError(_) => write!(f, "bad filename"),
285-
Error::TooManyOpenVolumes => write!(f, "too many open volumes"),
286-
Error::TooManyOpenDirs => write!(f, "too many open directories"),
287-
Error::TooManyOpenFiles => write!(f, "too many open files"),
288-
Error::BadHandle => write!(f, "bad handle"),
289-
Error::NotFound => write!(f, "file or directory does not exist"),
290-
Error::FileAlreadyOpen => write!(f, "file already open"),
291-
Error::DirAlreadyOpen => write!(f, "directory already open"),
292-
Error::OpenedDirAsFile => write!(f, "cannot open directory as file"),
293-
Error::OpenedFileAsDir => write!(f, "cannot open file as directory"),
294-
Error::DeleteNonEmptyDir => write!(f, "cannot delete a non-empty directory"),
295-
Error::VolumeStillInUse => write!(f, "volume is still in use"),
296-
Error::VolumeAlreadyOpen => write!(f, "cannot open volume twice"),
297-
Error::Unsupported => write!(f, "unsupported operation"),
298-
Error::EndOfFile => write!(f, "end of file"),
299-
Error::BadCluster => write!(f, "bad cluster"),
300-
Error::ConversionError => write!(f, "type conversion failed"),
301-
Error::NotEnoughSpace => write!(f, "not enough space on device"),
302-
Error::AllocationError => write!(f, "cluster not properly allocated"),
303-
Error::UnterminatedFatChain => write!(f, "FAT chain unterminated"),
304-
Error::ReadOnly => write!(f, "file is read-only"),
305-
Error::FileAlreadyExists => write!(f, "file already exists"),
306-
Error::BadBlockSize(size) => {
307-
write!(f, "bad block size: {size} (only 512 byte blocks supported)")
308-
}
309-
Error::InvalidOffset => write!(f, "invalid seek offset"),
310-
Error::DiskFull => write!(f, "disk full"),
311-
Error::DirAlreadyExists => write!(f, "directory already exists"),
312-
Error::LockError => write!(f, "already locked"),
313-
}
314-
}
315-
}
316-
317-
impl<E> core::error::Error for Error<E> where E: core::fmt::Debug + core::fmt::Display {}
318-
319296
/// A handle to a volume.
320297
///
321298
/// A volume is a partition with a filesystem within it.

src/volume_mgr.rs

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ pub struct VolumeManager<
3636
> where
3737
D: BlockDevice,
3838
T: TimeSource,
39-
<D as BlockDevice>::Error: core::fmt::Debug,
4039
{
4140
time_source: T,
4241
data: RefCell<VolumeManagerData<D, MAX_DIRS, MAX_FILES, MAX_VOLUMES>>,
@@ -46,7 +45,6 @@ impl<D, T> VolumeManager<D, T, 4, 4>
4645
where
4746
D: BlockDevice,
4847
T: TimeSource,
49-
<D as BlockDevice>::Error: core::fmt::Debug,
5048
{
5149
/// Create a new Volume Manager using a generic `BlockDevice`. From this
5250
/// object we can open volumes (partitions) and with those we can open
@@ -67,7 +65,6 @@ impl<D, T, const MAX_DIRS: usize, const MAX_FILES: usize, const MAX_VOLUMES: usi
6765
where
6866
D: BlockDevice,
6967
T: TimeSource,
70-
<D as BlockDevice>::Error: core::fmt::Debug,
7168
{
7269
/// Create a new Volume Manager using a generic `BlockDevice`. From this
7370
/// object we can open volumes (partitions) and with those we can open
@@ -1430,6 +1427,7 @@ impl<D, const MAX_DIRS: usize, const MAX_FILES: usize, const MAX_VOLUMES: usize>
14301427
VolumeManagerData<D, MAX_DIRS, MAX_FILES, MAX_VOLUMES>
14311428
where
14321429
D: BlockDevice,
1430+
<D as BlockDevice>::Error: core::error::Error,
14331431
{
14341432
/// Check if a file is open
14351433
///
@@ -1446,10 +1444,10 @@ where
14461444
false
14471445
}
14481446

1449-
fn get_volume_by_id<E>(&self, raw_volume: RawVolume) -> Result<usize, Error<E>>
1450-
where
1451-
E: core::fmt::Debug,
1452-
{
1447+
fn get_volume_by_id<E: core::error::Error>(
1448+
&self,
1449+
raw_volume: RawVolume,
1450+
) -> Result<usize, Error<E>> {
14531451
for (idx, v) in self.open_volumes.iter().enumerate() {
14541452
if v.raw_volume == raw_volume {
14551453
return Ok(idx);
@@ -1458,10 +1456,10 @@ where
14581456
Err(Error::BadHandle)
14591457
}
14601458

1461-
fn get_dir_by_id<E>(&self, raw_directory: RawDirectory) -> Result<usize, Error<E>>
1462-
where
1463-
E: core::fmt::Debug,
1464-
{
1459+
fn get_dir_by_id<E: core::error::Error>(
1460+
&self,
1461+
raw_directory: RawDirectory,
1462+
) -> Result<usize, Error<E>> {
14651463
for (idx, d) in self.open_dirs.iter().enumerate() {
14661464
if d.raw_directory == raw_directory {
14671465
return Ok(idx);
@@ -1470,10 +1468,7 @@ where
14701468
Err(Error::BadHandle)
14711469
}
14721470

1473-
fn get_file_by_id<E>(&self, raw_file: RawFile) -> Result<usize, Error<E>>
1474-
where
1475-
E: core::fmt::Debug,
1476-
{
1471+
fn get_file_by_id<E: core::error::Error>(&self, raw_file: RawFile) -> Result<usize, Error<E>> {
14771472
for (idx, f) in self.open_files.iter().enumerate() {
14781473
if f.raw_file == raw_file {
14791474
return Ok(idx);
@@ -1570,8 +1565,9 @@ mod tests {
15701565

15711566
struct Clock;
15721567

1573-
#[derive(Debug)]
1568+
#[derive(Debug, thiserror::Error)]
15741569
enum Error {
1570+
#[error("unknown error")]
15751571
Unknown,
15761572
}
15771573

tests/utils/mod.rs

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,29 +40,20 @@ use embedded_sdmmc::{Block, BlockCount, BlockDevice, BlockIdx};
4040
/// It will unpack to a Vec that is 1048576 * 512 = 512 MiB in size.
4141
pub static DISK_SOURCE: &[u8] = include_bytes!("../disk.img.gz");
4242

43-
#[derive(Debug)]
43+
#[derive(Debug, thiserror::Error)]
4444
#[allow(dead_code)]
4545
pub enum Error {
4646
/// Failed to read the source image
47-
Io(std::io::Error),
47+
#[error("I/O error: {0}")]
48+
Io(#[from] std::io::Error),
4849
/// Failed to unzip the source image
49-
Decode(flate2::DecompressError),
50+
#[error("flate2 decode error: {0}")]
51+
Decode(#[from] flate2::DecompressError),
5052
/// Asked for a block we don't have
53+
#[error("out of bounds block index: {0:?}")]
5154
OutOfBounds(BlockIdx),
5255
}
5356

54-
impl From<std::io::Error> for Error {
55-
fn from(value: std::io::Error) -> Self {
56-
Self::Io(value)
57-
}
58-
}
59-
60-
impl From<flate2::DecompressError> for Error {
61-
fn from(value: flate2::DecompressError) -> Self {
62-
Self::Decode(value)
63-
}
64-
}
65-
6657
/// Implements the block device traits for a chunk of bytes in RAM.
6758
///
6859
/// The slice should be a multiple of `embedded_sdmmc::Block::LEN` bytes in

0 commit comments

Comments
 (0)