commit efdce13757bf5e0cc86c6deab30176800d12c6bf Author: Alex Wright Date: Sun Sep 18 15:41:07 2022 +0100 Basic reader for the ONS postcode CSV diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..e575f3f --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "postcodes" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +csv = "1.1.6" +serde = { version = "1.0.145", features = ["derive"] } +serde_repr = "0.1.9" diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..a0e20af --- /dev/null +++ b/src/main.rs @@ -0,0 +1,88 @@ +use csv::Reader; +use csv::ReaderBuilder; +use std::error::Error; +use std::io; +use std::process; +use serde::{Deserialize, Serialize}; +use serde; +use serde_repr::*; + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "lowercase")] +enum Status { + Live, + Terminated, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "lowercase")] +enum UserType { + Small, + Large, +} + +#[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)] +#[repr(u8)] +enum PositionalQuality { + MatchedAddressPostcodeMean = 1, + LandlineMapsInspection = 2, + ApproximateWithin50Meters = 3, + PostcodeUnitMean = 4, + ImputedByONS = 5, + PostcodeSectorMean = 6, + TerminatedPriorToGridlink = 8, + NoGridReferenceAvailable = 9, +// 1 Within the building of the matched address closest to the postcode mean. +// 2 As for status value 1, except by visual inspection of Landline maps (Scotland only). +// 3 Approximate to within 50 metres. +// 4 Postcode unit mean (mean of matched addresses with the same postcode, but not snapped to a building). +// 5 Imputed by ONS, by reference to surrounding postcode grid references. +// 6 Postcode sector mean, (mainly PO Boxes). +// 7 Not used. +// 8 Postcode terminated prior to Gridlink® initiative, last known ONS postcode grid reference. +// 9 No grid reference available. +} + +#[derive(Debug, Deserialize)] +struct Postcode { + postcode: String, + status: Status, + usertype: UserType, + #[serde(deserialize_with = "csv::invalid_option")] + easting: Option, + #[serde(deserialize_with = "csv::invalid_option")] + northing: Option, + positional_quality_indicator: PositionalQuality, + country: String, + latitude: Option, + longitude: Option, + postcode_no_space: String, + postcode_fixed_width_seven: String, + postcode_fixed_width_eight: String, + postcode_area: String, + postcode_district: String, + postcode_sector: String, + outcode: String, + incode: String, +} + +fn read() -> Result<(), Box> { + let mut rdr = ReaderBuilder::new() + .has_headers(false) + .from_reader(io::stdin()); + let mut i: u32 = 0; + for result in rdr.deserialize() { + let record: Postcode = result?; + // println!("{}:: {:?}", i, record); + i += 1; + } + println!("Read {:?} postcodes", i); + Ok(()) +} + +fn main() { + if let Err(err) = read() { + println!("error running example: {}", err); + process::exit(1); + } +}