#cfg #target #syntax #attr #expression-parser #rust

parse_cfg

Parse and evaluate Rust’s cfg(any(condition)) attribute syntax and target triples

6 stable releases

4.1.1 Aug 18, 2023
4.1.0 Aug 16, 2023
3.1.0 May 1, 2023
3.0.0 Mar 9, 2023
0.1.0 May 20, 2018

#555 in Parser implementations

Download history 7/week @ 2024-01-07 3/week @ 2024-01-14 26/week @ 2024-01-21 44/week @ 2024-01-28 84/week @ 2024-02-04 43/week @ 2024-02-11 199/week @ 2024-02-18 293/week @ 2024-02-25 129/week @ 2024-03-03 148/week @ 2024-03-10 88/week @ 2024-03-17 189/week @ 2024-03-24

576 downloads per month
Used in 6 crates (2 directly)

CC0-1.0 OR MIT

26KB
489 lines

cfg() expression parser

Cfg is an AST for just cfg() expressions. Target allows target triples or cfg(), so it's suitable for parsing targets Cargo allows in target.🈁️.dependencies.

use parse_cfg::*;
fn main() -> Result<(), ParseError> {

let cfg: Cfg = r#"cfg(any(unix, feature = "extra"))"#.parse()?;
assert_eq!(Cfg::Any(vec![
    Cfg::Is("unix".into()),
    Cfg::Equal("feature".into(), "extra".into()),
]), cfg);

let is_set = cfg.eval(|key, comparison| if key == "feature" && comparison == "extra" { Some(comparison) } else { None });
assert!(is_set);

let target = "powerpc64le-unknown-linux-gnu".parse()?;
assert_eq!(Target::Triple {
    arch: "powerpc64le".into(),
    vendor: "unknown".into(),
    os: "linux".into(),
    env: Some("gnu".into()),
}, target);

/// `Cfg` and `Target` types take an optional generic argument for the string type,
/// so you can parse slices without allocating `String`s, or parse into `Cow<str>`.
let target = Target::<&str>::parse_generic("powerpc64le-unknown-linux-gnu")?;
assert_eq!(Target::Triple {
    arch: "powerpc64le",
    vendor: "unknown",
    os: "linux",
    env: Some("gnu"),
}, target);

Ok(()) }

It's safe to parse untrusted input. The depth of expressions is limited to 255 levels.

Target triples used by Rust don't follow its documented syntax, so sometimes os/vendor/env will be shifted.

Dependencies

~1MB
~17K SLoC