use super::korean_context::{KoreanPrefixInput, match_korean_prefix};
use crate::english::encode_english;
use std::sync::LazyLock;
static KOREAN_WORD_ENGINE: LazyLock<super::engine::EnglishUebEngine> =
LazyLock::new(super::engine::EnglishUebEngine::new);
pub(crate) struct KoreanSpanUnit {
pub(crate) cells: Vec<u8>,
pub(crate) consumed: usize,
pub(crate) contracted: bool,
}
#[expect(
clippy::too_many_arguments,
reason = "the wrapper preserves the engine's independent UEB rule gates"
)]
pub(crate) fn encode_korean_word(
chars: &[char],
suppress_caps: bool,
prepend_grade1_indicator: bool,
standing_alone: bool,
shortform_usable: bool,
word_initial: bool,
digit_adjacent: bool,
numeric_grade1_active: bool,
apostrophe_joined_lexeme: bool,
letter_initialism: bool,
) -> Option<Vec<u8>> {
KOREAN_WORD_ENGINE.encode_korean_word(
chars,
suppress_caps,
prepend_grade1_indicator,
standing_alone,
shortform_usable,
word_initial,
digit_adjacent,
numeric_grade1_active,
apostrophe_joined_lexeme,
letter_initialism,
)
}
pub(crate) fn encode_korean_unit(input: KoreanPrefixInput<'_>) -> Result<KoreanSpanUnit, String> {
let letter = input.word[input.pos];
match match_korean_prefix(input) {
Some(matched) => Ok(KoreanSpanUnit {
cells: matched.cells,
consumed: matched.consumed,
contracted: true,
}),
None => Ok(KoreanSpanUnit {
cells: vec![encode_english(letter)?],
consumed: 1,
contracted: false,
}),
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::unicode::decode_unicode;
fn unit(word: &str, pos: usize, wrap_active: bool) -> KoreanSpanUnit {
let chars: Vec<char> = word.chars().collect();
encode_korean_unit(KoreanPrefixInput {
word: &chars,
pos,
wrap_active,
is_all_uppercase: false,
at_entry: pos == 0,
standalone_wordsign: false,
})
.unwrap()
}
#[rstest::rstest]
#[case::plain_a("cat", 0, decode_unicode('⠉'), 1)]
#[case::plain_t("cat", 2, decode_unicode('⠞'), 1)]
fn falls_back_to_single_letter(
#[case] word: &str,
#[case] pos: usize,
#[case] expected_cell: u8,
#[case] consumed: usize,
) {
let u = unit(word, pos, false);
assert_eq!(u.cells, vec![expected_cell]);
assert_eq!(u.consumed, consumed);
}
#[test]
fn restricted_contraction_ong() {
let u = unit("pyeongchang", 3, false);
assert_eq!(u.cells, vec![decode_unicode('⠰'), decode_unicode('⠛')]);
assert_eq!(u.consumed, 3);
}
}