use crate::attrs::LeafOverride;
use crate::ir::TupleElement;
use crate::type_analysis::{AnalyzedBase, AnalyzedType, RawWrapper};
use proc_macro2::Span;
use super::errors;
use super::leaf::default_leaf_for_base;
use super::wrappers::normalize_wrappers;
#[derive(Clone, Copy)]
pub(super) enum FieldAttrRef<'a> {
Binary { span: Span },
Leaf { value: &'a LeafOverride, span: Span },
}
pub(super) fn reject_attrs_on_tuple(
_field: &syn::Field,
field_display_name: &str,
override_: Option<FieldAttrRef<'_>>,
) -> Result<(), syn::Error> {
let (attr, span) = match override_ {
None => return Ok(()),
Some(FieldAttrRef::Binary { span }) => ("as_binary", span),
Some(FieldAttrRef::Leaf {
value: override_,
span,
}) => match override_ {
LeafOverride::AsStr => ("as_str", span),
LeafOverride::AsString => ("as_string", span),
LeafOverride::Decimal { .. } => ("decimal(...)", span),
LeafOverride::TimeUnit(_) => ("time_unit = \"...\"", span),
},
};
Err(errors::unsupported_tuple_attr_at(
span,
field_display_name,
attr,
))
}
pub(super) fn analyzed_to_tuple_element(
analyzed: AnalyzedType,
field_display_name: &str,
) -> Result<TupleElement, syn::Error> {
let leaf_spec =
default_leaf_for_base(&analyzed.field_ty, field_display_name, analyzed.base, false)?;
let wrapper_shape = normalize_wrappers(&analyzed.wrappers);
Ok(TupleElement {
leaf_spec,
wrapper_shape,
outer_smart_ptr_depth: analyzed.outer_smart_ptr_depth,
})
}
const fn has_semantic_wrappers(wrappers: &[RawWrapper]) -> bool {
!wrappers.is_empty()
}
pub(super) fn reject_unsupported_wrapped_nested_tuples(
analyzed: &AnalyzedType,
field_display_name: &str,
) -> Result<(), syn::Error> {
let AnalyzedBase::Tuple(elements) = &analyzed.base else {
return Ok(());
};
let parent_wrapped = has_semantic_wrappers(&analyzed.wrappers);
for element in elements {
if matches!(element.base, AnalyzedBase::Tuple(_))
&& (parent_wrapped || has_semantic_wrappers(&element.wrappers))
{
return Err(errors::unsupported_wrapped_nested_tuple(
&element.field_ty,
field_display_name,
));
}
reject_unsupported_wrapped_nested_tuples(element, field_display_name)?;
}
Ok(())
}