xref: /Held/src/utils/file.rs (revision 7d5806d5b291a1c82166840048ed0c0986d637ec)
1 use std::{
2     fs::{self, File},
3     io::{self, Read, Seek, Write},
4 };
5 
6 use super::buffer::EditBuffer;
7 
8 use std::path::PathBuf;
9 
10 pub const BAK_SUFFIX: &'static str = ".heldbak";
11 
12 pub struct FileManager {
13     name: String,
14     file: File,
15     is_first_open: bool,
16     bak: Option<File>,
17 }
18 #[allow(unused)]
19 impl FileManager {
new(file_path: String) -> io::Result<Self>20     pub fn new(file_path: String) -> io::Result<Self> {
21         let ifo_flag = !PathBuf::from(file_path.clone()).exists();
22 
23         let file = File::options()
24             .write(true)
25             .read(true)
26             .create(true)
27             .open(file_path.clone())?;
28 
29         Ok(Self {
30             file,
31             is_first_open: ifo_flag,
32             name: file_path,
33             bak: None,
34         })
35     }
36 
init(&mut self, bak: bool) -> io::Result<EditBuffer>37     pub fn init(&mut self, bak: bool) -> io::Result<EditBuffer> {
38         let mut buf = Vec::new();
39         // 是否备份
40         if bak {
41             self.do_bak(&mut buf)?;
42         } else {
43             self.file.read_to_end(&mut buf)?;
44         }
45 
46         Ok(EditBuffer::new(buf))
47     }
48 
49     // 备份
do_bak(&mut self, buf: &mut Vec<u8>) -> io::Result<()>50     fn do_bak(&mut self, buf: &mut Vec<u8>) -> io::Result<()> {
51         let mut bak = File::options()
52             .write(true)
53             .read(true)
54             .create(true)
55             .open(format!("{}{}", self.name, BAK_SUFFIX))?;
56 
57         bak.set_len(0)?;
58 
59         self.file.read_to_end(buf)?;
60         bak.write_all(&buf)?;
61 
62         self.file.seek(io::SeekFrom::Start(0))?;
63 
64         if self.bak.is_some() {
65             error!("The backup already exists. The operation may cause data loss.");
66         }
67 
68         self.bak = Some(bak);
69 
70         Ok(())
71     }
72 
store(&mut self, buf: &EditBuffer) -> io::Result<()>73     pub fn store(&mut self, buf: &EditBuffer) -> io::Result<()> {
74         let data = buf.all_buffer();
75 
76         self.file.set_len(0)?;
77 
78         for (idx, line) in data.iter().enumerate() {
79             if idx == data.len() - 1 {
80                 self.file.write(&line[..line.len()])?;
81             } else {
82                 self.file.write(&line)?;
83             }
84         }
85 
86         if self.bak.is_some() {
87             fs::remove_file(format!("{}{}", self.name, BAK_SUFFIX))?;
88         }
89         self.is_first_open = false;
90 
91         Ok(())
92     }
93 
is_first_open(&mut self) -> bool94     pub fn is_first_open(&mut self) -> bool {
95         self.is_first_open
96     }
97 
delete_files(&mut self) -> io::Result<()>98     pub fn delete_files(&mut self) -> io::Result<()> {
99         if !self.name.is_empty() {
100             fs::remove_file(self.name.clone())?;
101         }
102 
103         if self.bak.is_some() {
104             fs::remove_file(format!("{}{}", self.name, BAK_SUFFIX))?;
105         }
106         Ok(())
107     }
108 
get_heldbak(&mut self) -> Option<File>109     pub fn get_heldbak(&mut self) -> Option<File> {
110         match self.bak.take() {
111             Some(file) => Some(file),
112             None => None,
113         }
114     }
115 
restore(&mut self) -> io::Result<()>116     pub fn restore(&mut self) -> io::Result<()> {
117         if self.bak.is_some() {
118             let bak_file = self.bak.as_mut().unwrap();
119             bak_file.seek(io::SeekFrom::Start(0)).unwrap();
120 
121             let mut buf = Vec::new();
122             bak_file.read_to_end(&mut buf).unwrap();
123 
124             self.file.write_all(&buf)?;
125 
126             self.file.seek(io::SeekFrom::Start(0))?;
127             bak_file.seek(io::SeekFrom::Start(0))?;
128         }
129         Ok(())
130     }
131 }
132