rlvgl_core/
fs.rs

1//! Asset loading interfaces for filesystem-backed content.
2//!
3//! This module provides traits used by the optional `fs` feature to source
4//! assets such as fonts or images from an underlying filesystem.
5
6use alloc::boxed::Box;
7
8/// Errors that can occur during filesystem operations.
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum FsError {
11    /// Underlying device reported an error.
12    Device,
13    /// Provided path was invalid.
14    InvalidPath,
15    /// File or directory was not found.
16    NoSuchFile,
17}
18
19/// Block device abstraction used by the filesystem layer.
20///
21/// Implementors provide sector-based access to a storage medium.
22pub trait BlockDevice {
23    /// Read blocks starting at `lba` into `buf`.
24    fn read_blocks(&mut self, lba: u64, buf: &mut [u8]) -> Result<(), FsError>;
25
26    /// Write blocks starting at `lba` from `buf`.
27    ///
28    /// Implementations may leave this unimplemented if the device is read-only.
29    fn write_blocks(&mut self, lba: u64, buf: &[u8]) -> Result<(), FsError>;
30
31    /// Return the logical block size in bytes.
32    fn block_size(&self) -> usize;
33
34    /// Return the total number of addressable blocks.
35    fn num_blocks(&self) -> u64;
36
37    /// Flush any buffered data to the underlying device.
38    fn flush(&mut self) -> Result<(), FsError>;
39}
40
41/// Error type returned by asset operations.
42#[derive(Debug, Clone)]
43pub enum AssetError {
44    /// Underlying filesystem error.
45    Fs(FsError),
46}
47
48/// Reader trait for streaming asset data.
49pub trait AssetRead {
50    /// Read data into `out`, returning the number of bytes read.
51    fn read(&mut self, out: &mut [u8]) -> Result<usize, AssetError>;
52
53    /// Total length of the asset in bytes.
54    fn len(&self) -> usize;
55
56    /// Return `true` if the asset has a length of zero bytes.
57    fn is_empty(&self) -> bool;
58
59    /// Seek to an absolute byte position within the asset.
60    fn seek(&mut self, pos: u64) -> Result<u64, AssetError>;
61}
62
63/// Source of assets such as fonts or images.
64pub trait AssetSource {
65    /// Open an asset by logical path, e.g., `"fonts/regular.bin"`.
66    fn open<'a>(&'a self, path: &str) -> Result<Box<dyn AssetRead + 'a>, AssetError>;
67
68    /// Determine whether an asset at `path` exists.
69    fn exists(&self, path: &str) -> bool;
70
71    /// List the contents of `dir`, returning an iterator over asset entries.
72    fn list(&self, dir: &str) -> Result<AssetIter, AssetError>;
73}
74
75/// Iterator over asset entries returned by [`AssetSource::list`].
76pub struct AssetIter;
77
78impl Iterator for AssetIter {
79    type Item = (); // placeholder until fleshed out
80
81    fn next(&mut self) -> Option<Self::Item> {
82        None
83    }
84}
85
86/// Manager that provides convenient typed loading helpers.
87pub struct AssetManager<S: AssetSource> {
88    source: S,
89}
90
91impl<S: AssetSource> AssetManager<S> {
92    /// Create a new [`AssetManager`] from an [`AssetSource`].
93    pub fn new(source: S) -> Self {
94        Self { source }
95    }
96
97    /// Open a raw asset stream at `path`.
98    pub fn open(&self, path: &str) -> Result<Box<dyn AssetRead + '_>, AssetError> {
99        self.source.open(path)
100    }
101}