//! Models for malie.io exports use std::borrow::Cow; use std::collections::HashMap; use anyhow::Context; use serde::{Deserialize, de}; use tracing::warn; use crate::editions::EditionCode; pub type RawIndex = HashMap>; pub type Index = Vec; #[derive(Copy, Clone, Debug, Deserialize, Eq, PartialEq, Hash)] pub enum Lang { #[serde(rename = "de-DE")] De, #[serde(rename = "en-US")] En, #[serde(rename = "es-ES")] Es, #[serde(rename = "es-419")] EsLa, #[serde(rename = "it-IT")] It, #[serde(rename = "fr-FR")] Fr, #[serde(rename = "pt-BR")] Pt, } #[derive(Deserialize)] pub struct RawEdition { path: String, #[serde(deserialize_with = "deserialize_edition_code")] abbr: Option, } #[derive(Debug, Clone)] pub struct Edition { pub lang: Lang, pub path: String, pub abbr: EditionCode, } fn deserialize_edition_code<'de, D>(deserializer: D) -> Result, D::Error> where D: de::Deserializer<'de>, { let buf = Cow::<'de, str>::deserialize(deserializer)?; if buf.is_empty() { return Ok(None); } let result = serde_json::from_str::(&format!("\"{buf}\"")) .with_context(|| format!("couldn't deserialize edition code {buf}")) .inspect_err(|e| warn!("{e}")); Ok(result.ok()) } pub fn filter_invalid_editions(index: RawIndex) -> Index { index .into_iter() .flat_map(|(lang, v)| { v.into_values().filter_map(move |e| match e.abbr { Some(abbr) => Some(Edition { path: e.path, abbr, lang, }), None => None, }) }) .collect() }