1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#![deny(intra_doc_link_resolution_failure)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![deny(missing_docs)]
#![deny(warnings)]
#![deny(rust_2018_idioms)]

//! Lightweight static `Jurisdiction` information.
//!
//! This crate provides interfaces to work with jurisdictions for areas around the world.
//! Information about a jurisdiction includes
//! * ISO 3166 [Alpha2] and [Alpha3] character codes.
//! * ISO 3166 numeric country code.
//! * [UN M49] region classifications.
//!
//! The [Jurisdiction] object is a lightweight object, the size of a pointer,
//! suitable for transfer in API surfaces throughout an ecosystem. Serialization on
//! API boundaries may choose to employ any of the standardized classification formats.
//!
//! # Examples
//!
//! Retrieve jurisdiction from API boundary and validate supported jurisdictions
//! ```rust
//! use anyhow::{Result, anyhow, format_err};
//! use jurisdiction::{Jurisdiction, Alpha2, Alpha3};
//! use jurisdiction::region::{Region, SubRegion};
//! use std::str::FromStr;
//!
//! fn supported_jurisdiction(alpha: &str) -> Result<Jurisdiction> {
//!     let jurisdiction = Jurisdiction::from_str(alpha)?;
//!     match jurisdiction.alpha2() {
//!         Alpha2::NO | Alpha2::SE | Alpha2::DK => Ok(jurisdiction),
//!         _ => Err(format_err!("only scandinavian countries are supported")),
//!     }
//! }
//!
//! let jurisdiction = supported_jurisdiction("NO").expect("unsupported");
//!
//! assert_eq!(jurisdiction, Alpha2::NO);
//! assert_eq!(jurisdiction.alpha2(), Alpha2::NO);
//! assert_eq!(jurisdiction.alpha2().to_string(), "NO");
//!
//! assert_eq!(jurisdiction, Alpha3::NOR);
//! assert_eq!(jurisdiction.alpha3(), Alpha3::NOR);
//! assert_eq!(jurisdiction.alpha3().to_string(), "NOR");
//!
//! assert_eq!(jurisdiction.country_code(), 578);
//!
//! assert_eq!(jurisdiction.region(), Region::Europe);
//! assert_eq!(jurisdiction.sub_region(), SubRegion::NorthernEurope);
//! ```
//!
//! Construct `Jurisdiction` from string:
//! ```rust
//! # use jurisdiction::{Jurisdiction, Alpha2};
//! # use std::str::FromStr;
//! let jurisdiction = Jurisdiction::from_str("NO");
//! assert!(jurisdiction.is_ok());
//! assert_eq!(jurisdiction.unwrap(), Alpha2::NO);
//! ```
//!
//! Construct `Jurisdiction` from `Alpha2`/`Alpha3`:
//! ```rust
//! # use jurisdiction::{Jurisdiction, Alpha2, Alpha3};
//! # use std::str::FromStr;
//! let jurisdiction = Jurisdiction::from(Alpha2::NO);
//! assert_eq!(jurisdiction, Alpha2::NO);
//!
//! let jurisdiction = Jurisdiction::from(Alpha3::NOR);
//! assert_eq!(jurisdiction, Alpha3::NOR);
//! ```

//!
//! # Static jurisdiction information
//!
//! All the static information about a jurisdiction is embedded into the application binary
//! through a `lazy_static` hashmap declaration, populated on first use from const definitions.
//! This way, the only copy of the definition should reside in the hashmap.
//!
//! This map is not publicly exported from the crate, only accessible through `Jurisdiction`.
//! A `Jurisdiction` object simply contains the reference to the definition within this hashmap,
//! making all look-up operations a simple pointer dereference into the statically
//! stored item in this global hashmap.
//!
//!
//! # Features
//! This crate has the following features:
//!
//! * `region`: Include the [region] module with region definitions and `Jurisdiction` array
//! methods returning the zoning jurisdictions within these regions (`in_*_region`).
//!
//!
//! [UN M49]: https://unstats.un.org/unsd/methodology/m49/overview
//! [region]: mod.region.html
//! [Jurisdiction]: struct.Jurisdiction.html
//! [Alpha2]: enum.Alpha2.html
//! [Alpha3]: enum.Alpha3.html

mod definition;
mod generated;
mod jurisdiction;
#[cfg(feature = "region")]
pub mod region;

// Re-export generated modules
use crate::generated::alpha;

// Publicly export types
pub use crate::alpha::{Alpha2, Alpha3};
pub use crate::jurisdiction::Jurisdiction;

// Assert properties about crate types
use static_assertions as sa;

#[cfg(feature = "region")]
sa::assert_impl_all!(crate::region::Region: Sized, Send, Sync);
#[cfg(feature = "region")]
sa::assert_impl_all!(crate::region::SubRegion: Sized, Send, Sync);
#[cfg(feature = "region")]
sa::assert_impl_all!(crate::region::IntermediateRegion: Sized, Send, Sync);

#[cfg(feature = "region")]
sa::assert_eq_size!(crate::region::Region, u8);
#[cfg(feature = "region")]
sa::assert_eq_size!(crate::region::SubRegion, u8);
#[cfg(feature = "region")]
sa::assert_eq_size!(crate::region::IntermediateRegion, u8);

sa::assert_impl_all!(crate::definition::Definition: Sized, Send, Sync);

// Assert that the Jurisdiction object is the same size as a simple pointer.
sa::assert_eq_size!(Jurisdiction, usize);

sa::assert_eq_size!(Alpha2, u8);
sa::assert_eq_size!(Alpha3, u8);