forked from rust-osdev/bootloader
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfile_data_source.rs
58 lines (53 loc) · 1.78 KB
/
file_data_source.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use alloc::vec::Vec;
use anyhow::Context;
use core::fmt::{Debug, Formatter};
use std::io::Cursor;
use std::path::PathBuf;
use std::{fs, io};
#[derive(Clone)]
/// Defines a data source, either a source `std::path::PathBuf`, or a vector of bytes.
pub enum FileDataSource {
File(PathBuf),
Data(Vec<u8>),
}
impl Debug for FileDataSource {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
match self {
FileDataSource::File(file) => {
f.write_fmt(format_args!("data source: File {}", file.display()))
}
FileDataSource::Data(d) => {
f.write_fmt(format_args!("data source: {} raw bytes ", d.len()))
}
}
}
}
impl FileDataSource {
/// Get the length of the inner data source
pub fn len(&self) -> anyhow::Result<u64> {
Ok(match self {
FileDataSource::File(path) => fs::metadata(path)
.with_context(|| format!("failed to read metadata of file `{}`", path.display()))?
.len(),
FileDataSource::Data(v) => v.len() as u64,
})
}
/// Copy this data source to the specified target that implements io::Write
pub fn copy_to(&self, target: &mut dyn io::Write) -> anyhow::Result<()> {
match self {
FileDataSource::File(file_path) => {
io::copy(
&mut fs::File::open(file_path).with_context(|| {
format!("failed to open `{}` for copying", file_path.display())
})?,
target,
)?;
}
FileDataSource::Data(contents) => {
let mut cursor = Cursor::new(contents);
io::copy(&mut cursor, target)?;
}
};
Ok(())
}
}