1#![no_std]
2#![feature(error_in_core)]
3
4extern crate alloc;
5
6use core::fmt::{Debug, Display, Formatter};
7use core::num::NonZeroU32;
8use filesystem::BlockDevice;
9
10mod superblock;
11
12use crate::superblock::Superblock;
13pub use superblock::SuperblockDecodeError;
14
15#[derive(Debug)]
16struct Ext2InodeAddress(NonZeroU32);
17
18impl Ext2InodeAddress {
19 pub fn new(n: u32) -> Option<Self> {
20 Some(Self(NonZeroU32::new(n)?))
21 }
22}
23
24pub struct Ext2Fs<T> {
25 block_device: T,
26 superblock: Superblock,
27}
28
29#[derive(Debug, Copy, Clone, Eq, PartialEq)]
30pub enum Error {
31 InvalidSuperblock(SuperblockDecodeError),
32 UnableToReadSuperblock,
33}
34
35impl Display for Error {
36 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
37 Debug::fmt(&self, f)
38 }
39}
40
41impl core::error::Error for Error {}
42
43impl From<SuperblockDecodeError> for Error {
44 fn from(value: SuperblockDecodeError) -> Self {
45 Self::InvalidSuperblock(value)
46 }
47}
48
49impl<T> Ext2Fs<T>
50where
51 T: BlockDevice,
52{
53 pub fn try_new(block_device: T) -> Result<Self, Error> {
54 let mut superblock_data = [0_u8; 1024];
55 block_device
56 .read_at(1024, &mut superblock_data)
57 .map_err(|_| Error::UnableToReadSuperblock)?;
58
59 let superblock = Superblock::try_from(superblock_data)?;
60
61 Ok(Self {
62 block_device,
63 superblock,
64 })
65 }
66}