shared/matchers/segment.matcher.ts
shared/matchers/segment.matcher.ts is a file in GovLab Extension Host. 63 lines of code and 18 definitions.
import type { LetterCase, Splitter } from "../../types/taxonomy.types.ts";
const LOWER = "abcdefghijklmnopqrstuvwxyz";
const UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const DIGITS = "0123456789";
const SLOT_JOINER = "-";
const isLower = function isLower(char: string): boolean {
return char.length === 1 && LOWER.includes(char);
};
const isUpper = function isUpper(char: string): boolean {
return char.length === 1 && UPPER.includes(char);
};
const isDigit = function isDigit(char: string): boolean {
return char.length === 1 && DIGITS.includes(char);
};
const isLowerOrDigit = function isLowerOrDigit(char: string): boolean {
return isLower(char) || isDigit(char);
};
const fitsLetters = function fitsLetters(word: string, letters: LetterCase): boolean {
const isLetter = letters === "upper" ? isUpper : isLower;
return word !== "" && Array.from(word, (char) => isLetter(char) || isDigit(char)).every(Boolean);
};
const joinedWords = function joinedWords(stem: string, joiner: string, letters: LetterCase): readonly string[] | null {
const words = stem.split(joiner);
return words.every((word) => fitsLetters(word, letters)) ? words.map((word) => word.toLowerCase()) : null;
};
const humpedWords = function humpedWords(stem: string, leadsUpper: boolean): readonly string[] | null {
const first = stem.charAt(0);
if (stem === "" || isUpper(first) !== leadsUpper || !(isUpper(first) || isLower(first))) {
return null;
}
const words: string[] = [];
let current = "";
for (const char of stem) {
if (isUpper(char)) {
if (current !== "") {
words.push(current);
}
current = char.toLowerCase();
} else if (isLowerOrDigit(char)) {
current += char;
} else {
return null;
}
}
words.push(current);
return words;
};
export const isWellFormedJoiner = function isWellFormedJoiner(joiner: string): boolean {
for (const char of joiner) {
if (isLower(char) || isUpper(char) || isDigit(char)) {
return false;
}
}
return joiner !== "";
};
export const wordsOf = function wordsOf(stem: string, splitter: Splitter): readonly string[] | null {
return splitter.joiner === null
? humpedWords(stem, splitter.letters === "upper")
: joinedWords(stem, splitter.joiner, splitter.letters);
};
export const slotWordOf = function slotWordOf(words: readonly string[]): string {
return words.join(SLOT_JOINER);
};