use crate::{Ctx, ast};
use core::fmt;
#[derive(Debug, Clone)]
#[derive(liberty_macros::Group)]
#[mut_set::derive::item]
#[derive(serde::Serialize, serde::Deserialize)]
#[serde(bound = "C::Pin: serde::Serialize + serde::de::DeserializeOwned")]
pub struct BusType<C: Ctx> {
#[id(borrow = str)]
#[liberty(name)]
pub name: String,
#[liberty(comments)]
comments: ast::GroupComments,
#[liberty(extra_ctx)]
pub extra_ctx: C::Pin,
#[liberty(attributes)]
pub attributes: ast::Attributes,
#[liberty(simple)]
pub base_type: BaseType,
#[liberty(simple)]
#[liberty(default = 0)]
pub bit_from: usize,
#[liberty(simple)]
#[liberty(default = 0)]
pub bit_to: usize,
#[liberty(simple)]
#[liberty(default = 1)]
pub bit_width: usize,
#[liberty(simple)]
pub data_type: DataType,
#[liberty(simple(type = Option))]
pub downto: Option<bool>,
}
impl<C: Ctx> ast::GroupFn<C> for BusType<C> {
fn before_build(builder: &mut Self::Builder, scope: &mut ast::BuilderScope<C>) {
_ = scope.bus_type.insert(
builder.name.clone(),
BusTypeCtx {
base_type: builder.base_type,
bit_from: builder.bit_from,
bit_to: builder.bit_to,
bit_width: builder.bit_width,
data_type: builder.data_type,
downto: builder.downto,
},
);
}
}
#[derive(Debug, Clone, Default)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct SimpleBusType {
pub name: String,
pub ctx: Option<BusTypeCtx>,
}
#[derive(Debug, Clone, Copy)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct BusTypeCtx {
pub base_type: BaseType,
pub bit_from: usize,
pub bit_to: usize,
pub bit_width: usize,
pub data_type: DataType,
pub downto: Option<bool>,
}
impl<C: Ctx> ast::ParsingBuilder<C> for SimpleBusType {
type Builder = String;
#[expect(clippy::renamed_function_params)]
fn build(name: Self::Builder, scope: &mut ast::BuilderScope<C>) -> Self {
Self { ctx: scope.bus_type.get(&name).copied(), name }
}
}
impl<C: Ctx> ast::SimpleAttri<C> for SimpleBusType {
fn nom_parse<'a>(
i: &'a str,
scope: &mut ast::ParseScope<'_>,
) -> ast::SimpleParseRes<'a, Self::Builder> {
ast::nom_parse_from_str::<C, _>(i, scope)
}
fn fmt_self<T: fmt::Write, I: ast::Indentation>(
&self,
f: &mut ast::CodeFormatter<'_, T, I>,
) -> fmt::Result {
ast::SimpleAttri::<C>::fmt_self(&self.name, f)
}
fn is_set(&self) -> bool {
!self.name.is_empty()
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, strum::Display, strum::EnumString, Default)]
#[derive(serde::Serialize, serde::Deserialize)]
pub enum BaseType {
#[default]
#[strum(serialize = "array")]
Array,
}
crate::ast::impl_self_builder!(BaseType);
crate::ast::impl_simple!(BaseType);
#[derive(Debug, Clone, Copy, Eq, PartialEq, strum::Display, strum::EnumString, Default)]
#[derive(serde::Serialize, serde::Deserialize)]
pub enum DataType {
#[default]
#[strum(serialize = "bit")]
Bit,
}
crate::ast::impl_self_builder!(DataType);
crate::ast::impl_simple!(DataType);