use crate::attributes::nested_class_access_flags::NestedClassAccessFlags;
use crate::byte_reader::ByteReader;
use crate::error::Result;
use byteorder::{BigEndian, WriteBytesExt};
use std::fmt;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct InnerClass {
pub class_info_index: u16,
pub outer_class_info_index: u16,
pub name_index: u16,
pub access_flags: NestedClassAccessFlags,
}
impl InnerClass {
pub fn from_bytes(bytes: &mut ByteReader<'_>) -> Result<InnerClass> {
let class_info_index = bytes.read_u16()?;
let outer_class_info_index = bytes.read_u16()?;
let name_index = bytes.read_u16()?;
let access_flags = NestedClassAccessFlags::from_bytes(bytes)?;
let inner_class = InnerClass {
class_info_index,
outer_class_info_index,
name_index,
access_flags,
};
Ok(inner_class)
}
pub fn to_bytes(&self, bytes: &mut Vec<u8>) -> Result<()> {
bytes.write_u16::<BigEndian>(self.class_info_index)?;
bytes.write_u16::<BigEndian>(self.outer_class_info_index)?;
bytes.write_u16::<BigEndian>(self.name_index)?;
self.access_flags.to_bytes(bytes)
}
}
impl fmt::Display for InnerClass {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"class_info_index: {}, outer_class_info_index: {}, name_index: {}, access_flags: {}",
self.class_info_index, self.outer_class_info_index, self.name_index, self.access_flags
)
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_to_string() {
let inner_class = InnerClass {
class_info_index: 1,
outer_class_info_index: 2,
name_index: 3,
access_flags: NestedClassAccessFlags::PUBLIC,
};
assert_eq!(
"class_info_index: 1, outer_class_info_index: 2, name_index: 3, access_flags: (0x0001) ACC_PUBLIC",
inner_class.to_string()
);
}
#[test]
fn test_serialization() -> Result<()> {
let inner_class = InnerClass {
class_info_index: 1,
outer_class_info_index: 2,
name_index: 3,
access_flags: NestedClassAccessFlags::PUBLIC,
};
let expected_value = [0, 1, 0, 2, 0, 3, 0, 1];
let mut bytes = Vec::new();
inner_class.clone().to_bytes(&mut bytes)?;
assert_eq!(expected_value, &bytes[..]);
let mut bytes = ByteReader::new(&expected_value);
assert_eq!(inner_class, InnerClass::from_bytes(&mut bytes)?);
Ok(())
}
}