Skip to content
This repository has been archived by the owner on Mar 15, 2024. It is now read-only.

Avoid multiple error types in IO traits #13

Merged
merged 1 commit into from
Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions src/fs/ext2/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::dev::Device;
use crate::error::Error;
use crate::fs::error::FsError;
use crate::fs::ext2::block_group::BlockGroupDescriptor;
use crate::io::{Read, Seek, SeekFrom, Write};
use crate::io::{Base, Read, Seek, SeekFrom, Write};

/// An ext2 block.
#[derive(Clone)]
Expand Down Expand Up @@ -196,9 +196,11 @@ impl<Dev: Device<u8, Ext2Error>> From<Block<Dev>> for u32 {
}
}

impl<Dev: Device<u8, Ext2Error>> Read for Block<Dev> {
impl<Dev: Device<u8, Ext2Error>> Base for Block<Dev> {
type Error = Ext2Error;
}

impl<Dev: Device<u8, Ext2Error>> Read for Block<Dev> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error<Ext2Error>> {
let fs = self.filesystem.borrow();
Expand All @@ -217,8 +219,6 @@ impl<Dev: Device<u8, Ext2Error>> Read for Block<Dev> {
}

impl<Dev: Device<u8, Ext2Error>> Write for Block<Dev> {
type Error = Ext2Error;

#[inline]
fn write(&mut self, buf: &[u8]) -> Result<usize, Error<Ext2Error>> {
let fs = self.filesystem.borrow();
Expand All @@ -244,8 +244,6 @@ impl<Dev: Device<u8, Ext2Error>> Write for Block<Dev> {
}

impl<Dev: Device<u8, Ext2Error>> Seek for Block<Dev> {
type Error = Ext2Error;

#[inline]
fn seek(&mut self, pos: SeekFrom) -> Result<u64, Error<Ext2Error>> {
let fs = self.filesystem.borrow();
Expand Down
18 changes: 7 additions & 11 deletions src/fs/ext2/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::file::{self, DirectoryEntry, Stat};
use crate::fs::error::FsError;
use crate::fs::ext2::block::Block;
use crate::fs::PATH_MAX;
use crate::io::{Read, Seek, SeekFrom, Write};
use crate::io::{Base, Read, Seek, SeekFrom, Write};
use crate::types::{Blkcnt, Blksize, Dev, Gid, Ino, Mode, Nlink, Off, Time, Timespec, Uid};

/// Limit in bytes for the length of a pointed path of a symbolic link to be store in an inode and not in a separate data block.
Expand Down Expand Up @@ -147,9 +147,11 @@ pub struct Regular<D: Device<u8, Ext2Error>> {
file: File<D>,
}

impl<D: Device<u8, Ext2Error>> Read for File<D> {
impl<D: Device<u8, Ext2Error>> Base for File<D> {
type Error = Ext2Error;
}

impl<D: Device<u8, Ext2Error>> Read for File<D> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error<Self::Error>> {
let filesystem = self.filesystem.borrow();
Expand Down Expand Up @@ -186,8 +188,6 @@ struct BlockWithState {
}

impl<D: Device<u8, Ext2Error>> Write for File<D> {
type Error = Ext2Error;

#[inline]
#[allow(clippy::too_many_lines)]
#[allow(clippy::cognitive_complexity)] // TODO: make this understandable for a human
Expand Down Expand Up @@ -673,8 +673,6 @@ impl<D: Device<u8, Ext2Error>> Write for File<D> {
}

impl<D: Device<u8, Ext2Error>> Seek for File<D> {
type Error = Ext2Error;

#[inline]
fn seek(&mut self, pos: SeekFrom) -> Result<u64, Error<Ext2Error>> {
// SAFETY: it is safe to assume that the file length is smaller than 2^63 bytes long
Expand Down Expand Up @@ -756,18 +754,18 @@ impl<D: Device<u8, Ext2Error>> file::File for Regular<D> {
}
}

impl<D: Device<u8, Ext2Error>> Read for Regular<D> {
impl<D: Device<u8, Ext2Error>> Base for Regular<D> {
type Error = Ext2Error;
}

impl<D: Device<u8, Ext2Error>> Read for Regular<D> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error<Ext2Error>> {
self.file.read(buf)
}
}

impl<D: Device<u8, Ext2Error>> Write for Regular<D> {
type Error = Ext2Error;

#[inline]
fn write(&mut self, buf: &[u8]) -> Result<usize, Error<Ext2Error>> {
self.file.write(buf)
Expand All @@ -780,8 +778,6 @@ impl<D: Device<u8, Ext2Error>> Write for Regular<D> {
}

impl<D: Device<u8, Ext2Error>> Seek for Regular<D> {
type Error = Ext2Error;

#[inline]
fn seek(&mut self, pos: SeekFrom) -> Result<u64, Error<Ext2Error>> {
self.file.seek(pos)
Expand Down
56 changes: 9 additions & 47 deletions src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

use crate::error::Error;

/// Allows for reading bytes from a source.
///
/// See [`std::io::Read`] for more information: this trait is a `no_std` based variant.
pub trait Read {
/// Base I/O trait that must be implemented for all types implementing [`Read`], [`Write`] or [`Seek`].
pub trait Base {
/// Error type corresponding to the [`FileSystem`](crate::fs::FileSystem) implemented.
type Error: core::error::Error;
}

/// Allows for reading bytes from a source.
///
/// See [`std::io::Read`] for more information: this trait is a `no_std` based variant.
pub trait Read: Base {
/// Pull some bytes from this source into the specified buffer, returning how many bytes were read.
///
/// If the returned number is 0, the reader is considered as ended.
Expand All @@ -23,23 +26,10 @@ pub trait Read {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error<Self::Error>>;
}

#[cfg(feature = "std")]
impl<S: std::io::Read> Read for S {
type Error = std::io::Error;

#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error<Self::Error>> {
std::io::Read::read(self, buf).map_err(Error::IO)
}
}

/// Allows for writing bytes to a destination.
///
/// See [`std::io::Write`] for more information: this trait is a `no_std` based variant.
pub trait Write {
/// Error type corresponding to the [`FileSystem`](crate::fs::FileSystem) implemented.
type Error: core::error::Error;

pub trait Write: Base {
/// Write a buffer into this writer, returning how many bytes were written.
///
/// If the returned number is 0, either the writer is ended or cannot add any more bytes at its end.
Expand All @@ -63,21 +53,6 @@ pub trait Write {
fn flush(&mut self) -> Result<(), Error<Self::Error>>;
}

#[cfg(feature = "std")]
impl<S: std::io::Write> Write for S {
type Error = std::io::Error;

#[inline]
fn write(&mut self, buf: &[u8]) -> Result<usize, Error<Self::Error>> {
std::io::Write::write(self, buf).map_err(Error::IO)
}

#[inline]
fn flush(&mut self) -> Result<(), Error<Self::Error>> {
std::io::Write::flush(self).map_err(Error::IO)
}
}

/// Enumeration of possible methods to seek within an I/O object.
///
/// See [`std::io::SeekFrom`] for more information.
Expand Down Expand Up @@ -124,10 +99,7 @@ impl From<SeekFrom> for std::io::SeekFrom {
/// Provides a cursor which can be moved within a stream of bytes.
///
/// See [`std::io::Seek`] for more information: this trait is a `no_std` based variant.
pub trait Seek {
/// Error type corresponding to the [`FileSystem`](crate::fs::FileSystem) implemented.
type Error: core::error::Error;

pub trait Seek: Base {
/// Seek to an offset, in bytes, in a stream.
///
/// See [`seek`](https://docs.rs/no_std_io/latest/no_std_io/io/trait.Seek.html#tymethod.seek) for more information.
Expand All @@ -137,13 +109,3 @@ pub trait Seek {
/// Returns an [`DevError`](crate::dev::error::DevError) if the device on which the directory is located could not be read.
fn seek(&mut self, pos: SeekFrom) -> Result<u64, Error<Self::Error>>;
}

#[cfg(feature = "std")]
impl<S: std::io::Seek> Seek for S {
type Error = std::io::Error;

#[inline]
fn seek(&mut self, pos: SeekFrom) -> Result<u64, Error<Self::Error>> {
std::io::Seek::seek(self, pos.into()).map_err(Error::IO)
}
}