Framework for embedding localizations into Rust types
macro_rules! impl_with_default {
    ($newtype:ident, $field_type:ty) => {
        impl<'environment> $newtype<'environment> {
            #[must_use]
            pub const fn with_default(mut self, default: $field_type) -> Self {
                self.default = Some(default);
                self
            }
        }
    };
}

macro_rules! impl_with_validator {
    ($newtype:ident) => {
        impl<'environment> $newtype<'environment> {
            pub fn with_validator<
                L: l10n_embed::Localize,
                V: Fn(&String) -> Result<(), L> + 'static,
            >(
                mut self,
                validator: V,
            ) -> Self {
                let locale = self.environment.locale.clone();
                self.validator = Some(Box::new(move |input: &String| -> Result<(), String> {
                    match validator(input) {
                        Ok(()) => Ok(()),
                        Err(message) => {
                            // Localize the error message
                            Err(message.localize_for(&locale))
                        }
                    }
                }));

                self
            }
        }
    };
}

// Re-export the macro helpers for other modules to use
pub(crate) use {impl_with_default, impl_with_validator};