From 7e726090ed456b22a76197968bf0492a17706e5e Mon Sep 17 00:00:00 2001 From: Sunli Date: Fri, 27 Nov 2020 10:27:47 +0800 Subject: [PATCH 01/20] Update examples --- examples | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples b/examples index d8906667a..04e3b1993 160000 --- a/examples +++ b/examples @@ -1 +1 @@ -Subproject commit d8906667a98cd26938906a546c583392195d030e +Subproject commit 04e3b1993ffb151ff8e0680478b5a54ea8a8e0af From 55a4f695cb1d77f0f8f1c30803514e1997f02c24 Mon Sep 17 00:00:00 2001 From: Sunli Date: Wed, 23 Dec 2020 11:13:28 +0800 Subject: [PATCH 02/20] Add `connection::query_with` function. #329 --- src/types/connection/connection_type.rs | 12 +-- src/types/connection/mod.rs | 105 ++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 6 deletions(-) diff --git a/src/types/connection/connection_type.rs b/src/types/connection/connection_type.rs index c126352f3..f6a37637f 100644 --- a/src/types/connection/connection_type.rs +++ b/src/types/connection/connection_type.rs @@ -90,10 +90,10 @@ impl Connection { self.edges.extend(iter); } - /// Append edges with `IntoIterator>` - pub fn try_append(&mut self, iter: I) -> Result<()> + /// Append edges with `IntoIterator, E>>` + pub fn try_append(&mut self, iter: I) -> Result<(), E> where - I: IntoIterator>>, + I: IntoIterator, E>>, { for edge in iter { self.edges.push(edge?); @@ -109,10 +109,10 @@ impl Connection { self.edges.extend(stream.collect::>().await); } - /// Append edges with `Stream>>` - pub async fn try_append_stream(&mut self, stream: S) -> Result<()> + /// Append edges with `Stream, E>>` + pub async fn try_append_stream(&mut self, stream: S) -> Result<(), E> where - S: Stream>> + Unpin, + S: Stream, E>> + Unpin, { self.edges.extend(stream.try_collect::>().await?); Ok(()) diff --git a/src/types/connection/mod.rs b/src/types/connection/mod.rs index 4a666d20a..e968b06af 100644 --- a/src/types/connection/mod.rs +++ b/src/types/connection/mod.rs @@ -102,6 +102,111 @@ where ::Error: Display + Send + Sync + 'static, F: FnOnce(Option, Option, Option, Option) -> R, R: Future>>, +{ + query_with(after, before, first, last, f).await +} + +/// Parses the parameters and executes the query and return a custom `Connection` type. +/// +/// `Connection` and `Edge` have certain limitations. For example, you cannot customize +/// the name of the type, so you can use this function to execute the query and return a customized `Connection` type. +/// +/// # Examples +/// +/// ```rust +/// use async_graphql::*; +/// use async_graphql::connection::*; +/// +/// #[derive(SimpleObject)] +/// struct MyEdge { +/// cursor: usize, +/// node: i32, +/// diff: i32, +/// } +/// +/// #[derive(SimpleObject)] +/// struct MyConnection { +/// edges: Vec, +/// page_info: PageInfo, +/// } +/// +/// struct QueryRoot; +/// +/// #[Object] +/// impl QueryRoot { +/// async fn numbers(&self, +/// after: Option, +/// before: Option, +/// first: Option, +/// last: Option +/// ) -> Result { +/// query_with(after, before, first, last, |after, before, first, last| async move { +/// let mut start = after.map(|after| after + 1).unwrap_or(0); +/// let mut end = before.unwrap_or(10000); +/// if let Some(first) = first { +/// end = (start + first).min(end); +/// } +/// if let Some(last) = last { +/// start = if last > end - start { +/// end +/// } else { +/// end - last +/// }; +/// } +/// let connection = MyConnection { +/// edges: (start..end).into_iter().map(|n| MyEdge { +/// cursor: n, +/// node: n as i32, +/// diff: (10000 - n) as i32, +/// }).collect(), +/// page_info: PageInfo { +/// has_previous_page: start > 0, +/// has_next_page: end < 10000, +/// start_cursor: Some(start.encode_cursor()), +/// end_cursor: Some(end.encode_cursor()), +/// }, +/// }; +/// Ok(connection) +/// }).await +/// } +/// } +/// +/// #[async_std::main] +/// async fn main() { +/// let schema = Schema::new(QueryRoot, EmptyMutation, EmptySubscription); +/// +/// assert_eq!(schema.execute("{ numbers(first: 2) { edges { node diff } } }").await.into_result().unwrap().data, value!({ +/// "numbers": { +/// "edges": [ +/// {"node": 0, "diff": 10000}, +/// {"node": 1, "diff": 9999}, +/// ] +/// }, +/// })); +/// +/// assert_eq!(schema.execute("{ numbers(last: 2) { edges { node diff } } }").await.into_result().unwrap().data, value!({ +/// "numbers": { +/// "edges": [ +/// {"node": 9998, "diff": 2}, +/// {"node": 9999, "diff": 1}, +/// ] +/// }, +/// })); +/// } +/// +/// ``` +pub async fn query_with( + after: Option, + before: Option, + first: Option, + last: Option, + f: F, +) -> Result +where + Cursor: CursorType + Send + Sync, + ::Error: Display + Send + Sync + 'static, + F: FnOnce(Option, Option, Option, Option) -> R, + R: Future>, { if first.is_some() && last.is_some() { return Err("The \"first\" and \"last\" parameters cannot exist at the same time".into()); From 7fc386b83dfee16f86be21e6135f1ee0219833f3 Mon Sep 17 00:00:00 2001 From: Sunli Date: Wed, 23 Dec 2020 11:58:21 +0800 Subject: [PATCH 03/20] Release 2.4.3 async-graphql@2.4.3 async-graphql-actix-web@2.4.3 async-graphql-tide@2.4.3 async-graphql-warp@2.4.3 Generated by cargo-workspaces --- Cargo.toml | 2 +- integrations/actix-web/Cargo.toml | 4 ++-- integrations/rocket/Cargo.toml | 2 +- integrations/tide/Cargo.toml | 4 ++-- integrations/warp/Cargo.toml | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f25b31007..9ed9804d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "async-graphql" -version = "2.4.2" +version = "2.4.3" authors = ["sunli ", "Koxiaet"] edition = "2018" description = "A GraphQL server library implemented in Rust" diff --git a/integrations/actix-web/Cargo.toml b/integrations/actix-web/Cargo.toml index 4b4ffec0d..64653ff00 100644 --- a/integrations/actix-web/Cargo.toml +++ b/integrations/actix-web/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "async-graphql-actix-web" -version = "2.4.2" +version = "2.4.3" authors = ["sunli ", "Koxiaet"] edition = "2018" description = "async-graphql for actix-web" @@ -12,7 +12,7 @@ keywords = ["futures", "async", "graphql"] categories = ["network-programming", "asynchronous"] [dependencies] -async-graphql = { path = "../..", version = "=2.4.2" } +async-graphql = { path = "../..", version = "=2.4.3" } actix = "0.10.0" actix-http = "2.0.0" diff --git a/integrations/rocket/Cargo.toml b/integrations/rocket/Cargo.toml index 51faadbe4..0b58d151c 100644 --- a/integrations/rocket/Cargo.toml +++ b/integrations/rocket/Cargo.toml @@ -14,7 +14,7 @@ keywords = ["futures", "async", "graphql", "rocket"] categories = ["network-programming", "asynchronous"] [dependencies] -async-graphql = { path = "../..", version = "=2.4.2" } +async-graphql = { path = "../..", version = "=2.4.3" } rocket = { git = "https://github.com/SergioBenitez/Rocket/", rev = "0c150c2", default-features = false } # TODO: Change to Cargo crate when Rocket 0.5.0 is released serde = "1.0.117" diff --git a/integrations/tide/Cargo.toml b/integrations/tide/Cargo.toml index 2d533f30c..3e0462286 100644 --- a/integrations/tide/Cargo.toml +++ b/integrations/tide/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "async-graphql-tide" -version = "2.4.2" +version = "2.4.3" authors = ["vkill "] edition = "2018" description = "async-graphql for tide" @@ -12,7 +12,7 @@ keywords = ["futures", "async", "graphql"] categories = ["network-programming", "asynchronous"] [dependencies] -async-graphql = { path = "../..", version = "=2.4.2" } +async-graphql = { path = "../..", version = "=2.4.3" } tide = { version = "0.15.0", default-features = false, features = ["h1-server"] } diff --git a/integrations/warp/Cargo.toml b/integrations/warp/Cargo.toml index c193fa07a..1c4294ddf 100644 --- a/integrations/warp/Cargo.toml +++ b/integrations/warp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "async-graphql-warp" -version = "2.4.2" +version = "2.4.3" authors = ["sunli ", "Koxiaet"] edition = "2018" description = "async-graphql for warp" @@ -12,7 +12,7 @@ keywords = ["futures", "async", "graphql"] categories = ["network-programming", "asynchronous"] [dependencies] -async-graphql = { path = "../..", version = "=2.4.2" } +async-graphql = { path = "../..", version = "=2.4.3" } warp = { version = "0.2.5", default-features = false, features = ["websocket"] } futures-util = { version = "0.3.8", default-features = false } From facb6d53dc60799bfa61f49b30a5ee6591483aee Mon Sep 17 00:00:00 2001 From: Sunli Date: Mon, 12 Apr 2021 16:00:27 +0800 Subject: [PATCH 04/20] Clippy clean --- src/registry/export_sdl.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registry/export_sdl.rs b/src/registry/export_sdl.rs index 134560748..c44f92549 100644 --- a/src/registry/export_sdl.rs +++ b/src/registry/export_sdl.rs @@ -118,7 +118,7 @@ impl Registry { return; } - if name.as_str() == &self.query_type && federation { + if name.as_str() == self.query_type && federation { let mut field_count = 0; for field in fields.values() { if field.name.starts_with("__") From b1d949ff254156f11b24b46931c2542db756da83 Mon Sep 17 00:00:00 2001 From: Sunli Date: Fri, 22 Oct 2021 12:19:03 +0800 Subject: [PATCH 05/20] Update release.yml --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 54187a660..6ea76e03d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -44,7 +44,7 @@ jobs: path: integrations/axum - name: async-graphql-rocket registryName: async-graphql-rocket - path: async-graphql-rocket + path: integrations/rocket steps: - uses: actions-rs/toolchain@v1 with: From 794f7d4ae3c6226a236363284f48f536ef2cd3d2 Mon Sep 17 00:00:00 2001 From: Jeffrey Rooks Date: Wed, 24 Aug 2022 22:56:02 +0100 Subject: [PATCH 06/20] Add more information to dataloader docs remove example --- docs/en/src/dataloader.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/en/src/dataloader.md b/docs/en/src/dataloader.md index 21b888553..1022d9042 100644 --- a/docs/en/src/dataloader.md +++ b/docs/en/src/dataloader.md @@ -7,7 +7,13 @@ Have you noticed some GraphQL queries end can make hundreds of database queries, Imagine if you have a simple query like this: ```graphql -query { todos { users { name } } } +query { + todos { + users { + name + } + } +} ``` and `User` resolver is like this: @@ -30,7 +36,7 @@ impl User { } ``` -The query executor will call the `Todos` resolver which does a `select * from todo and return N todos`. Then for each +The query executor will call the `Todos` resolver which does a `select * from todo and return N todos`. Then for each of the todos, concurrently, call the `User` resolver, `SELECT from USER where id = todo.user_id`. eg: @@ -55,7 +61,7 @@ SELECT name FROM user WHERE id = $1 SELECT name FROM user WHERE id = $1 ``` -After executing `SELECT name FROM user WHERE id = $1` many times, and most `Todo` objects belong to the same user, we +After executing `SELECT name FROM user WHERE id = $1` many times, and most `Todo` objects belong to the same user, we need to optimize these codes! ## Dataloader @@ -90,11 +96,13 @@ impl Loader for UserNameLoader { } } +#[derive(SimpleObject)] +#[graphql(complex)] struct User { id: u64, } -#[Object] +#[ComplexObject] impl User { async fn name(&self, ctx: &Context<'_>) -> Result { let loader = ctx.data_unchecked::>(); From 4e7d550cf2a1b2bd93a1f48bf9b452216a2089f0 Mon Sep 17 00:00:00 2001 From: Dominik Spicher Date: Mon, 29 Aug 2022 22:14:59 +0200 Subject: [PATCH 07/20] tests/federation: compare export_sdl against expected schema This commit adds logic to two unit tests where the schema export is compared against expected output cached in two schema files. This is intended to help prevent bugs like the ones fixed in 116f6e4 or the immediately succeeding commit, as unexpected changes to schema export will become apparent in the commit diff, easing reviews. When legitimately changing the export output behaviour, the test suite just needs to be run twice, as the unit-tests automatically overwrite the files with the new version. This unit-test approach is inspired by https://matklad.github.io/2022/03/26/self-modifying-code.html --- tests/federation.rs | 18 +++++ .../test_entity_inaccessible.schema.graphql | 67 +++++++++++++++++++ tests/schemas/test_entity_tag.schema.graphql | 67 +++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 tests/schemas/test_entity_inaccessible.schema.graphql create mode 100644 tests/schemas/test_entity_tag.schema.graphql diff --git a/tests/federation.rs b/tests/federation.rs index 0bfc6091b..8b36594cb 100644 --- a/tests/federation.rs +++ b/tests/federation.rs @@ -536,6 +536,15 @@ pub async fn test_entity_inaccessible() { assert!(schema_sdl.contains("inputFieldInaccessibleA: Int! @inaccessible")); // no trailing spaces assert!(!schema_sdl.contains(" \n")); + + // compare to expected schema + let path = std::path::Path::new(&std::env::var("CARGO_MANIFEST_DIR").unwrap()) + .join("tests/schemas/test_entity_inaccessible.schema.graphql"); + let expected_schema = std::fs::read_to_string(&path).unwrap(); + if schema_sdl != expected_schema { + std::fs::write(path, schema_sdl).unwrap(); + panic!("schema was not up-to-date. rerun") + } } #[tokio::test] @@ -737,4 +746,13 @@ pub async fn test_entity_tag() { ); // no trailing spaces assert!(!schema_sdl.contains(" \n")); + + // compare to expected schema + let path = std::path::Path::new(&std::env::var("CARGO_MANIFEST_DIR").unwrap()) + .join("tests/schemas/test_entity_tag.schema.graphql"); + let expected_schema = std::fs::read_to_string(&path).unwrap(); + if schema_sdl != expected_schema { + std::fs::write(path, schema_sdl).unwrap(); + panic!("schema was not up-to-date. rerun") + } } diff --git a/tests/schemas/test_entity_inaccessible.schema.graphql b/tests/schemas/test_entity_inaccessible.schema.graphql new file mode 100644 index 000000000..40f488c8a --- /dev/null +++ b/tests/schemas/test_entity_inaccessible.schema.graphql @@ -0,0 +1,67 @@ + + + + +type MyCustomObjInaccessible @inaccessible { + a: Int! + customObjectInaccessible: Int! @inaccessible +} + +enum MyEnumInaccessible @inaccessible{ + OPTION_A + OPTION_B + OPTION_C +} + +enum MyEnumVariantInaccessible{ + OPTION_A_INACCESSIBLE @inaccessible + OPTION_B + OPTION_C +} + +input MyInputObjFieldInaccessible{ + inputFieldInaccessibleA: Int! @inaccessible +} + +input MyInputObjInaccessible @inaccessible{ + a: Int! +} + +interface MyInterfaceInaccessible @inaccessible { + inaccessibleInterfaceValue: String! @inaccessible +} + +type MyInterfaceObjA implements MyInterfaceInaccessible { + inaccessibleInterfaceValue: String! +} + +type MyInterfaceObjB implements MyInterfaceInaccessible @inaccessible { + inaccessibleInterfaceValue: String! +} + +scalar MyNumberInaccessible @inaccessible + +type MyObjFieldInaccessible @key(fields: "id") { + objFieldInaccessibleA: Int! @inaccessible +} + +type MyObjInaccessible @key(fields: "id") @inaccessible { + a: Int! +} + +union MyUnionInaccessible @inaccessible = MyInterfaceObjA | MyInterfaceObjB + +extend type Query { + enumVariantInaccessible(id: Int!): MyEnumVariantInaccessible! + enumInaccessible(id: Int!): MyEnumInaccessible! + inaccessibleField(id: Int!): Int! @inaccessible + inaccessibleArgument(id: Int! @inaccessible): Int! + inaccessibleInterface: MyInterfaceInaccessible! + inaccessibleUnion: MyUnionInaccessible! + inaccessibleScalar: MyNumberInaccessible! + inaccessibleInputField(value: MyInputObjFieldInaccessible!): Int! + inaccessibleInput(value: MyInputObjInaccessible!): Int! + inaccessibleCustomObject: MyCustomObjInaccessible! +} + + diff --git a/tests/schemas/test_entity_tag.schema.graphql b/tests/schemas/test_entity_tag.schema.graphql new file mode 100644 index 000000000..6c0396e22 --- /dev/null +++ b/tests/schemas/test_entity_tag.schema.graphql @@ -0,0 +1,67 @@ + + + + +type MyCustomObjTagged @tag(name: "tagged") @tag(name: "object") @tag(name: "with") @tag(name: "multiple") @tag(name: "tags") { + a: Int! + customObjectTagged: Int! @tag(name: "tagged_custom_object_field") +} + +enum MyEnumTagged @tag(name: "tagged_num"){ + OPTION_A + OPTION_B + OPTION_C +} + +enum MyEnumVariantTagged{ + OPTION_A_TAGGED @tag(name: "tagged_enum_option") + OPTION_B + OPTION_C +} + +input MyInputObjFieldTagged{ + inputFieldTaggedA: Int! @tag(name: "tagged_input_object_field") +} + +input MyInputObjTagged @tag(name: "input_object_tag"){ + a: Int! +} + +type MyInterfaceObjA implements MyInterfaceTagged { + taggedInterfaceValue: String! +} + +type MyInterfaceObjB implements MyInterfaceTagged @tag(name: "interface_object") { + taggedInterfaceValue: String! +} + +interface MyInterfaceTagged @tag(name: "tagged_interface") { + taggedInterfaceValue: String! @tag(name: "tagged_interface_field") +} + +scalar MyNumberTagged @tag(name: "tagged_scalar") + +type MyObjFieldTagged @key(fields: "id") { + objFieldTaggedA: Int! @tag(name: "tagged_field") +} + +type MyObjTagged @key(fields: "id") @tag(name: "tagged_simple_object") { + a: Int! +} + +union MyUnionTagged @tag(name: "tagged_union") = MyInterfaceObjA | MyInterfaceObjB + +extend type Query { + enumVariantTagged(id: Int!): MyEnumVariantTagged! + enumTagged(id: Int!): MyEnumTagged! + taggedField(id: Int!): Int! @tag(name: "tagged_\"field\"") + taggedArgument(id: Int! @tag(name: "tagged_argument")): Int! + taggedInterface: MyInterfaceTagged! + taggedUnion: MyUnionTagged! + taggedScalar: MyNumberTagged! + taggedInputField(value: MyInputObjFieldTagged!): Int! + taggedInput(value: MyInputObjTagged!): Int! + taggedCustomObject: MyCustomObjTagged! +} + + From 6bbe78bd7ddc301588f47b4504e734b3c314a29e Mon Sep 17 00:00:00 2001 From: Dominik Spicher Date: Mon, 29 Aug 2022 22:13:58 +0200 Subject: [PATCH 08/20] export_sdl: add missing space before opening braces --- src/registry/export_sdl.rs | 4 ++-- tests/schemas/test_entity_inaccessible.schema.graphql | 8 ++++---- tests/schemas/test_entity_tag.schema.graphql | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/registry/export_sdl.rs b/src/registry/export_sdl.rs index faa22946b..ddd76e830 100644 --- a/src/registry/export_sdl.rs +++ b/src/registry/export_sdl.rs @@ -367,7 +367,7 @@ impl Registry { write!(sdl, " @tag(name: \"{}\")", tag.replace('"', "\\\"")).ok(); } } - writeln!(sdl, "{{").ok(); + writeln!(sdl, " {{").ok(); let mut values = enum_values.values().collect::>(); if options.sorted_enum_values { @@ -418,7 +418,7 @@ impl Registry { write!(sdl, " @tag(name: \"{}\")", tag.replace('"', "\\\"")).ok(); } } - writeln!(sdl, "{{").ok(); + writeln!(sdl, " {{").ok(); let mut fields = input_fields.values().collect::>(); if options.sorted_fields { diff --git a/tests/schemas/test_entity_inaccessible.schema.graphql b/tests/schemas/test_entity_inaccessible.schema.graphql index 40f488c8a..7da5863fb 100644 --- a/tests/schemas/test_entity_inaccessible.schema.graphql +++ b/tests/schemas/test_entity_inaccessible.schema.graphql @@ -7,23 +7,23 @@ type MyCustomObjInaccessible @inaccessible { customObjectInaccessible: Int! @inaccessible } -enum MyEnumInaccessible @inaccessible{ +enum MyEnumInaccessible @inaccessible { OPTION_A OPTION_B OPTION_C } -enum MyEnumVariantInaccessible{ +enum MyEnumVariantInaccessible { OPTION_A_INACCESSIBLE @inaccessible OPTION_B OPTION_C } -input MyInputObjFieldInaccessible{ +input MyInputObjFieldInaccessible { inputFieldInaccessibleA: Int! @inaccessible } -input MyInputObjInaccessible @inaccessible{ +input MyInputObjInaccessible @inaccessible { a: Int! } diff --git a/tests/schemas/test_entity_tag.schema.graphql b/tests/schemas/test_entity_tag.schema.graphql index 6c0396e22..d7bdf7aa6 100644 --- a/tests/schemas/test_entity_tag.schema.graphql +++ b/tests/schemas/test_entity_tag.schema.graphql @@ -7,23 +7,23 @@ type MyCustomObjTagged @tag(name: "tagged") @tag(name: "object") @tag(name: "wit customObjectTagged: Int! @tag(name: "tagged_custom_object_field") } -enum MyEnumTagged @tag(name: "tagged_num"){ +enum MyEnumTagged @tag(name: "tagged_num") { OPTION_A OPTION_B OPTION_C } -enum MyEnumVariantTagged{ +enum MyEnumVariantTagged { OPTION_A_TAGGED @tag(name: "tagged_enum_option") OPTION_B OPTION_C } -input MyInputObjFieldTagged{ +input MyInputObjFieldTagged { inputFieldTaggedA: Int! @tag(name: "tagged_input_object_field") } -input MyInputObjTagged @tag(name: "input_object_tag"){ +input MyInputObjTagged @tag(name: "input_object_tag") { a: Int! } From 896cccf3091733286d22a91b721bd00882e7c4e1 Mon Sep 17 00:00:00 2001 From: Marais Rossouw Date: Thu, 1 Sep 2022 16:11:33 +1000 Subject: [PATCH 09/20] docs: updates readme --- README.md | 225 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 116 insertions(+), 109 deletions(-) diff --git a/README.md b/README.md index 5e0f4d038..d068eab10 100644 --- a/README.md +++ b/README.md @@ -1,102 +1,79 @@ -# A GraphQL server library implemented in Rust -
- - - - - - - Crates.io version - - - - Download - - - - docs.rs docs - - - Unsafe Rust forbidden - -
+ -`Async-graphql` is a high-performance server-side library that supports all GraphQL specifications. +# async-graphql -* [Feature Comparison](feature-comparison.md) -* [Book](https://async-graphql.github.io/async-graphql/en/index.html) -* [中文文档](https://async-graphql.github.io/async-graphql/zh-CN/index.html) -* [Docs](https://docs.rs/async-graphql) -* [GitHub repository](https://github.com/async-graphql/async-graphql) -* [Cargo package](https://crates.io/crates/async-graphql) -* Minimum supported Rust version: 1.59.0 or later +**a high-performance graphql server library that's fully specification compliant** -## Safety + -This crate uses `#![forbid(unsafe_code)]` to ensure everything is implemented in 100% Safe Rust. +[Feature Comparison](feature-comparison.md) • [Book](https://async-graphql.github.io/async-graphql/en/index.html) • [中文文档](https://async-graphql.github.io/async-graphql/zh-CN/index.html) • [Docs](https://docs.rs/async-graphql) • [GitHub repository](https://github.com/async-graphql/async-graphql) • [Cargo package](https://crates.io/crates/async-graphql) -## Features +--- -* Fully supports async/await -* Type safety -* Rustfmt friendly (Procedural Macro) -* Custom scalars -* Minimal overhead -* Easy integration ([poem](https://crates.io/crates/poem), actix_web, tide, warp, rocket ...) -* Upload files (Multipart request) -* Subscriptions (WebSocket transport) -* Custom extensions -* Apollo Tracing extension -* Limit query complexity/depth -* Error Extensions -* Apollo Federation -* Batch Queries -* Apollo Persisted Queries +![ci status](https://github.com/async-graphql/async-graphql/workflows/CI/badge.svg) +[![code coverage](https://codecov.io/gh/async-graphql/async-graphql/branch/master/graph/badge.svg)](https://codecov.io/gh/async-graphql/async-graphql/) +[![Unsafe Rust forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance/) +[![Crates.io version](https://img.shields.io/crates/v/async-graphql.svg)](https://crates.io/crates/async-graphql) +[![docs.rs docs](https://img.shields.io/badge/docs-latest-blue.svg)](https://docs.rs/async-graphql) +[![downloads](https://img.shields.io/crates/d/async-graphql.svg)](https://crates.io/crates/async-graphql) +[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/async-graphql/async-graphql/compare) -## Crate features +_This crate uses `#![forbid(unsafe_code)]` to ensure everything is implemented in 100% safe Rust._ -This crate offers the following features, all of which are not activated by default: + + +```rs +struct Query; + +#[Object] +impl Query { + fn howdy() -> &'static str { + "partner" + } +} + +async fn main() { + let schema = Schema::build(Query, EmptyMutation, EmptySubscription).finish(); + + let app = Route::new() + .at("/", + get(graphiql) + .post(GraphQL::new(schema) + )); + + println!("GraphiQL: http://localhost:8000"); + Server::new(TcpListener::bind("0.0.0.0:8000")) + .run(app) + .await + .unwrap(); +} +``` + +## Features -- `apollo_tracing`: Enable the [Apollo tracing extension](extensions/struct.ApolloTracing.html). -- `apollo_persisted_queries`: Enable the [Apollo persisted queries extension](extensions/apollo_persisted_queries/struct.ApolloPersistedQueries.html). -- `log`: Enable the [logger extension](extensions/struct.Logger.html). -- `tracing`: Enable the [tracing extension](extensions/struct.Tracing.html). -- `opentelemetry`: Enable the [OpenTelemetry extension](extensions/struct.OpenTelemetry.html). -- `unblock`: Support [asynchronous reader for Upload](types/struct.Upload.html) -- `bson`: Integrate with the [`bson` crate](https://crates.io/crates/bson). -- `chrono`: Integrate with the [`chrono` crate](https://crates.io/crates/chrono). -- `chrono-tz`: Integrate with the [`chrono-tz` crate](https://crates.io/crates/chrono-tz). -- `url`: Integrate with the [`url` crate](https://crates.io/crates/url). -- `uuid`: Integrate with the [`uuid` crate](https://crates.io/crates/uuid). -- `uuid08`: Integrate with the [`uuid 0.8` crate](https://crates.io/crates/uuid/0.8.2). -- `string_number`: Enable the [StringNumber](types/struct.StringNumber.html). -- `dataloader`: Support [DataLoader](dataloader/struct.DataLoader.html). -- `secrecy`: Integrate with the [`secrecy` crate](https://crates.io/crates/secrecy). -- `decimal`: Integrate with the [`rust_decimal` crate](https://crates.io/crates/rust_decimal). -- `bigdecimal`: Integrate with the [`bigdecimal` crate](https://crates.io/crates/bigdecimal). -- `cbor`: Support for [serde_cbor](https://crates.io/crates/serde_cbor). -- `smol_str`: Integrate with the [`smol_str` crate](https://crates.io/crates/smol_str). -- `hashbrown`: Integrate with the [`hashbrown` crate](https://github.com/rust-lang/hashbrown). -- `time`: Integrate with the [`time` crate](https://github.com/time-rs/time). -- `tokio-sync` Integrate with the [`tokio::sync::RwLock`](https://docs.rs/tokio/1.18.1/tokio/sync/struct.RwLock.html) and [`tokio::sync::Mutex`](https://docs.rs/tokio/1.18.1/tokio/sync/struct.Mutex.html). -- `fast_chemail`: Integrate with the [`fast_chemail` crate](https://crates.io/crates/fast_chemail). - -## Apollo Studio - -Apollo Studio is a cloud platform that helps you build, monitor, validate, and secure your organization's data graph. -An existing extension is available for this crate [here](https://github.com/async-graphql/async_graphql_apollo_studio_extension) +- Fully supports async/await +- Type safety +- Rustfmt friendly (Procedural Macro) +- Custom scalars +- Minimal overhead +- Easy integration ([poem](https://crates.io/crates/poem), actix_web, tide, warp, rocket ...) +- Upload files (Multipart request) +- Subscriptions (WebSocket transport) +- Custom extensions +- Error extensions +- Limit query complexity/depth +- Batch queries +- Apollo Persisted Queries +- Apollo Tracing extension +- Apollo Federation + +> **Note**: Minimum supported Rust version: 1.59.0 or later ## Examples All examples are in the [sub-repository](https://github.com/async-graphql/examples), located in the examples directory. -**Run an example:** - ```shell git submodule update # update the examples repo cd examples && cargo run --bin [name] @@ -104,14 +81,51 @@ cd examples && cargo run --bin [name] ## Integrations -* Poem [async-graphql-poem](https://crates.io/crates/async-graphql-poem) -* Actix-web [async-graphql-actix-web](https://crates.io/crates/async-graphql-actix-web) -* Warp [async-graphql-warp](https://crates.io/crates/async-graphql-warp) -* Tide [async-graphql-tide](https://crates.io/crates/async-graphql-tide) -* Rocket [async-graphql-rocket](https://github.com/async-graphql/async-graphql/tree/master/integrations/rocket) -* Axum [async-graphql-axum](https://github.com/async-graphql/async-graphql/tree/master/integrations/axum) +Integrations are what glue `async-graphql` with your web server, here are provided ones, or you can build your own! -## Who's using Async-graphql in production? +- Poem [async-graphql-poem](https://crates.io/crates/async-graphql-poem) +- Actix-web [async-graphql-actix-web](https://crates.io/crates/async-graphql-actix-web) +- Warp [async-graphql-warp](https://crates.io/crates/async-graphql-warp) +- Tide [async-graphql-tide](https://crates.io/crates/async-graphql-tide) +- Rocket [async-graphql-rocket](https://github.com/async-graphql/async-graphql/tree/master/integrations/rocket) +- Axum [async-graphql-axum](https://github.com/async-graphql/async-graphql/tree/master/integrations/axum) + +## Crate features + +This crate offers the following features, all of which are not activated by default: + +| feature | enables | +| :----------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **`apollo_tracing`** | Enable the [Apollo tracing extension](extensions/struct.ApolloTracing.html). | +| **`apollo_persisted_queries`** | Enable the [Apollo persisted queries extension](extensions/apollo_persisted_queries/struct.ApolloPersistedQueries.html). | +| **`log`** | Enable the [logger extension](extensions/struct.Logger.html). | +| **`tracing`** | Enable the [tracing extension](extensions/struct.Tracing.html). | +| **`opentelemetry`** | Enable the [OpenTelemetry extension](extensions/struct.OpenTelemetry.html). | +| **`unblock`** | Support [asynchronous reader for Upload](types/struct.Upload.html) | +| **`bson`** | Integrate with the [`bson` crate](https://crates.io/crates/bson). | +| **`chrono`** | Integrate with the [`chrono` crate](https://crates.io/crates/chrono). | +| **`chrono-tz`** | Integrate with the [`chrono-tz` crate](https://crates.io/crates/chrono-tz). | +| **`url`** | Integrate with the [`url` crate](https://crates.io/crates/url). | +| **`uuid`** | Integrate with the [`uuid` crate](https://crates.io/crates/uuid). | +| **`uuid08`** | Integrate with the [`uuid 0.8` crate](https://crates.io/crates/uuid/0.8.2). | +| **`string_number`** | Enable the [StringNumber](types/struct.StringNumber.html). | +| **`dataloader`** | Support [DataLoader](dataloader/struct.DataLoader.html). | +| **`secrecy`** | Integrate with the [`secrecy` crate](https://crates.io/crates/secrecy). | +| **`decimal`** | Integrate with the [`rust_decimal` crate](https://crates.io/crates/rust_decimal). | +| **`bigdecimal`** | Integrate with the [`bigdecimal` crate](https://crates.io/crates/bigdecimal). | +| **`cbor`** | Support for [serde_cbor](https://crates.io/crates/serde_cbor). | +| **`smol_str`** | Integrate with the [`smol_str` crate](https://crates.io/crates/smol_str). | +| **`hashbrown`** | Integrate with the [`hashbrown` crate](https://github.com/rust-lang/hashbrown). | +| **`time`** | Integrate with the [`time` crate](https://github.com/time-rs/time). | +| **`tokio-sync`** | Integrate with the [`tokio::sync::RwLock`](https://docs.rs/tokio/1.18.1/tokio/sync/struct.RwLock.html) and [`tokio::sync::Mutex`](https://docs.rs/tokio/1.18.1/tokio/sync/struct.Mutex.html). | +| **`fast_chemail`** | Integrate with the [`fast_chemail` crate](https://crates.io/crates/fast_chemail). | + +### Observability + +One of the tools used to monitor your graphql server in production is Apollo Studio. Apollo Studio is a cloud platform that helps you build, monitor, validate, and secure your organization's data graph. +Add the extension crate [`async_graphql_apollo_studio_extension`](https://github.com/async-graphql/async_graphql_apollo_studio_extension) to make this avaliable. + +## Who's using `async-graphql` in production? - [Vector](https://vector.dev/) - [DiveDB](https://divedb.net) @@ -138,31 +152,24 @@ cd examples && cargo run --bin [name] ## Blog Posts - [Async GraphQL with Rust](https://formidable.com/blog/2022/async-graphql-with-rust-1/) - - [GraphQL in Rust](https://romankudryashov.com/blog/2020/12/graphql-rust/) - - [How to implement a Rust micro-service using Rocket, GraphQL, PostgreSQL](https://lionkeng.medium.com/how-to-implement-a-rust-micro-service-using-rocket-graphql-postgresql-a3f455f2ae8b) - - [Running GraphQL on Lambda with Rust](https://dylananthony.com/posts/graphql-lambda-rust) +## References + +- [GraphQL](https://graphql.org) +- [GraphQL Multipart Request](https://github.com/jaydenseric/graphql-multipart-request-spec) +- [GraphQL Cursor Connections Specification](https://facebook.github.io/relay/graphql/connections.htm) +- [GraphQL over WebSocket Protocol](https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md) +- [Apollo Tracing](https://github.com/apollographql/apollo-tracing) +- [Apollo Federation](https://www.apollographql.com/docs/apollo-server/federation/introduction) + ## License Licensed under either of -* Apache License, Version 2.0, +- Apache License, Version 2.0, ([LICENSE-APACHE](./LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) -* MIT license ([LICENSE-MIT](./LICENSE-MIT) or http://opensource.org/licenses/MIT) +- MIT license ([LICENSE-MIT](./LICENSE-MIT) or http://opensource.org/licenses/MIT) at your option. - -## References - -* [GraphQL](https://graphql.org) -* [GraphQL Multipart Request](https://github.com/jaydenseric/graphql-multipart-request-spec) -* [GraphQL Cursor Connections Specification](https://facebook.github.io/relay/graphql/connections.htm) -* [GraphQL over WebSocket Protocol](https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md) -* [Apollo Tracing](https://github.com/apollographql/apollo-tracing) -* [Apollo Federation](https://www.apollographql.com/docs/apollo-server/federation/introduction) - -## Contribute - -Welcome to contribute ! From 94df3dbec2e99ef454c2d0d729d8ad317c3a5f5b Mon Sep 17 00:00:00 2001 From: Sunli Date: Thu, 1 Sep 2022 16:37:36 +0800 Subject: [PATCH 10/20] Update examples --- examples | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples b/examples index fa8fc5dde..0c175213d 160000 --- a/examples +++ b/examples @@ -1 +1 @@ -Subproject commit fa8fc5dde0e1f70dee67719eceecfc9ade250d1f +Subproject commit 0c175213d4df3f401cbf11dc89d5e0ca9fa923cf From 479fa613cbea390573ad56d85909a5eca6f9325d Mon Sep 17 00:00:00 2001 From: Sunli Date: Thu, 1 Sep 2022 22:50:07 +0800 Subject: [PATCH 11/20] Remove `bson-uuid` feature #1032 --- Cargo.toml | 5 ++++- src/types/external/bson.rs | 5 +---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e5a2ecc07..34d83b8b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,7 +56,10 @@ thiserror = "1.0.24" base64 = "0.13.0" # Feature optional dependencies -bson = { version = "2.0.0", optional = true, features = ["chrono-0_4"] } +bson = { version = "2.4.0", optional = true, features = [ + "chrono-0_4", + "uuid-1", +] } chrono = { version = "0.4.19", optional = true, default-features = false, features = [ "clock", "std", diff --git a/src/types/external/bson.rs b/src/types/external/bson.rs index 3f35cf4f8..eb0541fc0 100644 --- a/src/types/external/bson.rs +++ b/src/types/external/bson.rs @@ -1,8 +1,6 @@ #[cfg(feature = "chrono")] use bson::DateTime as UtcDateTime; -#[cfg(feature = "bson-uuid")] -use bson::Uuid; -use bson::{oid::ObjectId, Bson, Document}; +use bson::{oid::ObjectId, Bson, Document, Uuid}; #[cfg(feature = "chrono")] use chrono::{DateTime, Utc}; @@ -22,7 +20,6 @@ impl ScalarType for ObjectId { } } -#[cfg(feature = "bson-uuid")] #[Scalar(internal, name = "UUID")] impl ScalarType for Uuid { fn parse(value: Value) -> InputValueResult { From 8b1b382c6081c575d5bcd4a731ddf4654a7883fa Mon Sep 17 00:00:00 2001 From: Marais Rossouw Date: Thu, 1 Sep 2022 20:09:15 +1000 Subject: [PATCH 12/20] docs: readme example be correct rust --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d068eab10..62eee6703 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ struct Query; #[Object] impl Query { - fn howdy() -> &'static str { + fn howdy(&self) -> &'static str { "partner" } } @@ -39,8 +39,8 @@ async fn main() { let app = Route::new() .at("/", get(graphiql) - .post(GraphQL::new(schema) - )); + .post(GraphQL::new(schema)) + ); println!("GraphiQL: http://localhost:8000"); Server::new(TcpListener::bind("0.0.0.0:8000")) From 77630ffe9a423cb58466c09254f0ba02e9e53f9f Mon Sep 17 00:00:00 2001 From: Sunli Date: Thu, 1 Sep 2022 23:04:40 +0800 Subject: [PATCH 13/20] Update ci.yml --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d81c4a076..84a0c0639 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -135,7 +135,7 @@ jobs: fail-fast: false matrix: include: - - { rust: nightly-2022-06-29, os: ubuntu-latest } + - { rust: stable, os: ubuntu-latest } steps: - name: Checkout uses: actions/checkout@v2 From 112546d7a096012c228a0b773f4f7a3b1af3de1f Mon Sep 17 00:00:00 2001 From: Sunli Date: Thu, 1 Sep 2022 23:20:53 +0800 Subject: [PATCH 14/20] Update ci.yml --- .github/workflows/ci.yml | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 84a0c0639..57b31ebc2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,6 +83,9 @@ jobs: components: rustfmt - name: Check format run: cargo +${{ matrix.rust }} fmt --all -- --check + - name: Check examples format + working-directory: ./examples + run: cargo +${{ matrix.rust }} fmt --all -- --check clippy: name: Run clippy - Rust (${{ matrix.rust }}) on ${{ matrix.os }} @@ -141,16 +144,6 @@ jobs: uses: actions/checkout@v2 with: submodules: true - - - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - override: true - components: clippy, rustfmt - - name: Check examples format - run: cargo +${{ matrix.rust }} fmt --all -- --check - working-directory: ./examples - - uses: actions-rs/toolchain@v1 with: toolchain: ${{ matrix.rust }} From 83dc5ad8e77b3303647e3da5be7fbc82f9150e6c Mon Sep 17 00:00:00 2001 From: Sunli Date: Fri, 2 Sep 2022 15:09:44 +0800 Subject: [PATCH 15/20] Add `no_cache` for `cache_control` attribute #1051 --- derive/src/args.rs | 2 + derive/src/complex_object.rs | 6 +- derive/src/object.rs | 12 +++- derive/src/simple_object.rs | 12 +++- src/registry/cache_control.rs | 123 +++++++++++++++++++++++++++++----- 5 files changed, 135 insertions(+), 20 deletions(-) diff --git a/derive/src/args.rs b/derive/src/args.rs index 5be1c4c42..5d9870786 100644 --- a/derive/src/args.rs +++ b/derive/src/args.rs @@ -17,6 +17,7 @@ use crate::validators::Validators; pub struct CacheControl { public: bool, private: bool, + pub no_cache: bool, pub max_age: usize, } @@ -25,6 +26,7 @@ impl Default for CacheControl { Self { public: true, private: false, + no_cache: false, max_age: 0, } } diff --git a/derive/src/complex_object.rs b/derive/src/complex_object.rs index 51256b42d..abd78700f 100644 --- a/derive/src/complex_object.rs +++ b/derive/src/complex_object.rs @@ -189,7 +189,11 @@ pub fn generate( }; let cache_control = { let public = method_args.cache_control.is_public(); - let max_age = method_args.cache_control.max_age; + let max_age = if method_args.cache_control.no_cache { + -1 + } else { + method_args.cache_control.max_age as i32 + }; quote! { #crate_name::CacheControl { public: #public, diff --git a/derive/src/object.rs b/derive/src/object.rs index 6f921d0d9..08566819f 100644 --- a/derive/src/object.rs +++ b/derive/src/object.rs @@ -335,7 +335,11 @@ pub fn generate( }; let cache_control = { let public = method_args.cache_control.is_public(); - let max_age = method_args.cache_control.max_age; + let max_age = if method_args.cache_control.no_cache { + -1 + } else { + method_args.cache_control.max_age as i32 + }; quote! { #crate_name::CacheControl { public: #public, @@ -583,7 +587,11 @@ pub fn generate( let cache_control = { let public = object_args.cache_control.is_public(); - let max_age = object_args.cache_control.max_age; + let max_age = if object_args.cache_control.no_cache { + -1 + } else { + object_args.cache_control.max_age as i32 + }; quote! { #crate_name::CacheControl { public: #public, diff --git a/derive/src/simple_object.rs b/derive/src/simple_object.rs index 1949913cb..49d74df52 100644 --- a/derive/src/simple_object.rs +++ b/derive/src/simple_object.rs @@ -161,7 +161,11 @@ pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult GeneratorResult i32 { /// 0 /// } +/// +/// #[graphql(cache_control(no_cache))] +/// async fn value3(&self) -> i32 { +/// 0 +/// } /// } /// /// # tokio::runtime::Runtime::new().unwrap().block_on(async { @@ -34,6 +39,7 @@ /// max_age: 30 /// } /// ); +/// /// assert_eq!( /// schema /// .execute("{ value2 }") @@ -46,6 +52,7 @@ /// max_age: 60 /// } /// ); +/// /// assert_eq!( /// schema /// .execute("{ value1 value2 }") @@ -58,6 +65,19 @@ /// max_age: 30 /// } /// ); +/// +/// assert_eq!( +/// schema +/// .execute("{ value1 value2 value3 }") +/// .await +/// .into_result() +/// .unwrap() +/// .cache_control, +/// CacheControl { +/// public: false, +/// max_age: -1 +/// } +/// ); /// # }); /// ``` #[derive(Clone, Copy, PartialEq, Eq, Debug)] @@ -65,8 +85,8 @@ pub struct CacheControl { /// Scope is public, default is true. pub public: bool, - /// Cache max age, default is 0. - pub max_age: usize, + /// Cache max age, `-1` represent `no-cache`, default is 0. + pub max_age: i32, } impl Default for CacheControl { @@ -82,12 +102,23 @@ impl CacheControl { /// Get 'Cache-Control' header value. #[must_use] pub fn value(&self) -> Option { - if self.max_age > 0 { - Some(format!( - "max-age={}{}", - self.max_age, - if self.public { "" } else { ", private" } - )) + let mut value = if self.max_age > 0 { + format!("max-age={}", self.max_age) + } else if self.max_age == -1 { + "no-cache".to_string() + } else { + String::new() + }; + + if !self.public { + if !value.is_empty() { + value += ", "; + } + value += "private"; + } + + if !value.is_empty() { + Some(value) } else { None } @@ -99,13 +130,75 @@ impl CacheControl { pub(crate) fn merge(self, other: &CacheControl) -> CacheControl { CacheControl { public: self.public && other.public, - max_age: if self.max_age == 0 { - other.max_age - } else if other.max_age == 0 { - self.max_age - } else { - self.max_age.min(other.max_age) + max_age: match (self.max_age, other.max_age) { + (-1, _) => -1, + (_, -1) => -1, + (a, 0) => a, + (0, b) => b, + (a, b) => a.min(b), }, } } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn to_value() { + assert_eq!( + CacheControl { + public: true, + max_age: 0, + } + .value(), + None + ); + + assert_eq!( + CacheControl { + public: false, + max_age: 0, + } + .value(), + Some("private".to_string()) + ); + + assert_eq!( + CacheControl { + public: false, + max_age: 10, + } + .value(), + Some("max-age=10, private".to_string()) + ); + + assert_eq!( + CacheControl { + public: true, + max_age: 10, + } + .value(), + Some("max-age=10".to_string()) + ); + + assert_eq!( + CacheControl { + public: true, + max_age: -1, + } + .value(), + Some("no-cache".to_string()) + ); + + assert_eq!( + CacheControl { + public: false, + max_age: -1, + } + .value(), + Some("no-cache, private".to_string()) + ); + } +} From f58bd8ac4f32b900e3e139782a7a23ced4c25ab4 Mon Sep 17 00:00:00 2001 From: Sunli Date: Tue, 6 Sep 2022 09:36:08 +0800 Subject: [PATCH 16/20] Fixes #1063 --- src/registry/export_sdl.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registry/export_sdl.rs b/src/registry/export_sdl.rs index ddd76e830..0461d3804 100644 --- a/src/registry/export_sdl.rs +++ b/src/registry/export_sdl.rs @@ -408,7 +408,7 @@ impl Registry { write!(sdl, "input {}", name).ok(); if *oneof { - write!(sdl, " @oneof").ok(); + write!(sdl, " @oneOf").ok(); } if options.federation { if *inaccessible { From 36bc41a46ddef80aa8e11ab284bf627495a44860 Mon Sep 17 00:00:00 2001 From: cw-ozaki Date: Mon, 29 Aug 2022 15:36:05 +0900 Subject: [PATCH 17/20] support for primitive type in CursorType --- src/types/connection/cursor.rs | 60 +++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/src/types/connection/cursor.rs b/src/types/connection/cursor.rs index 5f02ecede..325a25fed 100644 --- a/src/types/connection/cursor.rs +++ b/src/types/connection/cursor.rs @@ -1,7 +1,9 @@ use std::{ + char::ParseCharError, convert::Infallible, fmt::Display, num::{ParseFloatError, ParseIntError}, + str::ParseBoolError, }; use serde::{de::DeserializeOwned, Serialize}; @@ -23,20 +25,26 @@ pub trait CursorType: Sized { fn encode_cursor(&self) -> String; } -impl CursorType for usize { - type Error = ParseIntError; +macro_rules! cursor_type_int_impl { + ($($t:ty)*) => {$( + impl CursorType for $t { + type Error = ParseIntError; - fn decode_cursor(s: &str) -> Result { - s.parse() - } + fn decode_cursor(s: &str) -> Result { + s.parse() + } - fn encode_cursor(&self) -> String { - self.to_string() - } + fn encode_cursor(&self) -> String { + self.to_string() + } + } + )*} } -impl CursorType for i32 { - type Error = ParseIntError; +cursor_type_int_impl! { isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 } + +impl CursorType for f32 { + type Error = ParseFloatError; fn decode_cursor(s: &str) -> Result { s.parse() @@ -47,8 +55,8 @@ impl CursorType for i32 { } } -impl CursorType for i64 { - type Error = ParseIntError; +impl CursorType for f64 { + type Error = ParseFloatError; fn decode_cursor(s: &str) -> Result { s.parse() @@ -59,23 +67,23 @@ impl CursorType for i64 { } } -impl CursorType for String { - type Error = Infallible; +impl CursorType for char { + type Error = ParseCharError; fn decode_cursor(s: &str) -> Result { - Ok(s.to_string()) + s.parse() } fn encode_cursor(&self) -> String { - self.clone() + self.to_string() } } -impl CursorType for ID { - type Error = Infallible; +impl CursorType for bool { + type Error = ParseBoolError; fn decode_cursor(s: &str) -> Result { - Ok(s.to_string().into()) + s.parse() } fn encode_cursor(&self) -> String { @@ -83,23 +91,23 @@ impl CursorType for ID { } } -impl CursorType for f64 { - type Error = ParseFloatError; +impl CursorType for String { + type Error = Infallible; fn decode_cursor(s: &str) -> Result { - s.parse() + Ok(s.to_string()) } fn encode_cursor(&self) -> String { - self.to_string() + self.clone() } } -impl CursorType for f32 { - type Error = ParseFloatError; +impl CursorType for ID { + type Error = Infallible; fn decode_cursor(s: &str) -> Result { - s.parse() + Ok(s.to_string().into()) } fn encode_cursor(&self) -> String { From 661794506d6a7a9ca7a30a7c317136e2a1aa08b5 Mon Sep 17 00:00:00 2001 From: rsdy Date: Mon, 5 Sep 2022 17:22:48 +0100 Subject: [PATCH 18/20] Resurrect code generation through tests --- parser/Cargo.toml | 2 +- parser/build.rs | 32 - parser/src/parse/generated.rs | 2140 ++++++++++++++++++++++++++++++++- parser/tests/codegen.rs | 67 ++ 4 files changed, 2207 insertions(+), 34 deletions(-) delete mode 100644 parser/build.rs diff --git a/parser/Cargo.toml b/parser/Cargo.toml index 855f0f242..3ddba5604 100644 --- a/parser/Cargo.toml +++ b/parser/Cargo.toml @@ -17,6 +17,6 @@ pest = "2.2.1" serde = { version = "1.0.125", features = ["derive"] } serde_json = "1.0.64" -[build-dependencies] +[dev-dependencies] pest_generator = "2.2.1" proc-macro2 = "1.0.37" diff --git a/parser/build.rs b/parser/build.rs deleted file mode 100644 index 1d580660c..000000000 --- a/parser/build.rs +++ /dev/null @@ -1,32 +0,0 @@ -use std::{error::Error, fs}; - -const PREAMBLE: &str = "\ -//! This is @generated code, do not edit by hand. -//! See `graphql.pest` and `tests/codegen.rs`. -#![allow(unused_attributes)] -use super::GraphQLParser; -"; - -fn main() -> Result<(), Box> { - generated_code()?; - println!("cargo:rerun-if-changed=src/graphql.pest"); - Ok(()) -} - -fn generated_code() -> Result<(), Box> { - let input = r###" -#[derive(Parser)] -#[grammar = r#"graphql.pest"#] -struct GraphQLParser; -"### - .parse::() - .unwrap(); - let tokens = pest_generator::derive_parser(input, false); - let new = tokens.to_string(); - let code = format!("{}\n{}", PREAMBLE, &new); - let current_code = fs::read_to_string("./src/parse/generated.rs").unwrap(); - if current_code != code { - fs::write("./src/parse/generated.rs", code).unwrap(); - } - Ok(()) -} diff --git a/parser/src/parse/generated.rs b/parser/src/parse/generated.rs index ec972ab66..43aae14a9 100644 --- a/parser/src/parse/generated.rs +++ b/parser/src/parse/generated.rs @@ -1,6 +1,2144 @@ + //! This is @generated code, do not edit by hand. //! See `graphql.pest` and `tests/codegen.rs`. #![allow(unused_attributes)] use super::GraphQLParser; -# [allow (dead_code , non_camel_case_types , clippy :: upper_case_acronyms)] # [derive (Clone , Copy , Debug , Eq , Hash , Ord , PartialEq , PartialOrd)] pub enum Rule { EOI , WHITESPACE , COMMENT , line_terminator , executable_document , executable_definition , operation_definition , named_operation_definition , variable_definitions , variable_definition , selection_set , selection , field , alias , fragment_spread , inline_fragment , fragment_definition , type_condition , service_document , type_system_definition , schema_definition , operation_type_definition , type_definition , scalar_type , object_type , implements_interfaces , interface_type , fields_definition , field_definition , union_type , union_member_types , enum_type , enum_values , enum_value_definition , input_object_type , input_fields_definition , extend , directive_definition , directive_locations , directive_location , arguments_definition , input_value_definition , operation_type , default_value , type_ , const_value , value , variable , number , float , fractional , exponent , int , string , block_string_content , block_string_character , string_content , string_character , unicode_scalar_value_hex , boolean , null , enum_value , const_list , list , const_object , object , const_object_field , object_field , const_directives , directives , const_directive , directive , const_arguments , arguments , const_argument , argument , name_start , name } # [allow (clippy :: all)] impl :: pest :: Parser < Rule > for GraphQLParser { fn parse < 'i > (rule : Rule , input : & 'i str) -> :: std :: result :: Result < :: pest :: iterators :: Pairs < 'i , Rule > , :: pest :: error :: Error < Rule > > { mod rules { # ! [allow (clippy :: upper_case_acronyms)] pub mod hidden { use super :: super :: Rule ; # [inline] # [allow (dead_code , non_snake_case , unused_variables)] pub fn skip (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { if state . atomicity () == :: pest :: Atomicity :: NonAtomic { state . sequence (| state | { state . repeat (| state | super :: visible :: WHITESPACE (state)) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: visible :: COMMENT (state) . and_then (| state | { state . repeat (| state | super :: visible :: WHITESPACE (state)) }) }) }) }) }) } else { Ok (state) } } } pub mod visible { use super :: super :: Rule ; # [inline] # [allow (non_snake_case , unused_variables)] pub fn WHITESPACE (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . atomic (:: pest :: Atomicity :: Atomic , | state | { state . match_string (" ") . or_else (| state | { state . match_string (",") }) . or_else (| state | { state . match_string ("\t") }) . or_else (| state | { state . match_string ("\u{feff}") }) . or_else (| state | { self :: line_terminator (state) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn COMMENT (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . atomic (:: pest :: Atomicity :: Atomic , | state | { state . sequence (| state | { state . match_string ("#") . and_then (| state | { state . repeat (| state | { state . sequence (| state | { state . lookahead (false , | state | { self :: line_terminator (state) }) . and_then (| state | { self :: ANY (state) }) }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn line_terminator (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: line_terminator , | state | { state . atomic (:: pest :: Atomicity :: Atomic , | state | { state . match_string ("\r\n") . or_else (| state | { state . match_string ("\r") }) . or_else (| state | { state . match_string ("\n") }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn executable_document (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: executable_document , | state | { state . sequence (| state | { self :: SOI (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { self :: executable_definition (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: executable_definition (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: executable_definition (state) }) }) }) }) }) }) }) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: EOI (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn executable_definition (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: executable_definition , | state | { self :: operation_definition (state) . or_else (| state | { self :: fragment_definition (state) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn operation_definition (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: operation_definition , | state | { self :: named_operation_definition (state) . or_else (| state | { self :: selection_set (state) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn named_operation_definition (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: named_operation_definition , | state | { state . sequence (| state | { self :: operation_type (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: name (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: variable_definitions (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: directives (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: selection_set (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn variable_definitions (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: variable_definitions , | state | { state . sequence (| state | { state . match_string ("(") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: variable_definition (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: variable_definition (state) }) }) }) }) }) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string (")") }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn variable_definition (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: variable_definition , | state | { state . sequence (| state | { self :: variable (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string (":") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: type_ (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: directives (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: default_value (state) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn selection_set (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: selection_set , | state | { state . sequence (| state | { state . match_string ("{") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { self :: selection (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: selection (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: selection (state) }) }) }) }) }) }) }) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("}") }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn selection (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: selection , | state | { self :: field (state) . or_else (| state | { self :: inline_fragment (state) }) . or_else (| state | { self :: fragment_spread (state) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn field (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: field , | state | { state . sequence (| state | { state . optional (| state | { self :: alias (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: arguments (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: directives (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: selection_set (state) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn alias (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: alias , | state | { state . sequence (| state | { self :: name (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string (":") }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn fragment_spread (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: fragment_spread , | state | { state . sequence (| state | { state . match_string ("...") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . lookahead (false , | state | { self :: type_condition (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: directives (state) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn inline_fragment (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: inline_fragment , | state | { state . sequence (| state | { state . match_string ("...") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: type_condition (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: directives (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: selection_set (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn fragment_definition (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: fragment_definition , | state | { state . sequence (| state | { state . match_string ("fragment") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: type_condition (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: directives (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: selection_set (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn type_condition (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . atomic (:: pest :: Atomicity :: CompoundAtomic , | state | { state . rule (Rule :: type_condition , | state | { state . sequence (| state | { state . match_string ("on") . and_then (| state | { state . sequence (| state | { self :: WHITESPACE (state) . and_then (| state | { state . repeat (| state | { self :: WHITESPACE (state) }) }) }) }) . and_then (| state | { self :: name (state) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn service_document (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: service_document , | state | { state . sequence (| state | { self :: SOI (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { self :: type_system_definition (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: type_system_definition (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: type_system_definition (state) }) }) }) }) }) }) }) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: EOI (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn type_system_definition (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: type_system_definition , | state | { self :: schema_definition (state) . or_else (| state | { self :: type_definition (state) }) . or_else (| state | { self :: directive_definition (state) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn schema_definition (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: schema_definition , | state | { state . sequence (| state | { state . match_string ("schema") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: const_directives (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("{") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { self :: operation_type_definition (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: operation_type_definition (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: operation_type_definition (state) }) }) }) }) }) }) }) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("}") }) }) . or_else (| state | { state . sequence (| state | { self :: extend (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("schema") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: const_directives (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("{") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { self :: operation_type_definition (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: operation_type_definition (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: operation_type_definition (state) }) }) }) }) }) }) }) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("}") }) }) . or_else (| state | { self :: const_directives (state) }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn operation_type_definition (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: operation_type_definition , | state | { state . sequence (| state | { self :: operation_type (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string (":") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn type_definition (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: type_definition , | state | { self :: scalar_type (state) . or_else (| state | { self :: object_type (state) }) . or_else (| state | { self :: interface_type (state) }) . or_else (| state | { self :: union_type (state) }) . or_else (| state | { self :: enum_type (state) }) . or_else (| state | { self :: input_object_type (state) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn scalar_type (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: scalar_type , | state | { state . sequence (| state | { state . optional (| state | { self :: string (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("scalar") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: const_directives (state) }) }) }) . or_else (| state | { state . sequence (| state | { self :: extend (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("scalar") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: const_directives (state) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn object_type (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: object_type , | state | { state . sequence (| state | { state . optional (| state | { self :: string (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("type") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: implements_interfaces (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: const_directives (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: fields_definition (state) }) }) }) . or_else (| state | { state . sequence (| state | { self :: extend (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("type") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: implements_interfaces (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: const_directives (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: fields_definition (state) }) }) . or_else (| state | { self :: const_directives (state) }) }) }) . or_else (| state | { self :: implements_interfaces (state) }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn implements_interfaces (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: implements_interfaces , | state | { state . sequence (| state | { state . match_string ("implements") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { state . match_string ("&") }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { state . sequence (| state | { state . match_string ("&") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) }) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { state . sequence (| state | { state . match_string ("&") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) }) }) }) }) }) }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn interface_type (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: interface_type , | state | { state . sequence (| state | { state . optional (| state | { self :: string (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("interface") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: implements_interfaces (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: const_directives (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: fields_definition (state) }) }) }) . or_else (| state | { state . sequence (| state | { self :: extend (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("interface") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: implements_interfaces (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: const_directives (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: fields_definition (state) }) }) . or_else (| state | { self :: const_directives (state) }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn fields_definition (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: fields_definition , | state | { state . sequence (| state | { state . match_string ("{") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { self :: field_definition (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: field_definition (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: field_definition (state) }) }) }) }) }) }) }) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("}") }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn field_definition (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: field_definition , | state | { state . sequence (| state | { state . optional (| state | { self :: string (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: arguments_definition (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string (":") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: type_ (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: const_directives (state) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn union_type (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: union_type , | state | { state . sequence (| state | { state . optional (| state | { self :: string (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("union") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: const_directives (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: union_member_types (state) }) }) }) . or_else (| state | { state . sequence (| state | { self :: extend (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("union") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: const_directives (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: union_member_types (state) }) }) . or_else (| state | { self :: const_directives (state) }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn union_member_types (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: union_member_types , | state | { state . sequence (| state | { state . match_string ("=") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { state . match_string ("|") }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { state . sequence (| state | { state . match_string ("|") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) }) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { state . sequence (| state | { state . match_string ("|") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) }) }) }) }) }) }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn enum_type (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: enum_type , | state | { state . sequence (| state | { state . optional (| state | { self :: string (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("enum") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: const_directives (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: enum_values (state) }) }) }) . or_else (| state | { state . sequence (| state | { self :: extend (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("enum") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: const_directives (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: enum_values (state) }) }) . or_else (| state | { self :: const_directives (state) }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn enum_values (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: enum_values , | state | { state . sequence (| state | { state . match_string ("{") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { self :: enum_value_definition (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: enum_value_definition (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: enum_value_definition (state) }) }) }) }) }) }) }) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("}") }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn enum_value_definition (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: enum_value_definition , | state | { state . sequence (| state | { state . optional (| state | { self :: string (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: enum_value (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: const_directives (state) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn input_object_type (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: input_object_type , | state | { state . sequence (| state | { state . optional (| state | { self :: string (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("input") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: const_directives (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: input_fields_definition (state) }) }) }) . or_else (| state | { state . sequence (| state | { self :: extend (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("input") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: const_directives (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: input_fields_definition (state) }) }) . or_else (| state | { self :: const_directives (state) }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn input_fields_definition (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: input_fields_definition , | state | { state . sequence (| state | { state . match_string ("{") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { self :: input_value_definition (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: input_value_definition (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: input_value_definition (state) }) }) }) }) }) }) }) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("}") }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn extend (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: extend , | state | { state . match_string ("extend") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn directive_definition (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: directive_definition , | state | { state . sequence (| state | { state . optional (| state | { self :: string (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("directive") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("@") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: arguments_definition (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("on") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: directive_locations (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn directive_locations (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: directive_locations , | state | { state . sequence (| state | { state . optional (| state | { state . match_string ("|") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: directive_location (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { state . sequence (| state | { state . match_string ("|") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: directive_location (state) }) }) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { state . sequence (| state | { state . match_string ("|") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: directive_location (state) }) }) }) }) }) }) }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn directive_location (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: directive_location , | state | { state . match_string ("QUERY") . or_else (| state | { state . match_string ("MUTATION") }) . or_else (| state | { state . match_string ("SUBSCRIPTION") }) . or_else (| state | { state . match_string ("FIELD_DEFINITION") }) . or_else (| state | { state . match_string ("FIELD") }) . or_else (| state | { state . match_string ("FRAGMENT_DEFINITION") }) . or_else (| state | { state . match_string ("FRAGMENT_SPREAD") }) . or_else (| state | { state . match_string ("INLINE_FRAGMENT") }) . or_else (| state | { state . match_string ("VARIABLE_DEFINITION") }) . or_else (| state | { state . match_string ("SCHEMA") }) . or_else (| state | { state . match_string ("SCALAR") }) . or_else (| state | { state . match_string ("OBJECT") }) . or_else (| state | { state . match_string ("ARGUMENT_DEFINITION") }) . or_else (| state | { state . match_string ("INTERFACE") }) . or_else (| state | { state . match_string ("UNION") }) . or_else (| state | { state . match_string ("ENUM_VALUE") }) . or_else (| state | { state . match_string ("ENUM") }) . or_else (| state | { state . match_string ("INPUT_OBJECT") }) . or_else (| state | { state . match_string ("INPUT_FIELD_DEFINITION") }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn arguments_definition (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: arguments_definition , | state | { state . sequence (| state | { state . match_string ("(") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { self :: input_value_definition (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: input_value_definition (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: input_value_definition (state) }) }) }) }) }) }) }) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string (")") }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn input_value_definition (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: input_value_definition , | state | { state . sequence (| state | { state . optional (| state | { self :: string (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string (":") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: type_ (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: default_value (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: const_directives (state) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn operation_type (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: operation_type , | state | { state . match_string ("query") . or_else (| state | { state . match_string ("mutation") }) . or_else (| state | { state . match_string ("subscription") }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn default_value (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: default_value , | state | { state . sequence (| state | { state . match_string ("=") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: const_value (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn type_ (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: type_ , | state | { state . atomic (:: pest :: Atomicity :: Atomic , | state | { state . sequence (| state | { self :: name (state) . or_else (| state | { state . sequence (| state | { state . match_string ("[") . and_then (| state | { self :: type_ (state) }) . and_then (| state | { state . match_string ("]") }) }) }) . and_then (| state | { state . optional (| state | { state . match_string ("!") }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn const_value (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: const_value , | state | { self :: number (state) . or_else (| state | { self :: string (state) }) . or_else (| state | { self :: boolean (state) }) . or_else (| state | { self :: null (state) }) . or_else (| state | { self :: enum_value (state) }) . or_else (| state | { self :: const_list (state) }) . or_else (| state | { self :: const_object (state) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn value (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: value , | state | { self :: variable (state) . or_else (| state | { self :: number (state) }) . or_else (| state | { self :: string (state) }) . or_else (| state | { self :: boolean (state) }) . or_else (| state | { self :: null (state) }) . or_else (| state | { self :: enum_value (state) }) . or_else (| state | { self :: list (state) }) . or_else (| state | { self :: object (state) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn variable (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: variable , | state | { state . sequence (| state | { state . match_string ("$") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn number (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: number , | state | { state . atomic (:: pest :: Atomicity :: Atomic , | state | { state . sequence (| state | { self :: float (state) . or_else (| state | { self :: int (state) }) . and_then (| state | { state . lookahead (false , | state | { self :: name_start (state) }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn float (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: float , | state | { state . sequence (| state | { self :: int (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { self :: fractional (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: exponent (state) }) }) . or_else (| state | { self :: fractional (state) }) . or_else (| state | { self :: exponent (state) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn fractional (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: fractional , | state | { state . sequence (| state | { state . match_string (".") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: ASCII_DIGIT (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: ASCII_DIGIT (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: ASCII_DIGIT (state) }) }) }) }) }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn exponent (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: exponent , | state | { state . sequence (| state | { state . match_string ("E") . or_else (| state | { state . match_string ("e") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { state . match_string ("+") . or_else (| state | { state . match_string ("-") }) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: ASCII_DIGIT (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: ASCII_DIGIT (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: ASCII_DIGIT (state) }) }) }) }) }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn int (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: int , | state | { state . sequence (| state | { state . optional (| state | { state . match_string ("-") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("0") . or_else (| state | { state . sequence (| state | { self :: ASCII_NONZERO_DIGIT (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: ASCII_DIGIT (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: ASCII_DIGIT (state) }) }) }) }) }) }) }) }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn string (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . atomic (:: pest :: Atomicity :: CompoundAtomic , | state | { state . rule (Rule :: string , | state | { state . sequence (| state | { state . match_string ("\"\"\"") . and_then (| state | { self :: block_string_content (state) }) . and_then (| state | { state . match_string ("\"\"\"") }) }) . or_else (| state | { state . sequence (| state | { state . match_string ("\"") . and_then (| state | { self :: string_content (state) }) . and_then (| state | { state . match_string ("\"") }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn block_string_content (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: block_string_content , | state | { state . atomic (:: pest :: Atomicity :: Atomic , | state | { state . repeat (| state | { self :: block_string_character (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn block_string_character (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: block_string_character , | state | { state . sequence (| state | { state . lookahead (false , | state | { state . match_string ("\"\"\"") . or_else (| state | { state . match_string ("\\\"\"\"") }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: ANY (state) }) }) . or_else (| state | { state . match_string ("\\\"\"\"") }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn string_content (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: string_content , | state | { state . atomic (:: pest :: Atomicity :: Atomic , | state | { state . repeat (| state | { self :: string_character (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn string_character (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: string_character , | state | { state . sequence (| state | { state . lookahead (false , | state | { state . match_string ("\"") . or_else (| state | { state . match_string ("\\") }) . or_else (| state | { self :: line_terminator (state) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: ANY (state) }) }) . or_else (| state | { state . sequence (| state | { state . match_string ("\\") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("\"") . or_else (| state | { state . match_string ("\\") }) . or_else (| state | { state . match_string ("/") }) . or_else (| state | { state . match_string ("b") }) . or_else (| state | { state . match_string ("f") }) . or_else (| state | { state . match_string ("n") }) . or_else (| state | { state . match_string ("r") }) . or_else (| state | { state . match_string ("t") }) }) }) }) . or_else (| state | { state . sequence (| state | { state . match_string ("\\u") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: unicode_scalar_value_hex (state) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn unicode_scalar_value_hex (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: unicode_scalar_value_hex , | state | { state . sequence (| state | { state . lookahead (false , | state | { state . sequence (| state | { state . match_insensitive ("d") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_range ('8' .. '9') . or_else (| state | { state . match_range ('a' .. 'f') }) . or_else (| state | { state . match_range ('A' .. 'F') }) }) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: ASCII_HEX_DIGIT (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: ASCII_HEX_DIGIT (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: ASCII_HEX_DIGIT (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: ASCII_HEX_DIGIT (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn boolean (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: boolean , | state | { state . match_string ("true") . or_else (| state | { state . match_string ("false") }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn null (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: null , | state | { state . match_string ("null") }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn enum_value (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . atomic (:: pest :: Atomicity :: CompoundAtomic , | state | { state . rule (Rule :: enum_value , | state | { state . sequence (| state | { state . lookahead (false , | state | { self :: boolean (state) . or_else (| state | { self :: null (state) }) }) . and_then (| state | { self :: name (state) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn const_list (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: const_list , | state | { state . sequence (| state | { state . match_string ("[") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: const_value (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: const_value (state) }) }) }) }) }) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("]") }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn list (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: list , | state | { state . sequence (| state | { state . match_string ("[") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: value (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: value (state) }) }) }) }) }) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("]") }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn const_object (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: const_object , | state | { state . sequence (| state | { state . match_string ("{") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: const_object_field (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: const_object_field (state) }) }) }) }) }) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("}") }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn object (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: object , | state | { state . sequence (| state | { state . match_string ("{") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: object_field (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: object_field (state) }) }) }) }) }) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("}") }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn const_object_field (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: const_object_field , | state | { state . sequence (| state | { self :: name (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string (":") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: const_value (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn object_field (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: object_field , | state | { state . sequence (| state | { self :: name (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string (":") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: value (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn const_directives (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: const_directives , | state | { state . sequence (| state | { self :: const_directive (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: const_directive (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: const_directive (state) }) }) }) }) }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn directives (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: directives , | state | { state . sequence (| state | { self :: directive (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: directive (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: directive (state) }) }) }) }) }) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn const_directive (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: const_directive , | state | { state . sequence (| state | { state . match_string ("@") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: const_arguments (state) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn directive (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: directive , | state | { state . sequence (| state | { state . match_string ("@") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: name (state) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . optional (| state | { self :: arguments (state) }) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn const_arguments (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: const_arguments , | state | { state . sequence (| state | { state . match_string ("(") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { self :: const_argument (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: const_argument (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: const_argument (state) }) }) }) }) }) }) }) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string (")") }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn arguments (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: arguments , | state | { state . sequence (| state | { state . match_string ("(") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { self :: argument (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { self :: argument (state) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { self :: argument (state) }) }) }) }) }) }) }) }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string (")") }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn const_argument (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: const_argument , | state | { state . sequence (| state | { self :: name (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string (":") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: const_value (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn argument (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: argument , | state | { state . sequence (| state | { self :: name (state) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string (":") }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { self :: value (state) }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn name_start (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: name_start , | state | { state . atomic (:: pest :: Atomicity :: Atomic , | state | { self :: ASCII_ALPHA (state) . or_else (| state | { state . match_string ("_") }) }) }) } # [inline] # [allow (non_snake_case , unused_variables)] pub fn name (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: name , | state | { state . atomic (:: pest :: Atomicity :: Atomic , | state | { state . sequence (| state | { self :: name_start (state) . and_then (| state | { state . repeat (| state | { self :: ASCII_ALPHA (state) . or_else (| state | { self :: ASCII_DIGIT (state) }) . or_else (| state | { state . match_string ("_") }) }) }) }) }) }) } # [inline] # [allow (dead_code , non_snake_case , unused_variables)] pub fn ANY (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . skip (1) } # [inline] # [allow (dead_code , non_snake_case , unused_variables)] pub fn EOI (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . rule (Rule :: EOI , | state | state . end_of_input ()) } # [inline] # [allow (dead_code , non_snake_case , unused_variables)] pub fn SOI (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . start_of_input () } # [inline] # [allow (dead_code , non_snake_case , unused_variables)] pub fn ASCII_DIGIT (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . match_range ('0' ..'9') } # [inline] # [allow (dead_code , non_snake_case , unused_variables)] pub fn ASCII_NONZERO_DIGIT (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . match_range ('1' ..'9') } # [inline] # [allow (dead_code , non_snake_case , unused_variables)] pub fn ASCII_HEX_DIGIT (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . match_range ('0' ..'9') . or_else (| state | state . match_range ('a' ..'f')) . or_else (| state | state . match_range ('A' ..'F')) } # [inline] # [allow (dead_code , non_snake_case , unused_variables)] pub fn ASCII_ALPHA (state : :: std :: boxed :: Box < :: pest :: ParserState < Rule >>) -> :: pest :: ParseResult < :: std :: boxed :: Box < :: pest :: ParserState < Rule >> > { state . match_range ('a' ..'z') . or_else (| state | state . match_range ('A' ..'Z')) } } pub use self :: visible :: * ; } :: pest :: state (input , | state | { match rule { Rule :: WHITESPACE => rules :: WHITESPACE (state) , Rule :: COMMENT => rules :: COMMENT (state) , Rule :: line_terminator => rules :: line_terminator (state) , Rule :: executable_document => rules :: executable_document (state) , Rule :: executable_definition => rules :: executable_definition (state) , Rule :: operation_definition => rules :: operation_definition (state) , Rule :: named_operation_definition => rules :: named_operation_definition (state) , Rule :: variable_definitions => rules :: variable_definitions (state) , Rule :: variable_definition => rules :: variable_definition (state) , Rule :: selection_set => rules :: selection_set (state) , Rule :: selection => rules :: selection (state) , Rule :: field => rules :: field (state) , Rule :: alias => rules :: alias (state) , Rule :: fragment_spread => rules :: fragment_spread (state) , Rule :: inline_fragment => rules :: inline_fragment (state) , Rule :: fragment_definition => rules :: fragment_definition (state) , Rule :: type_condition => rules :: type_condition (state) , Rule :: service_document => rules :: service_document (state) , Rule :: type_system_definition => rules :: type_system_definition (state) , Rule :: schema_definition => rules :: schema_definition (state) , Rule :: operation_type_definition => rules :: operation_type_definition (state) , Rule :: type_definition => rules :: type_definition (state) , Rule :: scalar_type => rules :: scalar_type (state) , Rule :: object_type => rules :: object_type (state) , Rule :: implements_interfaces => rules :: implements_interfaces (state) , Rule :: interface_type => rules :: interface_type (state) , Rule :: fields_definition => rules :: fields_definition (state) , Rule :: field_definition => rules :: field_definition (state) , Rule :: union_type => rules :: union_type (state) , Rule :: union_member_types => rules :: union_member_types (state) , Rule :: enum_type => rules :: enum_type (state) , Rule :: enum_values => rules :: enum_values (state) , Rule :: enum_value_definition => rules :: enum_value_definition (state) , Rule :: input_object_type => rules :: input_object_type (state) , Rule :: input_fields_definition => rules :: input_fields_definition (state) , Rule :: extend => rules :: extend (state) , Rule :: directive_definition => rules :: directive_definition (state) , Rule :: directive_locations => rules :: directive_locations (state) , Rule :: directive_location => rules :: directive_location (state) , Rule :: arguments_definition => rules :: arguments_definition (state) , Rule :: input_value_definition => rules :: input_value_definition (state) , Rule :: operation_type => rules :: operation_type (state) , Rule :: default_value => rules :: default_value (state) , Rule :: type_ => rules :: type_ (state) , Rule :: const_value => rules :: const_value (state) , Rule :: value => rules :: value (state) , Rule :: variable => rules :: variable (state) , Rule :: number => rules :: number (state) , Rule :: float => rules :: float (state) , Rule :: fractional => rules :: fractional (state) , Rule :: exponent => rules :: exponent (state) , Rule :: int => rules :: int (state) , Rule :: string => rules :: string (state) , Rule :: block_string_content => rules :: block_string_content (state) , Rule :: block_string_character => rules :: block_string_character (state) , Rule :: string_content => rules :: string_content (state) , Rule :: string_character => rules :: string_character (state) , Rule :: unicode_scalar_value_hex => rules :: unicode_scalar_value_hex (state) , Rule :: boolean => rules :: boolean (state) , Rule :: null => rules :: null (state) , Rule :: enum_value => rules :: enum_value (state) , Rule :: const_list => rules :: const_list (state) , Rule :: list => rules :: list (state) , Rule :: const_object => rules :: const_object (state) , Rule :: object => rules :: object (state) , Rule :: const_object_field => rules :: const_object_field (state) , Rule :: object_field => rules :: object_field (state) , Rule :: const_directives => rules :: const_directives (state) , Rule :: directives => rules :: directives (state) , Rule :: const_directive => rules :: const_directive (state) , Rule :: directive => rules :: directive (state) , Rule :: const_arguments => rules :: const_arguments (state) , Rule :: arguments => rules :: arguments (state) , Rule :: const_argument => rules :: const_argument (state) , Rule :: argument => rules :: argument (state) , Rule :: name_start => rules :: name_start (state) , Rule :: name => rules :: name (state) , Rule :: EOI => rules :: EOI (state) } }) } } \ No newline at end of file +#[allow(dead_code, non_camel_case_types, clippy::upper_case_acronyms)] +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub enum Rule { + EOI, + WHITESPACE, + COMMENT, + line_terminator, + executable_document, + executable_definition, + operation_definition, + named_operation_definition, + variable_definitions, + variable_definition, + selection_set, + selection, + field, + alias, + fragment_spread, + inline_fragment, + fragment_definition, + type_condition, + service_document, + type_system_definition, + schema_definition, + operation_type_definition, + type_definition, + scalar_type, + object_type, + implements_interfaces, + interface_type, + fields_definition, + field_definition, + union_type, + union_member_types, + enum_type, + enum_values, + enum_value_definition, + input_object_type, + input_fields_definition, + extend, + directive_definition, + directive_locations, + directive_location, + arguments_definition, + input_value_definition, + operation_type, + default_value, + type_, + const_value, + value, + variable, + number, + float, + fractional, + exponent, + int, + string, + block_string_content, + block_string_character, + string_content, + string_character, + unicode_scalar_value_hex, + boolean, + null, + enum_value, + const_list, + list, + const_object, + object, + const_object_field, + object_field, + const_directives, + directives, + const_directive, + directive, + const_arguments, + arguments, + const_argument, + argument, + name_start, + name, +} +#[allow(clippy::all)] +impl ::pest::Parser for GraphQLParser { + fn parse<'i>( + rule: Rule, + input: &'i str, + ) -> ::std::result::Result<::pest::iterators::Pairs<'i, Rule>, ::pest::error::Error> { + mod rules { + #![allow(clippy::upper_case_acronyms)] + pub mod hidden { + use super::super::Rule; + #[inline] + #[allow(dead_code, non_snake_case, unused_variables)] + pub fn skip( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + if state.atomicity() == ::pest::Atomicity::NonAtomic { + state.sequence(|state| { + state + .repeat(|state| super::visible::WHITESPACE(state)) + .and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::visible::COMMENT(state) + .and_then(|state| state.repeat(|state| super::visible::WHITESPACE(state))) + }) + }) + }) + }) + } else { + Ok(state) + } + } + } + pub mod visible { + use super::super::Rule; + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn WHITESPACE( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.atomic(::pest::Atomicity::Atomic, |state| { + state + .match_string(" ") + .or_else(|state| state.match_string(",")) + .or_else(|state| state.match_string("\t")) + .or_else(|state| state.match_string("\u{feff}")) + .or_else(|state| self::line_terminator(state)) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn COMMENT( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.atomic(::pest::Atomicity::Atomic, |state| { + state.sequence(|state| { + state.match_string("#").and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + state + .lookahead(false, |state| self::line_terminator(state)) + .and_then(|state| self::ANY(state)) + }) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn line_terminator( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::line_terminator, |state| { + state.atomic(::pest::Atomicity::Atomic, |state| { + state + .match_string("\r\n") + .or_else(|state| state.match_string("\r")) + .or_else(|state| state.match_string("\n")) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn executable_document( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::executable_document, |state| { + state.sequence(|state| { + self::SOI(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + self::executable_definition(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::executable_definition(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::executable_definition(state)) + }) + }) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::EOI(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn executable_definition( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::executable_definition, |state| { + self::operation_definition(state).or_else(|state| self::fragment_definition(state)) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn operation_definition( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::operation_definition, |state| { + self::named_operation_definition(state).or_else(|state| self::selection_set(state)) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn named_operation_definition( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::named_operation_definition, |state| { + state.sequence(|state| { + self::operation_type(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::name(state))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::variable_definitions(state))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::directives(state))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::selection_set(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn variable_definitions( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::variable_definitions, |state| { + state.sequence(|state| { + state + .match_string("(") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::variable_definition(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::variable_definition(state)) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string(")")) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn variable_definition( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::variable_definition, |state| { + state.sequence(|state| { + self::variable(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string(":")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::type_(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::directives(state))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::default_value(state))) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn selection_set( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::selection_set, |state| { + state.sequence(|state| { + state + .match_string("{") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + self::selection(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::selection(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::selection(state)) + }) + }) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("}")) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn selection( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::selection, |state| { + self::field(state) + .or_else(|state| self::inline_fragment(state)) + .or_else(|state| self::fragment_spread(state)) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn field( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::field, |state| { + state.sequence(|state| { + state + .optional(|state| self::alias(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::arguments(state))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::directives(state))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::selection_set(state))) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn alias( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::alias, |state| { + state.sequence(|state| { + self::name(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string(":")) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn fragment_spread( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::fragment_spread, |state| { + state.sequence(|state| { + state + .match_string("...") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.lookahead(false, |state| self::type_condition(state))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::directives(state))) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn inline_fragment( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::inline_fragment, |state| { + state.sequence(|state| { + state + .match_string("...") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::type_condition(state))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::directives(state))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::selection_set(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn fragment_definition( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::fragment_definition, |state| { + state.sequence(|state| { + state + .match_string("fragment") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::type_condition(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::directives(state))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::selection_set(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn type_condition( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.atomic(::pest::Atomicity::CompoundAtomic, |state| { + state.rule(Rule::type_condition, |state| { + state.sequence(|state| { + state + .match_string("on") + .and_then(|state| { + state.sequence(|state| { + self::WHITESPACE(state) + .and_then(|state| state.repeat(|state| self::WHITESPACE(state))) + }) + }) + .and_then(|state| self::name(state)) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn service_document( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::service_document, |state| { + state.sequence(|state| { + self::SOI(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + self::type_system_definition(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::type_system_definition(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::type_system_definition(state)) + }) + }) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::EOI(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn type_system_definition( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::type_system_definition, |state| { + self::schema_definition(state) + .or_else(|state| self::type_definition(state)) + .or_else(|state| self::directive_definition(state)) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn schema_definition( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::schema_definition, |state| { + state + .sequence(|state| { + state + .match_string("schema") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::const_directives(state))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("{")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + self::operation_type_definition(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::operation_type_definition(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::operation_type_definition(state)) + }) + }) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("}")) + }) + .or_else(|state| { + state.sequence(|state| { + self::extend(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("schema")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state + .sequence(|state| { + state + .optional(|state| self::const_directives(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("{")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + self::operation_type_definition(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::operation_type_definition(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| { + self::operation_type_definition(state) + }) + }) + }) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("}")) + }) + .or_else(|state| self::const_directives(state)) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn operation_type_definition( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::operation_type_definition, |state| { + state.sequence(|state| { + self::operation_type(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string(":")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn type_definition( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::type_definition, |state| { + self::scalar_type(state) + .or_else(|state| self::object_type(state)) + .or_else(|state| self::interface_type(state)) + .or_else(|state| self::union_type(state)) + .or_else(|state| self::enum_type(state)) + .or_else(|state| self::input_object_type(state)) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn scalar_type( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::scalar_type, |state| { + state + .sequence(|state| { + state + .optional(|state| self::string(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("scalar")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::const_directives(state))) + }) + .or_else(|state| { + state.sequence(|state| { + self::extend(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("scalar")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::const_directives(state)) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn object_type( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::object_type, |state| { + state + .sequence(|state| { + state + .optional(|state| self::string(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("type")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::implements_interfaces(state))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::const_directives(state))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::fields_definition(state))) + }) + .or_else(|state| { + state.sequence(|state| { + self::extend(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("type")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state + .sequence(|state| { + state + .optional(|state| self::implements_interfaces(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state + .sequence(|state| { + state + .optional(|state| self::const_directives(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::fields_definition(state)) + }) + .or_else(|state| self::const_directives(state)) + }) + }) + .or_else(|state| self::implements_interfaces(state)) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn implements_interfaces( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::implements_interfaces, |state| { + state.sequence(|state| { + state + .match_string("implements") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| state.match_string("&"))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + state + .sequence(|state| { + state + .match_string("&") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + }) + .and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| { + state.sequence(|state| { + state + .match_string("&") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + }) + }) + }) + }) + }) + }) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn interface_type( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::interface_type, |state| { + state + .sequence(|state| { + state + .optional(|state| self::string(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("interface")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::implements_interfaces(state))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::const_directives(state))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::fields_definition(state))) + }) + .or_else(|state| { + state.sequence(|state| { + self::extend(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("interface")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::implements_interfaces(state))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state + .sequence(|state| { + state + .optional(|state| self::const_directives(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::fields_definition(state)) + }) + .or_else(|state| self::const_directives(state)) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn fields_definition( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::fields_definition, |state| { + state.sequence(|state| { + state + .match_string("{") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + self::field_definition(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::field_definition(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::field_definition(state)) + }) + }) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("}")) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn field_definition( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::field_definition, |state| { + state.sequence(|state| { + state + .optional(|state| self::string(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::arguments_definition(state))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string(":")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::type_(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::const_directives(state))) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn union_type( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::union_type, |state| { + state + .sequence(|state| { + state + .optional(|state| self::string(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("union")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::const_directives(state))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::union_member_types(state))) + }) + .or_else(|state| { + state.sequence(|state| { + self::extend(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("union")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state + .sequence(|state| { + state + .optional(|state| self::const_directives(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::union_member_types(state)) + }) + .or_else(|state| self::const_directives(state)) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn union_member_types( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::union_member_types, |state| { + state.sequence(|state| { + state + .match_string("=") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| state.match_string("|"))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + state + .sequence(|state| { + state + .match_string("|") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + }) + .and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| { + state.sequence(|state| { + state + .match_string("|") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + }) + }) + }) + }) + }) + }) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn enum_type( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::enum_type, |state| { + state + .sequence(|state| { + state + .optional(|state| self::string(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("enum")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::const_directives(state))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::enum_values(state))) + }) + .or_else(|state| { + state.sequence(|state| { + self::extend(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("enum")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state + .sequence(|state| { + state + .optional(|state| self::const_directives(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::enum_values(state)) + }) + .or_else(|state| self::const_directives(state)) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn enum_values( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::enum_values, |state| { + state.sequence(|state| { + state + .match_string("{") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + self::enum_value_definition(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::enum_value_definition(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::enum_value_definition(state)) + }) + }) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("}")) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn enum_value_definition( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::enum_value_definition, |state| { + state.sequence(|state| { + state + .optional(|state| self::string(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::enum_value(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::const_directives(state))) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn input_object_type( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::input_object_type, |state| { + state + .sequence(|state| { + state + .optional(|state| self::string(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("input")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::const_directives(state))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::input_fields_definition(state))) + }) + .or_else(|state| { + state.sequence(|state| { + self::extend(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("input")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state + .sequence(|state| { + state + .optional(|state| self::const_directives(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::input_fields_definition(state)) + }) + .or_else(|state| self::const_directives(state)) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn input_fields_definition( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::input_fields_definition, |state| { + state.sequence(|state| { + state + .match_string("{") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + self::input_value_definition(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::input_value_definition(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::input_value_definition(state)) + }) + }) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("}")) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn extend( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::extend, |state| state.match_string("extend")) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn directive_definition( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::directive_definition, |state| { + state.sequence(|state| { + state + .optional(|state| self::string(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("directive")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("@")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::arguments_definition(state))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("on")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::directive_locations(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn directive_locations( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::directive_locations, |state| { + state.sequence(|state| { + state + .optional(|state| state.match_string("|")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::directive_location(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + state + .sequence(|state| { + state + .match_string("|") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::directive_location(state)) + }) + .and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| { + state.sequence(|state| { + state + .match_string("|") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::directive_location(state)) + }) + }) + }) + }) + }) + }) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn directive_location( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::directive_location, |state| { + state + .match_string("QUERY") + .or_else(|state| state.match_string("MUTATION")) + .or_else(|state| state.match_string("SUBSCRIPTION")) + .or_else(|state| state.match_string("FIELD_DEFINITION")) + .or_else(|state| state.match_string("FIELD")) + .or_else(|state| state.match_string("FRAGMENT_DEFINITION")) + .or_else(|state| state.match_string("FRAGMENT_SPREAD")) + .or_else(|state| state.match_string("INLINE_FRAGMENT")) + .or_else(|state| state.match_string("VARIABLE_DEFINITION")) + .or_else(|state| state.match_string("SCHEMA")) + .or_else(|state| state.match_string("SCALAR")) + .or_else(|state| state.match_string("OBJECT")) + .or_else(|state| state.match_string("ARGUMENT_DEFINITION")) + .or_else(|state| state.match_string("INTERFACE")) + .or_else(|state| state.match_string("UNION")) + .or_else(|state| state.match_string("ENUM_VALUE")) + .or_else(|state| state.match_string("ENUM")) + .or_else(|state| state.match_string("INPUT_OBJECT")) + .or_else(|state| state.match_string("INPUT_FIELD_DEFINITION")) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn arguments_definition( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::arguments_definition, |state| { + state.sequence(|state| { + state + .match_string("(") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + self::input_value_definition(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::input_value_definition(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::input_value_definition(state)) + }) + }) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string(")")) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn input_value_definition( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::input_value_definition, |state| { + state.sequence(|state| { + state + .optional(|state| self::string(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string(":")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::type_(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::default_value(state))) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::const_directives(state))) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn operation_type( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::operation_type, |state| { + state + .match_string("query") + .or_else(|state| state.match_string("mutation")) + .or_else(|state| state.match_string("subscription")) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn default_value( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::default_value, |state| { + state.sequence(|state| { + state + .match_string("=") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::const_value(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn type_( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::type_, |state| { + state.atomic(::pest::Atomicity::Atomic, |state| { + state.sequence(|state| { + self::name(state) + .or_else(|state| { + state.sequence(|state| { + state + .match_string("[") + .and_then(|state| self::type_(state)) + .and_then(|state| state.match_string("]")) + }) + }) + .and_then(|state| state.optional(|state| state.match_string("!"))) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn const_value( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::const_value, |state| { + self::number(state) + .or_else(|state| self::string(state)) + .or_else(|state| self::boolean(state)) + .or_else(|state| self::null(state)) + .or_else(|state| self::enum_value(state)) + .or_else(|state| self::const_list(state)) + .or_else(|state| self::const_object(state)) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn value( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::value, |state| { + self::variable(state) + .or_else(|state| self::number(state)) + .or_else(|state| self::string(state)) + .or_else(|state| self::boolean(state)) + .or_else(|state| self::null(state)) + .or_else(|state| self::enum_value(state)) + .or_else(|state| self::list(state)) + .or_else(|state| self::object(state)) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn variable( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::variable, |state| { + state.sequence(|state| { + state + .match_string("$") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn number( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::number, |state| { + state.atomic(::pest::Atomicity::Atomic, |state| { + state.sequence(|state| { + self::float(state) + .or_else(|state| self::int(state)) + .and_then(|state| state.lookahead(false, |state| self::name_start(state))) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn float( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::float, |state| { + state.sequence(|state| { + self::int(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state + .sequence(|state| { + self::fractional(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::exponent(state)) + }) + .or_else(|state| self::fractional(state)) + .or_else(|state| self::exponent(state)) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn fractional( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::fractional, |state| { + state.sequence(|state| { + state + .match_string(".") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::ASCII_DIGIT(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::ASCII_DIGIT(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| self::ASCII_DIGIT(state)) + }) + }) + }) + }) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn exponent( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::exponent, |state| { + state.sequence(|state| { + state + .match_string("E") + .or_else(|state| state.match_string("e")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.optional(|state| { + state + .match_string("+") + .or_else(|state| state.match_string("-")) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::ASCII_DIGIT(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::ASCII_DIGIT(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| self::ASCII_DIGIT(state)) + }) + }) + }) + }) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn int( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::int, |state| { + state.sequence(|state| { + state + .optional(|state| state.match_string("-")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.match_string("0").or_else(|state| { + state.sequence(|state| { + self::ASCII_NONZERO_DIGIT(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::ASCII_DIGIT(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::ASCII_DIGIT(state)) + }) + }) + }) + }) + }) + }) + }) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn string( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.atomic(::pest::Atomicity::CompoundAtomic, |state| { + state.rule(Rule::string, |state| { + state + .sequence(|state| { + state + .match_string("\"\"\"") + .and_then(|state| self::block_string_content(state)) + .and_then(|state| state.match_string("\"\"\"")) + }) + .or_else(|state| { + state.sequence(|state| { + state + .match_string("\"") + .and_then(|state| self::string_content(state)) + .and_then(|state| state.match_string("\"")) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn block_string_content( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::block_string_content, |state| { + state.atomic(::pest::Atomicity::Atomic, |state| { + state.repeat(|state| self::block_string_character(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn block_string_character( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::block_string_character, |state| { + state + .sequence(|state| { + state + .lookahead(false, |state| { + state + .match_string("\"\"\"") + .or_else(|state| state.match_string("\\\"\"\"")) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::ANY(state)) + }) + .or_else(|state| state.match_string("\\\"\"\"")) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn string_content( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::string_content, |state| { + state.atomic(::pest::Atomicity::Atomic, |state| { + state.repeat(|state| self::string_character(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn string_character( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::string_character, |state| { + state + .sequence(|state| { + state + .lookahead(false, |state| { + state + .match_string("\"") + .or_else(|state| state.match_string("\\")) + .or_else(|state| self::line_terminator(state)) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::ANY(state)) + }) + .or_else(|state| { + state.sequence(|state| { + state + .match_string("\\") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state + .match_string("\"") + .or_else(|state| state.match_string("\\")) + .or_else(|state| state.match_string("/")) + .or_else(|state| state.match_string("b")) + .or_else(|state| state.match_string("f")) + .or_else(|state| state.match_string("n")) + .or_else(|state| state.match_string("r")) + .or_else(|state| state.match_string("t")) + }) + }) + }) + .or_else(|state| { + state.sequence(|state| { + state + .match_string("\\u") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::unicode_scalar_value_hex(state)) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn unicode_scalar_value_hex( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::unicode_scalar_value_hex, |state| { + state.sequence(|state| { + state + .lookahead(false, |state| { + state.sequence(|state| { + state + .match_insensitive("d") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state + .match_range('8'..'9') + .or_else(|state| state.match_range('a'..'f')) + .or_else(|state| state.match_range('A'..'F')) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::ASCII_HEX_DIGIT(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::ASCII_HEX_DIGIT(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::ASCII_HEX_DIGIT(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::ASCII_HEX_DIGIT(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn boolean( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::boolean, |state| { + state + .match_string("true") + .or_else(|state| state.match_string("false")) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn null( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::null, |state| state.match_string("null")) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn enum_value( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.atomic(::pest::Atomicity::CompoundAtomic, |state| { + state.rule(Rule::enum_value, |state| { + state.sequence(|state| { + state + .lookahead(false, |state| { + self::boolean(state).or_else(|state| self::null(state)) + }) + .and_then(|state| self::name(state)) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn const_list( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::const_list, |state| { + state.sequence(|state| { + state + .match_string("[") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::const_value(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| self::const_value(state)) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("]")) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn list( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::list, |state| { + state.sequence(|state| { + state + .match_string("[") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::value(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| self::value(state)) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("]")) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn const_object( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::const_object, |state| { + state.sequence(|state| { + state + .match_string("{") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::const_object_field(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::const_object_field(state)) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("}")) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn object( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::object, |state| { + state.sequence(|state| { + state + .match_string("{") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::object_field(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| self::object_field(state)) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("}")) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn const_object_field( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::const_object_field, |state| { + state.sequence(|state| { + self::name(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string(":")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::const_value(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn object_field( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::object_field, |state| { + state.sequence(|state| { + self::name(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string(":")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::value(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn const_directives( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::const_directives, |state| { + state.sequence(|state| { + self::const_directive(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::const_directive(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::const_directive(state)) + }) + }) + }) + }) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn directives( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::directives, |state| { + state.sequence(|state| { + self::directive(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::directive(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| self::directive(state)) + }) + }) + }) + }) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn const_directive( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::const_directive, |state| { + state.sequence(|state| { + state + .match_string("@") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::const_arguments(state))) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn directive( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::directive, |state| { + state.sequence(|state| { + state + .match_string("@") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::name(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::arguments(state))) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn const_arguments( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::const_arguments, |state| { + state.sequence(|state| { + state + .match_string("(") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + self::const_argument(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::const_argument(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::const_argument(state)) + }) + }) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string(")")) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn arguments( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::arguments, |state| { + state.sequence(|state| { + state + .match_string("(") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + self::argument(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::argument(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| self::argument(state)) + }) + }) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string(")")) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn const_argument( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::const_argument, |state| { + state.sequence(|state| { + self::name(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string(":")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::const_value(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn argument( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::argument, |state| { + state.sequence(|state| { + self::name(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string(":")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::value(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn name_start( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::name_start, |state| { + state.atomic(::pest::Atomicity::Atomic, |state| { + self::ASCII_ALPHA(state).or_else(|state| state.match_string("_")) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn name( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::name, |state| { + state.atomic(::pest::Atomicity::Atomic, |state| { + state.sequence(|state| { + self::name_start(state).and_then(|state| { + state.repeat(|state| { + self::ASCII_ALPHA(state) + .or_else(|state| self::ASCII_DIGIT(state)) + .or_else(|state| state.match_string("_")) + }) + }) + }) + }) + }) + } + #[inline] + #[allow(dead_code, non_snake_case, unused_variables)] + pub fn ANY( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.skip(1) + } + #[inline] + #[allow(dead_code, non_snake_case, unused_variables)] + pub fn EOI( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.rule(Rule::EOI, |state| state.end_of_input()) + } + #[inline] + #[allow(dead_code, non_snake_case, unused_variables)] + pub fn SOI( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.start_of_input() + } + #[inline] + #[allow(dead_code, non_snake_case, unused_variables)] + pub fn ASCII_DIGIT( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.match_range('0'..'9') + } + #[inline] + #[allow(dead_code, non_snake_case, unused_variables)] + pub fn ASCII_NONZERO_DIGIT( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state.match_range('1'..'9') + } + #[inline] + #[allow(dead_code, non_snake_case, unused_variables)] + pub fn ASCII_HEX_DIGIT( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state + .match_range('0'..'9') + .or_else(|state| state.match_range('a'..'f')) + .or_else(|state| state.match_range('A'..'F')) + } + #[inline] + #[allow(dead_code, non_snake_case, unused_variables)] + pub fn ASCII_ALPHA( + state: ::std::boxed::Box<::pest::ParserState>, + ) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState>> { + state + .match_range('a'..'z') + .or_else(|state| state.match_range('A'..'Z')) + } + } + pub use self::visible::*; + } + ::pest::state(input, |state| match rule { + Rule::WHITESPACE => rules::WHITESPACE(state), + Rule::COMMENT => rules::COMMENT(state), + Rule::line_terminator => rules::line_terminator(state), + Rule::executable_document => rules::executable_document(state), + Rule::executable_definition => rules::executable_definition(state), + Rule::operation_definition => rules::operation_definition(state), + Rule::named_operation_definition => rules::named_operation_definition(state), + Rule::variable_definitions => rules::variable_definitions(state), + Rule::variable_definition => rules::variable_definition(state), + Rule::selection_set => rules::selection_set(state), + Rule::selection => rules::selection(state), + Rule::field => rules::field(state), + Rule::alias => rules::alias(state), + Rule::fragment_spread => rules::fragment_spread(state), + Rule::inline_fragment => rules::inline_fragment(state), + Rule::fragment_definition => rules::fragment_definition(state), + Rule::type_condition => rules::type_condition(state), + Rule::service_document => rules::service_document(state), + Rule::type_system_definition => rules::type_system_definition(state), + Rule::schema_definition => rules::schema_definition(state), + Rule::operation_type_definition => rules::operation_type_definition(state), + Rule::type_definition => rules::type_definition(state), + Rule::scalar_type => rules::scalar_type(state), + Rule::object_type => rules::object_type(state), + Rule::implements_interfaces => rules::implements_interfaces(state), + Rule::interface_type => rules::interface_type(state), + Rule::fields_definition => rules::fields_definition(state), + Rule::field_definition => rules::field_definition(state), + Rule::union_type => rules::union_type(state), + Rule::union_member_types => rules::union_member_types(state), + Rule::enum_type => rules::enum_type(state), + Rule::enum_values => rules::enum_values(state), + Rule::enum_value_definition => rules::enum_value_definition(state), + Rule::input_object_type => rules::input_object_type(state), + Rule::input_fields_definition => rules::input_fields_definition(state), + Rule::extend => rules::extend(state), + Rule::directive_definition => rules::directive_definition(state), + Rule::directive_locations => rules::directive_locations(state), + Rule::directive_location => rules::directive_location(state), + Rule::arguments_definition => rules::arguments_definition(state), + Rule::input_value_definition => rules::input_value_definition(state), + Rule::operation_type => rules::operation_type(state), + Rule::default_value => rules::default_value(state), + Rule::type_ => rules::type_(state), + Rule::const_value => rules::const_value(state), + Rule::value => rules::value(state), + Rule::variable => rules::variable(state), + Rule::number => rules::number(state), + Rule::float => rules::float(state), + Rule::fractional => rules::fractional(state), + Rule::exponent => rules::exponent(state), + Rule::int => rules::int(state), + Rule::string => rules::string(state), + Rule::block_string_content => rules::block_string_content(state), + Rule::block_string_character => rules::block_string_character(state), + Rule::string_content => rules::string_content(state), + Rule::string_character => rules::string_character(state), + Rule::unicode_scalar_value_hex => rules::unicode_scalar_value_hex(state), + Rule::boolean => rules::boolean(state), + Rule::null => rules::null(state), + Rule::enum_value => rules::enum_value(state), + Rule::const_list => rules::const_list(state), + Rule::list => rules::list(state), + Rule::const_object => rules::const_object(state), + Rule::object => rules::object(state), + Rule::const_object_field => rules::const_object_field(state), + Rule::object_field => rules::object_field(state), + Rule::const_directives => rules::const_directives(state), + Rule::directives => rules::directives(state), + Rule::const_directive => rules::const_directive(state), + Rule::directive => rules::directive(state), + Rule::const_arguments => rules::const_arguments(state), + Rule::arguments => rules::arguments(state), + Rule::const_argument => rules::const_argument(state), + Rule::argument => rules::argument(state), + Rule::name_start => rules::name_start(state), + Rule::name => rules::name(state), + Rule::EOI => rules::EOI(state), + }) + } +} diff --git a/parser/tests/codegen.rs b/parser/tests/codegen.rs index 193573430..f3fa629dc 100644 --- a/parser/tests/codegen.rs +++ b/parser/tests/codegen.rs @@ -3,3 +3,70 @@ //! //! To avoid that, let's just dump generated code to string into this //! repository, and add a test that checks that the code is fresh. +use std::{ + fs, + io::Write, + process::{Command, Stdio}, +}; + +const PREAMBLE: &str = r#" +//! This is @generated code, do not edit by hand. +//! See `graphql.pest` and `tests/codegen.rs`. +#![allow(unused_attributes)] +use super::GraphQLParser; +"#; + +#[test] +fn generated_code_is_fresh() { + let input = format!( + r###" +#[derive(Parser)] +#[grammar = r#"graphql.pest"#] +struct GraphQLParser; +"###, + ) + .parse::() + .unwrap(); + + let tokens = pest_generator::derive_parser(input.into(), false); + let current = + String::from_utf8(fs::read("./src/parse/generated.rs").unwrap_or_default()).unwrap(); + + let current_content = match current.len() > PREAMBLE.len() { + true => ¤t[PREAMBLE.len()..], + false => current.as_str(), + }; + + let new = tokens.to_string(); + let is_up_to_date = normalize(¤t_content) == normalize(&new); + + if is_up_to_date { + return; + } + + let code = format!("{}\n{}", PREAMBLE, reformat(&new)); + fs::write("./src/parse/generated.rs", code).unwrap(); + panic!("Generated code in the repository is outdated, updating..."); +} + +fn reformat(code: &str) -> String { + let mut cmd = Command::new("rustfmt") + .args(&["--config", "tab_spaces=2"]) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .unwrap(); + + cmd.stdin + .take() + .unwrap() + .write_all(code.as_bytes()) + .unwrap(); + let output = cmd.wait_with_output().unwrap(); + assert!(output.status.success()); + String::from_utf8(output.stdout).unwrap() +} + +fn normalize(code: &str) -> String { + code.replace(|c: char| c.is_ascii_whitespace() || "{},".contains(c), "") +} From a4c6b368f00f1e592b2d954f42927b403c39e7cb Mon Sep 17 00:00:00 2001 From: Sunli Date: Sun, 20 Aug 2023 12:11:16 +0800 Subject: [PATCH 19/20] Update Cargo.toml --- Cargo.toml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 8ee16fcd3..2e6d8c6fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,13 @@ async-stream = "0.3.0" async-trait.workspace = true bytes.workspace = true fnv = "1.0.7" -futures-util = { workspace = true, features = ["std", "io", "sink"] } +futures-util = { workspace = true, features = [ + "std", + "io", + "sink", + "async-await", + "async-await-macro", +] } http = "0.2.3" indexmap.workspace = true mime = "0.3.15" From a02f6c78567be96f804329b34e75b69fa868e0e5 Mon Sep 17 00:00:00 2001 From: Sunli Date: Sat, 24 May 2025 11:31:40 +0800 Subject: [PATCH 20/20] Update book.yml --- .github/workflows/book.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/book.yml b/.github/workflows/book.yml index 8f97071a8..fbe390670 100644 --- a/.github/workflows/book.yml +++ b/.github/workflows/book.yml @@ -27,7 +27,7 @@ jobs: - name: Deploy uses: peaceiris/actions-gh-pages@v4 with: - deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }} + github_token: ${{ secrets.GITHUB_TOKEN }} allow_empty_commit: true keep_files: false publish_dir: gh-pages