mapper-impl 1.1.2

Implementation detail of the `mapper` crate
Documentation
use syn::{Error, Result};

use crate::ast::{data_type::Struct, Input};
impl Input<'_> {
    pub(crate) fn validate(&self) -> Result<()> {
        match self {
            Input::Struct(input) => input.validate(),
        }
    }
}

impl Struct<'_> {
    fn validate(&self) -> Result<()> {
        for field in &self.fields {
            for field_to in &field.attrs.to.to_items {
                if field_to.params.destination.is_none() {
                    break;
                }
                let field_dest = field_to.params.destination.as_ref().unwrap();
                for field_strategy in &field_to.params.strategies {
                    if let Some(struct_destinations) =
                        self.attrs.to.destinations_by_strategy.get(field_strategy)
                    {
                        if struct_destinations.contains(field_dest) {
                            return Err(Error::new_spanned(
                                &field_strategy.0,
                                format!(
                                    "Additive mapping not works for destination ({}) and strategy ({}) because it's already used in automatic mapping", 
                                    field_dest.path.get_ident().unwrap(),
                                    field_strategy
                            ),
                            ));
                        }
                    }
                }
                if field_to.params.exclude.1 && !self.attrs.to.destinations().contains(field_dest) {
                    return Err(Error::new_spanned(
                        &field_to.params.exclude.0,
                         format!(
                            "Cannot exclude a field for a destination ({}) not referenced in automatic mapping",
                             field_dest.path.get_ident().unwrap())
                            ));
                }

                for field_with in &field_to.params.with {
                    if !self.has_strategy_for_destination(field_dest, &field_with.1) {
                        return Err(Error::new_spanned(
                            field_with.0.clone(),
                             format!(
                                "There is no destination and strategy matching with strategy ({}) and destination ({})",
                                field_with.1,
                                field_dest.path.get_ident().unwrap()
                            )));
                    }
                }
            }
        }
        Ok(())
    }
}