100 lines
3.2 KiB
Rust
100 lines
3.2 KiB
Rust
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());
|
|
pub static KNOWN_SOFTWARE_NODEINFO_NAMES: LazyLock<
|
|
HashMap<String, (String, HashMap<String, String>)>,
|
|
> = LazyLock::new(|| KNOWN_SOFTWARE.get_nodeinfo_name_map());
|
|
|
|
#[derive(Deserialize)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct Software {
|
|
name: String,
|
|
nodeinfo_name: String,
|
|
build_metadata: Option<String>,
|
|
aliases: HashSet<String>,
|
|
groups: HashSet<String>,
|
|
fork_of: Option<String>,
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct Group {
|
|
name: String,
|
|
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
|
|
}
|
|
|
|
fn get_nodeinfo_name_map(&self) -> HashMap<String, (String, HashMap<String, String>)> {
|
|
let mut map: HashMap<String, (String, HashMap<String, String>)> = HashMap::new();
|
|
self.software.iter().for_each(|(name, software)| {
|
|
if let Some((mut_name, mut_map)) = map.get_mut(&software.nodeinfo_name) {
|
|
if let Some(build_metadata) = &software.build_metadata {
|
|
assert_eq!(
|
|
mut_map.insert(build_metadata.to_owned(), name.to_owned()),
|
|
None
|
|
);
|
|
} else {
|
|
*mut_name = name.to_owned();
|
|
}
|
|
} else {
|
|
let mut build_metadata_map = HashMap::new();
|
|
if let Some(build_metadata) = &software.build_metadata {
|
|
build_metadata_map.insert(build_metadata.to_owned(), name.to_owned());
|
|
}
|
|
map.insert(
|
|
software.nodeinfo_name.to_owned(),
|
|
(name.to_owned(), build_metadata_map),
|
|
);
|
|
}
|
|
});
|
|
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)
|
|
}
|
|
}
|
|
}
|