A better Rust ATProto crate
at lifetimes 1.7 kB view raw
1use super::LexiconSource; 2use crate::lexicon::LexiconDoc; 3use jacquard_common::types::value::Data; 4use jacquard_common::IntoStatic; 5use miette::{IntoDiagnostic, Result}; 6use serde::Deserialize; 7use std::collections::HashMap; 8use std::path::PathBuf; 9 10#[derive(Debug, Clone)] 11pub struct JsonFileSource { 12 pub path: PathBuf, 13} 14 15#[derive(Deserialize)] 16struct RecordsFile<'a> { 17 #[serde(borrow)] 18 records: Vec<Data<'a>>, 19} 20 21impl LexiconSource for JsonFileSource { 22 async fn fetch(&self) -> Result<HashMap<String, LexiconDoc<'_>>> { 23 let content = std::fs::read_to_string(&self.path).into_diagnostic()?; 24 let file: RecordsFile = serde_json::from_str(&content).into_diagnostic()?; 25 26 let mut lexicons = HashMap::new(); 27 28 for record_data in file.records { 29 if let Some(doc) = Self::parse_lexicon_record(&record_data) { 30 let nsid = doc.id.to_string(); 31 lexicons.insert(nsid, doc); 32 } 33 } 34 35 Ok(lexicons) 36 } 37} 38 39impl JsonFileSource { 40 fn parse_lexicon_record(record_data: &Data<'_>) -> Option<LexiconDoc<'static>> { 41 let value = match record_data { 42 Data::Object(map) => map.0.get("value")?, 43 _ => return None, 44 }; 45 46 match serde_json::to_string(value) { 47 Ok(json) => match serde_json::from_str::<LexiconDoc>(&json) { 48 Ok(doc) => Some(doc.into_static()), 49 Err(e) => { 50 eprintln!("Warning: Failed to parse lexicon from record: {}", e); 51 None 52 } 53 }, 54 Err(e) => { 55 eprintln!("Warning: Failed to serialize record value: {}", e); 56 None 57 } 58 } 59 } 60}