pidcat/sink/
file.rs

1use crate::log::Log;
2use crate::sink::Sink;
3use anyhow::Result;
4use async_trait::async_trait;
5use std::path::PathBuf;
6use tokio::fs::{File, OpenOptions};
7use tokio::io::AsyncWriteExt;
8use tokio::task;
9
10pub(crate) struct FileSink {
11    file: File,
12}
13
14impl FileSink {
15    #[allow(dead_code)]
16    pub(crate) async fn new(file: PathBuf) -> Result<Self> {
17        let f = OpenOptions::new()
18            .write(true)
19            .truncate(true)
20            .create(true)
21            .open(file)
22            .await?;
23        Ok(Self { file: f })
24    }
25}
26
27#[async_trait]
28impl Sink for FileSink {
29    async fn write(&self, log: Log) {
30        let s = format!(
31            "{} {:11} {:>5} {:<5} {} {}   {}\n",
32            log.date, log.time, log.pid, log.tid, log.level, log.tag, log.message
33        );
34        let file = self.file.try_clone().await;
35        task::spawn(async move {
36            if let Ok(mut file) = file {
37                if let Ok(_) = file.write_all(s.as_bytes()).await {}
38            }
39        });
40    }
41}