mongol_norm/lib.rs
1#![forbid(unsafe_code)]
2#![deny(missing_docs)]
3//! # mongol-norm
4//!
5//! Shape-aware normalizer for Traditional Mongolian (Hudum) script — the pure-Rust twin of the
6//! `mongol-norm` Python package that lives in the same repository.
7//!
8//! Traditional Mongolian in Unicode has a fundamental problem: the same visible word can be
9//! encoded in many different code-point sequences (letters share glyphs, FVS selectors create
10//! equivalent spellings, joiners and MVS suffixes collapse more letters together). This crate
11//! implements a lightweight shaping engine — the UTN #57 v4 Mongolian-specific phase, driven only
12//! by the rule data of UTN #57 / mongfontbuilder, no font needed — and, on top of it, a canonical
13//! normalizer: within the bundled table's domain, `shape(x) == shape(y)` implies
14//! `normalize(x) == normalize(y)`, and `shape(normalize(x)) == shape(x)`.
15//!
16//! * [`Shaper::shape`] — text → written-unit sequence (`Mvs` / `Nirugu` / `Zwj` appear verbatim)
17//! * [`Shaper::same_shape`] — do two encodings render identically?
18//! * [`Shaper::normalize`] / [`Shaper::normalize_text`] — canonical, FVS-pinned Unicode
19//! * [`Shaper::normalize_written_units`] / [`Shaper::normalize_positioned_written_units`] —
20//! encode written units directly
21//! * [`Shaper::trace`] — per-rule condition transitions, for debugging and the golden fixtures
22//!
23//! The crate has no dependencies and builds for `wasm32-unknown-unknown`. Its data tables are
24//! generated from the repository's JSON by `scripts/gen_rust_tables.py`; every value-producing
25//! operation is byte-identical
26//! to the Python package of the same version. Design:
27//! <https://github.com/Satsrag/mongol-norm/blob/main/docs/superpowers/specs/2026-09-01-rust-core-design.md>.
28
29/// The crate README is compiled and run as a doctest, so its example cannot rot.
30#[cfg(doctest)]
31#[doc = include_str!("../README.md")]
32struct ReadmeDoctests;
33
34mod error;
35// clippy::all silences style lints on generated code (see the design doc).
36#[allow(clippy::all)]
37mod generated;
38mod normalize;
39mod rules;
40mod shaper;
41mod tables;
42mod token;
43mod unicode;
44mod written_units;
45
46#[doc(hidden)]
47pub mod cli;
48
49pub use error::Error;
50pub use generated::enums::{Alias, Condition, WrittenUnit};
51pub use shaper::{ConditionChange, RuleTransition, ShapeTrace, Shaper, TokenDetail};
52pub use tables::{Fvs, Locale, Position, UnitPosition};
53pub use unicode::{is_mongolian_letter, is_mongolian_word_char};
54pub use written_units::{PositionedWrittenUnit, MAX_POSITIONED_RECORDS};
55
56/// Crate version (the Cargo package version; lockstep with the Python package version).
57pub fn version() -> &'static str {
58 env!("CARGO_PKG_VERSION")
59}