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 lvm_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        attr_name_idx: u16,
16    },
17    Deprecated {
18        attr_name_idx: u16,
19    },
20    Signature {
21        attr_name_idx: u16,
22        signature_idx: u16,
23    },
24    RuntimeVisibleAnnotations {
25        attr_name_idx: u16,
26        annotations: Vec<Annotation>,
27    },
28    RuntimeInvisibleAnnotations {
29        attr_name_idx: u16,
30        annotations: Vec<Annotation>,
31    },
32    RuntimeVisibleTypeAnnotations {
33        attr_name_idx: u16,
34        annotations: Vec<TypeAnnotation>,
35    },
36    RuntimeInvisibleTypeAnnotations {
37        attr_name_idx: u16,
38        annotations: Vec<TypeAnnotation>,
39    },
40}
41
42impl<'a> SharedAttribute {
43    pub(crate) fn read(
44        attr_name_idx: u16,
45        attr_type: AttributeKind,
46        cursor: &mut ByteCursor<'a>,
47    ) -> Result<Self, ClassFormatErr> {
48        match attr_type {
49            AttributeKind::Synthetic => Ok(SharedAttribute::Synthetic { attr_name_idx }),
50            AttributeKind::Deprecated => Ok(SharedAttribute::Deprecated { attr_name_idx }),
51            AttributeKind::Signature => {
52                let signature_idx = cursor.u16()?;
53                Ok(SharedAttribute::Signature {
54                    attr_name_idx,
55                    signature_idx,
56                })
57            }
58            AttributeKind::RuntimeVisibleAnnotations => {
59                let num_annotations = cursor.u16()?;
60                let mut annotations = Vec::with_capacity(num_annotations as usize);
61                for _ in 0..num_annotations {
62                    annotations.push(Annotation::read(cursor)?);
63                }
64                Ok(SharedAttribute::RuntimeVisibleAnnotations {
65                    attr_name_idx,
66                    annotations,
67                })
68            }
69            AttributeKind::RuntimeInvisibleAnnotations => {
70                let num_annotations = cursor.u16()?;
71                let mut annotations = Vec::with_capacity(num_annotations as usize);
72                for _ in 0..num_annotations {
73                    annotations.push(Annotation::read(cursor)?);
74                }
75                Ok(SharedAttribute::RuntimeInvisibleAnnotations {
76                    attr_name_idx,
77                    annotations,
78                })
79            }
80            AttributeKind::RuntimeInvisibleTypeAnnotations => {
81                let num_annotations = cursor.u16()?;
82                let mut annotations = Vec::with_capacity(num_annotations as usize);
83                for _ in 0..num_annotations {
84                    annotations.push(TypeAnnotation::read(cursor)?);
85                }
86                Ok(SharedAttribute::RuntimeInvisibleTypeAnnotations {
87                    attr_name_idx,
88                    annotations,
89                })
90            }
91            AttributeKind::RuntimeVisibleTypeAnnotations => {
92                let num_annotations = cursor.u16()?;
93                let mut annotations = Vec::with_capacity(num_annotations as usize);
94                for _ in 0..num_annotations {
95                    annotations.push(TypeAnnotation::read(cursor)?);
96                }
97                Ok(SharedAttribute::RuntimeVisibleTypeAnnotations {
98                    attr_name_idx,
99                    annotations,
100                })
101            }
102            _ => Err(ClassFormatErr::AttributeIsNotShared(attr_type.to_string())),
103        }
104    }
105}