71 lines
2.0 KiB
Rust
71 lines
2.0 KiB
Rust
use std::collections::HashMap;
|
|
|
|
use prometeu_analysis::ids::ProjectId;
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
|
|
pub struct ProjectKey {
|
|
pub name: String,
|
|
pub version: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
|
pub struct ProjectMeta {
|
|
pub id: ProjectId,
|
|
pub name: String,
|
|
pub version: String,
|
|
}
|
|
|
|
#[derive(Debug, Default, Clone)]
|
|
pub struct ProjectRegistry {
|
|
by_name: HashMap<ProjectKey, ProjectId>,
|
|
projects: Vec<ProjectMeta>,
|
|
}
|
|
|
|
impl ProjectRegistry {
|
|
pub fn new() -> Self { Self::default() }
|
|
|
|
pub fn intern(&mut self, key: &ProjectKey) -> ProjectId {
|
|
if let Some(id) = self.by_name.get(key).copied() { return id; }
|
|
|
|
let id = ProjectId(self.projects.len() as u32);
|
|
self.by_name.insert(key.clone(), id);
|
|
self.projects.push(ProjectMeta { id, name: key.name.clone(), version: key.version.clone() });
|
|
id
|
|
}
|
|
|
|
pub fn meta(&self, id: ProjectId) -> Option<&ProjectMeta> {
|
|
self.projects.get(id.as_usize())
|
|
}
|
|
|
|
pub fn key_of(&self, id: ProjectId) -> Option<ProjectKey> {
|
|
self.meta(id).map(|m| ProjectKey { name: m.name.clone(), version: m.version.clone() })
|
|
}
|
|
|
|
pub fn len(&self) -> usize { self.projects.len() }
|
|
pub fn is_empty(&self) -> bool { self.projects.is_empty() }
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn project_registry_stable_ids_for_same_key() {
|
|
let mut reg = ProjectRegistry::new();
|
|
let k = ProjectKey { name: "sdk".into(), version: "1.0.0".into() };
|
|
let id1 = reg.intern(&k);
|
|
let id2 = reg.intern(&k);
|
|
assert_eq!(id1, id2);
|
|
|
|
// Different version -> different id
|
|
let k2 = ProjectKey { name: "sdk".into(), version: "1.1.0".into() };
|
|
let id3 = reg.intern(&k2);
|
|
assert_ne!(id1, id3);
|
|
|
|
// Meta lookup
|
|
let m1 = reg.meta(id1).unwrap();
|
|
assert_eq!(m1.name, "sdk");
|
|
assert_eq!(m1.version, "1.0.0");
|
|
}
|
|
}
|