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

Commit

Permalink
* refactor(error): begin use of anyhow
Browse files Browse the repository at this point in the history
* feat(dev): begin of devices implementations
  • Loading branch information
RatCornu committed Oct 25, 2023
1 parent e78deea commit 529f58b
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 50 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ name = "efs"
path = "src/lib.rs"

[dependencies]
anyhow = { version = "1", default-features = false }
derive_more = "0.99"
itertools = { version = "0.11", default-features = false, features = ["use_alloc"] }
no_std_io = "0.6.0"
Expand Down
3 changes: 3 additions & 0 deletions src/dev/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
//! Everything related to the devices

pub mod sector;
124 changes: 124 additions & 0 deletions src/dev/sector.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
//! General description of sectors.

use core::fmt::{self, Debug};
use core::marker::PhantomData;

use anyhow::{anyhow, Error, Result};

/// General interface for sector sizes that are device-dependant.
pub trait Size: Clone + Copy + PartialEq + Eq {
/// Logarithm in base 2 of the sector size.
const LOG_SIZE: u32;

/// Size of a sector.
const SIZE: u32 = 1 << Self::LOG_SIZE;

/// Offset mask of the sector size.
const OFFSET_MASK: u32 = Self::SIZE - 1;
}

/// Size sector of 512 bytes.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Size512;

impl Size for Size512 {
const LOG_SIZE: u32 = 9;
}

/// Size sector of 1024 bytes.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Size1024;

impl Size for Size1024 {
const LOG_SIZE: u32 = 10;
}

/// Size sector of 2048 bytes.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Size2048;

impl Size for Size2048 {
const LOG_SIZE: u32 = 11;
}

/// Size sector of 4096 bytes.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Size4096;

impl Size for Size4096 {
const LOG_SIZE: u32 = 12;
}

/// Address of a physical sector
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Address<S: Size> {
/// Sector in which the address is located.
sector: u32,

/// Offset of this address in the sector.
offset: u32,

/// Phantom data to store the sector size.
_phantom: PhantomData<S>,
}

impl<S: Size> Debug for Address<S> {
#[inline]
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_struct("Address")
.field("sector", &self.sector)
.field("offset", &self.offset)
.finish()
}
}

impl<S: Size> Address<S> {
/// Returns a new [`Address`] with an offset such that `0 <= offset < S::SIZE`
///
/// # Errors
///
/// Returns an [`Error`](anyhow::Error)
#[inline]
pub fn new(sector: u32, offset: i32) -> Result<Self> {
let real_sector = TryInto::<u32>::try_into(TryInto::<i32>::try_into(sector).map_err(Error::msg)? + (offset >> S::LOG_SIZE))
.map_err(Error::msg)?;
let real_offset = offset.unsigned_abs() & S::OFFSET_MASK;
if real_offset >= S::SIZE {
Err(anyhow!("Offset Out of Bounds: the offset {real_offset} is greater than the sector size {}", S::SIZE))
} else {
Ok(Self {
sector: real_sector,
offset: real_offset,
_phantom: PhantomData,
})
}
}

/// Returns the sector containing this address.
#[inline]
#[must_use]
pub const fn sector(&self) -> u32 {
self.sector
}

/// Returns the offset of this address in its sector.
#[inline]
#[must_use]
pub const fn offset(&self) -> u32 {
self.offset
}
}

#[cfg(test)]
mod test {
use super::{Size, Size1024, Size2048, Size4096, Size512};

#[test]
fn sizes() {
assert_eq!(Size512::SIZE, 512);
assert_eq!(Size1024::SIZE, 1024);
assert_eq!(Size2048::SIZE, 2048);
assert_eq!(Size4096::SIZE, 4096);
}
}
36 changes: 0 additions & 36 deletions src/error.rs

This file was deleted.

23 changes: 23 additions & 0 deletions src/ext2/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//! Errors related to Ext2 manipulation.

use core::error;
use core::fmt::{self, Display};

/// Enumeration of possible errors encountered with Ext2's manipulation.
#[allow(clippy::module_name_repetitions)]
#[derive(Debug, PartialEq, Eq)]
pub enum Ext2Error {
/// A bad magic number has been found during the superblock parsing.
BadMagic(u16),
}

impl Display for Ext2Error {
#[inline]
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::BadMagic(magic) => write!(formatter, "Bad Magic: {magic} has been found while TODO was expected"),
}
}
}

impl error::Error for Ext2Error {}
5 changes: 5 additions & 0 deletions src/ext2/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//! Implementation of the Second Extended Filesystem (ext2fs) filesystem.
//!
//! See [its Wikipedia page](https://fr.wikipedia.org/wiki/Ext2) or [its OSDev page](https://wiki.osdev.org/Ext2) for more informations.

pub mod error;
26 changes: 13 additions & 13 deletions src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ use alloc::boxed::Box;
use alloc::string::{String, ToString};
use alloc::vec;
use alloc::vec::Vec;
use core::error;
use core::fmt::{self, Display};
use core::str::FromStr;

use anyhow::{anyhow, Error, Result};
use itertools::{Itertools, Position};
use no_std_io::io;

use crate::error::Error;
use crate::file::{Directory, Type};
use crate::path::{Component, Path};

Expand Down Expand Up @@ -51,6 +52,8 @@ impl Display for FsError {
}
}

impl error::Error for FsError {}

/// A filesystem
pub trait FileSystem {
/// Returns the root directory of the filesystem.
Expand Down Expand Up @@ -82,7 +85,7 @@ pub trait FileSystem {
///
/// Returns an [`NoEnt`](FsError::NoEnt) error if an encountered symlink points to a non-existing file.
#[inline]
fn pathname_resolution(&self, path: &Path, current_dir: Box<dyn Directory>, symlink_resolution: bool) -> Result<Type, Error>
fn pathname_resolution(&self, path: &Path, current_dir: Box<dyn Directory>, symlink_resolution: bool) -> Result<Type>
where
Self: Sized,
{
Expand All @@ -95,11 +98,11 @@ pub trait FileSystem {
mut current_dir: Box<dyn Directory>,
symlink_resolution: bool,
mut visited_symlinks: Vec<String>,
) -> Result<Type, Error> {
) -> Result<Type> {
let canonical_path = path.canonical();

if canonical_path.len() > PATH_MAX {
return Err(Error::Fs(FsError::NameTooLong(canonical_path.to_string())));
return Err(anyhow!(FsError::NameTooLong(canonical_path.to_string())));
}

let trailing_blackslash = canonical_path.as_unix_str().has_trailing_backslash();
Expand Down Expand Up @@ -131,7 +134,7 @@ pub trait FileSystem {
let children = current_dir.entries();
let Some(entry) = children.into_iter().find(|entry| entry.filename == filename).map(|entry| entry.file)
else {
return Err(Error::IO(io::ErrorKind::NotFound));
return Err(anyhow!(io::Error::from(io::ErrorKind::NotFound)));
};

#[allow(clippy::wildcard_enum_match_arm)]
Expand Down Expand Up @@ -159,7 +162,7 @@ pub trait FileSystem {
{
let pointed_file = symlink.pointed_file().to_owned();
if pointed_file.is_empty() {
return Err(Error::Fs(FsError::NoEnt(filename.to_string())));
return Err(anyhow!(FsError::NoEnt(filename.to_string())));
};

symlink_encountered = Some(pointed_file);
Expand All @@ -169,7 +172,7 @@ pub trait FileSystem {
return if (pos == Position::Last || pos == Position::Only) && !trailing_blackslash {
Ok(entry)
} else {
Err(Error::Fs(FsError::NotDir(filename.to_string())))
Err(anyhow!(FsError::NotDir(filename.to_string())))
};
},
}
Expand All @@ -181,22 +184,19 @@ pub trait FileSystem {
None => Ok(Type::Directory(current_dir)),
Some(pointed_file) => {
if visited_symlinks.contains(&pointed_file) {
return Err(Error::Fs(FsError::Loop(pointed_file)));
return Err(anyhow!(FsError::Loop(pointed_file)));
}
visited_symlinks.push(pointed_file.clone());

let pointed_path = match Path::from_str(&pointed_file) {
Ok(path) => path,
Err(path_error) => return Err(Error::Path(path_error)),
};
let pointed_path = Path::from_str(&pointed_file).map_err(Error::msg)?;

let complete_path = match TryInto::<Path>::try_into(&components) {
Ok(remaining_path) => pointed_path.join(&remaining_path),
Err(_) => pointed_path,
};

if complete_path.len() >= PATH_MAX {
Err(Error::Fs(FsError::NameTooLong(complete_path.to_string())))
Err(anyhow!(FsError::NameTooLong(complete_path.to_string())))
} else {
inner_resolution(fs, &complete_path, current_dir, symlink_resolution, visited_symlinks)
}
Expand Down
5 changes: 4 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,11 @@
extern crate alloc;
extern crate core;

pub mod error;
pub mod file;
pub mod fs;
pub mod path;
pub mod types;

pub mod dev;

pub mod ext2;

0 comments on commit 529f58b

Please sign in to comment.