use std::sync::Arc;
use crate::{
metadata::{
tables::{
CodedIndex, CodedIndexType, InterfaceImpl, InterfaceImplRc, TableId, TableInfoRef,
TableRow,
},
token::Token,
typesystem::TypeRegistry,
},
Result,
};
#[derive(Clone, Debug)]
pub struct InterfaceImplRaw {
pub rid: u32,
pub token: Token,
pub offset: usize,
pub class: u32,
pub interface: CodedIndex,
}
impl InterfaceImplRaw {
pub fn apply(&self, types: &TypeRegistry) -> Result<()> {
let Some(interface) = types.get(&self.interface.token) else {
return Err(malformed_error!(
"Failed to resolve interface token - {}",
self.interface.token.value()
));
};
match types.get(&Token::new(self.class | 0x0200_0000)) {
Some(class) => {
class.interfaces.push(interface.into());
Ok(())
}
None => Err(malformed_error!(
"Failed to resolve class token - {}",
self.class | 0x0200_0000
)),
}
}
pub fn to_owned(&self, types: &TypeRegistry) -> Result<InterfaceImplRc> {
Ok(Arc::new(InterfaceImpl {
rid: self.rid,
token: self.token,
offset: self.offset,
class: match types.get(&Token::new(self.class | 0x0200_0000)) {
Some(class) => class,
None => {
return Err(malformed_error!(
"Failed to resolve class token - {}",
self.class | 0x0200_0000
))
}
},
interface: match types.get(&self.interface.token) {
Some(interface) => interface,
None => {
return Err(malformed_error!(
"Failed to resolve interface token - {}",
self.interface.token.value()
))
}
},
custom_attributes: Arc::new(boxcar::Vec::new()),
}))
}
}
impl TableRow for InterfaceImplRaw {
#[rustfmt::skip]
fn row_size(sizes: &TableInfoRef) -> u32 {
u32::from(
sizes.table_index_bytes(TableId::TypeDef) +
sizes.coded_index_bytes(CodedIndexType::TypeDefOrRef)
)
}
}