#![forbid(unsafe_code)]
#![forbid(missing_docs)]
use crate::errors::ExporterError;
use crate::exporter::Exporter;
use std::fmt;
use std::io::{
self,
Write,
};
use std::path::PathBuf;
use tempfile::NamedTempFile;
use tracing::debug;
#[derive(Clone, Debug)]
pub enum FileExporterOutput {
File(PathBuf),
Stdout,
}
impl fmt::Display for FileExporterOutput {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::File(path) => {
let path = path.to_str().expect("path to str");
write!(f, "{path}")
},
Self::Stdout => write!(f, "-"),
}
}
}
pub struct FileExporter {
dest: FileExporterOutput,
}
impl FileExporter {
pub fn new(output: FileExporterOutput) -> Self {
debug!("New FileExporter output to: {output}");
Self {
dest: output,
}
}
fn write(&self, metrics: &str) -> Result<(), ExporterError> {
debug!("Writing metrics to: {}", self.dest);
match &self.dest {
FileExporterOutput::Stdout => {
io::stdout().write_all(metrics.as_bytes())?;
},
FileExporterOutput::File(path) => {
let parent = path.parent().expect("path to have a parent");
let mut file = NamedTempFile::new_in(parent)?;
file.write_all(metrics.as_bytes())?;
file.persist(path)?;
},
}
Ok(())
}
pub fn export(self) -> Result<(), ExporterError> {
debug!("Exporting metrics to file");
let exporter = Exporter::new();
let metrics = exporter.export()?;
self.write(&metrics)?;
Ok(())
}
}