///|
/// Assigns a non-negative contribution weight to a phonetic encoder.
pub(all) struct EncoderWeight {
  algorithm : Algorithm
  weight : Double
} derive(Eq, Debug)

///|
/// Configures normalization, evidence components, and the decision boundary.
pub(all) struct MatchConfig {
  normalization : NormalizationConfig
  encoders : Array[EncoderWeight]
  metric : SimilarityMetric
  string_weight : Double
  threshold : Double
  token_policy : TokenPolicy
  unmatched_token_penalty : Double
} derive(Eq, Debug)

///|
/// Records one raw and weighted score used in a matching decision.
pub(all) struct ComponentScore {
  name : String
  raw_score : Double
  weight : Double
  contribution : Double
} derive(Eq, Debug)

///|
/// Contains the normalized values, keys, components, and final decision.
pub(all) struct MatchEvidence {
  left_normalized : String
  right_normalized : String
  left_keys : Array[EncodedKeys]
  right_keys : Array[EncodedKeys]
  components : Array[ComponentScore]
  score : Double
  threshold : Double
  matched : Bool
  notices : Array[String]
} derive(Eq, Debug)

///|
/// Reports invalid matching configuration or a failed matching stage.
pub(all) enum MatchError {
  InvalidThreshold(Double)
  InvalidEncoderWeight(Algorithm, Double)
  InvalidStringWeight(Double)
  NoPositiveComponents
  DuplicateEncoder(Algorithm)
  InvalidUnmatchedTokenPenalty(Double)
  InvalidNormalizationConfig(NormalizationError)
  InvalidSimilarityMetric(SimilarityError)
  NormalizationFailed(NormalizationError)
  SimilarityFailed(SimilarityError)
} derive(Eq, Debug)