///|
/// Returns a strict configuration that rejects potentially lossy input.
pub fn conservative_normalization_config() -> NormalizationConfig {
  {
    case_policy: Upper,
    punctuation: Reject,
    whitespace: Keep,
    hyphen: Reject,
    apostrophe: Reject,
    digits: Reject,
    fold_latin_diacritics: false,
    max_input_length: 256,
  }
}

///|
/// Returns the default configuration for Latin-script personal names.
pub fn name_normalization_config() -> NormalizationConfig {
  {
    case_policy: Upper,
    punctuation: Drop,
    whitespace: Keep,
    hyphen: Keep,
    apostrophe: Drop,
    digits: Reject,
    fold_latin_diacritics: true,
    max_input_length: 256,
  }
}

///|
/// Returns a copy with a different maximum input length.
pub fn NormalizationConfig::with_max_input_length(
  self : NormalizationConfig,
  max_input_length : Int,
) -> NormalizationConfig {
  {
    case_policy: self.case_policy,
    punctuation: self.punctuation,
    whitespace: self.whitespace,
    hyphen: self.hyphen,
    apostrophe: self.apostrophe,
    digits: self.digits,
    fold_latin_diacritics: self.fold_latin_diacritics,
    max_input_length,
  }
}

///|
/// Returns a copy with a different case policy.
pub fn NormalizationConfig::with_case_policy(
  self : NormalizationConfig,
  case_policy : CasePolicy,
) -> NormalizationConfig {
  {
    case_policy,
    punctuation: self.punctuation,
    whitespace: self.whitespace,
    hyphen: self.hyphen,
    apostrophe: self.apostrophe,
    digits: self.digits,
    fold_latin_diacritics: self.fold_latin_diacritics,
    max_input_length: self.max_input_length,
  }
}

///|
/// Returns a copy with policies for punctuation, whitespace, hyphens,
/// apostrophes, and digits in that order.
pub fn NormalizationConfig::with_character_policies(
  self : NormalizationConfig,
  punctuation : CharacterPolicy,
  whitespace : CharacterPolicy,
  hyphen : CharacterPolicy,
  apostrophe : CharacterPolicy,
  digits : CharacterPolicy,
) -> NormalizationConfig {
  {
    case_policy: self.case_policy,
    punctuation,
    whitespace,
    hyphen,
    apostrophe,
    digits,
    fold_latin_diacritics: self.fold_latin_diacritics,
    max_input_length: self.max_input_length,
  }
}

///|
/// Validates limits that affect normalization resource use.
pub fn validate_normalization_config(
  config : NormalizationConfig,
) -> Result[Unit, NormalizationError] {
  if config.max_input_length < 1 || config.max_input_length > 4096 {
    Err(InvalidMaximumLength(config.max_input_length))
  } else {
    Ok(())
  }
}