ng-postcode-polars 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ng_postcode_polars-0.1.0/CRATE.md +78 -0
- ng_postcode_polars-0.1.0/Cargo.lock +436 -0
- ng_postcode_polars-0.1.0/Cargo.toml +34 -0
- ng_postcode_polars-0.1.0/LICENSE +21 -0
- ng_postcode_polars-0.1.0/PKG-INFO +82 -0
- ng_postcode_polars-0.1.0/README.md +63 -0
- ng_postcode_polars-0.1.0/examples/lookup.rs +14 -0
- ng_postcode_polars-0.1.0/native/polars/Cargo.lock +2396 -0
- ng_postcode_polars-0.1.0/native/polars/Cargo.toml +24 -0
- ng_postcode_polars-0.1.0/native/polars/LICENSE +21 -0
- ng_postcode_polars-0.1.0/native/polars/README.md +63 -0
- ng_postcode_polars-0.1.0/native/polars/src/lib.rs +77 -0
- ng_postcode_polars-0.1.0/native/polars/tests/test_conformance.py +73 -0
- ng_postcode_polars-0.1.0/native/polars/uv.lock +520 -0
- ng_postcode_polars-0.1.0/ng_postcode_polars/__init__.py +62 -0
- ng_postcode_polars-0.1.0/ng_postcode_polars/py.typed +0 -0
- ng_postcode_polars-0.1.0/pyproject.toml +50 -0
- ng_postcode_polars-0.1.0/src/api.rs +594 -0
- ng_postcode_polars-0.1.0/src/client.rs +151 -0
- ng_postcode_polars-0.1.0/src/lib.rs +34 -0
- ng_postcode_polars-0.1.0/src/postcode.rs +567 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# ng-postcode
|
|
2
|
+
|
|
3
|
+
[](https://crates.io/crates/ng-postcode)
|
|
4
|
+
[](https://docs.rs/ng-postcode)
|
|
5
|
+
|
|
6
|
+
Rust library for Nigeria's National Digital Alphanumeric Postcode System (NDAPS), the building-level postcode NIPOST launched in October 2026. Parse, validate and format postcodes offline, and call the [postcode.gov.ng](https://docs.postcode.gov.ng) API for lookup, autocomplete and reverse geocoding.
|
|
7
|
+
|
|
8
|
+
Part of the [ng-postcode project](https://github.com/Adeniyikayodee/ng-postcode), which has the same behaviour in Python, JavaScript and Java, MCP servers for AI assistants, and an address resolver.
|
|
9
|
+
|
|
10
|
+
## Format
|
|
11
|
+
|
|
12
|
+
An 11-character code in five segments: state, LGA, district, area, building unit.
|
|
13
|
+
|
|
14
|
+
| Form | Example | Use it to |
|
|
15
|
+
| --- | --- | --- |
|
|
16
|
+
| Canonical | `EK-01-A03-FK-01` | Write a code and pass it between systems |
|
|
17
|
+
| Spaced | `EK 01 A03 FK 01` | Show a code to people |
|
|
18
|
+
| Compact | `EK01A03FK01` | Store and compare codes |
|
|
19
|
+
|
|
20
|
+
Compact form as a regular expression: `^[A-Z]{2}(0[1-9]|[1-9][0-9])[A-Z0-9]{3}[A-Z]{2}(0[1-9]|[1-9][0-9])$`
|
|
21
|
+
|
|
22
|
+
## Offline
|
|
23
|
+
|
|
24
|
+
```rust
|
|
25
|
+
use ng_postcode::{ParseError, Postcode, Segment};
|
|
26
|
+
|
|
27
|
+
fn main() -> Result<(), ParseError> {
|
|
28
|
+
// Hyphens, spaces and case are all accepted.
|
|
29
|
+
let code: Postcode = "ek 01 a03 fk 01".parse()?;
|
|
30
|
+
|
|
31
|
+
assert_eq!(code.to_string(), "EK-01-A03-FK-01"); // canonical
|
|
32
|
+
assert_eq!(code.as_str(), "EK01A03FK01"); // compact, for storage
|
|
33
|
+
assert_eq!(code.to_spaced(), "EK 01 A03 FK 01"); // for display
|
|
34
|
+
|
|
35
|
+
assert_eq!(code.state(), "EK");
|
|
36
|
+
assert_eq!(code.prefix(Segment::Area), "EK-01-A03-FK");
|
|
37
|
+
Ok(())
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
- `Postcode::parse` checks the structure: 2 letters, 2 digits, 3 letters or digits, 2 letters, 2 digits, with numeric segments from 01 to 99.
|
|
42
|
+
- `Postcode::parse_lenient` first swaps look-alike characters that cannot occur where they stand (`O`/`0`, `I`/`1`, `S`/`5`, `B`/`8`) and reports how many it changed.
|
|
43
|
+
- `Postcode::from_segments` assembles a code from its parts and zero-fills the LGA and unit.
|
|
44
|
+
- `Prefix::parse` reads a code cut off after a segment, such as the district `EK-01-A03`, and `Postcode::truncate` cuts a code down to one. A prefix knows which codes it contains, so it groups them by state, LGA, district, or area.
|
|
45
|
+
- `Postcode` is `Copy`, 11 bytes, and sorts by state, LGA, district, area, unit.
|
|
46
|
+
|
|
47
|
+
A well-formed code is not necessarily assigned to a building, and the state is not checked against a list of state codes. Only the API can confirm that a postcode exists.
|
|
48
|
+
|
|
49
|
+
## API
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
cargo add ng-postcode --features client
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```rust,no_run
|
|
56
|
+
use ng_postcode::{api, client::Client};
|
|
57
|
+
|
|
58
|
+
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
59
|
+
let client = Client::new(std::env::var("NG_POSTCODE_API_KEY")?);
|
|
60
|
+
let found = client.send(&api::lookup("FC-03-B06-AG-12".parse()?, 2)?)?;
|
|
61
|
+
println!("{:?}", found.administrative_address);
|
|
62
|
+
Ok(())
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`api` covers lookup, autocomplete, reverse geocoding and nearby search. Each function returns a `Request` value, or `InvalidRequest` for one the API cannot answer, such as an empty autocomplete or a coordinate that is not finite, and `Request::decode` turns a status and body into a typed result, so the `api` feature alone works with any HTTP client, sync or async. The `client` feature adds a small blocking one, built on `ureq`. If your program installs a `log` logger at trace level, `ureq` writes each request's bytes to it, the key among them.
|
|
67
|
+
|
|
68
|
+
## Features
|
|
69
|
+
|
|
70
|
+
| Feature | Adds |
|
|
71
|
+
| --- | --- |
|
|
72
|
+
| `serde` | `Serialize` and `Deserialize` for `Postcode` |
|
|
73
|
+
| `api` | Request and response types, no I/O |
|
|
74
|
+
| `client` | Blocking HTTP client |
|
|
75
|
+
|
|
76
|
+
## License
|
|
77
|
+
|
|
78
|
+
MIT
|
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
# This file is automatically @generated by Cargo.
|
|
2
|
+
# It is not intended for manual editing.
|
|
3
|
+
version = 4
|
|
4
|
+
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "adler2"
|
|
7
|
+
version = "2.0.1"
|
|
8
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
9
|
+
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
|
10
|
+
|
|
11
|
+
[[package]]
|
|
12
|
+
name = "base64"
|
|
13
|
+
version = "0.23.1"
|
|
14
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
15
|
+
checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5"
|
|
16
|
+
|
|
17
|
+
[[package]]
|
|
18
|
+
name = "bytes"
|
|
19
|
+
version = "1.12.1"
|
|
20
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
21
|
+
checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
|
|
22
|
+
|
|
23
|
+
[[package]]
|
|
24
|
+
name = "cc"
|
|
25
|
+
version = "1.5.1"
|
|
26
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
27
|
+
checksum = "f360145194ee8e21db5ee7f3fcd4fe52210864c75c985dae33218202c8bbe040"
|
|
28
|
+
dependencies = [
|
|
29
|
+
"find-msvc-tools",
|
|
30
|
+
"shlex",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[[package]]
|
|
34
|
+
name = "cfg-if"
|
|
35
|
+
version = "1.0.5"
|
|
36
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
37
|
+
checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600"
|
|
38
|
+
|
|
39
|
+
[[package]]
|
|
40
|
+
name = "crc32fast"
|
|
41
|
+
version = "1.5.2"
|
|
42
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
43
|
+
checksum = "01a7799fd6b852db0e61728dde9a204c423b44d689dbd432522543614b490e78"
|
|
44
|
+
dependencies = [
|
|
45
|
+
"cfg-if",
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
[[package]]
|
|
49
|
+
name = "find-msvc-tools"
|
|
50
|
+
version = "0.1.14"
|
|
51
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
52
|
+
checksum = "aedcfb3409746eddb02b9e19ebda1c3394f759a152e48ee875a0844d1b955484"
|
|
53
|
+
|
|
54
|
+
[[package]]
|
|
55
|
+
name = "flate2"
|
|
56
|
+
version = "1.1.10"
|
|
57
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
58
|
+
checksum = "6e634e2e0ebac1ee034020da1ca582e17ffe4e0f5e985823721e168928136dcb"
|
|
59
|
+
dependencies = [
|
|
60
|
+
"crc32fast",
|
|
61
|
+
"miniz_oxide",
|
|
62
|
+
"zlib-rs",
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
[[package]]
|
|
66
|
+
name = "getrandom"
|
|
67
|
+
version = "0.2.17"
|
|
68
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
69
|
+
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
|
|
70
|
+
dependencies = [
|
|
71
|
+
"cfg-if",
|
|
72
|
+
"libc",
|
|
73
|
+
"wasi",
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
[[package]]
|
|
77
|
+
name = "http"
|
|
78
|
+
version = "1.5.0"
|
|
79
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
80
|
+
checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0"
|
|
81
|
+
dependencies = [
|
|
82
|
+
"bytes",
|
|
83
|
+
"itoa",
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
[[package]]
|
|
87
|
+
name = "httparse"
|
|
88
|
+
version = "1.10.1"
|
|
89
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
90
|
+
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
|
|
91
|
+
|
|
92
|
+
[[package]]
|
|
93
|
+
name = "itoa"
|
|
94
|
+
version = "1.0.18"
|
|
95
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
96
|
+
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
|
97
|
+
|
|
98
|
+
[[package]]
|
|
99
|
+
name = "libc"
|
|
100
|
+
version = "0.2.190"
|
|
101
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
102
|
+
checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78"
|
|
103
|
+
|
|
104
|
+
[[package]]
|
|
105
|
+
name = "log"
|
|
106
|
+
version = "0.4.34"
|
|
107
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
108
|
+
checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6"
|
|
109
|
+
|
|
110
|
+
[[package]]
|
|
111
|
+
name = "memchr"
|
|
112
|
+
version = "2.8.3"
|
|
113
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
114
|
+
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
|
|
115
|
+
|
|
116
|
+
[[package]]
|
|
117
|
+
name = "miniz_oxide"
|
|
118
|
+
version = "0.9.1"
|
|
119
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
120
|
+
checksum = "b63fbc4a50860e98e7b2aa7804ded1db5cbc3aff9193adaff57a6931bf7c4b4c"
|
|
121
|
+
dependencies = [
|
|
122
|
+
"adler2",
|
|
123
|
+
"simd-adler32",
|
|
124
|
+
]
|
|
125
|
+
|
|
126
|
+
[[package]]
|
|
127
|
+
name = "ng-postcode"
|
|
128
|
+
version = "0.5.2"
|
|
129
|
+
dependencies = [
|
|
130
|
+
"serde",
|
|
131
|
+
"serde_json",
|
|
132
|
+
"ureq",
|
|
133
|
+
]
|
|
134
|
+
|
|
135
|
+
[[package]]
|
|
136
|
+
name = "once_cell"
|
|
137
|
+
version = "1.21.4"
|
|
138
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
139
|
+
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
|
140
|
+
|
|
141
|
+
[[package]]
|
|
142
|
+
name = "percent-encoding"
|
|
143
|
+
version = "2.3.2"
|
|
144
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
145
|
+
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
|
146
|
+
|
|
147
|
+
[[package]]
|
|
148
|
+
name = "proc-macro2"
|
|
149
|
+
version = "1.0.107"
|
|
150
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
151
|
+
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
|
|
152
|
+
dependencies = [
|
|
153
|
+
"unicode-ident",
|
|
154
|
+
]
|
|
155
|
+
|
|
156
|
+
[[package]]
|
|
157
|
+
name = "quote"
|
|
158
|
+
version = "1.0.47"
|
|
159
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
160
|
+
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
|
|
161
|
+
dependencies = [
|
|
162
|
+
"proc-macro2",
|
|
163
|
+
]
|
|
164
|
+
|
|
165
|
+
[[package]]
|
|
166
|
+
name = "ring"
|
|
167
|
+
version = "0.17.14"
|
|
168
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
169
|
+
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
|
|
170
|
+
dependencies = [
|
|
171
|
+
"cc",
|
|
172
|
+
"cfg-if",
|
|
173
|
+
"getrandom",
|
|
174
|
+
"libc",
|
|
175
|
+
"untrusted",
|
|
176
|
+
"windows-sys",
|
|
177
|
+
]
|
|
178
|
+
|
|
179
|
+
[[package]]
|
|
180
|
+
name = "rustls"
|
|
181
|
+
version = "0.23.45"
|
|
182
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
183
|
+
checksum = "0d41d731c7d2f962d1ccc364cec258de3c0e93b38c2fb3ba97ac74513048d634"
|
|
184
|
+
dependencies = [
|
|
185
|
+
"log",
|
|
186
|
+
"once_cell",
|
|
187
|
+
"ring",
|
|
188
|
+
"rustls-pki-types",
|
|
189
|
+
"rustls-webpki",
|
|
190
|
+
"subtle",
|
|
191
|
+
"zeroize",
|
|
192
|
+
]
|
|
193
|
+
|
|
194
|
+
[[package]]
|
|
195
|
+
name = "rustls-pki-types"
|
|
196
|
+
version = "1.15.1"
|
|
197
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
198
|
+
checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96"
|
|
199
|
+
dependencies = [
|
|
200
|
+
"zeroize",
|
|
201
|
+
]
|
|
202
|
+
|
|
203
|
+
[[package]]
|
|
204
|
+
name = "rustls-webpki"
|
|
205
|
+
version = "0.103.15"
|
|
206
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
207
|
+
checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2"
|
|
208
|
+
dependencies = [
|
|
209
|
+
"ring",
|
|
210
|
+
"rustls-pki-types",
|
|
211
|
+
"untrusted",
|
|
212
|
+
]
|
|
213
|
+
|
|
214
|
+
[[package]]
|
|
215
|
+
name = "serde"
|
|
216
|
+
version = "1.0.229"
|
|
217
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
218
|
+
checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
|
|
219
|
+
dependencies = [
|
|
220
|
+
"serde_core",
|
|
221
|
+
]
|
|
222
|
+
|
|
223
|
+
[[package]]
|
|
224
|
+
name = "serde_core"
|
|
225
|
+
version = "1.0.229"
|
|
226
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
227
|
+
checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
|
|
228
|
+
dependencies = [
|
|
229
|
+
"serde_derive",
|
|
230
|
+
]
|
|
231
|
+
|
|
232
|
+
[[package]]
|
|
233
|
+
name = "serde_derive"
|
|
234
|
+
version = "1.0.229"
|
|
235
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
236
|
+
checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
|
|
237
|
+
dependencies = [
|
|
238
|
+
"proc-macro2",
|
|
239
|
+
"quote",
|
|
240
|
+
"syn",
|
|
241
|
+
]
|
|
242
|
+
|
|
243
|
+
[[package]]
|
|
244
|
+
name = "serde_json"
|
|
245
|
+
version = "1.0.151"
|
|
246
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
247
|
+
checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
|
|
248
|
+
dependencies = [
|
|
249
|
+
"itoa",
|
|
250
|
+
"memchr",
|
|
251
|
+
"serde",
|
|
252
|
+
"serde_core",
|
|
253
|
+
"zmij",
|
|
254
|
+
]
|
|
255
|
+
|
|
256
|
+
[[package]]
|
|
257
|
+
name = "shlex"
|
|
258
|
+
version = "2.0.1"
|
|
259
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
260
|
+
checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
|
|
261
|
+
|
|
262
|
+
[[package]]
|
|
263
|
+
name = "simd-adler32"
|
|
264
|
+
version = "0.3.10"
|
|
265
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
266
|
+
checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea"
|
|
267
|
+
|
|
268
|
+
[[package]]
|
|
269
|
+
name = "subtle"
|
|
270
|
+
version = "2.6.1"
|
|
271
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
272
|
+
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
|
273
|
+
|
|
274
|
+
[[package]]
|
|
275
|
+
name = "syn"
|
|
276
|
+
version = "3.0.6"
|
|
277
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
278
|
+
checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee"
|
|
279
|
+
dependencies = [
|
|
280
|
+
"proc-macro2",
|
|
281
|
+
"quote",
|
|
282
|
+
"unicode-ident",
|
|
283
|
+
]
|
|
284
|
+
|
|
285
|
+
[[package]]
|
|
286
|
+
name = "unicode-ident"
|
|
287
|
+
version = "1.0.26"
|
|
288
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
289
|
+
checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954"
|
|
290
|
+
|
|
291
|
+
[[package]]
|
|
292
|
+
name = "untrusted"
|
|
293
|
+
version = "0.9.0"
|
|
294
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
295
|
+
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
|
296
|
+
|
|
297
|
+
[[package]]
|
|
298
|
+
name = "ureq"
|
|
299
|
+
version = "3.4.2"
|
|
300
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
301
|
+
checksum = "9a7ac20be9b7726e0bbdbf974c059676d9acb1cd414961f570a4e8231cacd7fc"
|
|
302
|
+
dependencies = [
|
|
303
|
+
"base64",
|
|
304
|
+
"flate2",
|
|
305
|
+
"log",
|
|
306
|
+
"percent-encoding",
|
|
307
|
+
"rustls",
|
|
308
|
+
"rustls-pki-types",
|
|
309
|
+
"ureq-proto",
|
|
310
|
+
"utf8-zero",
|
|
311
|
+
"webpki-roots",
|
|
312
|
+
]
|
|
313
|
+
|
|
314
|
+
[[package]]
|
|
315
|
+
name = "ureq-proto"
|
|
316
|
+
version = "0.6.4"
|
|
317
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
318
|
+
checksum = "f86fd172ccca569e458f61b6bdd6220965a9ef36e672a6852953b51a0e1583be"
|
|
319
|
+
dependencies = [
|
|
320
|
+
"base64",
|
|
321
|
+
"http",
|
|
322
|
+
"httparse",
|
|
323
|
+
"log",
|
|
324
|
+
]
|
|
325
|
+
|
|
326
|
+
[[package]]
|
|
327
|
+
name = "utf8-zero"
|
|
328
|
+
version = "0.8.1"
|
|
329
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
330
|
+
checksum = "b8c0a043c9540bae7c578c88f91dda8bd82e59ae27c21baca69c8b191aaf5a6e"
|
|
331
|
+
|
|
332
|
+
[[package]]
|
|
333
|
+
name = "wasi"
|
|
334
|
+
version = "0.11.1+wasi-snapshot-preview1"
|
|
335
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
336
|
+
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
|
337
|
+
|
|
338
|
+
[[package]]
|
|
339
|
+
name = "webpki-roots"
|
|
340
|
+
version = "1.0.9"
|
|
341
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
342
|
+
checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a"
|
|
343
|
+
dependencies = [
|
|
344
|
+
"rustls-pki-types",
|
|
345
|
+
]
|
|
346
|
+
|
|
347
|
+
[[package]]
|
|
348
|
+
name = "windows-sys"
|
|
349
|
+
version = "0.52.0"
|
|
350
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
351
|
+
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
|
352
|
+
dependencies = [
|
|
353
|
+
"windows-targets",
|
|
354
|
+
]
|
|
355
|
+
|
|
356
|
+
[[package]]
|
|
357
|
+
name = "windows-targets"
|
|
358
|
+
version = "0.52.6"
|
|
359
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
360
|
+
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
|
361
|
+
dependencies = [
|
|
362
|
+
"windows_aarch64_gnullvm",
|
|
363
|
+
"windows_aarch64_msvc",
|
|
364
|
+
"windows_i686_gnu",
|
|
365
|
+
"windows_i686_gnullvm",
|
|
366
|
+
"windows_i686_msvc",
|
|
367
|
+
"windows_x86_64_gnu",
|
|
368
|
+
"windows_x86_64_gnullvm",
|
|
369
|
+
"windows_x86_64_msvc",
|
|
370
|
+
]
|
|
371
|
+
|
|
372
|
+
[[package]]
|
|
373
|
+
name = "windows_aarch64_gnullvm"
|
|
374
|
+
version = "0.52.6"
|
|
375
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
376
|
+
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
|
377
|
+
|
|
378
|
+
[[package]]
|
|
379
|
+
name = "windows_aarch64_msvc"
|
|
380
|
+
version = "0.52.6"
|
|
381
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
382
|
+
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
|
383
|
+
|
|
384
|
+
[[package]]
|
|
385
|
+
name = "windows_i686_gnu"
|
|
386
|
+
version = "0.52.6"
|
|
387
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
388
|
+
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
|
389
|
+
|
|
390
|
+
[[package]]
|
|
391
|
+
name = "windows_i686_gnullvm"
|
|
392
|
+
version = "0.52.6"
|
|
393
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
394
|
+
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
|
395
|
+
|
|
396
|
+
[[package]]
|
|
397
|
+
name = "windows_i686_msvc"
|
|
398
|
+
version = "0.52.6"
|
|
399
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
400
|
+
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
|
401
|
+
|
|
402
|
+
[[package]]
|
|
403
|
+
name = "windows_x86_64_gnu"
|
|
404
|
+
version = "0.52.6"
|
|
405
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
406
|
+
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
|
407
|
+
|
|
408
|
+
[[package]]
|
|
409
|
+
name = "windows_x86_64_gnullvm"
|
|
410
|
+
version = "0.52.6"
|
|
411
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
412
|
+
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
|
413
|
+
|
|
414
|
+
[[package]]
|
|
415
|
+
name = "windows_x86_64_msvc"
|
|
416
|
+
version = "0.52.6"
|
|
417
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
418
|
+
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
|
419
|
+
|
|
420
|
+
[[package]]
|
|
421
|
+
name = "zeroize"
|
|
422
|
+
version = "1.9.0"
|
|
423
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
424
|
+
checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
|
|
425
|
+
|
|
426
|
+
[[package]]
|
|
427
|
+
name = "zlib-rs"
|
|
428
|
+
version = "0.6.8"
|
|
429
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
430
|
+
checksum = "b268e58e7c693d7c271f93ffc4ba3b380412554231c85bf61ca7af91042a4112"
|
|
431
|
+
|
|
432
|
+
[[package]]
|
|
433
|
+
name = "zmij"
|
|
434
|
+
version = "1.0.23"
|
|
435
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
436
|
+
checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "ng-postcode"
|
|
3
|
+
version = "0.5.2"
|
|
4
|
+
edition = "2021"
|
|
5
|
+
rust-version = "1.85"
|
|
6
|
+
description = "Parse, validate and format Nigeria's NIPOST digital postcode (NDAPS) offline, plus a client for the postcode.gov.ng API."
|
|
7
|
+
license = "MIT"
|
|
8
|
+
repository = "https://github.com/Adeniyikayodee/ng-postcode"
|
|
9
|
+
documentation = "https://docs.rs/ng-postcode"
|
|
10
|
+
keywords = ["nigeria", "postcode", "nipost", "ndaps", "postal-code"]
|
|
11
|
+
categories = ["parser-implementations", "api-bindings", "science::geo", "value-formatting"]
|
|
12
|
+
readme = "CRATE.md"
|
|
13
|
+
# The repository also holds the Python package and the shared spec.
|
|
14
|
+
include = ["/src", "/examples", "/CRATE.md", "/LICENSE"]
|
|
15
|
+
|
|
16
|
+
[features]
|
|
17
|
+
serde = ["dep:serde"]
|
|
18
|
+
api = ["serde", "dep:serde_json"]
|
|
19
|
+
client = ["api", "dep:ureq"]
|
|
20
|
+
|
|
21
|
+
[dependencies]
|
|
22
|
+
serde = { version = "1", optional = true }
|
|
23
|
+
serde_json = { version = "1", optional = true }
|
|
24
|
+
ureq = { version = "3", optional = true }
|
|
25
|
+
|
|
26
|
+
[dev-dependencies]
|
|
27
|
+
serde_json = "1"
|
|
28
|
+
|
|
29
|
+
[[example]]
|
|
30
|
+
name = "lookup"
|
|
31
|
+
required-features = ["client"]
|
|
32
|
+
|
|
33
|
+
[package.metadata.docs.rs]
|
|
34
|
+
all-features = true
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kayode Adeniyi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ng-postcode-polars
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Classifier: Programming Language :: Rust
|
|
5
|
+
Classifier: Programming Language :: Python :: 3
|
|
6
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
7
|
+
Classifier: Typing :: Typed
|
|
8
|
+
Requires-Dist: polars>=1.30
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Summary: Polars expressions for Nigeria's NIPOST digital postcode (NDAPS): parse, format and group by place.
|
|
11
|
+
Keywords: nigeria,postcode,nipost,ndaps,polars,dataframe
|
|
12
|
+
Author: Kayode Adeniyi
|
|
13
|
+
License-Expression: MIT
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
16
|
+
Project-URL: Issues, https://github.com/Adeniyikayodee/ng-postcode/issues
|
|
17
|
+
Project-URL: Repository, https://github.com/Adeniyikayodee/ng-postcode
|
|
18
|
+
|
|
19
|
+
# ng-postcode-polars
|
|
20
|
+
|
|
21
|
+
Polars expressions for Nigeria's NIPOST digital postcode (NDAPS), the 11-character building code such as `EK-01-A03-FK-01`. They parse, format, and cut codes down to a state, LGA, district, or area, so that a DataFrame can be grouped by place with no map.
|
|
22
|
+
|
|
23
|
+
The work is done in Rust by the same core as the [`ng-postcode`](https://github.com/Adeniyikayodee/ng-postcode) libraries, in one pass over the column. On a million rows that is about 40 times faster than calling a Python function for each row.
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
pip install ng-postcode-polars
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
Importing the package adds an `ng` namespace to every expression.
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
import polars as pl
|
|
35
|
+
import ng_postcode_polars # noqa: F401
|
|
36
|
+
|
|
37
|
+
frame = pl.DataFrame({"postcode": ["ek 01 a03 fk 01", "EK-01-A03-ZZ-14", "la11w06tc10", "100001"]})
|
|
38
|
+
|
|
39
|
+
print(
|
|
40
|
+
frame.with_columns(
|
|
41
|
+
code=pl.col("postcode").ng.parse(),
|
|
42
|
+
ok=pl.col("postcode").ng.is_valid(),
|
|
43
|
+
)
|
|
44
|
+
)
|
|
45
|
+
# postcode code ok
|
|
46
|
+
# ek 01 a03 fk 01 EK01A03FK01 true
|
|
47
|
+
# EK-01-A03-ZZ-14 EK01A03ZZ14 true
|
|
48
|
+
# la11w06tc10 LA11W06TC10 true
|
|
49
|
+
# 100001 null false
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
A value that is not a well-formed code becomes null, so it can be counted and followed up.
|
|
53
|
+
|
|
54
|
+
## Group by place
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
by_district = frame.group_by(
|
|
58
|
+
pl.col("postcode").ng.truncate("district").ng.format().alias("district")
|
|
59
|
+
).len()
|
|
60
|
+
# EK-01-A03 2
|
|
61
|
+
# LA-11-W06 1
|
|
62
|
+
# null 1
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Expressions
|
|
66
|
+
|
|
67
|
+
| Expression | Returns |
|
|
68
|
+
| --- | --- |
|
|
69
|
+
| `.ng.parse()` | The compact code, `EK01A03FK01`, or null |
|
|
70
|
+
| `.ng.is_valid()` | Whether the value is a well-formed code |
|
|
71
|
+
| `.ng.format()` | The hyphenated form of a code or a prefix |
|
|
72
|
+
| `.ng.truncate(segment)` | The compact prefix through `state`, `lga`, `district`, `area`, or `unit` |
|
|
73
|
+
| `.ng.parse_prefix()` | The compact prefix, such as `EK01A03`, or null |
|
|
74
|
+
|
|
75
|
+
A type checker cannot see a namespace that is registered at import time. For checked code, call the class directly: `Postcodes(pl.col("postcode")).parse()`.
|
|
76
|
+
|
|
77
|
+
The expressions follow the shared cases in [`spec/vectors.json`](https://github.com/Adeniyikayodee/ng-postcode/blob/main/spec/vectors.json), as every `ng-postcode` library does. A well-formed code is not necessarily assigned to a building, and only the NIPOST API can confirm that.
|
|
78
|
+
|
|
79
|
+
## License
|
|
80
|
+
|
|
81
|
+
MIT
|
|
82
|
+
|