use crate::duocards::models::VocabularyCard;
use crate::error::Result;
use crate::output::{OutputBuilder, OutputDestination};
use serde_json;
use std::collections::HashSet;
use std::io::Write;
use std::time::Instant;
pub struct JsonOutputBuilder {
cards: Vec<VocabularyCard>,
existing_words: HashSet<String>,
start_time: Instant,
}
impl Default for JsonOutputBuilder {
fn default() -> Self {
Self::new()
}
}
impl JsonOutputBuilder {
pub fn new() -> Self {
Self {
cards: Vec::new(),
existing_words: HashSet::new(),
start_time: Instant::now(),
}
}
}
impl OutputBuilder for JsonOutputBuilder {
fn add_note(&mut self, card: VocabularyCard) -> Result<bool> {
if self.existing_words.contains(&card.word) {
return Ok(false); }
let word = card.word.clone();
self.cards.push(card);
self.existing_words.insert(word);
Ok(true)
}
fn write(&self, dest: OutputDestination<'_>) -> Result<()> {
match dest {
OutputDestination::Writer(writer) => {
serde_json::to_writer_pretty(writer, &self.cards)
.map_err(|e| anyhow::anyhow!("Failed to write JSON: {}", e))?;
}
OutputDestination::File(path) => {
let file = std::fs::File::create(path)?;
let mut writer = std::io::BufWriter::new(file);
serde_json::to_writer_pretty(&mut writer, &self.cards)
.map_err(|e| anyhow::anyhow!("Failed to write JSON: {}", e))?;
writer.flush()?;
}
}
println!(
"JSON written successfully at {:?}",
self.start_time.elapsed()
);
Ok(())
}
}