diff --git a/Cargo.toml b/Cargo.toml index e575f3f..ba492e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,3 +9,4 @@ edition = "2021" csv = "1.1.6" serde = { version = "1.0.145", features = ["derive"] } serde_repr = "0.1.9" +extindex = "0.5.0" diff --git a/src/main.rs b/src/main.rs index a0e20af..dd53cf7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,8 @@ -use csv::Reader; use csv::ReaderBuilder; +use extindex::{Builder, Entry, SerdeWrapper, Reader as ExtReader}; use std::error::Error; use std::io; +use std::path::Path; use std::process; use serde::{Deserialize, Serialize}; use serde; @@ -21,7 +22,7 @@ enum UserType { Large, } -#[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)] +#[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug, Clone)] #[repr(u8)] enum PositionalQuality { MatchedAddressPostcodeMean = 1, @@ -43,9 +44,9 @@ enum PositionalQuality { // 9 No grid reference available. } -#[derive(Debug, Deserialize)] +#[derive(Debug, Deserialize, Serialize)] struct Postcode { - postcode: String, + pub postcode: String, status: Status, usertype: UserType, #[serde(deserialize_with = "csv::invalid_option")] @@ -66,6 +67,31 @@ struct Postcode { incode: String, } +#[derive(Serialize, Deserialize, Debug)] +struct SmolPostcode { + postcode: String, + status: Status, + usertype: UserType, + positional_quality_indicator: PositionalQuality, + country: String, + latitude: Option, + longitude: Option, +} + +impl SmolPostcode { + fn from_postcode(full: Postcode) -> Self { + SmolPostcode { + postcode: full.postcode.to_owned(), + status: full.status, + usertype: full.usertype, + positional_quality_indicator: full.positional_quality_indicator.to_owned(), + country: full.country.to_owned(), + latitude: full.latitude.to_owned(), + longitude: full.longitude.to_owned(), + } + } +} + fn read() -> Result<(), Box> { let mut rdr = ReaderBuilder::new() .has_headers(false) @@ -80,9 +106,50 @@ fn read() -> Result<(), Box> { Ok(()) } +/* + * Thought this would be easy.. + * + let postcodes = csv_iter(io::stdin()); + for p in postcodes.take(10) { + println!("Postcode: {}", p); + } +fn csv_iter(file: impl io::Read + 'static) -> impl Iterator { + let mut reader = ReaderBuilder::new() + .has_headers(false) + .from_reader(file); + let iter = reader.deserialize(); + iter + .filter_map(|r: Result| r.ok()) + .map(|postcode| postcode.postcode.to_owned()) + .collect() +} + */ + fn main() { + build(); if let Err(err) = read() { println!("error running example: {}", err); process::exit(1); } } + + +fn build() { + let index_file_path = Path::new("./postcodes.db"); + + let builder: Builder> = Builder::new(index_file_path); + + let mut csv_reader = ReaderBuilder::new() + .has_headers(false) + .from_reader(io::stdin()); + let entries = csv_reader.deserialize() + .filter_map(|r: Result| r.ok()) + .map(|full: Postcode| SmolPostcode::from_postcode(full)) + .map(|smol| Entry::new(smol.postcode.to_owned(), SerdeWrapper(smol))); + + builder.build(entries.into_iter()).unwrap(); + + let reader = ExtReader::>::open(index_file_path).unwrap(); + let here = reader.find(&"LS27 8BW".to_string()).unwrap().expect("Not found"); + println!("Here: {:?}", here.value().0); +}