Skip to main content

backstage_client/entities/
common.rs

1use super::{
2    api::ApiEntity, component::Component, domain::DomainEntity, group::GroupEntity,
3    location::LocationEntity, resource::ResourceEntity, system::SystemEntity,
4    template::TemplateEntity, user::UserEntity,
5};
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8
9#[derive(Debug, Serialize, Deserialize)]
10pub struct Metadata {
11    pub name: String,
12    pub description: Option<String>,
13    pub annotations: Option<HashMap<String, String>>, // Use HashMap for annotations
14    pub tags: Option<Vec<String>>,
15    pub namespace: Option<String>, // Use Option if namespace can be missing
16    pub uid: Option<String>,       // Use Option if uid can be missing
17    pub etag: Option<String>,      // Use Option if etag can be missing
18}
19
20#[derive(Debug, Serialize, Deserialize)]
21pub struct Relation {
22    pub r#type: String,
23    pub target_ref: Option<String>,
24    pub target: Target,
25}
26
27#[derive(Debug, Serialize, Deserialize)]
28pub struct Target {
29    pub kind: String,
30    pub namespace: String,
31    pub name: String,
32}
33
34#[derive(Debug, Serialize, Deserialize)]
35#[serde(tag = "kind", rename_all = "PascalCase")]
36pub enum Entity {
37    Component(Component),
38    API(ApiEntity),
39    Resource(ResourceEntity),
40    System(SystemEntity),
41    Group(GroupEntity),
42    Location(LocationEntity),
43    Domain(DomainEntity),
44    Template(TemplateEntity),
45    User(UserEntity),
46}
47
48impl Entity {
49    /// Returns the kind of the entity as a string.
50    pub fn kind(&self) -> &'static str {
51        match self {
52            Entity::Component(_) => "Component",
53            Entity::API(_) => "API",
54            Entity::Resource(_) => "Resource",
55            Entity::System(_) => "System",
56            Entity::Group(_) => "Group",
57            Entity::Location(_) => "Location",
58            Entity::Domain(_) => "Domain",
59            Entity::Template(_) => "Template",
60            Entity::User(_) => "User",
61        }
62    }
63
64    /// Returns the metadata of the entity.
65    pub fn metadata(&self) -> &Metadata {
66        match self {
67            Entity::Component(c) => &c.metadata,
68            Entity::API(a) => &a.metadata,
69            Entity::Resource(r) => &r.metadata,
70            Entity::System(s) => &s.metadata,
71            Entity::Group(g) => &g.metadata,
72            Entity::Location(l) => &l.metadata,
73            Entity::Domain(d) => &d.metadata,
74            Entity::Template(t) => &t.metadata,
75            Entity::User(u) => &u.metadata,
76        }
77    }
78
79    /// Returns the relations of the entity if available.
80    pub fn relations(&self) -> Option<&Vec<Relation>> {
81        match self {
82            Entity::Component(c) => c.relations.as_ref(),
83            Entity::API(a) => Some(&a.relations),
84            Entity::Resource(r) => Some(&r.relations),
85            Entity::System(s) => Some(&s.relations),
86            Entity::Group(g) => Some(&g.relations),
87            Entity::Location(l) => l.relations.as_ref(),
88            Entity::Domain(d) => Some(&d.relations),
89            Entity::Template(t) => t.relations.as_ref(),
90            Entity::User(u) => u.relations.as_ref(),
91        }
92    }
93
94    /// Returns the name of the entity from its metadata.
95    pub fn name(&self) -> &str {
96        &self.metadata().name
97    }
98
99    /// Returns the namespace of the entity, defaulting to "default" if not specified.
100    pub fn namespace(&self) -> &str {
101        self.metadata().namespace.as_deref().unwrap_or("default")
102    }
103
104    /// Returns the fully qualified entity reference in the format "kind:namespace/name".
105    pub fn entity_ref(&self) -> String {
106        format!(
107            "{}:{}/{}",
108            self.kind().to_lowercase(),
109            self.namespace(),
110            self.name()
111        )
112    }
113
114    /// Returns the description of the entity if available.
115    pub fn description(&self) -> Option<&str> {
116        self.metadata().description.as_deref()
117    }
118
119    /// Returns the tags associated with the entity.
120    pub fn tags(&self) -> Option<&Vec<String>> {
121        self.metadata().tags.as_ref()
122    }
123
124    /// Returns the annotations associated with the entity.
125    pub fn annotations(&self) -> Option<&HashMap<String, String>> {
126        self.metadata().annotations.as_ref()
127    }
128
129    /// Checks if the entity has a specific tag.
130    pub fn has_tag(&self, tag: &str) -> bool {
131        self.tags()
132            .map(|tags| tags.contains(&tag.to_string()))
133            .unwrap_or(false)
134    }
135
136    /// Gets an annotation value by key.
137    pub fn get_annotation(&self, key: &str) -> Option<&str> {
138        self.annotations()
139            .and_then(|annotations| annotations.get(key))
140            .map(|s| s.as_str())
141    }
142}
143
144impl std::fmt::Display for Entity {
145    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
146        write!(f, "{} ({})", self.entity_ref(), self.kind())
147    }
148}