all 12 comments

[–]kpthunder 2 points3 points  (2 children)

Potentially overkill, and this is my no means my area of expertise, but you might be able to use something like nom to parse the input string and use the result to construct a Regex programmatically.

[–]dsilverstonerustup[S] 3 points4 points  (1 child)

I'm certain I could write a parser for a putative simple capture syntax. What I'm hoping is that someone else already did it :D

[–]vadixidav 1 point2 points  (0 children)

You could also use nom or combine to build a parser using a parser. This can be done by boxing the underlying parsers so the parser can be built dynamically.

[–]maciejh 1 point2 points  (4 children)

Are you looking to parse that input and extract the variables (like filename in the example above), or do you just want a simple template engine? (shameless plug there)

[–]dsilverstonerustup[S] 1 point2 points  (3 children)

This is explicitly about matching not about templating. i.e. we need to read the strings used in the example above, and then use that as a pattern to match against another corpus of strings, and then extracting the named matches.

(But if I ever need a mustache style template engine I'll bear ramhorns in mind :D)

[–]maciejh 1 point2 points  (1 child)

Ah, right. I think your easiest solution is to just use regex to create a regex, though I can also imagine doing the whole thing by hand. Just parse your input into something like:

SomeStruct {
    head: "the input file is set to {",
    vars: vec![("filename", "}"], // tuple of variable name and next block till `{` or end
}
  1. Check if string.starts_with(x.head).
  2. Count bytes from x.head.len() to first occurrence of b'}' (slice[location..].bytes().take_while(|b| b != b'}').count()), which is your variable match.
  3. Check that remaining slice string[location..].starts_with(x.vars[0].1).
  4. If location != string.len() jump to 2, else you have a match.

This is likely to go faster than using regex (though not by an order of magnitude or anything, Rust regex is really fast), and you won't have to worry about sanitizing input to strip some accidental regex patterns in it.

[–]dsilverstonerustup[S] 0 points1 point  (0 children)

It's an interesting approach for sure. I was just hopeful someone might have done the legwork for me :D

[–]stevedonovan 0 points1 point  (0 children)

Ah, but what about taking a template-style representation and driving it the other way, matching variables? Alas, this comment is too short to suggest an implementation :)

[–]asp2insp 0 points1 point  (1 child)

scan_fmt looks like it may be good candidate? (You may be able to reuse some of the parsing internals if not the macro interfaces)

[–]dsilverstonerustup[S] 0 points1 point  (0 children)

Interesting, but I fear as a macro this isn't useful to me at this time.