pub struct Shaper { /* private fields */ }Expand description
The UTN #57 shaping engine (and, for MNG, the canonical normalizer) for one locale.
Construction is cheap (microseconds) and the value is Send + Sync, so one instance can be
shared behind a reference for the lifetime of a program.
Implementations§
Source§impl Shaper
impl Shaper
Sourcepub fn canonical_version(&self) -> Option<&'static str>
pub fn canonical_version(&self) -> Option<&'static str>
Version of the canonical Unicode selection policy ("mng-canonical/1" for MNG; None
for locales without a normalize table). Persist it next to stored normalized keys.
Sourcepub fn normalize(&self, text: &str) -> Result<String, Error>
pub fn normalize(&self, text: &str) -> Result<String, Error>
Canonical, FVS-pinned encoding of one Mongolian word: within the normalize table’s domain,
shape(x) == shape(y) ⟹ normalize(x) == normalize(y), and
shape(normalize(x)) == shape(x).
Strict (the Python default): an uncovered shape is Error::NormalizationFallback.
Errors with Error::NonMongolianChar on mixed-script input — see
Shaper::normalize_text.
Sourcepub fn normalize_allow_fallback(&self, text: &str) -> Result<String, Error>
pub fn normalize_allow_fallback(&self, text: &str) -> Result<String, Error>
Like Shaper::normalize, but an uncovered shape returns the input unchanged
(Python strict=False).
Sourcepub fn normalize_text(&self, text: &str) -> Result<String, Error>
pub fn normalize_text(&self, text: &str) -> Result<String, Error>
Normalize free-form text: every Mongolian word run is normalized independently, everything
else (spaces, punctuation, Latin, …) is copied verbatim. Strict like Shaper::normalize.
Sourcepub fn normalize_text_allow_fallback(&self, text: &str) -> Result<String, Error>
pub fn normalize_text_allow_fallback(&self, text: &str) -> Result<String, Error>
Like Shaper::normalize_text, but an uncovered word is preserved unchanged.
Source§impl Shaper
impl Shaper
Sourcepub fn rule_names(&self) -> Vec<&'static str>
pub fn rule_names(&self) -> Vec<&'static str>
The names of the shaping rules, in the order they run (empty for locales without rules).
Sourcepub fn shape(&self, text: &str) -> Result<Vec<WrittenUnit>, Error>
pub fn shape(&self, text: &str) -> Result<Vec<WrittenUnit>, Error>
Shape text into its written-unit sequence. Structural characters appear verbatim as
WrittenUnit::Mvs, WrittenUnit::Nirugu and WrittenUnit::Zwj.
Errors with Error::NonMongolianChar on anything but Mongolian letters, FVS, MVS,
NNBSP, nirugu and ZWJ — use Shaper::normalize_text for mixed-script text.
Sourcepub fn shape_str(&self, text: &str) -> Result<String, Error>
pub fn shape_str(&self, text: &str) -> Result<String, Error>
Shaper::shape joined with + (S+A+I+I+A), the CLI’s output format.
Sourcepub fn same_shape(&self, a: &str, b: &str) -> Result<bool, Error>
pub fn same_shape(&self, a: &str, b: &str) -> Result<bool, Error>
Do a and b render the same glyph sequence?
Sourcepub fn shape_detailed(&self, text: &str) -> Result<Vec<TokenDetail>, Error>
pub fn shape_detailed(&self, text: &str) -> Result<Vec<TokenDetail>, Error>
Per-token shaping breakdown (Python shape_detailed).
Source§impl Shaper
impl Shaper
Sourcepub fn normalize_written_units(
&self,
units: &[WrittenUnit],
) -> Result<String, Error>
pub fn normalize_written_units( &self, units: &[WrittenUnit], ) -> Result<String, Error>
Encode an ordered written-unit sequence (e.g. the output of Shaper::shape) as
canonical Unicode. Letter positions are inferred from order and the structural tokens;
ZWJ is emitted only where Zwj is present in the request. The result is accepted only if
it reshapes to exactly the requested sequence.
An empty sequence returns "" — without consulting the table, so it succeeds on every
locale.
§Errors
Error::NormalizeUnsupported— this locale has no bundled normalize table.Error::UnsupportedWrittenUnit—units[index]is outside the table’s vocabulary (for example the Todo unitEon an MNG shaper). The first offender is reported.Error::NoCanonicalEncoding— the table covers every unit, but the sequence has no encoding that reshapes back to it.
Sourcepub fn normalize_positioned_written_units(
&self,
records: &[PositionedWrittenUnit],
) -> Result<String, Error>
pub fn normalize_positioned_written_units( &self, records: &[PositionedWrittenUnit], ) -> Result<String, Error>
Encode explicit HUD-position records as canonical Unicode (the API zvvnmod-utn57
uses). A complete multi-record chain runs init…fina; an incomplete edge gets an implicit
ZWJ; a single init record is encoded bare except O:init, which takes a trailing ZWJ;
single medi / fina records get the joining context their position needs. Mvs and
Nirugu require Control; explicit Zwj is rejected; at most
MAX_POSITIONED_RECORDS records.
§Validation order
Checks run in a fixed order, and it is observable — callers such as zvvnmod-utn57
dispatch on the variant, so the first failing check decides which one they see:
- record limit — 2000 records containing a
ZwjisError::TooManyRecords, notError::ExplicitZwj, and an over-limit request on a table-less locale isError::TooManyRecords, notError::NormalizeUnsupported; - explicit
Zwjanywhere in the request; - empty request — returns
""before the table is consulted, so it succeeds on every locale; - the normalize table;
- per record, the control/inventory check (
MvsandNiruguneedControl; every other(unit, position)must be in the HUD inventory), reporting the first offender; - per multi-record chain, that the declared positions match the padded chain;
- delegation to
Shaper::normalize_written_units.
§Errors
Error::TooManyRecords,Error::ExplicitZwj,Error::NormalizeUnsupported,Error::ControlRequiresControlPosition,Error::UnsupportedPositionedUnit,Error::ChainPositionMismatch— as numbered above.- Anything
Shaper::normalize_written_unitsreturns. Its indices point into the expanded written-unit sequence — after implicit ZWJs were inserted — not intorecords.
Sourcepub fn parse_written_units(&self, text: &str) -> Result<Vec<WrittenUnit>, Error>
pub fn parse_written_units(&self, text: &str) -> Result<Vec<WrittenUnit>, Error>
Parse the CLI’s written-unit spelling: explicit +-separated names (B+Aa) or a
compact PascalCase string with exactly one segmentation over this shaper’s known units
(BZwj). One trailing newline is tolerated; an ambiguous compact string is rejected.
Every name — explicit or compact — must belong to this shaper’s normalize table, not
merely to WrittenUnit: E is a Todo unit, so an MNG shaper rejects it. That keeps the
reported index identical to Python’s, which defers the same check to
normalize_written_units.
§Errors
Error::NormalizeUnsupported— this locale has no bundled normalize table.Error::InvalidUnitSpec— the spec contains whitespace or an empty+field, or the compact string has more than one segmentation.Error::UnknownWrittenUnit— a name is outside the table’s vocabulary; on the compact path an unsegmentable string is reported whole, at index 0.
Source§impl Shaper
impl Shaper
Sourcepub fn known_written_units(&self) -> Result<Vec<WrittenUnit>, Error>
pub fn known_written_units(&self) -> Result<Vec<WrittenUnit>, Error>
Every written unit this shaper’s normalize table can encode, plus the structural
controls (Mvs, Nirugu, Zwj), sorted by name.
These are exactly the names Shaper::normalize_written_units accepts; the Python
bindings use the list to validate their input with Python-formatted messages.
§Errors
Error::NormalizeUnsupported — this locale has no bundled normalize table.
Sourcepub fn positioned_written_units(
&self,
) -> Result<Vec<(WrittenUnit, Position)>, Error>
pub fn positioned_written_units( &self, ) -> Result<Vec<(WrittenUnit, Position)>, Error>
The HUD positioned inventory: every (unit, position) pair that
Shaper::normalize_positioned_written_units accepts for a letter record (letter
positions only — controls are not part of the inventory), sorted by unit name then
position.
§Errors
Error::NormalizeUnsupported — this locale has no bundled normalize table.