1use std::{fmt::Display, rc::Rc, sync::Arc};
2
3use convert_case::Boundary;
4#[cfg(test)]
5use device_driver_common::identifier::Namespace;
6use device_driver_common::{
7 identifier::{Global, Identifier, IdentifierRef, Local, Operation, RuntimeNamespace, Type},
8 span::{Span, SpanExt, Spanned},
9 specifiers::{
10 Access, AddressMode, AddressRange, BaseType, ByteOrder, Integer, NodeType, Repeat,
11 ResetValue, TypeConversion,
12 },
13};
14use device_driver_diagnostics::DynError;
15
16#[derive(Debug, Clone, Default, PartialEq)]
17pub struct Manifest {
18 pub description: String,
19 pub name: Spanned<Identifier<Global>>,
20 pub default_access: Option<Access>,
21 pub config: DeviceConfig,
22 pub objects: Vec<Object>,
23
24 pub short_properties_span: Span,
25 pub properties_span: Option<Span>,
26 pub span: Span,
27}
28
29impl Manifest {
30 pub fn iter_objects_with_config_mut(&mut self) -> ObjectIterMut<'_> {
31 ObjectIterMut {
32 children: &mut self.objects,
33 parent: None,
34 collection_object_returned: false,
35 current_device_config: Rc::new(self.config.clone()),
36 }
37 }
38
39 pub fn iter_objects(&self) -> impl Iterator<Item = &Object> {
40 ObjectIter {
41 children: &self.objects,
42 parent: None,
43 collection_object_returned: false,
44 current_device_config: Rc::new(self.config.clone()),
45 }
46 .map(|(object, _)| object)
47 }
48
49 #[must_use]
50 pub fn iter_objects_with_config(&self) -> ObjectIter<'_> {
51 ObjectIter {
52 children: &self.objects,
53 parent: None,
54 collection_object_returned: false,
55 current_device_config: Rc::new(self.config.clone()),
56 }
57 }
58
59 pub fn iter_enums(&self) -> impl Iterator<Item = &'_ Enum> {
60 self.iter_objects_with_config().filter_map(|(o, _)| {
61 if let Object::Enum(e) = o {
62 Some(e)
63 } else {
64 None
65 }
66 })
67 }
68
69 pub fn iter_enums_with_config(&self) -> impl Iterator<Item = (&'_ Enum, Rc<DeviceConfig>)> {
70 self.iter_objects_with_config().filter_map(|(o, config)| {
71 if let Object::Enum(e) = o {
72 Some((e, config))
73 } else {
74 None
75 }
76 })
77 }
78
79 pub fn iter_devices_with_config(&self) -> impl Iterator<Item = (&'_ Device, Rc<DeviceConfig>)> {
80 self.iter_objects_with_config().filter_map(|(o, config)| {
81 if let Object::Device(d) = o {
82 Some((d, config))
83 } else {
84 None
85 }
86 })
87 }
88}
89
90#[derive(Default)]
91pub struct ObjectIterMut<'a> {
92 children: &'a mut [Object],
93 parent: Option<Box<ObjectIterMut<'a>>>,
94 collection_object_returned: bool,
95 current_device_config: Rc<DeviceConfig>,
96}
97
98pub trait LendingIterator {
101 type Item<'a>
102 where
103 Self: 'a;
104
105 fn next(&mut self) -> Option<Self::Item<'_>>;
106}
107
108impl LendingIterator for ObjectIterMut<'_> {
109 type Item<'b>
110 = (&'b mut Object, Rc<DeviceConfig>)
111 where
112 Self: 'b;
113
114 fn next(&mut self) -> Option<Self::Item<'_>> {
115 if self.children.is_empty() {
116 match self.parent.take() {
117 Some(parent) => {
118 *self = *parent;
120 self.next()
121 }
122 None => None,
123 }
124 } else if self.children[0].child_objects_mut().is_empty() {
125 let (first, rest) = std::mem::take(&mut self.children)
126 .split_first_mut()
127 .expect("Already checked not empty");
128 self.children = rest;
129 Some((first, self.current_device_config.clone()))
130 } else if !self.collection_object_returned {
131 self.collection_object_returned = true;
132
133 let next_device_config = if let Some(new_config) = self.children[0].device_config() {
134 Rc::new(self.current_device_config.override_with(new_config))
135 } else {
136 self.current_device_config.clone()
137 };
138
139 Some((&mut self.children[0], next_device_config))
140 } else {
141 self.collection_object_returned = false;
142
143 let next_device_config = if let Some(new_config) = self.children[0].device_config() {
144 Rc::new(self.current_device_config.override_with(new_config))
145 } else {
146 self.current_device_config.clone()
147 };
148
149 let (first, rest) = std::mem::take(&mut self.children)
150 .split_first_mut()
151 .expect("Already checked not empty");
152 self.children = rest;
153
154 *self = ObjectIterMut {
155 children: first.child_objects_mut(),
156 parent: Some(Box::new(std::mem::take(self))),
157 collection_object_returned: false,
158 current_device_config: next_device_config,
159 };
160 self.next()
161 }
162 }
163}
164
165#[derive(Default)]
166pub struct ObjectIter<'a> {
167 children: &'a [Object],
168 parent: Option<Box<ObjectIter<'a>>>,
169 collection_object_returned: bool,
170 current_device_config: Rc<DeviceConfig>,
171}
172
173impl<'a> Iterator for ObjectIter<'a> {
174 type Item = (&'a Object, Rc<DeviceConfig>);
175
176 fn next(&mut self) -> Option<Self::Item> {
177 let children = std::mem::take(&mut self.children);
178
179 match children.split_first() {
180 None => match self.parent.take() {
181 Some(parent) => {
182 *self = *parent;
184 self.next()
185 }
186 None => None,
187 },
188 Some((first, rest)) => {
189 self.children = rest;
190
191 if first.child_objects().is_empty() {
192 Some((first, self.current_device_config.clone()))
193 } else if !self.collection_object_returned {
194 self.collection_object_returned = true;
195
196 let next_device_config = if let Some(new_config) = first.device_config() {
197 Rc::new(self.current_device_config.override_with(new_config))
198 } else {
199 self.current_device_config.clone()
200 };
201
202 self.children = children;
203
204 Some((&children[0], next_device_config))
205 } else {
206 self.collection_object_returned = false;
207
208 let next_device_config = if let Some(new_config) = first.device_config() {
209 Rc::new(self.current_device_config.override_with(new_config))
210 } else {
211 self.current_device_config.clone()
212 };
213
214 *self = ObjectIter {
215 children: first.child_objects(),
216 parent: Some(Box::new(std::mem::take(self))),
217 collection_object_returned: false,
218 current_device_config: next_device_config,
219 };
220 self.next()
221 }
222 }
223 }
224 }
225}
226
227impl From<Device> for Manifest {
229 fn from(value: Device) -> Self {
230 let default_access = value.default_access;
231
232 Self {
233 description: String::new(),
234 name: value
235 .name
236 .value
237 .clone()
238 .cast_unchecked()
239 .with_span(value.name.span),
240 short_properties_span: value.short_properties_span,
241 properties_span: value.properties_span,
242 span: value.span,
243 objects: vec![Object::Device(value)],
244 default_access,
245 config: DeviceConfig::default(),
246 }
247 }
248}
249
250#[derive(Debug, Clone, Default, PartialEq)]
251pub struct Device {
252 pub description: String,
253 pub name: Spanned<Identifier<Type>>,
254 pub default_access: Option<Access>,
255 pub address_offset: Spanned<i128>,
256 pub device_config: DeviceConfig,
257 pub objects: Vec<Object>,
258
259 pub short_properties_span: Span,
260 pub properties_span: Option<Span>,
261 pub span: Span,
263}
264
265impl Device {
266 pub fn iter_objects(&self) -> impl Iterator<Item = &Object> {
267 ObjectIter {
268 children: &self.objects,
269 parent: None,
270 collection_object_returned: false,
271 current_device_config: Rc::new(DeviceConfig::default()),
273 }
274 .map(|(object, _)| object)
275 }
276}
277
278#[derive(Debug, Clone, Default, PartialEq)]
279pub struct DeviceConfig {
280 pub owner: Option<ObjectId>,
282 pub byte_order: Option<ByteOrder>,
283 pub register_address_type: Option<Spanned<Integer>>,
284 pub command_address_type: Option<Spanned<Integer>>,
285 pub buffer_address_type: Option<Spanned<Integer>>,
286 pub name_word_boundaries: Option<Vec<Boundary>>,
287 pub register_address_mode: Option<Spanned<AddressMode>>,
288}
289
290impl DeviceConfig {
291 #[must_use]
292 pub fn override_with(&self, other: &Self) -> DeviceConfig {
293 Self {
294 owner: other.owner.clone().or(self.owner.clone()),
295 byte_order: other.byte_order.or(self.byte_order),
296 register_address_type: other.register_address_type.or(self.register_address_type),
297 command_address_type: other.command_address_type.or(self.command_address_type),
298 buffer_address_type: other.buffer_address_type.or(self.buffer_address_type),
299 name_word_boundaries: other
300 .name_word_boundaries
301 .as_ref()
302 .or(self.name_word_boundaries.as_ref())
303 .cloned(),
304 register_address_mode: other.register_address_mode.or(self.register_address_mode),
305 }
306 }
307}
308
309#[derive(Debug, Clone, PartialEq)]
310pub enum Object {
311 Device(Device),
312 Block(Block),
313 Register(Register),
314 Command(Command),
315 Buffer(Buffer),
316 FieldSet(FieldSet),
317 Enum(Enum),
318 Extern(Extern),
319 Field(Field),
320}
321
322impl Object {
323 pub fn device_config(&self) -> Option<&DeviceConfig> {
324 match self {
325 Object::Device(device) => Some(&device.device_config),
326 _ => None,
327 }
328 }
329
330 pub fn child_objects_mut(&mut self) -> &mut [Object] {
331 match self {
332 Object::Device(device) => &mut device.objects,
333 Object::Block(block) => &mut block.objects,
334 _ => &mut [],
335 }
336 }
337
338 pub fn child_objects_vec(&mut self) -> Option<&mut Vec<Object>> {
339 match self {
340 Object::Device(device) => Some(&mut device.objects),
341 Object::Block(block) => Some(&mut block.objects),
342 _ => None,
343 }
344 }
345
346 pub fn child_objects(&self) -> &[Object] {
347 match self {
348 Object::Device(device) => &device.objects,
349 Object::Block(block) => &block.objects,
350 _ => &[],
351 }
352 }
353
354 pub fn name_mut(&mut self) -> &mut Identifier<RuntimeNamespace> {
356 match self {
357 Object::Device(val) => val.name.as_runtime_namespace_mut(),
358 Object::Block(val) => val.name.as_runtime_namespace_mut(),
359 Object::Register(val) => val.name.as_runtime_namespace_mut(),
360 Object::Command(val) => val.name.as_runtime_namespace_mut(),
361 Object::Buffer(val) => val.name.as_runtime_namespace_mut(),
362 Object::FieldSet(val) => val.name.as_runtime_namespace_mut(),
363 Object::Enum(val) => val.name.as_runtime_namespace_mut(),
364 Object::Extern(val) => val.name.as_runtime_namespace_mut(),
365 Object::Field(val) => val.name.as_runtime_namespace_mut(),
366 }
367 }
368
369 pub fn name(&self) -> &Identifier<RuntimeNamespace> {
371 match self {
372 Object::Device(val) => val.name.as_runtime_namespace(),
373 Object::Block(val) => val.name.as_runtime_namespace(),
374 Object::Register(val) => val.name.as_runtime_namespace(),
375 Object::Command(val) => val.name.as_runtime_namespace(),
376 Object::Buffer(val) => val.name.as_runtime_namespace(),
377 Object::FieldSet(val) => val.name.as_runtime_namespace(),
378 Object::Enum(val) => val.name.as_runtime_namespace(),
379 Object::Extern(val) => val.name.as_runtime_namespace(),
380 Object::Field(val) => val.name.as_runtime_namespace(),
381 }
382 }
383
384 pub fn name_span(&self) -> Span {
386 match self {
387 Object::Device(val) => val.name.span,
388 Object::Block(val) => val.name.span,
389 Object::Register(val) => val.name.span,
390 Object::Command(val) => val.name.span,
391 Object::Buffer(val) => val.name.span,
392 Object::FieldSet(val) => val.name.span,
393 Object::Enum(val) => val.name.span,
394 Object::Extern(val) => val.name.span,
395 Object::Field(val) => val.name.span,
396 }
397 }
398
399 pub fn address(&self) -> Option<Spanned<i128>> {
401 match self {
402 Object::Device(device) => Some(device.address_offset),
403 Object::Block(block) => Some(block.address_offset),
404 Object::Register(register) => Some(register.address),
405 Object::Command(command) => Some(command.address),
406 Object::Buffer(buffer) => Some(buffer.address),
407 Object::FieldSet(_) => None,
408 Object::Enum(_) => None,
409 Object::Extern(_) => None,
410 Object::Field(_) => None,
411 }
412 }
413
414 pub fn repeat(&self) -> Option<&Repeat> {
416 match self {
417 Object::Device(_) => None,
418 Object::Block(block) => block.repeat.as_ref(),
419 Object::Register(register) => register.repeat.as_ref(),
420 Object::Command(command) => command.repeat.as_ref(),
421 Object::Buffer(_) => None,
422 Object::FieldSet(_) => None,
423 Object::Enum(_) => None,
424 Object::Extern(_) => None,
425 Object::Field(field) => field.repeat.as_ref(),
426 }
427 }
428
429 pub fn repeat_mut(&mut self) -> Option<&mut Repeat> {
431 match self {
432 Object::Device(_) => None,
433 Object::Block(block) => block.repeat.as_mut(),
434 Object::Register(register) => register.repeat.as_mut(),
435 Object::Command(command) => command.repeat.as_mut(),
436 Object::Buffer(_) => None,
437 Object::FieldSet(_) => None,
438 Object::Enum(_) => None,
439 Object::Extern(_) => None,
440 Object::Field(field) => field.repeat.as_mut(),
441 }
442 }
443
444 pub fn as_field_set(&self) -> Option<&FieldSet> {
445 if let Self::FieldSet(v) = self {
446 Some(v)
447 } else {
448 None
449 }
450 }
451
452 pub fn as_field_set_mut(&mut self) -> Option<&mut FieldSet> {
453 if let Self::FieldSet(v) = self {
454 Some(v)
455 } else {
456 None
457 }
458 }
459
460 pub fn as_enum(&self) -> Option<&Enum> {
461 if let Self::Enum(v) = self {
462 Some(v)
463 } else {
464 None
465 }
466 }
467
468 pub fn as_enum_mut(&mut self) -> Option<&mut Enum> {
469 if let Self::Enum(v) = self {
470 Some(v)
471 } else {
472 None
473 }
474 }
475
476 pub fn allow_address_overlap(&self) -> bool {
477 match self {
478 Object::Device(_) => false,
479 Object::Block(_) => false,
480 Object::Register(register) => register.allow_address_overlap,
481 Object::Command(command) => command.allow_address_overlap,
482 Object::Buffer(_) => false,
483 Object::FieldSet(_) => false,
484 Object::Enum(_) => false,
485 Object::Extern(_) => false,
486 Object::Field(_) => false,
487 }
488 }
489
490 pub fn span(&self) -> Span {
492 match self {
493 Object::Device(val) => val.span,
494 Object::Block(val) => val.span,
495 Object::Register(val) => val.span,
496 Object::Command(val) => val.span,
497 Object::Buffer(val) => val.span,
498 Object::FieldSet(val) => val.span,
499 Object::Enum(val) => val.span,
500 Object::Extern(val) => val.span,
501 Object::Field(val) => val.span,
502 }
503 }
504
505 pub fn node_type(&self) -> NodeType {
506 match self {
507 Object::Device(_) => NodeType::Device,
508 Object::Block(_) => NodeType::Block,
509 Object::Register(_) => NodeType::Register,
510 Object::Command(_) => NodeType::Command,
511 Object::Buffer(_) => NodeType::Buffer,
512 Object::FieldSet(_) => NodeType::FieldSet,
513 Object::Enum(_) => NodeType::Enum,
514 Object::Extern(_) => NodeType::Extern,
515 Object::Field(_) => NodeType::Field,
516 }
517 }
518
519 pub fn fieldset_refs(&self) -> Vec<Spanned<IdentifierRef<Type>>> {
521 match self {
522 Object::Device(_) => Vec::new(),
523 Object::Block(_) => Vec::new(),
524 Object::Register(r) => vec![r.field_set_ref.clone()],
525 Object::Command(c) => [c.field_set_ref_in.clone(), c.field_set_ref_out.clone()]
526 .into_iter()
527 .flatten()
528 .collect(),
529 Object::Buffer(_) => Vec::new(),
530 Object::FieldSet(_) => Vec::new(),
531 Object::Enum(_) => Vec::new(),
532 Object::Extern(_) => Vec::new(),
533 Object::Field(_) => Vec::new(),
534 }
535 }
536
537 pub fn properties_span(&self) -> Option<Span> {
538 match self {
539 Object::Device(val) => val.properties_span,
540 Object::Block(val) => val.properties_span,
541 Object::Register(val) => val.properties_span,
542 Object::Command(val) => val.properties_span,
543 Object::Buffer(val) => val.properties_span,
544 Object::FieldSet(val) => val.properties_span,
545 Object::Enum(val) => val.properties_span,
546 Object::Extern(val) => val.properties_span,
547 Object::Field(val) => val.properties_span,
548 }
549 }
550}
551
552#[derive(Debug, Clone, Default, PartialEq)]
553pub struct Block {
554 pub description: String,
555 pub name: Spanned<Identifier<Global>>,
556 pub address_offset: Spanned<i128>,
557 pub repeat: Option<Repeat>,
558 pub objects: Vec<Object>,
559 pub default_access: Option<Access>,
560
561 pub short_properties_span: Span,
562 pub properties_span: Option<Span>,
563 pub span: Span,
565}
566
567impl Block {
568 pub fn iter_objects(&self) -> impl Iterator<Item = &Object> {
569 ObjectIter {
570 children: &self.objects,
571 parent: None,
572 collection_object_returned: false,
573 current_device_config: Rc::new(DeviceConfig::default()),
575 }
576 .map(|(object, _)| object)
577 }
578}
579
580#[derive(Debug, Clone, Default, PartialEq)]
581pub struct Register {
582 pub description: String,
583 pub name: Spanned<Identifier<Operation>>,
584 pub access: Option<Access>,
585 pub allow_address_overlap: bool,
586 pub address: Spanned<i128>,
587 pub reset_value: Option<Spanned<ResetValue>>,
588 pub repeat: Option<Repeat>,
589 pub field_set_ref: Spanned<IdentifierRef<Type>>,
590
591 pub short_properties_span: Span,
592 pub properties_span: Option<Span>,
593 pub span: Span,
595}
596
597#[derive(Debug, Clone, Default, PartialEq)]
598pub struct FieldSet {
599 pub description: String,
600 pub name: Spanned<Identifier<Type>>,
601 pub size_bytes: Spanned<u32>,
602 pub byte_order: Option<ByteOrder>,
603 pub allow_bit_overlap: bool,
604 pub default_access: Option<Access>,
605 pub fields: Vec<Field>,
606
607 pub short_properties_span: Span,
608 pub properties_span: Option<Span>,
609 pub span: Span,
611}
612
613impl FieldSet {
614 pub fn size_bits(&self) -> u32 {
615 self.size_bytes.value * 8
616 }
617}
618
619#[derive(Debug, Clone, Default, PartialEq)]
620pub struct Field {
621 pub description: String,
622 pub name: Spanned<Identifier<Local>>,
623 pub access: Option<Access>,
624 pub base_type: Spanned<BaseType>,
625 pub field_conversion: Option<TypeConversion>,
626 pub field_address: Spanned<AddressRange>,
627 pub repeat: Option<Repeat>,
628
629 pub short_properties_span: Span,
630 pub properties_span: Option<Span>,
631 pub span: Span,
633}
634
635impl Field {
636 #[must_use]
637 pub fn get_type_specifier_string(&self) -> String {
638 match &self.field_conversion {
639 Some(fc) => {
640 format!(
641 "{}:{}{}",
642 self.base_type,
643 fc.type_name.original(),
644 if fc.fallible { "?" } else { "" }
645 )
646 }
647 None => self.base_type.to_string(),
648 }
649 }
650}
651
652#[derive(Debug, Clone, Default, PartialEq)]
653pub struct Enum {
654 pub description: String,
655 pub name: Spanned<Identifier<Type>>,
656 pub variants: Vec<EnumVariant>,
657 pub base_type: Spanned<BaseType>,
658 pub size_bits: Option<u32>,
659 pub generation_style: Option<EnumGenerationStyle>,
660
661 pub short_properties_span: Span,
662 pub properties_span: Option<Span>,
663 pub span: Span,
665}
666
667impl Enum {
668 #[cfg(test)]
669 pub fn new(
670 description: String,
671 name: Spanned<Identifier<Type>>,
672 variants: Vec<EnumVariant>,
673 base_type: Spanned<BaseType>,
674 size_bits: Option<u32>,
675 span: Span,
676 ) -> Self {
677 Self {
678 description,
679 name,
680 variants,
681 base_type,
682 size_bits,
683 generation_style: None,
684 short_properties_span: Span::empty(),
685 properties_span: None,
686 span,
687 }
688 }
689
690 #[cfg(test)]
691 pub fn new_with_style(
692 description: String,
693 name: Spanned<Identifier<Type>>,
694 variants: Vec<EnumVariant>,
695 base_type: Spanned<BaseType>,
696 size_bits: Option<u32>,
697 generation_style: EnumGenerationStyle,
698 span: Span,
699 ) -> Self {
700 Self {
701 description,
702 name,
703 variants,
704 base_type,
705 size_bits,
706 generation_style: Some(generation_style),
707 short_properties_span: Span::empty(),
708 properties_span: None,
709 span,
710 }
711 }
712
713 pub fn iter_variants_with_discriminant(&self) -> impl Iterator<Item = (i128, &EnumVariant)> {
718 let mut next_discriminant = 0;
719 self.variants.iter().map(move |variant| {
720 if let Some(discriminant) = variant.value.specified_discriminant() {
721 next_discriminant = discriminant + 1;
722 (discriminant, variant)
723 } else {
724 let discriminant = next_discriminant;
725 next_discriminant += 1;
726 (discriminant, variant)
727 }
728 })
729 }
730
731 pub fn iter_variants_with_discriminant_mut(
736 &mut self,
737 ) -> impl Iterator<Item = (i128, &mut EnumVariant)> {
738 let mut next_discriminant = 0;
739 self.variants.iter_mut().map(move |variant| {
740 if let Some(discriminant) = variant.value.specified_discriminant() {
741 next_discriminant = discriminant + 1;
742 (discriminant, variant)
743 } else {
744 let discriminant = next_discriminant;
745 next_discriminant += 1;
746 (discriminant, variant)
747 }
748 })
749 }
750}
751
752#[derive(Debug, Clone, PartialEq, Eq, Hash)]
753pub enum EnumGenerationStyle {
754 Fallible,
756 InfallibleWithinRange,
759 Fallback,
761}
762
763impl EnumGenerationStyle {
764 #[must_use]
768 pub fn is_fallible(&self) -> bool {
769 matches!(self, Self::Fallible)
770 }
771}
772
773#[derive(Debug, Clone, Default, PartialEq)]
774pub struct EnumVariant {
775 pub description: String,
776 pub name: Spanned<Identifier<Local>>,
777 pub value: EnumValue,
778 pub span: Span,
780}
781
782#[derive(Debug, Clone, PartialEq, Eq, Default, Hash)]
783pub enum EnumValue {
784 #[default]
785 Unspecified,
786 Specified(i128),
787 Default(i128),
788 UnspecifiedDefault,
789 CatchAll(i128),
790 UnspecifiedCatchAll,
791}
792
793impl EnumValue {
794 #[must_use]
795 pub fn is_default(&self) -> bool {
796 matches!(self, Self::Default(_) | Self::UnspecifiedDefault)
797 }
798
799 #[must_use]
800 pub fn is_catch_all(&self) -> bool {
801 matches!(self, Self::CatchAll(_) | Self::UnspecifiedCatchAll)
802 }
803
804 pub fn specified_discriminant(&self) -> Option<i128> {
805 match self {
806 Self::Unspecified | Self::UnspecifiedDefault | Self::UnspecifiedCatchAll => None,
807 Self::Specified(val) | EnumValue::Default(val) | EnumValue::CatchAll(val) => Some(*val),
808 }
809 }
810
811 pub fn specify(&mut self, num: i128) {
812 *self = match self {
813 EnumValue::Unspecified | EnumValue::Specified(_) => Self::Specified(num),
814 EnumValue::Default(_) | EnumValue::UnspecifiedDefault => Self::Default(num),
815 EnumValue::CatchAll(_) | EnumValue::UnspecifiedCatchAll => Self::CatchAll(num),
816 };
817 }
818}
819
820#[derive(Debug, Clone, Default, PartialEq)]
821pub struct Command {
822 pub description: String,
823 pub name: Spanned<Identifier<Operation>>,
824 pub address: Spanned<i128>,
825 pub allow_address_overlap: bool,
826 pub repeat: Option<Repeat>,
827
828 pub field_set_ref_in: Option<Spanned<IdentifierRef<Type>>>,
829 pub field_set_ref_out: Option<Spanned<IdentifierRef<Type>>>,
830
831 pub short_properties_span: Span,
832 pub properties_span: Option<Span>,
833 pub span: Span,
835}
836
837#[derive(Debug, Clone, Default, PartialEq)]
838pub struct Buffer {
839 pub description: String,
840 pub name: Spanned<Identifier<Operation>>,
841 pub access: Option<Access>,
842 pub address: Spanned<i128>,
843
844 pub short_properties_span: Span,
845 pub properties_span: Option<Span>,
846 pub span: Span,
848}
849
850#[derive(Debug, Clone, Default, PartialEq)]
851pub struct Extern {
852 pub description: String,
853 pub name: Spanned<Identifier<Type>>,
854 pub base_type: Spanned<BaseType>,
856 pub supports_infallible: bool,
858 pub size_bits: Option<Spanned<u64>>,
860
861 pub short_properties_span: Span,
862 pub properties_span: Option<Span>,
863 pub span: Span,
865}
866
867#[derive(Debug, Clone, Eq)]
868pub struct ObjectId {
869 object_name: Spanned<Identifier<RuntimeNamespace>>,
870}
871
872impl PartialEq for ObjectId {
873 fn eq(&self, other: &Self) -> bool {
874 self.object_name.original() == other.object_name.original()
875 && self.object_name.namespace() == other.object_name.namespace()
876 }
877}
878
879impl std::hash::Hash for ObjectId {
880 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
881 self.object_name.original().hash(state);
882 self.object_name.namespace().hash(state);
883 }
884}
885
886impl ObjectId {
887 #[must_use]
888 pub fn span(&self) -> Span {
889 self.object_name.span
890 }
891
892 pub fn identifier(&self) -> &Identifier<RuntimeNamespace> {
893 &self.object_name
894 }
895
896 #[cfg(test)]
898 pub fn new_test<T: Namespace>(identifier: Identifier<T>) -> Self {
899 use device_driver_common::span::SpanExt;
900
901 Self {
902 object_name: identifier.to_runtime_namespace().with_dummy_span(),
903 }
904 }
905
906 pub fn concrete_namespace_ids(
907 &self,
908 ) -> Result<impl Iterator<Item = Result<Self, DynError>>, DynError> {
909 let concretes = self.identifier().namespace().concrete_namespaces();
910
911 Ok(concretes.into_iter().map(|namespace| {
912 Ok(Self {
913 object_name: self
914 .object_name
915 .value
916 .clone()
917 .cast_concrete(namespace)
918 .with_span(self.object_name.span),
919 })
920 }))
921 }
922
923 pub fn words(&self) -> ObjectWords {
924 ObjectWords(self.object_name.words())
925 }
926}
927
928impl Display for ObjectId {
929 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
930 write!(
931 f,
932 "{} ({:?})",
933 self.object_name.original(),
934 self.object_name.namespace()
935 )
936 }
937}
938
939#[derive(Hash, PartialEq, Eq)]
940pub struct ObjectWords(Arc<[String]>);
941
942pub trait Id {
943 fn id(&self) -> ObjectId;
944 fn has_id(&self, id: &ObjectId) -> bool;
945}
946
947macro_rules! impl_unique_object {
948 ($t:ty) => {
949 impl Id for $t {
950 fn id(&self) -> ObjectId {
951 ObjectId {
952 object_name: self
953 .name
954 .value
955 .clone()
956 .to_runtime_namespace()
957 .with_span(self.name.span),
958 }
959 }
960
961 fn has_id(&self, id: &ObjectId) -> bool {
962 self.name.as_runtime_namespace() == &id.object_name.value
963 }
964 }
965 };
966}
967
968impl_unique_object!(Device);
969impl_unique_object!(Register);
970impl_unique_object!(Command);
971impl_unique_object!(Buffer);
972impl_unique_object!(Block);
973impl_unique_object!(Enum);
974impl_unique_object!(FieldSet);
975impl_unique_object!(Extern);
976impl_unique_object!(Field);
977impl_unique_object!(EnumVariant);
978
979impl Id for Object {
980 fn id(&self) -> ObjectId {
981 match self {
982 Object::Device(val) => val.id(),
983 Object::Block(val) => val.id(),
984 Object::Register(val) => val.id(),
985 Object::Command(val) => val.id(),
986 Object::Buffer(val) => val.id(),
987 Object::FieldSet(val) => val.id(),
988 Object::Enum(val) => val.id(),
989 Object::Extern(val) => val.id(),
990 Object::Field(_) => unimplemented!(),
992 }
993 }
994
995 fn has_id(&self, id: &ObjectId) -> bool {
996 match self {
997 Object::Device(val) => val.has_id(id),
998 Object::Block(val) => val.has_id(id),
999 Object::Register(val) => val.has_id(id),
1000 Object::Command(val) => val.has_id(id),
1001 Object::Buffer(val) => val.has_id(id),
1002 Object::FieldSet(val) => val.has_id(id),
1003 Object::Enum(val) => val.has_id(id),
1004 Object::Extern(val) => val.has_id(id),
1005 Object::Field(_) => unimplemented!(),
1007 }
1008 }
1009}
1010
1011#[cfg(test)]
1012mod tests {
1013 use device_driver_common::span::SpanExt;
1014
1015 use super::*;
1016
1017 #[test]
1018 fn iter_works() {
1019 const NAME_ORDER: &[&str] = &["a", "b", "c", "d"];
1020
1021 let mut manifest = Manifest {
1022 description: Default::default(),
1023 name: Default::default(),
1024 objects: vec![
1025 Object::Device(Device {
1026 description: String::new(),
1027 name: Identifier::try_parse("a").unwrap().with_dummy_span(),
1028 objects: vec![
1029 Object::Extern(Extern {
1030 name: Identifier::try_parse("b").unwrap().with_dummy_span(),
1031 ..Default::default()
1032 }),
1033 Object::Extern(Extern {
1034 name: Identifier::try_parse("c").unwrap().with_dummy_span(),
1035 ..Default::default()
1036 }),
1037 ],
1038 ..Default::default()
1039 }),
1040 Object::Extern(Extern {
1041 name: Identifier::try_parse("d").unwrap().with_dummy_span(),
1042 ..Default::default()
1043 }),
1044 ],
1045 ..Default::default()
1046 };
1047
1048 let names: Vec<_> = manifest
1049 .iter_objects()
1050 .map(|o| o.name().original())
1051 .collect();
1052 assert_eq!(&names, NAME_ORDER);
1053
1054 let mut names = Vec::new();
1055 let mut lender = manifest.iter_objects_with_config_mut();
1056 while let Some((object, _)) = lender.next() {
1057 names.push(object.name().original().to_string());
1058 }
1059 assert_eq!(&names, NAME_ORDER);
1060 }
1061
1062 #[test]
1063 fn correct_integer_size_bits() {
1064 assert_eq!(Integer::U8.bits_required(0, 0), 0);
1065 assert_eq!(Integer::U8.bits_required(0, 1), 1);
1066 assert_eq!(Integer::U8.bits_required(0, 2), 2);
1067 assert_eq!(Integer::U8.bits_required(0, 3), 2);
1068 assert_eq!(Integer::U8.bits_required(0, 4), 3);
1069
1070 assert_eq!(Integer::I8.bits_required(0, 0), 0);
1071 assert_eq!(Integer::I8.bits_required(-1, 0), 1);
1072 assert_eq!(Integer::I8.bits_required(-1, 1), 2);
1073 assert_eq!(Integer::I8.bits_required(0, 1), 2);
1074 assert_eq!(Integer::I8.bits_required(-2, 1), 2);
1075 assert_eq!(Integer::I8.bits_required(0, 2), 3);
1076 assert_eq!(Integer::I8.bits_required(-128, 0), 8);
1077 assert_eq!(Integer::I8.bits_required(-129, 0), 9);
1078 assert_eq!(Integer::I8.bits_required(0, 127), 8);
1079 assert_eq!(Integer::I8.bits_required(0, 128), 9);
1080 assert_eq!(Integer::I8.bits_required(-16, 15), 5);
1081 assert_eq!(Integer::I8.bits_required(-16, 16), 6);
1082 assert_eq!(Integer::I8.bits_required(-17, 15), 6);
1083 }
1084}