locale-rs
A comprehensive, strongly-typed Rust library for managing Unicode locales, built directly on the CLDR (Common Locale Data Repository) dataset.
This crate provides a type-safe interface for locale identifiers, ensuring that your application remains compliant with international standards while benefiting from Rust's performance and safety guarantees.
Features
- 766 Unicode Locales: Complete coverage of CLDR 48.1.0
- Type-Safe Locales: Compile-time validated locale identifiers as Rust enums
- Zero-Cost Abstractions: No runtime overhead for locale operations
- Number Formatting: Locale-aware formatting with native digit support
- Currency Formatting: ICU-compatible currency patterns
- DateTime Formatting: Localized month/weekday names and patterns
- Native Numbering Systems: Automatic support for Arabic-Indic, Devanagari, Bengali, and more
- Flexible Parsing: Parse locales with hyphens, underscores, or mixed case
- Locale Negotiation: Find the best matching locale from available options
- Fuzzy Suggestions: Get locale suggestions for typos or unknown identifiers
Quick Start
Installation
Add to your Cargo.toml:
[]
= "0.2"
# With number formatting support
= { = "0.2", = ["nums"] }
# With all features
= { = "0.2", = ["all"] }
Basic Usage
use Locale;
// Direct enum access
let locale = en_GB;
println!; // "en-GB"
// Parse from string
let locale = from_str?;
// Flexible parsing (case-insensitive, accepts hyphens or underscores)
let locale = from_flexible?;
// Extract subtags
assert_eq!;
assert_eq!;
Number Formatting
use Locale;
use ToFormattedString;
let num = 1234567;
// English: 1,234,567
println!;
// German: 1.234.567
println!;
// French: 1 234 567
println!;
// Arabic with native digits: ١٬٢٣٤٬٥٦٧
println!;
Locale Negotiation
use Locale;
let user_preference = en_GB;
let available = vec!;
// Find best match (falls back through parent chain)
if let Some = user_preference.negotiate
Locale Suggestions
use Locale;
// Get suggestions for typos or unknown locales
let suggestions = suggest;
for locale in suggestions
Features
nums - Number Formatting
Enables number formatting with locale-specific separators and native digit systems.
use Locale;
use ToFormattedString;
let value = 42.5;
println!; // 42,5
currency - Currency Formatting
Enables currency formatting patterns (requires nums).
use locale_rs;
use ToCurrencyString;
let locale = en;
for i in 0u32..10
let locale = de;
for i in 0u32..10
datetime - DateTime Formatting
Enables datetime formatting data.
use Locale;
let locale = de;
let months = locale.months_wide;
println!; // "Januar"
strum - Enum Iteration
Enables iteration over all locales using the strum crate.
use Locale;
use IntoEnumIter;
for locale in iter
all - All Features
Enables all optional features.
= { = "0.2", = ["all"] }
API Overview
Core Methods
| Method | Returns | Purpose |
|---|---|---|
as_str() |
&'static str |
Get string representation |
fallback() |
Option<Locale> |
Get parent locale |
language_code() |
&'static str |
Extract language subtag |
region_code() |
Option<&'static str> |
Extract region subtag |
from_flexible(s) |
Result<Locale, LocaleError> |
Parse with flexible formatting |
negotiate(available) |
Option<Locale> |
Find best match from list |
suggest(input) |
Vec<Locale> |
Get fuzzy suggestions |
Number Formatting (with nums feature)
| Method | Returns | Purpose |
|---|---|---|
decimal_separator() |
&'static str |
Decimal point character |
grouping_separator() |
&'static str |
Thousands separator |
grouping_sizes() |
&'static [usize] |
Grouping size array |
minus_sign() |
&'static str |
Negative sign character |
digits() |
Option<[char; 10]> |
Native digit characters |
Currency Formatting (with currency feature)
| Method | Returns | Purpose |
|---|---|---|
currency_standard_pattern() |
&'static str |
Standard currency pattern |
currency_accounting_pattern() |
&'static str |
Accounting format pattern |
DateTime Formatting (with datetime feature)
| Method | Returns | Purpose |
|---|---|---|
months_wide() |
&'static [&'static str] |
Full month names |
months_abbreviated() |
&'static [&'static str] |
Short month names |
weekdays_wide() |
&'static [&'static str] |
Full weekday names |
weekdays_abbreviated() |
&'static [&'static str] |
Short weekday names |
Examples
Parsing Locales
use Locale;
use FromStr;
// Standard parsing
let locale = from_str?;
// Flexible parsing (case-insensitive, accepts underscores)
let locale = from_flexible?;
let locale = from_flexible?;
// TryFrom conversion
let locale = try_from?;
Fallback Chain
use Locale;
let mut current = en_GB;
while let Some = current.fallback
// Output:
// Fallback: en
Locale Matching
use Locale;
let user_locales = vec!;
let available = vec!;
// Find best match for each user locale
for user_locale in user_locales
// Output:
// en-GB -> en
// en -> en
Formatting Numbers
use Locale;
use ToFormattedString;
let numbers = vec!;
for num in numbers
Formatting Floats
use Locale;
use ToFormattedString;
let value = 3.14159;
println!; // 3.14159
println!; // 3,14159
println!; // 3,14159
Currency Patterns
use Locale;
let locales = vec!;
for locale in locales
// Output:
// en: ¤#,##0.00
// de: #,##0.00 ¤
// fr: #,##0.00 ¤
// ja: ¤#,##0.00
DateTime Data
use Locale;
let locale = de;
println!;
for in locale.months_wide.iter.enumerate
println!;
for in locale.weekdays_abbreviated.iter.enumerate
Supported Locales
The library supports 766 locales from CLDR 48.1.0, including:
- Languages: 200+ languages
- Regions: 150+ territories
- Scripts: Multiple script variants (e.g.,
zh-Hans,zh-Hant) - Variants: Special variants (e.g.,
ca-ES-valencia,be-tarask)
View all available locales:
use AVAILABLE_LOCALES;
for locale_str in AVAILABLE_LOCALES.iter
Performance
- Runtime: Zero-cost abstractions; all operations are compile-time validated
- Memory: Locale enum variants are zero-sized types
Error Handling
use ;
use FromStr;
match from_str
Architecture
This library is auto-generated from Unicode CLDR data by the locale-dev tool. The generation process:
- Fetches the latest CLDR-JSON release from GitHub
- Parses locale definitions and formatting rules
- Generates strongly-typed Rust code
- Formats and lints the generated code
See locale-dev README for details on the code generation pipeline.
Updating to Latest CLDR
The library is automatically updated when new CLDR releases are available. To manually update:
# In the workspace root
# This will:
# 1. Check GitHub for the latest CLDR release
# 2. Generate updated code
# 3. Format and lint the generated code
Licensing
This project respects and adheres to the licensing requirements of its source data:
- Data Source: All locale data is derived from the Unicode CLDR project and is subject to the Unicode License V3.
- Code Inspiration: Architectural patterns inspired by
num-format, dual-licensed under Apache-2.0 or MIT. - This Project: Licensed under MIT License or Apache-2.0 License.
Contributing
Contributions are welcome! Since the core code is generated, most improvements should be directed toward:
- locale-dev: Improving code generation logic
- locale-rs: Adding new helper methods or improving documentation
- Tests: Expanding test coverage
If you find a missing locale or discrepancy with CLDR standards, please open an issue.
See Also
- locale-dev - Code generation tool
- CLDR Project - Unicode locale data source
- CLDR-JSON Repository - GitHub source
- num-format - Inspiration for this library