rjvm 0.3.0

Parse JVM class files with Rust
Documentation
use crate::bytecode::attributes::Attribute;
use crate::bytecode::flags::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags};
use crate::bytecode::pool::{ConstantPool, ConstantPoolIndex};

pub mod attributes;
pub mod descriptors;
pub mod flags;
pub mod pool;
pub mod reader;

#[derive(Debug, Clone, PartialEq)]
pub enum BytecodeError {
    ConstantPoolEntryAlreadyExists,
    ConstantPoolEntryNotFound,
    UnsupportedAttributeName,
    InvalidClassFile,
    UnexpectedEndOfData,
    InvalidData,
    UnsupportedInstruction,
    InvalidDescriptor,
    UnsupportedVerificationType,
}

#[derive(Debug)]
pub struct ClassFileVersion {
    pub minor: u16,
    pub major: u16,
}

#[derive(Debug)]
pub struct ClassFile {
    pub magic_number: u32,
    pub version: ClassFileVersion,
    pub constant_pool_count: u16,
    pub constant_pool: ConstantPool,
    pub access_flags: ClassAccessFlags,
    pub this_class: ConstantPoolIndex,
    pub super_class: ConstantPoolIndex,
    pub interfaces_count: u16,
    pub interfaces: Vec<Interface>,
    pub fields_count: u16,
    pub fields: Vec<Field>,
    pub methods_count: u16,
    pub methods: Vec<Method>,
    pub attributes_count: u16,
    pub attributes: Vec<Attribute>,
}

#[derive(Debug)]
pub struct Field {
    pub name: String,
    pub descriptor: Descriptor,
    pub access_flags: FieldAccessFlags,
    pub attributes: Vec<Attribute>,
}

#[derive(Debug)]
pub struct Method {
    pub access_flags: MethodAccessFlags,
    pub name: String,
    pub descriptor: Vec<Descriptor>,
    pub attributes: Vec<Attribute>,
}

#[derive(Debug)]
pub struct Interface {
    pub name_index: ConstantPoolIndex,
}

#[derive(Debug, Clone, PartialEq)]
pub enum DescriptorKind {
    Parameter,
    Return,
    Type,
}

#[derive(Debug, Clone, PartialEq)]
pub struct Descriptor {
    pub kind: DescriptorKind,
    pub ty: FieldType,
}

impl std::fmt::Display for Descriptor {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.ty)
    }
}

#[derive(Debug, Clone, PartialEq)]
pub enum FieldType {
    Base(BaseType),
    Object(String),
    Array(Box<FieldType>),
}

impl std::fmt::Display for FieldType {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            FieldType::Base(ty) => write!(f, "{}", ty),
            FieldType::Object(ty) => write!(f, "{}", ty),
            FieldType::Array(ty) => write!(f, "[{}]", ty),
        }
    }
}

#[derive(Debug, Clone, PartialEq)]
pub enum BaseType {
    Byte,
    Char,
    Double,
    Float,
    Int,
    Long,
    Short,
    Boolean,
    Void,
}

impl std::fmt::Display for BaseType {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            BaseType::Byte => write!(f, "byte"),
            BaseType::Char => write!(f, "char"),
            BaseType::Double => write!(f, "double"),
            BaseType::Float => write!(f, "float"),
            BaseType::Int => write!(f, "int"),
            BaseType::Long => write!(f, "long"),
            BaseType::Short => write!(f, "short"),
            BaseType::Boolean => write!(f, "boolean"),
            BaseType::Void => write!(f, "void"),
        }
    }
}