Skip to content

Commit 19dfd73

Browse files
committed
Replace crate::io traits with embedded-io traits
1 parent a3a834e commit 19dfd73

File tree

12 files changed

+244
-264
lines changed

12 files changed

+244
-264
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ exclude = [
1717

1818
[features]
1919
# Use Rust std library
20-
std = []
20+
std = ["embedded-io/std"]
2121
# LFN (Long File Name) support
2222
lfn = []
2323
# Use dynamic allocation. When used without std please enable core_io/collections
@@ -41,6 +41,7 @@ default = ["chrono", "std", "alloc", "lfn", "unicode", "log_level_trace"]
4141
[dependencies]
4242
bitflags = "1.0"
4343
log = "0.4"
44+
embedded-io = "0.4.0"
4445
chrono = { version = "0.4", default-features = false, features = ["clock"], optional = true }
4546

4647
[dev-dependencies]

src/boot_sector.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use core::u16;
33
use core::u8;
44

55
use crate::dir_entry::DIR_ENTRY_SIZE;
6-
use crate::error::{Error, IoError};
6+
use crate::error::{Error, IoError, ReadExactError};
77
use crate::fs::{FatType, FormatVolumeOptions, FsStatusFlags};
88
use crate::io::{Read, ReadLeExt, Write, WriteLeExt};
99
use crate::table::RESERVED_FAT_ENTRIES;
@@ -46,7 +46,10 @@ pub(crate) struct BiosParameterBlock {
4646
}
4747

4848
impl BiosParameterBlock {
49-
fn deserialize<R: Read>(rdr: &mut R) -> Result<Self, R::Error> {
49+
fn deserialize<R: Read>(rdr: &mut R) -> Result<Self, R::Error>
50+
where
51+
R::Error: From<ReadExactError<R::Error>>,
52+
{
5053
let mut bpb = Self {
5154
bytes_per_sector: rdr.read_u16_le()?,
5255
sectors_per_cluster: rdr.read_u8()?,
@@ -420,7 +423,10 @@ pub(crate) struct BootSector {
420423
}
421424

422425
impl BootSector {
423-
pub(crate) fn deserialize<R: Read>(rdr: &mut R) -> Result<Self, R::Error> {
426+
pub(crate) fn deserialize<R: Read>(rdr: &mut R) -> Result<Self, R::Error>
427+
where
428+
R::Error: From<ReadExactError<R::Error>>,
429+
{
424430
let mut boot = Self::default();
425431
rdr.read_exact(&mut boot.bootjmp)?;
426432
rdr.read_exact(&mut boot.oem_name)?;
@@ -802,6 +808,7 @@ pub(crate) fn format_boot_sector<E: IoError>(
802808
#[cfg(test)]
803809
mod tests {
804810
use super::*;
811+
use crate::io::StdErrWrapper;
805812
use core::u32;
806813

807814
fn init() {
@@ -972,9 +979,10 @@ mod tests {
972979
}
973980
total_sectors_vec.push(u32::MAX);
974981
for total_sectors in total_sectors_vec {
975-
let (boot, _) = format_boot_sector::<()>(&FormatVolumeOptions::new(), total_sectors, bytes_per_sector)
976-
.expect("format_boot_sector");
977-
boot.validate::<()>().expect("validate");
982+
let (boot, _) =
983+
format_boot_sector::<StdErrWrapper>(&FormatVolumeOptions::new(), total_sectors, bytes_per_sector)
984+
.expect("format_boot_sector");
985+
boot.validate::<StdErrWrapper>().expect("validate");
978986
}
979987
}
980988
}

src/dir.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#[cfg(all(not(feature = "std"), feature = "alloc", feature = "lfn"))]
22
use alloc::vec::Vec;
3+
34
use core::char;
45
use core::cmp;
56
use core::num;

src/dir_entry.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#[cfg(all(not(feature = "std"), feature = "alloc"))]
2-
use alloc::string::String;
31
use bitflags::bitflags;
42
use core::char;
53
use core::convert::TryInto;
@@ -8,10 +6,13 @@ use core::fmt;
86
use core::iter;
97
use core::str;
108

9+
#[cfg(all(not(feature = "std"), feature = "alloc", feature = "lfn"))]
10+
use alloc::string::String;
11+
1112
#[cfg(feature = "lfn")]
1213
use crate::dir::LfnBuffer;
1314
use crate::dir::{Dir, DirRawStream};
14-
use crate::error::{Error, IoError};
15+
use crate::error::{Error, IoError, ReadExactError};
1516
use crate::file::File;
1617
use crate::fs::{FatType, FileSystem, OemCpConverter, ReadWriteSeek};
1718
use crate::io::{self, Read, ReadLeExt, Write, WriteLeExt};
@@ -375,17 +376,20 @@ impl DirEntryData {
375376
}
376377
}
377378

378-
pub(crate) fn deserialize<E: IoError, R: Read<Error = Error<E>>>(rdr: &mut R) -> Result<Self, Error<E>> {
379+
pub(crate) fn deserialize<E: IoError, R: Read<Error = Error<E>>>(rdr: &mut R) -> Result<Self, Error<E>>
380+
where
381+
R::Error: From<ReadExactError<R::Error>>,
382+
{
379383
trace!("DirEntryData::deserialize");
380384
let mut name = [0; SFN_SIZE];
381385
match rdr.read_exact(&mut name) {
382-
Err(Error::UnexpectedEof) => {
386+
Err(ReadExactError::UnexpectedEof) => {
383387
// entries can occupy all clusters of directory so there is no zero entry at the end
384388
// handle it here by returning non-existing empty entry
385389
return Ok(DirEntryData::File(DirFileEntryData::default()));
386390
}
387391
Err(err) => {
388-
return Err(err);
392+
return Err(err.into());
389393
}
390394
Ok(_) => {}
391395
}

src/error.rs

Lines changed: 43 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
use core::fmt::Debug;
2+
pub use embedded_io::blocking::ReadExactError;
3+
pub use embedded_io::Error as IoError;
4+
pub use embedded_io::ErrorKind;
5+
pub use embedded_io::Io as IoBase;
6+
7+
#[cfg(feature = "std")]
8+
use crate::io::StdErrWrapper;
9+
110
/// Error enum with all errors that can be returned by functions from this crate
211
///
312
/// Generic parameter `T` is a type of external error returned by the user provided storage
@@ -28,17 +37,41 @@ pub enum Error<T> {
2837
UnsupportedFileNameCharacter,
2938
}
3039

40+
impl<T: Debug> IoError for Error<T> {
41+
fn kind(&self) -> ErrorKind {
42+
ErrorKind::Other
43+
}
44+
}
45+
3146
impl<T: IoError> From<T> for Error<T> {
3247
fn from(error: T) -> Self {
3348
Error::Io(error)
3449
}
3550
}
3651

52+
impl<T> From<ReadExactError<Error<T>>> for Error<T> {
53+
fn from(error: ReadExactError<Error<T>>) -> Self {
54+
match error {
55+
ReadExactError::UnexpectedEof => Self::UnexpectedEof,
56+
ReadExactError::Other(error) => error,
57+
}
58+
}
59+
}
60+
61+
impl<T: IoError> From<ReadExactError<T>> for Error<T> {
62+
fn from(error: ReadExactError<T>) -> Self {
63+
match error {
64+
ReadExactError::UnexpectedEof => Self::UnexpectedEof,
65+
ReadExactError::Other(error) => error.into(),
66+
}
67+
}
68+
}
69+
3770
#[cfg(feature = "std")]
38-
impl From<Error<std::io::Error>> for std::io::Error {
39-
fn from(error: Error<Self>) -> Self {
71+
impl From<Error<StdErrWrapper>> for std::io::Error {
72+
fn from(error: Error<StdErrWrapper>) -> Self {
4073
match error {
41-
Error::Io(io_error) => io_error,
74+
Error::Io(io_error) => io_error.into(),
4275
Error::UnexpectedEof | Error::NotEnoughSpace => Self::new(std::io::ErrorKind::UnexpectedEof, error),
4376
Error::WriteZero => Self::new(std::io::ErrorKind::WriteZero, error),
4477
Error::InvalidInput
@@ -81,57 +114,16 @@ impl<T: std::error::Error + 'static> std::error::Error for Error<T> {
81114
}
82115
}
83116

84-
/// Trait that should be implemented by errors returned from the user supplied storage.
85-
///
86-
/// Implementations for `std::io::Error` and `()` are provided by this crate.
87-
pub trait IoError: core::fmt::Debug {
88-
fn is_interrupted(&self) -> bool;
89-
fn new_unexpected_eof_error() -> Self;
90-
fn new_write_zero_error() -> Self;
91-
}
92-
93-
impl<T: core::fmt::Debug + IoError> IoError for Error<T> {
94-
fn is_interrupted(&self) -> bool {
95-
match self {
96-
Error::<T>::Io(io_error) => io_error.is_interrupted(),
97-
_ => false,
98-
}
99-
}
100-
101-
fn new_unexpected_eof_error() -> Self {
102-
Error::<T>::UnexpectedEof
103-
}
104-
105-
fn new_write_zero_error() -> Self {
106-
Error::<T>::WriteZero
107-
}
108-
}
109-
110-
impl IoError for () {
111-
fn is_interrupted(&self) -> bool {
112-
false
113-
}
114-
115-
fn new_unexpected_eof_error() -> Self {
116-
// empty
117-
}
118-
119-
fn new_write_zero_error() -> Self {
120-
// empty
117+
#[cfg(feature = "std")]
118+
impl core::fmt::Display for StdErrWrapper {
119+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
120+
write!(f, "pls implement")
121121
}
122122
}
123123

124124
#[cfg(feature = "std")]
125-
impl IoError for std::io::Error {
126-
fn is_interrupted(&self) -> bool {
127-
self.kind() == std::io::ErrorKind::Interrupted
128-
}
129-
130-
fn new_unexpected_eof_error() -> Self {
131-
Self::new(std::io::ErrorKind::UnexpectedEof, "failed to fill whole buffer")
132-
}
133-
134-
fn new_write_zero_error() -> Self {
135-
Self::new(std::io::ErrorKind::WriteZero, "failed to write whole buffer")
125+
impl std::error::Error for StdErrWrapper {
126+
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
127+
None
136128
}
137129
}

src/file.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -473,12 +473,12 @@ impl<IO: ReadWriteSeek, TP, OCC> Seek for File<'_, IO, TP, OCC> {
473473
}
474474
}
475475

476-
#[cfg(feature = "std")]
476+
#[cfg(test)]
477477
impl<IO: ReadWriteSeek, TP: TimeProvider, OCC> std::io::Seek for File<'_, IO, TP, OCC>
478478
where
479479
std::io::Error: From<Error<IO::Error>>,
480480
{
481481
fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
482-
Ok(Seek::seek(self, pos.into())?)
482+
Ok(Seek::seek(self, crate::StdSeekPosWrapper::from(pos).into())?)
483483
}
484484
}

src/fs.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#[cfg(all(not(feature = "std"), feature = "alloc"))]
2-
use alloc::string::String;
31
use core::borrow::BorrowMut;
42
use core::cell::{Cell, RefCell};
53
use core::char;
@@ -9,10 +7,13 @@ use core::fmt::Debug;
97
use core::marker::PhantomData;
108
use core::u32;
119

10+
#[cfg(all(not(feature = "std"), feature = "alloc", feature = "lfn"))]
11+
use alloc::string::String;
12+
1213
use crate::boot_sector::{format_boot_sector, BiosParameterBlock, BootSector};
1314
use crate::dir::{Dir, DirRawStream};
1415
use crate::dir_entry::{DirFileEntryData, FileAttributes, SFN_PADDING, SFN_SIZE};
15-
use crate::error::Error;
16+
use crate::error::{Error, ReadExactError};
1617
use crate::file::File;
1718
use crate::io::{self, IoBase, Read, ReadLeExt, Seek, SeekFrom, Write, WriteLeExt};
1819
use crate::table::{
@@ -120,11 +121,11 @@ impl FsStatusFlags {
120121

121122
/// A sum of `Read` and `Seek` traits.
122123
pub trait ReadSeek: Read + Seek {}
123-
impl<T: Read + Seek> ReadSeek for T {}
124+
impl<T: IoBase + Read + Seek> ReadSeek for T {}
124125

125126
/// A sum of `Read`, `Write` and `Seek` traits.
126127
pub trait ReadWriteSeek: Read + Write + Seek {}
127-
impl<T: Read + Write + Seek> ReadWriteSeek for T {}
128+
impl<T: IoBase + Read + Write + Seek> ReadWriteSeek for T {}
128129

129130
#[derive(Clone, Default, Debug)]
130131
struct FsInfoSector {
@@ -138,7 +139,11 @@ impl FsInfoSector {
138139
const STRUC_SIG: u32 = 0x6141_7272;
139140
const TRAIL_SIG: u32 = 0xAA55_0000;
140141

141-
fn deserialize<R: Read>(rdr: &mut R) -> Result<Self, Error<R::Error>> {
142+
fn deserialize<R: Read>(rdr: &mut R) -> Result<Self, Error<R::Error>>
143+
where
144+
Error<<R as IoBase>::Error>: From<ReadExactError<<R as IoBase>::Error>>,
145+
<R as IoBase>::Error: From<ReadExactError<<R as IoBase>::Error>>,
146+
{
142147
let lead_sig = rdr.read_u32_le()?;
143148
if lead_sig != Self::LEAD_SIG {
144149
error!("invalid lead_sig in FsInfo sector: {}", lead_sig);
@@ -362,7 +367,10 @@ impl<IO: Read + Write + Seek, TP, OCC> FileSystem<IO, TP, OCC> {
362367
/// # Panics
363368
///
364369
/// Panics in non-optimized build if `storage` position returned by `seek` is not zero.
365-
pub fn new<T: IntoStorage<IO>>(storage: T, options: FsOptions<TP, OCC>) -> Result<Self, Error<IO::Error>> {
370+
pub fn new<T: IntoStorage<IO>>(storage: T, options: FsOptions<TP, OCC>) -> Result<Self, Error<IO::Error>>
371+
where
372+
IO::Error: From<ReadExactError<IO::Error>>,
373+
{
366374
// Make sure given image is not seeked
367375
let mut disk = storage.into_storage();
368376
trace!("FileSystem::new");

0 commit comments

Comments
 (0)