drivers/standard_library/
loader.rs1use file_system::{FileSystemTraits, Flags, Mode, Open, Path, PathOwned, Time};
2use std::io;
3use std::prelude::rust_2024::*;
4use std::{fs::File, io::Read, path};
5use task::TaskIdentifier;
6use users::{GroupIdentifier, UserIdentifier};
7
8pub type Result<T> = core::result::Result<T, Error>;
9
10#[derive(Debug)]
11pub enum Error {
12 FileSystemError(file_system::Error),
13 IoError(io::Error),
14}
15
16impl From<file_system::Error> for Error {
17 fn from(error: file_system::Error) -> Self {
18 Self::FileSystemError(error)
19 }
20}
21
22impl From<io::Error> for Error {
23 fn from(error: io::Error) -> Self {
24 Self::IoError(error)
25 }
26}
27
28pub struct Loader<'a> {
29 paths: Vec<(path::PathBuf, PathOwned)>,
30 buffers: Vec<(&'a [u8], PathOwned)>,
31}
32
33impl Default for Loader<'_> {
34 fn default() -> Self {
35 Self::new()
36 }
37}
38
39impl<'a> Loader<'a> {
40 pub fn new() -> Self {
41 Self {
42 paths: vec![],
43 buffers: vec![],
44 }
45 }
46
47 pub fn add_file_from_buffer(mut self, buffer: &'a [u8], destination: impl AsRef<Path>) -> Self {
48 self.buffers.push((buffer, destination.as_ref().to_owned()));
49
50 self
51 }
52
53 pub fn add_files_from_buffers(
54 mut self,
55 buffers: impl IntoIterator<Item = (&'a [u8], PathOwned)>,
56 ) -> Self {
57 for (buffer, destination) in buffers {
58 self = self.add_file_from_buffer(buffer, destination);
59 }
60
61 self
62 }
63
64 pub fn add_file(
65 mut self,
66 source: impl AsRef<path::Path>,
67 destination: impl AsRef<Path>,
68 ) -> Self {
69 self.paths
70 .push((source.as_ref().to_owned(), destination.as_ref().to_owned()));
71
72 self
73 }
74
75 pub fn add_files(
76 mut self,
77 files: impl IntoIterator<Item = (path::PathBuf, PathOwned)>,
78 ) -> Self {
79 for file in files {
80 self = self.add_file(file.0, file.1);
81 }
82
83 self
84 }
85
86 pub fn load(&self, file_system: &mut dyn FileSystemTraits) -> Result<()> {
87 for (source_path, destination_path) in &self.paths {
89 let mut source_file = File::open(source_path)?;
91
92 let destination_file = file_system.open(
94 TaskIdentifier::new(0),
95 destination_path,
96 Flags::new(Mode::READ_ONLY, Some(Open::CREATE), None),
97 Time::new(0),
98 UserIdentifier::ROOT,
99 GroupIdentifier::ROOT,
100 )?;
101
102 let mut buffer = [0; 1024];
104 loop {
105 let read = source_file.read(&mut buffer)?;
106
107 if read == 0 {
108 break;
109 }
110
111 file_system.write(destination_file, &buffer[..read], Time::new(0))?;
112 }
113
114 file_system.close(destination_file)?;
115 }
116
117 for (buffer, destination_path) in &self.buffers {
119 let destination_file = file_system.open(
120 TaskIdentifier::new(0),
121 destination_path,
122 Flags::new(Mode::READ_ONLY, Some(Open::CREATE), None),
123 Time::new(0),
124 UserIdentifier::ROOT,
125 GroupIdentifier::ROOT,
126 )?;
127
128 file_system.write(destination_file, buffer, Time::new(0))?;
129 file_system.close(destination_file)?;
130 }
131
132 Ok(())
133 }
134}
135
136#[cfg(test)]
137mod tests {
138 use super::*;
139 use file_system::FileSystemTraits;
140
141 #[test]
142 fn test_loader() {
143 let source_path = "Cargo.toml";
145 let destination_path = "/Cargo.toml";
146
147 let device =
148 file_system::create_device!(file_system::MemoryDevice::<512>::new(1024 * 1024 * 512));
149
150 little_fs::FileSystem::format(device.clone(), 256).unwrap();
151 let mut file_system = little_fs::FileSystem::new(device, 256).unwrap();
152
153 let loader = Loader::new().add_file(source_path, destination_path);
154
155 loader.load(&mut file_system).unwrap();
156
157 let test_file = std::fs::read_to_string(source_path).unwrap();
159
160 let mut buffer = vec![0; test_file.len()];
161
162 let file: file_system::LocalFileIdentifier = file_system
163 .open(
164 TaskIdentifier::new(0),
165 Path::new(destination_path),
166 Flags::new(Mode::READ_ONLY, None, None),
167 Time::new(0),
168 UserIdentifier::ROOT,
169 GroupIdentifier::ROOT,
170 )
171 .unwrap();
172
173 let read = file_system.read(file, &mut buffer, Time::new(0)).unwrap();
174
175 assert_eq!(read, test_file.len());
176 assert_eq!(buffer, test_file.as_bytes());
177 }
178}