use pyo3::prelude::*;
#[pyfunction]
fn grapheme_boundaries(text: &str) -> Vec<usize> {
crate::segment::grapheme_boundaries(text)
}
#[pyfunction]
#[pyo3(signature = (text, locale=None))]
fn word_boundaries(text: &str, locale: Option<&str>) -> Vec<usize> {
crate::segment::word_boundaries(text, locale)
}
#[pyfunction]
#[pyo3(signature = (text, locale=None))]
fn sentence_boundaries(text: &str, locale: Option<&str>) -> Vec<usize> {
crate::segment::sentence_boundaries(text, locale)
}
#[pyfunction]
fn normalize_nfc(text: &str) -> String {
crate::normalize::nfc(text)
}
#[pyfunction]
fn normalize_nfd(text: &str) -> String {
crate::normalize::nfd(text)
}
#[pyfunction]
fn normalize_nfkc(text: &str) -> String {
crate::normalize::nfkc(text)
}
#[pyfunction]
fn normalize_nfkd(text: &str) -> String {
crate::normalize::nfkd(text)
}
#[pyfunction]
fn bidi_resolve(py: Python<'_>, text: &str) -> PyResult<PyObject> {
let info = crate::bidi::resolve(text, None);
let dict = pyo3::types::PyDict::new(py);
dict.set_item("paragraph_level", info.paragraph_level)?;
dict.set_item("levels", info.levels)?;
dict.set_item("reorder", info.reorder)?;
Ok(dict.into())
}
#[pyfunction]
fn line_break_opportunities(text: &str) -> Vec<(usize, String)> {
let actions = crate::linebreak::line_break_opportunities(text);
actions
.iter()
.enumerate()
.filter_map(|(i, a)| match a {
crate::linebreak::BreakAction::Mandatory => Some((i, "mandatory".to_owned())),
crate::linebreak::BreakAction::Allowed => Some((i, "allowed".to_owned())),
crate::linebreak::BreakAction::Prohibited => None,
})
.collect()
}
#[pyfunction]
fn line_break_opportunities_with_dictionary(text: &str) -> Vec<(usize, String)> {
let actions = crate::linebreak::line_break_opportunities_with_dictionary(text);
actions
.iter()
.enumerate()
.filter_map(|(i, a)| match a {
crate::linebreak::BreakAction::Mandatory => Some((i, "mandatory".to_owned())),
crate::linebreak::BreakAction::Allowed => Some((i, "allowed".to_owned())),
crate::linebreak::BreakAction::Prohibited => None,
})
.collect()
}
#[pyfunction]
#[pyo3(signature = (text, locale=None))]
fn to_lowercase(text: &str, locale: Option<&str>) -> String {
match locale {
Some(loc) => crate::casemap::to_lowercase_locale(text, loc),
None => crate::casemap::to_lowercase(text),
}
}
#[pyfunction]
#[pyo3(signature = (text, locale=None))]
fn to_uppercase(text: &str, locale: Option<&str>) -> String {
match locale {
Some(loc) => crate::casemap::to_uppercase_locale(text, loc),
None => crate::casemap::to_uppercase(text),
}
}
#[pyfunction]
fn to_titlecase(text: &str) -> String {
crate::casemap::to_titlecase(text)
}
#[pyfunction]
fn case_fold(text: &str) -> String {
crate::casemap::case_fold(text)
}
#[pyfunction]
fn case_fold_simple(text: &str) -> String {
crate::casemap::case_fold_simple(text)
}
#[pyfunction]
fn display_width(text: &str) -> u32 {
crate::width::display_width(text)
}
#[pyfunction]
fn truncate_graphemes(text: &str, max_graphemes: usize) -> String {
crate::truncate::truncate_graphemes(text, max_graphemes).to_owned()
}
#[pyfunction]
fn truncate_display_width(text: &str, max_width: u32) -> String {
crate::truncate::truncate_display_width(text, max_width)
}
#[pyfunction]
fn move_right(text: &str, current: usize) -> usize {
crate::cursor::move_right(text, current)
}
#[pyfunction]
fn move_left(text: &str, current: usize) -> usize {
crate::cursor::move_left(text, current)
}
#[pyfunction]
fn move_right_visual(text: &str, current: usize) -> usize {
crate::cursor::move_right_visual(text, current)
}
#[pyfunction]
fn move_left_visual(text: &str, current: usize) -> usize {
crate::cursor::move_left_visual(text, current)
}
#[pyfunction]
fn select_word(text: &str, current: usize) -> (usize, usize) {
crate::cursor::select_word(text, current)
}
#[pymodule]
fn uniworld(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(grapheme_boundaries, m)?)?;
m.add_function(wrap_pyfunction!(word_boundaries, m)?)?;
m.add_function(wrap_pyfunction!(sentence_boundaries, m)?)?;
m.add_function(wrap_pyfunction!(normalize_nfc, m)?)?;
m.add_function(wrap_pyfunction!(normalize_nfd, m)?)?;
m.add_function(wrap_pyfunction!(normalize_nfkc, m)?)?;
m.add_function(wrap_pyfunction!(normalize_nfkd, m)?)?;
m.add_function(wrap_pyfunction!(bidi_resolve, m)?)?;
m.add_function(wrap_pyfunction!(line_break_opportunities, m)?)?;
m.add_function(wrap_pyfunction!(line_break_opportunities_with_dictionary, m)?)?;
m.add_function(wrap_pyfunction!(to_lowercase, m)?)?;
m.add_function(wrap_pyfunction!(to_uppercase, m)?)?;
m.add_function(wrap_pyfunction!(to_titlecase, m)?)?;
m.add_function(wrap_pyfunction!(case_fold, m)?)?;
m.add_function(wrap_pyfunction!(case_fold_simple, m)?)?;
m.add_function(wrap_pyfunction!(display_width, m)?)?;
m.add_function(wrap_pyfunction!(truncate_graphemes, m)?)?;
m.add_function(wrap_pyfunction!(truncate_display_width, m)?)?;
m.add_function(wrap_pyfunction!(move_right, m)?)?;
m.add_function(wrap_pyfunction!(move_left, m)?)?;
m.add_function(wrap_pyfunction!(move_right_visual, m)?)?;
m.add_function(wrap_pyfunction!(move_left_visual, m)?)?;
m.add_function(wrap_pyfunction!(select_word, m)?)?;
Ok(())
}