[refactor] extract and centralize output writing logic into write_outputs function in output.rs for improved code reuse and maintainability
This commit is contained in:
89
src/output.rs
Normal file
89
src/output.rs
Normal file
@@ -0,0 +1,89 @@
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Context;
|
||||
|
||||
use crate::render_srt;
|
||||
use crate::OutputRoot;
|
||||
|
||||
/// Which formats to write.
|
||||
pub struct OutputFormats {
|
||||
pub json: bool,
|
||||
pub toml: bool,
|
||||
pub srt: bool,
|
||||
}
|
||||
|
||||
impl OutputFormats {
|
||||
pub fn all() -> Self {
|
||||
Self { json: true, toml: true, srt: true }
|
||||
}
|
||||
}
|
||||
|
||||
/// Write outputs for the given base path (without extension).
|
||||
/// This will create files named `base.json`, `base.toml`, and `base.srt`
|
||||
/// according to the `formats` flags. JSON and TOML will always end with a trailing newline.
|
||||
pub fn write_outputs(base: &Path, root: &OutputRoot, formats: &OutputFormats) -> anyhow::Result<()> {
|
||||
if formats.json {
|
||||
let json_path = base.with_extension("json");
|
||||
let mut json_file = File::create(&json_path).with_context(|| {
|
||||
format!("Failed to create output file: {}", json_path.display())
|
||||
})?;
|
||||
serde_json::to_writer_pretty(&mut json_file, root)?;
|
||||
// ensure trailing newline
|
||||
writeln!(&mut json_file)?;
|
||||
}
|
||||
|
||||
if formats.toml {
|
||||
let toml_path = base.with_extension("toml");
|
||||
let toml_str = toml::to_string_pretty(root)?;
|
||||
let mut toml_file = File::create(&toml_path).with_context(|| {
|
||||
format!("Failed to create output file: {}", toml_path.display())
|
||||
})?;
|
||||
toml_file.write_all(toml_str.as_bytes())?;
|
||||
if !toml_str.ends_with('\n') {
|
||||
writeln!(&mut toml_file)?;
|
||||
}
|
||||
}
|
||||
|
||||
if formats.srt {
|
||||
let srt_path = base.with_extension("srt");
|
||||
let srt_str = render_srt(&root.items);
|
||||
let mut srt_file = File::create(&srt_path).with_context(|| {
|
||||
format!("Failed to create output file: {}", srt_path.display())
|
||||
})?;
|
||||
srt_file.write_all(srt_str.as_bytes())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::OutputEntry;
|
||||
|
||||
#[test]
|
||||
fn write_outputs_creates_files_and_newlines() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let base = dir.path().join("test_base");
|
||||
let items = vec![OutputEntry { id: 0, speaker: "Alice".to_string(), start: 0.0, end: 1.23, text: "Hello".to_string() }];
|
||||
let root = OutputRoot { items };
|
||||
|
||||
write_outputs(&base, &root, &OutputFormats::all()).unwrap();
|
||||
|
||||
let json_path = base.with_extension("json");
|
||||
let toml_path = base.with_extension("toml");
|
||||
let srt_path = base.with_extension("srt");
|
||||
|
||||
assert!(json_path.exists(), "json file should exist");
|
||||
assert!(toml_path.exists(), "toml file should exist");
|
||||
assert!(srt_path.exists(), "srt file should exist");
|
||||
|
||||
let json = std::fs::read_to_string(&json_path).unwrap();
|
||||
let toml = std::fs::read_to_string(&toml_path).unwrap();
|
||||
|
||||
assert!(json.ends_with('\n'), "json should end with newline");
|
||||
assert!(toml.ends_with('\n'), "toml should end with newline");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user