use mavinspect::protocol::{Dialect, Enum, EnumEntry, MavType};
use serde::Serialize;
use crate::conventions::split_description;
use crate::generator::GeneratorParams;
use crate::patches::patched_enum_entry_name_stripped;
use crate::specs::dialects::dialect::DialectModuleSpec;
use crate::specs::dialects::dialect::MsrvSpec;
use crate::specs::Spec;
pub(crate) struct EnumsRootModuleSpec<'a> {
dialect_canonical_name: &'a str,
enums: &'a [&'a Enum],
params: &'a GeneratorParams,
msrv: Option<&'a MsrvSpec<'a>>,
}
impl<'a> Spec for EnumsRootModuleSpec<'a> {
fn params(&self) -> &GeneratorParams {
self.params
}
}
impl<'a> EnumsRootModuleSpec<'a> {
pub(crate) fn new(dialect_spec: &'a DialectModuleSpec, params: &'a GeneratorParams) -> Self {
Self {
dialect_canonical_name: dialect_spec.canonical_name(),
enums: dialect_spec.enums(),
params,
msrv: dialect_spec.msrv(),
}
}
pub(crate) fn dialect_canonical_name(&self) -> &str {
self.dialect_canonical_name
}
pub(crate) fn enums(&self) -> &[&Enum] {
self.enums
}
pub(crate) fn msrv_name(&self) -> Option<&'a str> {
self.msrv.as_ref().map(|msrv| msrv.name)
}
}
#[derive(Debug, Clone, Serialize)]
pub(crate) struct EnumImplModuleSpec<'a> {
name: &'a str,
dialect: &'a Dialect,
description: Vec<String>,
inferred_type: MavType,
entries: Vec<EnumEntrySpec<'a>>,
is_bitmask: bool,
params: &'a GeneratorParams,
msrv: Option<&'a MsrvSpec<'a>>,
}
impl<'a> Spec for EnumImplModuleSpec<'a> {
fn params(&self) -> &GeneratorParams {
self.params
}
}
impl<'a> EnumImplModuleSpec<'a> {
pub(crate) fn new(mav_enum: &'a Enum, dialect_spec: &'a DialectModuleSpec) -> Self {
let mut entries: Vec<EnumEntrySpec> = mav_enum
.entries()
.iter()
.map(EnumEntrySpec::from_enum_entry)
.collect();
entries.sort_by_key(|entry| entry.value);
EnumImplModuleSpec {
name: mav_enum.name(),
dialect: dialect_spec.dialect(),
description: split_description(mav_enum.description()),
inferred_type: mav_enum.inferred_type(),
entries,
is_bitmask: mav_enum.bitmask(),
params: dialect_spec.params(),
msrv: dialect_spec.msrv(),
}
}
pub(crate) fn name(&self) -> &str {
self.name
}
pub(crate) fn is_bitmask(&self) -> bool {
self.is_bitmask
}
pub(crate) fn description(&self) -> &[String] {
self.description.as_slice()
}
pub(crate) fn entries(&self) -> &[EnumEntrySpec] {
self.entries.as_slice()
}
pub(crate) fn inferred_type(&self) -> &MavType {
&self.inferred_type
}
pub(crate) fn dialect(&self) -> &Dialect {
self.dialect
}
pub(crate) fn msrv(&self) -> Option<&'a MsrvSpec> {
self.msrv
}
pub(crate) fn msrv_name(&self) -> Option<&'a str> {
self.msrv.map(|msrv| msrv.name)
}
}
#[derive(Debug, Clone, Serialize)]
pub(crate) struct EnumEntrySpec<'a> {
value: u32,
name: &'a str,
name_stripped: String,
description: Vec<String>,
}
impl<'a> EnumEntrySpec<'a> {
pub(crate) fn from_enum_entry(entry: &'a EnumEntry) -> Self {
Self {
value: entry.value(),
name: entry.name(),
name_stripped: patched_enum_entry_name_stripped(entry),
description: split_description(entry.description()),
}
}
pub(crate) fn value(&self) -> u32 {
self.value
}
pub(crate) fn value_expr(&self) -> syn::Expr {
syn::parse_str(format!("{}", self.value()).as_str()).unwrap()
}
pub(crate) fn name(&self) -> &str {
self.name
}
pub(crate) fn name_stripped(&self) -> &str {
self.name_stripped.as_str()
}
pub(crate) fn description(&self) -> &[String] {
self.description.as_slice()
}
}
pub(crate) struct EnumInheritedModuleSpec<'a> {
mav_enum: &'a Enum,
dialect_canonical_name: &'a str,
original_dialect_name: &'a str,
params: &'a GeneratorParams,
msrv: Option<&'a MsrvSpec<'a>>,
}
impl<'a> EnumInheritedModuleSpec<'a> {
pub(crate) fn new(
mav_enum: &'a Enum,
dialect_spec: &'a DialectModuleSpec,
original_dialect_name: &'a str,
params: &'a GeneratorParams,
) -> Self {
Self {
mav_enum,
dialect_canonical_name: dialect_spec.canonical_name(),
original_dialect_name,
params,
msrv: dialect_spec.msrv(),
}
}
pub(crate) fn name(&self) -> &str {
self.mav_enum.name()
}
pub(crate) fn dialect_canonical_name(&self) -> &str {
self.dialect_canonical_name
}
pub(crate) fn original_dialect_name(&self) -> &str {
self.original_dialect_name
}
pub(crate) fn msrv_name(&self) -> Option<&'a str> {
self.msrv.map(|msrv| msrv.name)
}
}
impl<'a> Spec for EnumInheritedModuleSpec<'a> {
fn params(&self) -> &GeneratorParams {
self.params
}
}