planus_buffer_inspection/
object_info.rs1use planus_types::intermediate::{
2 AbsolutePath, DeclarationIndex, DeclarationKind, Enum, SimpleType, Struct, Table, TypeKind,
3 Union,
4};
5
6use crate::{
7 ArrayObject, BoolObject, EnumObject, FloatObject, InspectableFlatbuffer, IntegerObject, Object,
8 OffsetObject, StringObject, StructObject, TableObject, UnionObject, UnionTagObject,
9 UnionVectorTagsObject, UnionVectorValuesObject, VTableObject, VectorObject,
10};
11
12pub trait DeclarationInfo {
13 type Declaration;
14 const KIND: &'static str;
15
16 fn declaration_index(&self) -> DeclarationIndex;
17 fn resolve_declaration<'a>(&self, buffer: &InspectableFlatbuffer<'a>) -> &'a Self::Declaration;
18 fn resolve_path<'a>(&self, buffer: &InspectableFlatbuffer<'a>) -> &'a AbsolutePath {
19 buffer
20 .declarations
21 .get_declaration(self.declaration_index())
22 .0
23 }
24}
25
26macro_rules! impl_object_name {
27 ($typ:ty) => {
28 impl<'a> ObjectName<'a> for $typ {
29 fn print_object(&self, buffer: &InspectableFlatbuffer<'_>) -> String {
30 format!("{}", self.resolve_path(buffer).0.last().unwrap())
31 }
32 }
33 };
34}
35
36pub trait ObjectName<'a> {
37 fn print_object(&self, buffer: &InspectableFlatbuffer<'a>) -> String;
38}
39
40impl DeclarationInfo for TableObject {
41 type Declaration = Table;
42 const KIND: &'static str = "table";
43
44 fn declaration_index(&self) -> DeclarationIndex {
45 self.declaration
46 }
47
48 fn resolve_declaration<'a>(&self, buffer: &InspectableFlatbuffer<'a>) -> &'a Table {
49 if let DeclarationKind::Table(decl) =
50 &buffer.declarations.get_declaration(self.declaration).1.kind
51 {
52 decl
53 } else {
54 panic!("Inconsistent declarations");
55 }
56 }
57}
58
59impl DeclarationInfo for StructObject {
60 type Declaration = Struct;
61 const KIND: &'static str = "struct";
62
63 fn declaration_index(&self) -> DeclarationIndex {
64 self.declaration
65 }
66
67 fn resolve_declaration<'a>(&self, buffer: &InspectableFlatbuffer<'a>) -> &'a Struct {
68 if let DeclarationKind::Struct(decl) =
69 &buffer.declarations.get_declaration(self.declaration).1.kind
70 {
71 decl
72 } else {
73 panic!("Inconsistent declarations");
74 }
75 }
76}
77
78impl DeclarationInfo for UnionTagObject {
79 type Declaration = Union;
80 const KIND: &'static str = "union_key";
81
82 fn declaration_index(&self) -> DeclarationIndex {
83 self.declaration
84 }
85
86 fn resolve_declaration<'a>(&self, buffer: &InspectableFlatbuffer<'a>) -> &'a Union {
87 if let DeclarationKind::Union(decl) =
88 &buffer.declarations.get_declaration(self.declaration).1.kind
89 {
90 decl
91 } else {
92 panic!("Inconsistent declarations");
93 }
94 }
95}
96
97impl DeclarationInfo for UnionObject {
98 type Declaration = Union;
99 const KIND: &'static str = "union";
100
101 fn declaration_index(&self) -> DeclarationIndex {
102 self.declaration
103 }
104
105 fn resolve_declaration<'a>(&self, buffer: &InspectableFlatbuffer<'a>) -> &'a Union {
106 if let DeclarationKind::Union(decl) =
107 &buffer.declarations.get_declaration(self.declaration).1.kind
108 {
109 decl
110 } else {
111 panic!("Inconsistent declarations");
112 }
113 }
114}
115
116impl DeclarationInfo for EnumObject {
117 type Declaration = Enum;
118 const KIND: &'static str = "enum";
119
120 fn declaration_index(&self) -> DeclarationIndex {
121 self.declaration
122 }
123
124 fn resolve_declaration<'a>(&self, buffer: &InspectableFlatbuffer<'a>) -> &'a Enum {
125 if let DeclarationKind::Enum(decl) =
126 &buffer.declarations.get_declaration(self.declaration).1.kind
127 {
128 decl
129 } else {
130 panic!("Inconsistent declarations");
131 }
132 }
133}
134
135impl DeclarationInfo for VTableObject {
136 type Declaration = Table;
137 const KIND: &'static str = "vtable";
138
139 fn declaration_index(&self) -> DeclarationIndex {
140 self.declaration
141 }
142
143 fn resolve_declaration<'a>(&self, buffer: &InspectableFlatbuffer<'a>) -> &'a Table {
144 if let DeclarationKind::Table(decl) =
145 &buffer.declarations.get_declaration(self.declaration).1.kind
146 {
147 decl
148 } else {
149 panic!("Inconsistent declarations");
150 }
151 }
152}
153
154impl<'a> ObjectName<'a> for VTableObject {
155 fn print_object(&self, buffer: &InspectableFlatbuffer<'a>) -> String {
156 let path = buffer.declarations.get_declaration(self.declaration).0;
157 let path = path.0.last().unwrap();
158 format!("vtable {path}")
159 }
160}
161
162impl<'a> ObjectName<'a> for OffsetObject<'a> {
163 fn print_object(&self, buffer: &InspectableFlatbuffer<'a>) -> String {
164 self.follow_offset(buffer).map_or_else(
165 |_| "invalid offset".to_string(),
166 |inner| inner.print_object(buffer),
167 )
168 }
169}
170
171impl<'a> ObjectName<'a> for VectorObject<'a> {
172 fn print_object(&self, buffer: &InspectableFlatbuffer<'a>) -> String {
173 let len = if let Ok(len) = self.len(buffer) {
174 len.to_string()
175 } else {
176 "?".to_string()
177 };
178
179 if let TypeKind::Table(declaration_index)
180 | TypeKind::Union(declaration_index)
181 | TypeKind::SimpleType(SimpleType::Enum(declaration_index))
182 | TypeKind::SimpleType(SimpleType::Struct(declaration_index)) = self.type_.kind
183 {
184 let (path, _) = buffer.declarations.get_declaration(declaration_index);
185 let path = path.0.last().unwrap();
186 format!("[{path}; {len}]",)
187 } else {
188 format!("[{:?}; {len}]", self.type_.kind)
189 }
190 }
191}
192
193impl<'a> ObjectName<'a> for UnionVectorTagsObject {
194 fn print_object(&self, buffer: &InspectableFlatbuffer<'a>) -> String {
195 let len = if let Ok(len) = self.len(buffer) {
196 len.to_string()
197 } else {
198 "?".to_string()
199 };
200
201 let (path, _) = buffer.declarations.get_declaration(self.declaration);
202 let path = path.0.last().unwrap();
203 format!("[{path}; {len}]",)
204 }
205}
206
207impl<'a> ObjectName<'a> for UnionVectorValuesObject {
208 fn print_object(&self, buffer: &InspectableFlatbuffer<'a>) -> String {
209 let len = if let Ok(len) = self.len(buffer) {
210 len.to_string()
211 } else {
212 "?".to_string()
213 };
214
215 let (path, _) = buffer.declarations.get_declaration(self.declaration);
216 let path = path.0.last().unwrap();
217 format!("[{path}; {len}]",)
218 }
219}
220
221impl<'a> ObjectName<'a> for ArrayObject<'a> {
222 fn print_object(&self, _buffer: &InspectableFlatbuffer<'a>) -> String {
223 "ARRAY".to_string() }
225}
226
227impl<'a> ObjectName<'a> for IntegerObject {
228 fn print_object(&self, buffer: &InspectableFlatbuffer<'a>) -> String {
229 format!("{}", self.read(buffer).unwrap())
230 }
231}
232
233impl<'a> ObjectName<'a> for FloatObject {
234 fn print_object(&self, buffer: &InspectableFlatbuffer<'a>) -> String {
235 format!("{}", self.read(buffer).unwrap())
236 }
237}
238
239impl<'a> ObjectName<'a> for BoolObject {
240 fn print_object(&self, buffer: &InspectableFlatbuffer<'a>) -> String {
241 format!("{}", self.read(buffer).unwrap())
242 }
243}
244
245impl<'a> ObjectName<'a> for StringObject {
246 fn print_object(&self, buffer: &InspectableFlatbuffer<'a>) -> String {
247 format!(
248 "{:?} (len={})",
249 String::from_utf8_lossy(self.bytes(buffer).unwrap()),
250 self.len(buffer).unwrap()
251 )
252 }
253}
254
255impl<'a> ObjectName<'a> for EnumObject {
256 fn print_object(&self, buffer: &InspectableFlatbuffer<'a>) -> String {
257 let tag = self.tag(buffer).unwrap();
258 let (path, decl) = buffer
259 .declarations
260 .get_declaration(self.declaration_index());
261 if let DeclarationKind::Enum(e) = &decl.kind {
262 let tag = tag.read(buffer).unwrap();
263 let path = path.0.last().unwrap();
264 if let Some(variant) = e.variants.get(&tag) {
265 format!("{path}::{}", variant.name)
266 } else {
267 format!("{path}::UnknownTag({tag})")
268 }
269 } else {
270 panic!("Inconsistent declarations");
271 }
272 }
273}
274
275impl_object_name!(StructObject);
276impl_object_name!(TableObject);
277
278impl<'a> ObjectName<'a> for UnionTagObject {
279 fn print_object(&self, buffer: &InspectableFlatbuffer<'a>) -> String {
280 let path = buffer.declarations.get_declaration(self.declaration).0;
281 let path = path.0.last().unwrap();
282 match self.tag_variant(buffer) {
283 Ok(Some((variant_name, _variant))) => {
284 format!("{path}::{variant_name}")
285 }
286 Ok(None) => {
287 format!(
288 "{path}::UnknownVariant({})",
289 self.tag_value(buffer).unwrap()
290 )
291 }
292 Err(_) => {
293 format!("{path}::ERROR")
294 }
295 }
296 }
297}
298
299impl<'a> ObjectName<'a> for UnionObject {
300 fn print_object(&self, buffer: &InspectableFlatbuffer<'a>) -> String {
301 let path = buffer.declarations.get_declaration(self.declaration).0;
302 let path = path.0.last().unwrap();
303 match self.tag_variant(buffer) {
304 Ok(Some((variant_name, _variant))) => {
305 format!("{path}::{variant_name}")
306 }
307 Ok(None) => {
308 format!("{path}::UnknownVariant({})", self.tag)
309 }
310 Err(_) => {
311 format!("{path}::ERROR")
312 }
313 }
314 }
315}
316
317impl<'a> ObjectName<'a> for Object<'a> {
318 fn print_object(&self, buffer: &InspectableFlatbuffer<'a>) -> String {
319 match self {
320 Object::Offset(obj) => obj.print_object(buffer),
321 Object::VTable(obj) => obj.print_object(buffer),
322 Object::Table(obj) => obj.print_object(buffer),
323 Object::Struct(obj) => obj.print_object(buffer),
324 Object::UnionTag(obj) => obj.print_object(buffer),
325 Object::Union(obj) => obj.print_object(buffer),
326 Object::Enum(obj) => obj.print_object(buffer),
327 Object::Vector(obj) => obj.print_object(buffer),
328 Object::Array(obj) => obj.print_object(buffer),
329 Object::Integer(obj) => obj.print_object(buffer),
330 Object::Float(obj) => obj.print_object(buffer),
331 Object::Bool(obj) => obj.print_object(buffer),
332 Object::String(obj) => obj.print_object(buffer),
333 Object::UnionVectorTags(obj) => obj.print_object(buffer),
334 Object::UnionVectorValues(obj) => obj.print_object(buffer),
335 Object::Unknown(_) => "?".to_string(),
336 }
337 }
338}