#[macro_export] macro_rules! gen_parse { ($command:ident, $args:ident) => { macro_rules! parse { (And_Or => $$val:tt) => { { let mut args = $args.into_iter(); let separator: Separator = args .next() .ok_or(CommandParseError::MissingArgument)? .parse()?; let sep_str = separator.to_string(); let args = args.collect::>(); let commands = args .split(|itm| itm.eq(&sep_str)) .map(|itm| match itm.len() { 0 => Err(CommandParseError::MissingArgument), 1 => HlwmCommand::from_str(itm.first().unwrap()), _ => { let mut args = itm.into_iter(); HlwmCommand::from_raw_parts( &args.next().unwrap(), args.map(|i| i.to_owned()).collect(), ) } }) .collect::, _>>()?; Ok(Self::$$val{ separator, commands, })} }; ($$arg_type:tt => $$val:tt) => { { #[allow(unused_mut)] let mut args_iter = $args.into_iter(); Ok(Self::$$val(parse!(Argument args_iter: $$arg_type))) } }; ($$($$arg:tt: $$arg_type:tt),+ => $val:tt) => { { #[allow(unused_mut)] let mut args_iter = $args.into_iter(); Ok(Self::$val{ $$( $$arg: parse!(Argument args_iter: $$arg_type) ),+ }) } }; (Argument $$args:ident: [Flag($pat:literal)]) => { { let mut args = $$args.clone().into_iter(); let mut flag = false; if args.any(|i| i == $pat) { $$args = $$args.filter(|a| a != $pat).collect::>().into_iter(); flag = true; } flag } }; (Argument $$args:ident: String) => { $$args .next() .ok_or(CommandParseError::BadArgument { command: $command.to_string(), })? }; (Argument $$args:ident: FromStrAll) => { $$args .collect::>() .join("\t") .parse() .map_err(|_| CommandParseError::BadArgument { command: $command.to_string(), })? }; (Argument $$args:ident: FromStr) => { parse!(Argument $$args: String) .parse() .map_err(|_| CommandParseError::BadArgument { command: $command.to_string(), })? }; (Argument $$args:ident: [Option]) => { { let args: Vec<_> = $$args.collect(); if args.len() == 0 { None } else { let mut args = args.into_iter(); Some(parse!(Argument args: String) .parse() .map_err(|_| CommandParseError::BadArgument { command: $command.to_string(), })?) } } }; (Argument $$args:ident: [Vec]) => { $$args.collect::>() }; (Argument $$args:ident: Bool) => { match parse!(Argument $$args: String).as_str() { "on" | "true" => true, "off" | "false" => false, _ => return Err(CommandParseError::BadArgument { command: $command.to_string(), }), } }; (Argument $$args:ident: [Option]) => { { let args = $$args.collect::>(); if args.len() == 0 { None } else { Some(args.join("\t")) } } }; (Argument $$args:ident: [Option>]) => { { let args = $$args.collect::>(); if args.len() == 0 { None } else { Some(args) } } }; (Argument $$args:ident: [Option]) => { { let args = $$args.map(|item| item.parse().map_err(|_| CommandParseError::BadArgument { command: $command.to_string(), })).collect::, _>>()?; if args.len() == 0 { None } else { Some(args) } } }; (Argument $$args:ident: [Vec]) => { { $$args.map(|item| item.parse().map_err(|_| CommandParseError::BadArgument { command: $command.to_string(), })).collect::, _>>()? } }; } }; }