use std::sync::Arc;
use crate::{
metadata::{
customattributes::CustomAttributeValue, token::Token, typesystem::CilTypeReference,
},
Result,
};
pub struct CustomAttribute {
pub rid: u32,
pub token: Token,
pub offset: usize,
pub parent: CilTypeReference,
pub constructor: CilTypeReference,
pub value: CustomAttributeValue,
}
impl CustomAttribute {
pub fn apply(&self) -> Result<()> {
let attribute_value = Arc::new(self.value.clone());
match &self.parent {
CilTypeReference::TypeDef(entry)
| CilTypeReference::TypeSpec(entry)
| CilTypeReference::TypeRef(entry) => {
if let Some(type_ref) = entry.upgrade() {
type_ref.custom_attributes.push(attribute_value);
Ok(())
} else {
Err(malformed_error!("Type reference is no longer valid"))
}
}
CilTypeReference::MethodDef(entry) => {
if let Some(method) = entry.upgrade() {
method.custom_attributes.push(attribute_value);
Ok(())
} else {
Err(malformed_error!("Method reference is no longer valid"))
}
}
CilTypeReference::Field(entry) => {
entry.custom_attributes.push(attribute_value);
Ok(())
}
CilTypeReference::Param(entry) => {
entry.custom_attributes.push(attribute_value);
Ok(())
}
CilTypeReference::Property(entry) => {
entry.custom_attributes.push(attribute_value);
Ok(())
}
CilTypeReference::Event(entry) => {
entry.custom_attributes.push(attribute_value);
Ok(())
}
CilTypeReference::Assembly(entry) => {
entry.custom_attributes.push(attribute_value);
Ok(())
}
CilTypeReference::Module(entry) => {
entry.custom_attributes.push(attribute_value);
Ok(())
}
CilTypeReference::InterfaceImpl(entry) => {
entry.custom_attributes.push(attribute_value);
Ok(())
}
CilTypeReference::MemberRef(entry) => {
entry.custom_attributes.push(attribute_value);
Ok(())
}
CilTypeReference::DeclSecurity(entry) => {
entry.custom_attributes.push(attribute_value);
Ok(())
}
CilTypeReference::StandAloneSig(entry) => {
entry.custom_attributes.push(attribute_value);
Ok(())
}
CilTypeReference::ModuleRef(entry) => {
entry.custom_attributes.push(attribute_value);
Ok(())
}
CilTypeReference::AssemblyRef(entry) => {
entry.custom_attributes.push(attribute_value);
Ok(())
}
CilTypeReference::File(entry) => {
entry.custom_attributes.push(attribute_value);
Ok(())
}
CilTypeReference::ExportedType(entry) => {
entry.custom_attributes.push(attribute_value);
Ok(())
}
CilTypeReference::GenericParam(entry) => {
entry.custom_attributes.push(attribute_value);
Ok(())
}
CilTypeReference::GenericParamConstraint(entry) => {
entry.custom_attributes.push(attribute_value);
Ok(())
}
CilTypeReference::MethodSpec(entry) => {
entry.custom_attributes.push(attribute_value);
Ok(())
}
CilTypeReference::None => {
Ok(())
}
}
}
}