use super :: *;
use macro_tools :: { Result, syn_err };
use super ::field_attrs ::FieldAttributes;
pub fn validate_variant_attributes(
variant: &syn ::Variant,
variant_attrs: &FieldAttributes,
field_count: usize,
variant_type: VariantType,
) -> Result< () >
{
validate_attribute_combinations(variant, variant_attrs)?;
validate_variant_type_compatibility(variant, variant_attrs, variant_type)?;
validate_field_count_requirements(variant, variant_attrs, field_count, variant_type)?;
Ok(())
}
#[ derive( Debug, Clone, Copy, PartialEq, Eq ) ]
pub enum VariantType
{
Unit,
Tuple,
Struct,
}
fn validate_attribute_combinations(
variant: &syn ::Variant,
variant_attrs: &FieldAttributes,
) -> Result< () >
{
if variant_attrs.scalar.is_some() && variant_attrs.subform_scalar.is_some()
{
if matches!(variant.fields, syn ::Fields ::Named(_))
{
} else {
return Err(syn_err!(
variant,
"Cannot use both #[ scalar ] and #[ subform_scalar ] on the same variant. \
These attributes have conflicting behaviors for tuple variants. \
Choose either #[ scalar ] for direct construction or #[ subform_scalar ] for subform construction."
));
}
}
Ok(())
}
fn validate_variant_type_compatibility(
variant: &syn ::Variant,
variant_attrs: &FieldAttributes,
variant_type: VariantType,
) -> Result< () >
{
if variant_attrs.subform_scalar.is_some()
{
match variant_type
{
VariantType ::Unit =>
{
return Err(syn_err!(
variant,
"#[ subform_scalar ] cannot be used on unit variants. \
Unit variants have no fields to form. \
Consider removing the #[ subform_scalar ] attribute."
));
}
VariantType ::Tuple | VariantType ::Struct =>
{
}
}
}
Ok(())
}
fn validate_field_count_requirements(
variant: &syn ::Variant,
variant_attrs: &FieldAttributes,
field_count: usize,
variant_type: VariantType,
) -> Result< () >
{
if variant_attrs.subform_scalar.is_some()
{
match (variant_type, field_count)
{
(VariantType ::Tuple | VariantType ::Struct, 0) =>
{
return Err(syn_err!(
variant,
"#[ subform_scalar ] cannot be used on zero-field variants. \
Zero-field variants have no fields to form. \
Consider using #[ scalar ] attribute instead for direct construction."
));
}
(VariantType ::Tuple, count) if count > 1 =>
{
return Err(syn_err!(
variant,
"#[ subform_scalar ] cannot be used on multi-field tuple variants. \
Multi-field tuple variants have ambiguous field selection for subform construction. \
Consider using #[ scalar ] for direct construction with all fields as parameters, \
or restructure as a struct variant for field-specific subform construction."
));
}
_ =>
{
}
}
}
if variant_type == VariantType ::Struct && field_count == 0
&& variant_attrs.scalar.is_none() && variant_attrs.subform_scalar.is_none() {
return Err(syn_err!(
variant,
"Zero-field struct variants require explicit #[ scalar ] attribute for disambiguation. \
Add #[ scalar ] to generate a direct constructor for this variant."
));
}
Ok(())
}
pub fn get_field_count(fields: &syn ::Fields) -> usize
{
match fields
{
syn ::Fields ::Unit => 0,
syn ::Fields ::Unnamed(fields) => fields.unnamed.len(),
syn ::Fields ::Named(fields) => fields.named.len(),
}
}
pub fn get_variant_type(fields: &syn ::Fields) -> VariantType
{
match fields
{
syn ::Fields ::Unit => VariantType ::Unit,
syn ::Fields ::Unnamed(_) => VariantType ::Tuple,
syn ::Fields ::Named(_) => VariantType ::Struct,
}
}