Skip to main content

lvm_class/attribute/
shared.rs

1//! Shared attribute types that can appear at multiple locations in a class file.
2//!
3//! These attributes can be attached to classes, fields, methods, and record components.
4
5use super::AttributeKind;
6use super::annotation::Annotation;
7use super::type_annotation::TypeAnnotation;
8use crate::ClassFormatErr;
9use common::utils::cursor::ByteCursor;
10
11/// Attribute payloads that can appear at multiple locations (class, field, method, record).
12#[derive(Debug, Clone, PartialEq, Eq)]
13pub enum SharedAttribute {
14    Synthetic,
15    Deprecated,
16    Signature(u16),
17    RuntimeVisibleAnnotations(Vec<Annotation>),
18    RuntimeInvisibleAnnotations(Vec<Annotation>),
19    RuntimeVisibleTypeAnnotations(Vec<TypeAnnotation>),
20    RuntimeInvisibleTypeAnnotations(Vec<TypeAnnotation>),
21}
22
23impl<'a> SharedAttribute {
24    pub(crate) fn read(
25        attr_type: AttributeKind,
26        cursor: &mut ByteCursor<'a>,
27    ) -> Result<Self, ClassFormatErr> {
28        match attr_type {
29            AttributeKind::Synthetic => Ok(SharedAttribute::Synthetic),
30            AttributeKind::Deprecated => Ok(SharedAttribute::Deprecated),
31            AttributeKind::Signature => {
32                let signature_index = cursor.u16()?;
33                Ok(SharedAttribute::Signature(signature_index))
34            }
35            AttributeKind::RuntimeVisibleAnnotations => {
36                let num_annotations = cursor.u16()?;
37                let mut annotations = Vec::with_capacity(num_annotations as usize);
38                for _ in 0..num_annotations {
39                    annotations.push(Annotation::read(cursor)?);
40                }
41                Ok(SharedAttribute::RuntimeVisibleAnnotations(annotations))
42            }
43            AttributeKind::RuntimeInvisibleAnnotations => {
44                let num_annotations = cursor.u16()?;
45                let mut annotations = Vec::with_capacity(num_annotations as usize);
46                for _ in 0..num_annotations {
47                    annotations.push(Annotation::read(cursor)?);
48                }
49                Ok(SharedAttribute::RuntimeInvisibleAnnotations(annotations))
50            }
51            AttributeKind::RuntimeInvisibleTypeAnnotations => {
52                let num_annotations = cursor.u16()?;
53                let mut annotations = Vec::with_capacity(num_annotations as usize);
54                for _ in 0..num_annotations {
55                    annotations.push(TypeAnnotation::read(cursor)?);
56                }
57                Ok(SharedAttribute::RuntimeInvisibleTypeAnnotations(
58                    annotations,
59                ))
60            }
61            AttributeKind::RuntimeVisibleTypeAnnotations => {
62                let num_annotations = cursor.u16()?;
63                let mut annotations = Vec::with_capacity(num_annotations as usize);
64                for _ in 0..num_annotations {
65                    annotations.push(TypeAnnotation::read(cursor)?);
66                }
67                Ok(SharedAttribute::RuntimeVisibleTypeAnnotations(annotations))
68            }
69            _ => Err(ClassFormatErr::AttributeIsNotShared(attr_type.to_string())),
70        }
71    }
72}