localize_it 1.4.0

Simple and fast library for localization
Documentation

localize_it - Simple and fast localization library

Tests Crates.io Documentation License

A tiny, zero-allocation localization system for Rust designed with #![no_std] support.

This crate provides a macro-based API for defining compile-time locales and localized expressions without using dynamic memory, hash maps, or runtime lookups. All localized expressions are stored in fixed-size arrays. You can manually control (via init_locale!) the locale state or use the built-in locale storage (via init_locale_with_storage!).


Cargo Features

  • serde — enables serde::Serialize and serde::Deserialize derives for enum Locale
  • miniserde — enables miniserde::Serialize and miniserde::Deserialize derives for enum Locale
  • borsh — enables borsh::BorshSerialize and borsh::BorshDeserialize derives for enum Locale

Example

A program that asks the user to choose a language, enter their name, and then greets them in the selected language:

use localize_it::{expressions, init_locale_with_storage, localize};
use std::io::{stdin, stdout, Write};

// Define available locales
init_locale_with_storage!(EN, RU);

// Expressions can be any type allowed in compile-time context
expressions!(
    ENTER_LANGUAGE => {
        EN: "Enter EN or RU: ",
        RU: "Введите EN или RU: ",
    },
    ENTER_YOU_NAME => {
        EN: "Please, enter your name: ",
        RU: "Пожалуйста, введите ваше имя: ",
    },
    HELLO: fn (&str) -> String => {
        EN: |name: &str| format!("Hello, {name}!"),
        RU: |name: &str| format!("Привет, {name}!"),
    },
);

fn main() {
    let mut lang = String::new();

    // You can set locale manually
    print!("{}", localize!(ENTER_LANGUAGE, Locale::EN));

    stdout().flush().unwrap();
    stdin().read_line(&mut lang).unwrap();

    // Set the selected locale
    set_locale(Locale::from_str_or_default(&lang.trim().to_uppercase()));

    let mut name = String::new();

    // Uses the currently selected locale automatically
    print!("{}", localize!(ENTER_YOU_NAME));

    stdout().flush().unwrap();
    stdin().read_line(&mut name).unwrap();

    // Use callable expression
    println!("{}", localize!(HELLO as (&name.trim())));
}

Recommended Project Structure

A recommended way to organize your project is to create a dedicated locale module that handles locale initialization and contains grouped expression modules. For example:

src/
├─ main.rs
└─ locale/
   ├─ mod.rs     # Initialization locale here
   ├─ error.rs   # First module with expressions
   └─ ui.rs      # Second module with expressions

Advantages

  • O(1) localization lookup
  • Zero allocations
  • Macro-based API
  • No external dependencies without optional features
  • no_std compatible

Design Constraints

  • Not possible to update or add the translations without recompiling
  • No plans to add automatic gender agreement, numeral declension, etc

How It Works

  • Locales are defined as an enum with #[repr(usize)]
  • Expressions as an array
  • Built-in locale storage implemented as AtomicUsize with Relaxed ordering
  • Localization resolves to a simple array index operation

Usage

Add the following to your Cargo.toml:

[dependencies]

localize_it = "1.4.0"


License

This project is licensed under either of

at your option.