1use std::borrow::Cow;
2
3use planus_types::{
4 ast::{FloatType, IntegerType},
5 intermediate::{
6 DeclarationIndex, DeclarationKind, Declarations, FloatLiteral, IntegerLiteral, SimpleType,
7 StructField, Type, TypeKind, UnionVariant,
8 },
9};
10
11use crate::object_info::DeclarationInfo;
12
13pub mod children;
14pub mod object_info;
15pub mod object_mapping;
16
17pub type ByteIndex = u32;
18
19#[derive(Debug)]
21pub struct Error;
22
23type Result<T> = std::result::Result<T, Error>;
24
25#[derive(Copy, Clone)]
26pub struct InspectableFlatbuffer<'a> {
27 pub declarations: &'a Declarations,
28 pub buffer: &'a [u8],
29}
30
31impl<'a> InspectableFlatbuffer<'a> {
32 pub fn read_u8(&self, offset: ByteIndex) -> Result<u8> {
33 let offset = offset as usize;
34 Ok(self.buffer[offset])
35 }
36
37 pub fn read_u16(&self, offset: ByteIndex) -> Result<u16> {
38 let offset = offset as usize;
39 let slice: &[u8; 2] = self.buffer[offset..offset + 2].try_into().unwrap();
40 Ok(u16::from_le_bytes(*slice))
41 }
42
43 pub fn read_u32(&self, offset: ByteIndex) -> Result<u32> {
44 let offset = offset as usize;
45 let slice: &[u8; 4] = self.buffer[offset..offset + 4].try_into().unwrap();
46 Ok(u32::from_le_bytes(*slice))
47 }
48
49 pub fn read_u64(&self, offset: ByteIndex) -> Result<u64> {
50 let offset = offset as usize;
51 let slice: &[u8; 8] = self.buffer[offset..offset + 8].try_into().unwrap();
52 Ok(u64::from_le_bytes(*slice))
53 }
54
55 pub fn read_i8(&self, offset: ByteIndex) -> Result<i8> {
56 let offset = offset as usize;
57 Ok(self.buffer[offset] as i8)
58 }
59
60 pub fn read_i16(&self, offset: ByteIndex) -> Result<i16> {
61 let offset = offset as usize;
62 let slice: &[u8; 2] = self.buffer[offset..offset + 2].try_into().unwrap();
63 Ok(i16::from_le_bytes(*slice))
64 }
65
66 pub fn read_i32(&self, offset: ByteIndex) -> Result<i32> {
67 let offset = offset as usize;
68 let slice: &[u8; 4] = self.buffer[offset..offset + 4].try_into().unwrap();
69 Ok(i32::from_le_bytes(*slice))
70 }
71
72 pub fn read_i64(&self, offset: ByteIndex) -> Result<i64> {
73 let offset = offset as usize;
74 let slice: &[u8; 8] = self.buffer[offset..offset + 8].try_into().unwrap();
75 Ok(i64::from_le_bytes(*slice))
76 }
77
78 pub fn read_f32(&self, offset: ByteIndex) -> Result<f32> {
79 let offset = offset as usize;
80 let slice: &[u8; 4] = self.buffer[offset..offset + 4].try_into().unwrap();
81 Ok(f32::from_le_bytes(*slice))
82 }
83
84 pub fn read_f64(&self, offset: ByteIndex) -> Result<f64> {
85 let offset = offset as usize;
86 let slice: &[u8; 8] = self.buffer[offset..offset + 8].try_into().unwrap();
87 Ok(f64::from_le_bytes(*slice))
88 }
89
90 pub fn read_slice(&self, offset: ByteIndex, size: usize) -> Result<&'a [u8]> {
91 let offset = offset as usize;
92 Ok(&self.buffer[offset..offset + size])
93 }
94}
95
96#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
97pub enum Object<'a> {
98 Offset(OffsetObject<'a>),
100
101 VTable(VTableObject),
103
104 Table(TableObject),
106
107 Struct(StructObject),
109
110 UnionTag(UnionTagObject),
112
113 Union(UnionObject),
115
116 UnionVectorTags(UnionVectorTagsObject),
118
119 UnionVectorValues(UnionVectorValuesObject),
121
122 Enum(EnumObject),
124
125 Vector(VectorObject<'a>),
127
128 Array(ArrayObject<'a>),
130
131 Integer(IntegerObject),
133
134 Float(FloatObject),
136
137 Bool(BoolObject),
139
140 String(StringObject),
142
143 Unknown(ByteIndex),
145}
146
147impl Object<'_> {
148 pub fn offset(&self) -> ByteIndex {
149 match self {
150 Object::Offset(inner) => inner.offset,
151 Object::VTable(inner) => inner.offset,
152 Object::Table(inner) => inner.offset,
153 Object::Struct(inner) => inner.offset,
154 Object::UnionTag(inner) => inner.offset,
155 Object::Union(inner) => inner.offset,
156 Object::Enum(inner) => inner.offset,
157 Object::Vector(inner) => inner.offset,
158 Object::Array(inner) => inner.offset,
159 Object::Integer(inner) => inner.offset,
160 Object::Float(inner) => inner.offset,
161 Object::Bool(inner) => inner.offset,
162 Object::String(inner) => inner.offset,
163 Object::UnionVectorTags(inner) => inner.tags_offset,
164 Object::UnionVectorValues(inner) => inner.values_offset,
165 Object::Unknown(offset) => *offset,
166 }
167 }
168
169 pub fn have_braces(&self) -> bool {
170 match self {
171 Object::Offset(_) => false,
172 Object::VTable(_) => true,
173 Object::Table(_) => true,
174 Object::Struct(_) => true,
175 Object::UnionTag(_) => false,
176 Object::Union(_) => false,
177 Object::Enum(_) => false,
178 Object::Vector(_) => true,
179 Object::Array(_) => true,
180 Object::Integer(_) => false,
181 Object::Float(_) => false,
182 Object::Bool(_) => false,
183 Object::String(_) => false,
184 Object::UnionVectorTags(_) => true,
185 Object::UnionVectorValues(_) => true,
186 Object::Unknown(_) => false,
187 }
188 }
189
190 pub fn type_name(&self, declarations: &Declarations) -> Cow<'static, str> {
191 match self {
192 Object::Offset(inner) => inner.type_name(declarations),
193 Object::VTable(inner) => Cow::Owned(inner.type_name(declarations)),
194 Object::Table(inner) => Cow::Owned(inner.type_name(declarations)),
195 Object::Struct(inner) => Cow::Owned(inner.type_name(declarations)),
196 Object::UnionTag(inner) => Cow::Owned(inner.type_name(declarations)),
197 Object::Union(inner) => Cow::Owned(inner.type_name(declarations)),
198 Object::Enum(inner) => Cow::Owned(inner.type_name(declarations)),
199 Object::Vector(inner) => Cow::Owned(inner.type_name(declarations)),
200 Object::Array(inner) => Cow::Owned(inner.type_name(declarations)),
201 Object::Integer(inner) => Cow::Borrowed(inner.type_.flatbuffer_name()),
202 Object::Float(inner) => Cow::Borrowed(inner.type_.flatbuffer_name()),
203 Object::Bool(_) => Cow::Borrowed("bool"),
204 Object::String(_) => Cow::Borrowed("string"),
205 Object::UnionVectorTags(inner) => Cow::Owned(inner.type_name(declarations)),
206 Object::UnionVectorValues(inner) => Cow::Owned(inner.type_name(declarations)),
207 Object::Unknown(_) => Cow::Borrowed("?"),
208 }
209 }
210}
211
212#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
213pub struct OffsetObject<'a> {
214 pub offset: ByteIndex,
215 pub kind: OffsetObjectKind<'a>,
216}
217
218#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
219pub enum OffsetObjectKind<'a> {
220 VTable(DeclarationIndex),
221 Table(DeclarationIndex),
222 Vector(&'a Type),
223 UnionVectorTags {
224 declaration: DeclarationIndex,
225 },
226 UnionVector {
227 declaration: DeclarationIndex,
228 tags_offset: Option<ByteIndex>,
229 },
230 String,
231 Unknown,
232}
233
234#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
235pub struct VTableObject {
236 pub offset: ByteIndex,
237 pub declaration: DeclarationIndex,
238}
239
240#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
241pub struct TableOffsetObject {
242 pub offset: ByteIndex,
243 pub declaration: DeclarationIndex,
244}
245
246#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
247pub struct TableObject {
248 pub offset: ByteIndex,
249 pub declaration: DeclarationIndex,
250}
251
252#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
253pub struct StructObject {
254 pub offset: ByteIndex,
255 pub declaration: DeclarationIndex,
256}
257
258#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
259pub struct UnionTagObject {
260 pub offset: ByteIndex,
261 pub declaration: DeclarationIndex,
262}
263
264impl UnionTagObject {
265 fn type_name(&self, declarations: &Declarations) -> String {
266 format!(
267 "union tag {}",
268 declarations.get_declaration(self.declaration).0
269 )
270 }
271
272 pub fn tag_value(&self, buffer: &InspectableFlatbuffer<'_>) -> Result<u8> {
273 buffer.read_u8(self.offset)
274 }
275
276 pub fn tag_variant<'a>(
277 &self,
278 buffer: &InspectableFlatbuffer<'a>,
279 ) -> Result<Option<(&'a str, &'a UnionVariant)>> {
280 let decl = self.resolve_declaration(buffer);
281 if let Some((k, v)) = decl
282 .variants
283 .get_index(self.tag_value(buffer)? as usize - 1)
284 {
285 Ok(Some((k, v)))
286 } else {
287 Ok(None)
288 }
289 }
290}
291
292#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
293pub struct UnionObject {
294 pub tag: u8,
295 pub offset: ByteIndex,
296 pub declaration: DeclarationIndex,
297}
298
299#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
300pub struct EnumObject {
301 pub offset: ByteIndex,
302 pub declaration: DeclarationIndex,
303}
304
305#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
306pub struct VectorObject<'a> {
307 pub offset: ByteIndex,
308 pub type_: &'a Type,
309}
310
311#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
312pub struct UnionVectorTagsObject {
313 tags_offset: ByteIndex,
314 declaration: DeclarationIndex,
315}
316
317#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
318pub struct UnionVectorValuesObject {
319 tags_offset: Option<ByteIndex>,
320 values_offset: ByteIndex,
321 declaration: DeclarationIndex,
322}
323
324#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
325pub struct ArrayObject<'a> {
326 pub offset: ByteIndex,
327 pub type_: &'a Type,
328 pub size: u32,
329}
330
331impl ArrayObject<'_> {
332 pub fn type_name(&self, declarations: &Declarations) -> String {
333 format!(
334 "[{}; {}]",
335 declarations.format_type_kind(&self.type_.kind),
336 self.size
337 )
338 }
339}
340
341#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
342pub struct IntegerObject {
343 pub offset: ByteIndex,
344 pub type_: IntegerType,
345}
346
347#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
348pub struct FloatObject {
349 pub offset: ByteIndex,
350 pub type_: FloatType,
351}
352
353#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
354pub struct BoolObject {
355 pub offset: ByteIndex,
356}
357
358#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
359pub struct StringObject {
360 pub offset: ByteIndex,
361}
362
363impl<'a> OffsetObject<'a> {
364 pub fn get_byte_index(&self, buffer: &InspectableFlatbuffer<'a>) -> Result<ByteIndex> {
365 let res = if matches!(self.kind, OffsetObjectKind::VTable(_)) {
366 self.offset
367 .checked_add_signed(-buffer.read_i32(self.offset)?)
368 .ok_or(Error)?
369 } else {
370 self.offset + buffer.read_u32(self.offset)?
371 };
372 Ok(res)
373 }
374
375 pub fn follow_offset(&self, buffer: &InspectableFlatbuffer<'a>) -> Result<Object<'a>> {
376 let offset = self.get_byte_index(buffer)?;
377 match self.kind {
378 OffsetObjectKind::VTable(declaration) => Ok(Object::VTable(VTableObject {
379 declaration,
380 offset,
381 })),
382 OffsetObjectKind::Table(declaration) => Ok(Object::Table(TableObject {
383 offset,
384 declaration,
385 })),
386 OffsetObjectKind::Vector(type_) => Ok(Object::Vector(VectorObject { offset, type_ })),
387 OffsetObjectKind::UnionVector {
388 declaration,
389 tags_offset,
390 } => Ok(Object::UnionVectorValues(UnionVectorValuesObject {
391 tags_offset: if let Some(tags_offset) = tags_offset {
392 Some(tags_offset + buffer.read_u32(tags_offset)?)
393 } else {
394 None
395 },
396 values_offset: offset,
397 declaration,
398 })),
399
400 OffsetObjectKind::UnionVectorTags { declaration } => {
401 Ok(Object::UnionVectorTags(UnionVectorTagsObject {
402 tags_offset: offset,
403 declaration,
404 }))
405 }
406 OffsetObjectKind::String => Ok(Object::String(StringObject { offset })),
407 OffsetObjectKind::Unknown => Ok(Object::Unknown(offset)),
408 }
409 }
410
411 fn type_name(&self, declarations: &Declarations) -> Cow<'static, str> {
412 match self.kind {
413 OffsetObjectKind::VTable(index) => {
414 Cow::Owned(format!("&vtable {}", declarations.get_declaration(index).0))
415 }
416 OffsetObjectKind::Table(index) => {
417 Cow::Owned(format!("&table {}", declarations.get_declaration(index).0))
418 }
419 OffsetObjectKind::Vector(type_) => {
420 Cow::Owned(format!("&[{}]", declarations.format_type_kind(&type_.kind)))
421 }
422 OffsetObjectKind::UnionVector { declaration, .. } => Cow::Owned(format!(
423 "&[{}]",
424 declarations.get_declaration(declaration).0
425 )),
426
427 OffsetObjectKind::UnionVectorTags { declaration, .. } => Cow::Owned(format!(
428 "&[{}] (tags)",
429 declarations.get_declaration(declaration).0
430 )),
431 OffsetObjectKind::String => Cow::Borrowed("&string"),
432 OffsetObjectKind::Unknown => Cow::Borrowed("&?"),
433 }
434 }
435}
436
437impl VTableObject {
438 pub fn get_vtable_size(&self, buffer: &InspectableFlatbuffer<'_>) -> Result<u16> {
439 buffer.read_u16(self.offset)
440 }
441
442 pub fn get_table_size(&self, buffer: &InspectableFlatbuffer<'_>) -> Result<u16> {
443 buffer.read_u16(self.offset + 2)
444 }
445
446 pub fn get_offset(&self, i: u32, buffer: &InspectableFlatbuffer<'_>) -> Result<Option<u16>> {
447 let value = buffer.read_u16(self.offset + 4 + 2 * i)?;
448 let value = (value != 0).then_some(value);
449 Ok(value)
450 }
451
452 pub fn get_offsets<'a>(
453 &self,
454 buffer: &InspectableFlatbuffer<'a>,
455 ) -> Result<impl 'a + ExactSizeIterator<Item = u16> + DoubleEndedIterator> {
456 let size = self.get_vtable_size(buffer)?;
457 let slice: &[u8] = buffer.read_slice(self.offset, size as usize)?;
458 Ok(slice[4..].chunks_exact(2).map(move |chunk| {
459 let slice: &[u8; 2] = chunk.try_into().unwrap();
460 u16::from_le_bytes(*slice)
461 }))
462 }
463
464 fn type_name(&self, declarations: &Declarations) -> String {
465 format!(
466 "vtable for {}",
467 declarations.get_declaration(self.declaration).0
468 )
469 }
470}
471
472impl TableObject {
473 pub fn get_vtable(&self, buffer: &InspectableFlatbuffer<'_>) -> Result<VTableObject> {
474 let vtable_offset = self
475 .offset
476 .checked_add_signed(-buffer.read_i32(self.offset)?)
477 .unwrap();
478
479 Ok(VTableObject {
480 declaration: self.declaration,
481 offset: vtable_offset,
482 })
483 }
484
485 pub fn get_field<'a>(
486 &self,
487 buffer: &InspectableFlatbuffer<'a>,
488 field_index: u32,
489 ) -> Result<Option<Object<'a>>> {
490 let decl = self.resolve_declaration(buffer);
491 let Some(object_offset) = self.get_vtable(buffer)?.get_offset(field_index, buffer)? else {
492 return Ok(None);
493 };
494
495 let offset = self.offset + object_offset as u32;
496 let (_field_name, field_decl, is_union_tag) =
497 decl.get_field_for_vtable_index(field_index).unwrap();
498 let object = match field_decl.type_.kind {
499 TypeKind::Table(declaration) => Object::Offset(OffsetObject {
500 offset,
501 kind: OffsetObjectKind::Table(declaration),
502 }),
503 TypeKind::Union(declaration) if is_union_tag => Object::UnionTag(UnionTagObject {
504 offset,
505 declaration,
506 }),
507 TypeKind::Union(declaration) => {
508 let Some(tag_offset) = self
509 .get_vtable(buffer)?
510 .get_offset(field_index - 1, buffer)?
511 else {
512 return Ok(None);
513 };
514
515 let tag_offset = self.offset + tag_offset as u32;
516 if let Ok(tag) = buffer.read_u8(tag_offset) {
517 Object::Union(UnionObject {
518 tag,
519 offset,
520 declaration,
521 })
522 } else {
523 return Ok(None);
524 }
525 }
526 TypeKind::Vector(ref type_) if is_union_tag => Object::Offset(OffsetObject {
527 offset,
528 kind: OffsetObjectKind::UnionVectorTags {
529 declaration: if let TypeKind::Union(declaration) = &type_.kind {
530 *declaration
531 } else {
532 return Ok(None);
533 },
534 },
535 }),
536 TypeKind::Vector(ref type_) if matches!(type_.kind, TypeKind::Union(_)) => {
537 let tags = self
538 .get_vtable(buffer)?
539 .get_offset(field_index - 1, buffer)?
540 .map(|tag_offset| self.offset + tag_offset as u32);
541
542 Object::Offset(OffsetObject {
543 offset,
544 kind: OffsetObjectKind::UnionVector {
545 declaration: if let TypeKind::Union(declaration) = &type_.kind {
546 *declaration
547 } else {
548 return Ok(None);
549 },
550 tags_offset: tags,
551 },
552 })
553 }
554 TypeKind::Vector(ref type_) => Object::Offset(OffsetObject {
555 offset,
556 kind: OffsetObjectKind::Vector(type_),
557 }),
558 TypeKind::Array(ref _type_, _size) => todo!(),
559 TypeKind::SimpleType(type_) => match type_ {
560 SimpleType::Struct(declaration) => Object::Struct(StructObject {
561 offset,
562 declaration,
563 }),
564 SimpleType::Enum(declaration) => Object::Enum(EnumObject {
565 offset,
566 declaration,
567 }),
568 SimpleType::Bool => Object::Bool(BoolObject { offset }),
569 SimpleType::Integer(type_) => Object::Integer(IntegerObject { offset, type_ }),
570 SimpleType::Float(type_) => Object::Float(FloatObject { offset, type_ }),
571 },
572 TypeKind::String => Object::Offset(OffsetObject {
573 offset,
574 kind: OffsetObjectKind::String,
575 }),
576 };
577 Ok(Some(object))
578 }
579
580 fn type_name(&self, declarations: &Declarations) -> String {
581 format!("table {}", declarations.get_declaration(self.declaration).0)
582 }
583}
584
585impl StructObject {
586 pub fn get_field_info<'a>(
587 &self,
588 buffer: &InspectableFlatbuffer<'a>,
589 field_index: usize,
590 ) -> Option<(&'a str, &'a StructField)> {
591 let decl = self.resolve_declaration(buffer);
592 let (field_name, field) = decl.fields.get_index(field_index)?;
593 Some((field_name.as_str(), field))
594 }
595
596 pub fn get_field<'a>(
597 &self,
598 buffer: &InspectableFlatbuffer<'a>,
599 field_index: usize,
600 ) -> Result<Object<'a>> {
601 let Some((_field_name, field)) = self.get_field_info(buffer, field_index) else {
602 return Err(Error);
603 };
604
605 let offset = self.offset + field.offset;
606 let object = match field.type_ {
607 SimpleType::Struct(declaration) => Object::Struct(StructObject {
608 offset,
609 declaration,
610 }),
611 SimpleType::Enum(declaration) => Object::Enum(EnumObject {
612 offset,
613 declaration,
614 }),
615 SimpleType::Bool => Object::Bool(BoolObject { offset }),
616 SimpleType::Integer(type_) => Object::Integer(IntegerObject { offset, type_ }),
617 SimpleType::Float(type_) => Object::Float(FloatObject { offset, type_ }),
618 };
619 Ok(object)
620 }
621
622 fn type_name(&self, declarations: &Declarations) -> String {
623 format!(
624 "struct {}",
625 declarations.get_declaration(self.declaration).0
626 )
627 }
628}
629
630impl UnionObject {
631 pub fn inner_offset<'a>(
632 &self,
633 buffer: &InspectableFlatbuffer<'a>,
634 ) -> Result<Option<OffsetObject<'a>>> {
635 if let Some((_name, variant)) = self.tag_variant(buffer)? {
636 Ok(Some(OffsetObject {
637 offset: self.offset,
638 kind: match &variant.type_.kind {
639 TypeKind::Table(index) => OffsetObjectKind::Table(*index),
640 TypeKind::Vector(type_) => OffsetObjectKind::Vector(type_),
641 TypeKind::String => OffsetObjectKind::String,
642 TypeKind::Array(_, _) | TypeKind::SimpleType(_) | TypeKind::Union(_) => {
643 panic!("Inconsistent declarations")
644 }
645 },
646 }))
647 } else {
648 Ok(None)
649 }
650 }
651
652 fn type_name(&self, declarations: &Declarations) -> String {
653 format!(
654 "&union {}",
655 declarations.get_declaration(self.declaration).0
656 )
657 }
658
659 pub fn tag_variant<'a>(
660 &self,
661 buffer: &InspectableFlatbuffer<'a>,
662 ) -> Result<Option<(&'a str, &'a UnionVariant)>> {
663 let decl = self.resolve_declaration(buffer);
664 if let Some((k, v)) = decl.variants.get_index(self.tag as usize - 1) {
665 Ok(Some((k, v)))
666 } else {
667 Ok(None)
668 }
669 }
670}
671
672impl EnumObject {
673 pub fn tag(&self, buffer: &InspectableFlatbuffer<'_>) -> Result<IntegerObject> {
674 let (_, decl) = buffer.declarations.get_declaration(self.declaration);
675
676 if let DeclarationKind::Enum(e) = &decl.kind {
677 Ok(IntegerObject {
678 offset: self.offset,
679 type_: e.type_,
680 })
681 } else {
682 Err(Error)
683 }
684 }
685
686 pub fn read(&self, buffer: &InspectableFlatbuffer<'_>) -> Result<u64> {
687 let tag = self.tag(buffer)?;
688 let val = tag.read(buffer)?;
689 Ok(val.to_u64())
690 }
691
692 fn type_name(&self, declarations: &Declarations) -> String {
693 format!("enum {}", declarations.get_declaration(self.declaration).0)
694 }
695}
696
697impl StringObject {
698 pub fn len(&self, buffer: &InspectableFlatbuffer<'_>) -> Result<u32> {
699 buffer.read_u32(self.offset)
700 }
701
702 pub fn bytes<'a>(&self, buffer: &InspectableFlatbuffer<'a>) -> Result<&'a [u8]> {
703 let offset = self.offset as usize;
704 Ok(&buffer.buffer[offset + 4..offset + 4 + self.len(buffer)? as usize])
705 }
706}
707
708impl BoolObject {
709 pub fn read(&self, buffer: &InspectableFlatbuffer<'_>) -> Result<bool> {
710 Ok(buffer.buffer[self.offset as usize] != 0)
711 }
712}
713
714impl FloatObject {
715 pub fn read(&self, buffer: &InspectableFlatbuffer<'_>) -> Result<FloatLiteral> {
716 match self.type_ {
717 FloatType::F32 => Ok(FloatLiteral::F32(buffer.read_f32(self.offset)?)),
718 FloatType::F64 => Ok(FloatLiteral::F64(buffer.read_f64(self.offset)?)),
719 }
720 }
721}
722
723impl IntegerObject {
724 pub fn read(&self, buffer: &InspectableFlatbuffer<'_>) -> Result<IntegerLiteral> {
725 let literal = match self.type_ {
726 IntegerType::U8 => IntegerLiteral::U8(buffer.read_u8(self.offset)?),
727 IntegerType::U16 => IntegerLiteral::U16(buffer.read_u16(self.offset)?),
728 IntegerType::U32 => IntegerLiteral::U32(buffer.read_u32(self.offset)?),
729 IntegerType::U64 => IntegerLiteral::U64(buffer.read_u64(self.offset)?),
730 IntegerType::I8 => IntegerLiteral::I8(buffer.read_i8(self.offset)?),
731 IntegerType::I16 => IntegerLiteral::I16(buffer.read_i16(self.offset)?),
732 IntegerType::I32 => IntegerLiteral::I32(buffer.read_i32(self.offset)?),
733 IntegerType::I64 => IntegerLiteral::I64(buffer.read_i64(self.offset)?),
734 };
735 Ok(literal)
736 }
737}
738
739impl<'a> VectorObject<'a> {
740 pub fn len(&self, buffer: &InspectableFlatbuffer<'_>) -> Result<u32> {
741 buffer.read_u32(self.offset)
742 }
743
744 pub fn read(
745 &self,
746 index: u32,
747 buffer: &InspectableFlatbuffer<'a>,
748 ) -> Result<Option<Object<'a>>> {
749 if index >= self.len(buffer)? {
750 return Ok(None);
751 }
752
753 let offset = self.offset + 4;
754 let object = match &self.type_.kind {
755 TypeKind::Union(_) => return Ok(None),
756 TypeKind::Array(_, _) => return Ok(None),
757 TypeKind::Table(declaration_index) => Object::Offset(OffsetObject {
758 offset: offset + index * 4,
759 kind: OffsetObjectKind::Table(*declaration_index),
760 }),
761 TypeKind::Vector(type_) => Object::Offset(OffsetObject {
762 offset: offset + index * 4,
763 kind: OffsetObjectKind::Vector(type_),
764 }),
765
766 TypeKind::String => Object::Offset(OffsetObject {
767 offset: offset + index * 4,
768 kind: OffsetObjectKind::String,
769 }),
770
771 TypeKind::SimpleType(type_) => match type_ {
772 SimpleType::Struct(declaration_index) => {
773 if let DeclarationKind::Struct(decl) = &buffer
774 .declarations
775 .get_declaration(*declaration_index)
776 .1
777 .kind
778 {
779 Object::Struct(StructObject {
780 offset: offset + index * decl.size,
781 declaration: *declaration_index,
782 })
783 } else {
784 panic!("Inconsistent declarations");
785 }
786 }
787 SimpleType::Enum(declaration_index) => {
788 if let DeclarationKind::Enum(decl) = &buffer
789 .declarations
790 .get_declaration(*declaration_index)
791 .1
792 .kind
793 {
794 Object::Enum(EnumObject {
795 offset: offset + index * decl.type_.byte_size(),
796 declaration: *declaration_index,
797 })
798 } else {
799 panic!("Inconsistent declarations");
800 }
801 }
802 SimpleType::Bool => Object::Bool(BoolObject {
803 offset: offset + index,
804 }),
805 SimpleType::Integer(type_) => Object::Integer(IntegerObject {
806 offset: offset + index * type_.byte_size(),
807 type_: *type_,
808 }),
809 SimpleType::Float(type_) => Object::Float(FloatObject {
810 offset: offset + index * type_.byte_size(),
811 type_: *type_,
812 }),
813 },
814 };
815 Ok(Some(object))
816 }
817
818 fn type_name(&self, declarations: &Declarations) -> String {
819 format!("[{}]", declarations.format_type_kind(&self.type_.kind))
820 }
821}
822
823impl UnionVectorTagsObject {
824 pub fn len(&self, buffer: &InspectableFlatbuffer<'_>) -> Result<u32> {
825 buffer.read_u32(self.tags_offset)
826 }
827
828 fn type_name(&self, declarations: &Declarations) -> String {
829 format!(
830 "[{}] (tags)",
831 declarations.get_declaration(self.declaration).0
832 )
833 }
834}
835
836impl UnionVectorValuesObject {
837 pub fn len(&self, buffer: &InspectableFlatbuffer<'_>) -> Result<u32> {
838 buffer.read_u32(self.values_offset)
839 }
840
841 fn type_name(&self, declarations: &Declarations) -> String {
842 format!("[{}]", declarations.get_declaration(self.declaration).0)
843 }
844}