celes

A no_std Rust crate for parsing ISO 3166-1 country codes and optional ISO 3166-2 subdivisions.

Library
Cargo
v3.0.0-pre2
23stars
Apache-2.0 OR MIT

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
46/100Fair
Development Activity68
Maintenance24
Community20
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
80/100Excellent
Architecture82
Code Quality93
Innovation58
Learning Curve85

Celes is a Rust crate that provides a strongly-typed Country struct for every ISO 3166-1 country, with lookup by numeric code, alpha-2 code, alpha-3 code, full state name, or common alias, plus a case-insensitive FromStr implementation that accepts any of those identifier forms. It is no_std compatible and ships with an optional serde feature, enabled by default, that serializes and deserializes a Country as its compact alpha-2 code.

An optional subdivisions feature adds ISO 3166-2 country subdivision data sourced from Unicode CLDR — over 5,000 current subdivision codes with English names, allocation-free binary-search lookups, and a precomputed index that links each subdivision back to its owning country. Version 3 of the crate replaced the previous per-country enum and wrapper-type hierarchy with static alias slices, shrinking Country from 192 to 88 bytes on 64-bit targets while keeping every lookup backed by compile-time perfect-hash maps.

What You Get

  • A Country struct with code, value, alpha2, alpha3, long_name, and aliases fields for every current ISO 3166-1 country
  • Six lookup functions (from_code, from_value, from_alpha2, from_alpha3, from_alias, from_name) plus a case-insensitive FromStr impl
  • An optional Subdivision type with ISO 3166-2 codes and English names for 5,000+ subdivisions sourced from Unicode CLDR
  • Optional serde support that (de)serializes Country as its alpha-2 code
  • no_std compatibility with zero heap allocation anywhere in the lookup path

Common Use Cases

  • Validating and normalizing user-supplied country input (names, ISO codes, or common aliases) in web forms
  • Storing and querying country and subdivision data on embedded or no_std targets without pulling in std
  • Serializing country fields to and from JSON, CBOR, TOML, or other serde-compatible formats using compact alpha-2 codes
  • Building address or shipping-region validators that need to resolve a US state or Canadian province code back to its parent country

Under The Hood

Architecture The crate is data-oriented rather than layered: src/lib.rs defines the core Country type, a country! macro that emits one const fn constructor per country (avoiding any runtime allocation or table lookup for construction), and seven phf perfect-hash maps (VALUE_MAP, NUMERIC_CODE_MAP, ALPHA2_MAP, ALPHA3_MAP, ALIAS_MAP, NAME_MAP, PARSE_MAP) that back the public lookup functions with O(1) access. An optional src/subdivision.rs module, gated behind the subdivisions feature, depends on a large generated table in src/subdivision_data.rs (5,027 entries) plus a small compile-time index array (country_indexes_by_alpha2) that maps a subdivision’s alpha-2 prefix straight back to its owning Country without re-parsing. The subdivision table itself is generated offline from CLDR XML by tools/generate_subdivisions.rs and checked into the repo, so refreshing ISO 3166-2 data is a codegen step rather than a runtime concern.

Tech Stack A Rust 2024-edition crate with MSRV 1.97, no_std by default. Runtime dependencies are phf 0.14 (default-features = false) for the perfect-hash maps, thiserror 2 (default-features = false) for the typed error enums, and an optional serde 1 dependency gated by the default-on serde feature. Dev-dependencies exercise serialization round-trips across five formats: postcard, serde_cbor_2, serde_json, toml, and yaml_serde. CI (.github/workflows/celes.yml) runs cargo build/test with --all-features, an MSRV check cross-compiled to the thumbv7m-none-eabi embedded target to confirm true no_std support, coverage via cargo-llvm-cov with a 100%-line-coverage gate uploaded to Codecov, clippy with pedantic lints denied, rustfmt --check, cargo doc, and cargo-udeps for unused-dependency detection.

Code Quality Tests live in tests/country.rs, tests/subdivision.rs, and tests/serde.rs, plus doctests embedded throughout lib.rs’s module documentation. country.rs iterates every Country and asserts that from_str, from_name, from_value, from_code, and from_alpha2/from_alpha3 all round-trip correctly, alongside Ord, Hash, Debug, and struct-size assertions. Error handling is explicit and typed — CountryParseError and SubdivisionParseError are thiserror-derived enums with one variant per failure mode, and clippy::unwrap_used = "deny" keeps panics out of non-test code. Naming is consistent snake_case per ISO country name, and both Country and Subdivision are Copy structs backed by 'static string slices, so there is no fallible or allocating construction outside the lookup functions themselves. CI enforces clippy::pedantic (deny), rustfmt --check, and a 100%-line-coverage gate, a materially high bar most crates in this category don’t hold themselves to.

API Design The public surface favors discoverability over cleverness: every ISO country has its own const fn constructor named after the country in snake_case (e.g. Country::the_united_states_of_america()), and callers who don’t know which lookup function they need can reach for FromStr, which accepts numeric codes, alpha-2/alpha-3 codes, full names, and aliases interchangeably and case-insensitively. All fallible lookups return a typed Result<_, _Error> rather than an Option, so callers get a specific reason for a failed parse. Getting started requires zero configuration — Country::from_str("USA") works with the default feature set — and enabling subdivisions or disabling serde is a one-line Cargo.toml change, documented with runnable examples directly in the README and crate-level docs.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search