xref: /Held/src/utils/file.rs (revision f192df4275eb6af11797155b3089f6ea94136533)
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 
19 impl FileManager {
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 
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     // 备份
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 
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 
90         Ok(())
91     }
92 
93     pub fn is_first_open(&mut self) -> bool {
94         self.is_first_open
95     }
96 
97     pub fn delete_files(&mut self) -> io::Result<()> {
98         if !self.name.is_empty() {
99             fs::remove_file(self.name.clone())?;
100         }
101 
102         if self.bak.is_some() {
103             fs::remove_file(format!("{}{}", self.name, BAK_SUFFIX))?;
104         }
105         Ok(())
106     }
107 }
108