textmetrics/search

Convenience helpers for spell-correction-style search built on distance and similarity.

Both functions are deterministic: ties are broken by the candidates’ original input order.

Types

A scored candidate produced by rank_jaro_winkler.

Both fields are labelled so callers can read them directly as r.label and r.score without destructuring a tuple.

pub type Ranked {
  Ranked(label: String, score: Float)
}

Constructors

  • Ranked(label: String, score: Float)

Values

pub fn closest(
  query: String,
  candidates: List(String),
  max_distance: Int,
) -> Result(String, Nil)

Single closest candidate within max_distance Levenshtein graphemes of query. Returns Error(Nil) when no candidate is close enough or when candidates is empty.

This is the convenience form of did_you_mean for the dominant CLI use case (“Unknown command. Did you mean X?”). Ties on distance are broken by the candidate’s position in candidates — the first qualifying candidate wins.

pub fn did_you_mean(
  query: String,
  candidates: List(String),
  max_distance: Int,
) -> List(String)

Return candidates within max_distance Levenshtein graphemes of query, sorted ascending by distance. Empty list when nothing matches or when candidates is empty.

Ties on distance are broken by the candidate’s position in candidates.

pub fn rank_jaro_winkler(
  query: String,
  candidates: List(String),
  top_n: Int,
) -> List(Ranked)

Rank candidates by Jaro-Winkler similarity (Winkler-1990 defaults) descending, returning up to top_n Ranked records.

Ties on similarity are broken by the candidate’s position in candidates. When top_n <= 0 returns an empty list.

Search Document