use proc_macro2::Span;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BitOrder {
Msb0,
Lsb0,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StorageKind {
U8,
U16,
U32,
U64,
U128,
}
impl StorageKind {
pub fn bit_width(self) -> u32 {
match self {
StorageKind::U8 => 8,
StorageKind::U16 => 16,
StorageKind::U32 => 32,
StorageKind::U64 => 64,
StorageKind::U128 => 128,
}
}
pub fn ident(self) -> &'static str {
match self {
StorageKind::U8 => "u8",
StorageKind::U16 => "u16",
StorageKind::U32 => "u32",
StorageKind::U64 => "u64",
StorageKind::U128 => "u128",
}
}
pub fn from_str(s: &str) -> Option<Self> {
match s {
"u8" => Some(StorageKind::U8),
"u16" => Some(StorageKind::U16),
"u32" => Some(StorageKind::U32),
"u64" => Some(StorageKind::U64),
"u128" => Some(StorageKind::U128),
_ => None,
}
}
pub fn smallest_fitting(bits: u32) -> Option<Self> {
if bits <= 8 {
Some(StorageKind::U8)
} else if bits <= 16 {
Some(StorageKind::U16)
} else if bits <= 32 {
Some(StorageKind::U32)
} else if bits <= 64 {
Some(StorageKind::U64)
} else if bits <= 128 {
Some(StorageKind::U128)
} else {
None
}
}
}
#[derive(Debug, Clone)]
pub struct BitfieldArgs {
pub storage: StorageKind,
pub storage_span: Span,
pub order: BitOrder,
#[allow(dead_code)]
pub order_span: Span,
pub width: Option<u32>,
pub width_span: Option<Span>,
}
#[derive(Debug, Clone, Copy)]
pub struct BitRange {
pub start: u32,
pub end: u32,
pub span: Span,
}
impl BitRange {
pub fn width(&self) -> u32 {
self.end - self.start + 1
}
pub fn overlaps(&self, other: &BitRange) -> bool {
self.start <= other.end && other.start <= self.end
}
}
#[derive(Clone)]
pub enum FieldType {
Bool,
Primitive(StorageKind),
Nested(syn::Type),
}
#[derive(Clone)]
pub struct FieldDef {
pub name: syn::Ident,
pub accessor_name: String,
pub ty: FieldType,
#[allow(dead_code)]
pub raw_ty: syn::Type,
pub range: BitRange,
pub readonly: bool,
pub aliases: Vec<String>,
pub overlay: Option<String>,
pub span: Span,
}
#[derive(Clone)]
pub struct BitfieldDef {
pub args: BitfieldArgs,
pub effective_width: u32,
pub fields: Vec<FieldDef>,
pub vis: syn::Visibility,
pub name: syn::Ident,
pub user_attrs: Vec<syn::Attribute>,
}