use std::{env, error::Error, fs, path::Path}; struct Region { variant: String, id: String, } fn main() -> Result<(), Box> { println!("cargo:rerun-if-changed=regions.txt"); let regions = include_str!("regions.txt") .lines() .map(|id| Region { variant: id .split('-') .map(|word| { let mut chars = word.chars(); if let Some(a) = chars.next() { a.to_uppercase() .chain(chars.as_str().to_lowercase().chars()) .collect() } else { String::new() } }) .collect::>() .join(""), id: id.into(), }) .collect::>(); let dest_path = Path::new(&env::var("OUT_DIR")?).join("region.rs"); // the enum let mut buf = "/// A list of AWS Regions supported by DynamoDB\n#[non_exhaustive]\npub enum Region {\n" .to_string(); for region in ®ions { buf.push_str(" "); buf.push_str(®ion.variant); buf.push_str(",\n"); } buf.push_str("}\n"); // the impl buf.push_str("\nimpl Region {\n"); buf.push_str(" /// Short region identifier\n"); buf.push_str(" pub fn id(&self) -> &str {\n"); buf.push_str(" match self {\n"); for region in ®ions { buf.push_str(" Region::"); buf.push_str(®ion.variant); buf.push_str(" => \""); buf.push_str(®ion.id); buf.push_str("\",\n"); } buf.push_str(" }\n }\n"); buf.push_str(" /// region specific dynamodb endpoint\n"); buf.push_str(" pub fn endpoint(&self) -> &str {\n"); buf.push_str(" match self {\n"); for region in ®ions { buf.push_str(" Region::"); buf.push_str(®ion.variant); buf.push_str(" => \"https://dynamodb."); buf.push_str(®ion.id); buf.push_str(".amazonaws.com\",\n"); } buf.push_str(" }\n }\n"); buf.push_str("}\n"); // from str buf.push_str("\nimpl std::str::FromStr for Region {\n"); buf.push_str(" type Err = String;\n"); buf.push_str(" fn from_str(s: &str) -> Result {\n"); buf.push_str(" match s {\n"); for region in ®ions { buf.push_str(" \""); buf.push_str(®ion.id); buf.push_str("\" => Ok(Region::"); buf.push_str(®ion.variant); buf.push_str("),\n"); } buf.push_str(" _ => Err(\"invalid region\".into()),\n"); buf.push_str(" }\n }\n"); buf.push_str("}\n"); fs::write(&dest_path, buf)?; Ok(()) }