use super::{
api::ApiEntity, component::Component, domain::DomainEntity, group::GroupEntity,
location::LocationEntity, resource::ResourceEntity, system::SystemEntity,
template::TemplateEntity, user::UserEntity,
};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Serialize, Deserialize)]
pub struct Metadata {
pub name: String,
pub description: Option<String>,
pub annotations: Option<HashMap<String, String>>, pub tags: Option<Vec<String>>,
pub namespace: Option<String>, pub uid: Option<String>, pub etag: Option<String>, }
#[derive(Debug, Serialize, Deserialize)]
pub struct Relation {
pub r#type: String,
pub target_ref: Option<String>,
pub target: Target,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Target {
pub kind: String,
pub namespace: String,
pub name: String,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "PascalCase")]
pub enum Entity {
Component(Component),
API(ApiEntity),
Resource(ResourceEntity),
System(SystemEntity),
Group(GroupEntity),
Location(LocationEntity),
Domain(DomainEntity),
Template(TemplateEntity),
User(UserEntity),
}
impl Entity {
pub fn kind(&self) -> &'static str {
match self {
Entity::Component(_) => "Component",
Entity::API(_) => "API",
Entity::Resource(_) => "Resource",
Entity::System(_) => "System",
Entity::Group(_) => "Group",
Entity::Location(_) => "Location",
Entity::Domain(_) => "Domain",
Entity::Template(_) => "Template",
Entity::User(_) => "User",
}
}
pub fn metadata(&self) -> &Metadata {
match self {
Entity::Component(c) => &c.metadata,
Entity::API(a) => &a.metadata,
Entity::Resource(r) => &r.metadata,
Entity::System(s) => &s.metadata,
Entity::Group(g) => &g.metadata,
Entity::Location(l) => &l.metadata,
Entity::Domain(d) => &d.metadata,
Entity::Template(t) => &t.metadata,
Entity::User(u) => &u.metadata,
}
}
pub fn relations(&self) -> Option<&Vec<Relation>> {
match self {
Entity::Component(c) => c.relations.as_ref(),
Entity::API(a) => Some(&a.relations),
Entity::Resource(r) => Some(&r.relations),
Entity::System(s) => Some(&s.relations),
Entity::Group(g) => Some(&g.relations),
Entity::Location(l) => l.relations.as_ref(),
Entity::Domain(d) => Some(&d.relations),
Entity::Template(t) => t.relations.as_ref(),
Entity::User(u) => u.relations.as_ref(),
}
}
pub fn name(&self) -> &str {
&self.metadata().name
}
pub fn namespace(&self) -> &str {
self.metadata().namespace.as_deref().unwrap_or("default")
}
pub fn entity_ref(&self) -> String {
format!(
"{}:{}/{}",
self.kind().to_lowercase(),
self.namespace(),
self.name()
)
}
pub fn description(&self) -> Option<&str> {
self.metadata().description.as_deref()
}
pub fn tags(&self) -> Option<&Vec<String>> {
self.metadata().tags.as_ref()
}
pub fn annotations(&self) -> Option<&HashMap<String, String>> {
self.metadata().annotations.as_ref()
}
pub fn has_tag(&self, tag: &str) -> bool {
self.tags()
.map(|tags| tags.contains(&tag.to_string()))
.unwrap_or(false)
}
pub fn get_annotation(&self, key: &str) -> Option<&str> {
self.annotations()
.and_then(|annotations| annotations.get(key))
.map(|s| s.as_str())
}
}
impl std::fmt::Display for Entity {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} ({})", self.entity_ref(), self.kind())
}
}