Skip to main content

device_driver_mir/
model.rs

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
97/// A GAT based lending iterator.
98/// Can't do anything fancy with it yet though.
99pub 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                    // continue with the parent node
118                    *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                    // continue with the parent node
182                    *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
226/// Implementation meant for testing to easily create a manifest with just one device
227impl 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    /// Span of the whole object
260    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            // Note: We can't give the config from here because there might be a config in the manifest we don't know about
270            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    /// The id of the device that owns this config. If None, then this is a manifest config
279    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    /// Get a mutable reference to the name of the specific object
353    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    /// Get a reference to the name of the specific object
368    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    /// Get the span of the name of the object
383    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    /// Return the address if it is specified.
398    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    /// Return the repeat value if it exists
413    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    /// Return the repeat value if it exists
428    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    /// The span of the entire object
481    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    /// Get the fieldset refs of the object. Only returns non-zero for registers and commands
510    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    /// Span of the whole object
554    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            // Note: We can't give the config from here because there might be a config in the manifest we don't know about
564            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    /// Span of the whole object
584    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    /// Span of the whole object
600    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    /// Span of the whole object
622    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    /// Span of the whole object
654    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    /// Get an iterator over the variants, but with an extra counter to get the specified discriminant for each.
704    ///
705    /// *Note:* The validity of this is checked in the [`passes::enum_values_checked`] pass. If this function is run
706    /// before that pass, there might be weird results.
707    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    /// Get an iterator over the variants, but with an extra counter to get the specified discriminant for each.
722    ///
723    /// *Note:* The validity of this is checked in the [`passes::enum_values_checked`] pass. If this function is run
724    /// before that pass, there might be weird results.
725    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    /// Not all basetype values can be converted to a variant
745    Fallible,
746    /// All bitpatterns within bits 0..size-bits are covered.
747    /// The general interface is fallible, but this special knowledge can be used for safety guarantees
748    InfallibleWithinRange,
749    /// There's a fallback, so it's always safe
750    Fallback,
751}
752
753impl EnumGenerationStyle {
754    /// Returns `true` if the enum generation style is [`Fallible`].
755    ///
756    /// [`Fallible`]: EnumGenerationStyle::Fallible
757    #[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    /// Span of the whole object
769    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    /// Span of the whole object
824    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    /// Span of the whole object
837    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    /// From/into what base type can this extern be converted?
845    pub base_type: Spanned<BaseType>,
846    /// If true, this extern can be converted infallibly too
847    pub supports_infallible: bool,
848    /// The user-specified size of the max value of the base type that should be expected
849    pub size_bits: Option<Spanned<u64>>,
850
851    pub short_properties_span: Span,
852    pub properties_span: Option<Span>,
853    /// Span of the whole object
854    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    /// *Only for tests:* Create a new instance with a dummy span.
891    #[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            // Special
1039            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            // Special
1058            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}