118 lines
3.1 KiB
Rust
118 lines
3.1 KiB
Rust
use crate::hlwm::parser::ParseError;
|
|
|
|
use super::{
|
|
command::HlwmCommand,
|
|
parser::{ArgParser, FromCommandArgs, FromStringsHint},
|
|
Separator,
|
|
};
|
|
|
|
pub struct AndOrCommands(Vec<HlwmCommand>);
|
|
|
|
impl AndOrCommands {
|
|
pub fn commands(self) -> Vec<HlwmCommand> {
|
|
self.0
|
|
}
|
|
}
|
|
|
|
impl FromStringsHint<Separator> for AndOrCommands {
|
|
fn from_strings_hint<I: Iterator<Item = String>>(
|
|
s: I,
|
|
hint: Separator,
|
|
) -> Result<Self, ParseError> {
|
|
Ok(Self(
|
|
split_by_separator(s, hint)
|
|
.into_iter()
|
|
.map(|cmd_args| -> Result<HlwmCommand, ParseError> {
|
|
let mut parser = ArgParser::from_strings(cmd_args.into_iter());
|
|
HlwmCommand::from_command_args(
|
|
&parser.must_string("hlwmcommand(command)")?,
|
|
parser.collect::<Vec<String>>().into_iter(),
|
|
)
|
|
})
|
|
.collect::<Result<Vec<HlwmCommand>, ParseError>>()?,
|
|
))
|
|
}
|
|
}
|
|
|
|
fn split_by_separator<I: Iterator<Item = String>>(s: I, separator: Separator) -> Vec<Vec<String>> {
|
|
let separator = separator.to_string();
|
|
let mut commands = Vec::new();
|
|
let mut working = Vec::new();
|
|
for itm in s {
|
|
if itm.len() == 1 && itm == separator {
|
|
if !working.is_empty() {
|
|
commands.push(working);
|
|
working = Vec::new();
|
|
}
|
|
continue;
|
|
}
|
|
working.push(itm);
|
|
}
|
|
if !working.is_empty() {
|
|
commands.push(working);
|
|
}
|
|
commands
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
use crate::hlwm::Separator;
|
|
|
|
use super::split_by_separator;
|
|
use pretty_assertions::assert_eq;
|
|
|
|
#[test]
|
|
fn test_split_by_separator() {
|
|
let cases = [(
|
|
[
|
|
"or",
|
|
",",
|
|
"and",
|
|
".",
|
|
"compare",
|
|
"tags.focus.curframe_wcount",
|
|
"=",
|
|
"2",
|
|
".",
|
|
"cycle_layout",
|
|
"+1",
|
|
"vertical",
|
|
"horizontal",
|
|
"max",
|
|
"vertical",
|
|
"grid",
|
|
",",
|
|
"cycle_layout",
|
|
"+1",
|
|
]
|
|
.into_iter(),
|
|
Separator::Comma,
|
|
vec![
|
|
vec!["or"],
|
|
vec![
|
|
"and",
|
|
".",
|
|
"compare",
|
|
"tags.focus.curframe_wcount",
|
|
"=",
|
|
"2",
|
|
".",
|
|
"cycle_layout",
|
|
"+1",
|
|
"vertical",
|
|
"horizontal",
|
|
"max",
|
|
"vertical",
|
|
"grid",
|
|
],
|
|
vec!["cycle_layout", "+1"],
|
|
],
|
|
)];
|
|
for (input, separator, expected) in cases {
|
|
let input = input.map(|i| i.to_string());
|
|
let actual = split_by_separator(input, separator);
|
|
assert_eq!(expected, actual);
|
|
}
|
|
}
|
|
}
|