use serde::Deserialize;
use crate::embedded;
#[derive(Debug, Clone, Deserialize)]
pub struct Pin {
pub name: String,
pub version: String,
#[serde(default)]
pub used_by: Vec<String>,
#[serde(default)]
pub check: Option<String>,
}
#[derive(Debug, Deserialize)]
struct Registry {
tool: Vec<Pin>,
}
#[must_use]
pub fn pins() -> Vec<Pin> {
parse(embedded::VERSIONS)
}
#[must_use]
pub fn pins_for(tech: &str) -> Vec<Pin> {
pins()
.into_iter()
.filter(|pin| pin.used_by.iter().any(|user| user == tech))
.collect()
}
#[must_use]
pub fn version_of(name: &str) -> Option<String> {
pins()
.into_iter()
.find(|pin| pin.name == name)
.map(|pin| pin.version)
}
fn parse(text: &str) -> Vec<Pin> {
toml::from_str::<Registry>(text)
.map(|registry| registry.tool)
.unwrap_or_default()
}
#[cfg(test)]
mod tests {
use super::{pins, pins_for};
#[test]
fn the_embedded_registry_parses_with_every_field() {
let pins = pins();
assert!(!pins.is_empty(), "the registry parsed to nothing");
for pin in &pins {
assert!(!pin.version.is_empty(), "{}: no version", pin.name);
assert!(!pin.used_by.is_empty(), "{}: no used_by", pin.name);
assert!(pin.check.is_some(), "{}: no check URL", pin.name);
}
}
#[test]
fn pins_filter_by_technology() {
let rust: Vec<String> = pins_for("rust").into_iter().map(|pin| pin.name).collect();
assert!(rust.contains(&"release-plz".to_owned()));
assert!(rust.contains(&"cargo-dist".to_owned()));
assert!(!rust.contains(&"git-cliff".to_owned()));
}
}