├── .github └── workflows │ ├── code_coverage.yml │ └── rust.yml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── clippy.toml ├── codegen-for-async-graphql-renderer ├── Cargo.toml └── src │ ├── README.md │ ├── base │ ├── config.rs │ ├── context.rs │ ├── generator.rs │ ├── mod.rs │ └── utils.rs │ ├── document_wrapper │ ├── field_wrapper.rs │ ├── input_object_type_wrapper.rs │ ├── input_value_wrapper.rs │ ├── interface_type_wrapper.rs │ ├── mod.rs │ ├── mutation_type_wrapper.rs │ ├── mutations_type_wrapper.rs │ ├── object_type_wrapper.rs │ ├── scalar_type_wrapper.rs │ ├── subscription_root_type_wrapper.rs │ ├── subscription_type_wrapper.rs │ ├── type_wrapper.rs │ └── union_type_wrapper.rs │ ├── lib.rs │ └── renderer │ ├── input_object │ ├── mod.rs │ └── renderer.rs │ ├── interface │ ├── mod.rs │ └── renderer.rs │ ├── internal │ ├── dependencies.rs │ ├── field.rs │ └── mod.rs │ ├── mod.rs │ ├── mod_file │ ├── mod.rs │ ├── root_module_renderer.rs │ └── sub_module_renderer.rs │ ├── mutation │ ├── mod.rs │ └── renderer.rs │ ├── object_type │ ├── mod.rs │ └── renderer.rs │ ├── output.rs │ ├── save.rs │ ├── scalar │ ├── mod.rs │ └── renderer.rs │ ├── subscription │ ├── mod.rs │ └── renderer.rs │ └── union_type │ ├── mod.rs │ └── renderer.rs ├── docker-compose.yml ├── examples └── codegen-for-async-graphql-example │ ├── Cargo.toml │ ├── schema.graphql │ ├── src │ ├── main.rs │ └── models │ │ ├── input_object_type │ │ ├── create_friend_mutation_input.rs │ │ └── mod.rs │ │ ├── interface_type │ │ ├── mod.rs │ │ └── user.rs │ │ ├── mod.rs │ │ ├── mutations_type │ │ ├── mod.rs │ │ └── mutation.rs │ │ ├── object_type │ │ ├── create_friend_mutation_payload.rs │ │ ├── friend.rs │ │ ├── friend_connection.rs │ │ ├── me.rs │ │ ├── mod.rs │ │ ├── notification.rs │ │ └── query.rs │ │ ├── scalar_type │ │ ├── mod.rs │ │ └── url.rs │ │ ├── subscription_type │ │ ├── mod.rs │ │ └── subscription.rs │ │ └── union_type │ │ ├── mod.rs │ │ └── search_result.rs │ └── tests │ └── snapshots │ ├── introspection.json │ └── main.json ├── src ├── codegen.rs └── main.rs └── tests ├── queries └── introspection.graphql └── schemas ├── README.md ├── kitchen-sink.graphql ├── query.graphql ├── schema.graphql └── schema.json /.github/workflows/code_coverage.yml: -------------------------------------------------------------------------------- 1 | name: Code Coverage 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | 7 | jobs: 8 | cover: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v1 12 | - uses: actions-rs/toolchain@v1 13 | with: 14 | toolchain: stable 15 | override: true 16 | - name: Run cargo-tarpaulin 17 | uses: actions-rs/tarpaulin@v0.1 18 | with: 19 | version: "0.11.0" 20 | args: --all --all-features 21 | - name: Upload coverage to Codecov 22 | uses: codecov/codecov-action@v1 23 | with: 24 | token: ${{secrets.CODECOV_TOKEN}} 25 | - name: Archive code coverage results 26 | uses: actions/upload-artifact@v1 27 | with: 28 | name: code-coverage-report 29 | path: cobertura.xml 30 | -------------------------------------------------------------------------------- /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | name: Rust 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | branches: [master] 8 | 9 | env: 10 | CARGO_TERM_COLOR: always 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v2 18 | - name: Check format 19 | run: cargo fmt --all -- --check 20 | - name: Build 21 | run: cargo build --all --verbose 22 | - name: Run tests 23 | run: cargo test --all --verbose 24 | - name: Run clippy 25 | run: | 26 | cargo clippy -- \ 27 | -D clippy::all \ 28 | -D clippy::nursery \ 29 | -W clippy::pedantic 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /tmp 3 | tarpaulin-report.html 4 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "Inflector" 5 | version = "0.11.4" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" 8 | dependencies = [ 9 | "lazy_static", 10 | "regex", 11 | ] 12 | 13 | [[package]] 14 | name = "aho-corasick" 15 | version = "0.7.13" 16 | source = "registry+https://github.com/rust-lang/crates.io-index" 17 | checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86" 18 | dependencies = [ 19 | "memchr", 20 | ] 21 | 22 | [[package]] 23 | name = "anyhow" 24 | version = "1.0.31" 25 | source = "registry+https://github.com/rust-lang/crates.io-index" 26 | checksum = "85bb70cc08ec97ca5450e6eba421deeea5f172c0fc61f78b5357b2a8e8be195f" 27 | 28 | [[package]] 29 | name = "arrayref" 30 | version = "0.3.6" 31 | source = "registry+https://github.com/rust-lang/crates.io-index" 32 | checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" 33 | 34 | [[package]] 35 | name = "arrayvec" 36 | version = "0.5.1" 37 | source = "registry+https://github.com/rust-lang/crates.io-index" 38 | checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" 39 | 40 | [[package]] 41 | name = "async-attributes" 42 | version = "1.1.1" 43 | source = "registry+https://github.com/rust-lang/crates.io-index" 44 | checksum = "efd3d156917d94862e779f356c5acae312b08fd3121e792c857d7928c8088423" 45 | dependencies = [ 46 | "quote", 47 | "syn", 48 | ] 49 | 50 | [[package]] 51 | name = "async-graphql" 52 | version = "1.16.9" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "ce1f0183671a6222b0745fd9ee189e681883613876d3741aa2ffaec746c4b6dc" 55 | dependencies = [ 56 | "Inflector", 57 | "anyhow", 58 | "async-graphql-derive", 59 | "async-graphql-parser", 60 | "async-stream", 61 | "async-trait", 62 | "base64 0.12.3", 63 | "bson", 64 | "byteorder", 65 | "bytes", 66 | "chrono", 67 | "chrono-tz", 68 | "fnv", 69 | "futures", 70 | "http", 71 | "httparse", 72 | "indexmap", 73 | "itertools", 74 | "log", 75 | "mime", 76 | "multer", 77 | "once_cell", 78 | "parking_lot", 79 | "regex", 80 | "serde", 81 | "serde_derive", 82 | "serde_json", 83 | "slab", 84 | "spin", 85 | "tempfile", 86 | "thiserror", 87 | "tracing", 88 | "url", 89 | "uuid", 90 | ] 91 | 92 | [[package]] 93 | name = "async-graphql-derive" 94 | version = "1.16.6" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | checksum = "da7ba4a29b54bf94f53dcb0bec220b97396684a5b7bc79cd41c63b5a4129874d" 97 | dependencies = [ 98 | "Inflector", 99 | "async-graphql-parser", 100 | "itertools", 101 | "proc-macro-crate", 102 | "proc-macro2", 103 | "quote", 104 | "syn", 105 | ] 106 | 107 | [[package]] 108 | name = "async-graphql-parser" 109 | version = "1.16.6" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | checksum = "1d4a40a0a81dcd56bf1bcba1b78fcfc1c960db1914372da2fd87bd736b6b50d6" 112 | dependencies = [ 113 | "arrayvec", 114 | "pest", 115 | "pest_derive", 116 | "serde_json", 117 | "thiserror", 118 | ] 119 | 120 | [[package]] 121 | name = "async-std" 122 | version = "1.6.2" 123 | source = "registry+https://github.com/rust-lang/crates.io-index" 124 | checksum = "00d68a33ebc8b57800847d00787307f84a562224a14db069b0acefe4c2abbf5d" 125 | dependencies = [ 126 | "async-attributes", 127 | "async-task", 128 | "crossbeam-utils", 129 | "futures-channel", 130 | "futures-core", 131 | "futures-io", 132 | "kv-log-macro", 133 | "log", 134 | "memchr", 135 | "num_cpus", 136 | "once_cell", 137 | "pin-project-lite", 138 | "pin-utils", 139 | "slab", 140 | "smol", 141 | "wasm-bindgen-futures", 142 | ] 143 | 144 | [[package]] 145 | name = "async-stream" 146 | version = "0.2.1" 147 | source = "registry+https://github.com/rust-lang/crates.io-index" 148 | checksum = "22068c0c19514942eefcfd4daf8976ef1aad84e61539f95cd200c35202f80af5" 149 | dependencies = [ 150 | "async-stream-impl", 151 | "futures-core", 152 | ] 153 | 154 | [[package]] 155 | name = "async-stream-impl" 156 | version = "0.2.1" 157 | source = "registry+https://github.com/rust-lang/crates.io-index" 158 | checksum = "25f9db3b38af870bf7e5cc649167533b493928e50744e2c30ae350230b414670" 159 | dependencies = [ 160 | "proc-macro2", 161 | "quote", 162 | "syn", 163 | ] 164 | 165 | [[package]] 166 | name = "async-task" 167 | version = "3.0.0" 168 | source = "registry+https://github.com/rust-lang/crates.io-index" 169 | checksum = "c17772156ef2829aadc587461c7753af20b7e8db1529bc66855add962a3b35d3" 170 | 171 | [[package]] 172 | name = "async-trait" 173 | version = "0.1.36" 174 | source = "registry+https://github.com/rust-lang/crates.io-index" 175 | checksum = "a265e3abeffdce30b2e26b7a11b222fe37c6067404001b434101457d0385eb92" 176 | dependencies = [ 177 | "proc-macro2", 178 | "quote", 179 | "syn", 180 | ] 181 | 182 | [[package]] 183 | name = "atty" 184 | version = "0.2.14" 185 | source = "registry+https://github.com/rust-lang/crates.io-index" 186 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 187 | dependencies = [ 188 | "hermit-abi", 189 | "libc", 190 | "winapi", 191 | ] 192 | 193 | [[package]] 194 | name = "autocfg" 195 | version = "1.0.0" 196 | source = "registry+https://github.com/rust-lang/crates.io-index" 197 | checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" 198 | 199 | [[package]] 200 | name = "base64" 201 | version = "0.11.0" 202 | source = "registry+https://github.com/rust-lang/crates.io-index" 203 | checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" 204 | 205 | [[package]] 206 | name = "base64" 207 | version = "0.12.3" 208 | source = "registry+https://github.com/rust-lang/crates.io-index" 209 | checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" 210 | 211 | [[package]] 212 | name = "bitflags" 213 | version = "1.2.1" 214 | source = "registry+https://github.com/rust-lang/crates.io-index" 215 | checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 216 | 217 | [[package]] 218 | name = "blake2b_simd" 219 | version = "0.5.10" 220 | source = "registry+https://github.com/rust-lang/crates.io-index" 221 | checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" 222 | dependencies = [ 223 | "arrayref", 224 | "arrayvec", 225 | "constant_time_eq", 226 | ] 227 | 228 | [[package]] 229 | name = "block-buffer" 230 | version = "0.7.3" 231 | source = "registry+https://github.com/rust-lang/crates.io-index" 232 | checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" 233 | dependencies = [ 234 | "block-padding", 235 | "byte-tools", 236 | "byteorder", 237 | "generic-array", 238 | ] 239 | 240 | [[package]] 241 | name = "block-padding" 242 | version = "0.1.5" 243 | source = "registry+https://github.com/rust-lang/crates.io-index" 244 | checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" 245 | dependencies = [ 246 | "byte-tools", 247 | ] 248 | 249 | [[package]] 250 | name = "blocking" 251 | version = "0.4.6" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | checksum = "9d17efb70ce4421e351d61aafd90c16a20fb5bfe339fcdc32a86816280e62ce0" 254 | dependencies = [ 255 | "futures-channel", 256 | "futures-util", 257 | "once_cell", 258 | "parking", 259 | "waker-fn", 260 | ] 261 | 262 | [[package]] 263 | name = "bson" 264 | version = "1.0.0" 265 | source = "registry+https://github.com/rust-lang/crates.io-index" 266 | checksum = "95cba0c807bb47ef40cce9c699e74ecd2aa77ae5ab838e0a645c58569495e406" 267 | dependencies = [ 268 | "base64 0.12.3", 269 | "byteorder", 270 | "chrono", 271 | "hex", 272 | "libc", 273 | "linked-hash-map", 274 | "md5", 275 | "rand", 276 | "serde", 277 | "serde_json", 278 | "time", 279 | ] 280 | 281 | [[package]] 282 | name = "bumpalo" 283 | version = "3.4.0" 284 | source = "registry+https://github.com/rust-lang/crates.io-index" 285 | checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" 286 | 287 | [[package]] 288 | name = "byte-tools" 289 | version = "0.3.1" 290 | source = "registry+https://github.com/rust-lang/crates.io-index" 291 | checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" 292 | 293 | [[package]] 294 | name = "byteorder" 295 | version = "1.3.4" 296 | source = "registry+https://github.com/rust-lang/crates.io-index" 297 | checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" 298 | 299 | [[package]] 300 | name = "bytes" 301 | version = "0.5.5" 302 | source = "registry+https://github.com/rust-lang/crates.io-index" 303 | checksum = "118cf036fbb97d0816e3c34b2d7a1e8cfc60f68fcf63d550ddbe9bd5f59c213b" 304 | dependencies = [ 305 | "loom", 306 | ] 307 | 308 | [[package]] 309 | name = "cache-padded" 310 | version = "1.1.1" 311 | source = "registry+https://github.com/rust-lang/crates.io-index" 312 | checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba" 313 | 314 | [[package]] 315 | name = "cc" 316 | version = "1.0.58" 317 | source = "registry+https://github.com/rust-lang/crates.io-index" 318 | checksum = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518" 319 | 320 | [[package]] 321 | name = "cfg-if" 322 | version = "0.1.10" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 325 | 326 | [[package]] 327 | name = "chrono" 328 | version = "0.4.13" 329 | source = "registry+https://github.com/rust-lang/crates.io-index" 330 | checksum = "c74d84029116787153e02106bf53e66828452a4b325cc8652b788b5967c0a0b6" 331 | dependencies = [ 332 | "num-integer", 333 | "num-traits", 334 | "time", 335 | ] 336 | 337 | [[package]] 338 | name = "chrono-tz" 339 | version = "0.5.2" 340 | source = "registry+https://github.com/rust-lang/crates.io-index" 341 | checksum = "65d96be7c3e993c9ee4356442db24ba364c924b6b8331866be6b6952bfe74b9d" 342 | dependencies = [ 343 | "chrono", 344 | "parse-zoneinfo", 345 | ] 346 | 347 | [[package]] 348 | name = "clap" 349 | version = "3.0.0-beta.1" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "860643c53f980f0d38a5e25dfab6c3c93b2cb3aa1fe192643d17a293c6c41936" 352 | dependencies = [ 353 | "atty", 354 | "bitflags", 355 | "clap_derive", 356 | "indexmap", 357 | "lazy_static", 358 | "os_str_bytes", 359 | "strsim", 360 | "termcolor", 361 | "textwrap", 362 | "unicode-width", 363 | "vec_map", 364 | ] 365 | 366 | [[package]] 367 | name = "clap_derive" 368 | version = "3.0.0-beta.1" 369 | source = "registry+https://github.com/rust-lang/crates.io-index" 370 | checksum = "fb51c9e75b94452505acd21d929323f5a5c6c4735a852adbd39ef5fb1b014f30" 371 | dependencies = [ 372 | "heck", 373 | "proc-macro-error", 374 | "proc-macro2", 375 | "quote", 376 | "syn", 377 | ] 378 | 379 | [[package]] 380 | name = "cloudabi" 381 | version = "0.0.3" 382 | source = "registry+https://github.com/rust-lang/crates.io-index" 383 | checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 384 | dependencies = [ 385 | "bitflags", 386 | ] 387 | 388 | [[package]] 389 | name = "codegen-for-async-graphql" 390 | version = "0.2.7" 391 | dependencies = [ 392 | "clap", 393 | "codegen-for-async-graphql-renderer", 394 | ] 395 | 396 | [[package]] 397 | name = "codegen-for-async-graphql-example" 398 | version = "0.2.0" 399 | dependencies = [ 400 | "async-graphql", 401 | "async-std", 402 | ] 403 | 404 | [[package]] 405 | name = "codegen-for-async-graphql-renderer" 406 | version = "0.2.7" 407 | dependencies = [ 408 | "async-graphql", 409 | "async-graphql-parser", 410 | "proc-macro2", 411 | "quote", 412 | "toolchain_find", 413 | ] 414 | 415 | [[package]] 416 | name = "concurrent-queue" 417 | version = "1.1.1" 418 | source = "registry+https://github.com/rust-lang/crates.io-index" 419 | checksum = "f83c06aff61f2d899eb87c379df3cbf7876f14471dcab474e0b6dc90ab96c080" 420 | dependencies = [ 421 | "cache-padded", 422 | ] 423 | 424 | [[package]] 425 | name = "constant_time_eq" 426 | version = "0.1.5" 427 | source = "registry+https://github.com/rust-lang/crates.io-index" 428 | checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" 429 | 430 | [[package]] 431 | name = "crossbeam-utils" 432 | version = "0.7.2" 433 | source = "registry+https://github.com/rust-lang/crates.io-index" 434 | checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" 435 | dependencies = [ 436 | "autocfg", 437 | "cfg-if", 438 | "lazy_static", 439 | ] 440 | 441 | [[package]] 442 | name = "derive_more" 443 | version = "0.99.9" 444 | source = "registry+https://github.com/rust-lang/crates.io-index" 445 | checksum = "298998b1cf6b5b2c8a7b023dfd45821825ce3ba8a8af55c921a0e734e4653f76" 446 | dependencies = [ 447 | "proc-macro2", 448 | "quote", 449 | "syn", 450 | ] 451 | 452 | [[package]] 453 | name = "digest" 454 | version = "0.8.1" 455 | source = "registry+https://github.com/rust-lang/crates.io-index" 456 | checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" 457 | dependencies = [ 458 | "generic-array", 459 | ] 460 | 461 | [[package]] 462 | name = "dirs" 463 | version = "1.0.5" 464 | source = "registry+https://github.com/rust-lang/crates.io-index" 465 | checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" 466 | dependencies = [ 467 | "libc", 468 | "redox_users", 469 | "winapi", 470 | ] 471 | 472 | [[package]] 473 | name = "either" 474 | version = "1.5.3" 475 | source = "registry+https://github.com/rust-lang/crates.io-index" 476 | checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" 477 | 478 | [[package]] 479 | name = "encoding_rs" 480 | version = "0.8.23" 481 | source = "registry+https://github.com/rust-lang/crates.io-index" 482 | checksum = "e8ac63f94732332f44fe654443c46f6375d1939684c17b0afb6cb56b0456e171" 483 | dependencies = [ 484 | "cfg-if", 485 | ] 486 | 487 | [[package]] 488 | name = "fake-simd" 489 | version = "0.1.2" 490 | source = "registry+https://github.com/rust-lang/crates.io-index" 491 | checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" 492 | 493 | [[package]] 494 | name = "fastrand" 495 | version = "1.3.3" 496 | source = "registry+https://github.com/rust-lang/crates.io-index" 497 | checksum = "36a9cb09840f81cd211e435d00a4e487edd263dc3c8ff815c32dd76ad668ebed" 498 | 499 | [[package]] 500 | name = "fnv" 501 | version = "1.0.7" 502 | source = "registry+https://github.com/rust-lang/crates.io-index" 503 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 504 | 505 | [[package]] 506 | name = "futures" 507 | version = "0.3.5" 508 | source = "registry+https://github.com/rust-lang/crates.io-index" 509 | checksum = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613" 510 | dependencies = [ 511 | "futures-channel", 512 | "futures-core", 513 | "futures-executor", 514 | "futures-io", 515 | "futures-sink", 516 | "futures-task", 517 | "futures-util", 518 | ] 519 | 520 | [[package]] 521 | name = "futures-channel" 522 | version = "0.3.5" 523 | source = "registry+https://github.com/rust-lang/crates.io-index" 524 | checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5" 525 | dependencies = [ 526 | "futures-core", 527 | "futures-sink", 528 | ] 529 | 530 | [[package]] 531 | name = "futures-core" 532 | version = "0.3.5" 533 | source = "registry+https://github.com/rust-lang/crates.io-index" 534 | checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399" 535 | 536 | [[package]] 537 | name = "futures-executor" 538 | version = "0.3.5" 539 | source = "registry+https://github.com/rust-lang/crates.io-index" 540 | checksum = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314" 541 | dependencies = [ 542 | "futures-core", 543 | "futures-task", 544 | "futures-util", 545 | ] 546 | 547 | [[package]] 548 | name = "futures-io" 549 | version = "0.3.5" 550 | source = "registry+https://github.com/rust-lang/crates.io-index" 551 | checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789" 552 | 553 | [[package]] 554 | name = "futures-macro" 555 | version = "0.3.5" 556 | source = "registry+https://github.com/rust-lang/crates.io-index" 557 | checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39" 558 | dependencies = [ 559 | "proc-macro-hack", 560 | "proc-macro2", 561 | "quote", 562 | "syn", 563 | ] 564 | 565 | [[package]] 566 | name = "futures-sink" 567 | version = "0.3.5" 568 | source = "registry+https://github.com/rust-lang/crates.io-index" 569 | checksum = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc" 570 | 571 | [[package]] 572 | name = "futures-task" 573 | version = "0.3.5" 574 | source = "registry+https://github.com/rust-lang/crates.io-index" 575 | checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626" 576 | dependencies = [ 577 | "once_cell", 578 | ] 579 | 580 | [[package]] 581 | name = "futures-util" 582 | version = "0.3.5" 583 | source = "registry+https://github.com/rust-lang/crates.io-index" 584 | checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6" 585 | dependencies = [ 586 | "futures-channel", 587 | "futures-core", 588 | "futures-io", 589 | "futures-macro", 590 | "futures-sink", 591 | "futures-task", 592 | "memchr", 593 | "pin-project", 594 | "pin-utils", 595 | "proc-macro-hack", 596 | "proc-macro-nested", 597 | "slab", 598 | ] 599 | 600 | [[package]] 601 | name = "generator" 602 | version = "0.6.21" 603 | source = "registry+https://github.com/rust-lang/crates.io-index" 604 | checksum = "add72f17bb81521258fcc8a7a3245b1e184e916bfbe34f0ea89558f440df5c68" 605 | dependencies = [ 606 | "cc", 607 | "libc", 608 | "log", 609 | "rustc_version", 610 | "winapi", 611 | ] 612 | 613 | [[package]] 614 | name = "generic-array" 615 | version = "0.12.3" 616 | source = "registry+https://github.com/rust-lang/crates.io-index" 617 | checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" 618 | dependencies = [ 619 | "typenum", 620 | ] 621 | 622 | [[package]] 623 | name = "getrandom" 624 | version = "0.1.14" 625 | source = "registry+https://github.com/rust-lang/crates.io-index" 626 | checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" 627 | dependencies = [ 628 | "cfg-if", 629 | "libc", 630 | "wasi", 631 | ] 632 | 633 | [[package]] 634 | name = "heck" 635 | version = "0.3.1" 636 | source = "registry+https://github.com/rust-lang/crates.io-index" 637 | checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" 638 | dependencies = [ 639 | "unicode-segmentation", 640 | ] 641 | 642 | [[package]] 643 | name = "hermit-abi" 644 | version = "0.1.15" 645 | source = "registry+https://github.com/rust-lang/crates.io-index" 646 | checksum = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9" 647 | dependencies = [ 648 | "libc", 649 | ] 650 | 651 | [[package]] 652 | name = "hex" 653 | version = "0.3.2" 654 | source = "registry+https://github.com/rust-lang/crates.io-index" 655 | checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" 656 | 657 | [[package]] 658 | name = "http" 659 | version = "0.2.1" 660 | source = "registry+https://github.com/rust-lang/crates.io-index" 661 | checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9" 662 | dependencies = [ 663 | "bytes", 664 | "fnv", 665 | "itoa", 666 | ] 667 | 668 | [[package]] 669 | name = "httparse" 670 | version = "1.3.4" 671 | source = "registry+https://github.com/rust-lang/crates.io-index" 672 | checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" 673 | 674 | [[package]] 675 | name = "idna" 676 | version = "0.2.0" 677 | source = "registry+https://github.com/rust-lang/crates.io-index" 678 | checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" 679 | dependencies = [ 680 | "matches", 681 | "unicode-bidi", 682 | "unicode-normalization", 683 | ] 684 | 685 | [[package]] 686 | name = "indexmap" 687 | version = "1.4.0" 688 | source = "registry+https://github.com/rust-lang/crates.io-index" 689 | checksum = "c398b2b113b55809ceb9ee3e753fcbac793f1956663f3c36549c1346015c2afe" 690 | dependencies = [ 691 | "autocfg", 692 | ] 693 | 694 | [[package]] 695 | name = "itertools" 696 | version = "0.9.0" 697 | source = "registry+https://github.com/rust-lang/crates.io-index" 698 | checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" 699 | dependencies = [ 700 | "either", 701 | ] 702 | 703 | [[package]] 704 | name = "itoa" 705 | version = "0.4.6" 706 | source = "registry+https://github.com/rust-lang/crates.io-index" 707 | checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" 708 | 709 | [[package]] 710 | name = "js-sys" 711 | version = "0.3.41" 712 | source = "registry+https://github.com/rust-lang/crates.io-index" 713 | checksum = "c4b9172132a62451e56142bff9afc91c8e4a4500aa5b847da36815b63bfda916" 714 | dependencies = [ 715 | "wasm-bindgen", 716 | ] 717 | 718 | [[package]] 719 | name = "kv-log-macro" 720 | version = "1.0.7" 721 | source = "registry+https://github.com/rust-lang/crates.io-index" 722 | checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" 723 | dependencies = [ 724 | "log", 725 | ] 726 | 727 | [[package]] 728 | name = "lazy_static" 729 | version = "1.4.0" 730 | source = "registry+https://github.com/rust-lang/crates.io-index" 731 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 732 | 733 | [[package]] 734 | name = "libc" 735 | version = "0.2.72" 736 | source = "registry+https://github.com/rust-lang/crates.io-index" 737 | checksum = "a9f8082297d534141b30c8d39e9b1773713ab50fdbe4ff30f750d063b3bfd701" 738 | 739 | [[package]] 740 | name = "linked-hash-map" 741 | version = "0.5.3" 742 | source = "registry+https://github.com/rust-lang/crates.io-index" 743 | checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a" 744 | 745 | [[package]] 746 | name = "lock_api" 747 | version = "0.3.4" 748 | source = "registry+https://github.com/rust-lang/crates.io-index" 749 | checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" 750 | dependencies = [ 751 | "scopeguard", 752 | ] 753 | 754 | [[package]] 755 | name = "log" 756 | version = "0.4.8" 757 | source = "registry+https://github.com/rust-lang/crates.io-index" 758 | checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" 759 | dependencies = [ 760 | "cfg-if", 761 | ] 762 | 763 | [[package]] 764 | name = "loom" 765 | version = "0.3.4" 766 | source = "registry+https://github.com/rust-lang/crates.io-index" 767 | checksum = "4ecc775857611e1df29abba5c41355cdf540e7e9d4acfdf0f355eefee82330b7" 768 | dependencies = [ 769 | "cfg-if", 770 | "generator", 771 | "scoped-tls 0.1.2", 772 | ] 773 | 774 | [[package]] 775 | name = "maplit" 776 | version = "1.0.2" 777 | source = "registry+https://github.com/rust-lang/crates.io-index" 778 | checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" 779 | 780 | [[package]] 781 | name = "matches" 782 | version = "0.1.8" 783 | source = "registry+https://github.com/rust-lang/crates.io-index" 784 | checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" 785 | 786 | [[package]] 787 | name = "md5" 788 | version = "0.6.1" 789 | source = "registry+https://github.com/rust-lang/crates.io-index" 790 | checksum = "7e6bcd6433cff03a4bfc3d9834d504467db1f1cf6d0ea765d37d330249ed629d" 791 | 792 | [[package]] 793 | name = "memchr" 794 | version = "2.3.3" 795 | source = "registry+https://github.com/rust-lang/crates.io-index" 796 | checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" 797 | 798 | [[package]] 799 | name = "mime" 800 | version = "0.3.16" 801 | source = "registry+https://github.com/rust-lang/crates.io-index" 802 | checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" 803 | 804 | [[package]] 805 | name = "multer" 806 | version = "1.2.1" 807 | source = "registry+https://github.com/rust-lang/crates.io-index" 808 | checksum = "fac1b095372c22271a5a91922ce2aebe2a3cdcea36c6c16fd9a9d3752c53a07b" 809 | dependencies = [ 810 | "bytes", 811 | "derive_more", 812 | "encoding_rs", 813 | "futures", 814 | "http", 815 | "httparse", 816 | "lazy_static", 817 | "log", 818 | "mime", 819 | "regex", 820 | "twoway", 821 | ] 822 | 823 | [[package]] 824 | name = "num-integer" 825 | version = "0.1.43" 826 | source = "registry+https://github.com/rust-lang/crates.io-index" 827 | checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" 828 | dependencies = [ 829 | "autocfg", 830 | "num-traits", 831 | ] 832 | 833 | [[package]] 834 | name = "num-traits" 835 | version = "0.2.12" 836 | source = "registry+https://github.com/rust-lang/crates.io-index" 837 | checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" 838 | dependencies = [ 839 | "autocfg", 840 | ] 841 | 842 | [[package]] 843 | name = "num_cpus" 844 | version = "1.13.0" 845 | source = "registry+https://github.com/rust-lang/crates.io-index" 846 | checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" 847 | dependencies = [ 848 | "hermit-abi", 849 | "libc", 850 | ] 851 | 852 | [[package]] 853 | name = "once_cell" 854 | version = "1.4.0" 855 | source = "registry+https://github.com/rust-lang/crates.io-index" 856 | checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d" 857 | 858 | [[package]] 859 | name = "opaque-debug" 860 | version = "0.2.3" 861 | source = "registry+https://github.com/rust-lang/crates.io-index" 862 | checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" 863 | 864 | [[package]] 865 | name = "os_str_bytes" 866 | version = "2.3.1" 867 | source = "registry+https://github.com/rust-lang/crates.io-index" 868 | checksum = "06de47b848347d8c4c94219ad8ecd35eb90231704b067e67e6ae2e36ee023510" 869 | 870 | [[package]] 871 | name = "parking" 872 | version = "1.0.4" 873 | source = "registry+https://github.com/rust-lang/crates.io-index" 874 | checksum = "1efcee3c6d23b94012e240525f131c6abaa9e5eeb8f211002d93beec3b7be350" 875 | 876 | [[package]] 877 | name = "parking_lot" 878 | version = "0.10.2" 879 | source = "registry+https://github.com/rust-lang/crates.io-index" 880 | checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" 881 | dependencies = [ 882 | "lock_api", 883 | "parking_lot_core", 884 | ] 885 | 886 | [[package]] 887 | name = "parking_lot_core" 888 | version = "0.7.2" 889 | source = "registry+https://github.com/rust-lang/crates.io-index" 890 | checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" 891 | dependencies = [ 892 | "cfg-if", 893 | "cloudabi", 894 | "libc", 895 | "redox_syscall", 896 | "smallvec", 897 | "winapi", 898 | ] 899 | 900 | [[package]] 901 | name = "parse-zoneinfo" 902 | version = "0.3.0" 903 | source = "registry+https://github.com/rust-lang/crates.io-index" 904 | checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" 905 | dependencies = [ 906 | "regex", 907 | ] 908 | 909 | [[package]] 910 | name = "percent-encoding" 911 | version = "2.1.0" 912 | source = "registry+https://github.com/rust-lang/crates.io-index" 913 | checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" 914 | 915 | [[package]] 916 | name = "pest" 917 | version = "2.1.3" 918 | source = "registry+https://github.com/rust-lang/crates.io-index" 919 | checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" 920 | dependencies = [ 921 | "ucd-trie", 922 | ] 923 | 924 | [[package]] 925 | name = "pest_derive" 926 | version = "2.1.0" 927 | source = "registry+https://github.com/rust-lang/crates.io-index" 928 | checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" 929 | dependencies = [ 930 | "pest", 931 | "pest_generator", 932 | ] 933 | 934 | [[package]] 935 | name = "pest_generator" 936 | version = "2.1.3" 937 | source = "registry+https://github.com/rust-lang/crates.io-index" 938 | checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" 939 | dependencies = [ 940 | "pest", 941 | "pest_meta", 942 | "proc-macro2", 943 | "quote", 944 | "syn", 945 | ] 946 | 947 | [[package]] 948 | name = "pest_meta" 949 | version = "2.1.3" 950 | source = "registry+https://github.com/rust-lang/crates.io-index" 951 | checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" 952 | dependencies = [ 953 | "maplit", 954 | "pest", 955 | "sha-1", 956 | ] 957 | 958 | [[package]] 959 | name = "pin-project" 960 | version = "0.4.22" 961 | source = "registry+https://github.com/rust-lang/crates.io-index" 962 | checksum = "12e3a6cdbfe94a5e4572812a0201f8c0ed98c1c452c7b8563ce2276988ef9c17" 963 | dependencies = [ 964 | "pin-project-internal", 965 | ] 966 | 967 | [[package]] 968 | name = "pin-project-internal" 969 | version = "0.4.22" 970 | source = "registry+https://github.com/rust-lang/crates.io-index" 971 | checksum = "6a0ffd45cf79d88737d7cc85bfd5d2894bee1139b356e616fe85dc389c61aaf7" 972 | dependencies = [ 973 | "proc-macro2", 974 | "quote", 975 | "syn", 976 | ] 977 | 978 | [[package]] 979 | name = "pin-project-lite" 980 | version = "0.1.7" 981 | source = "registry+https://github.com/rust-lang/crates.io-index" 982 | checksum = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715" 983 | 984 | [[package]] 985 | name = "pin-utils" 986 | version = "0.1.0" 987 | source = "registry+https://github.com/rust-lang/crates.io-index" 988 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 989 | 990 | [[package]] 991 | name = "ppv-lite86" 992 | version = "0.2.8" 993 | source = "registry+https://github.com/rust-lang/crates.io-index" 994 | checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" 995 | 996 | [[package]] 997 | name = "proc-macro-crate" 998 | version = "0.1.5" 999 | source = "registry+https://github.com/rust-lang/crates.io-index" 1000 | checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" 1001 | dependencies = [ 1002 | "toml", 1003 | ] 1004 | 1005 | [[package]] 1006 | name = "proc-macro-error" 1007 | version = "0.4.12" 1008 | source = "registry+https://github.com/rust-lang/crates.io-index" 1009 | checksum = "18f33027081eba0a6d8aba6d1b1c3a3be58cbb12106341c2d5759fcd9b5277e7" 1010 | dependencies = [ 1011 | "proc-macro-error-attr", 1012 | "proc-macro2", 1013 | "quote", 1014 | "syn", 1015 | "version_check", 1016 | ] 1017 | 1018 | [[package]] 1019 | name = "proc-macro-error-attr" 1020 | version = "0.4.12" 1021 | source = "registry+https://github.com/rust-lang/crates.io-index" 1022 | checksum = "8a5b4b77fdb63c1eca72173d68d24501c54ab1269409f6b672c85deb18af69de" 1023 | dependencies = [ 1024 | "proc-macro2", 1025 | "quote", 1026 | "syn", 1027 | "syn-mid", 1028 | "version_check", 1029 | ] 1030 | 1031 | [[package]] 1032 | name = "proc-macro-hack" 1033 | version = "0.5.16" 1034 | source = "registry+https://github.com/rust-lang/crates.io-index" 1035 | checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4" 1036 | 1037 | [[package]] 1038 | name = "proc-macro-nested" 1039 | version = "0.1.6" 1040 | source = "registry+https://github.com/rust-lang/crates.io-index" 1041 | checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a" 1042 | 1043 | [[package]] 1044 | name = "proc-macro2" 1045 | version = "1.0.18" 1046 | source = "registry+https://github.com/rust-lang/crates.io-index" 1047 | checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" 1048 | dependencies = [ 1049 | "unicode-xid", 1050 | ] 1051 | 1052 | [[package]] 1053 | name = "quote" 1054 | version = "1.0.7" 1055 | source = "registry+https://github.com/rust-lang/crates.io-index" 1056 | checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" 1057 | dependencies = [ 1058 | "proc-macro2", 1059 | ] 1060 | 1061 | [[package]] 1062 | name = "rand" 1063 | version = "0.7.3" 1064 | source = "registry+https://github.com/rust-lang/crates.io-index" 1065 | checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" 1066 | dependencies = [ 1067 | "getrandom", 1068 | "libc", 1069 | "rand_chacha", 1070 | "rand_core", 1071 | "rand_hc", 1072 | ] 1073 | 1074 | [[package]] 1075 | name = "rand_chacha" 1076 | version = "0.2.2" 1077 | source = "registry+https://github.com/rust-lang/crates.io-index" 1078 | checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" 1079 | dependencies = [ 1080 | "ppv-lite86", 1081 | "rand_core", 1082 | ] 1083 | 1084 | [[package]] 1085 | name = "rand_core" 1086 | version = "0.5.1" 1087 | source = "registry+https://github.com/rust-lang/crates.io-index" 1088 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 1089 | dependencies = [ 1090 | "getrandom", 1091 | ] 1092 | 1093 | [[package]] 1094 | name = "rand_hc" 1095 | version = "0.2.0" 1096 | source = "registry+https://github.com/rust-lang/crates.io-index" 1097 | checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 1098 | dependencies = [ 1099 | "rand_core", 1100 | ] 1101 | 1102 | [[package]] 1103 | name = "redox_syscall" 1104 | version = "0.1.57" 1105 | source = "registry+https://github.com/rust-lang/crates.io-index" 1106 | checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" 1107 | 1108 | [[package]] 1109 | name = "redox_users" 1110 | version = "0.3.4" 1111 | source = "registry+https://github.com/rust-lang/crates.io-index" 1112 | checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" 1113 | dependencies = [ 1114 | "getrandom", 1115 | "redox_syscall", 1116 | "rust-argon2", 1117 | ] 1118 | 1119 | [[package]] 1120 | name = "regex" 1121 | version = "1.3.9" 1122 | source = "registry+https://github.com/rust-lang/crates.io-index" 1123 | checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6" 1124 | dependencies = [ 1125 | "aho-corasick", 1126 | "memchr", 1127 | "regex-syntax", 1128 | "thread_local", 1129 | ] 1130 | 1131 | [[package]] 1132 | name = "regex-syntax" 1133 | version = "0.6.18" 1134 | source = "registry+https://github.com/rust-lang/crates.io-index" 1135 | checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" 1136 | 1137 | [[package]] 1138 | name = "remove_dir_all" 1139 | version = "0.5.3" 1140 | source = "registry+https://github.com/rust-lang/crates.io-index" 1141 | checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" 1142 | dependencies = [ 1143 | "winapi", 1144 | ] 1145 | 1146 | [[package]] 1147 | name = "rust-argon2" 1148 | version = "0.7.0" 1149 | source = "registry+https://github.com/rust-lang/crates.io-index" 1150 | checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017" 1151 | dependencies = [ 1152 | "base64 0.11.0", 1153 | "blake2b_simd", 1154 | "constant_time_eq", 1155 | "crossbeam-utils", 1156 | ] 1157 | 1158 | [[package]] 1159 | name = "rustc_version" 1160 | version = "0.2.3" 1161 | source = "registry+https://github.com/rust-lang/crates.io-index" 1162 | checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 1163 | dependencies = [ 1164 | "semver", 1165 | ] 1166 | 1167 | [[package]] 1168 | name = "ryu" 1169 | version = "1.0.5" 1170 | source = "registry+https://github.com/rust-lang/crates.io-index" 1171 | checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" 1172 | 1173 | [[package]] 1174 | name = "same-file" 1175 | version = "1.0.6" 1176 | source = "registry+https://github.com/rust-lang/crates.io-index" 1177 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 1178 | dependencies = [ 1179 | "winapi-util", 1180 | ] 1181 | 1182 | [[package]] 1183 | name = "scoped-tls" 1184 | version = "0.1.2" 1185 | source = "registry+https://github.com/rust-lang/crates.io-index" 1186 | checksum = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" 1187 | 1188 | [[package]] 1189 | name = "scoped-tls" 1190 | version = "1.0.0" 1191 | source = "registry+https://github.com/rust-lang/crates.io-index" 1192 | checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" 1193 | 1194 | [[package]] 1195 | name = "scopeguard" 1196 | version = "1.1.0" 1197 | source = "registry+https://github.com/rust-lang/crates.io-index" 1198 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 1199 | 1200 | [[package]] 1201 | name = "semver" 1202 | version = "0.9.0" 1203 | source = "registry+https://github.com/rust-lang/crates.io-index" 1204 | checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 1205 | dependencies = [ 1206 | "semver-parser", 1207 | ] 1208 | 1209 | [[package]] 1210 | name = "semver-parser" 1211 | version = "0.7.0" 1212 | source = "registry+https://github.com/rust-lang/crates.io-index" 1213 | checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 1214 | 1215 | [[package]] 1216 | name = "serde" 1217 | version = "1.0.114" 1218 | source = "registry+https://github.com/rust-lang/crates.io-index" 1219 | checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3" 1220 | dependencies = [ 1221 | "serde_derive", 1222 | ] 1223 | 1224 | [[package]] 1225 | name = "serde_derive" 1226 | version = "1.0.114" 1227 | source = "registry+https://github.com/rust-lang/crates.io-index" 1228 | checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e" 1229 | dependencies = [ 1230 | "proc-macro2", 1231 | "quote", 1232 | "syn", 1233 | ] 1234 | 1235 | [[package]] 1236 | name = "serde_json" 1237 | version = "1.0.56" 1238 | source = "registry+https://github.com/rust-lang/crates.io-index" 1239 | checksum = "3433e879a558dde8b5e8feb2a04899cf34fdde1fafb894687e52105fc1162ac3" 1240 | dependencies = [ 1241 | "indexmap", 1242 | "itoa", 1243 | "ryu", 1244 | "serde", 1245 | ] 1246 | 1247 | [[package]] 1248 | name = "sha-1" 1249 | version = "0.8.2" 1250 | source = "registry+https://github.com/rust-lang/crates.io-index" 1251 | checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" 1252 | dependencies = [ 1253 | "block-buffer", 1254 | "digest", 1255 | "fake-simd", 1256 | "opaque-debug", 1257 | ] 1258 | 1259 | [[package]] 1260 | name = "slab" 1261 | version = "0.4.2" 1262 | source = "registry+https://github.com/rust-lang/crates.io-index" 1263 | checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" 1264 | 1265 | [[package]] 1266 | name = "smallvec" 1267 | version = "1.4.1" 1268 | source = "registry+https://github.com/rust-lang/crates.io-index" 1269 | checksum = "3757cb9d89161a2f24e1cf78efa0c1fcff485d18e3f55e0aa3480824ddaa0f3f" 1270 | 1271 | [[package]] 1272 | name = "smol" 1273 | version = "0.1.18" 1274 | source = "registry+https://github.com/rust-lang/crates.io-index" 1275 | checksum = "620cbb3c6e34da57d3a248cda0cd01cd5848164dc062e764e65d06fe3ea7aed5" 1276 | dependencies = [ 1277 | "async-task", 1278 | "blocking", 1279 | "concurrent-queue", 1280 | "fastrand", 1281 | "futures-io", 1282 | "futures-util", 1283 | "libc", 1284 | "once_cell", 1285 | "scoped-tls 1.0.0", 1286 | "slab", 1287 | "socket2", 1288 | "wepoll-sys-stjepang", 1289 | "winapi", 1290 | ] 1291 | 1292 | [[package]] 1293 | name = "socket2" 1294 | version = "0.3.12" 1295 | source = "registry+https://github.com/rust-lang/crates.io-index" 1296 | checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918" 1297 | dependencies = [ 1298 | "cfg-if", 1299 | "libc", 1300 | "redox_syscall", 1301 | "winapi", 1302 | ] 1303 | 1304 | [[package]] 1305 | name = "spin" 1306 | version = "0.5.2" 1307 | source = "registry+https://github.com/rust-lang/crates.io-index" 1308 | checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" 1309 | 1310 | [[package]] 1311 | name = "strsim" 1312 | version = "0.10.0" 1313 | source = "registry+https://github.com/rust-lang/crates.io-index" 1314 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 1315 | 1316 | [[package]] 1317 | name = "syn" 1318 | version = "1.0.33" 1319 | source = "registry+https://github.com/rust-lang/crates.io-index" 1320 | checksum = "e8d5d96e8cbb005d6959f119f773bfaebb5684296108fb32600c00cde305b2cd" 1321 | dependencies = [ 1322 | "proc-macro2", 1323 | "quote", 1324 | "unicode-xid", 1325 | ] 1326 | 1327 | [[package]] 1328 | name = "syn-mid" 1329 | version = "0.5.0" 1330 | source = "registry+https://github.com/rust-lang/crates.io-index" 1331 | checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" 1332 | dependencies = [ 1333 | "proc-macro2", 1334 | "quote", 1335 | "syn", 1336 | ] 1337 | 1338 | [[package]] 1339 | name = "tempfile" 1340 | version = "3.1.0" 1341 | source = "registry+https://github.com/rust-lang/crates.io-index" 1342 | checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" 1343 | dependencies = [ 1344 | "cfg-if", 1345 | "libc", 1346 | "rand", 1347 | "redox_syscall", 1348 | "remove_dir_all", 1349 | "winapi", 1350 | ] 1351 | 1352 | [[package]] 1353 | name = "termcolor" 1354 | version = "1.1.0" 1355 | source = "registry+https://github.com/rust-lang/crates.io-index" 1356 | checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" 1357 | dependencies = [ 1358 | "winapi-util", 1359 | ] 1360 | 1361 | [[package]] 1362 | name = "textwrap" 1363 | version = "0.11.0" 1364 | source = "registry+https://github.com/rust-lang/crates.io-index" 1365 | checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" 1366 | dependencies = [ 1367 | "unicode-width", 1368 | ] 1369 | 1370 | [[package]] 1371 | name = "thiserror" 1372 | version = "1.0.20" 1373 | source = "registry+https://github.com/rust-lang/crates.io-index" 1374 | checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08" 1375 | dependencies = [ 1376 | "thiserror-impl", 1377 | ] 1378 | 1379 | [[package]] 1380 | name = "thiserror-impl" 1381 | version = "1.0.20" 1382 | source = "registry+https://github.com/rust-lang/crates.io-index" 1383 | checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793" 1384 | dependencies = [ 1385 | "proc-macro2", 1386 | "quote", 1387 | "syn", 1388 | ] 1389 | 1390 | [[package]] 1391 | name = "thread_local" 1392 | version = "1.0.1" 1393 | source = "registry+https://github.com/rust-lang/crates.io-index" 1394 | checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" 1395 | dependencies = [ 1396 | "lazy_static", 1397 | ] 1398 | 1399 | [[package]] 1400 | name = "time" 1401 | version = "0.1.43" 1402 | source = "registry+https://github.com/rust-lang/crates.io-index" 1403 | checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" 1404 | dependencies = [ 1405 | "libc", 1406 | "winapi", 1407 | ] 1408 | 1409 | [[package]] 1410 | name = "tinyvec" 1411 | version = "0.3.3" 1412 | source = "registry+https://github.com/rust-lang/crates.io-index" 1413 | checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed" 1414 | 1415 | [[package]] 1416 | name = "toml" 1417 | version = "0.5.6" 1418 | source = "registry+https://github.com/rust-lang/crates.io-index" 1419 | checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" 1420 | dependencies = [ 1421 | "serde", 1422 | ] 1423 | 1424 | [[package]] 1425 | name = "toolchain_find" 1426 | version = "0.1.4" 1427 | source = "registry+https://github.com/rust-lang/crates.io-index" 1428 | checksum = "e458af37ead6107144c2e3bb892f605ddfad20251f12143cda8b9c9072b1ca45" 1429 | dependencies = [ 1430 | "dirs", 1431 | "lazy_static", 1432 | "regex", 1433 | "semver", 1434 | "walkdir", 1435 | ] 1436 | 1437 | [[package]] 1438 | name = "tracing" 1439 | version = "0.1.16" 1440 | source = "registry+https://github.com/rust-lang/crates.io-index" 1441 | checksum = "c2e2a2de6b0d5cbb13fc21193a2296888eaab62b6044479aafb3c54c01c29fcd" 1442 | dependencies = [ 1443 | "cfg-if", 1444 | "tracing-attributes", 1445 | "tracing-core", 1446 | ] 1447 | 1448 | [[package]] 1449 | name = "tracing-attributes" 1450 | version = "0.1.9" 1451 | source = "registry+https://github.com/rust-lang/crates.io-index" 1452 | checksum = "f0693bf8d6f2bf22c690fc61a9d21ac69efdbb894a17ed596b9af0f01e64b84b" 1453 | dependencies = [ 1454 | "proc-macro2", 1455 | "quote", 1456 | "syn", 1457 | ] 1458 | 1459 | [[package]] 1460 | name = "tracing-core" 1461 | version = "0.1.11" 1462 | source = "registry+https://github.com/rust-lang/crates.io-index" 1463 | checksum = "94ae75f0d28ae10786f3b1895c55fe72e79928fd5ccdebb5438c75e93fec178f" 1464 | dependencies = [ 1465 | "lazy_static", 1466 | ] 1467 | 1468 | [[package]] 1469 | name = "twoway" 1470 | version = "0.2.1" 1471 | source = "registry+https://github.com/rust-lang/crates.io-index" 1472 | checksum = "6b40075910de3a912adbd80b5d8bad6ad10a23eeb1f5bf9d4006839e899ba5bc" 1473 | dependencies = [ 1474 | "memchr", 1475 | "unchecked-index", 1476 | ] 1477 | 1478 | [[package]] 1479 | name = "typenum" 1480 | version = "1.12.0" 1481 | source = "registry+https://github.com/rust-lang/crates.io-index" 1482 | checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" 1483 | 1484 | [[package]] 1485 | name = "ucd-trie" 1486 | version = "0.1.3" 1487 | source = "registry+https://github.com/rust-lang/crates.io-index" 1488 | checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" 1489 | 1490 | [[package]] 1491 | name = "unchecked-index" 1492 | version = "0.2.2" 1493 | source = "registry+https://github.com/rust-lang/crates.io-index" 1494 | checksum = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c" 1495 | 1496 | [[package]] 1497 | name = "unicode-bidi" 1498 | version = "0.3.4" 1499 | source = "registry+https://github.com/rust-lang/crates.io-index" 1500 | checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" 1501 | dependencies = [ 1502 | "matches", 1503 | ] 1504 | 1505 | [[package]] 1506 | name = "unicode-normalization" 1507 | version = "0.1.13" 1508 | source = "registry+https://github.com/rust-lang/crates.io-index" 1509 | checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977" 1510 | dependencies = [ 1511 | "tinyvec", 1512 | ] 1513 | 1514 | [[package]] 1515 | name = "unicode-segmentation" 1516 | version = "1.6.0" 1517 | source = "registry+https://github.com/rust-lang/crates.io-index" 1518 | checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" 1519 | 1520 | [[package]] 1521 | name = "unicode-width" 1522 | version = "0.1.8" 1523 | source = "registry+https://github.com/rust-lang/crates.io-index" 1524 | checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" 1525 | 1526 | [[package]] 1527 | name = "unicode-xid" 1528 | version = "0.2.1" 1529 | source = "registry+https://github.com/rust-lang/crates.io-index" 1530 | checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" 1531 | 1532 | [[package]] 1533 | name = "url" 1534 | version = "2.1.1" 1535 | source = "registry+https://github.com/rust-lang/crates.io-index" 1536 | checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" 1537 | dependencies = [ 1538 | "idna", 1539 | "matches", 1540 | "percent-encoding", 1541 | ] 1542 | 1543 | [[package]] 1544 | name = "uuid" 1545 | version = "0.8.1" 1546 | source = "registry+https://github.com/rust-lang/crates.io-index" 1547 | checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11" 1548 | dependencies = [ 1549 | "rand", 1550 | ] 1551 | 1552 | [[package]] 1553 | name = "vec_map" 1554 | version = "0.8.2" 1555 | source = "registry+https://github.com/rust-lang/crates.io-index" 1556 | checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" 1557 | 1558 | [[package]] 1559 | name = "version_check" 1560 | version = "0.9.2" 1561 | source = "registry+https://github.com/rust-lang/crates.io-index" 1562 | checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" 1563 | 1564 | [[package]] 1565 | name = "waker-fn" 1566 | version = "1.0.0" 1567 | source = "registry+https://github.com/rust-lang/crates.io-index" 1568 | checksum = "9571542c2ce85ce642e6b58b3364da2fb53526360dfb7c211add4f5c23105ff7" 1569 | 1570 | [[package]] 1571 | name = "walkdir" 1572 | version = "2.3.1" 1573 | source = "registry+https://github.com/rust-lang/crates.io-index" 1574 | checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" 1575 | dependencies = [ 1576 | "same-file", 1577 | "winapi", 1578 | "winapi-util", 1579 | ] 1580 | 1581 | [[package]] 1582 | name = "wasi" 1583 | version = "0.9.0+wasi-snapshot-preview1" 1584 | source = "registry+https://github.com/rust-lang/crates.io-index" 1585 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 1586 | 1587 | [[package]] 1588 | name = "wasm-bindgen" 1589 | version = "0.2.64" 1590 | source = "registry+https://github.com/rust-lang/crates.io-index" 1591 | checksum = "6a634620115e4a229108b71bde263bb4220c483b3f07f5ba514ee8d15064c4c2" 1592 | dependencies = [ 1593 | "cfg-if", 1594 | "wasm-bindgen-macro", 1595 | ] 1596 | 1597 | [[package]] 1598 | name = "wasm-bindgen-backend" 1599 | version = "0.2.64" 1600 | source = "registry+https://github.com/rust-lang/crates.io-index" 1601 | checksum = "3e53963b583d18a5aa3aaae4b4c1cb535218246131ba22a71f05b518098571df" 1602 | dependencies = [ 1603 | "bumpalo", 1604 | "lazy_static", 1605 | "log", 1606 | "proc-macro2", 1607 | "quote", 1608 | "syn", 1609 | "wasm-bindgen-shared", 1610 | ] 1611 | 1612 | [[package]] 1613 | name = "wasm-bindgen-futures" 1614 | version = "0.4.14" 1615 | source = "registry+https://github.com/rust-lang/crates.io-index" 1616 | checksum = "dba48d66049d2a6cc8488702e7259ab7afc9043ad0dc5448444f46f2a453b362" 1617 | dependencies = [ 1618 | "cfg-if", 1619 | "js-sys", 1620 | "wasm-bindgen", 1621 | "web-sys", 1622 | ] 1623 | 1624 | [[package]] 1625 | name = "wasm-bindgen-macro" 1626 | version = "0.2.64" 1627 | source = "registry+https://github.com/rust-lang/crates.io-index" 1628 | checksum = "3fcfd5ef6eec85623b4c6e844293d4516470d8f19cd72d0d12246017eb9060b8" 1629 | dependencies = [ 1630 | "quote", 1631 | "wasm-bindgen-macro-support", 1632 | ] 1633 | 1634 | [[package]] 1635 | name = "wasm-bindgen-macro-support" 1636 | version = "0.2.64" 1637 | source = "registry+https://github.com/rust-lang/crates.io-index" 1638 | checksum = "9adff9ee0e94b926ca81b57f57f86d5545cdcb1d259e21ec9bdd95b901754c75" 1639 | dependencies = [ 1640 | "proc-macro2", 1641 | "quote", 1642 | "syn", 1643 | "wasm-bindgen-backend", 1644 | "wasm-bindgen-shared", 1645 | ] 1646 | 1647 | [[package]] 1648 | name = "wasm-bindgen-shared" 1649 | version = "0.2.64" 1650 | source = "registry+https://github.com/rust-lang/crates.io-index" 1651 | checksum = "7f7b90ea6c632dd06fd765d44542e234d5e63d9bb917ecd64d79778a13bd79ae" 1652 | 1653 | [[package]] 1654 | name = "web-sys" 1655 | version = "0.3.41" 1656 | source = "registry+https://github.com/rust-lang/crates.io-index" 1657 | checksum = "863539788676619aac1a23e2df3655e96b32b0e05eb72ca34ba045ad573c625d" 1658 | dependencies = [ 1659 | "js-sys", 1660 | "wasm-bindgen", 1661 | ] 1662 | 1663 | [[package]] 1664 | name = "wepoll-sys-stjepang" 1665 | version = "1.0.6" 1666 | source = "registry+https://github.com/rust-lang/crates.io-index" 1667 | checksum = "6fd319e971980166b53e17b1026812ad66c6b54063be879eb182342b55284694" 1668 | dependencies = [ 1669 | "cc", 1670 | ] 1671 | 1672 | [[package]] 1673 | name = "winapi" 1674 | version = "0.3.9" 1675 | source = "registry+https://github.com/rust-lang/crates.io-index" 1676 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1677 | dependencies = [ 1678 | "winapi-i686-pc-windows-gnu", 1679 | "winapi-x86_64-pc-windows-gnu", 1680 | ] 1681 | 1682 | [[package]] 1683 | name = "winapi-i686-pc-windows-gnu" 1684 | version = "0.4.0" 1685 | source = "registry+https://github.com/rust-lang/crates.io-index" 1686 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1687 | 1688 | [[package]] 1689 | name = "winapi-util" 1690 | version = "0.1.5" 1691 | source = "registry+https://github.com/rust-lang/crates.io-index" 1692 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 1693 | dependencies = [ 1694 | "winapi", 1695 | ] 1696 | 1697 | [[package]] 1698 | name = "winapi-x86_64-pc-windows-gnu" 1699 | version = "0.4.0" 1700 | source = "registry+https://github.com/rust-lang/crates.io-index" 1701 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1702 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "codegen-for-async-graphql" 3 | version = "0.2.7" 4 | authors = ["Atsuhiro Takahashi "] 5 | edition = "2018" 6 | description = "Internal code generation crate for async-graphql" 7 | publish = true 8 | license = "MIT" 9 | homepage = "https://github.com/atsuhiro/codegen-for-async-graphql" 10 | repository = "https://github.com/atsuhiro/codegen-for-async-graphql" 11 | keywords = ["graphql", "async-graphql"] 12 | categories = ["network-programming", "web-programming"] 13 | readme = "README.md" 14 | 15 | [[bin]] 16 | name = "cargo-codegen-for-async-graphql" 17 | path = "src/codegen.rs" 18 | 19 | [dependencies] 20 | clap = "3.0.0-beta.1" 21 | codegen-for-async-graphql-renderer= { path = "codegen-for-async-graphql-renderer", version = "0.2.7" } 22 | 23 | [workspace] 24 | members = [ 25 | "codegen-for-async-graphql-renderer", 26 | "examples/codegen-for-async-graphql-example", 27 | ] 28 | 29 | exclude = [ 30 | "tmp/*", 31 | ] 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Atsuhiro Takahashi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # codegen-for-async-graphql 2 | 3 | [![codecov](https://codecov.io/gh/atsuhiro/codegen-for-async-graphql/branch/master/graph/badge.svg)](https://codecov.io/gh/atsuhiro/codegen-for-async-graphql) 4 | 5 | ## Usage 6 | 7 | ```bash 8 | cargo codegen-for-async-graphql --schema {path_to_schema} --output {path_to_output} 9 | # cargo codegen-for-async-graphql --schema ./schema.graphql --output src/models 10 | ``` 11 | 12 | ```rust 13 | mod models; 14 | 15 | use async_graphql::*; 16 | 17 | use models::{ 18 | Mutation, Query, 19 | }; 20 | 21 | let data_source = DataSource {}; 22 | let schema = Schema::build(Query {}, Mutation {}, EmptySubscription) 23 | .register_type::() 24 | .data(data_source) 25 | .finish(); 26 | let res = schema.execute(query).await; 27 | let json = serde_json::to_string_pretty(&async_graphql::http::GQLResponse(res)); 28 | json.unwrap() 29 | ``` 30 | -------------------------------------------------------------------------------- /clippy.toml: -------------------------------------------------------------------------------- 1 | blacklisted-names = ["hoge", "moge"] 2 | cognitive-complexity-threshold = 3 3 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "codegen-for-async-graphql-renderer" 3 | version = "0.2.7" 4 | authors = ["Atsuhiro Takahashi "] 5 | edition = "2018" 6 | description = "Internal code generation crate for async-graphql" 7 | publish = true 8 | license = "MIT" 9 | homepage = "https://github.com/atsuhiro/codegen-for-async-graphql" 10 | repository = "https://github.com/atsuhiro/codegen-for-async-graphql" 11 | keywords = ["graphql", "async-graphql"] 12 | categories = ["network-programming", "web-programming"] 13 | 14 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 15 | 16 | [dependencies] 17 | async-graphql = "1.16.9" 18 | async-graphql-parser = "1.16.6" 19 | proc-macro2 = { version = "1.0", default-features = false } 20 | quote = "1.0.7" 21 | toolchain_find = "0.1" 22 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atsuhiro/codegen-for-async-graphql/e74636da96d1e17f809ab9c89cc89fcb6d5cc50c/codegen-for-async-graphql-renderer/src/README.md -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/base/config.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug)] 2 | pub struct Config { 3 | pub output_bnase_path: String, 4 | } 5 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/base/context.rs: -------------------------------------------------------------------------------- 1 | use super::Config; 2 | use async_graphql_parser::schema::{Definition, Document, TypeDefinition}; 3 | use std::collections::HashMap; 4 | 5 | use crate::document_wrapper::{ 6 | FileRender, InputObjectTypeWrapper, InterfaceTypeWrapper, MutationsTypeWrapper, ObjectPath, 7 | ObjectTypeWrapper, RenderType, ScalarTypeWrapper, SubscriptionRootTypeWrapper, 8 | UnionTypeWrapper, 9 | }; 10 | 11 | #[derive(Debug, Clone)] 12 | pub struct Context<'a> { 13 | pub config: &'a Config, 14 | doc: &'a Document, 15 | } 16 | 17 | fn get_paths(obj: &[T]) -> Vec 18 | where 19 | T: FileRender, 20 | { 21 | obj.iter().map(|f| f.path()).collect() 22 | } 23 | 24 | impl<'a> Context<'a> { 25 | #[must_use] 26 | pub const fn new(config: &'a Config, doc: &'a Document) -> Self { 27 | Self { config, doc } 28 | } 29 | 30 | #[must_use] 31 | pub fn scalar_names(&self) -> Vec { 32 | self.scalar_types() 33 | .iter() 34 | .map(ScalarTypeWrapper::name) 35 | .collect() 36 | } 37 | 38 | #[must_use] 39 | pub fn union_names(&self) -> Vec { 40 | self.union_types() 41 | .iter() 42 | .map(UnionTypeWrapper::name) 43 | .collect() 44 | } 45 | 46 | pub fn input_object_type_names(&self) -> Vec { 47 | self.input_object_types() 48 | .iter() 49 | .map(InputObjectTypeWrapper::name) 50 | .collect() 51 | } 52 | 53 | pub fn file_paths(&self) -> Vec { 54 | vec![ 55 | self.scalar_file_paths(), 56 | self.object_type_file_paths(), 57 | self.interface_type_file_paths(), 58 | self.mutation_type_file_paths(), 59 | self.input_object_type_file_paths(), 60 | self.union_type_file_paths(), 61 | self.subscription_type_file_paths(), 62 | ] 63 | .into_iter() 64 | .flatten() 65 | .collect() 66 | } 67 | 68 | pub fn structured_file_paths(&self) -> HashMap> { 69 | let mut map = HashMap::new(); 70 | 71 | self.file_paths().iter().for_each(|f| { 72 | let r = vec![]; 73 | map.entry(f.super_module_name.clone()) 74 | .or_insert_with(|| r) 75 | .push(f.clone()); 76 | }); 77 | map 78 | } 79 | 80 | fn scalar_file_paths(&self) -> Vec { 81 | get_paths(&self.scalar_types()) 82 | } 83 | 84 | fn object_type_file_paths(&self) -> Vec { 85 | get_paths(&self.object_types()) 86 | } 87 | 88 | fn interface_type_file_paths(&self) -> Vec { 89 | get_paths(&self.interface_types()) 90 | } 91 | 92 | fn mutation_type_file_paths(&self) -> Vec { 93 | get_paths(&self.mutation_types()) 94 | } 95 | 96 | fn subscription_type_file_paths(&self) -> Vec { 97 | get_paths(&self.subscription_types()) 98 | } 99 | 100 | fn input_object_type_file_paths(&self) -> Vec { 101 | get_paths(&self.input_object_types()) 102 | } 103 | 104 | fn union_type_file_paths(&self) -> Vec { 105 | get_paths(&self.union_types()) 106 | } 107 | 108 | fn type_definition(&self) -> Vec<&TypeDefinition> { 109 | self.doc 110 | .definitions 111 | .iter() 112 | .filter_map(|f| match &f.node { 113 | Definition::TypeDefinition(n) => Some(&n.node), 114 | Definition::SchemaDefinition(_n) => None, 115 | _ => panic!("Not implemented:{:?}", f), 116 | }) 117 | .collect() 118 | } 119 | 120 | #[must_use] 121 | pub fn mutation_types(&self) -> Vec { 122 | self.type_definition() 123 | .iter() 124 | .filter_map(|f| match &f { 125 | TypeDefinition::Object(f) => { 126 | if f.node.name.node == "Mutation" { 127 | return Some(MutationsTypeWrapper { 128 | doc: &f.node, 129 | context: self, 130 | }); 131 | } 132 | None 133 | } 134 | _ => None, 135 | }) 136 | .collect() 137 | } 138 | 139 | #[must_use] 140 | pub fn subscription_types(&self) -> Vec { 141 | self.type_definition() 142 | .iter() 143 | .filter_map(|f| match &f { 144 | TypeDefinition::Object(f) => { 145 | if f.node.name.node == "Subscription" { 146 | return Some(SubscriptionRootTypeWrapper { 147 | doc: &f.node, 148 | context: self, 149 | }); 150 | } 151 | None 152 | } 153 | _ => None, 154 | }) 155 | .collect() 156 | } 157 | 158 | #[must_use] 159 | pub fn object_types(&self) -> Vec { 160 | self.type_definition() 161 | .iter() 162 | .filter_map(|f| match &f { 163 | TypeDefinition::Object(f) => { 164 | if f.node.name.node == "Mutation" { 165 | return None; 166 | } 167 | if f.node.name.node == "Subscription" { 168 | return None; 169 | } 170 | Some(ObjectTypeWrapper { 171 | doc: &f.node, 172 | context: self, 173 | }) 174 | } 175 | _ => None, 176 | }) 177 | .collect() 178 | } 179 | 180 | #[must_use] 181 | pub fn scalar_types(&self) -> Vec { 182 | self.type_definition() 183 | .iter() 184 | .filter_map(|f| match &f { 185 | TypeDefinition::Scalar(f) => Some(ScalarTypeWrapper { 186 | doc: &f.node, 187 | context: self, 188 | }), 189 | _ => None, 190 | }) 191 | .collect() 192 | } 193 | 194 | #[must_use] 195 | pub fn union_types(&self) -> Vec { 196 | self.type_definition() 197 | .iter() 198 | .filter_map(|f| match &f { 199 | TypeDefinition::Union(f) => Some(UnionTypeWrapper { 200 | doc: &f.node, 201 | context: self, 202 | }), 203 | _ => None, 204 | }) 205 | .collect() 206 | } 207 | 208 | #[must_use] 209 | pub fn interface_types(&self) -> Vec { 210 | self.type_definition() 211 | .iter() 212 | .filter_map(|f| match &f { 213 | TypeDefinition::Interface(f) => Some(InterfaceTypeWrapper { 214 | doc: &f.node, 215 | context: self, 216 | }), 217 | _ => None, 218 | }) 219 | .collect() 220 | } 221 | 222 | #[must_use] 223 | pub fn input_object_types(&self) -> Vec { 224 | self.type_definition() 225 | .iter() 226 | .filter_map(|f| match &f { 227 | TypeDefinition::InputObject(f) => Some(InputObjectTypeWrapper { 228 | doc: &f.node, 229 | context: self, 230 | }), 231 | _ => None, 232 | }) 233 | .collect() 234 | } 235 | } 236 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/base/generator.rs: -------------------------------------------------------------------------------- 1 | use std::fs; 2 | 3 | use super::render_to_files; 4 | use async_graphql_parser::parse_schema; 5 | use async_graphql_parser::schema::Document; 6 | 7 | use super::{Config, Context}; 8 | 9 | pub fn generate_from_path(path: &str, config: &Config) { 10 | let schema = open_schema(path); 11 | let doc = parse(&schema); 12 | let context = Context::new(config, &doc); 13 | render_to_files(&context); 14 | } 15 | 16 | fn parse(schema: &str) -> Document { 17 | match parse_schema(schema) { 18 | Ok(f) => f, 19 | Err(e) => { 20 | println!("{}", e); 21 | panic!("Parse Error: {:?}", e); 22 | } 23 | } 24 | } 25 | 26 | fn open_schema(path: &str) -> String { 27 | match fs::read_to_string(path) { 28 | Ok(f) => f, 29 | Err(f) => panic!("Not Found(Schema File): {:?}, {}", f, path), 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/base/mod.rs: -------------------------------------------------------------------------------- 1 | mod config; 2 | mod context; 3 | mod generator; 4 | pub mod utils; 5 | 6 | pub use generator::generate_from_path; 7 | 8 | pub use config::Config; 9 | pub use context::Context; 10 | 11 | use crate::renderer::render_to_files; 12 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/base/utils.rs: -------------------------------------------------------------------------------- 1 | // https://github.com/serde-rs/serde/blob/b87f8f35ee631ff5fb8f01e0ebf5ad1f5148d369/serde_derive/src/internals/case.rs#L46 2 | // snakecase 3 | 4 | #[must_use] 5 | pub fn snake_case(variant: &str) -> String { 6 | let mut snake = String::new(); 7 | for (i, ch) in variant.char_indices() { 8 | if i > 0 && ch.is_uppercase() { 9 | snake.push('_'); 10 | } 11 | snake.push(ch.to_ascii_lowercase()); 12 | } 13 | snake 14 | } 15 | 16 | #[cfg(test)] 17 | mod tests { 18 | use super::*; 19 | 20 | #[test] 21 | fn rename_to_snake_case() { 22 | let snake = "very_tasty".to_string(); 23 | ["VeryTasty", "veryTasty"].iter().for_each(|f| { 24 | assert_eq!(snake, snake_case(f)); 25 | }); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/document_wrapper/field_wrapper.rs: -------------------------------------------------------------------------------- 1 | use super::Context; 2 | use async_graphql_parser::schema::{Field, InputValue, Type}; 3 | 4 | use super::{RenderType, SupportField, SupportType, SupportTypeName, UseContext}; 5 | 6 | #[derive(Debug, Clone)] 7 | pub struct FieldWrapper<'a, 'b> { 8 | pub doc: &'a Field, 9 | pub context: &'a Context<'b>, 10 | } 11 | 12 | impl<'a, 'b> SupportType for FieldWrapper<'a, 'b> { 13 | fn ty(&self) -> &Type { 14 | &self.doc.ty.node 15 | } 16 | } 17 | 18 | impl<'a, 'b> UseContext for FieldWrapper<'a, 'b> { 19 | fn context(&self) -> &Context { 20 | self.context 21 | } 22 | } 23 | 24 | impl<'a, 'b> SupportField for FieldWrapper<'a, 'b> { 25 | fn input_value_types(&self) -> Vec<&InputValue> { 26 | let mut res = vec![]; 27 | self.doc.arguments.iter().for_each(|f| res.push(&f.node)); 28 | res 29 | } 30 | } 31 | 32 | impl<'a, 'b> RenderType for FieldWrapper<'a, 'b> { 33 | #[must_use] 34 | fn name(&self) -> String { 35 | self.doc.name.node.clone() 36 | } 37 | 38 | #[must_use] 39 | fn description(&self) -> Option<&String> { 40 | match &self.doc.description { 41 | Some(f) => Some(&f.node), 42 | _ => None, 43 | } 44 | } 45 | } 46 | 47 | impl<'a, 'b> SupportTypeName for FieldWrapper<'a, 'b> {} 48 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/document_wrapper/input_object_type_wrapper.rs: -------------------------------------------------------------------------------- 1 | use async_graphql_parser::schema::{InputObjectType, InputValue}; 2 | 3 | use super::{Context, FileRender, RenderType, SupportField, UseContext}; 4 | 5 | #[derive(Debug, Clone)] 6 | pub struct InputObjectTypeWrapper<'a, 'b> { 7 | pub doc: &'a InputObjectType, 8 | pub context: &'a Context<'b>, 9 | } 10 | 11 | impl<'a, 'b> FileRender for InputObjectTypeWrapper<'a, 'b> { 12 | fn super_module_name(&self) -> String { 13 | "input_object_type".to_string() 14 | } 15 | } 16 | 17 | impl<'a, 'b> RenderType for InputObjectTypeWrapper<'a, 'b> { 18 | #[must_use] 19 | fn name(&self) -> String { 20 | self.doc.name.node.clone() 21 | } 22 | 23 | #[must_use] 24 | fn description(&self) -> Option<&String> { 25 | match &self.doc.description { 26 | Some(_f) => panic!("Not Implemented"), 27 | _ => None, 28 | } 29 | } 30 | } 31 | 32 | impl<'a, 'b> UseContext for InputObjectTypeWrapper<'a, 'b> { 33 | fn context(&self) -> &Context { 34 | self.context 35 | } 36 | } 37 | 38 | impl<'a, 'b> SupportField for InputObjectTypeWrapper<'a, 'b> { 39 | fn input_value_types(&self) -> Vec<&InputValue> { 40 | let mut res = vec![]; 41 | self.doc.fields.iter().for_each(|f| res.push(&f.node)); 42 | res 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/document_wrapper/input_value_wrapper.rs: -------------------------------------------------------------------------------- 1 | use super::Context; 2 | use async_graphql_parser::schema::{InputValue, Type}; 3 | 4 | use super::{snake_case, RenderType, SupportType, SupportTypeName, UseContext}; 5 | 6 | #[derive(Debug, Clone)] 7 | pub struct InputValueWrapper<'a, 'b> { 8 | pub doc: &'a InputValue, 9 | pub context: &'a Context<'b>, 10 | } 11 | 12 | impl<'a, 'b> SupportType for InputValueWrapper<'a, 'b> { 13 | fn ty(&self) -> &Type { 14 | &self.doc.ty.node 15 | } 16 | } 17 | 18 | impl<'a, 'b> RenderType for InputValueWrapper<'a, 'b> { 19 | #[must_use] 20 | fn name(&self) -> String { 21 | self.doc.name.node.clone() 22 | } 23 | 24 | #[must_use] 25 | fn description(&self) -> Option<&String> { 26 | match &self.doc.description { 27 | Some(_f) => panic!("Not Implemented"), 28 | _ => None, 29 | } 30 | } 31 | } 32 | 33 | impl<'a, 'b> UseContext for InputValueWrapper<'a, 'b> { 34 | fn context(&self) -> &Context { 35 | self.context 36 | } 37 | } 38 | 39 | impl<'a, 'b> SupportTypeName for InputValueWrapper<'a, 'b> {} 40 | 41 | impl<'a, 'b> InputValueWrapper<'a, 'b> { 42 | #[must_use] 43 | pub fn field_name(&self) -> String { 44 | snake_case(&self.doc.name.node) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/document_wrapper/interface_type_wrapper.rs: -------------------------------------------------------------------------------- 1 | use async_graphql_parser::schema::InterfaceType; 2 | 3 | use super::{ 4 | BaseType, Dependency, FieldWrapper, FileRender, ObjectTypeWrapper, RenderType, SupportFields, 5 | }; 6 | 7 | pub type InterfaceTypeWrapper<'a, 'b> = BaseType<'a, 'b, InterfaceType>; 8 | 9 | impl<'a, 'b> FileRender for InterfaceTypeWrapper<'a, 'b> { 10 | fn super_module_name(&self) -> String { 11 | "interface_type".to_string() 12 | } 13 | } 14 | 15 | impl<'a, 'b> RenderType for InterfaceTypeWrapper<'a, 'b> { 16 | #[must_use] 17 | fn name(&self) -> String { 18 | self.doc.name.node.clone() 19 | } 20 | 21 | #[must_use] 22 | fn description(&self) -> Option<&String> { 23 | match &self.doc.description { 24 | Some(_f) => panic!("Not Implemented"), 25 | _ => None, 26 | } 27 | } 28 | } 29 | 30 | impl<'a, 'b> SupportFields for InterfaceTypeWrapper<'a, 'b> { 31 | #[must_use] 32 | fn fields(&self) -> Vec { 33 | self.doc 34 | .fields 35 | .iter() 36 | .map(|f| FieldWrapper { 37 | doc: &f.node, 38 | context: self.context, 39 | }) 40 | .collect() 41 | } 42 | } 43 | 44 | impl<'a, 'b> InterfaceTypeWrapper<'a, 'b> { 45 | pub fn dependencies(&self) -> Vec { 46 | self.implemented_object_types() 47 | .into_iter() 48 | .map(|f| Dependency { 49 | super_module_name: f.super_module_name(), 50 | module_name: f.file_name(), 51 | name: f.name(), 52 | }) 53 | .collect() 54 | } 55 | 56 | pub fn implemented_object_types(&self) -> Vec { 57 | let name = self.name(); 58 | self.context 59 | .object_types() 60 | .into_iter() 61 | .filter(|f| { 62 | f.implements_interfaces().iter().any(|f| { 63 | if name == *f { 64 | return true; 65 | } 66 | false 67 | }) 68 | }) 69 | .collect() 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/document_wrapper/mod.rs: -------------------------------------------------------------------------------- 1 | mod field_wrapper; 2 | mod input_object_type_wrapper; 3 | mod input_value_wrapper; 4 | mod interface_type_wrapper; 5 | mod mutation_type_wrapper; 6 | mod mutations_type_wrapper; 7 | mod object_type_wrapper; 8 | mod scalar_type_wrapper; 9 | mod subscription_root_type_wrapper; 10 | mod subscription_type_wrapper; 11 | mod type_wrapper; 12 | mod union_type_wrapper; 13 | 14 | use crate::base::utils::snake_case; 15 | use crate::base::Context; 16 | 17 | pub use type_wrapper::{ 18 | BaseType, Dependency, FileRender, ObjectPath, RenderType, SupportField, SupportFields, 19 | SupportType, SupportTypeName, UseContext, 20 | }; 21 | 22 | pub use field_wrapper::FieldWrapper; 23 | pub use input_object_type_wrapper::InputObjectTypeWrapper; 24 | pub use input_value_wrapper::InputValueWrapper; 25 | pub use interface_type_wrapper::InterfaceTypeWrapper; 26 | pub use mutation_type_wrapper::MutationTypeWrapper; 27 | pub use mutations_type_wrapper::MutationsTypeWrapper; 28 | pub use object_type_wrapper::ObjectTypeWrapper; 29 | pub use scalar_type_wrapper::ScalarTypeWrapper; 30 | pub use subscription_root_type_wrapper::SubscriptionRootTypeWrapper; 31 | pub use subscription_type_wrapper::SubscriptionTypeWrapper; 32 | pub use union_type_wrapper::UnionTypeWrapper; 33 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/document_wrapper/mutation_type_wrapper.rs: -------------------------------------------------------------------------------- 1 | use async_graphql_parser::schema::{Field, InputValue, Type}; 2 | 3 | use super::{Context, RenderType, SupportField, SupportType, SupportTypeName, UseContext}; 4 | 5 | #[derive(Debug)] 6 | pub struct MutationTypeWrapper<'a, 'b> { 7 | pub doc: &'a Field, 8 | pub context: &'a Context<'b>, 9 | } 10 | 11 | impl<'a, 'b> SupportType for MutationTypeWrapper<'a, 'b> { 12 | fn ty(&self) -> &Type { 13 | &self.doc.ty.node 14 | } 15 | } 16 | 17 | impl<'a, 'b> UseContext for MutationTypeWrapper<'a, 'b> { 18 | fn context(&self) -> &Context { 19 | self.context 20 | } 21 | } 22 | 23 | impl<'a, 'b> SupportField for MutationTypeWrapper<'a, 'b> { 24 | fn input_value_types(&self) -> Vec<&InputValue> { 25 | let mut res = vec![]; 26 | self.doc.arguments.iter().for_each(|f| res.push(&f.node)); 27 | res 28 | } 29 | } 30 | 31 | impl<'a, 'b> SupportTypeName for MutationTypeWrapper<'a, 'b> {} 32 | 33 | impl<'a, 'b> RenderType for MutationTypeWrapper<'a, 'b> { 34 | #[must_use] 35 | fn name(&self) -> String { 36 | self.doc.name.node.clone() 37 | } 38 | 39 | #[must_use] 40 | fn description(&self) -> Option<&String> { 41 | match &self.doc.description { 42 | Some(_f) => panic!("Not Implemented"), 43 | _ => None, 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/document_wrapper/mutations_type_wrapper.rs: -------------------------------------------------------------------------------- 1 | use async_graphql_parser::schema::ObjectType; 2 | 3 | use super::{ 4 | Context, Dependency, FileRender, MutationTypeWrapper, RenderType, SupportField, SupportTypeName, 5 | }; 6 | 7 | #[derive(Debug)] 8 | pub struct MutationsTypeWrapper<'a, 'b> { 9 | pub doc: &'a ObjectType, 10 | pub context: &'a Context<'b>, 11 | } 12 | 13 | impl<'a, 'b> FileRender for MutationsTypeWrapper<'a, 'b> { 14 | fn super_module_name(&self) -> String { 15 | "mutations_type".to_string() 16 | } 17 | } 18 | 19 | impl<'a, 'b> RenderType for MutationsTypeWrapper<'a, 'b> { 20 | #[must_use] 21 | fn name(&self) -> String { 22 | self.doc.name.node.clone() 23 | } 24 | 25 | #[must_use] 26 | fn description(&self) -> Option<&String> { 27 | match &self.doc.description { 28 | Some(_f) => panic!("Not Implemented"), 29 | _ => None, 30 | } 31 | } 32 | } 33 | 34 | impl<'a, 'b> MutationsTypeWrapper<'a, 'b> { 35 | #[must_use] 36 | pub fn mutations(&self) -> Vec { 37 | self.doc 38 | .fields 39 | .iter() 40 | .map(|f| MutationTypeWrapper { 41 | doc: &f.node, 42 | context: self.context, 43 | }) 44 | .collect() 45 | } 46 | 47 | pub fn dependencies(&self) -> Vec { 48 | let mut dep: Vec = self 49 | .mutations() 50 | .iter() 51 | .flat_map(|f| f.dependencies()) 52 | .collect(); 53 | 54 | let mut arg_dep: Vec = self 55 | .mutations() 56 | .iter() 57 | .flat_map(|f| f.arguments_dependencies()) 58 | .collect(); 59 | dep.append(&mut arg_dep); 60 | dep 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/document_wrapper/object_type_wrapper.rs: -------------------------------------------------------------------------------- 1 | use async_graphql_parser::schema::ObjectType; 2 | 3 | use super::{BaseType, FieldWrapper, FileRender, RenderType, SupportFields}; 4 | 5 | pub type ObjectTypeWrapper<'a, 'b> = BaseType<'a, 'b, ObjectType>; 6 | 7 | impl<'a, 'b> FileRender for ObjectTypeWrapper<'a, 'b> { 8 | fn super_module_name(&self) -> String { 9 | "object_type".to_string() 10 | } 11 | } 12 | 13 | impl<'a, 'b> RenderType for ObjectTypeWrapper<'a, 'b> { 14 | #[must_use] 15 | fn name(&self) -> String { 16 | self.doc.name.node.clone() 17 | } 18 | 19 | #[must_use] 20 | fn description(&self) -> Option<&String> { 21 | match &self.doc.description { 22 | Some(_f) => panic!("Not Implemented"), 23 | _ => None, 24 | } 25 | } 26 | } 27 | 28 | impl<'a, 'b> SupportFields for ObjectTypeWrapper<'a, 'b> { 29 | #[must_use] 30 | fn fields(&self) -> Vec { 31 | self.doc 32 | .fields 33 | .iter() 34 | .map(|f| FieldWrapper { 35 | doc: &f.node, 36 | context: self.context, 37 | }) 38 | .collect() 39 | } 40 | } 41 | 42 | impl<'a, 'b> ObjectTypeWrapper<'a, 'b> { 43 | pub fn implements_interfaces(&self) -> Vec { 44 | self.doc 45 | .implements_interfaces 46 | .iter() 47 | .map(|f| f.node.clone()) 48 | .collect() 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/document_wrapper/scalar_type_wrapper.rs: -------------------------------------------------------------------------------- 1 | use async_graphql_parser::schema::ScalarType; 2 | 3 | use super::{BaseType, FileRender, RenderType}; 4 | 5 | pub type ScalarTypeWrapper<'a, 'b> = BaseType<'a, 'b, ScalarType>; 6 | 7 | impl<'a, 'b> FileRender for ScalarTypeWrapper<'a, 'b> { 8 | fn super_module_name(&self) -> String { 9 | "scalar_type".to_string() 10 | } 11 | } 12 | 13 | impl<'a, 'b> RenderType for ScalarTypeWrapper<'a, 'b> { 14 | #[must_use] 15 | fn name(&self) -> String { 16 | self.doc.name.node.clone() 17 | } 18 | 19 | #[must_use] 20 | fn description(&self) -> Option<&String> { 21 | match &self.doc.description { 22 | Some(_f) => panic!("Not Implemented"), 23 | _ => None, 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/document_wrapper/subscription_root_type_wrapper.rs: -------------------------------------------------------------------------------- 1 | use async_graphql_parser::schema::ObjectType; 2 | 3 | use super::{Context, Dependency, FileRender, RenderType, SubscriptionTypeWrapper, SupportField}; 4 | 5 | pub struct SubscriptionRootTypeWrapper<'a, 'b> { 6 | pub doc: &'a ObjectType, 7 | pub context: &'a Context<'b>, 8 | } 9 | 10 | impl<'a, 'b> FileRender for SubscriptionRootTypeWrapper<'a, 'b> { 11 | fn super_module_name(&self) -> String { 12 | "subscription_type".to_string() 13 | } 14 | } 15 | 16 | impl<'a, 'b> RenderType for SubscriptionRootTypeWrapper<'a, 'b> { 17 | #[must_use] 18 | fn name(&self) -> String { 19 | self.doc.name.node.clone() 20 | } 21 | 22 | #[must_use] 23 | fn description(&self) -> Option<&String> { 24 | match &self.doc.description { 25 | Some(_f) => panic!("Not Implemented"), 26 | _ => None, 27 | } 28 | } 29 | } 30 | 31 | impl<'a, 'b> SubscriptionRootTypeWrapper<'a, 'b> { 32 | #[must_use] 33 | pub fn mutations(&self) -> Vec { 34 | self.doc 35 | .fields 36 | .iter() 37 | .map(|f| SubscriptionTypeWrapper { 38 | doc: &f.node, 39 | context: self.context, 40 | }) 41 | .collect() 42 | } 43 | 44 | pub fn dependencies(&self) -> Vec { 45 | self.mutations() 46 | .iter() 47 | .flat_map(|f| f.arguments_dependencies()) 48 | .collect() 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/document_wrapper/subscription_type_wrapper.rs: -------------------------------------------------------------------------------- 1 | use async_graphql_parser::schema::{Field, InputValue, Type}; 2 | 3 | use super::{Context, RenderType, SupportField, SupportType, UseContext}; 4 | 5 | pub struct SubscriptionTypeWrapper<'a, 'b> { 6 | pub doc: &'a Field, 7 | pub context: &'a Context<'b>, 8 | } 9 | 10 | impl<'a, 'b> SupportType for SubscriptionTypeWrapper<'a, 'b> { 11 | fn ty(&self) -> &Type { 12 | &self.doc.ty.node 13 | } 14 | } 15 | 16 | impl<'a, 'b> UseContext for SubscriptionTypeWrapper<'a, 'b> { 17 | fn context(&self) -> &Context { 18 | self.context 19 | } 20 | } 21 | 22 | impl<'a, 'b> SupportField for SubscriptionTypeWrapper<'a, 'b> { 23 | fn input_value_types(&self) -> Vec<&InputValue> { 24 | let mut res = vec![]; 25 | self.doc.arguments.iter().for_each(|f| res.push(&f.node)); 26 | res 27 | } 28 | } 29 | 30 | impl<'a, 'b> RenderType for SubscriptionTypeWrapper<'a, 'b> { 31 | #[must_use] 32 | fn name(&self) -> String { 33 | self.doc.name.node.clone() 34 | } 35 | 36 | #[must_use] 37 | fn description(&self) -> Option<&String> { 38 | match &self.doc.description { 39 | Some(_f) => panic!("Not Implemented"), 40 | _ => None, 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/document_wrapper/type_wrapper.rs: -------------------------------------------------------------------------------- 1 | use super::{snake_case, Context, FieldWrapper, InputValueWrapper}; 2 | use async_graphql_parser::schema::{InputValue, Type}; 3 | 4 | pub trait RenderType { 5 | fn name(&self) -> String; 6 | fn description(&self) -> Option<&String>; 7 | 8 | #[must_use] 9 | fn field_name(&self) -> String { 10 | snake_case(&self.name()) 11 | } 12 | } 13 | 14 | #[derive(Debug, Clone)] 15 | pub struct ObjectPath { 16 | pub super_module_name: String, 17 | pub module_name: String, 18 | pub name: String, 19 | } 20 | 21 | pub type Dependency = ObjectPath; 22 | 23 | pub trait FileRender: RenderType { 24 | #[must_use] 25 | fn file_name(&self) -> String { 26 | snake_case(&self.name()) 27 | } 28 | 29 | fn super_module_name(&self) -> String; 30 | 31 | fn path(&self) -> ObjectPath { 32 | ObjectPath { 33 | super_module_name: self.super_module_name(), 34 | module_name: self.file_name(), 35 | name: self.name(), 36 | } 37 | } 38 | } 39 | 40 | #[derive(Debug, Clone)] 41 | pub struct BaseType<'a, 'b, T> { 42 | pub doc: &'a T, 43 | pub context: &'a Context<'b>, 44 | } 45 | 46 | pub trait UseContext { 47 | fn context(&self) -> &Context; 48 | } 49 | 50 | pub trait SupportFields { 51 | #[must_use] 52 | fn fields(&self) -> Vec; 53 | 54 | #[must_use] 55 | fn dependencies(&self) -> Vec { 56 | self.fields() 57 | .into_iter() 58 | .flat_map(|f| f.dependencies()) 59 | .collect() 60 | } 61 | 62 | fn field_partition(&self) -> (Vec, Vec) { 63 | self.fields().into_iter().partition(FieldWrapper::is_scalar) 64 | } 65 | 66 | fn custom_fields(&self) -> Vec { 67 | self.field_partition().1 68 | } 69 | 70 | fn scalar_fields(&self) -> Vec { 71 | self.field_partition().0 72 | } 73 | } 74 | 75 | pub trait SupportField: UseContext { 76 | fn input_value_types(&self) -> Vec<&InputValue>; 77 | 78 | fn arguments(&self) -> Vec { 79 | self.input_value_types() 80 | .iter() 81 | .map(|f| InputValueWrapper { 82 | doc: f, 83 | context: self.context(), 84 | }) 85 | .collect() 86 | } 87 | 88 | fn fields(&self) -> Vec { 89 | self.arguments() 90 | } 91 | 92 | fn arguments_dependencies(&self) -> Vec { 93 | self.arguments() 94 | .iter() 95 | .flat_map(|f| f.dependencies()) 96 | .collect() 97 | } 98 | } 99 | 100 | pub trait SupportType: RenderType { 101 | #[must_use] 102 | fn ty(&self) -> &Type; 103 | 104 | #[must_use] 105 | fn non_null(&self) -> bool { 106 | match &self.ty() { 107 | Type::NonNull(_t) => true, 108 | _ => false, 109 | } 110 | } 111 | 112 | #[must_use] 113 | fn is_list(&self) -> bool { 114 | match &self.ty() { 115 | Type::List(_t) => true, 116 | Type::NonNull(t) => match &**t { 117 | Type::List(_t) => true, 118 | _ => false, 119 | }, 120 | _ => false, 121 | } 122 | } 123 | 124 | #[must_use] 125 | fn type_name(&self) -> String { 126 | match &self.ty() { 127 | Type::Named(name) => name.clone(), 128 | Type::NonNull(t) | Type::List(t) => Self::nested_type_name(t), 129 | } 130 | } 131 | 132 | #[must_use] 133 | fn nested_type_name(t: &Type) -> String { 134 | match &*t { 135 | Type::Named(name) => name.clone(), 136 | Type::List(t) => match &**t { 137 | Type::Named(name) => name.clone(), 138 | _ => unreachable!("Not Implemented"), 139 | }, 140 | _ => unreachable!("Not Implemented"), 141 | } 142 | } 143 | 144 | #[must_use] 145 | fn code_type_name(&self) -> String { 146 | let name = self.type_name(); 147 | match name.as_str() { 148 | "Bool" | "Boolean" => "bool".to_string(), 149 | "Int" => "i32".to_string(), 150 | "Float" => "f64".to_string(), 151 | "ID" => "ID".to_string(), 152 | _ => name.to_string(), 153 | } 154 | } 155 | } 156 | 157 | #[derive(Debug, Clone)] 158 | pub enum ScalarTypeOnScalar { 159 | DefaultScalar, 160 | CustomScalar, 161 | } 162 | 163 | pub trait SupportTypeName: SupportType + UseContext { 164 | fn scalar_type(&self) -> Option { 165 | let names = self.context().scalar_names(); 166 | let name = &self.type_name(); 167 | match name.as_str() { 168 | "String" | "Bool" | "Int" | "Float" | "ID" => Some(ScalarTypeOnScalar::DefaultScalar), 169 | _ => { 170 | if names.iter().any(|f| f == name) { 171 | Some(ScalarTypeOnScalar::CustomScalar) 172 | } else { 173 | None 174 | } 175 | } 176 | } 177 | } 178 | 179 | fn is_default_scalar(&self) -> bool { 180 | match &self.scalar_type() { 181 | Some(t) => match t { 182 | ScalarTypeOnScalar::DefaultScalar => true, 183 | _ => false, 184 | }, 185 | _ => false, 186 | } 187 | } 188 | 189 | #[must_use] 190 | fn module_name(&self) -> Option { 191 | if self.is_default_scalar() { 192 | return None; 193 | } 194 | 195 | let name = self.code_type_name(); 196 | Some(snake_case(&name)) 197 | } 198 | 199 | #[must_use] 200 | fn is_scalar(&self) -> bool { 201 | match &self.scalar_type() { 202 | Some(_t) => true, 203 | _ => false, 204 | } 205 | } 206 | 207 | fn is_input_object_type(&self) -> bool { 208 | let names = self.context().input_object_type_names(); 209 | let name = &self.type_name(); 210 | names.iter().any(|f| f == name) 211 | } 212 | 213 | fn is_union(&self) -> bool { 214 | let names = self.context().union_names(); 215 | let name = &self.type_name(); 216 | names.iter().any(|f| f == name) 217 | } 218 | 219 | #[must_use] 220 | fn is_custom_scalar(&self) -> bool { 221 | match &self.scalar_type() { 222 | Some(t) => match t { 223 | ScalarTypeOnScalar::CustomScalar => true, 224 | _ => false, 225 | }, 226 | _ => false, 227 | } 228 | } 229 | 230 | fn super_module_name(&self) -> Option { 231 | if self.is_custom_scalar() { 232 | return Some("scalar_type".to_string()); 233 | } else if self.is_union() { 234 | return Some("union_type".to_string()); 235 | } else if self.is_input_object_type() { 236 | return Some("input_object_type".to_string()); 237 | } else if !self.is_scalar() { 238 | return Some("object_type".to_string()); 239 | }; 240 | None 241 | } 242 | 243 | #[must_use] 244 | fn dependencies(&self) -> Vec { 245 | match self.super_module_name() { 246 | Some(super_module_name) => { 247 | let dep = Dependency { 248 | super_module_name, 249 | module_name: self.module_name().unwrap(), 250 | name: self.type_name(), 251 | }; 252 | return vec![dep]; 253 | } 254 | None => vec![], 255 | } 256 | } 257 | 258 | fn struct_name(&self) -> String { 259 | let name = self.code_type_name(); 260 | match (self.non_null(), self.is_list()) { 261 | (true, false) => name, 262 | (true, true) => format!("Vec<{}>", name), 263 | (false, false) => format!("Option<{}>", name), 264 | (false, true) => format!("Option>", name), 265 | } 266 | } 267 | } 268 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/document_wrapper/union_type_wrapper.rs: -------------------------------------------------------------------------------- 1 | use async_graphql_parser::schema::UnionType; 2 | 3 | use super::{BaseType, Dependency, FileRender, ObjectTypeWrapper, RenderType}; 4 | 5 | pub type UnionTypeWrapper<'a, 'b> = BaseType<'a, 'b, UnionType>; 6 | 7 | impl<'a, 'b> FileRender for UnionTypeWrapper<'a, 'b> { 8 | fn super_module_name(&self) -> String { 9 | "union_type".to_string() 10 | } 11 | } 12 | 13 | impl<'a, 'b> RenderType for UnionTypeWrapper<'a, 'b> { 14 | #[must_use] 15 | fn name(&self) -> String { 16 | self.doc.name.node.clone() 17 | } 18 | 19 | #[must_use] 20 | fn description(&self) -> Option<&String> { 21 | match &self.doc.description { 22 | Some(_f) => panic!("Not Implemented"), 23 | _ => None, 24 | } 25 | } 26 | } 27 | 28 | impl<'a, 'b> UnionTypeWrapper<'a, 'b> { 29 | pub fn dependencies(&self) -> Vec { 30 | self.implemented_object_types() 31 | .into_iter() 32 | .map(|f| Dependency { 33 | super_module_name: f.super_module_name(), 34 | module_name: f.file_name(), 35 | name: f.name(), 36 | }) 37 | .collect() 38 | } 39 | 40 | pub fn members(&self) -> Vec { 41 | self.doc.members.iter().map(|f| f.node.clone()).collect() 42 | } 43 | 44 | pub fn implemented_object_types(&self) -> Vec { 45 | self.context 46 | .object_types() 47 | .into_iter() 48 | .filter(|f| self.members().iter().any(|name| *name == f.name())) 49 | .collect() 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod base; 2 | mod document_wrapper; 3 | mod renderer; 4 | 5 | pub use base::{generate_from_path, Config}; 6 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/input_object/mod.rs: -------------------------------------------------------------------------------- 1 | mod renderer; 2 | 3 | use super::{ 4 | Context, FieldRenderer, FileRender, InputObjectTypeWrapper, Output, RenderDependencies, 5 | RenderType, Save, SupportField, 6 | }; 7 | 8 | use renderer::Renderer; 9 | 10 | use proc_macro2::TokenStream; 11 | 12 | pub struct Generate {} 13 | 14 | impl Output for Generate { 15 | fn generate_files(context: &Context) { 16 | context.clone().input_object_types().iter().for_each(|f| { 17 | Renderer::create_file(f); 18 | }); 19 | } 20 | 21 | fn generate_token_stream(context: &Context) -> Vec { 22 | context 23 | .clone() 24 | .input_object_types() 25 | .iter() 26 | .map(|f| Renderer::new_and_token_stream(f)) 27 | .collect() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/input_object/renderer.rs: -------------------------------------------------------------------------------- 1 | use quote::quote; 2 | 3 | use proc_macro2::{Ident, Span, TokenStream}; 4 | 5 | use super::{ 6 | FieldRenderer, FileRender, InputObjectTypeWrapper, RenderDependencies, RenderType, Save, 7 | SupportField, 8 | }; 9 | 10 | pub struct Renderer<'a, 'b> { 11 | wrapper_object: &'a InputObjectTypeWrapper<'a, 'b>, 12 | } 13 | 14 | impl<'a, 'b> RenderDependencies for Renderer<'a, 'b> {} 15 | 16 | impl<'a, 'b> Save for Renderer<'a, 'b> { 17 | fn file_name(&self) -> String { 18 | self.wrapper_object.file_name() 19 | } 20 | 21 | fn super_module_name(&self) -> Option { 22 | Some(self.wrapper_object.path().super_module_name) 23 | } 24 | 25 | fn str_src(&self) -> String { 26 | Renderer::token_stream(self).to_string() 27 | } 28 | } 29 | 30 | impl<'a, 'b> Renderer<'a, 'b> { 31 | pub fn create_file(wrapper_object: &'a InputObjectTypeWrapper<'a, 'b>) { 32 | let obj = Self { wrapper_object }; 33 | obj.save(wrapper_object.context); 34 | } 35 | 36 | pub fn new_and_token_stream(wrapper_object: &'a InputObjectTypeWrapper<'a, 'b>) -> TokenStream { 37 | let obj = Self { wrapper_object }; 38 | obj.token_stream() 39 | } 40 | 41 | fn token_stream(&self) -> TokenStream { 42 | let field_properties_token = self.field_properties_token(); 43 | let name = Ident::new(&self.wrapper_object.name(), Span::call_site()); 44 | 45 | quote!( 46 | use async_graphql::*; 47 | 48 | #[InputObject] 49 | pub struct #name { 50 | #field_properties_token 51 | } 52 | ) 53 | } 54 | 55 | fn field_properties_token(&self) -> TokenStream { 56 | let mut res = quote!(); 57 | self.wrapper_object.fields().iter().for_each(|f| { 58 | let field_property_token = FieldRenderer::field_property_token(f); 59 | res = quote!( 60 | #res 61 | #field_property_token 62 | ) 63 | }); 64 | res 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/interface/mod.rs: -------------------------------------------------------------------------------- 1 | mod renderer; 2 | 3 | use super::{ 4 | Context, FieldRenderer, FileRender, InterfaceTypeWrapper, Output, RenderDependencies, 5 | RenderType, Save, SupportFields, 6 | }; 7 | 8 | use renderer::Renderer; 9 | 10 | use proc_macro2::TokenStream; 11 | 12 | pub struct Generate {} 13 | 14 | impl Output for Generate { 15 | fn generate_files(context: &Context) { 16 | context.clone().interface_types().iter().for_each(|f| { 17 | Renderer::create_file(f); 18 | }); 19 | } 20 | 21 | fn generate_token_stream(context: &Context) -> Vec { 22 | context 23 | .clone() 24 | .interface_types() 25 | .iter() 26 | .map(|f| Renderer::new_and_token_stream(f)) 27 | .collect() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/interface/renderer.rs: -------------------------------------------------------------------------------- 1 | use quote::quote; 2 | 3 | use proc_macro2::{Ident, Span, TokenStream}; 4 | 5 | use super::{ 6 | FieldRenderer, FileRender, InterfaceTypeWrapper, RenderDependencies, RenderType, Save, 7 | SupportFields, 8 | }; 9 | 10 | pub struct Renderer<'a, 'b> { 11 | wrapper_object: &'a InterfaceTypeWrapper<'a, 'b>, 12 | } 13 | 14 | impl<'a, 'b> RenderDependencies for Renderer<'a, 'b> {} 15 | 16 | impl<'a, 'b> Save for Renderer<'a, 'b> { 17 | fn file_name(&self) -> String { 18 | self.wrapper_object.file_name() 19 | } 20 | 21 | fn super_module_name(&self) -> Option { 22 | Some(self.wrapper_object.path().super_module_name) 23 | } 24 | 25 | fn str_src(&self) -> String { 26 | Renderer::token_stream(self).to_string() 27 | } 28 | } 29 | 30 | impl<'a, 'b> Renderer<'a, 'b> { 31 | pub fn create_file(wrapper_object: &'a InterfaceTypeWrapper<'a, 'b>) { 32 | let obj = Self { wrapper_object }; 33 | obj.save(wrapper_object.context); 34 | } 35 | 36 | pub fn new_and_token_stream(wrapper_object: &'a InterfaceTypeWrapper<'a, 'b>) -> TokenStream { 37 | let obj = Self { wrapper_object }; 38 | obj.token_stream() 39 | } 40 | 41 | fn token_stream(&self) -> TokenStream { 42 | let name = self.name_token(); 43 | let fields = self.struct_properties_token(); 44 | let dependencies = self.dependencies_token(); 45 | let enum_properties = self.enum_properties(); 46 | 47 | Self::object_type_code(&name, &fields, &dependencies, &enum_properties) 48 | } 49 | 50 | pub fn name_token(&self) -> TokenStream { 51 | let name = Ident::new(&self.wrapper_object.name(), Span::call_site()); 52 | quote!(#name) 53 | } 54 | 55 | pub fn enum_properties(&self) -> TokenStream { 56 | let mut res = quote!(); 57 | self.wrapper_object 58 | .implemented_object_types() 59 | .iter() 60 | .for_each(|f| { 61 | let name = Ident::new(&f.name(), Span::call_site()); 62 | res = quote!( 63 | #res 64 | #name(#name), 65 | ) 66 | }); 67 | res 68 | } 69 | 70 | fn dependencies_token(&self) -> TokenStream { 71 | let dep = Self::render_dependencies(self.wrapper_object.dependencies()); 72 | quote!( 73 | use async_graphql::*; 74 | #dep 75 | ) 76 | } 77 | 78 | fn struct_properties_token(&self) -> TokenStream { 79 | let mut properties = quote! {}; 80 | self.wrapper_object.scalar_fields().iter().for_each(|f| { 81 | let field_property = FieldRenderer::field_interface_token(f); 82 | properties = quote!( 83 | #properties 84 | #field_property, 85 | ); 86 | }); 87 | properties 88 | } 89 | 90 | fn object_type_code( 91 | name: &TokenStream, 92 | fields: &TokenStream, 93 | dependencies: &TokenStream, 94 | enum_peoperties: &TokenStream, 95 | ) -> TokenStream { 96 | quote!( 97 | #dependencies 98 | 99 | #[Interface( 100 | #fields 101 | )] 102 | pub enum #name { 103 | #enum_peoperties 104 | } 105 | ) 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/internal/dependencies.rs: -------------------------------------------------------------------------------- 1 | use proc_macro2::{Ident, Span, TokenStream}; 2 | use quote::quote; 3 | 4 | use super::Dependency; 5 | 6 | pub trait Render { 7 | fn render_dependencies(dependencies: Vec) -> TokenStream { 8 | let mut res = quote!(); 9 | dependencies.iter().for_each(|f| { 10 | let super_module_name = Ident::new(&f.super_module_name, Span::call_site()); 11 | let module_name = Ident::new(&f.module_name, Span::call_site()); 12 | let name = Ident::new(&f.name, Span::call_site()); 13 | res = quote!( 14 | #res 15 | use super::super::#super_module_name::#module_name::#name; 16 | ) 17 | }); 18 | res 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/internal/field.rs: -------------------------------------------------------------------------------- 1 | use proc_macro2::{Ident, Span, TokenStream}; 2 | use quote::quote; 3 | 4 | use super::{SupportField, SupportType, SupportTypeName}; 5 | 6 | pub trait Render { 7 | fn field_name_token(f: &T) -> TokenStream 8 | where 9 | T: SupportType, 10 | { 11 | let name = f.field_name(); 12 | let name = Ident::new(name.as_str(), Span::call_site()); 13 | quote!(#name) 14 | } 15 | 16 | fn struct_name_token(f: &T) -> TokenStream 17 | where 18 | T: SupportType, 19 | { 20 | let name = f.code_type_name(); 21 | let name = Ident::new(&name, Span::call_site()); 22 | match (f.non_null(), f.is_list()) { 23 | (true, false) => quote!(#name), 24 | (true, true) => quote!(Vec<#name>), 25 | (false, false) => quote!(Option<#name>), 26 | (false, true) => quote!(Option>), 27 | } 28 | } 29 | } 30 | 31 | pub struct Renderer {} 32 | 33 | impl Render for Renderer {} 34 | 35 | impl Renderer { 36 | fn arguments_token(f: &T) -> TokenStream 37 | where 38 | T: SupportTypeName + SupportType + SupportField, 39 | { 40 | let mut res = quote!(); 41 | f.arguments().iter().for_each(|f| { 42 | let code_type_name = Self::struct_name_token(f); 43 | let field_name = Ident::new(&f.field_name(), Span::call_site()); 44 | res = quote!( 45 | #res 46 | #field_name: #code_type_name, 47 | ); 48 | }); 49 | res 50 | } 51 | 52 | fn arguments_variebles(f: &T) -> TokenStream 53 | where 54 | T: SupportTypeName + SupportType + SupportField, 55 | { 56 | let mut res = quote!(); 57 | f.arguments().iter().for_each(|f| { 58 | let field_name = Ident::new(&f.field_name(), Span::call_site()); 59 | res = quote!( 60 | #res 61 | #field_name, 62 | ); 63 | }); 64 | res 65 | } 66 | 67 | pub fn custom_field_token(f: &T) -> TokenStream 68 | where 69 | T: SupportTypeName + SupportType + SupportField, 70 | { 71 | let n = &Self::field_name_token(f); 72 | let ty = &Self::struct_name_token(f); 73 | let arguments = Self::arguments_token(f); 74 | let arguments_variebles = Self::arguments_variebles(f); 75 | let field = match f.description() { 76 | Some(desc) => quote!(#[field(desc = #desc)]), 77 | None => quote!(), 78 | }; 79 | quote!( 80 | #field 81 | pub async fn #n(&self, ctx: &Context<'_>, #arguments ) -> #ty { 82 | ctx.data_unchecked::().#n(#arguments_variebles) 83 | } 84 | ) 85 | } 86 | 87 | pub fn scalar_fields_token(f: &T) -> TokenStream 88 | where 89 | T: SupportTypeName + SupportType, 90 | { 91 | let n = &Self::field_name_token(f); 92 | let ty = &Self::struct_name_token(f); 93 | quote!( 94 | pub async fn #n(&self) -> #ty { 95 | self.#n.clone() 96 | } 97 | ) 98 | } 99 | 100 | pub fn field_property_token(f: &T) -> TokenStream 101 | where 102 | T: SupportTypeName + SupportType, 103 | { 104 | let n = &Self::field_name_token(f); 105 | let ty = &Self::struct_name_token(f); 106 | quote!( 107 | pub #n : #ty 108 | ) 109 | } 110 | 111 | pub fn field_interface_token(f: &T) -> TokenStream 112 | where 113 | T: SupportTypeName + SupportType, 114 | { 115 | let n = f.field_name(); 116 | let ty = f.struct_name(); 117 | quote!( 118 | field(name = #n, type = #ty) 119 | ) 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/internal/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod dependencies; 2 | pub mod field; 3 | 4 | use super::{Dependency, SupportField, SupportType, SupportTypeName}; 5 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/mod.rs: -------------------------------------------------------------------------------- 1 | mod input_object; 2 | mod interface; 3 | mod mod_file; 4 | mod mutation; 5 | mod object_type; 6 | mod output; 7 | mod save; 8 | mod scalar; 9 | mod subscription; 10 | mod union_type; 11 | 12 | mod internal; 13 | 14 | use internal::dependencies::Render as RenderDependencies; 15 | use internal::field::Render as RenderField; 16 | use internal::field::Renderer as FieldRenderer; 17 | 18 | use output::Output; 19 | use save::Save; 20 | 21 | use crate::base::Context; 22 | 23 | use crate::document_wrapper::{ 24 | Dependency, FileRender, InputObjectTypeWrapper, InterfaceTypeWrapper, MutationTypeWrapper, 25 | MutationsTypeWrapper, ObjectPath, ObjectTypeWrapper, RenderType, ScalarTypeWrapper, 26 | SubscriptionRootTypeWrapper, SubscriptionTypeWrapper, SupportField, SupportFields, SupportType, 27 | SupportTypeName, UnionTypeWrapper, 28 | }; 29 | 30 | pub fn render_to_files(context: &Context) { 31 | interface::Generate::generate_files(context); 32 | object_type::Generate::generate_files(context); 33 | mutation::Generate::generate_files(context); 34 | subscription::Generate::generate_files(context); 35 | scalar::Generate::generate_files(context); 36 | input_object::Generate::generate_files(context); 37 | union_type::Generate::generate_files(context); 38 | mod_file::Generate::generate_files(context); 39 | } 40 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/mod_file/mod.rs: -------------------------------------------------------------------------------- 1 | mod root_module_renderer; 2 | mod sub_module_renderer; 3 | 4 | use proc_macro2::TokenStream; 5 | 6 | use super::{Context, ObjectPath, Output, Save}; 7 | 8 | pub struct Generate {} 9 | 10 | impl Output for Generate { 11 | fn generate_files(context: &Context) { 12 | context.structured_file_paths().iter().for_each(|f| { 13 | sub_module_renderer::Renderer::create_file(f.0, f.1, context); 14 | }); 15 | root_module_renderer::Renderer::create_file(context) 16 | } 17 | 18 | fn generate_token_stream(_context: &Context) -> Vec { 19 | panic!("generate_token_stream") 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/mod_file/root_module_renderer.rs: -------------------------------------------------------------------------------- 1 | use proc_macro2::{Ident, Span, TokenStream}; 2 | use quote::quote; 3 | 4 | use super::{Context, Save}; 5 | 6 | pub struct Renderer<'a, 'b> { 7 | pub context: &'a Context<'b>, 8 | } 9 | 10 | impl<'a, 'b> Save for Renderer<'a, 'b> { 11 | fn file_name(&self) -> String { 12 | "mod".to_string() 13 | } 14 | 15 | fn super_module_name(&self) -> Option { 16 | None 17 | } 18 | 19 | fn str_src(&self) -> String { 20 | Renderer::token_stream(self).to_string() 21 | } 22 | } 23 | 24 | impl<'a, 'b> Renderer<'a, 'b> { 25 | pub fn create_file(context: &'a Context<'b>) { 26 | let obj = Self { context }; 27 | obj.save(context); 28 | } 29 | 30 | fn token_stream(&self) -> TokenStream { 31 | let src = quote!( 32 | use crate::DataSource; 33 | use super::ResolveMutation; 34 | ); 35 | let modules = self.modules(); 36 | let uses = self.uses(); 37 | quote!( 38 | #src 39 | #modules 40 | #uses 41 | ) 42 | } 43 | 44 | fn modules(&self) -> TokenStream { 45 | let mut src = quote!(); 46 | self.context.structured_file_paths().iter().for_each(|f| { 47 | let name = Ident::new(f.0, Span::call_site()); 48 | src = quote!( 49 | #src 50 | pub mod #name; 51 | ); 52 | }); 53 | src 54 | } 55 | 56 | fn uses(&self) -> TokenStream { 57 | let mut src = quote!(); 58 | self.context.file_paths().iter().for_each(|f| { 59 | let super_module_name = Ident::new(&f.super_module_name, Span::call_site()); 60 | let module_name = Ident::new(&f.module_name, Span::call_site()); 61 | let name = Ident::new(&f.name, Span::call_site()); 62 | src = quote!( 63 | #src 64 | pub use #super_module_name::#module_name::#name; 65 | ) 66 | }); 67 | src 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/mod_file/sub_module_renderer.rs: -------------------------------------------------------------------------------- 1 | use proc_macro2::{Ident, Span, TokenStream}; 2 | use quote::quote; 3 | 4 | use super::{Context, ObjectPath, Save}; 5 | 6 | pub struct Renderer<'a, 'b> { 7 | pub super_module_name: &'a str, 8 | pub object_paths: &'a [ObjectPath], 9 | pub context: &'a Context<'b>, 10 | } 11 | 12 | impl<'a, 'b> Save for Renderer<'a, 'b> { 13 | fn file_name(&self) -> String { 14 | "mod".to_string() 15 | } 16 | 17 | fn super_module_name(&self) -> Option { 18 | Some(self.super_module_name.to_string()) 19 | } 20 | 21 | fn str_src(&self) -> String { 22 | Renderer::token_stream(self).to_string() 23 | } 24 | } 25 | 26 | impl<'a, 'b> Renderer<'a, 'b> { 27 | pub fn create_file( 28 | super_module_name: &'a str, 29 | object_paths: &'a [ObjectPath], 30 | context: &'a Context<'b>, 31 | ) { 32 | let obj = Self { 33 | super_module_name, 34 | object_paths, 35 | context, 36 | }; 37 | obj.save(context); 38 | } 39 | 40 | fn token_stream(&self) -> TokenStream { 41 | let mut src = quote!( 42 | use crate::DataSource; 43 | use super::ResolveMutation; 44 | ); 45 | self.object_paths.iter().for_each(|f| { 46 | let name = Ident::new(&f.module_name, Span::call_site()); 47 | src = quote!( 48 | #src 49 | pub mod #name; 50 | ); 51 | }); 52 | src 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/mutation/mod.rs: -------------------------------------------------------------------------------- 1 | mod renderer; 2 | 3 | use proc_macro2::TokenStream; 4 | 5 | use super::{ 6 | Context, FileRender, MutationTypeWrapper, MutationsTypeWrapper, Output, RenderDependencies, 7 | RenderField, RenderType, Save, SupportField, SupportType, 8 | }; 9 | 10 | use renderer::Renderer; 11 | 12 | pub struct Generate {} 13 | 14 | impl Output for Generate { 15 | fn generate_files(context: &Context) { 16 | context.clone().mutation_types().iter().for_each(|f| { 17 | Renderer::create_file(f); 18 | }); 19 | } 20 | 21 | fn generate_token_stream(context: &Context) -> Vec { 22 | context 23 | .clone() 24 | .mutation_types() 25 | .iter() 26 | .map(|f| Renderer::new_and_token_stream(f)) 27 | .collect() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/mutation/renderer.rs: -------------------------------------------------------------------------------- 1 | use quote::quote; 2 | 3 | use proc_macro2::{Ident, Span, TokenStream}; 4 | 5 | use super::{ 6 | FileRender, MutationTypeWrapper, MutationsTypeWrapper, RenderDependencies, RenderField, 7 | RenderType, Save, SupportField, SupportType, 8 | }; 9 | 10 | pub struct Renderer<'a, 'b> { 11 | wrapper_object: &'a MutationsTypeWrapper<'a, 'b>, 12 | } 13 | 14 | impl<'a, 'b> RenderField for Renderer<'a, 'b> {} 15 | 16 | impl<'a, 'b> RenderDependencies for Renderer<'a, 'b> {} 17 | 18 | impl<'a, 'b> Save for Renderer<'a, 'b> { 19 | fn file_name(&self) -> String { 20 | self.wrapper_object.file_name() 21 | } 22 | 23 | fn super_module_name(&self) -> Option { 24 | Some(self.wrapper_object.path().super_module_name) 25 | } 26 | 27 | fn str_src(&self) -> String { 28 | Renderer::token_stream(self).to_string() 29 | } 30 | } 31 | 32 | impl<'a, 'b> Renderer<'a, 'b> { 33 | pub fn create_file(wrapper_object: &'a MutationsTypeWrapper<'a, 'b>) { 34 | let obj = Self { wrapper_object }; 35 | obj.save(wrapper_object.context); 36 | } 37 | 38 | pub fn new_and_token_stream(wrapper_object: &'a MutationsTypeWrapper<'a, 'b>) -> TokenStream { 39 | let obj = Self { wrapper_object }; 40 | obj.token_stream() 41 | } 42 | 43 | fn token_stream(&self) -> TokenStream { 44 | let mutations = self.mutations_tokens(); 45 | let dependencies = self.dependencies_token(); 46 | 47 | quote!( 48 | #dependencies 49 | 50 | pub struct Mutation; 51 | impl ResolveMutation for Mutation {} 52 | 53 | #[Object] 54 | impl Mutation { 55 | #mutations 56 | } 57 | ) 58 | } 59 | 60 | fn dependencies_token(&self) -> TokenStream { 61 | let dep = Self::render_dependencies(self.wrapper_object.dependencies()); 62 | quote!( 63 | use async_graphql::*; 64 | use super::ResolveMutation; 65 | 66 | #dep 67 | ) 68 | } 69 | 70 | fn resolver_body(f: &MutationTypeWrapper, arguments_variebles: &TokenStream) -> TokenStream { 71 | let field_name = &f.field_name(); 72 | let method_name = format!("{}_resolver", field_name); 73 | let method_name_token = Ident::new(&method_name, Span::call_site()); 74 | quote!(self.#method_name_token(#arguments_variebles)) 75 | } 76 | 77 | fn arguments_token(f: &MutationTypeWrapper) -> TokenStream { 78 | let mut res = quote!(); 79 | f.arguments().iter().for_each(|f| { 80 | let code_type_name = Ident::new(&f.code_type_name(), Span::call_site()); 81 | let field_name = Ident::new(&f.field_name(), Span::call_site()); 82 | res = quote!( 83 | #res 84 | #field_name: #code_type_name, 85 | ); 86 | }); 87 | res 88 | } 89 | 90 | fn arguments_variebles(f: &MutationTypeWrapper) -> TokenStream { 91 | let mut res = quote!(); 92 | f.arguments().iter().for_each(|f| { 93 | let field_name = Ident::new(&f.field_name(), Span::call_site()); 94 | res = quote!( 95 | #res 96 | #field_name, 97 | ); 98 | }); 99 | res 100 | } 101 | 102 | fn mutations_tokens(&self) -> TokenStream { 103 | let mut result = quote!(); 104 | self.wrapper_object.mutations().iter().for_each(|f| { 105 | let name = Self::field_name_token(f); 106 | let res = Self::struct_name_token(f); 107 | let arguments_variebles = Self::arguments_variebles(f); 108 | let resolver_body = Self::resolver_body(f, &arguments_variebles); 109 | let arguments = Self::arguments_token(f); 110 | 111 | result = quote!( 112 | #result 113 | 114 | async fn #name(&self, #arguments) -> #res { 115 | 116 | #resolver_body 117 | } 118 | ); 119 | }); 120 | result 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/object_type/mod.rs: -------------------------------------------------------------------------------- 1 | mod renderer; 2 | 3 | use proc_macro2::TokenStream; 4 | 5 | use super::{ 6 | Context, FieldRenderer, FileRender, ObjectTypeWrapper, Output, RenderDependencies, RenderType, 7 | Save, SupportFields, 8 | }; 9 | 10 | use renderer::Renderer; 11 | 12 | pub struct Generate {} 13 | 14 | impl Output for Generate { 15 | fn generate_files(context: &Context) { 16 | context.clone().object_types().iter().for_each(|f| { 17 | Renderer::create_file(f); 18 | }); 19 | } 20 | 21 | fn generate_token_stream(context: &Context) -> Vec { 22 | context 23 | .clone() 24 | .object_types() 25 | .iter() 26 | .map(|f| Renderer::new_and_token_stream(f)) 27 | .collect() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/object_type/renderer.rs: -------------------------------------------------------------------------------- 1 | use quote::quote; 2 | 3 | use proc_macro2::{Ident, Span, TokenStream}; 4 | 5 | use super::{ 6 | FieldRenderer, FileRender, ObjectTypeWrapper, RenderDependencies, RenderType, Save, 7 | SupportFields, 8 | }; 9 | 10 | pub struct Renderer<'a, 'b> { 11 | wrapper_object: &'a ObjectTypeWrapper<'a, 'b>, 12 | } 13 | 14 | impl<'a, 'b> RenderDependencies for Renderer<'a, 'b> {} 15 | 16 | impl<'a, 'b> Save for Renderer<'a, 'b> { 17 | fn file_name(&self) -> String { 18 | self.wrapper_object.file_name() 19 | } 20 | 21 | fn super_module_name(&self) -> Option { 22 | Some(self.wrapper_object.path().super_module_name) 23 | } 24 | 25 | fn str_src(&self) -> String { 26 | Renderer::token_stream(self).to_string() 27 | } 28 | } 29 | 30 | impl<'a, 'b> Renderer<'a, 'b> { 31 | pub fn create_file(wrapper_object: &'a ObjectTypeWrapper<'a, 'b>) { 32 | let obj = Self { wrapper_object }; 33 | obj.save(wrapper_object.context); 34 | } 35 | 36 | pub fn new_and_token_stream(wrapper_object: &'a ObjectTypeWrapper<'a, 'b>) -> TokenStream { 37 | let obj = Self { wrapper_object }; 38 | obj.token_stream() 39 | } 40 | 41 | fn token_stream(&self) -> TokenStream { 42 | let name = self.name_token(); 43 | let fields = self.custom_fields_token(); 44 | let struct_properties = self.struct_properties_token(); 45 | let scalar_fields_token = self.scalar_fields_token(); 46 | 47 | let dependencies = self.dependencies_token(); 48 | 49 | Self::object_type_code( 50 | &dependencies, 51 | &name, 52 | &struct_properties, 53 | &fields, 54 | &scalar_fields_token, 55 | ) 56 | } 57 | 58 | fn dependencies_token(&self) -> TokenStream { 59 | let dep = Self::render_dependencies(self.wrapper_object.dependencies()); 60 | quote!( 61 | use async_graphql::*; 62 | use super::DataSource; 63 | #dep 64 | ) 65 | } 66 | 67 | fn name_token(&self) -> TokenStream { 68 | let name = Ident::new(&self.wrapper_object.name(), Span::call_site()); 69 | quote!(#name) 70 | } 71 | 72 | fn struct_properties_token(&self) -> TokenStream { 73 | let mut properties = quote! {}; 74 | self.wrapper_object.scalar_fields().iter().for_each(|f| { 75 | let field_property = FieldRenderer::field_property_token(f); 76 | properties = quote!( 77 | #properties 78 | #field_property 79 | ); 80 | }); 81 | properties 82 | } 83 | 84 | fn custom_fields_token(&self) -> TokenStream { 85 | let mut fields = quote! {}; 86 | self.wrapper_object.custom_fields().iter().for_each(|f| { 87 | let field = &FieldRenderer::custom_field_token(f); 88 | fields = quote!( 89 | #fields 90 | #field 91 | ); 92 | }); 93 | fields 94 | } 95 | 96 | fn object_type_code( 97 | dependencies: &TokenStream, 98 | name: &TokenStream, 99 | struct_properties: &TokenStream, 100 | fields: &TokenStream, 101 | scalar_fields_token: &TokenStream, 102 | ) -> TokenStream { 103 | quote!( 104 | #dependencies 105 | 106 | #[derive(Debug)] 107 | pub struct #name { 108 | #struct_properties 109 | } 110 | 111 | #[Object] 112 | impl #name { 113 | #fields 114 | #scalar_fields_token 115 | } 116 | ) 117 | } 118 | 119 | fn scalar_fields_token(&self) -> TokenStream { 120 | let mut scalar_fields = quote! {}; 121 | self.wrapper_object.scalar_fields().iter().for_each(|f| { 122 | let field = FieldRenderer::scalar_fields_token(f); 123 | scalar_fields = quote!( 124 | #scalar_fields 125 | #field 126 | ); 127 | }); 128 | scalar_fields 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/output.rs: -------------------------------------------------------------------------------- 1 | use proc_macro2::TokenStream; 2 | 3 | use super::Context; 4 | 5 | pub trait Output { 6 | fn generate_files(context: &Context); 7 | fn generate_token_stream(context: &Context) -> Vec; 8 | } 9 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/save.rs: -------------------------------------------------------------------------------- 1 | use std::fs; 2 | use std::io::Write; 3 | use std::path::Path; 4 | 5 | use super::Context; 6 | 7 | use std::process::{Command, Stdio}; 8 | 9 | fn path_format(name: &str, path: &str) -> String { 10 | format!("{}/{}.rs", path, name) 11 | } 12 | 13 | fn create_or_get_path(base_path: &str, super_module_name: Option) -> String { 14 | match super_module_name { 15 | Some(f) => { 16 | let d = format!("{}/{}", base_path, f); 17 | if !Path::new(&d).exists() { 18 | fs::create_dir(&d).expect("Error"); 19 | }; 20 | d 21 | } 22 | None => base_path.to_string(), 23 | } 24 | } 25 | 26 | fn prepare_path(base_path: &str, super_module_name: Option, file_name: &str) -> String { 27 | if !Path::new(base_path).exists() { 28 | panic!("Does not exist: {}", base_path); 29 | } 30 | let dir = create_or_get_path(base_path, super_module_name); 31 | path_format(file_name, dir.as_str()) 32 | } 33 | 34 | pub fn lint(path: &str) { 35 | let rustfmt = toolchain_find::find_installed_component("rustfmt").unwrap(); 36 | Command::new(&rustfmt) 37 | .arg("--edition=2018") 38 | .arg(path) 39 | .stderr(Stdio::null()) 40 | .output() 41 | .expect("rustfmt error"); 42 | } 43 | 44 | pub trait Save { 45 | fn file_name(&self) -> String; 46 | 47 | fn str_src(&self) -> String; 48 | 49 | fn super_module_name(&self) -> Option; 50 | 51 | fn save(&self, context: &Context) { 52 | let path = prepare_path( 53 | &context.config.output_bnase_path, 54 | self.super_module_name(), 55 | &self.file_name(), 56 | ); 57 | let mut f = fs::File::create(&path).unwrap(); 58 | f.write_all(self.str_src().as_bytes()).unwrap(); 59 | lint(&path); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/scalar/mod.rs: -------------------------------------------------------------------------------- 1 | mod renderer; 2 | 3 | use super::{Context, FileRender, Output, RenderType, Save, ScalarTypeWrapper}; 4 | 5 | use proc_macro2::TokenStream; 6 | 7 | use renderer::Renderer; 8 | 9 | pub struct Generate {} 10 | 11 | impl Output for Generate { 12 | fn generate_files(context: &Context) { 13 | context.clone().scalar_types().iter().for_each(|f| { 14 | Renderer::create_file(f); 15 | }); 16 | } 17 | 18 | fn generate_token_stream(context: &Context) -> Vec { 19 | context 20 | .clone() 21 | .scalar_types() 22 | .iter() 23 | .map(|f| Renderer::new_and_token_stream(f)) 24 | .collect() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/scalar/renderer.rs: -------------------------------------------------------------------------------- 1 | use super::{FileRender, RenderType, Save, ScalarTypeWrapper}; 2 | 3 | use quote::quote; 4 | 5 | use proc_macro2::{Ident, Span, TokenStream}; 6 | 7 | pub struct Renderer<'a, 'b> { 8 | wrapper_object: &'a ScalarTypeWrapper<'a, 'b>, 9 | } 10 | 11 | impl<'a, 'b> Save for Renderer<'a, 'b> { 12 | fn file_name(&self) -> String { 13 | self.wrapper_object.file_name() 14 | } 15 | 16 | fn super_module_name(&self) -> Option { 17 | Some(self.wrapper_object.path().super_module_name) 18 | } 19 | 20 | fn str_src(&self) -> String { 21 | Renderer::token_stream(self).to_string() 22 | } 23 | } 24 | 25 | impl<'a, 'b> Renderer<'a, 'b> { 26 | pub fn create_file(wrapper_object: &'a ScalarTypeWrapper<'a, 'b>) { 27 | let obj = Self { wrapper_object }; 28 | obj.save(wrapper_object.context); 29 | } 30 | 31 | pub fn new_and_token_stream(wrapper_object: &'a ScalarTypeWrapper<'a, 'b>) -> TokenStream { 32 | let obj = Self { wrapper_object }; 33 | obj.token_stream() 34 | } 35 | 36 | fn token_stream(&self) -> TokenStream { 37 | let struct_name = self.struct_name(); 38 | 39 | Self::scalar_code(&struct_name) 40 | } 41 | 42 | fn struct_name(&self) -> Ident { 43 | Ident::new(&self.wrapper_object.name(), Span::call_site()) 44 | } 45 | 46 | fn scalar_code(struct_name: &Ident) -> TokenStream { 47 | quote!( 48 | use async_graphql::*; 49 | 50 | #[derive(Debug, Clone)] 51 | pub struct #struct_name(pub String); 52 | 53 | #[Scalar] 54 | impl ScalarType for #struct_name { 55 | fn parse(value: Value) -> InputValueResult { 56 | match value { 57 | Value::String(s) => Ok(#struct_name(s)), 58 | _ => Err(InputValueError::ExpectedType(value)), 59 | } 60 | } 61 | 62 | fn to_value(&self) -> Value { 63 | Value::String(self.0.to_string()) 64 | } 65 | } 66 | ) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/subscription/mod.rs: -------------------------------------------------------------------------------- 1 | mod renderer; 2 | 3 | use proc_macro2::TokenStream; 4 | 5 | use super::{ 6 | Context, FileRender, Output, RenderDependencies, RenderField, Save, 7 | SubscriptionRootTypeWrapper, SubscriptionTypeWrapper, SupportField, SupportType, 8 | }; 9 | 10 | use renderer::Renderer; 11 | 12 | pub struct Generate {} 13 | 14 | impl Output for Generate { 15 | fn generate_files(context: &Context) { 16 | context.clone().subscription_types().iter().for_each(|f| { 17 | Renderer::create_file(f); 18 | }); 19 | } 20 | 21 | fn generate_token_stream(context: &Context) -> Vec { 22 | context 23 | .clone() 24 | .subscription_types() 25 | .iter() 26 | .map(|f| Renderer::new_and_token_stream(f)) 27 | .collect() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/subscription/renderer.rs: -------------------------------------------------------------------------------- 1 | use quote::quote; 2 | 3 | use proc_macro2::{Ident, Span, TokenStream}; 4 | 5 | use super::{ 6 | FileRender, RenderDependencies, RenderField, Save, SubscriptionRootTypeWrapper, 7 | SubscriptionTypeWrapper, SupportField, SupportType, 8 | }; 9 | 10 | pub struct Renderer<'a, 'b> { 11 | wrapper_object: &'a SubscriptionRootTypeWrapper<'a, 'b>, 12 | } 13 | 14 | impl<'a, 'b> RenderField for Renderer<'a, 'b> {} 15 | 16 | impl<'a, 'b> RenderDependencies for Renderer<'a, 'b> {} 17 | 18 | impl<'a, 'b> Save for Renderer<'a, 'b> { 19 | fn file_name(&self) -> String { 20 | self.wrapper_object.file_name() 21 | } 22 | 23 | fn super_module_name(&self) -> Option { 24 | Some(self.wrapper_object.path().super_module_name) 25 | } 26 | 27 | fn str_src(&self) -> String { 28 | Renderer::token_stream(self).to_string() 29 | } 30 | } 31 | 32 | impl<'a, 'b> Renderer<'a, 'b> { 33 | pub fn create_file(wrapper_object: &'a SubscriptionRootTypeWrapper<'a, 'b>) { 34 | let obj = Self { wrapper_object }; 35 | obj.save(wrapper_object.context); 36 | } 37 | 38 | pub fn new_and_token_stream( 39 | wrapper_object: &'a SubscriptionRootTypeWrapper<'a, 'b>, 40 | ) -> TokenStream { 41 | let obj = Self { wrapper_object }; 42 | obj.token_stream() 43 | } 44 | 45 | fn token_stream(&self) -> TokenStream { 46 | let subscriptions = self.subscriptions_tokens(); 47 | let dependencies = self.dependencies_token(); 48 | 49 | quote!( 50 | #dependencies 51 | 52 | #[derive(Debug)] 53 | pub struct Subscription {} 54 | #[Subscription] 55 | impl Subscription { 56 | #subscriptions 57 | } 58 | ) 59 | } 60 | 61 | fn dependencies_token(&self) -> TokenStream { 62 | let dep = Self::render_dependencies(self.wrapper_object.dependencies()); 63 | quote!( 64 | use super::DataSource; 65 | use async_graphql::*; 66 | use futures::{stream, Stream}; 67 | 68 | #dep 69 | ) 70 | } 71 | 72 | fn arguments_token(f: &SubscriptionTypeWrapper) -> TokenStream { 73 | let mut res = quote!(); 74 | f.arguments().iter().for_each(|f| { 75 | let code_type_name = Ident::new(&f.code_type_name(), Span::call_site()); 76 | let field_name = Ident::new(&f.field_name(), Span::call_site()); 77 | res = quote!( 78 | #res 79 | #field_name: #code_type_name, 80 | ); 81 | }); 82 | res 83 | } 84 | 85 | fn struct_name_token(f: &T) -> TokenStream 86 | where 87 | T: SupportType, 88 | { 89 | let name = f.code_type_name(); 90 | let name = Ident::new(&name, Span::call_site()); 91 | match (f.non_null(), f.is_list()) { 92 | (true, false) => quote!(impl Stream), 93 | (true, true) => quote!(impl Stream>), 94 | (false, false) => quote!(impl Stream>), 95 | (false, true) => quote!(impl Stream>), 96 | } 97 | } 98 | 99 | fn subscriptions_tokens(&self) -> TokenStream { 100 | let mut result = quote!(); 101 | self.wrapper_object.mutations().iter().for_each(|f| { 102 | let name = Self::field_name_token(f); 103 | let res = Self::struct_name_token(f); 104 | let arguments = Self::arguments_token(f); 105 | 106 | result = quote!( 107 | #result 108 | 109 | pub async fn #name(&self, ctx: &Context<'_>, #arguments) -> #res { 110 | stream::iter(0..10) 111 | } 112 | ); 113 | }); 114 | result 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/union_type/mod.rs: -------------------------------------------------------------------------------- 1 | mod renderer; 2 | 3 | use super::{Context, FileRender, Output, RenderDependencies, Save, UnionTypeWrapper}; 4 | 5 | use renderer::Renderer; 6 | 7 | use proc_macro2::TokenStream; 8 | 9 | pub struct Generate {} 10 | 11 | impl Output for Generate { 12 | fn generate_files(context: &Context) { 13 | context.clone().union_types().iter().for_each(|f| { 14 | Renderer::create_file(f); 15 | }); 16 | } 17 | 18 | fn generate_token_stream(context: &Context) -> Vec { 19 | context 20 | .clone() 21 | .union_types() 22 | .iter() 23 | .map(|f| Renderer::new_and_token_stream(f)) 24 | .collect() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /codegen-for-async-graphql-renderer/src/renderer/union_type/renderer.rs: -------------------------------------------------------------------------------- 1 | use quote::quote; 2 | 3 | use proc_macro2::{Ident, Span, TokenStream}; 4 | 5 | use super::{FileRender, RenderDependencies, Save, UnionTypeWrapper}; 6 | 7 | pub struct Renderer<'a, 'b> { 8 | wrapper_object: &'a UnionTypeWrapper<'a, 'b>, 9 | } 10 | 11 | impl<'a, 'b> RenderDependencies for Renderer<'a, 'b> {} 12 | 13 | impl<'a, 'b> Save for Renderer<'a, 'b> { 14 | fn file_name(&self) -> String { 15 | self.wrapper_object.file_name() 16 | } 17 | 18 | fn super_module_name(&self) -> Option { 19 | Some(self.wrapper_object.path().super_module_name) 20 | } 21 | 22 | fn str_src(&self) -> String { 23 | Renderer::token_stream(self).to_string() 24 | } 25 | } 26 | 27 | impl<'a, 'b> Renderer<'a, 'b> { 28 | pub fn create_file(wrapper_object: &'a UnionTypeWrapper<'a, 'b>) { 29 | let obj = Self { wrapper_object }; 30 | obj.save(wrapper_object.context); 31 | } 32 | 33 | pub fn new_and_token_stream(wrapper_object: &'a UnionTypeWrapper<'a, 'b>) -> TokenStream { 34 | let obj = Self { wrapper_object }; 35 | obj.token_stream() 36 | } 37 | 38 | fn token_stream(&self) -> TokenStream { 39 | let union_properties = self.union_properties(); 40 | let dependencies_token = self.dependencies_token(); 41 | 42 | quote!( 43 | #dependencies_token 44 | 45 | #[Union] 46 | pub enum SearchResult { 47 | #union_properties 48 | } 49 | ) 50 | } 51 | 52 | fn union_properties(&self) -> TokenStream { 53 | let mut res = quote!(); 54 | self.wrapper_object.members().iter().for_each(|f| { 55 | let name = Ident::new(f, Span::call_site()); 56 | res = quote!( 57 | #res 58 | #name(#name), 59 | ) 60 | }); 61 | res 62 | } 63 | 64 | fn dependencies_token(&self) -> TokenStream { 65 | let dep = Self::render_dependencies(self.wrapper_object.dependencies()); 66 | quote!( 67 | use async_graphql::*; 68 | #dep 69 | ) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | services: 3 | rust: 4 | image: rust:1.44 5 | security_opt: 6 | - seccomp:unconfined 7 | volumes: 8 | - .:/myapp 9 | command: /bin/sh -c "cd ./myapp && cargo install cargo-tarpaulin && cargo tarpaulin --all --all-features --out Html" 10 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "codegen-for-async-graphql-example" 3 | version = "0.2.0" 4 | authors = ["Atsuhiro Takahashi "] 5 | edition = "2018" 6 | publish = false 7 | homepage = "https://github.com/atsuhiro/codegen-for-async-graphql" 8 | repository = "https://github.com/atsuhiro/codegen-for-async-graphql" 9 | 10 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 11 | 12 | [dependencies] 13 | async-graphql = "1.16.9" 14 | async-std = { version = "1.6.2", features = ["attributes"] } 15 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/schema.graphql: -------------------------------------------------------------------------------- 1 | schema { 2 | query: Query 3 | mutation: Mutation 4 | } 5 | 6 | type Query { 7 | "me: Single-line comment" 8 | me: Me! 9 | active: Bool! 10 | } 11 | 12 | type Mutation { 13 | createFriendMutation( 14 | input: CreateFriendMutationInput! 15 | ): CreateFriendMutationPayload 16 | } 17 | 18 | type Subscription { 19 | badge: Int! 20 | } 21 | 22 | type CreateFriendMutationPayload { 23 | friend: Friend! 24 | } 25 | 26 | input CreateFriendMutationInput { 27 | userId: ID! 28 | } 29 | 30 | scalar Url 31 | 32 | interface User { 33 | id: ID! 34 | name: String! 35 | } 36 | 37 | type Friend implements User { 38 | id: ID! 39 | name: String! 40 | } 41 | 42 | type FriendConnection { 43 | totalCount: Int! 44 | nodes: [Friend]! 45 | } 46 | 47 | type Me implements User { 48 | id: ID! 49 | name: String! 50 | rank: Float! 51 | email: String 52 | age: Int 53 | active: Bool 54 | friends(first: Int): FriendConnection! 55 | notifications: [Notification] 56 | web: Url 57 | search(text: String!): [SearchResult] 58 | } 59 | 60 | type Notification { 61 | id: ID! 62 | title: String! 63 | } 64 | 65 | union SearchResult = Friend | Notification 66 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/src/main.rs: -------------------------------------------------------------------------------- 1 | // use codegen_for_async_graphql_derive::*; 2 | 3 | mod models; 4 | 5 | use async_graphql::*; 6 | use async_std::task; 7 | use futures::StreamExt; 8 | 9 | use models::{ 10 | CreateFriendMutationInput, CreateFriendMutationPayload, Friend, FriendConnection, Me, Mutation, 11 | Notification, Query, SearchResult, Subscription, Url, User, 12 | }; 13 | 14 | #[derive(Debug, Clone, Copy)] 15 | pub struct DataSource {} 16 | 17 | impl DataSource { 18 | fn me(&self) -> Me { 19 | Me { 20 | id: ID::from("11111"), 21 | name: "Aaron".to_string(), 22 | email: Some("aaa@".to_string()), 23 | rank: 5.1, 24 | age: Some(30), 25 | active: Some(true), 26 | web: Some(Url("https://github.com/".to_string())), 27 | } 28 | } 29 | 30 | fn nodes(&self) -> Vec { 31 | let friend1 = Friend { 32 | id: ID::from("1-1"), 33 | name: "Beck".to_string(), 34 | }; 35 | vec![friend1] 36 | } 37 | 38 | fn friend(&self) -> Friend { 39 | Friend { 40 | id: ID::from("1-1"), 41 | name: "Beck".to_string(), 42 | } 43 | } 44 | 45 | fn friends(&self, first: Option) -> FriendConnection { 46 | FriendConnection { total_count: 10 } 47 | } 48 | 49 | fn notifications(&self) -> Option> { 50 | let node1 = Notification { 51 | id: ID::from("1-1"), 52 | title: "title1".to_string(), 53 | }; 54 | let node2 = Notification { 55 | id: ID::from("2-1"), 56 | title: "title2".to_string(), 57 | }; 58 | Some(vec![node1, node2]) 59 | } 60 | 61 | fn badge(&self) -> Option { 62 | Some(1) 63 | } 64 | 65 | fn search(&self, text: String) -> Option> { 66 | let res = vec![]; 67 | Some(res) 68 | } 69 | } 70 | 71 | pub trait ResolveMutation { 72 | fn create_friend_mutation_resolver( 73 | &self, 74 | input: CreateFriendMutationInput, 75 | ) -> Option { 76 | Some(CreateFriendMutationPayload {}) 77 | } 78 | } 79 | 80 | fn main() { 81 | task::block_on(async { run("query{}").await }); 82 | } 83 | 84 | fn build_schema() -> Schema { 85 | let data_source = DataSource {}; 86 | Schema::build(Query { active: true }, Mutation, Subscription {}) 87 | .register_type::() 88 | .data(data_source) 89 | .finish() 90 | } 91 | 92 | // #[DynSchema("./codegen-for-async-graphql-example/schema.graphql")] 93 | async fn run(query: &str) -> String { 94 | let schema = build_schema(); 95 | let res = schema.execute(query).await; 96 | let json = serde_json::to_string_pretty(&async_graphql::http::GQLResponse(res)); 97 | json.unwrap() 98 | } 99 | 100 | async fn run_subscription(query: &str) -> Vec { 101 | let mut result = vec![]; 102 | let schema = build_schema(); 103 | 104 | let mut stream = schema 105 | .create_subscription_stream(query, None, Default::default(), None) 106 | .await 107 | .unwrap(); 108 | loop { 109 | let res = stream.next().await; 110 | if res.is_none() { 111 | return result; 112 | } 113 | let json = serde_json::to_string_pretty(&res.unwrap().expect("")); 114 | let j = json.unwrap(); 115 | result.push(j); 116 | } 117 | } 118 | 119 | #[async_std::test] 120 | async fn instance_query() { 121 | use std::fs; 122 | 123 | let query = "{ 124 | active 125 | me { 126 | id 127 | name 128 | email 129 | rank 130 | age 131 | active 132 | web 133 | friends { 134 | totalCount 135 | nodes { 136 | id 137 | name 138 | } 139 | } 140 | notifications { 141 | id 142 | title 143 | } 144 | search(text: \"abc\") { 145 | ... on Friend { 146 | id 147 | name 148 | } 149 | ... on Notification { 150 | id 151 | title 152 | } 153 | } 154 | } 155 | }"; 156 | let json = run(query).await; 157 | let path = "./tests/snapshots/main.json"; 158 | // fs::write(path, json).unwrap(); 159 | let snapshot: String = fs::read_to_string(path).unwrap(); 160 | assert_eq!(json, snapshot); 161 | } 162 | 163 | #[async_std::test] 164 | async fn instance_mutation() { 165 | let query = " 166 | mutation { 167 | createFriendMutation(input: {userId: \"11\"}) { 168 | friend { 169 | id 170 | } 171 | } 172 | }"; 173 | 174 | let json = run(query).await; 175 | println!("{:?}", json); 176 | } 177 | 178 | #[async_std::test] 179 | async fn test_subscription() { 180 | let query = "subscription { badge }"; 181 | let json = run_subscription(query).await; 182 | println!("{:?}", json); 183 | } 184 | 185 | #[async_std::test] 186 | async fn introspection_query() { 187 | use std::fs; 188 | 189 | let query = fs::read_to_string("../../tests/queries/introspection.graphql").unwrap(); 190 | 191 | let json = run(query.as_str()).await; 192 | let path = "./tests/snapshots/introspection.json"; 193 | // fs::write(path, json).unwrap(); 194 | let snapshot: String = fs::read_to_string(path).unwrap(); 195 | assert_eq!(json, snapshot); 196 | } 197 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/src/models/input_object_type/create_friend_mutation_input.rs: -------------------------------------------------------------------------------- 1 | use async_graphql::*; 2 | #[InputObject] 3 | pub struct CreateFriendMutationInput { 4 | pub user_id: ID, 5 | } 6 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/src/models/input_object_type/mod.rs: -------------------------------------------------------------------------------- 1 | use super::ResolveMutation; 2 | use crate::DataSource; 3 | pub mod create_friend_mutation_input; 4 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/src/models/interface_type/mod.rs: -------------------------------------------------------------------------------- 1 | use super::ResolveMutation; 2 | use crate::DataSource; 3 | pub mod user; 4 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/src/models/interface_type/user.rs: -------------------------------------------------------------------------------- 1 | use super::super::object_type::friend::Friend; 2 | use super::super::object_type::me::Me; 3 | use async_graphql::*; 4 | #[Interface(field(name = "id", type = "ID"), field(name = "name", type = "String"))] 5 | pub enum User { 6 | Friend(Friend), 7 | Me(Me), 8 | } 9 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/src/models/mod.rs: -------------------------------------------------------------------------------- 1 | use super::ResolveMutation; 2 | use crate::DataSource; 3 | pub mod input_object_type; 4 | pub mod interface_type; 5 | pub mod mutations_type; 6 | pub mod object_type; 7 | pub mod scalar_type; 8 | pub mod subscription_type; 9 | pub mod union_type; 10 | pub use input_object_type::create_friend_mutation_input::CreateFriendMutationInput; 11 | pub use interface_type::user::User; 12 | pub use mutations_type::mutation::Mutation; 13 | pub use object_type::create_friend_mutation_payload::CreateFriendMutationPayload; 14 | pub use object_type::friend::Friend; 15 | pub use object_type::friend_connection::FriendConnection; 16 | pub use object_type::me::Me; 17 | pub use object_type::notification::Notification; 18 | pub use object_type::query::Query; 19 | pub use scalar_type::url::Url; 20 | pub use subscription_type::subscription::Subscription; 21 | pub use union_type::search_result::SearchResult; 22 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/src/models/mutations_type/mod.rs: -------------------------------------------------------------------------------- 1 | use super::ResolveMutation; 2 | use crate::DataSource; 3 | pub mod mutation; 4 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/src/models/mutations_type/mutation.rs: -------------------------------------------------------------------------------- 1 | use super::super::input_object_type::create_friend_mutation_input::CreateFriendMutationInput; 2 | use super::super::object_type::create_friend_mutation_payload::CreateFriendMutationPayload; 3 | use super::ResolveMutation; 4 | use async_graphql::*; 5 | pub struct Mutation; 6 | impl ResolveMutation for Mutation {} 7 | #[Object] 8 | impl Mutation { 9 | async fn create_friend_mutation( 10 | &self, 11 | input: CreateFriendMutationInput, 12 | ) -> Option { 13 | self.create_friend_mutation_resolver(input) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/src/models/object_type/create_friend_mutation_payload.rs: -------------------------------------------------------------------------------- 1 | use super::super::object_type::friend::Friend; 2 | use super::DataSource; 3 | use async_graphql::*; 4 | #[derive(Debug)] 5 | pub struct CreateFriendMutationPayload {} 6 | #[Object] 7 | impl CreateFriendMutationPayload { 8 | pub async fn friend(&self, ctx: &Context<'_>) -> Friend { 9 | ctx.data_unchecked::().friend() 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/src/models/object_type/friend.rs: -------------------------------------------------------------------------------- 1 | use super::DataSource; 2 | use async_graphql::*; 3 | #[derive(Debug)] 4 | pub struct Friend { 5 | pub id: ID, 6 | pub name: String, 7 | } 8 | #[Object] 9 | impl Friend { 10 | pub async fn id(&self) -> ID { 11 | self.id.clone() 12 | } 13 | pub async fn name(&self) -> String { 14 | self.name.clone() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/src/models/object_type/friend_connection.rs: -------------------------------------------------------------------------------- 1 | use super::super::object_type::friend::Friend; 2 | use super::DataSource; 3 | use async_graphql::*; 4 | #[derive(Debug)] 5 | pub struct FriendConnection { 6 | pub total_count: i32, 7 | } 8 | #[Object] 9 | impl FriendConnection { 10 | pub async fn nodes(&self, ctx: &Context<'_>) -> Vec { 11 | ctx.data_unchecked::().nodes() 12 | } 13 | pub async fn total_count(&self) -> i32 { 14 | self.total_count.clone() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/src/models/object_type/me.rs: -------------------------------------------------------------------------------- 1 | use super::super::object_type::friend_connection::FriendConnection; 2 | use super::super::object_type::notification::Notification; 3 | use super::super::scalar_type::url::Url; 4 | use super::super::union_type::search_result::SearchResult; 5 | use super::DataSource; 6 | use async_graphql::*; 7 | #[derive(Debug)] 8 | pub struct Me { 9 | pub id: ID, 10 | pub name: String, 11 | pub rank: f64, 12 | pub email: Option, 13 | pub age: Option, 14 | pub active: Option, 15 | pub web: Option, 16 | } 17 | #[Object] 18 | impl Me { 19 | pub async fn friends(&self, ctx: &Context<'_>, first: Option) -> FriendConnection { 20 | ctx.data_unchecked::().friends(first) 21 | } 22 | pub async fn notifications(&self, ctx: &Context<'_>) -> Option> { 23 | ctx.data_unchecked::().notifications() 24 | } 25 | pub async fn search(&self, ctx: &Context<'_>, text: String) -> Option> { 26 | ctx.data_unchecked::().search(text) 27 | } 28 | pub async fn id(&self) -> ID { 29 | self.id.clone() 30 | } 31 | pub async fn name(&self) -> String { 32 | self.name.clone() 33 | } 34 | pub async fn rank(&self) -> f64 { 35 | self.rank.clone() 36 | } 37 | pub async fn email(&self) -> Option { 38 | self.email.clone() 39 | } 40 | pub async fn age(&self) -> Option { 41 | self.age.clone() 42 | } 43 | pub async fn active(&self) -> Option { 44 | self.active.clone() 45 | } 46 | pub async fn web(&self) -> Option { 47 | self.web.clone() 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/src/models/object_type/mod.rs: -------------------------------------------------------------------------------- 1 | use super::ResolveMutation; 2 | use crate::DataSource; 3 | pub mod create_friend_mutation_payload; 4 | pub mod friend; 5 | pub mod friend_connection; 6 | pub mod me; 7 | pub mod notification; 8 | pub mod query; 9 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/src/models/object_type/notification.rs: -------------------------------------------------------------------------------- 1 | use super::DataSource; 2 | use async_graphql::*; 3 | #[derive(Debug)] 4 | pub struct Notification { 5 | pub id: ID, 6 | pub title: String, 7 | } 8 | #[Object] 9 | impl Notification { 10 | pub async fn id(&self) -> ID { 11 | self.id.clone() 12 | } 13 | pub async fn title(&self) -> String { 14 | self.title.clone() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/src/models/object_type/query.rs: -------------------------------------------------------------------------------- 1 | use super::super::object_type::me::Me; 2 | use super::DataSource; 3 | use async_graphql::*; 4 | #[derive(Debug)] 5 | pub struct Query { 6 | pub active: bool, 7 | } 8 | #[Object] 9 | impl Query { 10 | #[field(desc = "\"me: Single-line comment\"")] 11 | pub async fn me(&self, ctx: &Context<'_>) -> Me { 12 | ctx.data_unchecked::().me() 13 | } 14 | pub async fn active(&self) -> bool { 15 | self.active.clone() 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/src/models/scalar_type/mod.rs: -------------------------------------------------------------------------------- 1 | use super::ResolveMutation; 2 | use crate::DataSource; 3 | pub mod url; 4 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/src/models/scalar_type/url.rs: -------------------------------------------------------------------------------- 1 | use async_graphql::*; 2 | #[derive(Debug, Clone)] 3 | pub struct Url(pub String); 4 | #[Scalar] 5 | impl ScalarType for Url { 6 | fn parse(value: Value) -> InputValueResult { 7 | match value { 8 | Value::String(s) => Ok(Url(s)), 9 | _ => Err(InputValueError::ExpectedType(value)), 10 | } 11 | } 12 | fn to_value(&self) -> Value { 13 | Value::String(self.0.to_string()) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/src/models/subscription_type/mod.rs: -------------------------------------------------------------------------------- 1 | use super::ResolveMutation; 2 | use crate::DataSource; 3 | pub mod subscription; 4 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/src/models/subscription_type/subscription.rs: -------------------------------------------------------------------------------- 1 | use super::DataSource; 2 | use async_graphql::*; 3 | use futures::{stream, Stream}; 4 | #[derive(Debug)] 5 | pub struct Subscription {} 6 | #[Subscription] 7 | impl Subscription { 8 | pub async fn badge(&self, ctx: &Context<'_>) -> impl Stream { 9 | stream::iter(0..10) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/src/models/union_type/mod.rs: -------------------------------------------------------------------------------- 1 | use super::ResolveMutation; 2 | use crate::DataSource; 3 | pub mod search_result; 4 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/src/models/union_type/search_result.rs: -------------------------------------------------------------------------------- 1 | use super::super::object_type::friend::Friend; 2 | use super::super::object_type::notification::Notification; 3 | use async_graphql::*; 4 | #[Union] 5 | pub enum SearchResult { 6 | Friend(Friend), 7 | Notification(Notification), 8 | } 9 | -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/tests/snapshots/introspection.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "__schema": { 4 | "queryType": { 5 | "name": "Query" 6 | }, 7 | "mutationType": { 8 | "name": "Mutation" 9 | }, 10 | "subscriptionType": { 11 | "name": "Subscription" 12 | }, 13 | "types": [ 14 | { 15 | "kind": "SCALAR", 16 | "name": "Boolean", 17 | "description": "The `Boolean` scalar type represents `true` or `false`.", 18 | "fields": null, 19 | "inputFields": null, 20 | "interfaces": null, 21 | "enumValues": null, 22 | "possibleTypes": null 23 | }, 24 | { 25 | "kind": "INPUT_OBJECT", 26 | "name": "CreateFriendMutationInput", 27 | "description": null, 28 | "fields": null, 29 | "inputFields": [ 30 | { 31 | "name": "userId", 32 | "description": null, 33 | "type": { 34 | "kind": "NON_NULL", 35 | "name": null, 36 | "ofType": { 37 | "kind": "SCALAR", 38 | "name": "ID", 39 | "ofType": null 40 | } 41 | }, 42 | "defaultValue": null 43 | } 44 | ], 45 | "interfaces": null, 46 | "enumValues": null, 47 | "possibleTypes": null 48 | }, 49 | { 50 | "kind": "OBJECT", 51 | "name": "CreateFriendMutationPayload", 52 | "description": null, 53 | "fields": [ 54 | { 55 | "name": "friend", 56 | "description": null, 57 | "args": [], 58 | "type": { 59 | "kind": "NON_NULL", 60 | "name": null, 61 | "ofType": { 62 | "kind": "OBJECT", 63 | "name": "Friend", 64 | "ofType": null 65 | } 66 | }, 67 | "isDeprecated": false, 68 | "deprecationReason": null 69 | } 70 | ], 71 | "inputFields": null, 72 | "interfaces": [], 73 | "enumValues": null, 74 | "possibleTypes": null 75 | }, 76 | { 77 | "kind": "SCALAR", 78 | "name": "Float", 79 | "description": "The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE 754](https://en.wikipedia.org/wiki/IEEE_floating_point).", 80 | "fields": null, 81 | "inputFields": null, 82 | "interfaces": null, 83 | "enumValues": null, 84 | "possibleTypes": null 85 | }, 86 | { 87 | "kind": "OBJECT", 88 | "name": "Friend", 89 | "description": null, 90 | "fields": [ 91 | { 92 | "name": "id", 93 | "description": null, 94 | "args": [], 95 | "type": { 96 | "kind": "NON_NULL", 97 | "name": null, 98 | "ofType": { 99 | "kind": "SCALAR", 100 | "name": "ID", 101 | "ofType": null 102 | } 103 | }, 104 | "isDeprecated": false, 105 | "deprecationReason": null 106 | }, 107 | { 108 | "name": "name", 109 | "description": null, 110 | "args": [], 111 | "type": { 112 | "kind": "NON_NULL", 113 | "name": null, 114 | "ofType": { 115 | "kind": "SCALAR", 116 | "name": "String", 117 | "ofType": null 118 | } 119 | }, 120 | "isDeprecated": false, 121 | "deprecationReason": null 122 | } 123 | ], 124 | "inputFields": null, 125 | "interfaces": [ 126 | { 127 | "kind": "INTERFACE", 128 | "name": "User", 129 | "ofType": null 130 | } 131 | ], 132 | "enumValues": null, 133 | "possibleTypes": null 134 | }, 135 | { 136 | "kind": "OBJECT", 137 | "name": "FriendConnection", 138 | "description": null, 139 | "fields": [ 140 | { 141 | "name": "nodes", 142 | "description": null, 143 | "args": [], 144 | "type": { 145 | "kind": "NON_NULL", 146 | "name": null, 147 | "ofType": { 148 | "kind": "LIST", 149 | "name": null, 150 | "ofType": { 151 | "kind": "NON_NULL", 152 | "name": null, 153 | "ofType": { 154 | "kind": "OBJECT", 155 | "name": "Friend", 156 | "ofType": null 157 | } 158 | } 159 | } 160 | }, 161 | "isDeprecated": false, 162 | "deprecationReason": null 163 | }, 164 | { 165 | "name": "totalCount", 166 | "description": null, 167 | "args": [], 168 | "type": { 169 | "kind": "NON_NULL", 170 | "name": null, 171 | "ofType": { 172 | "kind": "SCALAR", 173 | "name": "Int", 174 | "ofType": null 175 | } 176 | }, 177 | "isDeprecated": false, 178 | "deprecationReason": null 179 | } 180 | ], 181 | "inputFields": null, 182 | "interfaces": [], 183 | "enumValues": null, 184 | "possibleTypes": null 185 | }, 186 | { 187 | "kind": "SCALAR", 188 | "name": "ID", 189 | "description": null, 190 | "fields": null, 191 | "inputFields": null, 192 | "interfaces": null, 193 | "enumValues": null, 194 | "possibleTypes": null 195 | }, 196 | { 197 | "kind": "SCALAR", 198 | "name": "Int", 199 | "description": "The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.", 200 | "fields": null, 201 | "inputFields": null, 202 | "interfaces": null, 203 | "enumValues": null, 204 | "possibleTypes": null 205 | }, 206 | { 207 | "kind": "OBJECT", 208 | "name": "Me", 209 | "description": null, 210 | "fields": [ 211 | { 212 | "name": "friends", 213 | "description": null, 214 | "args": [ 215 | { 216 | "name": "first", 217 | "description": null, 218 | "type": { 219 | "kind": "SCALAR", 220 | "name": "Int", 221 | "ofType": null 222 | }, 223 | "defaultValue": null 224 | } 225 | ], 226 | "type": { 227 | "kind": "NON_NULL", 228 | "name": null, 229 | "ofType": { 230 | "kind": "OBJECT", 231 | "name": "FriendConnection", 232 | "ofType": null 233 | } 234 | }, 235 | "isDeprecated": false, 236 | "deprecationReason": null 237 | }, 238 | { 239 | "name": "notifications", 240 | "description": null, 241 | "args": [], 242 | "type": { 243 | "kind": "LIST", 244 | "name": null, 245 | "ofType": { 246 | "kind": "NON_NULL", 247 | "name": null, 248 | "ofType": { 249 | "kind": "OBJECT", 250 | "name": "Notification", 251 | "ofType": null 252 | } 253 | } 254 | }, 255 | "isDeprecated": false, 256 | "deprecationReason": null 257 | }, 258 | { 259 | "name": "search", 260 | "description": null, 261 | "args": [ 262 | { 263 | "name": "text", 264 | "description": null, 265 | "type": { 266 | "kind": "NON_NULL", 267 | "name": null, 268 | "ofType": { 269 | "kind": "SCALAR", 270 | "name": "String", 271 | "ofType": null 272 | } 273 | }, 274 | "defaultValue": null 275 | } 276 | ], 277 | "type": { 278 | "kind": "LIST", 279 | "name": null, 280 | "ofType": { 281 | "kind": "NON_NULL", 282 | "name": null, 283 | "ofType": { 284 | "kind": "UNION", 285 | "name": "SearchResult", 286 | "ofType": null 287 | } 288 | } 289 | }, 290 | "isDeprecated": false, 291 | "deprecationReason": null 292 | }, 293 | { 294 | "name": "id", 295 | "description": null, 296 | "args": [], 297 | "type": { 298 | "kind": "NON_NULL", 299 | "name": null, 300 | "ofType": { 301 | "kind": "SCALAR", 302 | "name": "ID", 303 | "ofType": null 304 | } 305 | }, 306 | "isDeprecated": false, 307 | "deprecationReason": null 308 | }, 309 | { 310 | "name": "name", 311 | "description": null, 312 | "args": [], 313 | "type": { 314 | "kind": "NON_NULL", 315 | "name": null, 316 | "ofType": { 317 | "kind": "SCALAR", 318 | "name": "String", 319 | "ofType": null 320 | } 321 | }, 322 | "isDeprecated": false, 323 | "deprecationReason": null 324 | }, 325 | { 326 | "name": "rank", 327 | "description": null, 328 | "args": [], 329 | "type": { 330 | "kind": "NON_NULL", 331 | "name": null, 332 | "ofType": { 333 | "kind": "SCALAR", 334 | "name": "Float", 335 | "ofType": null 336 | } 337 | }, 338 | "isDeprecated": false, 339 | "deprecationReason": null 340 | }, 341 | { 342 | "name": "email", 343 | "description": null, 344 | "args": [], 345 | "type": { 346 | "kind": "SCALAR", 347 | "name": "String", 348 | "ofType": null 349 | }, 350 | "isDeprecated": false, 351 | "deprecationReason": null 352 | }, 353 | { 354 | "name": "age", 355 | "description": null, 356 | "args": [], 357 | "type": { 358 | "kind": "SCALAR", 359 | "name": "Int", 360 | "ofType": null 361 | }, 362 | "isDeprecated": false, 363 | "deprecationReason": null 364 | }, 365 | { 366 | "name": "active", 367 | "description": null, 368 | "args": [], 369 | "type": { 370 | "kind": "SCALAR", 371 | "name": "Boolean", 372 | "ofType": null 373 | }, 374 | "isDeprecated": false, 375 | "deprecationReason": null 376 | }, 377 | { 378 | "name": "web", 379 | "description": null, 380 | "args": [], 381 | "type": { 382 | "kind": "SCALAR", 383 | "name": "Url", 384 | "ofType": null 385 | }, 386 | "isDeprecated": false, 387 | "deprecationReason": null 388 | } 389 | ], 390 | "inputFields": null, 391 | "interfaces": [ 392 | { 393 | "kind": "INTERFACE", 394 | "name": "User", 395 | "ofType": null 396 | } 397 | ], 398 | "enumValues": null, 399 | "possibleTypes": null 400 | }, 401 | { 402 | "kind": "OBJECT", 403 | "name": "Mutation", 404 | "description": null, 405 | "fields": [ 406 | { 407 | "name": "createFriendMutation", 408 | "description": null, 409 | "args": [ 410 | { 411 | "name": "input", 412 | "description": null, 413 | "type": { 414 | "kind": "NON_NULL", 415 | "name": null, 416 | "ofType": { 417 | "kind": "INPUT_OBJECT", 418 | "name": "CreateFriendMutationInput", 419 | "ofType": null 420 | } 421 | }, 422 | "defaultValue": null 423 | } 424 | ], 425 | "type": { 426 | "kind": "OBJECT", 427 | "name": "CreateFriendMutationPayload", 428 | "ofType": null 429 | }, 430 | "isDeprecated": false, 431 | "deprecationReason": null 432 | } 433 | ], 434 | "inputFields": null, 435 | "interfaces": [], 436 | "enumValues": null, 437 | "possibleTypes": null 438 | }, 439 | { 440 | "kind": "OBJECT", 441 | "name": "Notification", 442 | "description": null, 443 | "fields": [ 444 | { 445 | "name": "id", 446 | "description": null, 447 | "args": [], 448 | "type": { 449 | "kind": "NON_NULL", 450 | "name": null, 451 | "ofType": { 452 | "kind": "SCALAR", 453 | "name": "ID", 454 | "ofType": null 455 | } 456 | }, 457 | "isDeprecated": false, 458 | "deprecationReason": null 459 | }, 460 | { 461 | "name": "title", 462 | "description": null, 463 | "args": [], 464 | "type": { 465 | "kind": "NON_NULL", 466 | "name": null, 467 | "ofType": { 468 | "kind": "SCALAR", 469 | "name": "String", 470 | "ofType": null 471 | } 472 | }, 473 | "isDeprecated": false, 474 | "deprecationReason": null 475 | } 476 | ], 477 | "inputFields": null, 478 | "interfaces": [], 479 | "enumValues": null, 480 | "possibleTypes": null 481 | }, 482 | { 483 | "kind": "OBJECT", 484 | "name": "Query", 485 | "description": null, 486 | "fields": [ 487 | { 488 | "name": "me", 489 | "description": "\"me: Single-line comment\"", 490 | "args": [], 491 | "type": { 492 | "kind": "NON_NULL", 493 | "name": null, 494 | "ofType": { 495 | "kind": "OBJECT", 496 | "name": "Me", 497 | "ofType": null 498 | } 499 | }, 500 | "isDeprecated": false, 501 | "deprecationReason": null 502 | }, 503 | { 504 | "name": "active", 505 | "description": null, 506 | "args": [], 507 | "type": { 508 | "kind": "NON_NULL", 509 | "name": null, 510 | "ofType": { 511 | "kind": "SCALAR", 512 | "name": "Boolean", 513 | "ofType": null 514 | } 515 | }, 516 | "isDeprecated": false, 517 | "deprecationReason": null 518 | } 519 | ], 520 | "inputFields": null, 521 | "interfaces": [], 522 | "enumValues": null, 523 | "possibleTypes": null 524 | }, 525 | { 526 | "kind": "UNION", 527 | "name": "SearchResult", 528 | "description": null, 529 | "fields": null, 530 | "inputFields": null, 531 | "interfaces": null, 532 | "enumValues": null, 533 | "possibleTypes": [ 534 | { 535 | "kind": "OBJECT", 536 | "name": "Friend", 537 | "ofType": null 538 | }, 539 | { 540 | "kind": "OBJECT", 541 | "name": "Notification", 542 | "ofType": null 543 | } 544 | ] 545 | }, 546 | { 547 | "kind": "SCALAR", 548 | "name": "String", 549 | "description": "The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.", 550 | "fields": null, 551 | "inputFields": null, 552 | "interfaces": null, 553 | "enumValues": null, 554 | "possibleTypes": null 555 | }, 556 | { 557 | "kind": "OBJECT", 558 | "name": "Subscription", 559 | "description": null, 560 | "fields": [ 561 | { 562 | "name": "badge", 563 | "description": null, 564 | "args": [], 565 | "type": { 566 | "kind": "NON_NULL", 567 | "name": null, 568 | "ofType": { 569 | "kind": "SCALAR", 570 | "name": "Int", 571 | "ofType": null 572 | } 573 | }, 574 | "isDeprecated": false, 575 | "deprecationReason": null 576 | } 577 | ], 578 | "inputFields": null, 579 | "interfaces": [], 580 | "enumValues": null, 581 | "possibleTypes": null 582 | }, 583 | { 584 | "kind": "SCALAR", 585 | "name": "Url", 586 | "description": null, 587 | "fields": null, 588 | "inputFields": null, 589 | "interfaces": null, 590 | "enumValues": null, 591 | "possibleTypes": null 592 | }, 593 | { 594 | "kind": "INTERFACE", 595 | "name": "User", 596 | "description": null, 597 | "fields": [ 598 | { 599 | "name": "id", 600 | "description": null, 601 | "args": [], 602 | "type": { 603 | "kind": "NON_NULL", 604 | "name": null, 605 | "ofType": { 606 | "kind": "SCALAR", 607 | "name": "ID", 608 | "ofType": null 609 | } 610 | }, 611 | "isDeprecated": false, 612 | "deprecationReason": null 613 | }, 614 | { 615 | "name": "name", 616 | "description": null, 617 | "args": [], 618 | "type": { 619 | "kind": "NON_NULL", 620 | "name": null, 621 | "ofType": { 622 | "kind": "SCALAR", 623 | "name": "String", 624 | "ofType": null 625 | } 626 | }, 627 | "isDeprecated": false, 628 | "deprecationReason": null 629 | } 630 | ], 631 | "inputFields": null, 632 | "interfaces": null, 633 | "enumValues": null, 634 | "possibleTypes": [ 635 | { 636 | "kind": "OBJECT", 637 | "name": "Friend", 638 | "ofType": null 639 | }, 640 | { 641 | "kind": "OBJECT", 642 | "name": "Me", 643 | "ofType": null 644 | } 645 | ] 646 | }, 647 | { 648 | "kind": "OBJECT", 649 | "name": "__Directive", 650 | "description": "A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.", 651 | "fields": [ 652 | { 653 | "name": "name", 654 | "description": null, 655 | "args": [], 656 | "type": { 657 | "kind": "NON_NULL", 658 | "name": null, 659 | "ofType": { 660 | "kind": "SCALAR", 661 | "name": "String", 662 | "ofType": null 663 | } 664 | }, 665 | "isDeprecated": false, 666 | "deprecationReason": null 667 | }, 668 | { 669 | "name": "description", 670 | "description": null, 671 | "args": [], 672 | "type": { 673 | "kind": "SCALAR", 674 | "name": "String", 675 | "ofType": null 676 | }, 677 | "isDeprecated": false, 678 | "deprecationReason": null 679 | }, 680 | { 681 | "name": "locations", 682 | "description": null, 683 | "args": [], 684 | "type": { 685 | "kind": "NON_NULL", 686 | "name": null, 687 | "ofType": { 688 | "kind": "LIST", 689 | "name": null, 690 | "ofType": { 691 | "kind": "NON_NULL", 692 | "name": null, 693 | "ofType": { 694 | "kind": "ENUM", 695 | "name": "__DirectiveLocation", 696 | "ofType": null 697 | } 698 | } 699 | } 700 | }, 701 | "isDeprecated": false, 702 | "deprecationReason": null 703 | }, 704 | { 705 | "name": "args", 706 | "description": null, 707 | "args": [], 708 | "type": { 709 | "kind": "NON_NULL", 710 | "name": null, 711 | "ofType": { 712 | "kind": "LIST", 713 | "name": null, 714 | "ofType": { 715 | "kind": "NON_NULL", 716 | "name": null, 717 | "ofType": { 718 | "kind": "OBJECT", 719 | "name": "__InputValue", 720 | "ofType": null 721 | } 722 | } 723 | } 724 | }, 725 | "isDeprecated": false, 726 | "deprecationReason": null 727 | } 728 | ], 729 | "inputFields": null, 730 | "interfaces": [], 731 | "enumValues": null, 732 | "possibleTypes": null 733 | }, 734 | { 735 | "kind": "ENUM", 736 | "name": "__DirectiveLocation", 737 | "description": "A Directive can be adjacent to many parts of the GraphQL language, a __DirectiveLocation describes one such possible adjacencies.", 738 | "fields": null, 739 | "inputFields": null, 740 | "interfaces": null, 741 | "enumValues": [ 742 | { 743 | "name": "QUERY", 744 | "description": "Location adjacent to a query operation.", 745 | "isDeprecated": false, 746 | "deprecationReason": null 747 | }, 748 | { 749 | "name": "MUTATION", 750 | "description": "Location adjacent to a mutation operation.", 751 | "isDeprecated": false, 752 | "deprecationReason": null 753 | }, 754 | { 755 | "name": "SUBSCRIPTION", 756 | "description": "Location adjacent to a subscription operation.", 757 | "isDeprecated": false, 758 | "deprecationReason": null 759 | }, 760 | { 761 | "name": "FIELD", 762 | "description": "Location adjacent to a field.", 763 | "isDeprecated": false, 764 | "deprecationReason": null 765 | }, 766 | { 767 | "name": "FRAGMENT_DEFINITION", 768 | "description": "Location adjacent to a fragment definition.", 769 | "isDeprecated": false, 770 | "deprecationReason": null 771 | }, 772 | { 773 | "name": "FRAGMENT_SPREAD", 774 | "description": "Location adjacent to a fragment spread.", 775 | "isDeprecated": false, 776 | "deprecationReason": null 777 | }, 778 | { 779 | "name": "INLINE_FRAGMENT", 780 | "description": "Location adjacent to an inline fragment.", 781 | "isDeprecated": false, 782 | "deprecationReason": null 783 | }, 784 | { 785 | "name": "VARIABLE_DEFINITION", 786 | "description": "Location adjacent to a variable definition.", 787 | "isDeprecated": false, 788 | "deprecationReason": null 789 | }, 790 | { 791 | "name": "SCHEMA", 792 | "description": "Location adjacent to a schema definition.", 793 | "isDeprecated": false, 794 | "deprecationReason": null 795 | }, 796 | { 797 | "name": "SCALAR", 798 | "description": "Location adjacent to a scalar definition.", 799 | "isDeprecated": false, 800 | "deprecationReason": null 801 | }, 802 | { 803 | "name": "OBJECT", 804 | "description": "Location adjacent to an object type definition.", 805 | "isDeprecated": false, 806 | "deprecationReason": null 807 | }, 808 | { 809 | "name": "FIELD_DEFINITION", 810 | "description": "Location adjacent to a field definition.", 811 | "isDeprecated": false, 812 | "deprecationReason": null 813 | }, 814 | { 815 | "name": "ARGUMENT_DEFINITION", 816 | "description": "Location adjacent to an argument definition.", 817 | "isDeprecated": false, 818 | "deprecationReason": null 819 | }, 820 | { 821 | "name": "INTERFACE", 822 | "description": "Location adjacent to an interface definition.", 823 | "isDeprecated": false, 824 | "deprecationReason": null 825 | }, 826 | { 827 | "name": "UNION", 828 | "description": "Location adjacent to a union definition.", 829 | "isDeprecated": false, 830 | "deprecationReason": null 831 | }, 832 | { 833 | "name": "ENUM", 834 | "description": "Location adjacent to an enum definition.", 835 | "isDeprecated": false, 836 | "deprecationReason": null 837 | }, 838 | { 839 | "name": "ENUM_VALUE", 840 | "description": "Location adjacent to an enum value definition.", 841 | "isDeprecated": false, 842 | "deprecationReason": null 843 | }, 844 | { 845 | "name": "INPUT_OBJECT", 846 | "description": "Location adjacent to an input object type definition.", 847 | "isDeprecated": false, 848 | "deprecationReason": null 849 | }, 850 | { 851 | "name": "INPUT_FIELD_DEFINITION", 852 | "description": "Location adjacent to an input object field definition.", 853 | "isDeprecated": false, 854 | "deprecationReason": null 855 | } 856 | ], 857 | "possibleTypes": null 858 | }, 859 | { 860 | "kind": "OBJECT", 861 | "name": "__EnumValue", 862 | "description": "One possible value for a given Enum. Enum values are unique values, not a placeholder for a string or numeric value. However an Enum value is returned in a JSON response as a string.", 863 | "fields": [ 864 | { 865 | "name": "name", 866 | "description": null, 867 | "args": [], 868 | "type": { 869 | "kind": "NON_NULL", 870 | "name": null, 871 | "ofType": { 872 | "kind": "SCALAR", 873 | "name": "String", 874 | "ofType": null 875 | } 876 | }, 877 | "isDeprecated": false, 878 | "deprecationReason": null 879 | }, 880 | { 881 | "name": "description", 882 | "description": null, 883 | "args": [], 884 | "type": { 885 | "kind": "SCALAR", 886 | "name": "String", 887 | "ofType": null 888 | }, 889 | "isDeprecated": false, 890 | "deprecationReason": null 891 | }, 892 | { 893 | "name": "isDeprecated", 894 | "description": null, 895 | "args": [], 896 | "type": { 897 | "kind": "NON_NULL", 898 | "name": null, 899 | "ofType": { 900 | "kind": "SCALAR", 901 | "name": "Boolean", 902 | "ofType": null 903 | } 904 | }, 905 | "isDeprecated": false, 906 | "deprecationReason": null 907 | }, 908 | { 909 | "name": "deprecationReason", 910 | "description": null, 911 | "args": [], 912 | "type": { 913 | "kind": "SCALAR", 914 | "name": "String", 915 | "ofType": null 916 | }, 917 | "isDeprecated": false, 918 | "deprecationReason": null 919 | } 920 | ], 921 | "inputFields": null, 922 | "interfaces": [], 923 | "enumValues": null, 924 | "possibleTypes": null 925 | }, 926 | { 927 | "kind": "OBJECT", 928 | "name": "__Field", 929 | "description": "Object and Interface types are described by a list of Fields, each of which has a name, potentially a list of arguments, and a return type.", 930 | "fields": [ 931 | { 932 | "name": "name", 933 | "description": null, 934 | "args": [], 935 | "type": { 936 | "kind": "NON_NULL", 937 | "name": null, 938 | "ofType": { 939 | "kind": "SCALAR", 940 | "name": "String", 941 | "ofType": null 942 | } 943 | }, 944 | "isDeprecated": false, 945 | "deprecationReason": null 946 | }, 947 | { 948 | "name": "description", 949 | "description": null, 950 | "args": [], 951 | "type": { 952 | "kind": "SCALAR", 953 | "name": "String", 954 | "ofType": null 955 | }, 956 | "isDeprecated": false, 957 | "deprecationReason": null 958 | }, 959 | { 960 | "name": "args", 961 | "description": null, 962 | "args": [], 963 | "type": { 964 | "kind": "NON_NULL", 965 | "name": null, 966 | "ofType": { 967 | "kind": "LIST", 968 | "name": null, 969 | "ofType": { 970 | "kind": "NON_NULL", 971 | "name": null, 972 | "ofType": { 973 | "kind": "OBJECT", 974 | "name": "__InputValue", 975 | "ofType": null 976 | } 977 | } 978 | } 979 | }, 980 | "isDeprecated": false, 981 | "deprecationReason": null 982 | }, 983 | { 984 | "name": "type", 985 | "description": null, 986 | "args": [], 987 | "type": { 988 | "kind": "NON_NULL", 989 | "name": null, 990 | "ofType": { 991 | "kind": "OBJECT", 992 | "name": "__Type", 993 | "ofType": null 994 | } 995 | }, 996 | "isDeprecated": false, 997 | "deprecationReason": null 998 | }, 999 | { 1000 | "name": "isDeprecated", 1001 | "description": null, 1002 | "args": [], 1003 | "type": { 1004 | "kind": "NON_NULL", 1005 | "name": null, 1006 | "ofType": { 1007 | "kind": "SCALAR", 1008 | "name": "Boolean", 1009 | "ofType": null 1010 | } 1011 | }, 1012 | "isDeprecated": false, 1013 | "deprecationReason": null 1014 | }, 1015 | { 1016 | "name": "deprecationReason", 1017 | "description": null, 1018 | "args": [], 1019 | "type": { 1020 | "kind": "SCALAR", 1021 | "name": "String", 1022 | "ofType": null 1023 | }, 1024 | "isDeprecated": false, 1025 | "deprecationReason": null 1026 | } 1027 | ], 1028 | "inputFields": null, 1029 | "interfaces": [], 1030 | "enumValues": null, 1031 | "possibleTypes": null 1032 | }, 1033 | { 1034 | "kind": "OBJECT", 1035 | "name": "__InputValue", 1036 | "description": "Arguments provided to Fields or Directives and the input fields of an InputObject are represented as Input Values which describe their type and optionally a default value.", 1037 | "fields": [ 1038 | { 1039 | "name": "name", 1040 | "description": null, 1041 | "args": [], 1042 | "type": { 1043 | "kind": "NON_NULL", 1044 | "name": null, 1045 | "ofType": { 1046 | "kind": "SCALAR", 1047 | "name": "String", 1048 | "ofType": null 1049 | } 1050 | }, 1051 | "isDeprecated": false, 1052 | "deprecationReason": null 1053 | }, 1054 | { 1055 | "name": "description", 1056 | "description": null, 1057 | "args": [], 1058 | "type": { 1059 | "kind": "SCALAR", 1060 | "name": "String", 1061 | "ofType": null 1062 | }, 1063 | "isDeprecated": false, 1064 | "deprecationReason": null 1065 | }, 1066 | { 1067 | "name": "type", 1068 | "description": null, 1069 | "args": [], 1070 | "type": { 1071 | "kind": "NON_NULL", 1072 | "name": null, 1073 | "ofType": { 1074 | "kind": "OBJECT", 1075 | "name": "__Type", 1076 | "ofType": null 1077 | } 1078 | }, 1079 | "isDeprecated": false, 1080 | "deprecationReason": null 1081 | }, 1082 | { 1083 | "name": "defaultValue", 1084 | "description": null, 1085 | "args": [], 1086 | "type": { 1087 | "kind": "SCALAR", 1088 | "name": "String", 1089 | "ofType": null 1090 | }, 1091 | "isDeprecated": false, 1092 | "deprecationReason": null 1093 | } 1094 | ], 1095 | "inputFields": null, 1096 | "interfaces": [], 1097 | "enumValues": null, 1098 | "possibleTypes": null 1099 | }, 1100 | { 1101 | "kind": "OBJECT", 1102 | "name": "__Schema", 1103 | "description": "A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, as well as the entry points for query, mutation, and subscription operations.", 1104 | "fields": [ 1105 | { 1106 | "name": "types", 1107 | "description": "A list of all types supported by this server.", 1108 | "args": [], 1109 | "type": { 1110 | "kind": "NON_NULL", 1111 | "name": null, 1112 | "ofType": { 1113 | "kind": "LIST", 1114 | "name": null, 1115 | "ofType": { 1116 | "kind": "NON_NULL", 1117 | "name": null, 1118 | "ofType": { 1119 | "kind": "OBJECT", 1120 | "name": "__Type", 1121 | "ofType": null 1122 | } 1123 | } 1124 | } 1125 | }, 1126 | "isDeprecated": false, 1127 | "deprecationReason": null 1128 | }, 1129 | { 1130 | "name": "queryType", 1131 | "description": "The type that query operations will be rooted at.", 1132 | "args": [], 1133 | "type": { 1134 | "kind": "NON_NULL", 1135 | "name": null, 1136 | "ofType": { 1137 | "kind": "OBJECT", 1138 | "name": "__Type", 1139 | "ofType": null 1140 | } 1141 | }, 1142 | "isDeprecated": false, 1143 | "deprecationReason": null 1144 | }, 1145 | { 1146 | "name": "mutationType", 1147 | "description": "If this server supports mutation, the type that mutation operations will be rooted at.", 1148 | "args": [], 1149 | "type": { 1150 | "kind": "OBJECT", 1151 | "name": "__Type", 1152 | "ofType": null 1153 | }, 1154 | "isDeprecated": false, 1155 | "deprecationReason": null 1156 | }, 1157 | { 1158 | "name": "subscriptionType", 1159 | "description": "If this server support subscription, the type that subscription operations will be rooted at.", 1160 | "args": [], 1161 | "type": { 1162 | "kind": "OBJECT", 1163 | "name": "__Type", 1164 | "ofType": null 1165 | }, 1166 | "isDeprecated": false, 1167 | "deprecationReason": null 1168 | }, 1169 | { 1170 | "name": "directives", 1171 | "description": "A list of all directives supported by this server.", 1172 | "args": [], 1173 | "type": { 1174 | "kind": "NON_NULL", 1175 | "name": null, 1176 | "ofType": { 1177 | "kind": "LIST", 1178 | "name": null, 1179 | "ofType": { 1180 | "kind": "NON_NULL", 1181 | "name": null, 1182 | "ofType": { 1183 | "kind": "OBJECT", 1184 | "name": "__Directive", 1185 | "ofType": null 1186 | } 1187 | } 1188 | } 1189 | }, 1190 | "isDeprecated": false, 1191 | "deprecationReason": null 1192 | } 1193 | ], 1194 | "inputFields": null, 1195 | "interfaces": [], 1196 | "enumValues": null, 1197 | "possibleTypes": null 1198 | }, 1199 | { 1200 | "kind": "OBJECT", 1201 | "name": "__Type", 1202 | "description": "The fundamental unit of any GraphQL Schema is the type. There are many kinds of types in GraphQL as represented by the `__TypeKind` enum.\n\nDepending on the kind of a type, certain fields describe information about that type. Scalar types provide no information beyond a name and description, while Enum types provide their values. Object and Interface types provide the fields they describe. Abstract types, Union and Interface, provide the Object types possible at runtime. List and NonNull types compose other types.", 1203 | "fields": [ 1204 | { 1205 | "name": "kind", 1206 | "description": null, 1207 | "args": [], 1208 | "type": { 1209 | "kind": "NON_NULL", 1210 | "name": null, 1211 | "ofType": { 1212 | "kind": "ENUM", 1213 | "name": "__TypeKind", 1214 | "ofType": null 1215 | } 1216 | }, 1217 | "isDeprecated": false, 1218 | "deprecationReason": null 1219 | }, 1220 | { 1221 | "name": "name", 1222 | "description": null, 1223 | "args": [], 1224 | "type": { 1225 | "kind": "SCALAR", 1226 | "name": "String", 1227 | "ofType": null 1228 | }, 1229 | "isDeprecated": false, 1230 | "deprecationReason": null 1231 | }, 1232 | { 1233 | "name": "description", 1234 | "description": null, 1235 | "args": [], 1236 | "type": { 1237 | "kind": "SCALAR", 1238 | "name": "String", 1239 | "ofType": null 1240 | }, 1241 | "isDeprecated": false, 1242 | "deprecationReason": null 1243 | }, 1244 | { 1245 | "name": "fields", 1246 | "description": null, 1247 | "args": [ 1248 | { 1249 | "name": "includeDeprecated", 1250 | "description": null, 1251 | "type": { 1252 | "kind": "NON_NULL", 1253 | "name": null, 1254 | "ofType": { 1255 | "kind": "SCALAR", 1256 | "name": "Boolean", 1257 | "ofType": null 1258 | } 1259 | }, 1260 | "defaultValue": "false" 1261 | } 1262 | ], 1263 | "type": { 1264 | "kind": "LIST", 1265 | "name": null, 1266 | "ofType": { 1267 | "kind": "NON_NULL", 1268 | "name": null, 1269 | "ofType": { 1270 | "kind": "OBJECT", 1271 | "name": "__Field", 1272 | "ofType": null 1273 | } 1274 | } 1275 | }, 1276 | "isDeprecated": false, 1277 | "deprecationReason": null 1278 | }, 1279 | { 1280 | "name": "interfaces", 1281 | "description": null, 1282 | "args": [], 1283 | "type": { 1284 | "kind": "LIST", 1285 | "name": null, 1286 | "ofType": { 1287 | "kind": "NON_NULL", 1288 | "name": null, 1289 | "ofType": { 1290 | "kind": "OBJECT", 1291 | "name": "__Type", 1292 | "ofType": null 1293 | } 1294 | } 1295 | }, 1296 | "isDeprecated": false, 1297 | "deprecationReason": null 1298 | }, 1299 | { 1300 | "name": "possibleTypes", 1301 | "description": null, 1302 | "args": [], 1303 | "type": { 1304 | "kind": "LIST", 1305 | "name": null, 1306 | "ofType": { 1307 | "kind": "NON_NULL", 1308 | "name": null, 1309 | "ofType": { 1310 | "kind": "OBJECT", 1311 | "name": "__Type", 1312 | "ofType": null 1313 | } 1314 | } 1315 | }, 1316 | "isDeprecated": false, 1317 | "deprecationReason": null 1318 | }, 1319 | { 1320 | "name": "enumValues", 1321 | "description": null, 1322 | "args": [ 1323 | { 1324 | "name": "includeDeprecated", 1325 | "description": null, 1326 | "type": { 1327 | "kind": "NON_NULL", 1328 | "name": null, 1329 | "ofType": { 1330 | "kind": "SCALAR", 1331 | "name": "Boolean", 1332 | "ofType": null 1333 | } 1334 | }, 1335 | "defaultValue": "false" 1336 | } 1337 | ], 1338 | "type": { 1339 | "kind": "LIST", 1340 | "name": null, 1341 | "ofType": { 1342 | "kind": "NON_NULL", 1343 | "name": null, 1344 | "ofType": { 1345 | "kind": "OBJECT", 1346 | "name": "__EnumValue", 1347 | "ofType": null 1348 | } 1349 | } 1350 | }, 1351 | "isDeprecated": false, 1352 | "deprecationReason": null 1353 | }, 1354 | { 1355 | "name": "inputFields", 1356 | "description": null, 1357 | "args": [], 1358 | "type": { 1359 | "kind": "LIST", 1360 | "name": null, 1361 | "ofType": { 1362 | "kind": "NON_NULL", 1363 | "name": null, 1364 | "ofType": { 1365 | "kind": "OBJECT", 1366 | "name": "__InputValue", 1367 | "ofType": null 1368 | } 1369 | } 1370 | }, 1371 | "isDeprecated": false, 1372 | "deprecationReason": null 1373 | }, 1374 | { 1375 | "name": "ofType", 1376 | "description": null, 1377 | "args": [], 1378 | "type": { 1379 | "kind": "OBJECT", 1380 | "name": "__Type", 1381 | "ofType": null 1382 | }, 1383 | "isDeprecated": false, 1384 | "deprecationReason": null 1385 | } 1386 | ], 1387 | "inputFields": null, 1388 | "interfaces": [], 1389 | "enumValues": null, 1390 | "possibleTypes": null 1391 | }, 1392 | { 1393 | "kind": "ENUM", 1394 | "name": "__TypeKind", 1395 | "description": "An enum describing what kind of type a given `__Type` is.", 1396 | "fields": null, 1397 | "inputFields": null, 1398 | "interfaces": null, 1399 | "enumValues": [ 1400 | { 1401 | "name": "SCALAR", 1402 | "description": "Indicates this type is a scalar.", 1403 | "isDeprecated": false, 1404 | "deprecationReason": null 1405 | }, 1406 | { 1407 | "name": "OBJECT", 1408 | "description": "Indicates this type is an object. `fields` and `interfaces` are valid fields.", 1409 | "isDeprecated": false, 1410 | "deprecationReason": null 1411 | }, 1412 | { 1413 | "name": "INTERFACE", 1414 | "description": "Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.", 1415 | "isDeprecated": false, 1416 | "deprecationReason": null 1417 | }, 1418 | { 1419 | "name": "UNION", 1420 | "description": "Indicates this type is a union. `possibleTypes` is a valid field.", 1421 | "isDeprecated": false, 1422 | "deprecationReason": null 1423 | }, 1424 | { 1425 | "name": "ENUM", 1426 | "description": "Indicates this type is an enum. `enumValues` is a valid field.", 1427 | "isDeprecated": false, 1428 | "deprecationReason": null 1429 | }, 1430 | { 1431 | "name": "INPUT_OBJECT", 1432 | "description": "Indicates this type is an input object. `inputFields` is a valid field.", 1433 | "isDeprecated": false, 1434 | "deprecationReason": null 1435 | }, 1436 | { 1437 | "name": "LIST", 1438 | "description": "Indicates this type is a list. `ofType` is a valid field.", 1439 | "isDeprecated": false, 1440 | "deprecationReason": null 1441 | }, 1442 | { 1443 | "name": "NON_NULL", 1444 | "description": "Indicates this type is a non-null. `ofType` is a valid field.", 1445 | "isDeprecated": false, 1446 | "deprecationReason": null 1447 | } 1448 | ], 1449 | "possibleTypes": null 1450 | } 1451 | ], 1452 | "directives": [ 1453 | { 1454 | "name": "defer", 1455 | "description": null, 1456 | "locations": [ 1457 | "FIELD" 1458 | ], 1459 | "args": [] 1460 | }, 1461 | { 1462 | "name": "include", 1463 | "description": "Directs the executor to include this field or fragment only when the `if` argument is true.", 1464 | "locations": [ 1465 | "FIELD", 1466 | "FRAGMENT_SPREAD", 1467 | "INLINE_FRAGMENT" 1468 | ], 1469 | "args": [ 1470 | { 1471 | "name": "if", 1472 | "description": "Included when true.", 1473 | "type": { 1474 | "kind": "NON_NULL", 1475 | "name": null, 1476 | "ofType": { 1477 | "kind": "SCALAR", 1478 | "name": "Boolean", 1479 | "ofType": null 1480 | } 1481 | }, 1482 | "defaultValue": null 1483 | } 1484 | ] 1485 | }, 1486 | { 1487 | "name": "skip", 1488 | "description": "Directs the executor to skip this field or fragment when the `if` argument is true.", 1489 | "locations": [ 1490 | "FIELD", 1491 | "FRAGMENT_SPREAD", 1492 | "INLINE_FRAGMENT" 1493 | ], 1494 | "args": [ 1495 | { 1496 | "name": "if", 1497 | "description": "Skipped when true.", 1498 | "type": { 1499 | "kind": "NON_NULL", 1500 | "name": null, 1501 | "ofType": { 1502 | "kind": "SCALAR", 1503 | "name": "Boolean", 1504 | "ofType": null 1505 | } 1506 | }, 1507 | "defaultValue": null 1508 | } 1509 | ] 1510 | }, 1511 | { 1512 | "name": "stream", 1513 | "description": null, 1514 | "locations": [ 1515 | "FIELD" 1516 | ], 1517 | "args": [] 1518 | } 1519 | ] 1520 | } 1521 | } 1522 | } -------------------------------------------------------------------------------- /examples/codegen-for-async-graphql-example/tests/snapshots/main.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "active": true, 4 | "me": { 5 | "id": "11111", 6 | "name": "Aaron", 7 | "email": "aaa@", 8 | "rank": 5.1, 9 | "age": 30, 10 | "active": true, 11 | "web": "https://github.com/", 12 | "friends": { 13 | "totalCount": 10, 14 | "nodes": [ 15 | { 16 | "id": "1-1", 17 | "name": "Beck" 18 | } 19 | ] 20 | }, 21 | "notifications": [ 22 | { 23 | "id": "1-1", 24 | "title": "title1" 25 | }, 26 | { 27 | "id": "2-1", 28 | "title": "title2" 29 | } 30 | ], 31 | "search": [] 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/codegen.rs: -------------------------------------------------------------------------------- 1 | use clap::Clap; 2 | 3 | use codegen_for_async_graphql_renderer::{generate_from_path, Config}; 4 | 5 | #[derive(Clap)] 6 | #[clap()] 7 | struct Opts { 8 | _dummy: Option, 9 | #[clap(short, long, required = true)] 10 | schema: String, 11 | #[clap(short, long, required = true)] 12 | output: String, 13 | } 14 | 15 | fn main() { 16 | let opts: Opts = Opts::parse(); 17 | let path = opts.schema; 18 | let config = Config { 19 | output_bnase_path: opts.output, 20 | }; 21 | generate_from_path(&path, &config); 22 | } 23 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() {} 2 | -------------------------------------------------------------------------------- /tests/queries/introspection.graphql: -------------------------------------------------------------------------------- 1 | query IntrospectionQuery { 2 | __schema { 3 | queryType { 4 | name 5 | } 6 | mutationType { 7 | name 8 | } 9 | subscriptionType { 10 | name 11 | } 12 | types { 13 | ...FullType 14 | } 15 | directives { 16 | name 17 | description 18 | locations 19 | args { 20 | ...InputValue 21 | } 22 | } 23 | } 24 | } 25 | fragment FullType on __Type { 26 | kind 27 | name 28 | description 29 | fields(includeDeprecated: true) { 30 | name 31 | description 32 | args { 33 | ...InputValue 34 | } 35 | type { 36 | ...TypeRef 37 | } 38 | isDeprecated 39 | deprecationReason 40 | } 41 | inputFields { 42 | ...InputValue 43 | } 44 | interfaces { 45 | ...TypeRef 46 | } 47 | enumValues(includeDeprecated: true) { 48 | name 49 | description 50 | isDeprecated 51 | deprecationReason 52 | } 53 | possibleTypes { 54 | ...TypeRef 55 | } 56 | } 57 | fragment InputValue on __InputValue { 58 | name 59 | description 60 | type { 61 | ...TypeRef 62 | } 63 | defaultValue 64 | } 65 | fragment TypeRef on __Type { 66 | kind 67 | name 68 | ofType { 69 | kind 70 | name 71 | ofType { 72 | kind 73 | name 74 | ofType { 75 | kind 76 | name 77 | ofType { 78 | kind 79 | name 80 | ofType { 81 | kind 82 | name 83 | ofType { 84 | kind 85 | name 86 | ofType { 87 | kind 88 | name 89 | } 90 | } 91 | } 92 | } 93 | } 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /tests/schemas/README.md: -------------------------------------------------------------------------------- 1 | https://github.com/apollographql/apollo-tooling/blob/78495e391789ad80c4af6242dfd17dde30521a58/__fixtures__/misc/schema.graphql 2 | 3 | https://github.com/apollographql/apollo-tooling/blob/78495e391789ad80c4af6242dfd17dde30521a58/__fixtures__/misc/schema.json 4 | -------------------------------------------------------------------------------- /tests/schemas/kitchen-sink.graphql: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015-present, Facebook, Inc. 2 | # 3 | # This source code is licensed under the MIT license found in the 4 | # LICENSE file in the root directory of this source tree. 5 | 6 | schema { 7 | query: QueryType 8 | mutation: MutationType 9 | } 10 | 11 | """ 12 | This is a description 13 | of the `Foo` type. 14 | """ 15 | type Foo implements Bar & Baz { 16 | one: Type 17 | two(argument: InputType!): Type 18 | three(argument: InputType, other: String): Int 19 | four(argument: String = "string"): String 20 | five(argument: [String] = ["string", "string"]): String 21 | six(argument: InputType = { key: "value" }): Type 22 | seven(argument: Int = null): Type 23 | } 24 | 25 | type AnnotatedObject @onObject(arg: "value") { 26 | annotatedField(arg: Type = "default" @onArg): Type @onField 27 | } 28 | 29 | type UndefinedType 30 | 31 | extend type Foo { 32 | seven(argument: [String]): Type 33 | } 34 | 35 | extend type Foo @onType 36 | 37 | interface Bar { 38 | one: Type 39 | four(argument: String = "string"): String 40 | } 41 | 42 | interface AnnotatedInterface @onInterface { 43 | annotatedField(arg: Type @onArg): Type @onField 44 | } 45 | 46 | interface UndefinedInterface 47 | 48 | extend interface Bar { 49 | two(argument: InputType!): Type 50 | } 51 | 52 | extend interface Bar @onInterface 53 | 54 | union Feed = Story | Article | Advert 55 | 56 | union AnnotatedUnion @onUnion = A | B 57 | 58 | union AnnotatedUnionTwo @onUnion = A | B 59 | 60 | union UndefinedUnion 61 | 62 | extend union Feed = Photo | Video 63 | 64 | extend union Feed @onUnion 65 | 66 | scalar CustomScalar 67 | 68 | scalar AnnotatedScalar @onScalar 69 | 70 | extend scalar CustomScalar @onScalar 71 | 72 | enum Site { 73 | DESKTOP 74 | MOBILE 75 | } 76 | 77 | enum AnnotatedEnum @onEnum { 78 | ANNOTATED_VALUE @onEnumValue 79 | OTHER_VALUE 80 | } 81 | 82 | enum UndefinedEnum 83 | 84 | extend enum Site { 85 | VR 86 | } 87 | 88 | extend enum Site @onEnum 89 | 90 | input InputType { 91 | key: String! 92 | answer: Int = 42 93 | } 94 | 95 | input AnnotatedInput @onInputObject { 96 | annotatedField: Type @onField 97 | } 98 | 99 | input UndefinedInput 100 | 101 | extend input InputType { 102 | other: Float = 1.23e4 103 | } 104 | 105 | extend input InputType @onInputObject 106 | 107 | directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT 108 | 109 | directive @include(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT 110 | 111 | directive @include2(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT 112 | -------------------------------------------------------------------------------- /tests/schemas/query.graphql: -------------------------------------------------------------------------------- 1 | # schema { 2 | # query: Root 3 | # } 4 | 5 | type Root { 6 | me: Me! 7 | active: Bool! 8 | } 9 | 10 | type Me { 11 | id: ID! 12 | name: String! 13 | email: String! 14 | age: Int! 15 | rank: Float! 16 | } 17 | -------------------------------------------------------------------------------- /tests/schemas/schema.graphql: -------------------------------------------------------------------------------- 1 | schema { 2 | query: Query 3 | mutation: Mutation 4 | } 5 | 6 | scalar Date 7 | 8 | type doubleHump { 9 | humpOne: String 10 | humpTwo: String 11 | } 12 | 13 | type OddType { 14 | date: Date 15 | camel: doubleHump 16 | } 17 | 18 | # This is a type to test comments 19 | type CommentTest { 20 | "This is a single-line comment" 21 | singleLine: String 22 | """ 23 | This is a 24 | multi-line 25 | comment. 26 | """ 27 | multiLine: String 28 | enumCommentTest: EnumCommentTestCase 29 | } 30 | 31 | enum EnumCommentTestCase { 32 | "This is a single-line comment" 33 | first 34 | """ 35 | This is a 36 | multi-line 37 | comment. 38 | """ 39 | second 40 | } 41 | 42 | interface InterfaceTestCase { 43 | prop: String! 44 | } 45 | 46 | type ImplA implements InterfaceTestCase { 47 | prop: String! 48 | propA: String! 49 | } 50 | 51 | type ImplB implements InterfaceTestCase { 52 | prop: String! 53 | propB: Int 54 | } 55 | 56 | type PartialA { 57 | prop: String! 58 | } 59 | 60 | type PartialB { 61 | prop: String! 62 | } 63 | 64 | type Nesting { 65 | propA: [[EnumCommentTestCase!]!]! 66 | propB: [[EnumCommentTestCase]] 67 | } 68 | 69 | input Duplicate { 70 | propA: EnumCommentTestCase! 71 | propB: [EnumCommentTestCase!]! 72 | } 73 | 74 | union UnionTestCase = PartialA | PartialB 75 | 76 | type Query { 77 | misc: OddType 78 | commentTest: CommentTest 79 | interfaceTest: InterfaceTestCase 80 | unionTest: UnionTestCase 81 | scalarTest: Boolean! 82 | nesting: Nesting! 83 | } 84 | 85 | type Mutation { 86 | duplicates( 87 | a: EnumCommentTestCase! 88 | b: EnumCommentTestCase! 89 | c: Duplicate! 90 | ): Nesting! 91 | } 92 | --------------------------------------------------------------------------------