Skip to content

Instantly share code, notes, and snippets.

@AnthonyMikh
Created November 27, 2020 19:35
Show Gist options
  • Save AnthonyMikh/107fbfddaec3fd313a84a21cd591ff0f to your computer and use it in GitHub Desktop.
Save AnthonyMikh/107fbfddaec3fd313a84a21cd591ff0f to your computer and use it in GitHub Desktop.
Реализация макросов для разбора строк по префиксам с детекцией повторяющихся паттернов
macro_rules! prefixes {
(match $value:ident {
$($prefix:literal .. $(if $condition:expr)? => $arm:expr,)*
_ => $catch_all:expr $(,)?
}) => {{
#[allow(dead_code)]
fn non_repeating() {
#[warn(unreachable_patterns)]
match "" {
$($prefix => (),)*
_ => (),
}
}
match $value {
$(x if x.starts_with($prefix) $(&& $condition)? => $arm,)*
_ => $catch_all,
}
}}
}
macro_rules! cut_prefixes {
(match $value:ident {
$($prefix:literal..=$rest:ident => $arm:expr,)*
_ => $catch_all:expr $(,)?
}) => {{
#[allow(dead_code)]
fn non_repeating() {
#[warn(unreachable_patterns)]
match "" {
$($prefix => (),)*
_ => (),
}
}
$(if let Some($rest) = $value.strip_prefix($prefix) {
$arm
} else)* {
$catch_all
}
}}
}
fn use_cut_prefixes(s: &str) -> String {
cut_prefixes!(match s {
"foo"..=rest => rest.to_string(),
"bar"..=tail /* if s.len() % 2 == 0 */ => [tail, tail].concat(),
_ => String::new(),
})
}
fn use_prefixes(s: &str) -> String {
prefixes!(match s {
"foo".. => s.to_string(),
"bar".. => [s, s].concat(),
"over".. if s.ends_with("all") => [s, "3"].concat(),
_ => String::new(),
})
}
fn main() {
let inputs = [
"foobar",
"barfoo",
"overall",
];
for input in &inputs[..] {
println!("{:?}", use_prefixes(input));
}
}
// версия cut_prefixes с поддержкой if clause
/*
macro_rules! cut_prefixes {
(match $value:ident {
$($prefix:literal..=$rest:ident $(if $cond:expr)? => $arm:expr,)*
_ => $catch_all:expr $(,)?
}) => {{
#[allow(dead_code)]
fn non_repeating() {
#[warn(unreachable_patterns)]
match "" {
$($prefix => (),)*
_ => (),
}
}
match $value {
$(x if x.starts_with($prefix) $(&& $cond)? => {
let (_, $rest) = x.split_at($prefix.len());
$arm
},)*
_ => $catch_all,
}
}}
}
*/
@AnthonyMikh
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment