Skip to main content

Crate ukraine

Crate ukraine 

Source
Expand description

§Ukraine 🇺🇦

Crates.io Documentation License: AGPL-3.0-only

A Rust library for transliterating Ukrainian Cyrillic text into Latin-script representations. In the hope that one day the Ukrainian Latin script will be widely adopted and the last remnants of russian aggressive imperialism will be erased from the history of modern Ukraine 💙💛

§Support Ukraine

United24

§Overview

This Rust crate provides functionality for converting Ukrainian Cyrillic text into various transliteration schemes described on the Ukrainian Latin alphabet page.

Currently supports the following transliteration systems from Ukrainian Cyrillic to Latin:

  • Lozynskyi’s Abecadło — A historical Ukrainian Latin alphabet proposal
  • DSTU 9112:2021 System A and B — Official Ukrainian standard for Cyrillic-Latin transliteration reference
  • KMU #55 (2010) — Ukrainian National transliteration system for romanization of geographic names. Resolution of the Cabinet of Ministers of Ukraine reference

This library is implemented in pure Rust with zero dependencies and no regex. All transliteration logic is built from scratch using native Rust string processing for maximum performance and minimal overhead.

§Features

  • Greeting: Say hello in various forms—formal or casual.
  • Ukrainian Transliteration: Convert Ukrainian text from Cyrillic to Latin script.
  • Number Conversion: Convert numbers into Ukrainian words.
  • Ordinal Number Conversion: Convert integers into Ukrainian ordinal words.
  • Date and Time Conversion: Format dates and times according to Ukrainian standards.
  • Counting Endings: Properly display singular and plural forms.
  • Feminization: Convert masculine forms to feminine forms and vice versa.
  • Currency Formatting: Convert numerical currency values into Ukrainian words.
  • Name generation: Generate placeholder names for persons, cities, and companies.
  • Address Conversion: Convert addresses to Ukrainian standards.
  • Phone Number Formatting: Convert phone numbers to Ukrainian standards.

§Installation

Add the following line to your Cargo.toml dependencies:

[dependencies]
ukraine = "2"

§Examples

§Say “Hello” in Ukrainian

// ukraine = { version = "2", default-features = false, features = ["greeting"] }

use ukraine::greeting::vitayu;

fn main() {
    println!("{}", vitayu()); // Вітаю
}

§DSTU 9112:2021 System A (ДСТУ 9112:2021)

Cyrillic-Latin transliteration of Ukrainian texts

DSTU 9112

// ukraine = { version = "2", default-features = false, features = ["dstu9112a"] }
use ukraine::latin::transliterate_dstu9112a;

fn main() {
    assert_eq!(transliterate_dstu9112a("Привіт"), "Pryvit");
    assert_eq!(transliterate_dstu9112a("Житомир"), "Žytomyr");
    assert_eq!(transliterate_dstu9112a("Запоріжжя"), "Zaporižžja");
    assert_eq!(transliterate_dstu9112a("Київ"), "Kyïv");
    assert_eq!(transliterate_dstu9112a("Ужгород"), "Užğorod");
    assert_eq!(transliterate_dstu9112a("Черкаси"), "Čerkasy");
    assert_eq!(transliterate_dstu9112a("Чернівці"), "Černivci");
    assert_eq!(transliterate_dstu9112a("Чернігів"), "Černiğiv");
    assert_eq!(transliterate_dstu9112a("Україна"), "Ukraïna");
}

§DSTU 9112:2021 System B (ДСТУ 9112:2021)

Cyrillic-Latin transliteration of Ukrainian texts

DSTU 9112

// ukraine = { version = "2", default-features = false, features = ["dstu9112b"] }
use ukraine::latin::transliterate_dstu9112b;

fn main() {
    let input = "Ще не вмерла України і слава, і воля,
Ще нам, браття молодії, усміхнеться доля.
Згинуть наші воріженьки, як роса на сонці.
Запануєм і ми, браття, у своїй сторонці.";
    let expected = "Shche ne vmerla Ukrajiny i slava, i volja,
Shche nam, brattja molodiji, usmikhnetjsja dolja.
Zghynutj nashi vorizhenjku, jak rosa na sonci.
Zapanujem i my, brattja, u svojij storonci.";
    assert_eq!(transliterate_dstu9112b(input), expected);
}

§Transliteration system approved by Cabinet of Ministers resolution #55 (2010 year)

KMU №55

// ukraine = { version = "2", default-features = false, features = ["kmu55"] }

use ukraine::latin::transliterate_kmu55;

fn main() {
    assert_eq!(transliterate_kmu55("Київ"), "Kyiv");
    assert_eq!(transliterate_kmu55("Михайло"), "Mykhailo");
    assert_eq!(transliterate_kmu55("Юрій"), "Yurii");
    assert_eq!(transliterate_kmu55("Борщ"), "Borshch");

    // Note 1: "зг" is rendered "zgh" wherever it occurs, so that it never
    // collapses onto "zh", the rendering of "ж".
    assert_eq!(transliterate_kmu55("Згорани"), "Zghorany");
    assert_eq!(transliterate_kmu55("Розгон"), "Rozghon");

    // A fully capitalised word stays capitalised through its last letter.
    assert_eq!(transliterate_kmu55("БОРЩ"), "BORSHCH");
}

§Lozynskyi’s abecadło

Abecadło

// ukraine = { version = "2", default-features = false, features = ["lozynsky"] }

use ukraine::latin::transliterate_lozynsky;

fn main() {
    assert_eq!(transliterate_lozynsky("❤️ Україна"), "❤️ Ukrajina");
}

§Convert numbers into Ukrainian words

// ukraine = { version = "2", default-features = false, features = ["numbers"] }
use ukraine::numbers::{to_ordinal_words, to_words, OrdinalGender};

fn main() {
    assert_eq!(
        to_words(12_345_678),
        "дванадцять мільйонів триста сорок п'ять тисяч шістсот сімдесят вісім"
    );
}

§Convert numbers into Ukrainian ordinal words

// ukraine = { version = "2", default-features = false, features = ["numbers"] }

use ukraine::numbers::{to_ordinal_words, OrdinalGender};

fn main() {
    assert_eq!(to_ordinal_words(123, OrdinalGender::Feminine), "сто двадцять третя");
    assert_eq!(to_ordinal_words(123, OrdinalGender::Masculine), "сто двадцять третій");
    assert_eq!(to_ordinal_words(123, OrdinalGender::Neuter), "сто двадцять третє");
    assert_eq!(
        to_ordinal_words(21, OrdinalGender::Masculine),
        "двадцять перший"
    );
    assert_eq!(
        to_ordinal_words(45, OrdinalGender::Feminine),
        "сорок п'ята"
    );

    // An exact multiple of a scale fuses into a single adjective,
    // while a compound keeps its thousands cardinal.
    assert_eq!(to_ordinal_words(2_000, OrdinalGender::Masculine), "двохтисячний");
    assert_eq!(
        to_ordinal_words(2_345, OrdinalGender::Masculine),
        "дві тисячі триста сорок п'ятий"
    );
}
§New in 2.0.0

try_to_ordinal_words returns the ordinal words, or nothing when the number is too large to name. MAX_ORDINAL is the largest value the converter accepts.

// ukraine = { version = "2", default-features = false, features = ["numbers"] }

use ukraine::numbers::{try_to_ordinal_words, MAX_ORDINAL, OrdinalGender};

fn main() {
    assert_eq!(
        try_to_ordinal_words(1_000_000, OrdinalGender::Neuter),
        Some("мільйонне".to_string())
    );

    assert_eq!(MAX_ORDINAL, 999_999_999_999_999);
    assert_eq!(try_to_ordinal_words(MAX_ORDINAL + 1, OrdinalGender::Masculine), None);
}

§Format dates and times in Ukrainian

// ukraine = { version = "2", default-features = false, features = ["datetime"] }

use chrono::{NaiveDate, NaiveDateTime, NaiveTime};
use ukraine::datetime::{
    format_date, format_datetime, format_time, DateFormatStyle, FormatOptions, TimeFormatStyle,
};

fn main() {
    let independence_day = NaiveDate::from_ymd_opt(2024, 8, 24).unwrap();
    let ceremony = NaiveDateTime::new(
        independence_day,
        NaiveTime::from_hms_opt(9, 0, 0).unwrap(),
    );

    // Date format
    assert_eq!(
        format_date(independence_day, DateFormatStyle::Long),
        "24 серпня 2024 року"
    );

    // Full date time format
    assert_eq!(
        format_datetime(ceremony, FormatOptions::default()),
        "24 серпня 2024 року о 09:00"
    );

    // 12 hours
    let time = NaiveTime::from_hms_opt(8, 10, 59).unwrap();
    assert_eq!(
        format_time(time, TimeFormatStyle::TwelveHourNoSeconds),
        "08:10 ранку"
    );

    // 24 hours
    let time = NaiveTime::from_hms_opt(23, 59, 59).unwrap();
    assert_eq!(
        format_time(time, TimeFormatStyle::TwentyFourHour),
        "23:59:59"
    );

    // 24 hours no seconds
    let time = NaiveTime::from_hms_opt(23, 59, 59).unwrap();
    assert_eq!(
        format_time(time, TimeFormatStyle::TwentyFourHourNoSeconds),
        "23:59"
    );
}
// ukraine = { version = "2", default-features = false, features = ["numbers", "dstu9112a"] }

use ukraine::numbers::to_words;
use ukraine::latin::dstu9112a::transliterate_dstu9112a;

fn main() {
    assert_eq!(
        transliterate_dstu9112a(&to_words(12_345_678)),
        "dvanadcjatj miljjoniv trysta sorok p’jatj tysjač šistsot simdesjat visim"
    );
}

§Documentation

The full API documentation is available at docs.rs/ukraine.

§Alternative

Alternative crates for supporting DSTU 9112:2021 and KMU 55:2010: the uklatn crate provides a solid regex-based implementation of these transliteration schemes.

§Contributing

Contributions are welcome! Please open an issue or submit a pull request for any improvements or bug fixes.

§License

Licensed under the GNU Affero General Public License v3.0 only (AGPL-3.0-only).

Note for anyone upgrading: versions 1.x were LGPL-3.0-only. The AGPL is stricter, and its §13 extends the obligation to offer source code to users who interact with a modified version of this crate over a network. If that does not suit your project, pin ukraine = "1" or open an issue to discuss.

Modules§

datetime
greeting
latin
numbers

Constants§

APOSTROPHE
Get the Ukrainian apostrophe character
CHAR_GYO
Get the Ukrainian character ‘ґ’
CHAR_GYO_UPPER
Get the Ukrainian character ‘ґ’
CHAR_YI
Get the Ukrainian character ‘ї’
CHAR_YI_UPPER
Get the Ukrainian character ‘ї’
DAY_OF_WEEK
Get the name of the days of the week in Ukrainian
DAY_OF_WEEK_GENITIVE
Get the genitive case of the days of the week in Ukrainian
MONTH
Constants for Ukrainian language localization.
MONTH_GENITIVE
Get the genitive case of January

Functions§

glory_to_ukraine