use indexmap::IndexMap;
use rkyv::{Archive, Deserialize, Serialize};
#[derive(Debug, Default, Archive, Serialize, Deserialize)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[rkyv(derive(Debug))]
pub struct Profile {
pub architecture: Architecture,
pub enums: IndexMap<String, Enum>,
pub structs: IndexMap<String, Struct>,
pub symbols: IndexMap<String, u64>,
}
#[derive(Debug, Default, Archive, Serialize, Deserialize)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[rkyv(derive(Debug))]
pub enum Architecture {
#[default]
Unknown,
X86,
Amd64,
Arm32,
Arm64,
}
#[derive(Debug, Archive, Serialize, Deserialize)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[rkyv(derive(Debug))]
pub struct Enum {
pub subtype: Type,
pub fields: IndexMap<String, Variant>,
}
#[allow(missing_docs)]
#[derive(Debug, Archive, Serialize, Deserialize)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(untagged)
)]
#[rkyv(derive(Debug))]
pub enum Variant {
U8(u8),
U16(u16),
U32(u32),
U64(u64),
U128(u128),
I8(i8),
I16(i16),
I32(i32),
I64(i64),
I128(i128),
}
#[derive(Debug, Archive, Serialize, Deserialize)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[rkyv(derive(Debug))]
pub struct Struct {
pub kind: StructKind,
pub size: u64,
pub fields: IndexMap<String, Field>,
}
#[derive(Debug, Archive, Serialize, Deserialize)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(rename_all = "snake_case")
)]
#[rkyv(derive(Debug))]
pub enum StructKind {
Struct,
Class,
Union,
Interface,
}
#[derive(Debug, Archive, Serialize, Deserialize)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[rkyv(derive(Debug))]
pub struct Field {
pub offset: u64,
#[cfg_attr(feature = "serde", serde(rename = "type"))]
pub ty: Type,
}
#[derive(Debug, Archive, Serialize, Deserialize)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(rename_all = "snake_case", tag = "kind")
)]
#[rkyv(derive(Debug))]
pub enum Type {
Base(Base),
Enum(EnumRef),
Struct(StructRef),
Array(Array),
Pointer(Pointer),
Bitfield(Bitfield),
Function,
}
#[allow(missing_docs)]
#[derive(Debug, Archive, Serialize, Deserialize)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(rename_all = "snake_case", tag = "subkind")
)]
#[rkyv(derive(Debug))]
pub enum Base {
Void,
Bool,
Char8,
Char16,
Char32,
I8,
I16,
I32,
I64,
I128,
U8,
U16,
U32,
U64,
U128,
F8,
F16,
F32,
F64,
F128,
}
impl Base {
pub fn size(&self) -> u64 {
match self {
Self::Void => 0,
Self::Char8 | Self::I8 | Self::U8 | Self::F8 | Self::Bool => 1,
Self::Char16 | Self::I16 | Self::U16 | Self::F16 => 2,
Self::Char32 | Self::I32 | Self::U32 | Self::F32 => 4,
Self::I64 | Self::U64 | Self::F64 => 8,
Self::I128 | Self::U128 | Self::F128 => 16,
}
}
}
impl ArchivedBase {
pub fn size(&self) -> u64 {
match self {
Self::Void => 0,
Self::Char8 | Self::I8 | Self::U8 | Self::F8 | Self::Bool => 1,
Self::Char16 | Self::I16 | Self::U16 | Self::F16 => 2,
Self::Char32 | Self::I32 | Self::U32 | Self::F32 => 4,
Self::I64 | Self::U64 | Self::F64 => 8,
Self::I128 | Self::U128 | Self::F128 => 16,
}
}
}
#[derive(Debug, Archive, Serialize, Deserialize)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[rkyv(derive(Debug))]
pub struct EnumRef {
pub name: String,
}
#[derive(Debug, Archive, Serialize, Deserialize)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[rkyv(derive(Debug))]
pub struct StructRef {
pub name: String,
}
#[derive(Debug, Archive, Serialize, Deserialize)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[rkyv(
derive(Debug),
serialize_bounds(
__S: rkyv::ser::Writer + rkyv::ser::Allocator,
__S::Error: rkyv::rancor::Source,
),
deserialize_bounds(
__D::Error: rkyv::rancor::Source,
),
bytecheck(bounds(
__C: rkyv::validation::ArchiveContext,
__C::Error: rkyv::rancor::Source,
)
))]
pub struct Array {
#[rkyv(omit_bounds)]
pub subtype: Box<Type>,
pub dims: Vec<u64>,
}
#[derive(Debug, Archive, Serialize, Deserialize)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[rkyv(
derive(Debug),
serialize_bounds(
__S: rkyv::ser::Writer + rkyv::ser::Allocator,
__S::Error: rkyv::rancor::Source,
),
deserialize_bounds(
__D::Error: rkyv::rancor::Source,
),
bytecheck(bounds(
__C: rkyv::validation::ArchiveContext,
__C::Error: rkyv::rancor::Source,
)
))]
pub struct Bitfield {
#[rkyv(omit_bounds)]
pub subtype: Box<Type>,
pub bit_length: u64,
pub bit_position: u64,
}
#[derive(Debug, Archive, Serialize, Deserialize)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[rkyv(
derive(Debug),
serialize_bounds(
__S: rkyv::ser::Writer + rkyv::ser::Allocator,
__S::Error: rkyv::rancor::Source,
),
deserialize_bounds(
__D::Error: rkyv::rancor::Source,
),
bytecheck(bounds(
__C: rkyv::validation::ArchiveContext,
__C::Error: rkyv::rancor::Source,
)
))]
pub struct Pointer {
#[rkyv(omit_bounds)]
pub subtype: Box<Type>,
pub size: u64,
}