1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
use std::{ io::{self, Read}, process, }; use molecule_codegen::{Compiler, IntermediateFormat, Language}; pub(crate) enum AppAction { DisplayFormat, ProcessIntermediate(Vec<u8>), } pub struct AppConfig { action: AppAction, lang: Language, format: IntermediateFormat, } type RawAppConfig<'a> = (Language, IntermediateFormat, &'a clap::ArgMatches<'a>); pub fn build_commandline(lang: Language, format: IntermediateFormat) -> AppConfig { let yaml = clap::load_yaml!("cli/compiler-plugin.yaml"); let matches = clap::App::from_yaml(yaml) .name(format!("Moleculec {} Plugin", lang)) .about("Compiler plugin for molecule to generate code.") .version(clap::crate_version!()) .get_matches(); AppConfig::from(&(lang, format, &matches)) } impl<'a> From<&'a RawAppConfig<'a>> for AppConfig { fn from(input: &'a RawAppConfig<'a>) -> Self { let (lang, format, matches) = input; let action = if matches.is_present("format") { AppAction::DisplayFormat } else { let mut input = Vec::new(); if io::stdin().read_to_end(&mut input).is_err() { eprintln!("Error: failed to read data from stdin)"); process::exit(1); }; AppAction::ProcessIntermediate(input) }; Self { action, lang: *lang, format: *format, } } } impl AppConfig { pub fn execute(self) { match self.action { AppAction::DisplayFormat => { println!("{}", self.format); } AppAction::ProcessIntermediate(ref input) => { Compiler::new() .generate_code(self.lang) .input_intermediate(self.format, input.to_owned()) .run() .unwrap(); } } } }