Skip to main content

moonlight_core/storage/
writer.rs

1use crate::ComparisonRun;
2use std::{path::Path, sync::Arc};
3use tokio::{
4    fs::{self, File, OpenOptions},
5    io::{AsyncWriteExt, BufWriter},
6    sync::Mutex,
7};
8
9#[derive(Clone)]
10pub struct RunWriter {
11    file: Arc<Mutex<BufWriter<File>>>,
12}
13
14impl RunWriter {
15    pub async fn open(write_path: std::path::PathBuf) -> anyhow::Result<Self> {
16        if let Some(parent) = write_path.parent() {
17            fs::create_dir_all(parent).await?;
18        }
19        let file = OpenOptions::new()
20            .create(true)
21            .append(true)
22            .open(write_path)
23            .await?;
24
25        Ok(Self {
26            file: Arc::new(Mutex::new(BufWriter::new(file))),
27        })
28    }
29
30    pub async fn append(&self, run: &ComparisonRun) -> anyhow::Result<()> {
31        let line = serde_json::to_string(run)?;
32        let mut file = self.file.lock().await;
33        file.write_all(line.as_bytes()).await?;
34        file.write_all(b"\n").await?;
35        Ok(())
36    }
37
38    pub async fn flush(&self) -> anyhow::Result<()> {
39        self.file.lock().await.flush().await?;
40        Ok(())
41    }
42
43    pub async fn reopen(&self, write_path: &Path) -> anyhow::Result<()> {
44        let mut writer = self.file.lock().await;
45        writer.flush().await?;
46        let file = OpenOptions::new()
47            .create(true)
48            .append(true)
49            .open(write_path)
50            .await?;
51        *writer = BufWriter::new(file);
52        Ok(())
53    }
54}