TreeMatcher
can be used from a build script to generate a matcher
function that maps byte sequences to arbitrary values. It returns the mapped
value (or None
) and the remainder of the input.
For example, suppose you generate a matcher for all HTML entities
called entity_matcher()
:
assert!(entity_matcher(b"×XYZ") == (Some("×"), b"XYZ".as_slice()));
- The prefixes it checks do not all have to be the same length.
- If more than one prefix matches, it will return the longest one.
- If nothing matches, it will return
(None, &input)
.
Since the matchers only check the start of the input, you will want to use
iter().position()
or the memchr crate to find the start of a
potential match.
It can also be configured to accept an iterator over bytes as input instead of a slice.
To create a matcher to handle the four basic HTML entities, use a build script like the following:
use matchgen::TreeMatcher;
use std::env;
use std::error::Error;
use std::fs::File;
use std::io::{BufWriter, Write};
use std::path::Path;
fn main() -> Result<(), Box<dyn Error>> {
let out_path = Path::new(&env::var("OUT_DIR")?).join("matcher.rs");
let mut out = BufWriter::new(File::create(out_path)?);
TreeMatcher::new("pub fn entity_decode", "u8")
.doc("Decode basic HTML entities.")
.add(b"&", "b'&'")
.add(b"<", "b'<'")
.add(b">", "b'>'")
.add(b""", "b'\"'")
.render(&mut out)?;
Ok(())
}
To use the matcher:
include!(concat!(env!("OUT_DIR"), "/matcher.rs"));
fn main() {
assert_eq!(
entity_decode(b"& on & on"),
(Some(b'&'), b" on & on".as_slice()),
);
}
This is potentially stable. I’m letting it bake a while to see if I come up with new features or better ways to accomplish the same thing before I release version 1.0.
I am open to suggestions.
This project dual-licensed under the Apache 2 and MIT licenses. You may choose to use either.
Unless you explicitly state otherwise, any contribution you submit as defined in the Apache 2.0 license shall be dual licensed as above, without any additional terms or conditions.