2025-12-27 01:48:17 -03:00
|
|
|
//! Models for malie.io exports
|
|
|
|
|
|
2025-12-27 13:01:53 -03:00
|
|
|
use std::borrow::Cow;
|
2025-12-27 01:48:17 -03:00
|
|
|
use std::collections::HashMap;
|
|
|
|
|
|
2025-12-27 17:12:49 -03:00
|
|
|
use anyhow::Context;
|
2025-12-27 13:01:53 -03:00
|
|
|
use serde::{Deserialize, de};
|
2025-12-27 17:12:49 -03:00
|
|
|
use tracing::warn;
|
2025-12-27 01:48:17 -03:00
|
|
|
|
|
|
|
|
use crate::editions::EditionCode;
|
|
|
|
|
|
2025-12-27 17:12:49 -03:00
|
|
|
pub type RawIndex = HashMap<Lang, HashMap<String, RawEdition>>;
|
2025-12-27 23:11:03 -03:00
|
|
|
pub type Index = Vec<Edition>;
|
2025-12-27 01:48:17 -03:00
|
|
|
|
2025-12-27 23:11:03 -03:00
|
|
|
#[derive(Copy, Clone, Debug, Deserialize, Eq, PartialEq, Hash)]
|
2025-12-27 01:48:17 -03:00
|
|
|
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,
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-27 23:11:03 -03:00
|
|
|
#[derive(Deserialize)]
|
2025-12-27 17:12:49 -03:00
|
|
|
pub struct RawEdition {
|
2025-12-27 01:48:17 -03:00
|
|
|
path: String,
|
2025-12-27 13:01:53 -03:00
|
|
|
#[serde(deserialize_with = "deserialize_edition_code")]
|
2025-12-27 01:48:17 -03:00
|
|
|
abbr: Option<EditionCode>,
|
|
|
|
|
}
|
2025-12-27 13:01:53 -03:00
|
|
|
|
2025-12-28 21:20:16 -03:00
|
|
|
#[derive(Debug, Clone)]
|
2025-12-27 17:12:49 -03:00
|
|
|
pub struct Edition {
|
2025-12-28 21:20:16 -03:00
|
|
|
pub lang: Lang,
|
|
|
|
|
pub path: String,
|
|
|
|
|
pub abbr: EditionCode,
|
2025-12-27 17:12:49 -03:00
|
|
|
}
|
|
|
|
|
|
2025-12-27 13:01:53 -03:00
|
|
|
fn deserialize_edition_code<'de, D>(deserializer: D) -> Result<Option<EditionCode>, D::Error>
|
|
|
|
|
where
|
|
|
|
|
D: de::Deserializer<'de>,
|
|
|
|
|
{
|
|
|
|
|
let buf = Cow::<'de, str>::deserialize(deserializer)?;
|
|
|
|
|
|
|
|
|
|
if buf.is_empty() {
|
|
|
|
|
return Ok(None);
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-27 17:12:49 -03:00
|
|
|
let result = serde_json::from_str::<EditionCode>(&format!("\"{buf}\""))
|
|
|
|
|
.with_context(|| format!("couldn't deserialize edition code {buf}"))
|
|
|
|
|
.inspect_err(|e| warn!("{e}"));
|
|
|
|
|
Ok(result.ok())
|
|
|
|
|
}
|
2025-12-27 13:01:53 -03:00
|
|
|
|
2025-12-27 23:11:03 -03:00
|
|
|
pub fn filter_invalid_editions(index: RawIndex) -> Index {
|
2025-12-27 17:12:49 -03:00
|
|
|
index
|
|
|
|
|
.into_iter()
|
2025-12-28 21:20:16 -03:00
|
|
|
.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,
|
|
|
|
|
})
|
2025-12-27 17:12:49 -03:00
|
|
|
})
|
|
|
|
|
.collect()
|
2025-12-27 13:01:53 -03:00
|
|
|
}
|