Validation

Countries

ISO 3166 countries for forms and addresses: alpha-2, alpha-3 and numeric codes, names in several languages, calling codes, flags, continents, currencies and EU membership.

Version 1.0.0 · 5 functions · 1 crate

#forms#addresses#phone#i18n

Functions

What use countries.qwer gives a program, with the types Quillo sees. To take only some, or under other names: use country, country_list from countries (Quillo 0.6).

country(code_or_name: str) → anyor an error

A country by its code or name: "FR", "FRA", "250", "France", "French Republic" or a common name, in several languages ("The Netherlands", "Deutschland", "Estados Unidos"). Gives { alpha2, alpha3, numeric, name, official_name, calling_code, flag, continent, region, currency, languages, eu, postal_codes }; postal_codes says whether its addresses have them. An error when there is none.

country_list() → list

All 249 countries as [{ alpha2, name, flag, calling_code }], sorted by name: the options of a country select or a phone prefix picker.

country_by_calling_code(code: str) → list

The countries using a calling code, as alpha-2 codes: "+44" is ["GB", "GG", "IM", "JE"]; "1" is the US, Canada and the Caribbean.

country_flag(alpha2: str) → str?

The flag emoji of an alpha-2 code: "JP" is 🇯🇵. Made from the letters, so it is null only when the code is not two letters.

country_valid(code: str) → bool

Whether code is an assigned ISO 3166-1 alpha-2 or alpha-3 code, case ignored.

Get it

$ quillo install countries               # countries.qwer into this folder$ quillo install countries --example     # and its example, countries.qwe

Or with curl:

$ curl -O https://quillolang.org/plugins/files/countries.qwer$ curl -O https://quillolang.org/plugins/files/countries.qwe

Then, in your program, all of it or only what you call:

main.qwe
use countries.qweruse country, country_list from countries      // Quillo 0.6: only these

It uses this crate, which cargo fetches the first time the plugin is built:

[dependencies]
keshvar = { version = "0.7", features = ["emojis", "search-iso-short-name", "search-iso-long-name", "search-iso-number"] }

Example

countries.qwe
// A checkout's country select with flags and phone prefixes, and an address check.////   quillo run countries.qwe      then open http://localhost:8080/country?q=Deutschlanduse "countries.qwer"route GET /country ? { q: str } = country(q)?route GET /select = <html>    <body>        <select name="country">{country_list() | map((c) => <option value={c.alpha2}>{`${c.flag} ${c.name} (${c.calling_code})`}</option>)}</select>    </body></html>route GET /codes = {    count: len(country_list()),    plus44: country_by_calling_code("+44"),    flag: country_flag("jp"),    valid: [country_valid("DE"), country_valid("DEU"), country_valid("XX")],    numeric: country("840")?.name,}
$ quillo run countries.qwe$ curl 'localhost:8080/country?q=Deutschland'$ curl 'localhost:8080/codes'$ curl 'localhost:8080/select'

Source

countries.qwer
//! ISO 3166 countries for forms, addresses and phone fields: codes (US, USA, 840), names, calling codes, flags, continents, currencies and EU membership.//! version: 1.0.0//!//! [dependencies]//! keshvar = { version = "0.7", features = ["emojis", "search-iso-short-name", "search-iso-long-name", "search-iso-number"] }use keshvar::{Country, CountryIterator};use serde_json::{json, Value};fn find(code_or_name: &str) -> Result<Country, String> {    let q = code_or_name.trim();    let not_found = || format!("no country {:?}", code_or_name);    if q.is_empty() || q.len() > 100 {        return Err(not_found());    }    if let Ok(n) = q.parse::<usize>() {        return keshvar::find_by_number(n).map_err(|_| not_found());    }    if q.len() <= 3 {        if let Ok(c) = Country::try_from(q) {            return Ok(c);        }    }    let l = q.to_lowercase();    keshvar::find_by_iso_short_name(&l)        .or_else(|_| keshvar::find_by_iso_long_name(&l))        .ok()        .or_else(|| CountryIterator::new().find(|c| c.unofficial_name_list().iter().any(|n| n.to_lowercase() == l)))        .ok_or_else(not_found)}fn info(c: &Country) -> Value {    json!({        "alpha2": c.alpha2().to_string(),        "alpha3": c.alpha3().to_string(),        "numeric": c.number(),        "name": c.iso_short_name(),        "official_name": c.iso_long_name(),        "calling_code": format!("+{}", c.country_code()),        "flag": c.emoji(),        "continent": c.continent().to_string(),        "region": c.maybe_subregion().map(|r| r.to_string()),        "currency": c.currency_code().to_string(),        "languages": c.maybe_official_language_list(),        "eu": c.eu_member(),        "postal_codes": c.postal_code(),    })}/// A country by its code or name: "FR", "FRA", "250", "France", "French Republic" or a common name, in several languages ("The Netherlands", "Deutschland", "Estados Unidos"). Gives `{ alpha2, alpha3, numeric, name, official_name, calling_code, flag, continent, region, currency, languages, eu, postal_codes }`; `postal_codes` says whether its addresses have them. An error when there is none.pub fn country(code_or_name: &str) -> Result<Value, String> {    Ok(info(&find(code_or_name)?))}/// All 249 countries as `[{ alpha2, name, flag, calling_code }]`, sorted by name: the options of a country select or a phone prefix picker.pub fn country_list() -> Vec<Value> {    let mut all: Vec<Country> = CountryIterator::new().collect();    all.sort_by(|a, b| a.iso_short_name().cmp(b.iso_short_name()));    all.iter().map(|c| json!({ "alpha2": c.alpha2().to_string(), "name": c.iso_short_name(), "flag": c.emoji(), "calling_code": format!("+{}", c.country_code()) })).collect()}/// The countries using a calling code, as alpha-2 codes: "+44" is ["GB", "GG", "IM", "JE"]; "1" is the US, Canada and the Caribbean.pub fn country_by_calling_code(code: &str) -> Vec<String> {    let n: usize = code.trim().trim_start_matches('+').parse().unwrap_or(0);    let mut v: Vec<String> = CountryIterator::new().filter(|c| c.country_code() == n).map(|c| c.alpha2().to_string()).collect();    v.sort();    v}/// The flag emoji of an alpha-2 code: "JP" is 🇯🇵. Made from the letters, so it is null only when the code is not two letters.pub fn country_flag(alpha2: &str) -> Option<String> {    let a = alpha2.trim().to_uppercase();    if a.len() != 2 || !a.chars().all(|c| c.is_ascii_uppercase()) {        return None;    }    Some(a.chars().filter_map(|c| char::from_u32(0x1F1E6 + (c as u32 - 'A' as u32))).collect())}/// Whether `code` is an assigned ISO 3166-1 alpha-2 or alpha-3 code, case ignored.pub fn country_valid(code: &str) -> bool {    let q = code.trim();    (q.len() == 2 && keshvar::Alpha2::try_from(q).is_ok()) || (q.len() == 3 && keshvar::Alpha3::try_from(q).is_ok())}
Thread
97Useful? Like it, or add to its thread below.

Thread 0 posts

On Countries: questions, tips, corrections, and code that uses it.

No posts yet. The first one opens the thread.