reed-parser 0.1.0

A parser for the GraphQL language.
Documentation

Features

  • Typed GraphQL concrete syntax tree
  • Error resilience
    • lexing and parsing does not fail or panic if a lexical or a syntax error is found
  • GraphQL lexer
  • GraphQL parser

Getting started

Add the dependency to start using reed-parser:

cargo add reed-parser

Or add this to your Cargo.toml for a manual installation:

# Just an example, change to the necessary package version.
[dependencies]
reed-parser = "0.1.0"

Rust versions

reed-parser is tested on the latest stable version of Rust. Older version may or may not be compatible.

Usage

reed-parser parses GraphQL schemas and executable documents into a typed syntax tree that can be walked to extract the required information. You can quick start with:

use reed_parser::Parser;

let input = "union SearchResult = Photo | Person | Cat | Dog";
let parser = Parser::new(input);
let cst = parser.parse();

reed-parser is built to be error-resilient. This means we don't abort parsing (or lexing) if an error occurs. That means parser.parse() will always produce a CST (Concrete Syntax Tree), and it will be accompanied by any errors that are encountered:

use reed_parser::Parser;

let input = "union SearchResult = Photo | Person | Cat | Dog";
let parser = Parser::new(input);
let cst = parser.parse();

// cst.errors() returns an iterator with the errors encountered during lexing and parsing
assert_eq!(0, cst.errors().len());

// cst.document() gets the Document, or root node, of the tree that you can
// start iterating on.
let doc = cst.document();

Examples

Two examples outlined here:

The examples directory in this repository has a few more useful implementations such as:

Get field names in an object

use reed_parser::{cst, Parser};

let input = "
type ProductDimension {
  size: String
  weight: Float @tag(name: \"hi from inventory value type field\")
}
";
let parser = Parser::new(input);
let cst = parser.parse();
assert_eq!(0, cst.errors().len());

let doc = cst.document();

for def in doc.definitions() {
    if let cst::Definition::ObjectTypeDefinition(object_type) = def {
        assert_eq!(object_type.name().unwrap().text(), "ProductDimension");
        for field_def in object_type.fields_definition().unwrap().field_definitions() {
            println!("{}", field_def.name().unwrap().text()); // size weight
        }
    }
}

Get variables used in a query

use reed_parser::{cst, Parser};

let input = "
  query GraphQuery($graph_id: ID!, $variant: String) {
    service(id: $graph_id) {
      schema(tag: $variant) {
        document
      }
    }
  }
  ";

  let parser = Parser::new(input);
  let cst = parser.parse();
  assert_eq!(0, cst.errors().len());

  let doc = cst.document();

  for def in doc.definitions() {
      if let cst::Definition::OperationDefinition(op_def) = def {
          assert_eq!(op_def.name().unwrap().text(), "GraphQuery");

          let variable_defs = op_def.variable_definitions();
          let variables: Vec<String> = variable_defs
              .iter()
              .map(|v| v.variable_definitions())
              .flatten()
              .filter_map(|v| Some(v.variable()?.text().to_string()))
              .collect();
          assert_eq!(
              variables.as_slice(),
              ["graph_id".to_string(), "variant".to_string()]
          );
      }
  }

License

Licensed under either of

at your option.

Upstream provenance

Reed Parser 0.1.0 is derived from Apollo Parser 0.8.6 at upstream revision e36ca6dceb668b4b0c703449beea39e75c16ead5. The source corrections used to establish Reed are preserved in the historical apollo-parser-0.8.6.patch. Package naming, documentation paths, fixture discovery, source item order needed by workspace lints, and regression tests are adapted for the Reed package; the parser module organization is retained. The restored upstream fixture corpus reclassifies operation descriptions and empty selection sets and updates Unicode diagnostics to match the maintained September 2025 language corrections.