use icu_locale_core::{LanguageIdentifier, langid};
use icu_segmenter::options::LineBreakOptions;
use icu_segmenter::options::LineBreakStrictness;
use icu_segmenter::options::LineBreakWordOption;
use icu_segmenter::*;
include!("helpers.rs.raw");
static JA: LanguageIdentifier = langid!("ja");
#[track_caller]
fn strict(s: &str, ja_zh: bool, expected: &[&str]) {
let mut options = LineBreakOptions::default();
options.strictness = Some(LineBreakStrictness::Strict);
options.word_option = Some(LineBreakWordOption::Normal);
options.content_locale = ja_zh.then_some(&JA);
check_line(s, expected, LineSegmenter::new_dictionary(options));
check_line(s, expected, {
let mut s = LineSegmenter::new_17_for_non_complex_scripts(options);
s.load_dictionary();
s
});
check_line(s, expected, {
let mut s = LineSegmenter::new_neo_for_non_complex_scripts(options);
s.load_dictionary();
s
});
}
#[track_caller]
fn normal(s: &str, ja_zh: bool, expected: &[&str]) {
let mut options = LineBreakOptions::default();
options.strictness = Some(LineBreakStrictness::Normal);
options.word_option = Some(LineBreakWordOption::Normal);
options.content_locale = ja_zh.then_some(&JA);
check_line(s, expected, LineSegmenter::new_dictionary(options));
check_line(s, expected, {
let mut s = LineSegmenter::new_17_for_non_complex_scripts(options);
s.load_dictionary();
s
});
check_line(s, expected, {
let mut s = LineSegmenter::new_neo_for_non_complex_scripts(options);
s.load_dictionary();
s
});
}
#[track_caller]
fn loose(s: &str, ja_zh: bool, expected: &[&str]) {
let mut options = LineBreakOptions::default();
options.strictness = Some(LineBreakStrictness::Loose);
options.word_option = Some(LineBreakWordOption::Normal);
options.content_locale = ja_zh.then_some(&JA);
check_line(s, expected, LineSegmenter::new_dictionary(options));
check_line(s, expected, {
let mut s = LineSegmenter::new_17_for_non_complex_scripts(options);
s.load_dictionary();
s
});
check_line(s, expected, {
let mut s = LineSegmenter::new_neo_for_non_complex_scripts(options);
s.load_dictionary();
s
});
}
#[track_caller]
fn anywhere(s: &str, ja_zh: bool, expected: &[&str]) {
let mut options = LineBreakOptions::default();
options.strictness = Some(LineBreakStrictness::Anywhere);
options.word_option = Some(LineBreakWordOption::Normal);
options.content_locale = ja_zh.then_some(&JA);
check_line(s, expected, LineSegmenter::new_dictionary(options));
check_line(s, expected, {
let mut s = LineSegmenter::new_17_for_non_complex_scripts(options);
s.load_dictionary();
s
});
check_line(s, expected, {
let mut s = LineSegmenter::new_neo_for_non_complex_scripts(options);
s.load_dictionary();
s
});
}
#[test]
fn linebreak_strict() {
strict("サぁサ", false, &["サぁ", "サ"]);
strict("サーサ", false, &["サー", "サ"]);
strict("サ〜サ", false, &["サ〜", "サ"]);
strict("サ々サ", false, &["サ々", "サ"]);
strict("‥‥サ", false, &["‥‥", "サ"]);
strict("サ・サ", false, &["サ・", "サ"]);
strict("サ°サ", false, &["サ°", "サ"]);
strict("サ€サ", false, &["サ", "€サ"]);
}
#[test]
fn linebreak_normal() {
normal("サぁサ", false, &["サ", "ぁ", "サ"]);
normal("サーサ", false, &["サ", "ー", "サ"]);
normal("サ〜サ", true, &["サ", "〜", "サ"]);
normal("サ々サ", true, &["サ々", "サ"]);
normal("‥‥サ", true, &["‥‥", "サ"]);
normal("サ・サ", true, &["サ・", "サ"]);
normal("サ°サ", true, &["サ°", "サ"]);
normal("サ€サ", true, &["サ", "€サ"]);
normal("文文±字字", false, &["文", "文", "±字", "字"]);
normal("文文€字字", false, &["文", "文", "€字", "字"]);
normal("文文№字字", false, &["文", "文", "№字", "字"]);
}
#[test]
fn linebreak_loose() {
loose("サぁサ", true, &["サ", "ぁ", "サ"]);
loose("サーサ", true, &["サ", "ー", "サ"]);
loose("サ〜サ", true, &["サ", "〜", "サ"]);
loose("サ々サ", true, &["サ", "々", "サ"]);
loose("‥‥サ", true, &["‥", "‥", "サ"]);
loose("サ・サ", true, &["サ", "・", "サ"]);
loose("サ°サ", true, &["サ", "°", "サ"]);
loose("文€文", true, &["文", "€", "文"]);
loose("文№文", true, &["文", "№", "文"]);
loose("文$文", true, &["文", "$", "文"]);
loose("文£文", true, &["文", "£", "文"]);
loose("文¥文", true, &["文", "¥", "文"]);
loose("文±文", true, &["文", "±", "文"]);
loose("文€文", true, &["文", "€", "文"]);
loose("文$文", true, &["文", "$", "文"]);
loose("文․文", false, &["文․", "文"]);
loose("文‥文", false, &["文‥", "文"]);
loose("文…文", false, &["文…", "文"]);
loose("文⋯文", false, &["文⋯", "文"]);
loose("文︙文", false, &["文︙", "文"]);
loose("文±文", false, &["文", "±文"]);
loose("文€文", false, &["文", "€文"]);
loose("文№文", false, &["文", "№文"]);
loose("文$文", false, &["文", "$文"]);
loose("文․文", true, &["文․", "文"]);
loose("文‥文", true, &["文‥", "文"]);
loose("文…文", true, &["文…", "文"]);
loose("文⋯文", true, &["文⋯", "文"]);
loose("文︙文", true, &["文︙", "文"]);
loose("文‐文", true, &["文", "‐", "文"]);
loose("文–文", true, &["文", "–", "文"]);
loose("aa‐", false, &["aa‐"]);
loose("aa–", false, &["aa–"]);
}
#[test]
fn linebreak_anywhere() {
anywhere(
"الخيل والليل",
false,
&["ا", "ل", "خ", "ي", "ل", " ", "و", "ا", "ل", "ل", "ي", "ل"],
);
anywhere(
"aa-a.a)a,a) a aa\u{2060}aa・a",
true,
&[
"a", "a", "-", "a", ".", "a", ")", "a", ",", "a", ")", " ", "a", " ", "a", "a",
"\u{2060}", "a", "a", "・", "a",
],
);
anywhere(
"no hyphenation",
false,
&[
"n", "o", " ", "h", "y", "p", "h", "e", "n", "a", "t", "i", "o", "n",
],
);
anywhere("latin", false, &["l", "a", "t", "i", "n"]);
anywhere("XX XXX", false, &["X", "X", " ", "X", "X", "X"]);
anywhere("X X", false, &["X", " ", "X"]);
anywhere(
"XXXX XXXX",
false,
&["X", "X", "X", "X", " ", "X", "X", "X", "X"],
);
anywhere("X XX...", true, &["X", " ", "X", "X", ".", ".", "."]);
anywhere("X XX...", true, &["X", " ", "X", "X", ".", ".", "."]);
anywhere("X X", true, &["X", " ", "X"]);
anywhere(
"XXXX XXXX",
true,
&["X", "X", "X", "X", " ", "X", "X", "X", "X"],
);
anywhere("XX///", true, &["X", "X", "/", "/", "/"]);
anywhere(r#"X XX\\\"#, true, &["X", " ", "X", "X", "\\", "\\", "\\"]);
anywhere("XXX/X", true, &["X", "X", "X", "/", "X"]);
anywhere(r#"XXX\X"#, false, &["X", "X", "X", "\\", "X"]);
anywhere(r#"XXX\X"#, false, &["X", "X", "X", "\\", "X"]);
anywhere("XXX/X", false, &["X", "X", "X", "/", "X"]);
anywhere("XXXX X", false, &["X", "X", "X", "X", " ", "X"]);
anywhere("XX\u{2060}XX", false, &["X", "X", "\u{2060}", "X", "X"]);
anywhere(
"..\u{200B}...X",
false,
&[".", ".", "\u{200B}", ".", ".", ".", "X"],
);
}