exfat/io/
mod.rs

1#[cfg(feature = "std")]
2pub mod std;
3
4#[cfg(all(feature = "async", not(feature = "std")))]
5use alloc::boxed::Box;
6use core::fmt::Debug;
7use core::ops::{Deref, DerefMut};
8
9#[cfg(feature = "async")]
10use async_trait::async_trait;
11
12use crate::error::Error;
13use crate::types::SectorID;
14
15pub const BLOCK_SIZE: usize = 512;
16pub type Block = [u8; BLOCK_SIZE];
17
18pub(crate) fn flatten(sector: &[Block]) -> &[u8] {
19    unsafe { core::slice::from_raw_parts(&sector[0][0], sector.len() * 512) }
20}
21
22#[cfg_attr(feature = "async", async_trait)]
23#[cfg_attr(not(feature = "async"), maybe_async::must_be_sync)]
24pub trait IO {
25    type Block<'a>: Deref<Target = [Block]> + 'a;
26    type Error: Debug;
27
28    /// Default to 9, which means 512B
29    fn set_sector_size_shift(&mut self, shift: u8) -> Result<(), Self::Error>;
30    async fn read<'a>(&mut self, id: SectorID) -> Result<Self::Block<'a>, Self::Error>;
31    /// Caller guarantees bytes.len() <= SECTOR_SIZE - offset
32    async fn write(&mut self, id: SectorID, offset: usize, data: &[u8]) -> Result<(), Self::Error>;
33    async fn flush(&mut self) -> Result<(), Self::Error>;
34}
35
36pub(crate) struct Wrapper<D>(D);
37
38#[cfg_attr(not(feature = "async"), maybe_async::must_be_sync)]
39impl<B: Deref<Target = [Block]>, E, T, D> Wrapper<D>
40where
41    T: IO<Block<'static> = B, Error = E>,
42    D: DerefMut<Target = T>,
43{
44    pub fn set_sector_size_shift(&mut self, shift: u8) -> Result<(), Error<E>> {
45        self.0.set_sector_size_shift(shift).map_err(|e| Error::IO(e))
46    }
47
48    pub async fn read(&mut self, sector: SectorID) -> Result<B, Error<E>> {
49        self.0.read(sector).await.map_err(|e| Error::IO(e))
50    }
51
52    pub async fn write(&mut self, id: SectorID, idx: usize, data: &[u8]) -> Result<(), Error<E>> {
53        let result = self.0.write(id, idx, data).await;
54        result.map_err(|e| Error::IO(e))
55    }
56
57    pub async fn flush(&mut self) -> Result<(), Error<E>> {
58        self.0.flush().await.map_err(|e| Error::IO(e))
59    }
60}
61
62pub(crate) trait Wrap {
63    type Output;
64    fn wrap(self) -> Self::Output;
65}
66
67impl<B: Deref<Target = [Block]>, E, T, D> Wrap for D
68where
69    T: IO<Block<'static> = B, Error = E>,
70    D: DerefMut<Target = T>,
71{
72    type Output = Wrapper<D>;
73    fn wrap(self) -> Self::Output {
74        Wrapper(self)
75    }
76}