geo_kit/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]
2#![forbid(unsafe_code)]
3#![deny(missing_docs)]
4
5//! # geo-kit
6//!
7//! Typed newtypes for validated geo primitives — replaces hand-rolled `is_valid_*` checks
8//! with parse-once, use-everywhere strong types.
9//!
10//! | Type | Validation |
11//! |------|-----------|
12//! | [`UkPostcode`] | UK postcode `^[A-Z]{1,2}[0-9][A-Z0-9]? [0-9][A-Z]{2}$`, space optional, uppercase normalized |
13//! | [`UsZipCode`] | US ZIP `^\d{5}(-\d{4})?$` |
14//! | [`Postcode`] | Generic postcode (UK or US) |
15//! | [`CountryCode`] | ISO 3166-1 alpha-2 `^[A-Z]{2}$`, with `country_name()` mapping |
16//! | [`Coords`] | Latitude `-90..=90`, longitude `-180..=180`, finite |
17//! | [`Address`] | Validated address with non-empty lines, postcode, country, optional coords |
18//!
19//! ## Example
20//!
21//! ```rust
22//! use geo_kit::{UkPostcode, CountryCode, Coords, Address};
23//!
24//! let pc = UkPostcode::parse("SW1A 1AA").expect("valid");
25//! assert_eq!(pc.as_str(), "SW1A 1AA");
26//!
27//! let cc = CountryCode::parse("GB").expect("valid");
28//! assert_eq!(cc.country_name(), "United Kingdom");
29//!
30//! let coords = Coords::new(51.5074, -0.1278).expect("valid");
31//! assert!(coords.lat > 51.0);
32//!
33//! let addr = Address::new(
34//! "10 Downing St".to_string(),
35//! None,
36//! "London".to_string(),
37//! None,
38//! pc,
39//! cc,
40//! ).expect("valid");
41//! assert_eq!(addr.city(), "London");
42//! ```
43//!
44//! All postcode/country types implement `TryFrom<String>`, `FromStr`, `Display`, `Deref<Target=str>`,
45//! `AsRef<str>`, and optional `serde` transparent (de)serialization.
46
47extern crate alloc;
48
49pub mod address;
50pub mod coords;
51pub mod country;
52pub mod error;
53pub mod postcode;
54
55// Re-exports
56pub use address::{Address, AddressBuilder, PostcodeChoice};
57pub use coords::{Coords, is_valid_coords};
58pub use country::{CountryCode, is_valid_country_code};
59pub use error::GeoError;
60pub use postcode::{Postcode, UkPostcode, UsZipCode, is_valid_uk_postcode, is_valid_us_zip};
61
62#[cfg(test)]
63mod smoke {
64 use super::*;
65
66 #[test]
67 fn reexports_work() {
68 let _ = UkPostcode::parse("SW1A 1AA").expect("valid");
69 let _ = UsZipCode::parse("90210").expect("valid");
70 let _ = Postcode::parse("SW1A 1AA").expect("valid");
71 let _ = CountryCode::parse("GB").expect("valid");
72 let _ = Coords::new(51.5, -0.12).expect("valid");
73 let _ = Address::new(
74 "10 Downing St".to_string(),
75 None,
76 "London".to_string(),
77 None,
78 UkPostcode::parse("SW1A 1AA").expect("valid"),
79 CountryCode::parse("GB").expect("valid"),
80 )
81 .expect("valid");
82 }
83}