FeDirect/src/known_software.rs

70 lines
1.8 KiB
Rust
Raw Normal View History

2025-01-12 04:47:05 +01:00
use rocket::request::FromParam;
use serde::Deserialize;
use std::{
collections::{HashMap, HashSet},
sync::LazyLock,
};
pub static KNOWN_SOFTWARE: LazyLock<KnownSoftware> =
LazyLock::new(|| serde_json::from_str(include_str!("../known-software.json")).unwrap());
pub static KNOWN_SOFTWARE_NAMES: LazyLock<HashMap<String, String>> =
LazyLock::new(|| KNOWN_SOFTWARE.get_name_map());
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Software {
2025-01-12 06:39:38 +01:00
name: String,
2025-01-12 04:47:05 +01:00
aliases: HashSet<String>,
groups: HashSet<String>,
fork_of: Option<String>,
}
#[derive(Deserialize)]
pub struct Group {
2025-01-12 06:39:38 +01:00
name: String,
2025-01-12 04:47:05 +01:00
aliases: HashSet<String>,
}
#[derive(Deserialize)]
pub struct KnownSoftware {
software: HashMap<String, Software>,
groups: HashMap<String, Group>,
}
impl KnownSoftware {
fn get_name_map(&self) -> HashMap<String, String> {
let mut map = HashMap::new();
self.software.iter().for_each(|(name, software)| {
software.aliases.iter().for_each(|alias| {
assert_eq!(map.insert(alias.to_owned(), name.to_owned()), None);
});
});
self.groups.iter().for_each(|(name, group)| {
group.aliases.iter().for_each(|alias: &String| {
assert_eq!(map.insert(alias.to_owned(), name.to_owned()), None);
});
});
map
}
}
pub struct KnownInstanceSoftware<'r> {
pub requested: &'r str,
pub resolved: &'static String,
}
impl<'r> FromParam<'r> for KnownInstanceSoftware<'r> {
type Error = &'r str;
fn from_param(param: &'r str) -> Result<Self, Self::Error> {
if let Some(resolved) = KNOWN_SOFTWARE_NAMES.get(param) {
Ok(KnownInstanceSoftware {
requested: param,
resolved,
})
} else {
Err(param)
}
}
}