token-expander
December 25, 2018 ยท View on GitHub
Tokenizer with expansion capabilities for efficiently expanding strings with shell-like variable expansions. The caller decides how variables and escaped characters are expanded, as well as which character is to be used as the escape character.
Tokenizer
The tokenizer may be used by itself, if expansion is to be handled uniquely.
use token_expander::{Token, Tokenizer};
let url = "https://$domain/$repo/$name/${name}_${version}_$arch.deb";
assert_eq!(
Tokenizer::new(url).collect::<Vec<_>>(),
vec![
Token::Normal("https://"),
Token::Key("domain"),
Token::Normal("/"),
Token::Key("repo"),
Token::Normal("/"),
Token::Key("name"),
Token::Normal("/"),
Token::Key("name"),
Token::Normal("_"),
Token::Key("version"),
Token::Normal("_"),
Token::Key("arch"),
Token::Normal(".deb"),
]
);
Expander
Or the token expander functionality can be used to automate the handling of token expansions,
which can be accessed through the TokenizerExt trait.
use token_expander::{Token, Tokenizer, TokenizerExt};
let url = "https://${domain}/${repo}/${name}/${name}_${version}_${arch}.deb";
assert_eq!(
Tokenizer::new(url).expand(|buf, key| {
match key {
Token::Normal(text) => buf.push_str(text),
Token::Key("name") => buf.push_str("system76"),
Token::Key("version") => buf.push_str("1.0.0"),
Token::Key("arch") => buf.push_str("amd64"),
Token::Key("domain") => buf.push_str("apt.pop-os.org"),
Token::Key("repo") => buf.push_str("free"),
Token::Key(other) => return Err(format!("unsupported key: {}", other)),
Token::Escaped('n') => buf.push('\n'),
Token::Escaped('t') => buf.push('\t'),
Token::Escaped(character) => buf.push(character),
}
Ok(true)
}),
Ok("https://apt.pop-os.org/free/system76/system76_1.0.0_amd64.deb".into())
);
Custom Escapes
Sometimes you may want to alternate between escape characters, depending on the kind of source input that you need to process.
use token_expander::{Token, Tokenizer};
let pattern = "foo\\${bar}";
assert_eq!(
Tokenizer::new(pattern).collect::<Vec<_>>(),
vec![
Token::Normal("foo"),
Token::Escaped('$'),
Token::Normal("{bar}"),
]
);
assert_eq!(
Tokenizer::new("foo###${bar}").set_escape(b'#').collect::<Vec<_>>(),
vec![
Token::Normal("foo"),
Token::Escaped('#'),
Token::Escaped('$'),
Token::Normal("{bar}"),
]
)