| Crates.io | language |
| lib.rs | language |
| version | 0.4.1 |
| created_at | 2024-07-15 14:05:59.308044+00 |
| updated_at | 2026-01-17 12:32:28.949521+00 |
| description | Typed BCP47 language tags with built-in names, plural metadata, and conversion helpers. |
| homepage | https://hack.ink/language |
| repository | https://github.com/hack-ink/language |
| max_upload_size | |
| id | 1303892 |
| size | 210,025 |
Typed BCP47 language tags with names, plural metadata, and conversion helpers to common libraries.
Language tags are defined in BCP47. A friendly overview is available in the W3C article “Language tags in HTML and XML.” These tags are commonly used in HTML and in the Content-Language and Accept-Language HTTP headers.
Language enum.tag, name, and local_name give tags, English names, and native names, with TryFrom for parsing.Language::all() provides a compile-time array for iterating over every language without allocation.serde feature for serializing and deserializing language values.cargo build enforces validity and the language binary downloads fresh data when regenerating.icu_locale_core feature) for converting to/from Locale and LanguageIdentifier.whatlang feature) for converting to/from whatlang::Lang with clear error reporting.lingua feature) for converting to/from lingua::Language with clear error reporting.sqlx-postgres / sqlx-mysql / sqlx-sqlite) for Type/Encode/Decode support using textual tags.// crates.io
use language::Language;
let en = Language::En;
assert_eq!(en.tag(), "en");
assert_eq!(Language::try_from("en").unwrap(), Language::En);
assert_eq!(en.name(), "English");
assert_eq!(en.local_name(), "English");
Parse user input safely (any invalid tag becomes a typed error):
// crates.io
use language::Language;
let parsed: Result<Language, _> = Language::try_from("zh-Hant");
assert!(parsed.is_ok());
let bad = Language::try_from("zz-INVALID");
assert!(bad.is_err());
Iterate over every language without allocation:
// crates.io
use language::Language;
let tags: Vec<&'static str> = Language::all().iter().map(Language::tag).collect();
assert!(tags.contains(&"fr-CA"));
serde (enable the serde feature):
// crates.io
use language::Language;
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct Payload {
lang: Language,
}
let json = r#"{"lang":"es-MX"}"#;
let payload: Payload = serde_json::from_str(json)?;
assert_eq!(payload.lang, Language::EsMx);
ICU4X interop (enable icu_locale_core):
// crates.io
use icu_locale_core::Locale;
use language::Language;
let locale: Locale = "pt-BR".parse()?;
let language = Language::try_from(&locale)?;
assert_eq!(language.tag(), "pt-BR");
whatlang interop (enable whatlang):
// crates.io
use language::Language;
use whatlang::Lang;
let lang = Language::try_from(Lang::Ukr)?;
assert_eq!(lang, Language::Uk);
lingua interop (enable lingua):
// crates.io
use language::Language;
use lingua::Language as LinguaLanguage;
let lang = Language::try_from(LinguaLanguage::Japanese)?;
assert_eq!(lang, Language::Ja);
SQLx (enable one of the sqlx-* features):
// crates.io
use language::Language;
use sqlx::types::Json;
// Language stores as a text tag; works with Postgres/MySQL/SQLite feature flags.
let stored = Language::Ja;
let row = sqlx::query!("select $1 as lang", stored)
.fetch_one(&pool)
.await?;
assert_eq!(row.lang, Language::Ja);
If you find this project helpful and would like to support its development, you can buy me a coffee!
Your support is greatly appreciated and motivates me to keep improving this project.
bc1pedlrf67ss52md29qqkzr2avma6ghyrt4jx9ecp9457qsl75x247sqcp43c0x3e25247CfF03F99a7D83b28F207112234feE73a6156HGo9setPcU2qhFMVWLkcmtCEGySLwNqa3DaEiYSWtte4YThank you for your support!
We would like to extend our heartfelt gratitude to the following projects and contributors:
cargo run --features codegen --bin language.Licensed under GPL-3.0.