use crate::anki::note::{VocabularyNote, create_vocabulary_model};
use crate::duocards::models::VocabularyCard;
use crate::error::{DuoloadError, Result};
use crate::output::{OutputBuilder, OutputDestination};
use genanki_rs::Deck;
use std::collections::HashSet;
pub struct AnkiPackageBuilder {
pub deck: Deck,
pub model: genanki_rs::Model,
existing_words: HashSet<String>,
}
impl AnkiPackageBuilder {
pub fn new(deck_name: &str) -> Self {
let model = create_vocabulary_model();
let deck = Deck::new(
2059400110, deck_name,
"Vocabulary imported from Duocards",
);
Self {
deck,
model,
existing_words: HashSet::new(),
}
}
}
impl OutputBuilder for AnkiPackageBuilder {
fn add_note(&mut self, vocab_card: VocabularyCard) -> Result<bool> {
if self.existing_words.contains(&vocab_card.word) {
return Ok(false); }
let word = vocab_card.word.clone();
let note = VocabularyNote::from(vocab_card).to_anki_note(&self.model)?;
self.deck.add_note(note);
self.existing_words.insert(word);
Ok(true)
}
fn write(&self, dest: OutputDestination<'_>) -> Result<()> {
match dest {
OutputDestination::Writer(_) => {
Err(DuoloadError::AnkiOutputNotSupported)
}
OutputDestination::File(path) => {
let path_str = path
.to_str()
.ok_or_else(|| anyhow::anyhow!("Invalid file path"))?;
self.deck
.write_to_file(path_str)
.map_err(|e| anyhow::anyhow!("Failed to write Anki package: {}", e))?;
Ok(())
}
}
}
}