use proc_macro2::Span;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BitOrder {
Msb0,
Lsb0,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StorageKind {
W8,
W16,
W32,
W64,
W128,
}
impl StorageKind {
pub fn bit_width(self) -> u32 {
match self {
StorageKind::W8 => 8,
StorageKind::W16 => 16,
StorageKind::W32 => 32,
StorageKind::W64 => 64,
StorageKind::W128 => 128,
}
}
pub fn unsigned_ident(self) -> &'static str {
match self {
StorageKind::W8 => "u8",
StorageKind::W16 => "u16",
StorageKind::W32 => "u32",
StorageKind::W64 => "u64",
StorageKind::W128 => "u128",
}
}
pub fn signed_ident(self) -> &'static str {
match self {
StorageKind::W8 => "i8",
StorageKind::W16 => "i16",
StorageKind::W32 => "i32",
StorageKind::W64 => "i64",
StorageKind::W128 => "i128",
}
}
pub fn from_unsigned_str(s: &str) -> Option<Self> {
match s {
"u8" => Some(StorageKind::W8),
"u16" => Some(StorageKind::W16),
"u32" => Some(StorageKind::W32),
"u64" => Some(StorageKind::W64),
"u128" => Some(StorageKind::W128),
_ => None,
}
}
pub fn from_signed_str(s: &str) -> Option<Self> {
match s {
"i8" => Some(StorageKind::W8),
"i16" => Some(StorageKind::W16),
"i32" => Some(StorageKind::W32),
"i64" => Some(StorageKind::W64),
"i128" => Some(StorageKind::W128),
_ => None,
}
}
pub fn smallest_fitting(bits: u32) -> Option<Self> {
if bits <= 8 {
Some(StorageKind::W8)
} else if bits <= 16 {
Some(StorageKind::W16)
} else if bits <= 32 {
Some(StorageKind::W32)
} else if bits <= 64 {
Some(StorageKind::W64)
} else if bits <= 128 {
Some(StorageKind::W128)
} 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,
PrimitiveUnsigned(StorageKind),
PrimitiveSigned(StorageKind),
Nested(syn::Type),
}
#[derive(Clone)]
pub struct FieldDef {
pub name: syn::Ident,
pub accessor_name: String,
pub ty: FieldType,
pub raw_ty: syn::Type,
pub range: BitRange,
pub readonly: bool,
pub aliases: Vec<String>,
pub overlay: Option<String>,
pub default: Option<syn::Expr>,
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<proc_macro2::TokenStream>,
pub debug_span: Option<proc_macro2::Span>,
pub default_span: Option<proc_macro2::Span>,
pub copy_span: Option<proc_macro2::Span>,
pub clone_span: Option<proc_macro2::Span>,
}