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