use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
use std::fs::File;
use std::io::{self, Write};
use std::path::PathBuf;
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
#[derive(Debug, Copy, Clone, Deserialize, Serialize)]
struct Coordinate {
latitude: f64,
longitude: f64,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
struct Geography {
coordinates: Coordinate,
#[serde(rename = "isLandlocked")]
land_locked: bool,
#[serde(rename = "capitalCity")]
capital: Vec<String>,
#[serde(rename = "landArea")]
area: f64,
region: String,
subregion: String,
#[serde(rename = "borderCountries")]
border_countries: Vec<String>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
struct Currency {
name: String,
short_name: Option<String>,
#[serde(rename = "iso4217")]
iso_4217: String,
iso_numeric: Option<String>,
symbol: String,
subunit: Option<String>,
prefix: Option<String>,
suffix: Option<String>,
decimal_mark: Option<String>,
decimal_places: u8,
thousands_separator: Option<String>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
struct OfficialLanguageName {
common: String,
native: Option<String>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
struct OfficialLanguage {
name: OfficialLanguageName,
#[serde(rename = "iso639_3")]
iso_639_3: String,
#[serde(rename = "bcp47")]
bcp_47: String,
#[serde(rename = "iso15924")]
iso_15924: String,
iana: Vec<String>,
#[serde(rename = "isExtinct")]
extinct: bool,
#[serde(rename = "isSpurious")]
spurious: bool,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
struct Language {
official: Vec<OfficialLanguage>,
spoken: Option<Vec<String>>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
struct Timezone {
name: String,
#[serde(rename = "type")]
ty: String,
#[serde(rename = "linkedTo")]
linked_to: Option<String>,
#[serde(rename = "utcOffset")]
utc_offset: String,
#[serde(rename = "dstOffset")]
dst_offset: String,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
struct Locale {
ietf: Vec<String>,
measurement_system: String,
driving_side: String,
hour_clock: String,
timezones: Vec<Timezone>,
date_formats: HashMap<String, String>,
week_starts_on: String,
#[serde(rename = "distanceMeasurement")]
distance_uint: String,
#[serde(rename = "temperatureMeasurement")]
temperature_uint: String,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
struct CountryName {
common: String,
official: String,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
struct CountryMeta {
common: String,
official: String,
native: Option<HashMap<String, CountryName>>,
alternates: Option<Vec<String>>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(untagged)]
enum SubdivisionOfficialName {
Number(usize),
String(String)
}
#[derive(Debug, Clone, Deserialize, Serialize)]
struct SubdivisionName {
official: SubdivisionOfficialName,
common: Option<String>,
native: Option<String>,
}
#[derive(Clone, Serialize, Deserialize)]
struct IDD {
prefix: Option<String>,
suffixes: Option<Vec<String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
struct Subdivision {
#[serde(rename = "isoCode")]
iso_code: String,
#[serde(rename = "type")]
ty: Option<String>,
name: HashMap<String, SubdivisionName>,
}
#[derive(Clone, Serialize, Deserialize)]
struct CountryData {
name: CountryMeta,
flag: String,
cca2: String,
cca3: String,
ccn3: String,
ioc: Option<String>,
tld: Vec<String>,
locale: Locale,
geography: Geography,
languages: Language,
currencies: Vec<Currency>,
idd: IDD,
subdivisions: Vec<Subdivision>,
}
fn main() -> Result<()> {
let out_path = PathBuf::from("src/generated.rs");
let src_path = PathBuf::from("data.json");
let mut out = io::BufWriter::new(File::create(&out_path)?);
let src = File::open(&src_path)?;
let countries: Vec<CountryData> = serde_json::from_reader(src)?;
Ok(())
}