parse!() { /* proc-macro */ }Expand description
The parse macro allows you to parse a string into any type that implements Parse.
(Which can be derived with the Parse macro)
let input = "5 + -2 = 3";
let total: i32;
let (lhs, rhs): (i32, i32) = parse!(input, "{} + {} = {total}");
assert_eq!(lhs + rhs, total);
// You can also specify the variable's position in the tuple.
let (rhs, lhs): (u32, u32) = parse!("10 / 2", "{1} / {0}");
assert_eq!(lhs / rhs, 5);§Repetition
You can parse multiple parts of a string using one of the following methods:
§Array
You can parse a string into an array of parsed elements using the following syntax {<var>:<sep>:<count>}.
let input = "My farm contains exactly 3 animals: Beatrice, Betsy, Callum";
// var = nothing, sep = ", " and count = 3
let array: [&str; 3] = parse!(input, "My farm contains exactly 3 animals: {:, :3}");
assert_eq!(array, ["Beatrice", "Betsy", "Callum"]);§Vec
You can parse a string into a Vec of parsed elements using the following syntax {<var>:<sep>:}.
This way of parsing is only available if the alloc feature has been enabled.
let input = "My farm contains some amount of booleans: true || false || true || false";
let many: Vec<bool>;
// var = many and sep = " || "
parse!(input, "My farm contains some amount of booleans: {many: || :}");
assert_eq!(many, vec![true, false, true, false]);§Iterator
Alternatively if you are unable to allocate anything then you can use a lazy iterator
by using the following syntax {<var>:<sep>:0}.
One important note is that since the iterator is evaluated lazily it will always return an iterator of Results.
The returned iterator will either be ParseIter or ParseChars if the separator is empty.
let input = "My farm has this many animals: [5,23,42,1,3,5]";
// var = nothing and sep = ","
let animal_count: u32 = parse!(input, "My farm has this many animals: [{:,:0}]")
.flat_map(|c: Result<u32, _>| c.ok())
.sum();
assert_eq!(animal_count, 79);§Modifiers
All three multi-parsers (Array, Vec and Iterator) allow {<var>:<sep>:!<kind>} syntax to skip multiple separators, for example
assert_eq!([1, 2, 3], parse!("1-2---3", "{:-:!3}"));§Empty separators
If the separator is an empty string slice (e.g. {::}) then the multi-parsers will iterate over every char.
assert_eq!([3, 2, 1], parse!("321", "{::3}"))§Syntax
The parse! macro uses a literal with {} brackets to denote where it should
try to parse into a type. The macro must fully consume the string as it will otherwise
return an error. If this is not what you want you can create a dummy capture variable
that captures the rest of the string.
let input = "Hello world! Today is a great day!";
let world: &str;
// We only care about world so capture everything else as a string to prevent an error.
let _capture: &str = parse!(input, "Hello {world}!{}")
assert_eq!(world, "world");§Escaping
The { and } brackets can be escaped by doubling them up. This leads to the following syntax:
let input = "Stuff in {} is really important: {42}";
let num: u128;
parse!(input, "Stuff in {{}} is really important: {{{num}}}");
assert_eq!(num, 42);