gwr_track/tracker/aka.rs
1// Copyright (c) 2025 Graphcore Ltd. All rights reserved.
2
3//! Also Known As (AKA) - an alternative name manager.
4//!
5//! `Aka` lets a composite model expose stable public names while delegating the
6//! actual entity or port implementation to child components. Constructors named
7//! `new_and_register_with_renames` accept an `Option<&Aka>` and pass it to
8//! [`Entity::new_with_renames`](crate::entity::Entity::new_with_renames), port
9//! constructors such as `InPort::new_with_renames` and
10//! `OutPort::new_with_renames`, or child constructors so the tracking layer can
11//! record both the local implementation name and the parent-visible name.
12//!
13//! The usual public constructor should remain `new_and_register`; it normally
14//! calls the rename-aware constructor with `None` so users do not need to know
15//! about `Aka`. Add a rename-aware constructor when a component delegates
16//! public ports to internal subcomponents, composes other rename-aware
17//! children, or needs alternate names for tracking, filtering, or monitor
18//! configuration. Leaf components whose local ports are already their public
19//! API can stay with `new_and_register` until a real composition use case
20//! appears.
21
22use std::collections::HashMap;
23use std::fmt::Display;
24use std::rc::Rc;
25
26use crate::entity::Entity;
27
28/// Helper function for creating local Aka derived from incoming Aka
29#[macro_export]
30macro_rules! build_aka {
31 ($aka:ident, $parent:expr, $renames:expr) => {{
32 let mut tmp_aka = gwr_track::tracker::aka::Aka::default();
33 gwr_track::tracker::aka::populate_aka($aka, Some(&mut tmp_aka), $parent, $renames);
34 tmp_aka
35 }};
36}
37
38/// Type alias for the optional list of alternative names
39pub type AlternativeNames<'a> = Option<&'a Vec<String>>;
40
41/// A structure to manage alternative names for entities
42#[derive(Default)]
43pub struct Aka {
44 names: HashMap<String, Vec<String>>,
45}
46
47impl Aka {
48 /// Get the list of alternative names for an entity
49 #[must_use]
50 pub fn get_alternative_names<'a>(&'a self, name: &str) -> AlternativeNames<'a> {
51 self.names.get(name)
52 }
53}
54
55impl Display for Aka {
56 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57 write!(f, "{:#?}", self.names)
58 }
59}
60
61/// Lookup the renames for a given port name
62#[must_use]
63pub fn get_alternative_names<'a>(aka: Option<&'a Aka>, name: &str) -> AlternativeNames<'a> {
64 if let Some(aka) = aka {
65 return aka.get_alternative_names(name);
66 }
67 None
68}
69
70/// Build up a new set of alternative names with a new set of renames
71pub fn populate_aka_from_string(
72 aka: Option<&Aka>,
73 new_aka: Option<&mut Aka>,
74 entity: &Rc<Entity>,
75 renames: &[(String, String)],
76) {
77 let ref_names: Vec<(&str, &str)> = renames
78 .iter()
79 .map(|(a, b)| (a.as_str(), b.as_str()))
80 .collect();
81 populate_aka(aka, new_aka, entity, &ref_names);
82}
83
84/// Build up a new set of alternative names with a new set of renames.
85///
86/// Each tuple maps a name visible on `entity` to the child-local name that
87/// should inherit the alternative names. For example, a composite can map a
88/// public `rx_a` port to an internal limiter's `rx` port so traces and monitor
89/// configuration can refer to either level of the model.
90pub fn populate_aka(
91 aka: Option<&Aka>,
92 new_aka: Option<&mut Aka>,
93 entity: &Rc<Entity>,
94 renames: &[(&str, &str)],
95) {
96 if let Some(new_aka) = new_aka {
97 for (name_in_entity, name_in_child) in renames {
98 let renames = if let Some(aka) = aka.as_ref() {
99 match aka.names.get(*name_in_entity) {
100 Some(existing_renames) => {
101 let mut new_renames = existing_renames.clone();
102 new_renames.push(format!("{}::{}", entity.full_name(), name_in_entity));
103 new_renames
104 }
105 None => {
106 vec![format!("{}::{}", entity.full_name(), name_in_entity)]
107 }
108 }
109 } else {
110 vec![format!("{}::{}", entity.full_name(), name_in_entity)]
111 };
112 new_aka.names.insert((*name_in_child).to_string(), renames);
113 }
114 }
115}