dfa.rs (1306B)
1 use automaton::{dfa::DFA, Automaton, Encodable}; 2 use std::{env, error::Error, fmt::Display, fs}; 3 4 #[derive(Debug)] 5 struct CommandLineError { 6 reason: String, 7 } 8 9 impl Display for CommandLineError { 10 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 11 write!(f, "{}", self.reason) 12 } 13 } 14 15 impl CommandLineError { 16 fn cause(reason: &str) -> Self { 17 CommandLineError { 18 reason: reason.to_owned(), 19 } 20 } 21 } 22 23 impl Error for CommandLineError {} 24 25 fn usage(prog_name: &str) -> String { 26 format!("Usage: {prog_name} <DFA filename> <input string>") 27 } 28 29 fn main() -> Result<(), Box<dyn Error>> { 30 let args: Vec<String> = env::args().collect(); 31 32 if args.len() < 2 { 33 return Err(Box::new(CommandLineError::cause(&usage( 34 args.get(0).map_or("automaton", |s| s), 35 )))); 36 } 37 38 let dfa_json = fs::read_to_string(args.get(1).ok_or(CommandLineError::cause( 39 "Could not get filename from commandline args", 40 ))?)?; 41 let input_string: String = args.get(2).map_or("".to_owned(), String::to_owned); 42 43 let dfa: DFA = DFA::parse(dfa_json.as_str())?; 44 println!("DFA:\n{dfa}"); 45 println!("Running on the following input:\n{input_string}"); 46 println!("Accepts: {}", dfa.accepts(&input_string)); 47 48 Ok(()) 49 }