hlctl/src/hlwm/macros.rs

154 lines
4.2 KiB
Rust

#[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::<Vec<_>>();
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::<Result<Vec<_>, _>>()?;
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::<Vec<_>>().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::<Vec<_>>()
.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<FromStr>]) => {
{
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<String>]) => {
$$args.collect::<Vec<String>>()
};
(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<String>]) => {
{
let args = $$args.collect::<Vec<String>>();
if args.len() == 0 {
None
} else {
Some(args.join("\t"))
}
}
};
(Argument $$args:ident: [Option<Vec<String>>]) => {
{
let args = $$args.collect::<Vec<String>>();
if args.len() == 0 {
None
} else {
Some(args)
}
}
};
(Argument $$args:ident: [Option<FromStr>]) => {
{
let args = $$args.map(|item| item.parse().map_err(|_| CommandParseError::BadArgument {
command: $command.to_string(),
})).collect::<Result<Vec<_>, _>>()?;
if args.len() == 0 {
None
} else {
Some(args)
}
}
};
(Argument $$args:ident: [Vec<FromStr>]) => {
{
$$args.map(|item| item.parse().map_err(|_| CommandParseError::BadArgument {
command: $command.to_string(),
})).collect::<Result<Vec<_>, _>>()?
}
};
}
};
}