isr_macros/
profile.rs

1use isr_core::{Profile, types::Type};
2
3use crate::{Bitfield, Error, Field, offsets::FieldDescriptor, symbols::SymbolDescriptor};
4
5pub trait ProfileExt {
6    fn find_field(&self, type_name: &str, field_name: &str) -> Option<Field>;
7    fn find_bitfield(&self, type_name: &str, field_name: &str) -> Option<Bitfield>;
8    fn find_symbol_descriptor(&self, symbol_name: &str) -> Result<SymbolDescriptor, Error>;
9    fn find_field_descriptor(
10        &self,
11        type_name: &str,
12        field_name: &str,
13    ) -> Result<FieldDescriptor, Error>;
14}
15
16impl ProfileExt for Profile<'_> {
17    fn find_field(&self, type_name: &str, field_name: &str) -> Option<Field> {
18        let udt = self.find_struct(type_name)?;
19
20        if let Some(field) = udt.fields.get(field_name) {
21            return Some(Field {
22                offset: field.offset,
23                size: self.type_size(&field.type_)?,
24            });
25        }
26
27        for field in udt.fields.values() {
28            let udt = match &field.type_ {
29                Type::Struct(udt) => udt,
30                _ => continue,
31            };
32
33            if let Some(child) = self.find_field(&udt.name, field_name) {
34                return Some(Field {
35                    offset: field.offset + child.offset,
36                    size: child.size,
37                });
38            }
39        }
40
41        None
42    }
43
44    fn find_bitfield(&self, type_name: &str, field_name: &str) -> Option<Bitfield> {
45        let udt = self.find_struct(type_name)?;
46
47        if let Some(field) = udt.fields.get(field_name) {
48            if let Type::Bitfield(bitfield) = &field.type_ {
49                return Some(Bitfield {
50                    field: Field {
51                        offset: field.offset,
52                        size: self.type_size(&field.type_)?,
53                    },
54                    bit_position: bitfield.bit_position,
55                    bit_length: bitfield.bit_length,
56                });
57            }
58        }
59
60        for field in udt.fields.values() {
61            let udt = match &field.type_ {
62                Type::Struct(udt) => udt,
63                _ => continue,
64            };
65
66            if let Some(child) = self.find_bitfield(&udt.name, field_name) {
67                return Some(Bitfield {
68                    field: Field {
69                        offset: field.offset + child.offset,
70                        size: child.size,
71                    },
72                    bit_position: child.bit_position,
73                    bit_length: child.bit_length,
74                });
75            };
76        }
77
78        None
79    }
80
81    fn find_symbol_descriptor(&self, symbol_name: &str) -> Result<SymbolDescriptor, Error> {
82        match self.find_symbol(symbol_name) {
83            Some(offset) => Ok(SymbolDescriptor { offset }),
84            None => Err(Error::symbol_not_found(symbol_name)),
85        }
86    }
87
88    fn find_field_descriptor(
89        &self,
90        type_name: &str,
91        field_name: &str,
92    ) -> Result<FieldDescriptor, Error> {
93        let udt = match self.find_struct(type_name) {
94            Some(udt) => udt,
95            None => return Err(Error::type_not_found(type_name)),
96        };
97
98        if let Some(field) = udt.fields.get(field_name) {
99            return Ok(match &field.type_ {
100                Type::Bitfield(bitfield) => FieldDescriptor::Bitfield(Bitfield {
101                    field: Field {
102                        offset: field.offset,
103                        size: match self.type_size(&field.type_) {
104                            Some(size) => size,
105                            None => {
106                                return Err(Error::field_not_found(type_name, field_name));
107                            }
108                        },
109                    },
110                    bit_position: bitfield.bit_position,
111                    bit_length: bitfield.bit_length,
112                }),
113                _ => FieldDescriptor::Field(Field {
114                    offset: field.offset,
115                    size: match self.type_size(&field.type_) {
116                        Some(size) => size,
117                        None => {
118                            return Err(Error::field_not_found(type_name, field_name));
119                        }
120                    },
121                }),
122            });
123        }
124
125        for field in udt.fields.values() {
126            let udt = match &field.type_ {
127                Type::Struct(udt) => udt,
128                _ => continue,
129            };
130
131            if let Ok(child) = self.find_field_descriptor(&udt.name, field_name) {
132                return Ok(match child {
133                    FieldDescriptor::Field(child) => FieldDescriptor::Field(Field {
134                        offset: field.offset + child.offset,
135                        size: child.size,
136                    }),
137                    FieldDescriptor::Bitfield(child) => FieldDescriptor::Bitfield(Bitfield {
138                        field: Field {
139                            offset: field.offset + child.offset,
140                            size: child.size,
141                        },
142                        bit_position: child.bit_position,
143                        bit_length: child.bit_length,
144                    }),
145                });
146            }
147        }
148
149        Err(Error::field_not_found(type_name, field_name))
150    }
151}