gistools/parsers/write/
file.rs

1use super::Writer;
2use alloc::{vec, vec::Vec};
3use std::{
4    fs::{File, OpenOptions},
5    io::{Read, Seek, SeekFrom, Write},
6    path::{Path, PathBuf},
7};
8
9/// A writer that operates on the filesystem
10#[derive(Debug)]
11pub struct FileWriter {
12    path: PathBuf,
13    file: File,
14}
15impl FileWriter {
16    /// Create a new FileWriter, truncating the file if it exists
17    pub fn new<P: AsRef<Path>>(path: P) -> std::io::Result<Self> {
18        let path_buf = path.as_ref().to_path_buf();
19        let file =
20            OpenOptions::new().read(true).write(true).create(true).truncate(true).open(path)?;
21        Ok(Self { path: path_buf, file })
22    }
23
24    /// Get the length of the file
25    pub fn len(&self) -> u64 {
26        self.file.metadata().unwrap().len()
27    }
28
29    /// Check if the file is empty
30    pub fn is_empty(&self) -> bool {
31        self.len() == 0
32    }
33}
34impl Clone for FileWriter {
35    fn clone(&self) -> Self {
36        let file = OpenOptions::new()
37            .read(true)
38            .write(true)
39            .open(&self.path)
40            .expect("Failed to reopen file");
41        Self { path: self.path.clone(), file }
42    }
43}
44impl Writer for FileWriter {
45    fn offset(&mut self) -> u64 {
46        self.file.stream_position().expect("Seek failed")
47    }
48
49    fn write(&mut self, data: &[u8], offset: u64) {
50        self.file.seek(SeekFrom::Start(offset)).expect("Seek failed");
51        self.file.write_all(data).expect("Write failed");
52    }
53
54    fn append(&mut self, data: &[u8]) {
55        self.file.seek(SeekFrom::End(0)).expect("Seek failed");
56        self.file.write_all(data).expect("Write failed");
57    }
58
59    fn append_string(&mut self, string: &str) {
60        self.append(string.as_bytes());
61    }
62
63    fn take(&mut self) -> Vec<u8> {
64        self.file.seek(SeekFrom::Start(0)).expect("Seek failed");
65        let mut buffer = Vec::new();
66        self.file.read_to_end(&mut buffer).expect("Read failed");
67        buffer
68    }
69
70    fn slice(&mut self, start: u64, end: u64) -> Vec<u8> {
71        let len = end - start;
72        let mut buffer = vec![0u8; len as usize];
73        self.file.seek(SeekFrom::Start(start)).expect("Seek failed");
74        self.file.read_exact(&mut buffer).expect("Read failed");
75        buffer
76    }
77
78    fn flush(&mut self) {
79        self.file.flush().expect("Flush failed");
80    }
81}