extern crate csv; use std::fs::File; use std::io::Write; fn main() { generate_passenger_kind().expect("can't generate PassengerKind"); } fn generate_passenger_kind() -> Result<(), std::io::Error> { let mut rdr = csv::Reader::from_file("PTYP.TXT").expect("PTYP.txt not found"); let mut records = Vec::new(); for record in rdr.decode() { let (code, description): (String, String) = record.unwrap(); records.push((code, description)); } let mut file = File::create("src/passenger_kind.rs")?; write!(file, "// generated from PTYP.txt retrieved from")?; write!(file, "// https://developer.travelport.com/euf/assets/developer-network/downloads/ReferenceData.zip")?; // generate enum write!(file, "/// ATPCO passenger types\n")?; write!(file, "#[allow(non_camel_case_types)]\n")?; write!(file, "#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)]\npub enum PassengerKind {{\n")?; for record in &records { write!(file, "\t{},\n", record.0)?; } write!(file, "}}\n\n")?; // generate display for enum write!(file, "impl ::std::fmt::Display for PassengerKind {{\n")?; write!(file, "fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {{\n")?; write!(file, "\tmatch *self {{")?; for record in &records { write!(file, "\t\tPassengerKind::{} => write!(f, \"{}\"),\n", record.0, record.0)?; } write!(file, "\t\t}}\n")?; write!(file, "\t}}\n")?; write!(file, "}}\n")?; // error for from_str write!(file, "#[derive(Debug,Copy,Clone)]\npub struct PassengerKindParseError;\n")?; write!(file, "impl ::std::fmt::Display for PassengerKindParseError {{\n")?; write!(file, "fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {{\n")?; write!(file, "write!(f, \"invalid passenger kind\")\n")?; write!(file, "}}\n}}\n")?; write!(file, "impl ::std::error::Error for PassengerKindParseError {{\n")?; write!(file, "fn description(&self) -> &str {{\n")?; write!(file, "\"passenger kind parse error\"")?; write!(file, "}}\n}}\n")?; // FromStr for enum write!(file, "impl ::std::str::FromStr for PassengerKind {{\n")?; write!(file, "\ttype Err = PassengerKindParseError;\n")?; write!(file, "\tfn from_str(value: &str) -> Result {{\n")?; write!(file, "\t\tmatch value {{\n")?; for record in &records { write!(file, "\t\t\"{}\" => Ok(PassengerKind::{}),\n", record.0, record.0)?; } write!(file, "\t\t_ => return Err(PassengerKindParseError),\n")?; write!(file, "\t}}\n")?; write!(file, "}}\n")?; write!(file, "}}\n")?; // serialize for enum write!(file, "#[cfg(feature = \"serde\")] impl ::serde::Serialize for PassengerKind {{ fn serialize(&self, serializer: S) -> Result where S: ::serde::Serializer {{ serializer.serialize_str(self.name()) }} }} ")?; // deserialize for enum write!(file, "#[cfg(feature = \"serde\")] impl<'de> ::serde::Deserialize<'de> for PassengerKind {{ fn deserialize(deserializer: D) -> Result where D: ::serde::Deserializer<'de> {{\n use ::serde::de::Visitor; use ::serde::de::Unexpected;\n use std::fmt; use std::str::FromStr; struct PassengerKindVisitor; impl <'de> Visitor<'de> for PassengerKindVisitor {{\n type Value = PassengerKind; fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {{ f.write_str(\"valid passenger kind\") }} fn visit_str(self, value: &str) -> Result where E: ::serde::de::Error {{ match PassengerKind::from_str(value) {{ Ok(pk) => Ok(pk), Err(_) => Err(E::invalid_value(Unexpected::Str(value), &\"passenger kind\")), }} }} }} deserializer.deserialize_str(PassengerKindVisitor) ")?; write!(file, "}}\n")?; write!(file, "}}\n")?; // enum implementation write!(file, "impl PassengerKind {{\n")?; write!(file, "pub fn description(&self) -> &'static str {{\n")?; write!(file, "\t match *self {{\n")?; for record in &records { write!(file, "\t\t PassengerKind::{} => \"{}\",\n", record.0, record.1)?; } write!(file, "}}\n")?; write!(file, "}}\n")?; write!(file, "pub fn name(&self) -> &'static str {{\n")?; write!(file, "\t match *self {{\n")?; for record in &records { write!(file, "\t\t PassengerKind::{} => \"{}\",\n", record.0, record.0)?; } write!(file, "}}\n")?; write!(file, "}}\n")?; write!(file, "}}\n")?; Ok(()) }