moonlight_core/storage/
writer.rs1use 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}