1use super::{
2 array::{descriptions, names},
3 registercluster::{
4 AllRegistersIter, AllRegistersIterMut, ClusterIter, ClusterIterMut, RegisterIter,
5 RegisterIterMut,
6 },
7 BuildError, Description, DimElement, EmptyToNone, MaybeArray, Name, Register, RegisterCluster,
8 RegisterProperties, SvdError, ValidateLevel,
9};
10use std::ops::Deref;
11
12pub type Cluster = MaybeArray<ClusterInfo>;
14
15#[derive(Clone, Debug, PartialEq, Eq, thiserror::Error)]
17pub enum Error {
18 #[error("Cluster must contain at least one Register or Cluster")]
20 EmptyCluster,
21}
22
23#[cfg_attr(
25 feature = "serde",
26 derive(serde::Deserialize, serde::Serialize),
27 serde(rename_all = "camelCase")
28)]
29#[derive(Clone, Debug, PartialEq)]
30#[non_exhaustive]
31pub struct ClusterInfo {
32 pub name: String,
35
36 #[cfg_attr(
38 feature = "serde",
39 serde(default, skip_serializing_if = "Option::is_none")
40 )]
41 pub description: Option<String>,
42
43 #[cfg_attr(
45 feature = "serde",
46 serde(default, skip_serializing_if = "Option::is_none")
47 )]
48 pub alternate_cluster: Option<String>,
49
50 #[cfg_attr(
52 feature = "serde",
53 serde(default, skip_serializing_if = "Option::is_none")
54 )]
55 pub header_struct_name: Option<String>,
56
57 pub address_offset: u32,
59
60 #[cfg_attr(feature = "serde", serde(flatten))]
62 pub default_register_properties: RegisterProperties,
63
64 pub children: Vec<RegisterCluster>,
66
67 #[cfg_attr(
70 feature = "serde",
71 serde(default, skip_serializing_if = "Option::is_none")
72 )]
73 pub derived_from: Option<String>,
74}
75
76pub fn address_offsets<'a>(
78 info: &'a ClusterInfo,
79 dim: &'a DimElement,
80) -> impl Iterator<Item = u32> + 'a {
81 (0..dim.dim).map(move |i| info.address_offset + i * dim.dim_increment)
82}
83
84pub fn expand<'a>(
86 info: &'a ClusterInfo,
87 dim: &'a DimElement,
88) -> impl Iterator<Item = ClusterInfo> + 'a {
89 names(info, dim)
90 .zip(descriptions(info, dim))
91 .zip(address_offsets(info, dim))
92 .map(|((name, description), address_offset)| {
93 let mut info = info.clone();
94 info.name = name;
95 info.description = description;
96 info.address_offset = address_offset;
97 info
98 })
99}
100
101#[derive(Clone, Debug, Default, PartialEq)]
103pub struct ClusterInfoBuilder {
104 name: Option<String>,
105 description: Option<String>,
106 alternate_cluster: Option<String>,
107 header_struct_name: Option<String>,
108 address_offset: Option<u32>,
109 default_register_properties: RegisterProperties,
110 children: Option<Vec<RegisterCluster>>,
111 derived_from: Option<String>,
112}
113
114impl From<ClusterInfo> for ClusterInfoBuilder {
115 fn from(c: ClusterInfo) -> Self {
116 Self {
117 name: Some(c.name),
118 description: c.description,
119 alternate_cluster: c.alternate_cluster,
120 header_struct_name: c.header_struct_name,
121 address_offset: Some(c.address_offset),
122 default_register_properties: c.default_register_properties,
123 children: Some(c.children),
124 derived_from: c.derived_from,
125 }
126 }
127}
128
129impl ClusterInfoBuilder {
130 pub fn name(mut self, value: String) -> Self {
132 self.name = Some(value);
133 self
134 }
135 pub fn description(mut self, value: Option<String>) -> Self {
137 self.description = value;
138 self
139 }
140 pub fn alternate_cluster(mut self, value: Option<String>) -> Self {
142 self.alternate_cluster = value;
143 self
144 }
145 pub fn header_struct_name(mut self, value: Option<String>) -> Self {
147 self.header_struct_name = value;
148 self
149 }
150 pub fn address_offset(mut self, value: u32) -> Self {
152 self.address_offset = Some(value);
153 self
154 }
155 pub fn default_register_properties(mut self, value: RegisterProperties) -> Self {
157 self.default_register_properties = value;
158 self
159 }
160 pub fn children(mut self, value: Vec<RegisterCluster>) -> Self {
162 self.children = Some(value);
163 self
164 }
165 pub fn derived_from(mut self, value: Option<String>) -> Self {
167 self.derived_from = value;
168 self
169 }
170 pub fn build(self, lvl: ValidateLevel) -> Result<ClusterInfo, SvdError> {
172 let cluster = ClusterInfo {
173 name: self
174 .name
175 .ok_or_else(|| BuildError::Uninitialized("name".to_string()))?,
176 description: self.description.empty_to_none(),
177 alternate_cluster: self.alternate_cluster.empty_to_none(),
178 header_struct_name: self.header_struct_name.empty_to_none(),
179 address_offset: self
180 .address_offset
181 .ok_or_else(|| BuildError::Uninitialized("address_offset".to_string()))?,
182 default_register_properties: self.default_register_properties.build(lvl)?,
183 children: self
184 .children
185 .ok_or_else(|| BuildError::Uninitialized("children".to_string()))?,
186 derived_from: self.derived_from,
187 };
188 cluster.validate(lvl)?;
189 Ok(cluster)
190 }
191}
192
193impl ClusterInfo {
194 pub fn builder() -> ClusterInfoBuilder {
196 ClusterInfoBuilder::default()
197 }
198 pub const fn single(self) -> Cluster {
200 Cluster::Single(self)
201 }
202 pub const fn array(self, dim: DimElement) -> Cluster {
204 Cluster::Array(self, dim)
205 }
206 pub fn maybe_array(self, dim: Option<DimElement>) -> Cluster {
208 if let Some(dim) = dim {
209 self.array(dim)
210 } else {
211 self.single()
212 }
213 }
214 pub fn modify_from(
216 &mut self,
217 builder: ClusterInfoBuilder,
218 lvl: ValidateLevel,
219 ) -> Result<(), SvdError> {
220 if let Some(name) = builder.name {
221 self.name = name;
222 }
223 if builder.description.is_some() {
224 self.description = builder.description.empty_to_none();
225 }
226 if builder.alternate_cluster.is_some() {
227 self.alternate_cluster = builder.alternate_cluster.empty_to_none();
228 }
229 if builder.header_struct_name.is_some() {
230 self.header_struct_name = builder.header_struct_name.empty_to_none();
231 }
232 if let Some(address_offset) = builder.address_offset {
233 self.address_offset = address_offset;
234 }
235 if builder.derived_from.is_some() {
236 self.derived_from = builder.derived_from;
237 self.children = Vec::new();
238 self.default_register_properties = RegisterProperties::default();
239 } else {
240 self.default_register_properties
241 .modify_from(builder.default_register_properties, lvl)?;
242 if let Some(children) = builder.children {
243 self.children = children;
244 }
245 }
246 self.validate(lvl)
247 }
248
249 pub fn validate(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
251 if !lvl.is_disabled() {
252 if lvl.is_strict() {
253 super::check_dimable_name(&self.name, "name")?;
254 }
255 if let Some(name) = self.derived_from.as_ref() {
256 if lvl.is_strict() {
257 super::check_derived_name(name, "derivedFrom")?;
258 }
259 } else if self.children.is_empty() && lvl.is_strict() {
260 return Err(Error::EmptyCluster.into());
261 }
262 }
263 Ok(())
264 }
265 pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
267 self.default_register_properties.validate(lvl)?;
268 for r in self.registers() {
269 r.validate_all(lvl)?;
270 }
271 for c in self.clusters() {
272 c.validate_all(lvl)?;
273 }
274 self.validate(lvl)
275 }
276
277 #[deprecated(since = "0.12.1", note = "Please use `all_registers` instead")]
279 pub fn reg_iter(&self) -> AllRegistersIter {
280 self.all_registers()
281 }
282
283 pub fn all_registers(&self) -> AllRegistersIter {
285 AllRegistersIter {
286 rem: self.children.iter().rev().collect(),
287 }
288 }
289
290 #[deprecated(since = "0.12.1", note = "Please use `all_registers_mut` instead")]
292 pub fn reg_iter_mut(&mut self) -> AllRegistersIterMut {
293 self.all_registers_mut()
294 }
295
296 pub fn all_registers_mut(&mut self) -> AllRegistersIterMut {
298 AllRegistersIterMut {
299 rem: self.children.iter_mut().rev().collect(),
300 }
301 }
302
303 pub fn registers(&self) -> RegisterIter {
305 RegisterIter {
306 all: self.children.iter(),
307 }
308 }
309
310 pub fn registers_mut(&mut self) -> RegisterIterMut {
312 RegisterIterMut {
313 all: self.children.iter_mut(),
314 }
315 }
316
317 pub fn clusters(&self) -> ClusterIter {
319 ClusterIter {
320 all: self.children.iter(),
321 }
322 }
323
324 pub fn clusters_mut(&mut self) -> ClusterIterMut {
326 ClusterIterMut {
327 all: self.children.iter_mut(),
328 }
329 }
330
331 pub fn get_register(&self, name: &str) -> Option<&Register> {
333 self.registers().find(|f| f.name == name)
334 }
335
336 pub fn get_mut_register(&mut self, name: &str) -> Option<&mut Register> {
338 self.registers_mut().find(|f| f.name == name)
339 }
340
341 pub fn get_cluster(&self, name: &str) -> Option<&Cluster> {
343 self.clusters().find(|f| f.name == name)
344 }
345
346 pub fn get_mut_cluster(&mut self, name: &str) -> Option<&mut Cluster> {
348 self.clusters_mut().find(|f| f.name == name)
349 }
350}
351
352impl Cluster {
353 pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
355 if let Self::Array(_, dim) = self {
356 dim.validate(lvl)?;
357 }
358 self.deref().validate_all(lvl)
359 }
360}
361
362impl Name for ClusterInfo {
363 fn name(&self) -> &str {
364 &self.name
365 }
366}
367
368impl Description for ClusterInfo {
369 fn description(&self) -> Option<&str> {
370 self.description.as_deref()
371 }
372}