use super::error::{check_limit, invalid};
use super::KuromojiLimits;
use crate::morphology::filter::Work;
use crate::AnalysisResult;
use uqa_core::memory::{Budgeted, MemoryBudget};
mod policy;
pub(super) use policy::filter;
struct Context<'a, 'b> {
work: &'a mut Work<'b>,
budget: &'a MemoryBudget,
maximum: usize,
}
impl crate::morphology::decimal::Context for Context<'_, '_> {
fn tick(&mut self) -> AnalysisResult<()> {
self.work.tick()
}
fn budget(&self) -> &MemoryBudget {
self.budget
}
fn check_digits(&self, digits: usize) -> AnalysisResult<()> {
check_limit("Kuromoji numeric units", digits, self.maximum)?;
Ok(())
}
fn invalid(&self, reason: &'static str) -> crate::AnalysisError {
invalid("Kuromoji number", reason).into()
}
}
pub fn normalize_number(input: &str) -> AnalysisResult<String> {
Ok(normalize_number_budgeted(
input,
KuromojiLimits::default(),
&MemoryBudget::new(usize::MAX),
&mut || Ok(()),
)?
.into_parts()
.0)
}
pub fn normalize_number_budgeted(
input: &str,
limits: KuromojiLimits,
budget: &MemoryBudget,
poll: &mut impl FnMut() -> AnalysisResult<()>,
) -> AnalysisResult<Budgeted<String>> {
let units = crate::allocation::input::encode(input, budget, poll, |required| {
check_limit(
"Kuromoji input UTF-16 units",
required,
limits.max_input_utf16,
)?;
Ok(())
})?;
let normalized = normalize_number_utf16_budgeted(&units, limits, budget, poll)?;
drop(units);
let (term, memory) = crate::TokenTerm::from_utf16_budgeted(normalized, poll)?.into_parts();
let text = term
.into_string()
.map_err(|_| invalid("Kuromoji number", "invalid scalar result"))?;
Ok(Budgeted::new(text, memory))
}
pub fn normalize_number_utf16(
input: &[u16],
limits: KuromojiLimits,
poll: &mut impl FnMut() -> AnalysisResult<()>,
) -> AnalysisResult<Vec<u16>> {
Ok(
normalize_number_utf16_budgeted(input, limits, &MemoryBudget::new(usize::MAX), poll)?
.into_parts()
.0,
)
}
pub fn normalize_number_utf16_budgeted(
input: &[u16],
limits: KuromojiLimits,
budget: &MemoryBudget,
poll: &mut impl FnMut() -> AnalysisResult<()>,
) -> AnalysisResult<Budgeted<Vec<u16>>> {
let mut work = Work::new(poll)?;
check_limit(
"Kuromoji input UTF-16 units",
input.len(),
limits.max_input_utf16,
)?;
let result = normalize_budgeted(input, limits.max_output_utf16, budget, &mut work)?;
work.finish()?;
Ok(result)
}
fn normalize_budgeted(
input: &[u16],
maximum: usize,
budget: &MemoryBudget,
work: &mut Work<'_>,
) -> AnalysisResult<Budgeted<Vec<u16>>> {
crate::morphology::number::normalize::<policy::Symbols>(
input,
&mut Context {
work,
budget,
maximum,
},
)
}