Skip to main content

Shaper

Struct Shaper 

Source
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

Source

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.

Source

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.

Source

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).

Source

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.

Source

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

Source

pub fn new(locale: Locale) -> Shaper

Build the shaper for locale from the generated tables.

Source

pub fn locale(&self) -> Locale

The locale this shaper was built for.

Source

pub fn rule_names(&self) -> Vec<&'static str>

The names of the shaping rules, in the order they run (empty for locales without rules).

Source

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.

Source

pub fn shape_str(&self, text: &str) -> Result<String, Error>

Shaper::shape joined with + (S+A+I+I+A), the CLI’s output format.

Source

pub fn same_shape(&self, a: &str, b: &str) -> Result<bool, Error>

Do a and b render the same glyph sequence?

Source

pub fn shape_detailed(&self, text: &str) -> Result<Vec<TokenDetail>, Error>

Per-token shaping breakdown (Python shape_detailed).

Source

pub fn trace(&self, text: &str) -> Result<ShapeTrace, Error>

Run the pipeline one rule at a time and record every condition change.

Source§

impl Shaper

Source

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
Source

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:

  1. record limit — 2000 records containing a Zwj is Error::TooManyRecords, not Error::ExplicitZwj, and an over-limit request on a table-less locale is Error::TooManyRecords, not Error::NormalizeUnsupported;
  2. explicit Zwj anywhere in the request;
  3. empty request — returns "" before the table is consulted, so it succeeds on every locale;
  4. the normalize table;
  5. per record, the control/inventory check (Mvs and Nirugu need Control; every other (unit, position) must be in the HUD inventory), reporting the first offender;
  6. per multi-record chain, that the declared positions match the padded chain;
  7. delegation to Shaper::normalize_written_units.
§Errors
Source

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
Source§

impl Shaper

Source

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.

Source

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.

Trait Implementations§

Source§

impl Debug for Shaper

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Shaper

Source§

fn default() -> Shaper

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.