use std::env; use std::str::{self, FromStr}; pub trait Parsable { fn parse(s: &str) -> Self; } impl Parsable for Vec { fn parse(s: &str) -> Vec { let mut depth = 0; let mut sep = Vec::new(); let s = s .trim() .strip_prefix("[") .expect("Missing [") .strip_suffix("]") .expect("Missing ]"); let mut last = 0; for (i, c) in s.chars().enumerate() { if c == '[' { depth += 1; } else if c == ']' { if depth == 0 { panic!("Invalid array format"); } depth -= 1; } else if c == ',' && depth == 0 { sep.push((last, i)); last = i + 1; } } if last != s.len() { sep.push((last, s.len())); } let mut out = Vec::new(); for (start, end) in sep { out.push(parse(s[start..end].trim())); } out } } impl Parsable for i32 { fn parse(s: &str) -> i32 { i32::from_str(s).unwrap_or_else(|_| panic!("Failed to parse integer ({s})")) } } impl Parsable for char { fn parse(s: &str) -> char { s.chars() .next() .unwrap_or_else(|| panic!("Parsing empty string")) } } pub fn parse(s: &str) -> T { ::parse(s) } pub fn vc(s: &str) -> Vec { parse(s) } pub fn vvc(s: &str) -> Vec> { parse(s) } pub fn vi(s: &str) -> Vec { parse(s) } pub fn vvi(s: &str) -> Vec> { parse(s) } pub fn arg(n: usize) -> String { env::args() .nth(n) .unwrap_or_else(|| panic!("Failed to get argument ({n})")) } pub fn arg_into(n: usize) -> T { ::parse(arg(n).as_str()) }