You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

45 lines
1.4 KiB

use crate::application::ports::DictSource;
use crate::core::entities::{DictEntry, DictEntryId};
use serde::Deserialize;
use std::fs::File;
use std::io::BufReader;
use std::path::Path;
// The "Wire Format".
// It exists ONLY here to map external JSON names to internal Entity names.
#[derive(Deserialize)]
struct JsonEntry {
id: u32,
word: String, // "word" in JSON, "text" in Entity
// If JSON has extra fields we don't care about, Serde ignores them.
}
pub struct JsonFileDictSource {
// Helper iterator from Serde
iter:
serde_json::StreamDeserializer<'static, serde_json::de::IoRead<BufReader<File>>, JsonEntry>,
}
impl JsonFileDictSource {
pub fn new<P: AsRef<Path>>(path: P) -> anyhow::Result<Self> {
let file = File::open(path)?;
let reader = BufReader::new(file);
let iter = serde_json::Deserializer::from_reader(reader).into_iter::<JsonEntry>();
Ok(Self { iter })
}
}
impl DictSource for JsonFileDictSource {
fn next_entry(&mut self) -> Option<Result<DictEntry, anyhow::Error>> {
self.iter.next().map(|res| {
match res {
Ok(json) => {
// MAPPING HAPPENS HERE.
// This is type-safe. If DictEntry::new signature changes, this breaks.
Ok(DictEntry::new(json.id as DictEntryId, json.word))
}
Err(e) => Err(anyhow::Error::new(e)),
}
})
}
}