libsurfer/
variable_name_type.rs
1use derive_more::Display;
2use enum_iterator::Sequence;
3use itertools::Itertools;
4use std::str::FromStr;
5
6use serde::{Deserialize, Serialize};
7
8use crate::displayed_item_tree::Node;
9use crate::wave_container::{ScopeRefExt, VariableRefExt};
10use crate::{displayed_item::DisplayedItem, wave_container::VariableRef, wave_data::WaveData};
11
12#[derive(PartialEq, Copy, Clone, Debug, Deserialize, Display, Serialize, Sequence)]
13pub enum VariableNameType {
14 #[display("Local")]
16 Local,
17
18 #[display("Unique")]
20 Unique,
21
22 #[display("Global")]
24 Global,
25}
26
27impl FromStr for VariableNameType {
28 type Err = String;
29
30 fn from_str(input: &str) -> Result<VariableNameType, Self::Err> {
31 match input {
32 "Local" => Ok(VariableNameType::Local),
33 "Unique" => Ok(VariableNameType::Unique),
34 "Global" => Ok(VariableNameType::Global),
35 _ => Err(format!(
36 "'{input}' is not a valid VariableNameType (Valid options: Local|Unique|Global)"
37 )),
38 }
39 }
40}
41
42impl WaveData {
43 pub fn compute_variable_display_names(&mut self) {
44 let full_names = self
45 .items_tree
46 .iter()
47 .map(|node| self.displayed_items.get(&node.item_ref))
48 .filter_map(|item| match item {
49 Some(DisplayedItem::Variable(variable)) => Some(variable.variable_ref.clone()),
50 _ => None,
51 })
52 .unique()
53 .collect_vec();
54
55 for Node { item_ref, .. } in self.items_tree.iter() {
56 self.displayed_items
57 .entry(*item_ref)
58 .and_modify(|item| match item {
59 DisplayedItem::Variable(variable) => {
60 let local_name = variable.variable_ref.name.clone();
61 variable.display_name = match variable.display_name_type {
62 VariableNameType::Local => local_name,
63 VariableNameType::Global => variable.variable_ref.full_path_string(),
64 VariableNameType::Unique => {
65 fn unique(
69 variable: &VariableRef,
70 variables: &[VariableRef],
71 ) -> String {
72 let other_variables = variables
73 .iter()
74 .filter(|&s| {
75 *s.full_path_string() != variable.full_path_string()
76 })
77 .collect_vec();
78
79 fn take_front(v: &VariableRef, l: usize) -> String {
80 if l == 0 {
81 v.name.clone()
82 } else {
83 format!(
84 "{}{}.{}",
85 if l < v.path.strs().len() { "…" } else { "" },
86 v.path.strs().iter().rev().take(l).rev().join("."),
87 v.name
88 )
89 }
90 }
91
92 let mut l = 0;
93 while other_variables
94 .iter()
95 .map(|v| take_front(v, l))
96 .contains(&take_front(variable, l))
97 {
98 l += 1;
99 }
100 take_front(variable, l)
101 }
102
103 unique(&variable.variable_ref, &full_names)
104 }
105 };
106 if self.display_variable_indices {
107 let index = self
108 .inner
109 .as_waves()
110 .unwrap()
111 .variable_meta(&variable.variable_ref)
112 .ok()
113 .as_ref()
114 .and_then(|meta| meta.index)
115 .map(|index| format!(" {index}"))
116 .unwrap_or_default();
117 variable.display_name = format!("{}{}", variable.display_name, index);
118 }
119 }
120 DisplayedItem::Divider(_) => {}
121 DisplayedItem::Marker(_) => {}
122 DisplayedItem::TimeLine(_) => {}
123 DisplayedItem::Placeholder(_) => {}
124 DisplayedItem::Stream(_) => {}
125 DisplayedItem::Group(_) => {}
126 });
127 }
128 }
129
130 pub fn force_variable_name_type(&mut self, name_type: VariableNameType) {
131 for Node { item_ref, .. } in self.items_tree.iter() {
132 self.displayed_items.entry(*item_ref).and_modify(|item| {
133 if let DisplayedItem::Variable(variable) = item {
134 variable.display_name_type = name_type;
135 }
136 });
137 }
138 self.default_variable_name_type = name_type;
139 self.compute_variable_display_names();
140 }
141}