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 address_offset: Spanned<i128>,
255    pub device_config: DeviceConfig,
256    pub objects: Vec<Object>,
257
258    pub short_properties_span: Span,
259    pub properties_span: Option<Span>,
260    /// Span of the whole object
261    pub span: Span,
262}
263
264impl Device {
265    pub fn iter_objects(&self) -> impl Iterator<Item = &Object> {
266        ObjectIter {
267            children: &self.objects,
268            parent: None,
269            collection_object_returned: false,
270            // Note: We can't give the config from here because there might be a config in the manifest we don't know about
271            current_device_config: Rc::new(DeviceConfig::default()),
272        }
273        .map(|(object, _)| object)
274    }
275}
276
277#[derive(Debug, Clone, Default, PartialEq)]
278pub struct DeviceConfig {
279    /// The id of the device that owns this config. If None, then this is a manifest config
280    pub owner: Option<UniqueId>,
281    pub byte_order: Option<ByteOrder>,
282    pub register_address_type: Option<Spanned<Integer>>,
283    pub command_address_type: Option<Spanned<Integer>>,
284    pub buffer_address_type: Option<Spanned<Integer>>,
285    pub name_word_boundaries: Option<Vec<Boundary>>,
286    pub register_address_mode: Option<Spanned<AddressMode>>,
287}
288
289impl DeviceConfig {
290    #[must_use]
291    pub fn override_with(&self, other: &Self) -> DeviceConfig {
292        Self {
293            owner: other.owner.clone().or(self.owner.clone()),
294            byte_order: other.byte_order.or(self.byte_order),
295            register_address_type: other.register_address_type.or(self.register_address_type),
296            command_address_type: other.command_address_type.or(self.command_address_type),
297            buffer_address_type: other.buffer_address_type.or(self.buffer_address_type),
298            name_word_boundaries: other
299                .name_word_boundaries
300                .as_ref()
301                .or(self.name_word_boundaries.as_ref())
302                .cloned(),
303            register_address_mode: other.register_address_mode.or(self.register_address_mode),
304        }
305    }
306}
307
308#[derive(Debug, Clone, PartialEq)]
309pub enum Object {
310    Device(Device),
311    Block(Block),
312    Register(Register),
313    Command(Command),
314    Buffer(Buffer),
315    FieldSet(FieldSet),
316    Enum(Enum),
317    Extern(Extern),
318    Field(Field),
319}
320
321impl Object {
322    pub fn device_config(&self) -> Option<&DeviceConfig> {
323        match self {
324            Object::Device(device) => Some(&device.device_config),
325            _ => None,
326        }
327    }
328
329    pub fn child_objects_mut(&mut self) -> &mut [Object] {
330        match self {
331            Object::Device(device) => &mut device.objects,
332            Object::Block(block) => &mut block.objects,
333            _ => &mut [],
334        }
335    }
336
337    pub fn child_objects_vec(&mut self) -> Option<&mut Vec<Object>> {
338        match self {
339            Object::Device(device) => Some(&mut device.objects),
340            Object::Block(block) => Some(&mut block.objects),
341            _ => None,
342        }
343    }
344
345    pub fn child_objects(&self) -> &[Object] {
346        match self {
347            Object::Device(device) => &device.objects,
348            Object::Block(block) => &block.objects,
349            _ => &[],
350        }
351    }
352
353    /// Get a mutable reference to the name of the specific object
354    pub fn name_mut(&mut self) -> &mut Identifier<RuntimeType> {
355        match self {
356            Object::Device(val) => val.name.as_runtime_type_mut(),
357            Object::Block(val) => val.name.as_runtime_type_mut(),
358            Object::Register(val) => val.name.as_runtime_type_mut(),
359            Object::Command(val) => val.name.as_runtime_type_mut(),
360            Object::Buffer(val) => val.name.as_runtime_type_mut(),
361            Object::FieldSet(val) => val.name.as_runtime_type_mut(),
362            Object::Enum(val) => val.name.as_runtime_type_mut(),
363            Object::Extern(val) => val.name.as_runtime_type_mut(),
364            Object::Field(val) => val.name.as_runtime_type_mut(),
365        }
366    }
367
368    /// Get a reference to the name of the specific object
369    pub fn name(&self) -> &Identifier<RuntimeType> {
370        match self {
371            Object::Device(val) => val.name.as_runtime_type(),
372            Object::Block(val) => val.name.as_runtime_type(),
373            Object::Register(val) => val.name.as_runtime_type(),
374            Object::Command(val) => val.name.as_runtime_type(),
375            Object::Buffer(val) => val.name.as_runtime_type(),
376            Object::FieldSet(val) => val.name.as_runtime_type(),
377            Object::Enum(val) => val.name.as_runtime_type(),
378            Object::Extern(val) => val.name.as_runtime_type(),
379            Object::Field(val) => val.name.as_runtime_type(),
380        }
381    }
382
383    /// Get the span of the name of the object
384    pub fn name_span(&self) -> Span {
385        match self {
386            Object::Device(val) => val.name.span,
387            Object::Block(val) => val.name.span,
388            Object::Register(val) => val.name.span,
389            Object::Command(val) => val.name.span,
390            Object::Buffer(val) => val.name.span,
391            Object::FieldSet(val) => val.name.span,
392            Object::Enum(val) => val.name.span,
393            Object::Extern(val) => val.name.span,
394            Object::Field(val) => val.name.span,
395        }
396    }
397
398    /// Return the address if it is specified.
399    pub fn address(&self) -> Option<Spanned<i128>> {
400        match self {
401            Object::Device(device) => Some(device.address_offset),
402            Object::Block(block) => Some(block.address_offset),
403            Object::Register(register) => Some(register.address),
404            Object::Command(command) => Some(command.address),
405            Object::Buffer(buffer) => Some(buffer.address),
406            Object::FieldSet(_) => None,
407            Object::Enum(_) => None,
408            Object::Extern(_) => None,
409            Object::Field(_) => None,
410        }
411    }
412
413    /// Return the repeat value if it exists
414    pub fn repeat(&self) -> Option<&Repeat> {
415        match self {
416            Object::Device(_) => None,
417            Object::Block(block) => block.repeat.as_ref(),
418            Object::Register(register) => register.repeat.as_ref(),
419            Object::Command(command) => command.repeat.as_ref(),
420            Object::Buffer(_) => None,
421            Object::FieldSet(_) => None,
422            Object::Enum(_) => None,
423            Object::Extern(_) => None,
424            Object::Field(field) => field.repeat.as_ref(),
425        }
426    }
427
428    /// Return the repeat value if it exists
429    pub fn repeat_mut(&mut self) -> Option<&mut Repeat> {
430        match self {
431            Object::Device(_) => None,
432            Object::Block(block) => block.repeat.as_mut(),
433            Object::Register(register) => register.repeat.as_mut(),
434            Object::Command(command) => command.repeat.as_mut(),
435            Object::Buffer(_) => None,
436            Object::FieldSet(_) => None,
437            Object::Enum(_) => None,
438            Object::Extern(_) => None,
439            Object::Field(field) => field.repeat.as_mut(),
440        }
441    }
442
443    pub fn as_field_set(&self) -> Option<&FieldSet> {
444        if let Self::FieldSet(v) = self {
445            Some(v)
446        } else {
447            None
448        }
449    }
450
451    pub fn as_field_set_mut(&mut self) -> Option<&mut FieldSet> {
452        if let Self::FieldSet(v) = self {
453            Some(v)
454        } else {
455            None
456        }
457    }
458
459    pub fn as_enum(&self) -> Option<&Enum> {
460        if let Self::Enum(v) = self {
461            Some(v)
462        } else {
463            None
464        }
465    }
466
467    pub fn allow_address_overlap(&self) -> bool {
468        match self {
469            Object::Device(_) => false,
470            Object::Block(_) => false,
471            Object::Register(register) => register.allow_address_overlap,
472            Object::Command(command) => command.allow_address_overlap,
473            Object::Buffer(_) => false,
474            Object::FieldSet(_) => false,
475            Object::Enum(_) => false,
476            Object::Extern(_) => false,
477            Object::Field(_) => false,
478        }
479    }
480
481    /// The span of the entire object
482    pub fn span(&self) -> Span {
483        match self {
484            Object::Device(val) => val.span,
485            Object::Block(val) => val.span,
486            Object::Register(val) => val.span,
487            Object::Command(val) => val.span,
488            Object::Buffer(val) => val.span,
489            Object::FieldSet(val) => val.span,
490            Object::Enum(val) => val.span,
491            Object::Extern(val) => val.span,
492            Object::Field(val) => val.span,
493        }
494    }
495
496    pub fn node_type(&self) -> NodeType {
497        match self {
498            Object::Device(_) => NodeType::Device,
499            Object::Block(_) => NodeType::Block,
500            Object::Register(_) => NodeType::Register,
501            Object::Command(_) => NodeType::Command,
502            Object::Buffer(_) => NodeType::Buffer,
503            Object::FieldSet(_) => NodeType::FieldSet,
504            Object::Enum(_) => NodeType::Enum,
505            Object::Extern(_) => NodeType::Extern,
506            Object::Field(_) => NodeType::Field,
507        }
508    }
509
510    /// Get the fieldset refs of the object. Only returns non-zero for registers and commands
511    pub fn fieldset_refs(&self) -> Vec<Spanned<IdentifierRef<Type>>> {
512        match self {
513            Object::Device(_) => Vec::new(),
514            Object::Block(_) => Vec::new(),
515            Object::Register(r) => vec![r.field_set_ref.clone()],
516            Object::Command(c) => [c.field_set_ref_in.clone(), c.field_set_ref_out.clone()]
517                .into_iter()
518                .flatten()
519                .collect(),
520            Object::Buffer(_) => Vec::new(),
521            Object::FieldSet(_) => Vec::new(),
522            Object::Enum(_) => Vec::new(),
523            Object::Extern(_) => Vec::new(),
524            Object::Field(_) => Vec::new(),
525        }
526    }
527
528    pub fn properties_span(&self) -> Option<Span> {
529        match self {
530            Object::Device(val) => val.properties_span,
531            Object::Block(val) => val.properties_span,
532            Object::Register(val) => val.properties_span,
533            Object::Command(val) => val.properties_span,
534            Object::Buffer(val) => val.properties_span,
535            Object::FieldSet(val) => val.properties_span,
536            Object::Enum(val) => val.properties_span,
537            Object::Extern(val) => val.properties_span,
538            Object::Field(val) => val.properties_span,
539        }
540    }
541}
542
543#[derive(Debug, Clone, Default, PartialEq)]
544pub struct Block {
545    pub description: String,
546    pub name: Spanned<Identifier<All>>,
547    pub address_offset: Spanned<i128>,
548    pub repeat: Option<Repeat>,
549    pub objects: Vec<Object>,
550    pub default_access: Option<Access>,
551
552    pub short_properties_span: Span,
553    pub properties_span: Option<Span>,
554    /// Span of the whole object
555    pub span: Span,
556}
557
558impl Block {
559    pub fn iter_objects(&self) -> impl Iterator<Item = &Object> {
560        ObjectIter {
561            children: &self.objects,
562            parent: None,
563            collection_object_returned: false,
564            // Note: We can't give the config from here because there might be a config in the manifest we don't know about
565            current_device_config: Rc::new(DeviceConfig::default()),
566        }
567        .map(|(object, _)| object)
568    }
569}
570
571#[derive(Debug, Clone, Default, PartialEq)]
572pub struct Register {
573    pub description: String,
574    pub name: Spanned<Identifier<Operation>>,
575    pub access: Option<Access>,
576    pub allow_address_overlap: bool,
577    pub address: Spanned<i128>,
578    pub reset_value: Option<Spanned<ResetValue>>,
579    pub repeat: Option<Repeat>,
580    pub field_set_ref: Spanned<IdentifierRef<Type>>,
581
582    pub short_properties_span: Span,
583    pub properties_span: Option<Span>,
584    /// Span of the whole object
585    pub span: Span,
586}
587
588#[derive(Debug, Clone, Default, PartialEq)]
589pub struct FieldSet {
590    pub description: String,
591    pub name: Spanned<Identifier<Type>>,
592    pub size_bytes: Spanned<u32>,
593    pub byte_order: Option<ByteOrder>,
594    pub allow_bit_overlap: bool,
595    pub default_access: Option<Access>,
596    pub fields: Vec<Field>,
597
598    pub short_properties_span: Span,
599    pub properties_span: Option<Span>,
600    /// Span of the whole object
601    pub span: Span,
602}
603
604impl FieldSet {
605    pub fn size_bits(&self) -> u32 {
606        self.size_bytes.value * 8
607    }
608}
609
610#[derive(Debug, Clone, Default, PartialEq)]
611pub struct Field {
612    pub description: String,
613    pub name: Spanned<Identifier<All>>,
614    pub access: Option<Access>,
615    pub base_type: Spanned<BaseType>,
616    pub field_conversion: Option<TypeConversion>,
617    pub field_address: Spanned<AddressRange>,
618    pub repeat: Option<Repeat>,
619
620    pub short_properties_span: Span,
621    pub properties_span: Option<Span>,
622    /// Span of the whole object
623    pub span: Span,
624}
625
626impl Field {
627    #[must_use]
628    pub fn get_type_specifier_string(&self) -> String {
629        match &self.field_conversion {
630            Some(fc) => {
631                format!(
632                    "{}:{}{}",
633                    self.base_type,
634                    fc.type_name.original(),
635                    if fc.fallible { "?" } else { "" }
636                )
637            }
638            None => self.base_type.to_string(),
639        }
640    }
641}
642
643#[derive(Debug, Clone, Default, PartialEq)]
644pub struct Enum {
645    pub description: String,
646    pub name: Spanned<Identifier<Type>>,
647    pub variants: Vec<EnumVariant>,
648    pub base_type: Spanned<BaseType>,
649    pub size_bits: Option<u32>,
650    pub generation_style: Option<EnumGenerationStyle>,
651
652    pub short_properties_span: Span,
653    pub properties_span: Option<Span>,
654    /// Span of the whole object
655    pub span: Span,
656}
657
658impl Enum {
659    #[cfg(test)]
660    pub fn new(
661        description: String,
662        name: Spanned<Identifier<Type>>,
663        variants: Vec<EnumVariant>,
664        base_type: Spanned<BaseType>,
665        size_bits: Option<u32>,
666        span: Span,
667    ) -> Self {
668        Self {
669            description,
670            name,
671            variants,
672            base_type,
673            size_bits,
674            generation_style: None,
675            short_properties_span: Span::empty(),
676            properties_span: None,
677            span,
678        }
679    }
680
681    #[cfg(test)]
682    pub fn new_with_style(
683        description: String,
684        name: Spanned<Identifier<Type>>,
685        variants: Vec<EnumVariant>,
686        base_type: Spanned<BaseType>,
687        size_bits: Option<u32>,
688        generation_style: EnumGenerationStyle,
689        span: Span,
690    ) -> Self {
691        Self {
692            description,
693            name,
694            variants,
695            base_type,
696            size_bits,
697            generation_style: Some(generation_style),
698            short_properties_span: Span::empty(),
699            properties_span: None,
700            span,
701        }
702    }
703
704    /// Get an iterator over the variants, but with an extra counter to get the specified discriminant for each.
705    ///
706    /// *Note:* The validity of this is checked in the [`passes::enum_values_checked`] pass. If this function is run
707    /// before that pass, there might be weird results.
708    pub fn iter_variants_with_discriminant(&self) -> impl Iterator<Item = (i128, &EnumVariant)> {
709        let mut next_discriminant = 0;
710        self.variants.iter().map(move |variant| {
711            if let Some(discriminant) = variant.value.specified_discriminant() {
712                next_discriminant = discriminant + 1;
713                (discriminant, variant)
714            } else {
715                let discriminant = next_discriminant;
716                next_discriminant += 1;
717                (discriminant, variant)
718            }
719        })
720    }
721
722    /// Get an iterator over the variants, but with an extra counter to get the specified discriminant for each.
723    ///
724    /// *Note:* The validity of this is checked in the [`passes::enum_values_checked`] pass. If this function is run
725    /// before that pass, there might be weird results.
726    pub fn iter_variants_with_discriminant_mut(
727        &mut self,
728    ) -> impl Iterator<Item = (i128, &mut EnumVariant)> {
729        let mut next_discriminant = 0;
730        self.variants.iter_mut().map(move |variant| {
731            if let Some(discriminant) = variant.value.specified_discriminant() {
732                next_discriminant = discriminant + 1;
733                (discriminant, variant)
734            } else {
735                let discriminant = next_discriminant;
736                next_discriminant += 1;
737                (discriminant, variant)
738            }
739        })
740    }
741}
742
743#[derive(Debug, Clone, PartialEq, Eq, Hash)]
744pub enum EnumGenerationStyle {
745    /// Not all basetype values can be converted to a variant
746    Fallible,
747    /// All bitpatterns within bits 0..size-bits are covered.
748    /// The general interface is fallible, but this special knowledge can be used for safety guarantees
749    InfallibleWithinRange,
750    /// There's a fallback, so it's always safe
751    Fallback,
752}
753
754impl EnumGenerationStyle {
755    /// Returns `true` if the enum generation style is [`Fallible`].
756    ///
757    /// [`Fallible`]: EnumGenerationStyle::Fallible
758    #[must_use]
759    pub fn is_fallible(&self) -> bool {
760        matches!(self, Self::Fallible)
761    }
762}
763
764#[derive(Debug, Clone, Default, PartialEq)]
765pub struct EnumVariant {
766    pub description: String,
767    pub name: Spanned<Identifier<All>>,
768    pub value: EnumValue,
769    /// Span of the whole object
770    pub span: Span,
771}
772
773#[derive(Debug, Clone, PartialEq, Eq, Default, Hash)]
774pub enum EnumValue {
775    #[default]
776    Unspecified,
777    Specified(i128),
778    Default(i128),
779    UnspecifiedDefault,
780    CatchAll(i128),
781    UnspecifiedCatchAll,
782}
783
784impl EnumValue {
785    #[must_use]
786    pub fn is_default(&self) -> bool {
787        matches!(self, Self::Default(_) | Self::UnspecifiedDefault)
788    }
789
790    #[must_use]
791    pub fn is_catch_all(&self) -> bool {
792        matches!(self, Self::CatchAll(_) | Self::UnspecifiedCatchAll)
793    }
794
795    pub fn specified_discriminant(&self) -> Option<i128> {
796        match self {
797            Self::Unspecified | Self::UnspecifiedDefault | Self::UnspecifiedCatchAll => None,
798            Self::Specified(val) | EnumValue::Default(val) | EnumValue::CatchAll(val) => Some(*val),
799        }
800    }
801
802    pub fn specify(&mut self, num: i128) {
803        *self = match self {
804            EnumValue::Unspecified | EnumValue::Specified(_) => Self::Specified(num),
805            EnumValue::Default(_) | EnumValue::UnspecifiedDefault => Self::Default(num),
806            EnumValue::CatchAll(_) | EnumValue::UnspecifiedCatchAll => Self::CatchAll(num),
807        };
808    }
809}
810
811#[derive(Debug, Clone, Default, PartialEq)]
812pub struct Command {
813    pub description: String,
814    pub name: Spanned<Identifier<Operation>>,
815    pub address: Spanned<i128>,
816    pub allow_address_overlap: bool,
817    pub repeat: Option<Repeat>,
818
819    pub field_set_ref_in: Option<Spanned<IdentifierRef<Type>>>,
820    pub field_set_ref_out: Option<Spanned<IdentifierRef<Type>>>,
821
822    pub short_properties_span: Span,
823    pub properties_span: Option<Span>,
824    /// Span of the whole object
825    pub span: Span,
826}
827
828#[derive(Debug, Clone, Default, PartialEq)]
829pub struct Buffer {
830    pub description: String,
831    pub name: Spanned<Identifier<Operation>>,
832    pub access: Option<Access>,
833    pub address: Spanned<i128>,
834
835    pub short_properties_span: Span,
836    pub properties_span: Option<Span>,
837    /// Span of the whole object
838    pub span: Span,
839}
840
841#[derive(Debug, Clone, Default, PartialEq)]
842pub struct Extern {
843    pub description: String,
844    pub name: Spanned<Identifier<Type>>,
845    /// From/into what base type can this extern be converted?
846    pub base_type: Spanned<BaseType>,
847    /// If true, this extern can be converted infallibly too
848    pub supports_infallible: bool,
849    /// The user-specified size of the max value of the base type that should be expected
850    pub size_bits: Option<Spanned<u64>>,
851
852    pub short_properties_span: Span,
853    pub properties_span: Option<Span>,
854    /// Span of the whole object
855    pub span: Span,
856}
857
858#[derive(Debug, Clone, Hash, PartialEq, Eq)]
859pub enum UniqueId {
860    Object {
861        object_name: Spanned<Identifier<RuntimeType>>,
862    },
863    Field {
864        parent_id: Box<UniqueId>,
865        field_name: Spanned<Identifier<RuntimeType>>,
866    },
867    Variant {
868        parent_id: Box<UniqueId>,
869        variant_name: Spanned<Identifier<RuntimeType>>,
870    },
871}
872
873impl UniqueId {
874    #[must_use]
875    pub fn span(&self) -> Span {
876        match self {
877            UniqueId::Object { object_name } => object_name.span,
878            UniqueId::Field { field_name, .. } => field_name.span,
879            UniqueId::Variant { variant_name, .. } => variant_name.span,
880        }
881    }
882
883    pub fn identifier(&self) -> &Identifier<RuntimeType> {
884        match self {
885            UniqueId::Object { object_name } => object_name,
886            UniqueId::Field { field_name, .. } => field_name,
887            UniqueId::Variant { variant_name, .. } => variant_name,
888        }
889    }
890
891    /// *Only for tests:* Create a new instance with a dummy span.
892    #[cfg(test)]
893    pub fn new_test<T: IdentifierType>(identifier: Identifier<T>) -> Self {
894        use device_driver_common::span::SpanExt;
895
896        Self::Object {
897            object_name: identifier.to_runtime_type().with_dummy_span(),
898        }
899    }
900}
901
902impl Display for UniqueId {
903    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
904        match self {
905            UniqueId::Object { object_name } => write!(f, "{}", object_name.original()),
906            UniqueId::Field {
907                parent_id,
908                field_name,
909            } => write!(f, "{parent_id} {{ {} }}", field_name.original()),
910            UniqueId::Variant {
911                parent_id,
912                variant_name,
913            } => write!(f, "{parent_id} {{ {} }}", variant_name.original()),
914        }
915    }
916}
917
918pub trait Unique {
919    type Metadata;
920
921    fn id(&self) -> UniqueId
922    where
923        Self::Metadata: Empty;
924    fn id_with(&self, meta: Self::Metadata) -> UniqueId;
925
926    fn has_id(&self, id: &UniqueId) -> bool
927    where
928        Self::Metadata: Empty;
929    fn has_id_with(&self, meta: Self::Metadata, id: &UniqueId) -> bool {
930        self.id_with(meta) == *id
931    }
932}
933
934pub trait Empty {}
935impl Empty for () {}
936
937macro_rules! impl_unique_object {
938    ($t:ty) => {
939        impl Unique for $t {
940            type Metadata = ();
941
942            fn id(&self) -> UniqueId {
943                UniqueId::Object {
944                    object_name: self
945                        .name
946                        .value
947                        .clone()
948                        .to_runtime_type()
949                        .with_span(self.name.span),
950                }
951            }
952
953            fn id_with(&self, _: Self::Metadata) -> UniqueId {
954                self.id()
955            }
956
957            fn has_id(&self, id: &UniqueId) -> bool {
958                match id {
959                    UniqueId::Object { object_name } => {
960                        self.name.as_runtime_type() == &object_name.value
961                    }
962                    _ => false,
963                }
964            }
965        }
966    };
967}
968
969impl_unique_object!(Device);
970impl_unique_object!(Register);
971impl_unique_object!(Command);
972impl_unique_object!(Buffer);
973impl_unique_object!(Block);
974impl_unique_object!(Enum);
975impl_unique_object!(FieldSet);
976impl_unique_object!(Extern);
977
978impl Unique for Field {
979    type Metadata = UniqueId;
980
981    fn id(&self) -> UniqueId {
982        unreachable!()
983    }
984
985    fn id_with(&self, parent: Self::Metadata) -> UniqueId {
986        UniqueId::Field {
987            parent_id: Box::new(parent),
988            field_name: self
989                .name
990                .value
991                .clone()
992                .to_runtime_type()
993                .with_span(self.name.span),
994        }
995    }
996
997    fn has_id(&self, _id: &UniqueId) -> bool {
998        unreachable!()
999    }
1000}
1001
1002impl Unique for EnumVariant {
1003    type Metadata = UniqueId;
1004
1005    fn id(&self) -> UniqueId {
1006        unreachable!()
1007    }
1008
1009    fn id_with(&self, parent: Self::Metadata) -> UniqueId {
1010        UniqueId::Variant {
1011            parent_id: Box::new(parent),
1012            variant_name: self
1013                .name
1014                .value
1015                .clone()
1016                .to_runtime_type()
1017                .with_span(self.name.span),
1018        }
1019    }
1020
1021    fn has_id(&self, _id: &UniqueId) -> bool {
1022        unreachable!()
1023    }
1024}
1025
1026impl Unique for Object {
1027    type Metadata = ();
1028
1029    fn id(&self) -> UniqueId {
1030        match self {
1031            Object::Device(val) => val.id(),
1032            Object::Block(val) => val.id(),
1033            Object::Register(val) => val.id(),
1034            Object::Command(val) => val.id(),
1035            Object::Buffer(val) => val.id(),
1036            Object::FieldSet(val) => val.id(),
1037            Object::Enum(val) => val.id(),
1038            Object::Extern(val) => val.id(),
1039            // Special
1040            Object::Field(_) => unimplemented!(),
1041        }
1042    }
1043
1044    fn id_with(&self, (): Self::Metadata) -> UniqueId {
1045        self.id()
1046    }
1047
1048    fn has_id(&self, id: &UniqueId) -> bool {
1049        match self {
1050            Object::Device(val) => val.has_id(id),
1051            Object::Block(val) => val.has_id(id),
1052            Object::Register(val) => val.has_id(id),
1053            Object::Command(val) => val.has_id(id),
1054            Object::Buffer(val) => val.has_id(id),
1055            Object::FieldSet(val) => val.has_id(id),
1056            Object::Enum(val) => val.has_id(id),
1057            Object::Extern(val) => val.has_id(id),
1058            // Special
1059            Object::Field(_) => unimplemented!(),
1060        }
1061    }
1062}
1063
1064#[cfg(test)]
1065mod tests {
1066    use device_driver_common::span::SpanExt;
1067
1068    use super::*;
1069
1070    #[test]
1071    fn iter_works() {
1072        const NAME_ORDER: &[&str] = &["a", "b", "c", "d"];
1073
1074        let mut manifest = Manifest {
1075            description: Default::default(),
1076            name: Default::default(),
1077            objects: vec![
1078                Object::Device(Device {
1079                    description: String::new(),
1080                    name: Identifier::try_parse("a").unwrap().with_dummy_span(),
1081                    objects: vec![
1082                        Object::Extern(Extern {
1083                            name: Identifier::try_parse("b").unwrap().with_dummy_span(),
1084                            ..Default::default()
1085                        }),
1086                        Object::Extern(Extern {
1087                            name: Identifier::try_parse("c").unwrap().with_dummy_span(),
1088                            ..Default::default()
1089                        }),
1090                    ],
1091                    ..Default::default()
1092                }),
1093                Object::Extern(Extern {
1094                    name: Identifier::try_parse("d").unwrap().with_dummy_span(),
1095                    ..Default::default()
1096                }),
1097            ],
1098            ..Default::default()
1099        };
1100
1101        let names: Vec<_> = manifest
1102            .iter_objects()
1103            .map(|o| o.name().original())
1104            .collect();
1105        assert_eq!(&names, NAME_ORDER);
1106
1107        let mut names = Vec::new();
1108        let mut lender = manifest.iter_objects_with_config_mut();
1109        while let Some((object, _)) = lender.next() {
1110            names.push(object.name().original().to_string());
1111        }
1112        assert_eq!(&names, NAME_ORDER);
1113    }
1114
1115    #[test]
1116    fn correct_integer_size_bits() {
1117        assert_eq!(Integer::U8.bits_required(0, 0), 0);
1118        assert_eq!(Integer::U8.bits_required(0, 1), 1);
1119        assert_eq!(Integer::U8.bits_required(0, 2), 2);
1120        assert_eq!(Integer::U8.bits_required(0, 3), 2);
1121        assert_eq!(Integer::U8.bits_required(0, 4), 3);
1122
1123        assert_eq!(Integer::I8.bits_required(0, 0), 0);
1124        assert_eq!(Integer::I8.bits_required(-1, 0), 1);
1125        assert_eq!(Integer::I8.bits_required(-1, 1), 2);
1126        assert_eq!(Integer::I8.bits_required(0, 1), 2);
1127        assert_eq!(Integer::I8.bits_required(-2, 1), 2);
1128        assert_eq!(Integer::I8.bits_required(0, 2), 3);
1129        assert_eq!(Integer::I8.bits_required(-128, 0), 8);
1130        assert_eq!(Integer::I8.bits_required(-129, 0), 9);
1131        assert_eq!(Integer::I8.bits_required(0, 127), 8);
1132        assert_eq!(Integer::I8.bits_required(0, 128), 9);
1133        assert_eq!(Integer::I8.bits_required(-16, 15), 5);
1134        assert_eq!(Integer::I8.bits_required(-16, 16), 6);
1135        assert_eq!(Integer::I8.bits_required(-17, 15), 6);
1136    }
1137}