1use anyhow::Result;
2use flexi_logger::writers::LogWriter;
3use std::{
4 fs::{self, File, OpenOptions},
5 io::{Error, ErrorKind},
6 sync::{Arc, Mutex},
7};
8
9pub fn init_logger() -> Result<()> {
10 let dir = directories::BaseDirs::new()
11 .unwrap()
12 .home_dir()
13 .join(".cache")
14 .join("diff-folders");
15 if !dir.exists() {
16 fs::create_dir_all(&dir)?;
17 }
18 let logfile = dir.clone().join("diff-folders.log");
19 if !logfile.exists() {
20 File::create(&logfile)?;
21 }
22 let fd = OpenOptions::new()
23 .write(true)
24 .append(true)
25 .open(logfile)
26 .unwrap();
27 let my_writer = FileWriter {
28 file: Arc::new(Mutex::new(fd)),
29 };
30 flexi_logger::Logger::try_with_str("info")
31 .unwrap()
32 .log_to_writer(Box::new(my_writer))
33 .write_mode(flexi_logger::WriteMode::BufferAndFlush)
34 .start()?;
35 Ok(())
36}
37
38struct FileWriter<F> {
39 file: Arc<Mutex<F>>,
40}
41
42impl<F: std::io::Write + Send + Sync> LogWriter for FileWriter<F> {
43 fn write(
44 &self,
45 now: &mut flexi_logger::DeferredNow,
46 record: &flexi_logger::Record,
47 ) -> std::io::Result<()> {
48 let mut file = self
49 .file
50 .lock()
51 .map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
52 flexi_logger::detailed_format(&mut *file, now, record)
53 }
54
55 fn flush(&self) -> std::io::Result<()> {
56 let mut file = self
57 .file
58 .lock()
59 .map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
60 file.flush()
61 }
62}