Skip to content

Repository files navigation

language

Typed BCP47 language tags with names, plural metadata, and conversion helpers to common libraries.

LicenseDocsRustReleaseGitHub tag (latest by date)GitHub last commitGitHub code lines

Introduction

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.

Feature Highlights

  • Typed coverage of BCP47 language tags through a single Language enum.
  • Conversion helpers: 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.
  • Optional serde feature for serializing and deserializing language values.
  • Code is generated directly from the translation.io “languages with plural cases” page; cargo build enforces validity and the language binary downloads fresh data when regenerating.
  • Optional ICU4X interop (icu_locale_core feature) for converting to/from Locale and LanguageIdentifier.
  • Optional whatlang interop (whatlang feature) for converting to/from whatlang::Lang with clear error reporting.
  • Optional lingua interop (lingua feature) for converting to/from lingua::Language with clear error reporting.
  • Optional SQLx interop (sqlx-postgres / sqlx-mysql / sqlx-sqlite) for Type/Encode/Decode support using textual tags.

Usage

// crates.iouse 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");

More examples

Parse user input safely (any invalid tag becomes a typed error):

// crates.iouse 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.iouse language::Language;let tags:Vec<&'staticstr> = Language::all().iter().map(Language::tag).collect();assert!(tags.contains(&"fr-CA"));

serde (enable the serde feature):

// crates.iouse language::Language;use serde::{Deserialize,Serialize};#[derive(Debug,Serialize,Deserialize,PartialEq)]structPayload{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.iouse 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.iouse language::Language;use whatlang::Lang;let lang = Language::try_from(Lang::Ukr)?;assert_eq!(lang,Language::Uk);

lingua interop (enable lingua):

// crates.iouse language::Language;use lingua::LanguageasLinguaLanguage;let lang = Language::try_from(LinguaLanguage::Japanese)?;assert_eq!(lang,Language::Ja);

SQLx (enable one of the sqlx-* features):

// crates.iouse 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);

Support Me

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.

  • Fiat
  • Crypto
    • Bitcoin
      • bc1pedlrf67ss52md29qqkzr2avma6ghyrt4jx9ecp9457qsl75x247sqcp43c
    • Ethereum
      • 0x3e25247CfF03F99a7D83b28F207112234feE73a6
    • Polkadot
      • 156HGo9setPcU2qhFMVWLkcmtCEGySLwNqa3DaEiYSWtte4Y

Thank you for your support!

Appreciation

We would like to extend our heartfelt gratitude to the following projects and contributors:

  • The Rust community for their continuous support and development of the Rust ecosystem.
  • translation.io for publishing the languages-with-plural-cases reference we build from.

Additional Acknowledgements

License

Licensed under GPL-3.0.

About

Typed BCP47 language tags with names, plural metadata, and conversion helpers to common libraries.

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

Generated from acg-box/vibe-mono