use crate::module::Module;
use crate::prelude::*;
use crate::mod_utf8::{modified_utf8_to_string, string_to_modified_utf8};
#[derive(Clone, PartialEq, Debug)]
pub struct RawAttribute {
pub(crate) keep: bool,
pub name: Cow<'static, str>,
pub inner: Cow<'static, [u8]>
}
impl RawAttribute {
pub fn new<S: Into<Cow<'static, str>>, B: Into<Cow<'static, [u8]>>>(name: S, inner: B) -> Self {
Self {
keep: true,
name: name.into(),
inner: inner.into()
}
}
pub(crate) fn __new(name: Cow<'static, str>, inner: Vec<u8>) -> Self {
Self {
keep: false,
name,
inner: Cow::Owned(inner)
}
}
}
impl ConstantPoolReadWrite for Option<(Cow<'static,str>, Type)> {
fn read_from<C: ConstantPoolReader, R: Read>(cp: &mut C, reader: &mut R) -> Result<Self, Error> {
let idx = u16::read_from(reader)?;
if idx == 0 {
Ok(None)
} else {
try_cp_read!(idx, cp.read_nameandtype(idx)).map(Some)
}
}
fn write_to<C: ConstantPoolWriter, W: Write>(&self, cp: &mut C, writer: &mut W) -> Result<(), Error> {
if let Some((n, t)) = self {
cp.insert_nameandtype(n.clone(), t.to_string()).write_to(writer)
} else {
0u16.write_to(writer)
}
}
}
#[derive(Eq, PartialEq, Debug, Clone)]
pub struct SourceDebugExtension(pub Cow<'static, str>);
impl ReadWrite for SourceDebugExtension {
fn read_from<T: Read>(reader: &mut T) -> Result<Self> {
let mut buf = vec![];
reader.read_to_end(&mut buf)?;
Ok(SourceDebugExtension(modified_utf8_to_string(&buf)?.into()))
}
fn write_to<T: Write>(&self, writer: &mut T) -> Result<()> {
writer.write_all(&string_to_modified_utf8(&self.0))?;
Ok(())
}
}
#[derive(Eq, PartialEq, Debug, Clone, ConstantPoolReadWrite)]
pub struct InnerClass {
#[str_type(Class)]
pub inner_fqname: Cow<'static, str>,
#[str_optional]
#[str_type(Class)]
pub outer_fqname: Option<Cow<'static, str>>,
#[str_optional]
pub inner_name: Option<Cow<'static, str>>,
#[use_normal_rw]
pub inner_access: InnerClassFlags
}
#[derive(PartialEq, Debug, Clone, ConstantPoolReadWrite)]
#[attr_enum]
pub enum ClassAttribute {
Signature(ClassSignature),
Synthetic,
Deprecated,
SourceFile(Cow<'static, str>),
InnerClasses(#[vec_len_type(u16)] Vec<InnerClass>),
EnclosingMethod(#[str_type(Class)] Cow<'static, str>, Option<(Cow<'static,str>, Type)>),
SourceDebugExtension(#[use_normal_rw] SourceDebugExtension),
BootstrapMethods(#[vec_len_type(u16)] Vec<BootstrapMethod>),
Module(Module),
ModulePackages(#[vec_len_type(u16)] #[str_type(Package)] Vec<Cow<'static, str>>),
ModuleMainClass(#[str_type(Class)] Cow<'static, str>),
NestHost(#[str_type(Class)] Cow<'static, str>),
NestMembers(#[vec_len_type(u16)] #[str_type(Class)] Vec<Cow<'static, str>>),
#[raw_variant]
Raw(RawAttribute)
}