1use super::LexiconSource;
2use crate::fetch::sources::parse_from_index_or_lexicon_file;
3use crate::lexicon::LexiconDoc;
4use jacquard_common::IntoStatic;
5use miette::{IntoDiagnostic, Result};
6use std::collections::HashMap;
7use std::path::PathBuf;
8
9#[derive(Debug, Clone)]
10pub struct LocalSource {
11 pub path: PathBuf,
12 pub pattern: Option<String>,
13}
14
15impl LexiconSource for LocalSource {
16 async fn fetch(&self) -> Result<HashMap<String, LexiconDoc<'_>>> {
17 let mut lexicons = HashMap::new();
18
19 // Find all JSON files recursively
20 for entry in walkdir::WalkDir::new(&self.path)
21 .follow_links(true)
22 .into_iter()
23 .filter_map(|e| e.ok())
24 {
25 let path = entry.path();
26
27 if !path.is_file() || path.extension().and_then(|s| s.to_str()) != Some("json") {
28 continue;
29 }
30
31 // Try to parse as lexicon
32 let content = std::fs::read_to_string(path).into_diagnostic()?;
33 match parse_from_index_or_lexicon_file(&content) {
34 Ok((nsid, doc)) => {
35 let doc = doc.into_static();
36 lexicons.insert(nsid, doc);
37 }
38 Err(_) => {
39 // Not a lexicon, skip
40 continue;
41 }
42 }
43 }
44
45 Ok(lexicons)
46 }
47}