Skip to main content

device_driver_mir/
model.rs

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