Skip to content

Selecting enums

Enums in Rust can appear in two contexts: as declarations and as variant references. (enum) selects both and has the following signature:

clojure
(enum [name?] [variant?])

Enum declarations

Without arguments, (enum) matches any enum declaration:

clojure
(enum)      ; enum Foo { A, B }
(enum Foo)  ; enum Foo { A, B }
(enum /^E/) ; enum Error { ... }

Variant references

When an enum variant is referenced via EnumName::Variant, (enum) matches the scoped identifier:

clojure
(enum Foo)   ; Foo::A, Foo::B
(enum Foo A) ; Foo::A (but not Foo::B)

The name and variant arguments accept any selector, so you can use patterns:

clojure
(enum /Error/ /^Fatal/)  ; AppError::FatalCrash, Error::FatalIO

Matching both declarations and references

A single query can match both the enum declaration and its variant references:

rust
fn main() {
    log(Foo::A);  // matched by (enum Foo)
    log(Foo::B);  // matched by (enum Foo)
}

enum Foo {  // matched by (enum Foo)
    A,
    B
}
clojure
(enum Foo) ; matches all 3 locations above

Caveat: Macro invocations

Enum variant references inside macro invocations are not semantically parsed by tree-sitter. See Caveats for details and workarounds using (:text).

rust
eprintln!("{:?}", Foo::A);  // NOT matched by (enum Foo A)

Copyright © 2022-present Semantic Works, Inc.