lvm_class/attribute/
annotation.rs1use crate::ClassFormatErr;
6use lvm_common::utils::cursor::ByteCursor;
7use num_enum::TryFromPrimitive;
8
9#[derive(Debug, Clone, PartialEq, Eq)]
13pub struct Annotation {
14 pub type_index: u16,
15 pub element_value_pairs: Vec<ElementValuePair>,
16}
17
18impl<'a> Annotation {
19 pub(crate) fn read(cursor: &mut ByteCursor<'a>) -> Result<Self, ClassFormatErr> {
20 let type_index = cursor.u16()?;
21 let num_element_value_pairs = cursor.u16()?;
22 let mut element_value_pairs = Vec::with_capacity(num_element_value_pairs as usize);
23
24 for _ in 0..num_element_value_pairs {
25 element_value_pairs.push(ElementValuePair::read(cursor)?)
26 }
27
28 Ok(Self {
29 type_index,
30 element_value_pairs,
31 })
32 }
33}
34
35#[derive(Debug, Clone, PartialEq, Eq)]
39pub struct ElementValuePair {
40 pub element_name_index: u16,
41 pub value: ElementValue,
42}
43
44impl<'a> ElementValuePair {
45 pub(crate) fn read(cursor: &mut ByteCursor<'a>) -> Result<Self, ClassFormatErr> {
46 Ok(Self {
47 element_name_index: cursor.u16()?,
48 value: ElementValue::read(cursor)?,
49 })
50 }
51}
52
53#[derive(Debug, Clone, PartialEq, Eq, TryFromPrimitive)]
57#[repr(u8)]
58pub enum ElementKind {
59 Byte = b'B',
60 Char = b'C',
61 Double = b'D',
62 Float = b'F',
63 Int = b'I',
64 Long = b'J',
65 Short = b'S',
66 Boolean = b'Z',
67 String = b's',
68 EnumClass = b'e',
69 Class = b'c',
70 AnnotationInterface = b'@',
71 ArrayType = b'[',
72}
73
74#[derive(Debug, Clone, PartialEq, Eq)]
78pub enum ElementValue {
79 Byte(u16),
80 Char(u16),
81 Double(u16),
82 Float(u16),
83 Int(u16),
84 Long(u16),
85 Short(u16),
86 Boolean(u16),
87 String(u16),
88 EnumConstValue {
89 type_name_index: u16,
90 const_name_index: u16,
91 },
92 Class(u16),
93 AnnotationValue(Annotation),
94 Array(Vec<ElementValue>),
95}
96
97impl<'a> ElementValue {
98 pub(crate) fn read(cursor: &mut ByteCursor<'a>) -> Result<Self, ClassFormatErr> {
99 let raw_tag = cursor.u8()?;
100 let tag = ElementKind::try_from_primitive(raw_tag)
101 .map_err(|_| ClassFormatErr::UnknownTag(raw_tag))?;
102
103 let ev = match tag {
104 ElementKind::Byte => Self::Byte(cursor.u16()?),
105 ElementKind::Char => Self::Char(cursor.u16()?),
106 ElementKind::Double => Self::Double(cursor.u16()?),
107 ElementKind::Float => Self::Float(cursor.u16()?),
108 ElementKind::Int => Self::Int(cursor.u16()?),
109 ElementKind::Long => Self::Long(cursor.u16()?),
110 ElementKind::Short => Self::Short(cursor.u16()?),
111 ElementKind::Boolean => Self::Boolean(cursor.u16()?),
112 ElementKind::String => Self::String(cursor.u16()?),
113 ElementKind::EnumClass => Self::EnumConstValue {
114 type_name_index: cursor.u16()?,
115 const_name_index: cursor.u16()?,
116 },
117 ElementKind::Class => Self::Class(cursor.u16()?),
118 ElementKind::AnnotationInterface => Self::AnnotationValue(Annotation::read(cursor)?),
119 ElementKind::ArrayType => {
120 let element_types = cursor.u16()?;
121 let mut elements = Vec::with_capacity(element_types as usize);
122 for _ in 0..element_types {
123 elements.push(Self::read(cursor)?)
124 }
125 ElementValue::Array(elements)
126 }
127 };
128
129 Ok(ev)
130 }
131}